@ai-sdk/openai 4.0.111 → 4.0.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "4.0.111",
3
+ "version": "4.0.113",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@ai-sdk/provider": "4.0.37",
39
- "@ai-sdk/provider-utils": "5.0.76"
39
+ "@ai-sdk/provider-utils": "5.0.78"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@ai-sdk/test-server": "2.0.4",
@@ -0,0 +1,64 @@
1
+ import { withTelemetryRedaction } from '@ai-sdk/provider-utils';
2
+
3
+ /** OpenAI owns both the SDK configuration paths and their wire equivalents. */
4
+ export function redactOpenAIToolArgs(
5
+ type: unknown,
6
+ args: Record<string, unknown>,
7
+ wireFormat = false,
8
+ ): Record<string, unknown> {
9
+ if (type === 'mcp') {
10
+ return {
11
+ ...args,
12
+ ...(args.authorization != null ? { authorization: '[redacted]' } : {}),
13
+ ...(isRecord(args.headers)
14
+ ? {
15
+ headers: Object.fromEntries(
16
+ Object.keys(args.headers).map(name => [name, '[redacted]']),
17
+ ),
18
+ }
19
+ : {}),
20
+ };
21
+ }
22
+
23
+ const key =
24
+ type === 'code_interpreter'
25
+ ? 'container'
26
+ : type === 'shell'
27
+ ? 'environment'
28
+ : undefined;
29
+ if (key == null || !isRecord(args[key])) return args;
30
+ const container = args[key];
31
+ const policyKey = wireFormat ? 'network_policy' : 'networkPolicy';
32
+ const secretsKey = wireFormat ? 'domain_secrets' : 'domainSecrets';
33
+ const policy = container[policyKey];
34
+ if (!isRecord(policy) || !Array.isArray(policy[secretsKey])) return args;
35
+ return {
36
+ ...args,
37
+ [key]: {
38
+ ...container,
39
+ [policyKey]: {
40
+ ...policy,
41
+ [secretsKey]: policy[secretsKey].map(secret =>
42
+ isRecord(secret) && 'value' in secret
43
+ ? { ...secret, value: '[redacted]' }
44
+ : secret,
45
+ ),
46
+ },
47
+ },
48
+ };
49
+ }
50
+
51
+ /** Preserve raw request/response bodies while providing a safe telemetry view. */
52
+ export function withOpenAIResponseRedaction<T>(value: T): T {
53
+ if (!isRecord(value) || !Array.isArray(value.tools)) return value;
54
+ return withTelemetryRedaction(value, body => ({
55
+ ...body,
56
+ tools: (body.tools as unknown[]).map(tool =>
57
+ isRecord(tool) ? redactOpenAIToolArgs(tool.type, tool, true) : tool,
58
+ ),
59
+ }));
60
+ }
61
+
62
+ function isRecord(value: unknown): value is Record<string, unknown> {
63
+ return value != null && typeof value === 'object' && !Array.isArray(value);
64
+ }
@@ -311,7 +311,7 @@ async function convertFunctionToolResultOutput({
311
311
  }
312
312
 
313
313
  type ParallelToolResultGroup = {
314
- metadata: ParallelToolCallMetadata;
314
+ metadata: ParallelToolCallMetadata & { input: string };
315
315
  results: Array<LanguageModelV4ToolResultPart>;
316
316
  };
317
317
 
@@ -323,7 +323,9 @@ function hasSameParallelToolCall(
323
323
  first.itemId === second.itemId &&
324
324
  first.toolCallId === second.toolCallId &&
325
325
  first.toolName === second.toolName &&
326
- first.input === second.input &&
326
+ (first.input === undefined ||
327
+ second.input === undefined ||
328
+ first.input === second.input) &&
327
329
  first.count === second.count
328
330
  );
329
331
  }
@@ -381,6 +383,12 @@ function collectCompleteParallelToolResultGroups({
381
383
  continue;
382
384
  }
383
385
 
386
+ if (
387
+ existing.metadata.input === undefined &&
388
+ metadata.input !== undefined
389
+ ) {
390
+ existing.metadata = metadata;
391
+ }
384
392
  existing.results.set(metadata.index, part);
385
393
  }
386
394
  }
