@ai-sdk/openai 4.0.0-beta.11 → 4.0.0-beta.13
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/CHANGELOG.md +48 -33
- package/dist/index.d.mts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +110 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +112 -27
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +17 -1
- package/dist/internal/index.d.ts +17 -1
- package/dist/internal/index.js +109 -26
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +111 -26
- package/dist/internal/index.mjs.map +1 -1
- package/docs/03-openai.mdx +124 -0
- package/package.json +3 -5
- package/src/chat/openai-chat-language-model.ts +10 -2
- package/src/index.ts +1 -0
- package/src/responses/convert-to-openai-responses-input.ts +35 -4
- package/src/responses/openai-responses-api.ts +23 -1
- package/src/responses/openai-responses-language-model.ts +46 -4
- package/src/responses/openai-responses-options.ts +12 -0
- package/src/responses/openai-responses-provider-metadata.ts +10 -0
package/docs/03-openai.mdx
CHANGED
|
@@ -257,6 +257,11 @@ The following provider options are available:
|
|
|
257
257
|
- **forceReasoning** _boolean_
|
|
258
258
|
Force treating this model as a reasoning model. This is useful for "stealth" reasoning models (e.g. via a custom baseURL) where the model ID is not recognized by the SDK's allowlist. When enabled, the SDK applies reasoning-model parameter compatibility rules and defaults `systemMessageMode` to `developer` unless overridden.
|
|
259
259
|
|
|
260
|
+
- **contextManagement** _Array<object>_
|
|
261
|
+
Enable server-side context management (compaction). When configured, the server automatically compresses conversation context when token usage crosses a specified threshold. Each object in the array should have:
|
|
262
|
+
- `type`: `'compaction'`
|
|
263
|
+
- `compactThreshold`: _number_ — the token count at which compaction is triggered
|
|
264
|
+
|
|
260
265
|
The OpenAI responses provider also returns provider-specific metadata:
|
|
261
266
|
|
|
262
267
|
For Responses models, you can type this metadata using `OpenaiResponsesProviderMetadata`:
|
|
@@ -1511,6 +1516,125 @@ for (const part of result.content) {
|
|
|
1511
1516
|
are fields like `filename` that are directly available on the source object.
|
|
1512
1517
|
</Note>
|
|
1513
1518
|
|
|
1519
|
+
#### Compaction
|
|
1520
|
+
|
|
1521
|
+
The OpenAI Responses API supports server-side context compaction. When enabled, the server automatically compresses conversation context when token usage crosses a configured threshold. This is useful for long-running conversations or agent loops where you want to stay within token limits without manually managing context.
|
|
1522
|
+
|
|
1523
|
+
The compaction item returned by the server is opaque and encrypted — it carries forward key prior state and reasoning into the next turn using fewer tokens. The AI SDK handles this automatically: compaction items are returned as text parts with special `providerMetadata`, and when passed back in subsequent requests they are sent as compaction input items.
|
|
1524
|
+
|
|
1525
|
+
```ts highlight="7-11"
|
|
1526
|
+
import {
|
|
1527
|
+
openai,
|
|
1528
|
+
type OpenAILanguageModelResponsesOptions,
|
|
1529
|
+
} from '@ai-sdk/openai';
|
|
1530
|
+
import { generateText } from 'ai';
|
|
1531
|
+
|
|
1532
|
+
const result = await generateText({
|
|
1533
|
+
model: openai.responses('gpt-5.2'),
|
|
1534
|
+
messages: conversationHistory,
|
|
1535
|
+
providerOptions: {
|
|
1536
|
+
openai: {
|
|
1537
|
+
store: false,
|
|
1538
|
+
contextManagement: [{ type: 'compaction', compactThreshold: 50000 }],
|
|
1539
|
+
} satisfies OpenAILanguageModelResponsesOptions,
|
|
1540
|
+
},
|
|
1541
|
+
});
|
|
1542
|
+
```
|
|
1543
|
+
|
|
1544
|
+
**Configuration:**
|
|
1545
|
+
|
|
1546
|
+
- **type** — Must be `'compaction'`
|
|
1547
|
+
- **compactThreshold** — The token count at which compaction is triggered. When the rendered input token count crosses this threshold, the server runs a compaction pass before continuing inference.
|
|
1548
|
+
|
|
1549
|
+
<Note>
|
|
1550
|
+
Server-side compaction is ZDR-friendly when you set `store: false` on your
|
|
1551
|
+
requests.
|
|
1552
|
+
</Note>
|
|
1553
|
+
|
|
1554
|
+
##### Detecting Compaction in Streams
|
|
1555
|
+
|
|
1556
|
+
When using `streamText`, you can detect compaction by checking the `providerMetadata` on `text-start` and `text-end` events:
|
|
1557
|
+
|
|
1558
|
+
```ts
|
|
1559
|
+
import {
|
|
1560
|
+
openai,
|
|
1561
|
+
type OpenAILanguageModelResponsesOptions,
|
|
1562
|
+
} from '@ai-sdk/openai';
|
|
1563
|
+
import { streamText } from 'ai';
|
|
1564
|
+
|
|
1565
|
+
const result = streamText({
|
|
1566
|
+
model: openai.responses('gpt-5.2'),
|
|
1567
|
+
messages: conversationHistory,
|
|
1568
|
+
providerOptions: {
|
|
1569
|
+
openai: {
|
|
1570
|
+
store: false,
|
|
1571
|
+
contextManagement: [{ type: 'compaction', compactThreshold: 50000 }],
|
|
1572
|
+
} satisfies OpenAILanguageModelResponsesOptions,
|
|
1573
|
+
},
|
|
1574
|
+
});
|
|
1575
|
+
|
|
1576
|
+
for await (const part of result.fullStream) {
|
|
1577
|
+
switch (part.type) {
|
|
1578
|
+
case 'text-start': {
|
|
1579
|
+
const isCompaction = part.providerMetadata?.openai?.type === 'compaction';
|
|
1580
|
+
if (isCompaction) {
|
|
1581
|
+
// ... your logic
|
|
1582
|
+
}
|
|
1583
|
+
break;
|
|
1584
|
+
}
|
|
1585
|
+
case 'text-end': {
|
|
1586
|
+
const isCompaction = part.providerMetadata?.openai?.type === 'compaction';
|
|
1587
|
+
if (isCompaction) {
|
|
1588
|
+
// ... your logic
|
|
1589
|
+
}
|
|
1590
|
+
break;
|
|
1591
|
+
}
|
|
1592
|
+
case 'text-delta': {
|
|
1593
|
+
process.stdout.write(part.text);
|
|
1594
|
+
break;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
```
|
|
1599
|
+
|
|
1600
|
+
##### Compaction in UI Applications
|
|
1601
|
+
|
|
1602
|
+
When using `useChat` or other UI hooks, compaction items appear as text parts with `providerMetadata`. You can detect and style them differently in your UI:
|
|
1603
|
+
|
|
1604
|
+
```tsx
|
|
1605
|
+
{
|
|
1606
|
+
message.parts.map((part, index) => {
|
|
1607
|
+
if (part.type === 'text') {
|
|
1608
|
+
const isCompaction =
|
|
1609
|
+
(part.providerMetadata?.openai as { type?: string } | undefined)
|
|
1610
|
+
?.type === 'compaction';
|
|
1611
|
+
|
|
1612
|
+
if (isCompaction) {
|
|
1613
|
+
return (
|
|
1614
|
+
<div
|
|
1615
|
+
key={index}
|
|
1616
|
+
className="bg-yellow-100 border-l-4 border-yellow-500 p-2"
|
|
1617
|
+
>
|
|
1618
|
+
<span className="font-bold">[Context Compacted]</span>
|
|
1619
|
+
<p className="text-sm text-yellow-700">
|
|
1620
|
+
The server compressed the conversation context to reduce token
|
|
1621
|
+
usage.
|
|
1622
|
+
</p>
|
|
1623
|
+
</div>
|
|
1624
|
+
);
|
|
1625
|
+
}
|
|
1626
|
+
return <div key={index}>{part.text}</div>;
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
```
|
|
1631
|
+
|
|
1632
|
+
The metadata includes the following fields:
|
|
1633
|
+
|
|
1634
|
+
- **type** — Always `'compaction'`
|
|
1635
|
+
- **itemId** _string_ — The ID of the compaction item in the Responses API
|
|
1636
|
+
- **encryptedContent** _string_ (optional) — The encrypted compaction state. This is automatically sent back to the API when the message is included in subsequent requests.
|
|
1637
|
+
|
|
1514
1638
|
### Chat Models
|
|
1515
1639
|
|
|
1516
1640
|
You can create models that call the [OpenAI chat API](https://platform.openai.com/docs/api-reference/chat) using the `.chat()` factory method.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/openai",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.13",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@ai-sdk/provider": "4.0.0-beta.
|
|
40
|
-
"@ai-sdk/provider-utils": "5.0.0-beta.
|
|
39
|
+
"@ai-sdk/provider": "4.0.0-beta.4",
|
|
40
|
+
"@ai-sdk/provider-utils": "5.0.0-beta.6"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "20.17.24",
|
|
@@ -71,9 +71,7 @@
|
|
|
71
71
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
72
72
|
"build:watch": "pnpm clean && tsup --watch",
|
|
73
73
|
"clean": "del-cli dist docs *.tsbuildinfo",
|
|
74
|
-
"lint": "eslint \"./**/*.ts*\"",
|
|
75
74
|
"type-check": "tsc --build",
|
|
76
|
-
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
77
75
|
"test": "pnpm test:node && pnpm test:edge",
|
|
78
76
|
"test:update": "pnpm test:node -u",
|
|
79
77
|
"test:watch": "vitest --config vitest.node.config.js",
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
createEventSourceResponseHandler,
|
|
18
18
|
createJsonResponseHandler,
|
|
19
19
|
generateId,
|
|
20
|
+
isCustomReasoning,
|
|
20
21
|
isParsableJson,
|
|
21
22
|
parseProviderOptions,
|
|
22
23
|
postJsonToApi,
|
|
@@ -81,6 +82,7 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
|
|
|
81
82
|
seed,
|
|
82
83
|
tools,
|
|
83
84
|
toolChoice,
|
|
85
|
+
reasoning,
|
|
84
86
|
providerOptions,
|
|
85
87
|
}: LanguageModelV4CallOptions) {
|
|
86
88
|
const warnings: SharedV4Warning[] = [];
|
|
@@ -94,6 +96,12 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
|
|
|
94
96
|
})) ?? {};
|
|
95
97
|
|
|
96
98
|
const modelCapabilities = getOpenAILanguageModelCapabilities(this.modelId);
|
|
99
|
+
|
|
100
|
+
// AI SDK reasoning values map directly to the OpenAI reasoning values.
|
|
101
|
+
const resolvedReasoningEffort =
|
|
102
|
+
openaiOptions.reasoningEffort ??
|
|
103
|
+
(isCustomReasoning(reasoning) ? reasoning : undefined);
|
|
104
|
+
|
|
97
105
|
const isReasoningModel =
|
|
98
106
|
openaiOptions.forceReasoning ?? modelCapabilities.isReasoningModel;
|
|
99
107
|
|
|
@@ -168,7 +176,7 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
|
|
|
168
176
|
store: openaiOptions.store,
|
|
169
177
|
metadata: openaiOptions.metadata,
|
|
170
178
|
prediction: openaiOptions.prediction,
|
|
171
|
-
reasoning_effort:
|
|
179
|
+
reasoning_effort: resolvedReasoningEffort,
|
|
172
180
|
service_tier: openaiOptions.serviceTier,
|
|
173
181
|
prompt_cache_key: openaiOptions.promptCacheKey,
|
|
174
182
|
prompt_cache_retention: openaiOptions.promptCacheRetention,
|
|
@@ -184,7 +192,7 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
|
|
|
184
192
|
// when reasoning effort is none, gpt-5.1 models allow temperature, topP, logprobs
|
|
185
193
|
// https://platform.openai.com/docs/guides/latest-model#gpt-5-1-parameter-compatibility
|
|
186
194
|
if (
|
|
187
|
-
|
|
195
|
+
resolvedReasoningEffort !== 'none' ||
|
|
188
196
|
!modelCapabilities.supportsNonReasoningParameters
|
|
189
197
|
) {
|
|
190
198
|
if (baseArgs.temperature != null) {
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type { OpenAIEmbeddingModelOptions } from './embedding/openai-embedding-o
|
|
|
15
15
|
export type { OpenAISpeechModelOptions } from './speech/openai-speech-options';
|
|
16
16
|
export type { OpenAITranscriptionModelOptions } from './transcription/openai-transcription-options';
|
|
17
17
|
export type {
|
|
18
|
+
OpenaiResponsesCompactionProviderMetadata,
|
|
18
19
|
OpenaiResponsesProviderMetadata,
|
|
19
20
|
OpenaiResponsesReasoningProviderMetadata,
|
|
20
21
|
OpenaiResponsesTextProviderMetadata,
|
|
@@ -23,15 +23,16 @@ import {
|
|
|
23
23
|
} from '../tool/local-shell';
|
|
24
24
|
import { shellInputSchema, shellOutputSchema } from '../tool/shell';
|
|
25
25
|
import {
|
|
26
|
-
|
|
27
|
-
toolSearchOutputSchema,
|
|
28
|
-
} from '../tool/tool-search';
|
|
29
|
-
import {
|
|
26
|
+
OpenAIResponsesCompactionItem,
|
|
30
27
|
OpenAIResponsesCustomToolCallOutput,
|
|
31
28
|
OpenAIResponsesFunctionCallOutput,
|
|
32
29
|
OpenAIResponsesInput,
|
|
33
30
|
OpenAIResponsesReasoning,
|
|
34
31
|
} from './openai-responses-api';
|
|
32
|
+
import {
|
|
33
|
+
toolSearchInputSchema,
|
|
34
|
+
toolSearchOutputSchema,
|
|
35
|
+
} from '../tool/tool-search';
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* Check if a string is a file ID based on the given prefixes
|
|
@@ -543,6 +544,36 @@ export async function convertToOpenAIResponsesInput({
|
|
|
543
544
|
}
|
|
544
545
|
break;
|
|
545
546
|
}
|
|
547
|
+
|
|
548
|
+
case 'custom': {
|
|
549
|
+
if (part.kind === 'openai-compaction') {
|
|
550
|
+
const providerOpts =
|
|
551
|
+
part.providerOptions?.[providerOptionsName];
|
|
552
|
+
const id = providerOpts?.itemId as string | undefined;
|
|
553
|
+
|
|
554
|
+
if (hasConversation && id != null) {
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (store && id != null) {
|
|
559
|
+
input.push({ type: 'item_reference', id });
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const encryptedContent = providerOpts?.encryptedContent as
|
|
564
|
+
| string
|
|
565
|
+
| undefined;
|
|
566
|
+
|
|
567
|
+
if (id != null) {
|
|
568
|
+
input.push({
|
|
569
|
+
type: 'compaction',
|
|
570
|
+
id,
|
|
571
|
+
encrypted_content: encryptedContent!,
|
|
572
|
+
} satisfies OpenAIResponsesCompactionItem);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
break;
|
|
576
|
+
}
|
|
546
577
|
}
|
|
547
578
|
}
|
|
548
579
|
|
|
@@ -34,7 +34,8 @@ export type OpenAIResponsesInputItem =
|
|
|
34
34
|
| OpenAIResponsesToolSearchCall
|
|
35
35
|
| OpenAIResponsesToolSearchOutput
|
|
36
36
|
| OpenAIResponsesReasoning
|
|
37
|
-
| OpenAIResponsesItemReference
|
|
37
|
+
| OpenAIResponsesItemReference
|
|
38
|
+
| OpenAIResponsesCompactionItem;
|
|
38
39
|
|
|
39
40
|
export type OpenAIResponsesIncludeValue =
|
|
40
41
|
| 'web_search_call.action.sources'
|
|
@@ -235,6 +236,12 @@ export type OpenAIResponsesItemReference = {
|
|
|
235
236
|
id: string;
|
|
236
237
|
};
|
|
237
238
|
|
|
239
|
+
export type OpenAIResponsesCompactionItem = {
|
|
240
|
+
type: 'compaction';
|
|
241
|
+
id: string;
|
|
242
|
+
encrypted_content: string;
|
|
243
|
+
};
|
|
244
|
+
|
|
238
245
|
/**
|
|
239
246
|
* A filter used to compare a specified attribute key to a given value using a defined comparison operation.
|
|
240
247
|
*/
|
|
@@ -611,6 +618,11 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
611
618
|
commands: z.array(z.string()),
|
|
612
619
|
}),
|
|
613
620
|
}),
|
|
621
|
+
z.object({
|
|
622
|
+
type: z.literal('compaction'),
|
|
623
|
+
id: z.string(),
|
|
624
|
+
encrypted_content: z.string().nullish(),
|
|
625
|
+
}),
|
|
614
626
|
z.object({
|
|
615
627
|
type: z.literal('shell_call_output'),
|
|
616
628
|
id: z.string(),
|
|
@@ -850,6 +862,11 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
850
862
|
commands: z.array(z.string()),
|
|
851
863
|
}),
|
|
852
864
|
}),
|
|
865
|
+
z.object({
|
|
866
|
+
type: z.literal('compaction'),
|
|
867
|
+
id: z.string(),
|
|
868
|
+
encrypted_content: z.string(),
|
|
869
|
+
}),
|
|
853
870
|
z.object({
|
|
854
871
|
type: z.literal('shell_call_output'),
|
|
855
872
|
id: z.string(),
|
|
@@ -1289,6 +1306,11 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
|
|
|
1289
1306
|
commands: z.array(z.string()),
|
|
1290
1307
|
}),
|
|
1291
1308
|
}),
|
|
1309
|
+
z.object({
|
|
1310
|
+
type: z.literal('compaction'),
|
|
1311
|
+
id: z.string(),
|
|
1312
|
+
encrypted_content: z.string(),
|
|
1313
|
+
}),
|
|
1292
1314
|
z.object({
|
|
1293
1315
|
type: z.literal('shell_call_output'),
|
|
1294
1316
|
id: z.string(),
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
createToolNameMapping,
|
|
22
22
|
generateId,
|
|
23
23
|
InferSchema,
|
|
24
|
+
isCustomReasoning,
|
|
24
25
|
parseProviderOptions,
|
|
25
26
|
ParseResult,
|
|
26
27
|
postJsonToApi,
|
|
@@ -67,6 +68,7 @@ import {
|
|
|
67
68
|
} from './openai-responses-options';
|
|
68
69
|
import { prepareResponsesTools } from './openai-responses-prepare-tools';
|
|
69
70
|
import {
|
|
71
|
+
ResponsesCompactionProviderMetadata,
|
|
70
72
|
ResponsesProviderMetadata,
|
|
71
73
|
ResponsesReasoningProviderMetadata,
|
|
72
74
|
ResponsesSourceDocumentProviderMetadata,
|
|
@@ -129,6 +131,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
129
131
|
frequencyPenalty,
|
|
130
132
|
seed,
|
|
131
133
|
prompt,
|
|
134
|
+
reasoning,
|
|
132
135
|
providerOptions,
|
|
133
136
|
tools,
|
|
134
137
|
toolChoice,
|
|
@@ -174,6 +177,10 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
174
177
|
});
|
|
175
178
|
}
|
|
176
179
|
|
|
180
|
+
const resolvedReasoningEffort =
|
|
181
|
+
openaiOptions?.reasoningEffort ??
|
|
182
|
+
(isCustomReasoning(reasoning) ? reasoning : undefined);
|
|
183
|
+
|
|
177
184
|
const isReasoningModel =
|
|
178
185
|
openaiOptions?.forceReasoning ?? modelCapabilities.isReasoningModel;
|
|
179
186
|
|
|
@@ -337,13 +344,21 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
337
344
|
top_logprobs: topLogprobs,
|
|
338
345
|
truncation: openaiOptions?.truncation,
|
|
339
346
|
|
|
347
|
+
// context management (server-side compaction):
|
|
348
|
+
...(openaiOptions?.contextManagement && {
|
|
349
|
+
context_management: openaiOptions.contextManagement.map(cm => ({
|
|
350
|
+
type: cm.type,
|
|
351
|
+
compact_threshold: cm.compactThreshold,
|
|
352
|
+
})),
|
|
353
|
+
}),
|
|
354
|
+
|
|
340
355
|
// model-specific settings:
|
|
341
356
|
...(isReasoningModel &&
|
|
342
|
-
(
|
|
357
|
+
(resolvedReasoningEffort != null ||
|
|
343
358
|
openaiOptions?.reasoningSummary != null) && {
|
|
344
359
|
reasoning: {
|
|
345
|
-
...(
|
|
346
|
-
effort:
|
|
360
|
+
...(resolvedReasoningEffort != null && {
|
|
361
|
+
effort: resolvedReasoningEffort,
|
|
347
362
|
}),
|
|
348
363
|
...(openaiOptions?.reasoningSummary != null && {
|
|
349
364
|
summary: openaiOptions.reasoningSummary,
|
|
@@ -359,7 +374,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
359
374
|
// https://platform.openai.com/docs/guides/latest-model#gpt-5-1-parameter-compatibility
|
|
360
375
|
if (
|
|
361
376
|
!(
|
|
362
|
-
|
|
377
|
+
resolvedReasoningEffort === 'none' &&
|
|
363
378
|
modelCapabilities.supportsNonReasoningParameters
|
|
364
379
|
)
|
|
365
380
|
) {
|
|
@@ -977,6 +992,21 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
977
992
|
|
|
978
993
|
break;
|
|
979
994
|
}
|
|
995
|
+
|
|
996
|
+
case 'compaction': {
|
|
997
|
+
content.push({
|
|
998
|
+
type: 'custom',
|
|
999
|
+
kind: 'openai-compaction',
|
|
1000
|
+
providerMetadata: {
|
|
1001
|
+
[providerOptionsName]: {
|
|
1002
|
+
type: 'compaction',
|
|
1003
|
+
itemId: part.id,
|
|
1004
|
+
encryptedContent: part.encrypted_content,
|
|
1005
|
+
} satisfies ResponsesCompactionProviderMetadata,
|
|
1006
|
+
},
|
|
1007
|
+
});
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
980
1010
|
}
|
|
981
1011
|
}
|
|
982
1012
|
|
|
@@ -1782,6 +1812,18 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1782
1812
|
}
|
|
1783
1813
|
|
|
1784
1814
|
delete activeReasoning[value.item.id];
|
|
1815
|
+
} else if (value.item.type === 'compaction') {
|
|
1816
|
+
controller.enqueue({
|
|
1817
|
+
type: 'custom',
|
|
1818
|
+
kind: 'openai-compaction',
|
|
1819
|
+
providerMetadata: {
|
|
1820
|
+
[providerOptionsName]: {
|
|
1821
|
+
type: 'compaction',
|
|
1822
|
+
itemId: value.item.id,
|
|
1823
|
+
encryptedContent: value.item.encrypted_content,
|
|
1824
|
+
} satisfies ResponsesCompactionProviderMetadata,
|
|
1825
|
+
},
|
|
1826
|
+
});
|
|
1785
1827
|
}
|
|
1786
1828
|
} else if (isResponseFunctionCallArgumentsDeltaChunk(value)) {
|
|
1787
1829
|
const toolCall = ongoingToolCalls[value.output_index];
|
|
@@ -300,6 +300,18 @@ export const openaiLanguageModelResponsesOptionsSchema = lazySchema(() =>
|
|
|
300
300
|
* and defaults `systemMessageMode` to `developer` unless overridden.
|
|
301
301
|
*/
|
|
302
302
|
forceReasoning: z.boolean().optional(),
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Enable server-side context management (compaction).
|
|
306
|
+
*/
|
|
307
|
+
contextManagement: z
|
|
308
|
+
.array(
|
|
309
|
+
z.object({
|
|
310
|
+
type: z.literal('compaction'),
|
|
311
|
+
compactThreshold: z.number(),
|
|
312
|
+
}),
|
|
313
|
+
)
|
|
314
|
+
.nullish(),
|
|
303
315
|
}),
|
|
304
316
|
),
|
|
305
317
|
);
|
|
@@ -30,6 +30,16 @@ export type OpenaiResponsesProviderMetadata = {
|
|
|
30
30
|
openai: ResponsesProviderMetadata;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
export type ResponsesCompactionProviderMetadata = {
|
|
34
|
+
type: 'compaction';
|
|
35
|
+
itemId: string;
|
|
36
|
+
encryptedContent?: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type OpenaiResponsesCompactionProviderMetadata = {
|
|
40
|
+
openai: ResponsesCompactionProviderMetadata;
|
|
41
|
+
};
|
|
42
|
+
|
|
33
43
|
export type ResponsesTextProviderMetadata = {
|
|
34
44
|
itemId: string;
|
|
35
45
|
phase?: 'commentary' | 'final_answer' | null;
|