@opencode/ai 0.0.0-dev-20141 → 0.0.0-dev-20142
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/dist/protocols/open-responses.d.ts +3 -0
- package/dist/protocols/open-responses.js +2 -5
- package/dist/protocols/openai-responses.js +13 -18
- package/dist/protocols/utils/responses-checkpoint.js +3 -7
- package/dist/protocols/utils/responses-compaction.d.ts +3 -1
- package/dist/protocols/utils/responses-compaction.js +16 -3
- package/dist/protocols/xai-responses.js +1 -1
- package/dist/providers/openai-options.d.ts +3 -9
- package/dist/providers/openai-options.js +4 -7
- package/dist/providers/openai.js +1 -1
- package/package.json +3 -3
|
@@ -725,6 +725,9 @@ export declare const lowerTool: (protocolName: string, tool: ToolDefinition) =>
|
|
|
725
725
|
};
|
|
726
726
|
strict: boolean;
|
|
727
727
|
}, AIError, never>;
|
|
728
|
+
export declare const lowerTools: (tools: ReadonlyArray<ToolDefinition>, adapter: ProviderAdapter) => Effect.Effect<{
|
|
729
|
+
readonly type: string;
|
|
730
|
+
}[], AIError, never>;
|
|
728
731
|
export declare const lowerToolChoice: (protocolName: string, toolChoice: NonNullable<LLMRequest["toolChoice"]>) => Effect.Effect<"required" | "auto" | "none" | {
|
|
729
732
|
type: "function";
|
|
730
733
|
name: string;
|
|
@@ -292,6 +292,7 @@ export const lowerTool = Effect.fn("OpenResponses.lowerTool")(function* (protoco
|
|
|
292
292
|
strict: false,
|
|
293
293
|
};
|
|
294
294
|
});
|
|
295
|
+
export const lowerTools = (tools, adapter) => Effect.forEach(tools, (tool) => tool.native !== undefined && adapter.nativeTool ? adapter.nativeTool(tool.native) : lowerTool(adapter.name, tool));
|
|
295
296
|
export const lowerToolChoice = (protocolName, toolChoice) => ProviderShared.matchToolChoice(protocolName, toolChoice, {
|
|
296
297
|
auto: () => "auto",
|
|
297
298
|
none: () => "none",
|
|
@@ -605,11 +606,7 @@ export const fromRequestWithAdapter = Effect.fn("OpenResponses.fromRequestWithAd
|
|
|
605
606
|
return {
|
|
606
607
|
...(yield* lowerConversation(projected.request, adapter)),
|
|
607
608
|
...lowerGeneration(request),
|
|
608
|
-
tools: projected.tools.length === 0
|
|
609
|
-
? undefined
|
|
610
|
-
: yield* Effect.forEach(projected.tools, (tool) => tool.native !== undefined && adapter.nativeTool
|
|
611
|
-
? adapter.nativeTool(tool.native)
|
|
612
|
-
: lowerTool(adapter.name, tool)),
|
|
609
|
+
tools: projected.tools.length === 0 ? undefined : yield* lowerTools(projected.tools, adapter),
|
|
613
610
|
tool_choice: allowedToolChoice(request) ??
|
|
614
611
|
(request.toolChoice ? yield* lowerToolChoice(adapter.name, request.toolChoice) : undefined),
|
|
615
612
|
};
|
|
@@ -5,7 +5,7 @@ import { Auth } from "../route/auth.js";
|
|
|
5
5
|
import { Endpoint } from "../route/endpoint.js";
|
|
6
6
|
import { Protocol } from "../route/protocol.js";
|
|
7
7
|
import { HttpTransport } from "../route/transport/index.js";
|
|
8
|
-
import { LLMRequest
|
|
8
|
+
import { LLMRequest } from "../schema/index.js";
|
|
9
9
|
import { resolveEffortUpdates } from "../effort-updates.js";
|
|
10
10
|
import { OpenResponses } from "./open-responses.js";
|
|
11
11
|
import { OpenResponsesOptions } from "./utils/open-responses-options.js";
|
|
@@ -105,9 +105,6 @@ export const CompactionTrigger = Schema.Struct({ type: Schema.Literal("compactio
|
|
|
105
105
|
const CheckpointBody = Schema.Struct({
|
|
106
106
|
...OpenAIResponsesBody.fields,
|
|
107
107
|
input: Schema.Array(Schema.Union([OpenAIResponsesInputItem, CompactionTrigger])),
|
|
108
|
-
store: Schema.Literal(false),
|
|
109
|
-
prompt_cache_retention: optionalNull(Schema.String),
|
|
110
|
-
prompt_cache_options: optionalNull(Schema.Struct({ mode: Schema.optional(Schema.String), ttl: Schema.optional(Schema.String) })),
|
|
111
108
|
});
|
|
112
109
|
const adapter = {
|
|
113
110
|
id: ADAPTER,
|
|
@@ -154,6 +151,7 @@ const lowerToolEntry = Effect.fn("OpenAIResponses.lowerToolEntry")(function* (to
|
|
|
154
151
|
tools: yield* Effect.forEach(ProviderShared.flattenTools(tool.tools), (leaf) => OpenResponses.lowerTool(NAME, leaf)),
|
|
155
152
|
};
|
|
156
153
|
});
|
|
154
|
+
const lowerTools = (request) => Effect.forEach(request.tools, lowerToolEntry);
|
|
157
155
|
const lowerToolChoice = (toolChoice, tools) => ProviderShared.matchToolChoice(NAME, toolChoice, {
|
|
158
156
|
auto: () => "auto",
|
|
159
157
|
none: () => "none",
|
|
@@ -171,7 +169,7 @@ const fromRequest = Effect.fn("OpenAIResponses.fromRequest")(function* (request)
|
|
|
171
169
|
...(yield* OpenResponses.lowerConversation(updates.request, adapter)),
|
|
172
170
|
...OpenResponses.lowerGeneration(request, { ...options, reasoningEffort: updates.effort }),
|
|
173
171
|
context_management: management?.map((edit) => ({ type: edit.type, compact_threshold: edit.compactThreshold })),
|
|
174
|
-
tools: request.tools.length === 0 ? undefined : yield*
|
|
172
|
+
tools: request.tools.length === 0 ? undefined : yield* lowerTools(request),
|
|
175
173
|
tool_choice: request.tools.length === 0
|
|
176
174
|
? undefined
|
|
177
175
|
: (OpenResponses.allowedToolChoice(request) ??
|
|
@@ -181,25 +179,19 @@ const fromRequest = Effect.fn("OpenAIResponses.fromRequest")(function* (request)
|
|
|
181
179
|
const checkpointBody = {
|
|
182
180
|
schema: CheckpointBody,
|
|
183
181
|
from: Effect.fn("OpenAIResponses.checkpointBody")(function* (request) {
|
|
184
|
-
const native = yield* fromRequest(LLMRequest.update(request, { toolChoice: undefined }));
|
|
185
182
|
const overlay = request.http?.body;
|
|
186
183
|
// Complete history is required for stateless replay and SSE recovery. Raw input overrides bypass that contract.
|
|
187
184
|
if (overlay?.input !== undefined ||
|
|
188
185
|
overlay?.previous_response_id !== undefined ||
|
|
189
186
|
overlay?.conversation !== undefined)
|
|
190
187
|
return yield* ProviderShared.invalidRequest("Trigger compaction requires complete canonical history, not an input or continuation override");
|
|
191
|
-
|
|
192
|
-
|
|
188
|
+
if (overlay?.stream !== undefined && overlay.stream !== true)
|
|
189
|
+
return yield* ProviderShared.invalidRequest("Trigger compaction requires a streamed response");
|
|
190
|
+
const native = yield* fromRequest(request);
|
|
191
|
+
return {
|
|
192
|
+
...native,
|
|
193
193
|
input: [...native.input, { type: "compaction_trigger" }],
|
|
194
|
-
|
|
195
|
-
store: false,
|
|
196
|
-
parallel_tool_calls: true,
|
|
197
|
-
tool_choice: undefined,
|
|
198
|
-
context_management: undefined,
|
|
199
|
-
text: undefined,
|
|
200
|
-
max_output_tokens: undefined,
|
|
201
|
-
max_tool_calls: undefined,
|
|
202
|
-
});
|
|
194
|
+
};
|
|
203
195
|
}),
|
|
204
196
|
};
|
|
205
197
|
const hostedToolResult = Effect.fn("OpenAIResponses.hostedToolResult")(function* (item) {
|
|
@@ -270,7 +262,10 @@ export const transport = channelTransport({
|
|
|
270
262
|
headers: (headers) => Headers.set(headers, "openai-beta", headers["openai-beta"] ?? WEBSOCKET_PROTOCOL_HEADER),
|
|
271
263
|
});
|
|
272
264
|
export const route = Route.make({
|
|
273
|
-
compact: {
|
|
265
|
+
compact: {
|
|
266
|
+
endpoint: ResponsesCompaction.make(adapter, lowerTools),
|
|
267
|
+
trigger: ResponsesCheckpoint.make(checkpointBody),
|
|
268
|
+
},
|
|
274
269
|
id: ADAPTER,
|
|
275
270
|
provider: "openai",
|
|
276
271
|
providerMetadataKey: "openai",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect, Schema, Stream } from "effect";
|
|
2
2
|
import { Route } from "../../route/client.js";
|
|
3
3
|
import { Protocol } from "../../route/protocol.js";
|
|
4
|
-
import { CompactionCheckpointResponse,
|
|
4
|
+
import { CompactionCheckpointResponse, LLMEvent, LLMRequest } from "../../schema/index.js";
|
|
5
5
|
import { OpenResponses } from "../open-responses.js";
|
|
6
6
|
import { ProviderShared } from "../shared.js";
|
|
7
7
|
const onOutputItem = Effect.fn("ResponsesCheckpoint.onOutputItem")(function* (state, input) {
|
|
@@ -94,12 +94,8 @@ export const make = (body) => Effect.fn("ResponsesCheckpoint.execute")(function*
|
|
|
94
94
|
transport: source.transport,
|
|
95
95
|
});
|
|
96
96
|
const native = yield* body.from(request);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
http: request.http === undefined ? undefined : new HttpOptions({ ...request.http, body: undefined }),
|
|
100
|
-
});
|
|
101
|
-
const prepared = yield* route.prepareTransport(native, preparedRequest, options);
|
|
102
|
-
yield* route.streamPrepared(prepared, preparedRequest, { http: executor }, options).pipe(Stream.runDrain);
|
|
97
|
+
const prepared = yield* route.prepareTransport(native, request, options);
|
|
98
|
+
yield* route.streamPrepared(prepared, request, { http: executor }, options).pipe(Stream.runDrain);
|
|
103
99
|
if (!result)
|
|
104
100
|
return yield* ProviderShared.eventError(source.id, "Compaction response ended without a checkpoint");
|
|
105
101
|
return result;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { AIError, LLMRequest } from "../../schema/index.js";
|
|
1
3
|
import type { CompactOperation } from "../../route/client.js";
|
|
2
4
|
import { OpenResponses } from "../open-responses.js";
|
|
3
|
-
export declare const make: (adapter: OpenResponses.ProviderAdapter) => CompactOperation;
|
|
5
|
+
export declare const make: (adapter: OpenResponses.ProviderAdapter, lowerTools: (request: LLMRequest) => Effect.Effect<ReadonlyArray<Record<string, unknown>>, AIError>) => CompactOperation;
|
|
4
6
|
export * as ResponsesCompaction from "./responses-compaction.js";
|
|
@@ -7,12 +7,18 @@ import { HttpTransport } from "../../route/transport/index.js";
|
|
|
7
7
|
import { OpenResponses } from "../open-responses.js";
|
|
8
8
|
import { JsonObject, optionalNull, ProviderShared } from "../shared.js";
|
|
9
9
|
import { Media } from "../../media.js";
|
|
10
|
+
// /compact has a smaller wire contract than /responses; keep the request controls it accepts.
|
|
10
11
|
const Body = Schema.Struct({
|
|
11
12
|
model: Schema.String,
|
|
12
13
|
input: Schema.Array(Schema.Unknown),
|
|
13
14
|
instructions: optionalNull(Schema.String),
|
|
14
15
|
previous_response_id: optionalNull(Schema.String),
|
|
15
16
|
service_tier: optionalNull(Schema.String),
|
|
17
|
+
reasoning: Schema.optional(JsonObject),
|
|
18
|
+
text: Schema.optional(JsonObject),
|
|
19
|
+
include: OpenResponses.coreFields.include,
|
|
20
|
+
parallel_tool_calls: OpenResponses.coreFields.parallel_tool_calls,
|
|
21
|
+
tools: Schema.optional(Schema.Array(JsonObject)),
|
|
16
22
|
prompt_cache_key: optionalNull(Schema.String),
|
|
17
23
|
prompt_cache_retention: optionalNull(Schema.String),
|
|
18
24
|
prompt_cache_options: optionalNull(Schema.Struct({ mode: Schema.optional(Schema.String), ttl: Schema.optional(Schema.String) })),
|
|
@@ -54,14 +60,21 @@ const Response = Schema.Struct({
|
|
|
54
60
|
])),
|
|
55
61
|
usage: Schema.optional(Schema.StructWithRest(OpenResponses.OpenResponsesUsage, [JsonObject])),
|
|
56
62
|
});
|
|
57
|
-
export const make = (adapter) => Effect.fn("ResponsesCompaction.execute")(function* (request, executor, options) {
|
|
63
|
+
export const make = (adapter, lowerTools) => Effect.fn("ResponsesCompaction.execute")(function* (request, executor, options) {
|
|
58
64
|
const route = request.model.route;
|
|
59
65
|
// The standalone compaction endpoint rejects histories containing configuration updates.
|
|
60
66
|
const native = yield* OpenResponses.lowerConversation(stripEffortUpdates(request), adapter);
|
|
67
|
+
const generation = OpenResponses.lowerGeneration(request);
|
|
68
|
+
const tools = request.tools.length === 0 ? undefined : yield* lowerTools(request);
|
|
61
69
|
const body = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Body))(mergeJsonRecords({
|
|
62
70
|
...native,
|
|
63
|
-
service_tier:
|
|
64
|
-
|
|
71
|
+
service_tier: generation.service_tier,
|
|
72
|
+
reasoning: generation.reasoning,
|
|
73
|
+
text: generation.text,
|
|
74
|
+
include: generation.include,
|
|
75
|
+
parallel_tool_calls: generation.parallel_tool_calls,
|
|
76
|
+
tools,
|
|
77
|
+
prompt_cache_key: generation.prompt_cache_key,
|
|
65
78
|
}, request.http?.body));
|
|
66
79
|
const url = Endpoint.render(route.endpoint, { request, body: native });
|
|
67
80
|
url.pathname = `${url.pathname.replace(/\/$/, "")}/compact`;
|
|
@@ -77,5 +77,5 @@ export const protocol = Protocol.make({
|
|
|
77
77
|
terminal: OpenResponses.terminal,
|
|
78
78
|
},
|
|
79
79
|
});
|
|
80
|
-
export const compact = ResponsesCompaction.make(adapter);
|
|
80
|
+
export const compact = ResponsesCompaction.make(adapter, (request) => OpenResponses.lowerTools(ProviderShared.flattenTools(request.tools), adapter));
|
|
81
81
|
export * as XAIResponses from "./xai-responses.js";
|
|
@@ -10,17 +10,11 @@ export type OpenAIOptionsInput = Omit<Options, "serviceTier"> & {
|
|
|
10
10
|
readonly [key: string]: unknown;
|
|
11
11
|
};
|
|
12
12
|
export type OpenAIProviderOptionsInput = OpenAIOptionsInput;
|
|
13
|
-
export declare const gpt5DefaultOptions: (modelID: string
|
|
14
|
-
|
|
15
|
-
}) => ProviderOptions | undefined;
|
|
16
|
-
export declare const openAIDefaultOptions: (modelID: string, options?: {
|
|
17
|
-
readonly textVerbosity?: boolean;
|
|
18
|
-
}) => ProviderOptions | undefined;
|
|
13
|
+
export declare const gpt5DefaultOptions: (modelID: string) => ProviderOptions | undefined;
|
|
14
|
+
export declare const openAIDefaultOptions: (modelID: string) => ProviderOptions | undefined;
|
|
19
15
|
export declare const withOpenAIOptions: <Options extends {
|
|
20
16
|
readonly providerOptions?: OpenAIProviderOptionsInput;
|
|
21
|
-
}>(modelID: string, options: Options,
|
|
22
|
-
readonly textVerbosity?: boolean;
|
|
23
|
-
}) => Omit<Options, "providerOptions"> & {
|
|
17
|
+
}>(modelID: string, options: Options) => Omit<Options, "providerOptions"> & {
|
|
24
18
|
readonly providerOptions?: ProviderOptions;
|
|
25
19
|
};
|
|
26
20
|
export * as OpenAIProviderOptions from "./openai-options.js";
|
|
@@ -13,7 +13,7 @@ const openAIProviderOptions = (options) => {
|
|
|
13
13
|
return undefined;
|
|
14
14
|
return result;
|
|
15
15
|
};
|
|
16
|
-
export const gpt5DefaultOptions = (modelID
|
|
16
|
+
export const gpt5DefaultOptions = (modelID) => {
|
|
17
17
|
const id = modelID.toLowerCase();
|
|
18
18
|
if (!id.includes("gpt-5") || id.includes("gpt-5-chat") || id.includes("gpt-5-pro"))
|
|
19
19
|
return undefined;
|
|
@@ -26,16 +26,13 @@ export const gpt5DefaultOptions = (modelID, options = {}) => {
|
|
|
26
26
|
// this, callers using the default model facade get reasoning summaries
|
|
27
27
|
// they cannot replay statelessly.
|
|
28
28
|
include: ["reasoning.encrypted_content"],
|
|
29
|
-
textVerbosity: options.textVerbosity === true && id.includes("gpt-5.") && !id.includes("codex") && !id.includes("-chat")
|
|
30
|
-
? "low"
|
|
31
|
-
: undefined,
|
|
32
29
|
});
|
|
33
30
|
};
|
|
34
|
-
export const openAIDefaultOptions = (modelID
|
|
35
|
-
export const withOpenAIOptions = (modelID, options
|
|
31
|
+
export const openAIDefaultOptions = (modelID) => mergeProviderOptions(openAIProviderOptions({ store: false }), gpt5DefaultOptions(modelID));
|
|
32
|
+
export const withOpenAIOptions = (modelID, options) => {
|
|
36
33
|
return {
|
|
37
34
|
...options,
|
|
38
|
-
providerOptions: mergeProviderOptions(openAIDefaultOptions(modelID
|
|
35
|
+
providerOptions: mergeProviderOptions(openAIDefaultOptions(modelID), options.providerOptions),
|
|
39
36
|
};
|
|
40
37
|
};
|
|
41
38
|
export * as OpenAIProviderOptions from "./openai-options.js";
|
package/dist/providers/openai.js
CHANGED
|
@@ -41,7 +41,7 @@ export const configure = (input = {}) => {
|
|
|
41
41
|
const chatRoute = configuredRoute(OpenAIChat.route, input);
|
|
42
42
|
const modelDefaults = defaults(input);
|
|
43
43
|
const responses = (id) => responsesRoute
|
|
44
|
-
.with(withOpenAIOptions(id, modelDefaults
|
|
44
|
+
.with(withOpenAIOptions(id, modelDefaults))
|
|
45
45
|
.model({ id });
|
|
46
46
|
const chat = (id) => chatRoute.with(withOpenAIOptions(id, modelDefaults)).model({
|
|
47
47
|
id,
|
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-20142",
|
|
4
4
|
"name": "@opencode/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
36
36
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
37
|
-
"@opencode/http-recorder": "0.0.0-dev-
|
|
37
|
+
"@opencode/http-recorder": "0.0.0-dev-20142",
|
|
38
38
|
"@tsconfig/bun": "1.0.9",
|
|
39
39
|
"@types/bun": "1.4.0",
|
|
40
40
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@aws-sdk/credential-providers": "3.1057.0",
|
|
45
45
|
"@smithy/eventstream-codec": "4.2.14",
|
|
46
46
|
"@smithy/util-utf8": "4.2.2",
|
|
47
|
-
"@opencode/schema": "0.0.0-dev-
|
|
47
|
+
"@opencode/schema": "0.0.0-dev-20142",
|
|
48
48
|
"aws4fetch": "1.0.20",
|
|
49
49
|
"effect": "4.0.0-rc.112",
|
|
50
50
|
"google-auth-library": "10.5.0"
|