package plugin import ( "encoding/json" "net/http" "net/url" "time" ) const ( ABIVersion uint32 = 1 SchemaVersion uint32 = 3 PluginName = "billing" Version = "0.1.0" ) 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 }