264 lines
6.9 KiB
Go
264 lines
6.9 KiB
Go
package plugin
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
ABIVersion uint32 = 1
|
|
SchemaVersion uint32 = 3
|
|
PluginName = "cpa-ext"
|
|
Version = "0.1.0-dev"
|
|
)
|
|
|
|
const (
|
|
MethodPluginRegister = "plugin.register"
|
|
MethodPluginReconfigure = "plugin.reconfigure"
|
|
MethodPluginShutdown = "plugin.shutdown"
|
|
MethodRequestComplete = "request.complete"
|
|
MethodUsageHandle = "usage.handle"
|
|
MethodFrontendIdentifier = "frontend_auth.identifier"
|
|
MethodFrontendAuthenticate = "frontend_auth.authenticate"
|
|
MethodSchedulerPick = "scheduler.pick"
|
|
MethodRequestBefore = "request.intercept_before"
|
|
MethodRequestAfter = "request.intercept_after"
|
|
MethodManagementRegister = "management.register"
|
|
MethodManagementHandle = "management.handle"
|
|
)
|
|
|
|
type Envelope struct {
|
|
OK bool `json:"ok"`
|
|
Result json.RawMessage `json:"result,omitempty"`
|
|
Error *EnvelopeError `json:"error,omitempty"`
|
|
}
|
|
|
|
type EnvelopeError struct {
|
|
Code string `json:"code"`
|
|
Message string `json:"message"`
|
|
Retryable bool `json:"retryable,omitempty"`
|
|
HTTPStatus int `json:"http_status,omitempty"`
|
|
}
|
|
|
|
type LifecycleRequest struct {
|
|
ConfigYAML []byte `json:"config_yaml"`
|
|
SchemaVersion uint32 `json:"schema_version"`
|
|
}
|
|
|
|
type Registration struct {
|
|
SchemaVersion uint32 `json:"schema_version"`
|
|
Metadata Metadata `json:"metadata"`
|
|
Capabilities Capabilities `json:"capabilities"`
|
|
}
|
|
|
|
type Metadata struct {
|
|
Name string
|
|
Version string
|
|
Author string
|
|
GitHubRepository string
|
|
Logo string
|
|
ConfigFields []ConfigField
|
|
}
|
|
|
|
type ConfigField struct {
|
|
Name string
|
|
Type string
|
|
EnumValues []string
|
|
Description string
|
|
}
|
|
|
|
type Capabilities struct {
|
|
FrontendAuthProvider bool `json:"frontend_auth_provider"`
|
|
FrontendAuthProviderExclusive bool `json:"frontend_auth_provider_exclusive"`
|
|
Scheduler bool `json:"scheduler"`
|
|
RequestInterceptor bool `json:"request_interceptor"`
|
|
RequestLifecyclePlugin bool `json:"request_lifecycle_plugin"`
|
|
UsagePlugin bool `json:"usage_plugin"`
|
|
ManagementAPI bool `json:"management_api"`
|
|
}
|
|
|
|
type FrontendIdentifierResponse struct {
|
|
Identifier string `json:"identifier"`
|
|
}
|
|
|
|
type FrontendAuthRequest struct {
|
|
Method string
|
|
Path string
|
|
Headers http.Header
|
|
Query url.Values
|
|
Body []byte
|
|
}
|
|
|
|
type FrontendAuthResponse struct {
|
|
Authenticated bool
|
|
Principal string
|
|
Metadata map[string]string
|
|
}
|
|
|
|
type SchedulerPickRequest struct {
|
|
Provider string
|
|
Providers []string
|
|
Model string
|
|
Stream bool
|
|
Options SchedulerOptions
|
|
Candidates []SchedulerAuthCandidate
|
|
}
|
|
|
|
type SchedulerOptions struct {
|
|
Headers map[string][]string
|
|
Metadata map[string]any
|
|
}
|
|
|
|
type SchedulerAuthCandidate struct {
|
|
ID string
|
|
Provider string
|
|
Priority int
|
|
Status string
|
|
Attributes map[string]string
|
|
Metadata map[string]any
|
|
}
|
|
|
|
type SchedulerPickResponse struct {
|
|
AuthID string
|
|
DelegateBuiltin string
|
|
Handled bool
|
|
}
|
|
|
|
type RequestInterceptRequest struct {
|
|
RequestID string
|
|
TraceID string
|
|
SourceFormat string
|
|
ToFormat string
|
|
Model string
|
|
RequestedModel string
|
|
Stream bool
|
|
Headers http.Header
|
|
Body []byte
|
|
Metadata map[string]any
|
|
}
|
|
|
|
type RequestInterceptResponse struct {
|
|
Headers http.Header
|
|
Body []byte
|
|
ClearHeaders []string
|
|
Terminate bool
|
|
StatusCode int
|
|
ResponseHeaders http.Header
|
|
ResponseBody []byte
|
|
}
|
|
|
|
type HostAuthFileEntry struct {
|
|
ID string `json:"id,omitempty"`
|
|
AuthIndex string `json:"auth_index,omitempty"`
|
|
Name string `json:"name"`
|
|
Type string `json:"type,omitempty"`
|
|
Provider string `json:"provider,omitempty"`
|
|
Label string `json:"label,omitempty"`
|
|
Status string `json:"status,omitempty"`
|
|
StatusMessage string `json:"status_message,omitempty"`
|
|
Disabled bool `json:"disabled,omitempty"`
|
|
Unavailable bool `json:"unavailable,omitempty"`
|
|
Email string `json:"email,omitempty"`
|
|
ProjectID string `json:"project_id,omitempty"`
|
|
Account string `json:"account,omitempty"`
|
|
Priority int `json:"priority,omitempty"`
|
|
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
|
}
|
|
|
|
type RequestCompletionOutcome string
|
|
|
|
const (
|
|
RequestCompletionSucceeded RequestCompletionOutcome = "succeeded"
|
|
RequestCompletionFailed RequestCompletionOutcome = "failed"
|
|
RequestCompletionRejected RequestCompletionOutcome = "rejected"
|
|
RequestCompletionCanceled RequestCompletionOutcome = "canceled"
|
|
)
|
|
|
|
// RequestCompletion 是一次模型执行的终态,Token 由 UsageRecord 单独补充。
|
|
type RequestCompletion struct {
|
|
RequestID string
|
|
TraceID string
|
|
SourceFormat string
|
|
Model string
|
|
RequestedModel string
|
|
Stream bool
|
|
Outcome RequestCompletionOutcome
|
|
StatusCode int
|
|
Error string
|
|
StartedAt time.Time
|
|
CompletedAt time.Time
|
|
Metadata map[string]any
|
|
}
|
|
|
|
type ManagementRegistrationResponse struct {
|
|
Routes []ManagementRoute `json:"routes,omitempty"`
|
|
Resources []ResourceRoute `json:"resources,omitempty"`
|
|
}
|
|
|
|
type ManagementRoute struct {
|
|
Method string `json:"Method"`
|
|
Path string `json:"Path"`
|
|
Description string `json:"Description,omitempty"`
|
|
}
|
|
|
|
type ResourceRoute struct {
|
|
Path string `json:"Path"`
|
|
Menu string `json:"Menu,omitempty"`
|
|
Description string `json:"Description,omitempty"`
|
|
}
|
|
|
|
type ManagementRequest struct {
|
|
Method string `json:"Method"`
|
|
Path string `json:"Path"`
|
|
Headers http.Header `json:"Headers"`
|
|
Query url.Values `json:"Query"`
|
|
Body []byte `json:"Body"`
|
|
}
|
|
|
|
type ManagementResponse struct {
|
|
StatusCode int `json:"StatusCode,omitempty"`
|
|
Headers http.Header `json:"Headers,omitempty"`
|
|
Body []byte `json:"Body,omitempty"`
|
|
}
|
|
|
|
// UsageRecord mirrors CLIProxyAPI sdk/pluginapi. Keep it in sync with the
|
|
// target host because exported field names are part of the JSON wire contract.
|
|
type UsageRecord struct {
|
|
Provider string
|
|
ExecutorType string
|
|
Model string
|
|
Alias string
|
|
APIKey string
|
|
AuthID string
|
|
AuthIndex string
|
|
AuthType string
|
|
Source string
|
|
ReasoningEffort string
|
|
ServiceTier string
|
|
Generate bool
|
|
RequestedAt time.Time
|
|
Latency time.Duration
|
|
TTFT time.Duration
|
|
Failed bool
|
|
Failure UsageFailure
|
|
Detail UsageDetail
|
|
ResponseHeaders http.Header
|
|
}
|
|
|
|
type UsageFailure struct {
|
|
StatusCode int
|
|
Body string
|
|
}
|
|
|
|
type UsageDetail struct {
|
|
InputTokens int64
|
|
OutputTokens int64
|
|
ReasoningTokens int64
|
|
CachedTokens int64
|
|
CacheReadTokens int64
|
|
CacheCreationTokens int64
|
|
TotalTokens int64
|
|
}
|