























@@ -78,7 +78,9 @@ const AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS = 30_000;
7878const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
7979const MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS = 64;
8080const RESPONSE_FAILED_NO_DETAILS_MESSAGE = "Unknown error (no error details in response)";
81+const MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS = 256;
8182const log = createSubsystemLogger("openai-transport");
83+const loggedOpenAIStrictToolDowngradeDiagnosticKeys = new Set<string>();
82848385type ReplayableResponseOutputMessage = Omit<ResponseOutputMessage, "id"> & { id?: string };
8486type ReplayableResponseReasoningItem = Omit<ResponseReasoningItem, "id"> & { id?: string };
@@ -976,6 +978,9 @@ function resolveOpenAIStrictToolFlagWithDiagnostics(
976978const strict = resolveOpenAIStrictToolFlagForInventory(tools, strictSetting);
977979if (strictSetting === true && strict === false && log.isEnabled("debug", "any")) {
978980const diagnostics = findOpenAIStrictToolSchemaDiagnostics(tools);
981+if (!shouldLogOpenAIStrictToolDowngradeDiagnostic(diagnostics, context)) {
982+return strict;
983+}
979984const sample = diagnostics.slice(0, 5).map((entry) => ({
980985tool: entry.toolName ?? `tool[${entry.toolIndex}]`,
981986violations: entry.violations.slice(0, 8),
@@ -996,6 +1001,44 @@ function resolveOpenAIStrictToolFlagWithDiagnostics(
9961001return strict;
9971002}
99810031004+function buildOpenAIStrictToolDowngradeDiagnosticKey(
1005+diagnostics: ReturnType<typeof findOpenAIStrictToolSchemaDiagnostics>,
1006+context: { transport: "responses" | "completions"; model: OpenAIModeModel },
1007+): string {
1008+return createHash("sha256")
1009+.update(
1010+JSON.stringify({
1011+transport: context.transport,
1012+provider: context.model.provider ?? null,
1013+model: context.model.id ?? null,
1014+diagnostics: diagnostics.map((entry) => ({
1015+toolIndex: entry.toolIndex,
1016+toolName: entry.toolName ?? null,
1017+violations: entry.violations,
1018+})),
1019+}),
1020+)
1021+.digest("hex");
1022+}
1023+1024+function shouldLogOpenAIStrictToolDowngradeDiagnostic(
1025+diagnostics: ReturnType<typeof findOpenAIStrictToolSchemaDiagnostics>,
1026+context: { transport: "responses" | "completions"; model: OpenAIModeModel },
1027+): boolean {
1028+const key = buildOpenAIStrictToolDowngradeDiagnosticKey(diagnostics, context);
1029+if (loggedOpenAIStrictToolDowngradeDiagnosticKeys.has(key)) {
1030+return false;
1031+}
1032+if (
1033+loggedOpenAIStrictToolDowngradeDiagnosticKeys.size >=
1034+MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS
1035+) {
1036+loggedOpenAIStrictToolDowngradeDiagnosticKeys.clear();
1037+}
1038+loggedOpenAIStrictToolDowngradeDiagnosticKeys.add(key);
1039+return true;
1040+}
1041+9991042function createResponsesFirstEventTimeoutError(model: Model<Api>, timeoutMs: number): Error {
10001043return new Error(
10011044`Azure OpenAI Responses stream did not deliver a first event within ${timeoutMs}ms after HTTP streaming headers. ` +
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。