File size: 7,057 Bytes
01d9631
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb77958
01d9631
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb77958
01d9631
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb77958
01d9631
 
 
 
 
 
bb77958
01d9631
 
 
 
 
 
 
 
 
 
 
 
 
bb77958
01d9631
 
 
 
bb77958
 
01d9631
 
 
 
 
 
 
 
 
bb77958
01d9631
 
 
 
 
 
 
 
bb77958
 
 
 
 
 
01d9631
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb77958
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package main

import "encoding/json"

// --- Claude API Structs (Anthropic Format) ---

// ClaudeRequest represents the incoming request structure from the client
type ClaudeRequest struct {
	Model         string             `json:"model"`
	Messages      []ClaudeMessage    `json:"messages"`
	System        json.RawMessage    `json:"system,omitempty"` // Can be string or list of blocks
	MaxTokens     *int               `json:"max_tokens,omitempty"` // Use pointer for optional fields
	StopSequences []string           `json:"stop_sequences,omitempty"`
	Stream        bool               `json:"stream,omitempty"`
	Temperature   *float64           `json:"temperature,omitempty"`
	TopP          *float64           `json:"top_p,omitempty"`
	TopK          *int               `json:"top_k,omitempty"` 
}

// ClaudeMessage represents a message in the Claude request
type ClaudeMessage struct {
	Role    string            `json:"role"` // "user" or "assistant"
	Content json.RawMessage   `json:"content"` // Can be string or list of blocks
}

// ClaudeContentBlock represents a block within the content array
type ClaudeContentBlock struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
	// Add other block types if needed (e.g., image)
}

// ClaudeResponse represents the non-streaming response structure sent to the client
type ClaudeResponse struct {
	ID           string               `json:"id"`
	Type         string               `json:"type"` // e.g., "message"
	Role         string               `json:"role"` // e.g., "assistant"
	Content      []ClaudeContentBlock `json:"content"`
	Model        string               `json:"model"`
	StopReason   string               `json:"stop_reason"` // e.g., "end_turn", "max_tokens"
	StopSequence *string              `json:"stop_sequence"` // Usually null
	Usage        ClaudeUsage          `json:"usage"`
}

// ClaudeUsage represents the token usage information
type ClaudeUsage struct {
	InputTokens  int `json:"input_tokens"`
	OutputTokens int `json:"output_tokens"`
}

// ClaudeErrorResponse represents the error structure sent to the client
type ClaudeErrorResponse struct {
	Type  string        `json:"type"` // Always "error"
	Error ClaudeError `json:"error"`
}

// ClaudeError represents the detailed error information
type ClaudeError struct {
	Type    string `json:"type"`    // e.g., "invalid_request_error", "api_error"
	Message string `json:"message"`
}


// --- OpenAI API Structs ---

// OpenAIRequest represents the request structure sent to the upstream OpenAI API
type OpenAIRequest struct {
	Model       string          `json:"model"`
	Messages    []OpenAIMessage `json:"messages"`
	MaxTokens   *int            `json:"max_tokens,omitempty"`
	Temperature *float64        `json:"temperature,omitempty"`
	TopP        *float64        `json:"top_p,omitempty"`
	TopK        *int            `json:"top_k,omitempty"` 
	Stop        []string        `json:"stop,omitempty"`
	Stream      bool            `json:"stream,omitempty"`
}

// OpenAIMessage represents a message in the OpenAI request
type OpenAIMessage struct {
	Role    string `json:"role"` // "system", "user", or "assistant"
	Content string `json:"content"`
}

// OpenAIResponse represents the non-streaming response from the upstream OpenAI API
type OpenAIResponse struct {
	ID      string             `json:"id"`
	Object  string             `json:"object"` // e.g., "chat.completion"
	Created int64              `json:"created"`
	Model   string             `json:"model"`
	Choices []OpenAIChoice     `json:"choices"`
	Usage   *OpenAIUsage       `json:"usage,omitempty"` 
}

// OpenAIChoice represents a choice in the OpenAI response
type OpenAIChoice struct {
	Index        int             `json:"index"`
	Message      OpenAIMessage   `json:"message"`
	FinishReason *string         `json:"finish_reason"` 
}

// OpenAIUsage represents the token usage information from OpenAI
type OpenAIUsage struct {
	PromptTokens     int `json:"prompt_tokens"`
	CompletionTokens int `json:"completion_tokens"`
	TotalTokens      int `json:"total_tokens"`
}

// OpenAIStreamChoice represents a choice within an OpenAI SSE chunk
type OpenAIStreamChoice struct {
	Index        int                  `json:"index"`
	Delta        OpenAIStreamDelta    `json:"delta"`
	FinishReason *string              `json:"finish_reason"` 
}

// OpenAIStreamDelta represents the delta content within an OpenAI SSE chunk
type OpenAIStreamDelta struct {
	Role    *string `json:"role,omitempty"` 
	Content *string `json:"content,omitempty"` 
}

// OpenAIStreamChunk represents the structure of a data chunk in the OpenAI SSE stream
type OpenAIStreamChunk struct {
	ID      string               `json:"id"`
	Object  string               `json:"object"` // e.g., "chat.completion.chunk"
	Created int64                `json:"created"`
	Model   string               `json:"model"`
	Choices []OpenAIStreamChoice `json:"choices"`
	Usage   *OpenAIUsage         `json:"usage,omitempty"` 
}


// --- Claude SSE Structs (for sending back to client) ---

// ClaudeSSEEvent represents a generic Claude SSE event structure for easy marshaling
type ClaudeSSEEvent struct {
	Type         string                `json:"type"`
	Index        *int                  `json:"index,omitempty"` 
	Message      *ClaudeSSEMessage     `json:"message,omitempty"` 
	ContentBlock *ClaudeSSEContentBlock `json:"content_block,omitempty"` 
	Delta        *ClaudeSSEDelta       `json:"delta,omitempty"` 
	Usage        *ClaudeSSEUsage       `json:"usage,omitempty"` 
	Error        *ClaudeError          `json:"error,omitempty"` 
}

// ClaudeSSEMessage is nested within message_start
type ClaudeSSEMessage struct {
	ID           string               `json:"id"`
	Type         string               `json:"type"` // "message"
	Role         string               `json:"role"` // "assistant"
	Content      []ClaudeContentBlock `json:"content"` // Initially empty
	Model        string               `json:"model"`
	StopReason   *string              `json:"stop_reason"` // Initially null
	StopSequence *string              `json:"stop_sequence"` // Initially null
	Usage        ClaudeUsage          `json:"usage"` // Initial usage (input tokens)
}

// ClaudeSSEContentBlock is nested within content_block_start
type ClaudeSSEContentBlock struct {
	Type string `json:"type"` // "text"
	Text string `json:"text"` // Initially empty
}

// ClaudeSSEDelta is nested within content_block_delta and message_delta
type ClaudeSSEDelta struct {
	Type         string  `json:"type,omitempty"` // "text_delta" in content_block_delta
	Text         *string `json:"text,omitempty"` // Pointer for content_block_delta
	StopReason   *string `json:"stop_reason,omitempty"` // Pointer for message_delta
	StopSequence *string `json:"stop_sequence,omitempty"` // Pointer for message_delta (usually null)
}

// ClaudeSSEUsage is nested within message_delta (HACK) and message_stop
type ClaudeSSEUsage struct {
	InputTokens  *int `json:"input_tokens,omitempty"` // Only in message_stop
	OutputTokens int  `json:"output_tokens"` 
}