@opencode-ai/ai 0.0.0-dev-18263 → 0.0.0-dev-18266
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.
|
@@ -550,7 +550,6 @@ export declare const Event: Schema.StructWithRest<Schema.Struct<{
|
|
|
550
550
|
readonly headers: Schema.optional<Schema.Unknown>;
|
|
551
551
|
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>;
|
|
552
552
|
export type Event = Schema.Schema.Type<typeof Event>;
|
|
553
|
-
export type ItemKind = "message" | "reasoning" | "function-call" | "hosted-tool";
|
|
554
553
|
export interface Extension {
|
|
555
554
|
readonly id: string;
|
|
556
555
|
readonly name: string;
|
|
@@ -560,7 +559,6 @@ export interface Extension {
|
|
|
560
559
|
readonly request: LLMRequest;
|
|
561
560
|
}) => MediaInput | undefined;
|
|
562
561
|
readonly lowerHostedToolItem?: (item: unknown) => ExtendedHostedToolItem | undefined;
|
|
563
|
-
readonly acceptsItemID?: (kind: ItemKind, id: string) => boolean;
|
|
564
562
|
}
|
|
565
563
|
export interface ParserState {
|
|
566
564
|
readonly id: string;
|
|
@@ -281,41 +281,36 @@ export const lowerToolChoice = (protocolName, toolChoice) => ProviderShared.matc
|
|
|
281
281
|
required: () => "required",
|
|
282
282
|
tool: (toolName) => ({ type: "function", name: toolName }),
|
|
283
283
|
});
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
// resending; anything else is treated as absent so the item is resent without
|
|
287
|
-
// an id (or skipped, for items that cannot be expressed without one).
|
|
288
|
-
const ITEM_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
284
|
+
// Server-issued item ids need a nonempty prefix and suffix, but the prefix is
|
|
285
|
+
// provider-defined and does not necessarily identify the item's semantic type.
|
|
289
286
|
const itemID = (providerMetadata, providerMetadataKey) => {
|
|
290
287
|
const metadata = providerMetadata?.[providerMetadataKey];
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
: undefined;
|
|
288
|
+
if (!ProviderShared.isRecord(metadata) || typeof metadata.itemId !== "string")
|
|
289
|
+
return undefined;
|
|
290
|
+
const separator = metadata.itemId.indexOf("_");
|
|
291
|
+
return separator > 0 && separator < metadata.itemId.length - 1 ? metadata.itemId : undefined;
|
|
296
292
|
};
|
|
297
|
-
const
|
|
298
|
-
const lowerToolCall = (part, providerMetadataKey, extension) => {
|
|
293
|
+
const lowerToolCall = (part, providerMetadataKey) => {
|
|
299
294
|
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
300
295
|
return {
|
|
301
296
|
type: "function_call",
|
|
302
|
-
...(
|
|
297
|
+
...(id === undefined ? {} : { id }),
|
|
303
298
|
call_id: part.id,
|
|
304
299
|
name: part.name,
|
|
305
300
|
arguments: ProviderShared.encodeJson(part.input),
|
|
306
301
|
};
|
|
307
302
|
};
|
|
308
|
-
const lowerReasoning = (part, providerMetadataKey
|
|
303
|
+
const lowerReasoning = (part, providerMetadataKey) => {
|
|
309
304
|
const metadata = part.providerMetadata?.[providerMetadataKey];
|
|
310
|
-
|
|
311
|
-
if (!ProviderShared.isRecord(metadata) || !acceptsItemID(extension, "reasoning", id))
|
|
305
|
+
if (!ProviderShared.isRecord(metadata))
|
|
312
306
|
return undefined;
|
|
307
|
+
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
313
308
|
const encryptedContent = typeof metadata.reasoningEncryptedContent === "string" || metadata.reasoningEncryptedContent === null
|
|
314
309
|
? metadata.reasoningEncryptedContent
|
|
315
310
|
: undefined;
|
|
316
311
|
return {
|
|
317
312
|
type: "reasoning",
|
|
318
|
-
id,
|
|
313
|
+
...(id === undefined ? {} : { id }),
|
|
319
314
|
summary: part.text.length > 0 ? [{ type: "summary_text", text: part.text }] : [],
|
|
320
315
|
encrypted_content: encryptedContent,
|
|
321
316
|
};
|
|
@@ -400,8 +395,7 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
400
395
|
return;
|
|
401
396
|
const groups = content.reduce((groups, part) => {
|
|
402
397
|
const metadata = part.providerMetadata?.[providerMetadataKey];
|
|
403
|
-
const
|
|
404
|
-
const id = acceptsItemID(extension, "message", rawID) ? rawID : undefined;
|
|
398
|
+
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
405
399
|
const phase = ProviderShared.isRecord(metadata) ? messagePhase(metadata.phase) : undefined;
|
|
406
400
|
const group = groups.at(-1);
|
|
407
401
|
if (group && group.id === id && group.phase === phase)
|
|
@@ -426,17 +420,18 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
426
420
|
}
|
|
427
421
|
if (part.type === "reasoning") {
|
|
428
422
|
flushText();
|
|
429
|
-
const reasoning = lowerReasoning(part, providerMetadataKey
|
|
423
|
+
const reasoning = lowerReasoning(part, providerMetadataKey);
|
|
430
424
|
if (!reasoning)
|
|
431
425
|
continue;
|
|
432
|
-
const existing = reasoningItems[reasoning.id];
|
|
426
|
+
const existing = reasoning.id === undefined ? undefined : reasoningItems[reasoning.id];
|
|
433
427
|
if (existing) {
|
|
434
428
|
existing.summary.push(...reasoning.summary);
|
|
435
429
|
if (typeof reasoning.encrypted_content === "string")
|
|
436
430
|
existing.encrypted_content = reasoning.encrypted_content;
|
|
437
431
|
continue;
|
|
438
432
|
}
|
|
439
|
-
|
|
433
|
+
if (reasoning.id !== undefined)
|
|
434
|
+
reasoningItems[reasoning.id] = reasoning;
|
|
440
435
|
input.push(reasoning);
|
|
441
436
|
continue;
|
|
442
437
|
}
|
|
@@ -444,7 +439,7 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
444
439
|
flushText();
|
|
445
440
|
if (part.providerExecuted === true)
|
|
446
441
|
continue;
|
|
447
|
-
input.push(lowerToolCall(part, providerMetadataKey
|
|
442
|
+
input.push(lowerToolCall(part, providerMetadataKey));
|
|
448
443
|
continue;
|
|
449
444
|
}
|
|
450
445
|
if (part.type === "tool-result" && part.providerExecuted === true) {
|
|
@@ -455,7 +450,7 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
455
450
|
: Schema.is(HostedToolItem)(part.result.value)
|
|
456
451
|
? part.result.value
|
|
457
452
|
: extension.lowerHostedToolItem?.(part.result.value);
|
|
458
|
-
if (
|
|
453
|
+
if (id !== undefined && hosted?.id === id) {
|
|
459
454
|
if (!hostedToolItems.has(id)) {
|
|
460
455
|
input.push(hosted);
|
|
461
456
|
hostedToolItems.add(id);
|
|
@@ -68,27 +68,10 @@ const OpenAIResponsesBody = Schema.Struct({
|
|
|
68
68
|
...OpenAIResponsesCoreFields,
|
|
69
69
|
stream: Schema.Literal(true),
|
|
70
70
|
});
|
|
71
|
-
// Replayed items are paired with stored server state by id, so a foreign or
|
|
72
|
-
// synthetic token can fail request validation even when `call_id` pairing is
|
|
73
|
-
// intact. Only resend ids in each item kind's own grammar; hosted tool
|
|
74
|
-
// items keep generic validation because every hosted tool mints its own
|
|
75
|
-
// prefix. The same allowlist approach codex uses before resending history
|
|
76
|
-
// (codex-rs core/src/client.rs, `prepare_response_items_for_request`).
|
|
77
|
-
const ITEM_ID_PREFIXES = {
|
|
78
|
-
message: ["msg_"],
|
|
79
|
-
reasoning: ["rs_"],
|
|
80
|
-
"function-call": ["fc_"],
|
|
81
|
-
// Every hosted tool mints its own id prefix, so items keep generic validation.
|
|
82
|
-
"hosted-tool": [],
|
|
83
|
-
};
|
|
84
71
|
const extension = {
|
|
85
72
|
id: ADAPTER,
|
|
86
73
|
name: NAME,
|
|
87
74
|
lowerHostedToolItem: (item) => (Schema.is(OpenAIResponsesHostedToolItem)(item) ? item : undefined),
|
|
88
|
-
acceptsItemID: (kind, id) => {
|
|
89
|
-
const prefixes = ITEM_ID_PREFIXES[kind];
|
|
90
|
-
return prefixes.length === 0 || prefixes.some((prefix) => id.startsWith(prefix));
|
|
91
|
-
},
|
|
92
75
|
};
|
|
93
76
|
const nativeImageToolInput = (tool) => {
|
|
94
77
|
const native = tool.native?.openai;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-18266",
|
|
4
4
|
"name": "@opencode-ai/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
32
32
|
"@effect/platform-node": "4.0.0-rc.111",
|
|
33
|
-
"@opencode-ai/http-recorder": "0.0.0-dev-
|
|
33
|
+
"@opencode-ai/http-recorder": "0.0.0-dev-18266",
|
|
34
34
|
"@tsconfig/bun": "1.0.9",
|
|
35
35
|
"@types/bun": "1.3.13",
|
|
36
36
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@smithy/eventstream-codec": "4.2.14",
|
|
41
41
|
"@smithy/util-utf8": "4.2.2",
|
|
42
|
-
"@opencode-ai/schema": "0.0.0-dev-
|
|
42
|
+
"@opencode-ai/schema": "0.0.0-dev-18266",
|
|
43
43
|
"aws4fetch": "1.0.20",
|
|
44
44
|
"effect": "4.0.0-rc.111",
|
|
45
45
|
"google-auth-library": "10.5.0"
|