Skip to content

Commit c3600b0

Browse files
embed #9535
1 parent e284a46 commit c3600b0

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

libs/langchain/src/agents/nodes/AgentNode.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -835,13 +835,18 @@ export class AgentNode<
835835
* check if the user requests a native schema output
836836
*/
837837
if (structuredResponseFormat?.type === "native") {
838+
const resolvedStrict =
839+
preparedOptions?.modelSettings?.strict ??
840+
structuredResponseFormat?.strategy?.strict ??
841+
true;
842+
838843
const jsonSchemaParams = {
839844
name: structuredResponseFormat.strategy.schema?.name ?? "extract",
840845
description: getSchemaDescription(
841846
structuredResponseFormat.strategy.schema
842847
),
843848
schema: structuredResponseFormat.strategy.schema,
844-
strict: structuredResponseFormat.strategy.strict,
849+
strict: resolvedStrict,
845850
};
846851

847852
Object.assign(options, {
@@ -860,7 +865,7 @@ export class AgentNode<
860865
kwargs: { method: "json_schema" },
861866
schema: structuredResponseFormat.strategy.schema,
862867
},
863-
strict: true,
868+
strict: resolvedStrict,
864869
});
865870
}
866871

libs/providers/langchain-openai/src/chat_models/responses.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ export class ChatOpenAIResponses<
7373
let strict: boolean | undefined;
7474
if (options?.strict !== undefined) {
7575
strict = options.strict;
76-
} else if (this.supportsStrictToolCalling !== undefined) {
76+
}
77+
if (strict === undefined && this.supportsStrictToolCalling !== undefined) {
7778
strict = this.supportsStrictToolCalling;
7879
}
7980

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { describe, it, expect } from "vitest";
2+
import { ChatOpenAIResponses } from "../responses.js";
3+
4+
describe("strict tool-calling configuration", () => {
5+
it("falls back to supportsStrictToolCalling when strict is undefined", () => {
6+
const model = new ChatOpenAIResponses({
7+
model: "gpt-4o",
8+
supportsStrictToolCalling: true,
9+
});
10+
11+
const params = model.invocationParams({
12+
tools: [
13+
{
14+
type: "function",
15+
function: {
16+
name: "test_func",
17+
description: "testing",
18+
parameters: { type: "object", properties: {} },
19+
},
20+
},
21+
],
22+
});
23+
24+
expect("strict" in params).toBe(false);
25+
26+
expect((params.tools as Array<{ strict?: boolean }>)[0].strict).toBe(true);
27+
});
28+
29+
it("respects user-provided strict option", () => {
30+
const model = new ChatOpenAIResponses({
31+
model: "gpt-4o",
32+
supportsStrictToolCalling: true,
33+
});
34+
35+
const params = model.invocationParams({
36+
strict: false,
37+
tools: [
38+
{
39+
type: "function",
40+
function: {
41+
name: "test_func",
42+
description: "testing",
43+
parameters: { type: "object", properties: {} },
44+
},
45+
},
46+
],
47+
});
48+
49+
expect("strict" in params).toBe(false);
50+
51+
expect((params.tools as Array<{ strict?: boolean }>)[0].strict).toBe(false);
52+
});
53+
});

0 commit comments

Comments
 (0)