package proxy import "encoding/json" // ============================================ // Anthropic API Types // ============================================ // AnthropicRequest represents a request to the Anthropic Messages API type AnthropicRequest struct { Model string `json:"model"` Messages []AnthropicMsg `json:"messages"` System interface{} `json:"system,omitempty"` // string or []SystemBlock MaxTokens int `json:"max_tokens"` Stream bool `json:"stream,omitempty"` Temperature *float64 `json:"temperature,omitempty"` TopP *float64 `json:"top_p,omitempty"` TopK *int `json:"top_k,omitempty"` StopSequences []string `json:"stop_sequences,omitempty"` Tools []AnthropicTool `json:"tools,omitempty"` ToolChoice *AnthropicToolChoice `json:"tool_choice,omitempty"` Metadata map[string]string `json:"metadata,omitempty"` } // AnthropicMsg represents a message in Anthropic format type AnthropicMsg struct { Role string `json:"role"` Content interface{} `json:"content"` // string or []ContentBlock } // ContentBlock represents a content block in Anthropic messages type ContentBlock struct { Type string `json:"type"` // For text blocks Text string `json:"text,omitempty"` // For image blocks Source *ImageSource `json:"source,omitempty"` // For tool_use blocks ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Input interface{} `json:"input,omitempty"` // For tool_result blocks ToolUseID string `json:"tool_use_id,omitempty"` Content interface{} `json:"content,omitempty"` // string or []ContentBlock IsError bool `json:"is_error,omitempty"` } // ImageSource represents an image source in Anthropic format type ImageSource struct { Type string `json:"type"` // "base64" or "url" MediaType string `json:"media_type,omitempty"` // e.g., "image/jpeg" Data string `json:"data,omitempty"` // base64 encoded data URL string `json:"url,omitempty"` // URL for url type } // SystemBlock represents a system message block type SystemBlock struct { Type string `json:"type"` Text string `json:"text"` } // AnthropicTool represents a tool definition in Anthropic format type AnthropicTool struct { Name string `json:"name"` Description string `json:"description,omitempty"` InputSchema interface{} `json:"input_schema"` } // AnthropicToolChoice represents tool choice in Anthropic format type AnthropicToolChoice struct { Type string `json:"type"` // "auto", "any", "tool" Name string `json:"name,omitempty"` } // AnthropicResponse represents a response from the Anthropic Messages API type AnthropicResponse struct { ID string `json:"id"` Type string `json:"type"` Role string `json:"role"` Content []ContentBlock `json:"content"` Model string `json:"model"` StopReason *string `json:"stop_reason"` StopSequence *string `json:"stop_sequence,omitempty"` Usage *Usage `json:"usage"` } // Usage represents token usage statistics type Usage struct { InputTokens int `json:"input_tokens"` OutputTokens int `json:"output_tokens"` } // AnthropicStreamEvent represents an SSE event in Anthropic format type AnthropicStreamEvent struct { Type string `json:"type"` Index int `json:"index,omitempty"` Message *AnthropicResponse `json:"message,omitempty"` ContentBlock *ContentBlock `json:"content_block,omitempty"` Delta *DeltaContent `json:"delta,omitempty"` Usage *Usage `json:"usage,omitempty"` } // DeltaContent represents delta content in streaming type DeltaContent struct { Type string `json:"type,omitempty"` Text string `json:"text,omitempty"` PartialJSON string `json:"partial_json,omitempty"` StopReason *string `json:"stop_reason,omitempty"` } // ============================================ // OpenAI API Types // ============================================ // OpenAIRequest represents a request to OpenAI Chat Completions API type OpenAIRequest struct { Model string `json:"model"` Messages []OpenAIMsg `json:"messages"` MaxTokens int `json:"max_tokens,omitempty"` Stream bool `json:"stream,omitempty"` StreamOptions *StreamOptions `json:"stream_options,omitempty"` Temperature *float64 `json:"temperature,omitempty"` TopP *float64 `json:"top_p,omitempty"` Stop []string `json:"stop,omitempty"` Tools []OpenAITool `json:"tools,omitempty"` ToolChoice interface{} `json:"tool_choice,omitempty"` // "auto", "none", "required", or object // Extra options for backend-specific parameters (e.g., thinking for GLM-4) // These are merged into the final JSON request ExtraOptions map[string]interface{} `json:"-"` } // MarshalJSON custom marshaler to merge ExtraOptions into the request func (r OpenAIRequest) MarshalJSON() ([]byte, error) { // Create a map with standard fields m := map[string]interface{}{ "model": r.Model, "messages": r.Messages, } if r.MaxTokens > 0 { m["max_tokens"] = r.MaxTokens } if r.Stream { m["stream"] = r.Stream } if r.StreamOptions != nil { m["stream_options"] = r.StreamOptions } if r.Temperature != nil { m["temperature"] = *r.Temperature } if r.TopP != nil { m["top_p"] = *r.TopP } if len(r.Stop) > 0 { m["stop"] = r.Stop } if len(r.Tools) > 0 { m["tools"] = r.Tools } if r.ToolChoice != nil { m["tool_choice"] = r.ToolChoice } // Merge extra options (backend-specific parameters like thinking, etc.) for k, v := range r.ExtraOptions { // Don't override standard fields if _, exists := m[k]; !exists { m[k] = v } } return json.Marshal(m) } // StreamOptions represents stream options in OpenAI format type StreamOptions struct { IncludeUsage bool `json:"include_usage"` } // OpenAIMsg represents a message in OpenAI format type OpenAIMsg struct { Role string `json:"role"` Content interface{} `json:"content,omitempty"` // string or []OpenAIContent ToolCalls []OpenAIToolCall `json:"tool_calls,omitempty"` ToolCallID string `json:"tool_call_id,omitempty"` Name string `json:"name,omitempty"` } // OpenAIContent represents content in OpenAI messages (for multimodal) type OpenAIContent struct { Type string `json:"type"` Text string `json:"text,omitempty"` ImageURL *OpenAIImageURL `json:"image_url,omitempty"` } // OpenAIImageURL represents an image URL in OpenAI format type OpenAIImageURL struct { URL string `json:"url"` Detail string `json:"detail,omitempty"` // "auto", "low", "high" } // OpenAITool represents a tool definition in OpenAI format type OpenAITool struct { Type string `json:"type"` Function OpenAIFunction `json:"function"` } // OpenAIFunction represents a function in OpenAI tool type OpenAIFunction struct { Name string `json:"name"` Description string `json:"description,omitempty"` Parameters interface{} `json:"parameters"` } // OpenAIToolCall represents a tool call in OpenAI format type OpenAIToolCall struct { ID string `json:"id"` Type string `json:"type"` Function OpenAIFunctionCall `json:"function"` Index *int `json:"index,omitempty"` // For streaming } // OpenAIFunctionCall represents a function call in OpenAI format type OpenAIFunctionCall struct { Name string `json:"name"` Arguments string `json:"arguments"` } // OpenAIResponse represents a response from OpenAI Chat Completions API type OpenAIResponse struct { ID string `json:"id"` Object string `json:"object"` Created int64 `json:"created"` Model string `json:"model"` Choices []OpenAIChoice `json:"choices"` Usage *OpenAIUsage `json:"usage,omitempty"` } // OpenAIChoice represents a choice in OpenAI response type OpenAIChoice struct { Index int `json:"index"` Message OpenAIMsg `json:"message"` FinishReason string `json:"finish_reason"` } // OpenAIUsage represents usage statistics in OpenAI format type OpenAIUsage struct { PromptTokens int `json:"prompt_tokens"` CompletionTokens int `json:"completion_tokens"` TotalTokens int `json:"total_tokens"` } // OpenAIStreamChunk represents a streaming chunk from OpenAI type OpenAIStreamChunk struct { ID string `json:"id"` Object string `json:"object"` Created int64 `json:"created"` Model string `json:"model"` Choices []OpenAIStreamChoice `json:"choices"` Usage *OpenAIUsage `json:"usage,omitempty"` } // OpenAIStreamChoice represents a choice in OpenAI streaming response type OpenAIStreamChoice struct { Index int `json:"index"` Delta OpenAIStreamDelta `json:"delta"` FinishReason string `json:"finish_reason,omitempty"` } // OpenAIStreamDelta represents delta content in OpenAI streaming type OpenAIStreamDelta struct { Role string `json:"role,omitempty"` Content string `json:"content,omitempty"` ToolCalls []OpenAIToolCall `json:"tool_calls,omitempty"` } // ============================================ // Internal Types // ============================================ // ToolCallAccumulator accumulates tool call data during streaming type ToolCallAccumulator struct { Index int ID string Name string Args string }