Skip to content

Commit dc530dc

Browse files
committed
support chat completions json_object with tool call
for anthropic and openai-format models that do not natively support structured output.
1 parent 6418a0a commit dc530dc

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

packages/proxy/src/proxy.ts

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,6 +1713,7 @@ async function fetchOpenAI(
17131713
delete bodyData.response_format;
17141714
break;
17151715
case "json_schema":
1716+
case "json_object":
17161717
if (
17171718
bodyData.model.startsWith("gpt") ||
17181719
bodyData.model.startsWith("o1") ||
@@ -1734,8 +1735,20 @@ async function fetchOpenAI(
17341735
function: {
17351736
name: "json",
17361737
description: "Output the result in JSON format",
1737-
parameters: responseFormatParsed.data.json_schema.schema,
1738-
strict: responseFormatParsed.data.json_schema.strict,
1738+
parameters:
1739+
responseFormatParsed.data.type === "json_schema"
1740+
? responseFormatParsed.data.json_schema.schema
1741+
: {
1742+
type: "object",
1743+
description:
1744+
"A flexible schema that accepts any JSON object.",
1745+
properties: {},
1746+
additionalProperties: true,
1747+
},
1748+
strict:
1749+
responseFormatParsed.data.type === "json_schema"
1750+
? responseFormatParsed.data.json_schema.strict
1751+
: false,
17391752
},
17401753
},
17411754
];
@@ -1745,6 +1758,11 @@ async function fetchOpenAI(
17451758
}
17461759
}
17471760

1761+
console.log("fetching openai:", {
1762+
fullURL: fullURL.toString(),
1763+
headers,
1764+
body: JSON.stringify(bodyData),
1765+
});
17481766
const proxyResponse = await fetch(
17491767
fullURL.toString(),
17501768
method === "POST"
@@ -2113,7 +2131,10 @@ async function fetchAnthropicChatCompletions({
21132131

21142132
let isStructuredOutput = false;
21152133
const parsed = responseFormatSchema.safeParse(oaiParams.response_format);
2116-
if (parsed.success && parsed.data.type === "json_schema") {
2134+
if (
2135+
parsed.success &&
2136+
(parsed.data.type === "json_schema" || parsed.data.type === "json_object")
2137+
) {
21172138
isStructuredOutput = true;
21182139
if (params.tools || params.tool_choice) {
21192140
throw new ProxyBadRequestError(
@@ -2124,7 +2145,15 @@ async function fetchAnthropicChatCompletions({
21242145
{
21252146
name: "json",
21262147
description: "Output the result in JSON format",
2127-
input_schema: parsed.data.json_schema.schema,
2148+
input_schema:
2149+
parsed.data.type === "json_schema"
2150+
? parsed.data.json_schema.schema
2151+
: {
2152+
type: "object",
2153+
description: "A flexible schema that accepts any JSON object.",
2154+
properties: {},
2155+
additionalProperties: true,
2156+
},
21282157
},
21292158
];
21302159
params.tool_choice = { type: "tool", name: "json" };
@@ -2155,6 +2184,15 @@ async function fetchAnthropicChatCompletions({
21552184
delete params.model;
21562185
}
21572186

2187+
console.log("fetching anthropic:", {
2188+
fullURL: fullURL.toString(),
2189+
headers,
2190+
body: JSON.stringify({
2191+
messages,
2192+
system,
2193+
...params,
2194+
}),
2195+
});
21582196
const proxyResponse = await fetch(fullURL.toString(), {
21592197
method: "POST",
21602198
headers,

0 commit comments

Comments
 (0)