Skip to content

Commit 10595c9

Browse files
committed
feat: update tool choice handling and enhance response interfaces
1 parent 437028e commit 10595c9

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

src/routes/messages/responses-translation.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
type ResponseFunctionToolCallItem,
2020
type ResponseFunctionCallOutputItem,
2121
type Tool,
22+
type ToolChoiceFunction,
23+
type ToolChoiceOptions,
2224
} from "~/services/copilot/create-responses"
2325

2426
import {
@@ -315,9 +317,9 @@ const convertAnthropicTools = (
315317

316318
const convertAnthropicToolChoice = (
317319
choice: AnthropicMessagesPayload["tool_choice"],
318-
): unknown => {
320+
): ToolChoiceOptions | ToolChoiceFunction => {
319321
if (!choice) {
320-
return undefined
322+
return "auto"
321323
}
322324

323325
switch (choice.type) {
@@ -328,13 +330,13 @@ const convertAnthropicToolChoice = (
328330
return "required"
329331
}
330332
case "tool": {
331-
return choice.name ? { type: "function", name: choice.name } : undefined
333+
return choice.name ? { type: "function", name: choice.name } : "auto"
332334
}
333335
case "none": {
334336
return "none"
335337
}
336338
default: {
337-
return undefined
339+
return "auto"
338340
}
339341
}
340342
}
@@ -541,9 +543,6 @@ const mapResponsesStopReason = (
541543
if (incompleteDetails?.reason === "content_filter") {
542544
return "end_turn"
543545
}
544-
if (incompleteDetails?.reason === "tool_use") {
545-
return "tool_use"
546-
}
547546
}
548547

549548
return null

src/services/copilot/create-responses.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ export interface ResponsesPayload {
1010
instructions?: string | null
1111
input?: string | Array<ResponseInputItem>
1212
tools?: Array<Tool> | null
13-
tool_choice?: unknown
13+
tool_choice?: ToolChoiceOptions | ToolChoiceFunction
1414
temperature?: number | null
1515
top_p?: number | null
1616
max_output_tokens?: number | null
17-
metadata?: Record<string, unknown> | null
17+
metadata?: Metadata | null
1818
stream?: boolean | null
1919
safety_identifier?: string | null
2020
prompt_cache_key?: string | null
@@ -25,6 +25,13 @@ export interface ResponsesPayload {
2525
[key: string]: unknown
2626
}
2727

28+
export type ToolChoiceOptions = "none" | "auto" | "required"
29+
30+
export interface ToolChoiceFunction {
31+
name: string
32+
type: "function"
33+
}
34+
2835
export type Tool = FunctionTool
2936

3037
export interface FunctionTool {
@@ -112,16 +119,22 @@ export interface ResponsesResult {
112119
status: string
113120
usage?: ResponseUsage | null
114121
error: ResponseError | null
115-
incomplete_details: Record<string, unknown> | null
122+
incomplete_details: IncompleteDetails | null
116123
instructions: string | null
117-
metadata: Record<string, unknown> | null
124+
metadata: Metadata | null
118125
parallel_tool_calls: boolean
119126
temperature: number | null
120127
tool_choice: unknown
121-
tools: Array<Record<string, unknown>>
128+
tools: Array<Tool>
122129
top_p: number | null
123130
}
124131

132+
export type Metadata = { [key: string]: string }
133+
134+
export interface IncompleteDetails {
135+
reason?: "max_output_tokens" | "content_filter"
136+
}
137+
125138
export interface ResponseError {
126139
message: string
127140
}

tests/translation.test.ts renamed to tests/responses-translation.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ describe("translateAnthropicMessagesToResponsesPayload", () => {
5050
it("converts anthropic text blocks into response input messages", () => {
5151
const result = translateAnthropicMessagesToResponsesPayload(samplePayload)
5252

53-
console.log("result:", JSON.stringify(result, null, 2))
5453
expect(Array.isArray(result.input)).toBe(true)
5554
const input = result.input as Array<ResponseInputMessage>
5655
expect(input).toHaveLength(1)
@@ -81,7 +80,7 @@ describe("translateResponsesResultToAnthropic", () => {
8180
{
8281
id: "reason_1",
8382
type: "reasoning",
84-
summary: [{ type: "text", text: "Thinking about the task." }],
83+
summary: [{ type: "summary_text", text: "Thinking about the task." }],
8584
status: "completed",
8685
encrypted_content: "encrypted_reasoning_content",
8786
},
@@ -116,7 +115,7 @@ describe("translateResponsesResultToAnthropic", () => {
116115
total_tokens: 156,
117116
},
118117
error: null,
119-
incomplete_details: { reason: "tool_use" },
118+
incomplete_details: { reason: "content_filter" },
120119
instructions: null,
121120
metadata: null,
122121
parallel_tool_calls: false,
@@ -129,7 +128,7 @@ describe("translateResponsesResultToAnthropic", () => {
129128
const anthropicResponse =
130129
translateResponsesResultToAnthropic(responsesResult)
131130

132-
expect(anthropicResponse.stop_reason).toBe("tool_use")
131+
expect(anthropicResponse.stop_reason).toBe("end_turn")
133132
expect(anthropicResponse.content).toHaveLength(3)
134133

135134
const [thinkingBlock, toolUseBlock, textBlock] = anthropicResponse.content

0 commit comments

Comments
 (0)