






















@@ -5683,6 +5683,66 @@ describe("openai transport stream", () => {
56835683expect(params.tools?.[0]).not.toHaveProperty("strict");
56845684});
568556855686+it("keeps native responses strict mode for projected tools after dropping bad schemas", () => {
5687+const params = buildOpenAIResponsesParams(
5688+{
5689+id: "gpt-5.4",
5690+name: "GPT-5.4",
5691+api: "openai-responses",
5692+provider: "openai",
5693+baseUrl: "https://api.openai.com/v1",
5694+reasoning: true,
5695+input: ["text"],
5696+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
5697+contextWindow: 200000,
5698+maxTokens: 8192,
5699+} satisfies Model<"openai-responses">,
5700+{
5701+systemPrompt: "system",
5702+messages: [],
5703+tools: [
5704+{
5705+name: "broken",
5706+description: "Broken",
5707+parameters: {
5708+type: "object",
5709+get properties(): never {
5710+throw new Error("properties exploded");
5711+},
5712+},
5713+},
5714+{
5715+name: "lookup_weather",
5716+description: "Get forecast",
5717+parameters: {},
5718+},
5719+],
5720+} as never,
5721+undefined,
5722+) as {
5723+tools?: Array<{
5724+name?: string;
5725+strict?: boolean;
5726+parameters?: Record<string, unknown>;
5727+}>;
5728+};
5729+5730+expect(params.tools).toEqual([
5731+{
5732+type: "function",
5733+name: "lookup_weather",
5734+description: "Get forecast",
5735+strict: true,
5736+parameters: {
5737+type: "object",
5738+properties: {},
5739+required: [],
5740+additionalProperties: false,
5741+},
5742+},
5743+]);
5744+});
5745+56865746it("still normalizes responses tool parameters when strict is omitted", () => {
56875747const params = buildOpenAIResponsesParams(
56885748{
@@ -7401,6 +7461,67 @@ describe("openai transport stream", () => {
74017461expect(params.tools?.[0]?.function?.strict).toBe(true);
74027462});
740374637464+it("keeps native completions strict mode for projected tools after dropping bad schemas", () => {
7465+const params = buildOpenAICompletionsParams(
7466+{
7467+id: "gpt-5",
7468+name: "GPT-5",
7469+api: "openai-completions",
7470+provider: "openai",
7471+baseUrl: "https://api.openai.com/v1",
7472+reasoning: true,
7473+input: ["text"],
7474+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
7475+contextWindow: 200000,
7476+maxTokens: 8192,
7477+} satisfies Model<"openai-completions">,
7478+{
7479+systemPrompt: "system",
7480+messages: [],
7481+tools: [
7482+{
7483+name: "broken",
7484+description: "Broken",
7485+parameters: {
7486+type: "object",
7487+get properties(): never {
7488+throw new Error("properties exploded");
7489+},
7490+},
7491+},
7492+{
7493+name: "lookup_weather",
7494+description: "Get forecast",
7495+parameters: {},
7496+},
7497+],
7498+} as never,
7499+undefined,
7500+) as {
7501+tools?: Array<{
7502+function?: {
7503+name?: string;
7504+strict?: boolean;
7505+parameters?: Record<string, unknown>;
7506+};
7507+}>;
7508+};
7509+7510+expect(params.tools?.map((tool) => tool.function)).toEqual([
7511+{
7512+name: "lookup_weather",
7513+description: "Get forecast",
7514+strict: true,
7515+parameters: {
7516+type: "object",
7517+properties: {},
7518+required: [],
7519+additionalProperties: false,
7520+},
7521+},
7522+]);
7523+});
7524+74047525it("falls back to completions strict:false when a native OpenAI tool schema is not strict-compatible", () => {
74057526const params = buildOpenAICompletionsParams(
74067527{
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。