@@ -388,7 +396,11 @@ function collectCompleteParallelToolResultGroups({
388
396
  const completeGroups = new Map<string, ParallelToolResultGroup>();
389
397
 
390
398
  for (const [toolCallId, group] of pendingGroups) {
391
- if (group.invalid || group.results.size !== group.metadata.count) {
399
+ if (
400
+ group.invalid ||
401
+ group.results.size !== group.metadata.count ||
402
+ group.metadata.input === undefined
403
+ ) {
392
404
  continue;
393
405
  }
394
406
 
@@ -398,7 +410,7 @@ function collectCompleteParallelToolResultGroups({
398
410
 
399
411
  if (results.every(isNonNullable)) {
400
412
  completeGroups.set(toolCallId, {
401
- metadata: group.metadata,
413
+ metadata: { ...group.metadata, input: group.metadata.input },
402
414
  results,
403
415
  });
404
416
  }
@@ -17,7 +17,8 @@ export type ParallelToolCallMetadata = {
17
17
  itemId: string;
18
18
  toolCallId: string;
19
19
  toolName: string;
20
- input: string;
20
+ /** Retained only on the first child; older histories may repeat it. */
21
+ input?: string;
21
22
  index: number;
22
23
  count: number;
23
24
  };
@@ -36,7 +37,7 @@ export function getParallelToolCallMetadata({
36
37
  typeof metadata.itemId !== 'string' ||
37
38
  typeof metadata.toolCallId !== 'string' ||
38
39
  typeof metadata.toolName !== 'string' ||
39
- typeof metadata.input !== 'string' ||
40
+ (metadata.input !== undefined && typeof metadata.input !== 'string') ||
40
41
  typeof metadata.index !== 'number' ||
41
42
  !Number.isInteger(metadata.index) ||
42
43
  typeof metadata.count !== 'number' ||
@@ -129,7 +130,7 @@ export async function expandParallelToolCall({
129
130
  itemId,
130
131
  toolCallId: toolCall.toolCallId,
131
132
  toolName: toolCall.toolName,
132
- input: toolCall.input,
133
+ ...(index === 0 && { input: toolCall.input }),
133
134
  index,
134
135
  count: toolUses.length,
135
136
  } satisfies ParallelToolCallMetadata,
@@ -32,6 +32,7 @@ import {
32
32
  type ParseResult,
33
33
  } from '@ai-sdk/provider-utils';
34
34
  import { normalizeOpenAIJsonSchema } from '../normalize-openai-json-schema';
35
+ import { withOpenAIResponseRedaction } from '../redact-openai-tool-credentials';
35
36
  import {
36
37
  prepareOpenAIConfigForWorkflowDeserialize,
37
38
  type OpenAIConfig,
@@ -809,11 +810,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
809
810
 
810
811
  return {
811
812
  webSearchToolName,
812
- args: {
813
+ args: withOpenAIResponseRedaction({
813
814
  ...baseArgs,
814
815
  tools: openaiTools,
815
816
  tool_choice: openaiToolChoice,
816
- },
817
+ }),
817
818
  warnings: [...warnings, ...toolWarnings],
818
819
  store,
819
820
  toolNameMapping,
@@ -1559,7 +1560,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
1559
1560
  timestamp: new Date(response.created_at! * 1000),
1560
1561
  modelId: response.model,
1561
1562
  headers: responseHeaders,
1562
- body: rawResponse,
1563
+ body: withOpenAIResponseRedaction(rawResponse),
1563
1564
  },
1564
1565
  providerMetadata,
1565
1566
  warnings,
@@ -1590,10 +1591,10 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
1590
1591
  await resolve(this.config.headers),
1591
1592
  options.headers,
1592
1593
  ),
1593
- body: {
1594
+ body: withOpenAIResponseRedaction({
1594
1595
  ...body,
1595
1596
  stream: true,
1596
- },
1597
+ }),
1597
1598
  failedResponseHandler: openaiFailedResponseHandler,
1598
1599
  successfulResponseHandler: createEventSourceResponseHandler(
1599
1600
  openaiResponsesChunkSchema,
@@ -4,6 +4,7 @@ import {
4
4
  zodSchema,
5
5
  } from '@ai-sdk/provider-utils';
6
6
  import { z } from 'zod/v4';
7
+ import { redactOpenAIToolArgs } from '../redact-openai-tool-credentials';
7
8
 
8
9
  export const codeInterpreterInputSchema = lazySchema(() =>
9
10
  zodSchema(
@@ -128,6 +129,7 @@ export const codeInterpreterToolFactory = createProviderExecutedToolFactory<
128
129
  CodeInterpreterArgs
129
130
  >({
130
131
  id: 'openai.code_interpreter',
132
+ redactArgs: args => redactOpenAIToolArgs('code_interpreter', args),
131
133
  inputSchema: codeInterpreterInputSchema,
132
134
  outputSchema: codeInterpreterOutputSchema,
133
135
  });
package/src/tool/mcp.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  } from '@ai-sdk/provider-utils';
6
6
  import type { JSONValue } from '@ai-sdk/provider';
7
7
  import { z } from 'zod/v4';
8
+ import { redactOpenAIToolArgs } from '../redact-openai-tool-credentials';
8
9
 
9
10
  let cachedJsonValueSchema: z.ZodType<JSONValue> | undefined;
10
11
  const jsonValueSchema = (): z.ZodType<JSONValue> =>
@@ -139,6 +140,7 @@ export const mcpToolFactory = createProviderExecutedToolFactory<
139
140
  McpArgs
140
141
  >({
141
142
  id: 'openai.mcp',
143
+ redactArgs: args => redactOpenAIToolArgs('mcp', args),
142
144
  inputSchema: mcpInputSchema,
143
145
  outputSchema: mcpOutputSchema,
144
146
  });
package/src/tool/shell.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  } from '@ai-sdk/provider-utils';
6
6
  import type { SharedV4ProviderReference } from '@ai-sdk/provider';
7
7
  import { z } from 'zod/v4';
8
+ import { redactOpenAIToolArgs } from '../redact-openai-tool-credentials';
8
9
 
9
10
  export const shellInputSchema = lazySchema(() =>
10
11
  zodSchema(
@@ -210,6 +211,7 @@ export const shell = createProviderDefinedToolFactoryWithOutputSchema<
210
211
  ShellArgs
211
212
  >({
212
213
  id: 'openai.shell',
214
+ redactArgs: args => redactOpenAIToolArgs('shell', args),
213
215
  inputSchema: shellInputSchema,
214
216
  outputSchema: shellOutputSchema,
215
217
  });