Skip to content

Commit 44f733f

Browse files
committed
feat: Improve Anthropic message type handling and mapping
1 parent da1ad2e commit 44f733f

2 files changed

Lines changed: 61 additions & 47 deletions

File tree

src/routes/messages/anthropic-types.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,6 @@ export interface AnthropicMessagesPayload {
2020
}
2121
}
2222

23-
export interface AnthropicMessage {
24-
role: "user" | "assistant"
25-
content: string | Array<AnthropicContentBlock>
26-
}
27-
28-
export type AnthropicContentBlock =
29-
| AnthropicTextBlock
30-
| AnthropicImageBlock
31-
| AnthropicToolResultBlock
32-
3323
export interface AnthropicTextBlock {
3424
type: "text"
3525
text: string
@@ -51,6 +41,34 @@ export interface AnthropicToolResultBlock {
5141
is_error?: boolean
5242
}
5343

44+
export interface AnthropicToolUseBlock {
45+
type: "tool_use"
46+
id: string
47+
name: string
48+
input: Record<string, unknown>
49+
}
50+
51+
export type AnthropicUserContentBlock =
52+
| AnthropicTextBlock
53+
| AnthropicImageBlock
54+
| AnthropicToolResultBlock
55+
56+
export type AnthropicAssistantContentBlock =
57+
| AnthropicTextBlock
58+
| AnthropicToolUseBlock
59+
60+
export interface AnthropicUserMessage {
61+
role: "user"
62+
content: string | Array<AnthropicUserContentBlock>
63+
}
64+
65+
export interface AnthropicAssistantMessage {
66+
role: "assistant"
67+
content: string | Array<AnthropicAssistantContentBlock>
68+
}
69+
70+
export type AnthropicMessage = AnthropicUserMessage | AnthropicAssistantMessage
71+
5472
export interface AnthropicTool {
5573
name: string
5674
description?: string
@@ -61,7 +79,7 @@ export interface AnthropicResponse {
6179
id: string
6280
type: "message"
6381
role: "assistant"
64-
content: Array<AnthropicResponseContentBlock>
82+
content: Array<AnthropicAssistantContentBlock>
6583
model: string
6684
stop_reason:
6785
| "end_turn"
@@ -77,16 +95,7 @@ export interface AnthropicResponse {
7795
}
7896
}
7997

80-
export type AnthropicResponseContentBlock =
81-
| AnthropicTextBlock
82-
| AnthropicToolUseBlock
83-
84-
export interface AnthropicToolUseBlock {
85-
type: "tool_use"
86-
id: string
87-
name: string
88-
input: Record<string, unknown>
89-
}
98+
export type AnthropicResponseContentBlock = AnthropicAssistantContentBlock
9099

91100
// Anthropic Stream Event Types
92101
export interface AnthropicMessageStartEvent {

src/routes/messages/non-stream-translation.ts

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ import {
99
} from "~/services/copilot/create-chat-completions"
1010

1111
import {
12-
type AnthropicContentBlock,
12+
type AnthropicAssistantContentBlock,
13+
type AnthropicAssistantMessage,
1314
type AnthropicMessage,
1415
type AnthropicMessagesPayload,
1516
type AnthropicResponse,
1617
type AnthropicTextBlock,
1718
type AnthropicTool,
1819
type AnthropicToolResultBlock,
1920
type AnthropicToolUseBlock,
21+
type AnthropicUserContentBlock,
22+
type AnthropicUserMessage,
2023
} from "./anthropic-types"
2124
import { mapOpenAIStopReasonToAnthropic } from "./utils"
2225

@@ -72,8 +75,9 @@ function handleSystemPrompt(
7275
}
7376
}
7477

75-
function handleUserMessage(message: AnthropicMessage): Array<Message> {
78+
function handleUserMessage(message: AnthropicUserMessage): Array<Message> {
7679
const newMessages: Array<Message> = []
80+
7781
if (Array.isArray(message.content)) {
7882
const toolResultBlocks = message.content.filter(
7983
(block): block is AnthropicToolResultBlock =>
@@ -103,22 +107,32 @@ function handleUserMessage(message: AnthropicMessage): Array<Message> {
103107
content: mapContent(message.content),
104108
})
105109
}
110+
106111
return newMessages
107112
}
108113

109-
function handleAssistantMessage(message: AnthropicMessage): Array<Message> {
110-
if (Array.isArray(message.content)) {
111-
const toolUseBlocks = message.content.filter(
112-
(block): block is AnthropicToolUseBlock =>
113-
(block as { type: string }).type === "tool_use",
114-
)
114+
function handleAssistantMessage(
115+
message: AnthropicAssistantMessage,
116+
): Array<Message> {
117+
if (!Array.isArray(message.content)) {
118+
return [
119+
{
120+
role: "assistant",
121+
content: mapContent(message.content),
122+
},
123+
]
124+
}
115125

116-
const textBlocks = message.content.filter(
117-
(block): block is AnthropicTextBlock => block.type === "text",
118-
)
126+
const toolUseBlocks = message.content.filter(
127+
(block): block is AnthropicToolUseBlock => block.type === "tool_use",
128+
)
129+
130+
const textBlocks = message.content.filter(
131+
(block): block is AnthropicTextBlock => block.type === "text",
132+
)
119133

120-
if (toolUseBlocks.length > 0) {
121-
return [
134+
return toolUseBlocks.length > 0 ?
135+
[
122136
{
123137
role: "assistant",
124138
content: textBlocks.map((b) => b.text).join("\n\n") || null,
@@ -132,27 +146,18 @@ function handleAssistantMessage(message: AnthropicMessage): Array<Message> {
132146
})),
133147
},
134148
]
135-
} else {
136-
// No tool use, just regular content
137-
return [
149+
: [
138150
{
139151
role: "assistant",
140152
content: mapContent(message.content),
141153
},
142154
]
143-
}
144-
} else {
145-
return [
146-
{
147-
role: "assistant",
148-
content: mapContent(message.content),
149-
},
150-
]
151-
}
152155
}
153156

154157
function mapContent(
155-
content: string | Array<AnthropicContentBlock>,
158+
content:
159+
| string
160+
| Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,
156161
): string | Array<ContentPart> | null {
157162
if (typeof content === "string") {
158163
return content

0 commit comments

Comments
 (0)