@opencode/ai 0.0.0-dev-19594 → 0.0.0-dev-19596
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/cache-policy.js +10 -2
- package/dist/effort-updates.d.ts +12 -0
- package/dist/effort-updates.js +23 -0
- package/dist/protocols/alibaba-messages.d.ts +4 -1
- package/dist/protocols/anthropic-messages.d.ts +11 -2
- package/dist/protocols/anthropic-messages.js +48 -17
- package/dist/protocols/meta-messages.d.ts +4 -1
- package/dist/protocols/meta-responses.d.ts +2 -2
- package/dist/protocols/open-responses.d.ts +9 -2
- package/dist/protocols/open-responses.js +17 -2
- package/dist/protocols/openai-chat.d.ts +7 -7
- package/dist/protocols/openai-compatible-chat.d.ts +1 -1
- package/dist/protocols/openai-compatible-responses.d.ts +1 -1
- package/dist/protocols/openai-responses.d.ts +56 -25
- package/dist/protocols/openai-responses.js +23 -4
- package/dist/protocols/utils/open-responses-options.d.ts +2 -4
- package/dist/protocols/utils/open-responses-options.js +2 -2
- package/dist/protocols/utils/responses-compaction.js +3 -1
- package/dist/protocols/xai-responses.d.ts +1 -1
- package/dist/protocols/zai-chat.d.ts +1 -1
- package/dist/protocols/zai-messages.d.ts +4 -1
- package/dist/providers/alibaba.d.ts +12 -9
- package/dist/providers/amazon-bedrock-mantle.d.ts +2 -2
- package/dist/providers/anthropic-compatible.d.ts +4 -1
- package/dist/providers/anthropic.d.ts +4 -1
- package/dist/providers/azure.d.ts +13 -3
- package/dist/providers/baseten.d.ts +2 -2
- package/dist/providers/cerebras.d.ts +2 -2
- package/dist/providers/cloudflare-ai-gateway.d.ts +2 -2
- package/dist/providers/cloudflare-workers-ai.d.ts +2 -2
- package/dist/providers/deepinfra.d.ts +2 -2
- package/dist/providers/deepseek.d.ts +2 -2
- package/dist/providers/fireworks.d.ts +2 -2
- package/dist/providers/google-vertex-chat.d.ts +1 -1
- package/dist/providers/google-vertex-messages.d.ts +4 -1
- package/dist/providers/google-vertex-responses.d.ts +1 -1
- package/dist/providers/groq.d.ts +2 -2
- package/dist/providers/meta.d.ts +6 -3
- package/dist/providers/minimax.d.ts +6 -3
- package/dist/providers/moonshot.d.ts +6 -3
- package/dist/providers/openai-compatible-responses.d.ts +1 -1
- package/dist/providers/openai-compatible.d.ts +1 -1
- package/dist/providers/openai.d.ts +7 -2
- package/dist/providers/openrouter.d.ts +4 -4
- package/dist/providers/togetherai.d.ts +2 -2
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/zai-coding-plan.d.ts +6 -3
- package/dist/providers/zai.d.ts +1 -1
- package/dist/route/client.d.ts +1 -0
- package/dist/route/client.js +3 -1
- package/dist/route/protocol.d.ts +2 -0
- package/dist/schema/messages.d.ts +22 -3
- package/dist/schema/messages.js +9 -1
- package/dist/schema/options.d.ts +5 -0
- package/dist/schema/options.js +4 -0
- package/package.json +3 -3
package/dist/cache-policy.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// count against the four-breakpoint budget; auto only fills remaining slots.
|
|
13
13
|
import { CacheHint } from "./schema/options.js";
|
|
14
14
|
import { LLMRequest, Message, ToolDefinition } from "./schema/messages.js";
|
|
15
|
+
import { effortUpdate } from "./effort-updates.js";
|
|
15
16
|
const AUTO = {
|
|
16
17
|
tools: true,
|
|
17
18
|
system: true,
|
|
@@ -100,10 +101,17 @@ const markMessages = (messages, strategy, hint, budget) => {
|
|
|
100
101
|
return markMessageAt(messages, lastIndexOfRole(messages, "user"), hint, budget);
|
|
101
102
|
if (strategy === "latest-assistant")
|
|
102
103
|
return markMessageAt(messages, lastIndexOfRole(messages, "assistant"), hint, budget);
|
|
103
|
-
|
|
104
|
+
let start = messages.length;
|
|
105
|
+
let remaining = strategy.tail;
|
|
106
|
+
while (remaining > 0 && start > 0) {
|
|
107
|
+
start -= 1;
|
|
108
|
+
if (effortUpdate(messages[start]) === undefined)
|
|
109
|
+
remaining -= 1;
|
|
110
|
+
}
|
|
104
111
|
let next = messages;
|
|
105
112
|
for (let i = start; i < messages.length; i++)
|
|
106
|
-
|
|
113
|
+
if (effortUpdate(messages[i]) === undefined)
|
|
114
|
+
next = markMessageAt(next, i, hint, budget);
|
|
107
115
|
return next;
|
|
108
116
|
};
|
|
109
117
|
const countHints = (request) => countToolHints(request.tools) +
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LLMRequest, type EffortPart, type Message } from "./schema/messages.js";
|
|
2
|
+
export declare const effortUpdate: (message: Message) => EffortPart | undefined;
|
|
3
|
+
export declare const stripEffortUpdates: (request: LLMRequest) => LLMRequest<import("./index.js").LanguageModel<{
|
|
4
|
+
readonly [x: string]: unknown;
|
|
5
|
+
}, import("./route.js").CompactionOperations | undefined>>;
|
|
6
|
+
export declare const applyEffortUpdates: (request: LLMRequest) => LLMRequest;
|
|
7
|
+
export declare const resolveEffortUpdates: (request: LLMRequest, current: string | undefined) => {
|
|
8
|
+
request: LLMRequest<import("./index.js").LanguageModel<{
|
|
9
|
+
readonly [x: string]: unknown;
|
|
10
|
+
}, import("./route.js").CompactionOperations | undefined>>;
|
|
11
|
+
effort: string | undefined;
|
|
12
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Changing the top-level reasoning effort invalidates the provider prompt cache. Protocols with a native
|
|
2
|
+
// per-message update keep it frozen and lower `Message.effort(...)` markers instead; other routes strip them.
|
|
3
|
+
import { LLMRequest } from "./schema/messages.js";
|
|
4
|
+
export const effortUpdate = (message) => {
|
|
5
|
+
if (message.role !== "system" || message.content.length !== 1)
|
|
6
|
+
return undefined;
|
|
7
|
+
const part = message.content[0];
|
|
8
|
+
return part.type === "effort" ? part : undefined;
|
|
9
|
+
};
|
|
10
|
+
export const stripEffortUpdates = (request) => {
|
|
11
|
+
const messages = request.messages.filter((message) => effortUpdate(message) === undefined);
|
|
12
|
+
return messages.length === request.messages.length ? request : LLMRequest.update(request, { messages });
|
|
13
|
+
};
|
|
14
|
+
export const applyEffortUpdates = (request) => request.model.route.supportsEffortUpdates?.(request) ? request : stripEffortUpdates(request);
|
|
15
|
+
// Reverted or forked history can leave the last marker disagreeing with the requested effort.
|
|
16
|
+
export const resolveEffortUpdates = (request, current) => {
|
|
17
|
+
const updates = request.messages.flatMap((message) => effortUpdate(message) ?? []);
|
|
18
|
+
if (updates.length === 0)
|
|
19
|
+
return { request, effort: current };
|
|
20
|
+
if (updates.at(-1)?.effort !== current)
|
|
21
|
+
return { request: stripEffortUpdates(request), effort: current };
|
|
22
|
+
return { request, effort: updates[0]?.previous };
|
|
23
|
+
};
|
|
@@ -187,7 +187,6 @@ export declare const protocol: Protocol<{
|
|
|
187
187
|
readonly content: string | null;
|
|
188
188
|
})[];
|
|
189
189
|
} | {
|
|
190
|
-
readonly role: "system";
|
|
191
190
|
readonly content: readonly {
|
|
192
191
|
readonly type: "text";
|
|
193
192
|
readonly text: string;
|
|
@@ -196,6 +195,10 @@ export declare const protocol: Protocol<{
|
|
|
196
195
|
readonly ttl?: "1h" | "5m" | undefined;
|
|
197
196
|
} | undefined;
|
|
198
197
|
}[];
|
|
198
|
+
readonly role: "system";
|
|
199
|
+
readonly output_config?: {
|
|
200
|
+
readonly effort: string;
|
|
201
|
+
} | undefined;
|
|
199
202
|
})[];
|
|
200
203
|
readonly stream: true;
|
|
201
204
|
readonly metadata?: {
|
|
@@ -286,6 +286,9 @@ export declare const AnthropicMessagesBody: Schema.Struct<{
|
|
|
286
286
|
readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
|
|
287
287
|
}>>;
|
|
288
288
|
}>>;
|
|
289
|
+
readonly output_config: Schema.optional<Schema.Struct<{
|
|
290
|
+
readonly effort: Schema.String;
|
|
291
|
+
}>>;
|
|
289
292
|
}>]>>;
|
|
290
293
|
tools: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
291
294
|
readonly name: Schema.String;
|
|
@@ -529,7 +532,6 @@ export declare const protocol: Protocol<{
|
|
|
529
532
|
readonly content: string | null;
|
|
530
533
|
})[];
|
|
531
534
|
} | {
|
|
532
|
-
readonly role: "system";
|
|
533
535
|
readonly content: readonly {
|
|
534
536
|
readonly type: "text";
|
|
535
537
|
readonly text: string;
|
|
@@ -538,6 +540,10 @@ export declare const protocol: Protocol<{
|
|
|
538
540
|
readonly ttl?: "1h" | "5m" | undefined;
|
|
539
541
|
} | undefined;
|
|
540
542
|
}[];
|
|
543
|
+
readonly role: "system";
|
|
544
|
+
readonly output_config?: {
|
|
545
|
+
readonly effort: string;
|
|
546
|
+
} | undefined;
|
|
541
547
|
})[];
|
|
542
548
|
readonly stream: true;
|
|
543
549
|
readonly metadata?: {
|
|
@@ -883,7 +889,6 @@ export declare const route: Route<{
|
|
|
883
889
|
readonly content: string | null;
|
|
884
890
|
})[];
|
|
885
891
|
} | {
|
|
886
|
-
readonly role: "system";
|
|
887
892
|
readonly content: readonly {
|
|
888
893
|
readonly type: "text";
|
|
889
894
|
readonly text: string;
|
|
@@ -892,6 +897,10 @@ export declare const route: Route<{
|
|
|
892
897
|
readonly ttl?: "1h" | "5m" | undefined;
|
|
893
898
|
} | undefined;
|
|
894
899
|
}[];
|
|
900
|
+
readonly role: "system";
|
|
901
|
+
readonly output_config?: {
|
|
902
|
+
readonly effort: string;
|
|
903
|
+
} | undefined;
|
|
895
904
|
})[];
|
|
896
905
|
readonly stream: true;
|
|
897
906
|
readonly metadata?: {
|
|
@@ -11,6 +11,7 @@ import { HttpTransport } from "../route/transport/index.js";
|
|
|
11
11
|
import { AIError, HttpOptions, LLMRequest, LLMEvent, mergeJsonRecords, Usage, } from "../schema/index.js";
|
|
12
12
|
import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
|
|
13
13
|
import { classifyProviderFailure } from "../provider-error.js";
|
|
14
|
+
import { effortUpdate, resolveEffortUpdates } from "../effort-updates.js";
|
|
14
15
|
import * as Cache from "./utils/cache.js";
|
|
15
16
|
import { Lifecycle } from "./utils/lifecycle.js";
|
|
16
17
|
import { ToolSchemaProjection } from "./utils/tool-schema.js";
|
|
@@ -19,6 +20,7 @@ const ADAPTER = "anthropic-messages";
|
|
|
19
20
|
export const DEFAULT_BASE_URL = "https://api.anthropic.com/v1";
|
|
20
21
|
export const PATH = "/messages";
|
|
21
22
|
export const DEFAULT_MAX_TOKENS = 32_000;
|
|
23
|
+
const DEFAULT_EFFORT = "high";
|
|
22
24
|
const SSE_EVENTS = new Set([
|
|
23
25
|
"message",
|
|
24
26
|
"message_start",
|
|
@@ -183,7 +185,11 @@ const AnthropicAssistantBlock = Schema.Union([
|
|
|
183
185
|
const AnthropicMessage = Schema.Union([
|
|
184
186
|
Schema.Struct({ role: Schema.Literal("user"), content: Schema.Array(AnthropicUserBlock) }),
|
|
185
187
|
Schema.Struct({ role: Schema.Literal("assistant"), content: Schema.Array(AnthropicAssistantBlock) }),
|
|
186
|
-
Schema.Struct({
|
|
188
|
+
Schema.Struct({
|
|
189
|
+
role: Schema.Literal("system"),
|
|
190
|
+
content: Schema.Array(AnthropicTextBlock),
|
|
191
|
+
output_config: Schema.optional(Schema.Struct({ effort: Schema.String })),
|
|
192
|
+
}),
|
|
187
193
|
]).pipe(Schema.toTaggedUnion("role"));
|
|
188
194
|
const AnthropicTool = Schema.Struct({
|
|
189
195
|
name: Schema.String,
|
|
@@ -697,6 +703,12 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (re
|
|
|
697
703
|
const providerMetadataKey = request.model.route.providerMetadataKey ?? String(request.model.provider);
|
|
698
704
|
for (const [index, message] of request.messages.entries()) {
|
|
699
705
|
if (message.role === "system") {
|
|
706
|
+
const update = effortUpdate(message);
|
|
707
|
+
if (update) {
|
|
708
|
+
// Accepted at any position, so the text-update placement rules do not apply.
|
|
709
|
+
messages.push({ role: "system", content: [], output_config: { effort: update.effort ?? DEFAULT_EFFORT } });
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
700
712
|
if (splitsLocalToolResults(request.messages, index))
|
|
701
713
|
return yield* invalid("Anthropic Messages system updates cannot split a local tool call from its tool result");
|
|
702
714
|
if (supportsNativeSystemUpdates(request) && canUseNativeSystemUpdate(request, index)) {
|
|
@@ -842,17 +854,11 @@ const resolveOptions = Effect.fn("AnthropicMessages.resolveOptions")(function* (
|
|
|
842
854
|
const outputConfigFormat = ProviderShared.isRecord(rawOutputConfig) && ProviderShared.isRecord(rawOutputConfig.format)
|
|
843
855
|
? rawOutputConfig.format
|
|
844
856
|
: undefined;
|
|
845
|
-
const output_config = outputConfigEffort === undefined && outputConfigFormat === undefined
|
|
846
|
-
? undefined
|
|
847
|
-
: {
|
|
848
|
-
...(outputConfigEffort === undefined ? {} : { effort: outputConfigEffort }),
|
|
849
|
-
...(outputConfigFormat === undefined ? {} : { format: outputConfigFormat }),
|
|
850
|
-
};
|
|
851
857
|
const thinking = yield* resolveThinking(input?.thinking);
|
|
852
858
|
return {
|
|
853
859
|
thinking: applyThinkingBindingDefault(request.model, thinking),
|
|
854
860
|
effort: outputConfigEffort,
|
|
855
|
-
|
|
861
|
+
format: outputConfigFormat,
|
|
856
862
|
service_tier,
|
|
857
863
|
metadata,
|
|
858
864
|
container,
|
|
@@ -860,17 +866,32 @@ const resolveOptions = Effect.fn("AnthropicMessages.resolveOptions")(function* (
|
|
|
860
866
|
cache_control,
|
|
861
867
|
};
|
|
862
868
|
});
|
|
869
|
+
// Accept gateway namespaces and Vertex suffixes without treating a snapshot date as a minor version.
|
|
870
|
+
const claudeVersion = (id) => {
|
|
871
|
+
const match = /(?:^|[./])claude-(?<family>[a-z]+)-(?<major>\d+)(?:[.-](?<minor>\d{1,2}))?(?:$|[-:@])/.exec(id.toLowerCase())?.groups;
|
|
872
|
+
if (!match)
|
|
873
|
+
return undefined;
|
|
874
|
+
return { family: match.family, major: Number(match.major), minor: Number(match.minor ?? 0) };
|
|
875
|
+
};
|
|
863
876
|
const supportsThinkingBlockBinding = (model) => {
|
|
864
877
|
const override = model.compatibility?.supportsThinkingBlockBinding;
|
|
865
878
|
if (override !== undefined)
|
|
866
879
|
return override;
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
880
|
+
const version = claudeVersion(model.id);
|
|
881
|
+
return version !== undefined && (version.major > 5 || (version.major === 5 && version.minor >= 1));
|
|
882
|
+
};
|
|
883
|
+
const supportsEffortUpdates = (model) => {
|
|
884
|
+
const override = model.compatibility?.supportsEffortUpdates;
|
|
885
|
+
if (override !== undefined)
|
|
886
|
+
return override;
|
|
887
|
+
const version = claudeVersion(model.id);
|
|
888
|
+
if (version === undefined)
|
|
870
889
|
return false;
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
890
|
+
if (version.family === "opus")
|
|
891
|
+
return version.major >= 5;
|
|
892
|
+
if (version.family !== "fable" && version.family !== "mythos")
|
|
893
|
+
return false;
|
|
894
|
+
return version.major > 5 || (version.major === 5 && version.minor >= 1);
|
|
874
895
|
};
|
|
875
896
|
const applyThinkingBindingDefault = (model, thinking) => {
|
|
876
897
|
if (thinking?.type === "disabled")
|
|
@@ -909,13 +930,15 @@ const resolveThinking = Effect.fn("AnthropicMessages.resolveThinking")(function*
|
|
|
909
930
|
});
|
|
910
931
|
const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (request) {
|
|
911
932
|
const management = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Schema.UndefinedOr(ContextManagement)))(request.providerOptions?.contextManagement);
|
|
933
|
+
const options = yield* resolveOptions(request);
|
|
934
|
+
const updates = resolveEffortUpdates(request, options.effort);
|
|
912
935
|
const generation = request.generation;
|
|
913
936
|
const toolSchemaCompatibility = request.model.compatibility?.toolSchema;
|
|
914
937
|
// Allocate the 4-breakpoint budget in invalidation order: tools → system →
|
|
915
938
|
// messages. Tools live highest in the cache hierarchy, so when callers
|
|
916
939
|
// over-mark we keep their tool hints and shed the message-tail ones first.
|
|
917
940
|
const breakpoints = Cache.newBreakpoints(ANTHROPIC_BREAKPOINT_CAP);
|
|
918
|
-
const flattened = ProviderShared.flattenToolRequest(request);
|
|
941
|
+
const flattened = ProviderShared.flattenToolRequest(updates.request);
|
|
919
942
|
const tools = flattened.tools.length === 0
|
|
920
943
|
? undefined
|
|
921
944
|
: flattened.tools.map((tool) => lowerTool(breakpoints, tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, toolSchemaCompatibility)));
|
|
@@ -933,7 +956,12 @@ const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (reques
|
|
|
933
956
|
if (breakpoints.dropped > 0) {
|
|
934
957
|
yield* Effect.logWarning(`Anthropic Messages: dropped ${breakpoints.dropped} cache breakpoint(s); the API allows at most ${ANTHROPIC_BREAKPOINT_CAP} per request.`);
|
|
935
958
|
}
|
|
936
|
-
const
|
|
959
|
+
const output_config = updates.effort === undefined && options.format === undefined
|
|
960
|
+
? undefined
|
|
961
|
+
: {
|
|
962
|
+
...(updates.effort === undefined ? {} : { effort: updates.effort }),
|
|
963
|
+
...(options.format === undefined ? {} : { format: options.format }),
|
|
964
|
+
};
|
|
937
965
|
const body = {
|
|
938
966
|
model: request.model.id,
|
|
939
967
|
system,
|
|
@@ -947,7 +975,7 @@ const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (reques
|
|
|
947
975
|
top_k: generation?.topK,
|
|
948
976
|
stop_sequences: generation?.stop,
|
|
949
977
|
thinking: options.thinking,
|
|
950
|
-
output_config
|
|
978
|
+
output_config,
|
|
951
979
|
// top-level passthrough per SDK MessageCreateParamsBase:4638,4643,4649,4654,4670
|
|
952
980
|
cache_control: options.cache_control,
|
|
953
981
|
container: options.container,
|
|
@@ -1404,6 +1432,7 @@ export const protocol = Protocol.make({
|
|
|
1404
1432
|
}),
|
|
1405
1433
|
step,
|
|
1406
1434
|
},
|
|
1435
|
+
supportsEffortUpdates: (request) => supportsEffortUpdates(request.model),
|
|
1407
1436
|
});
|
|
1408
1437
|
export const transport = () => {
|
|
1409
1438
|
const http = HttpTransport.httpJson({ framing });
|
|
@@ -1440,6 +1469,8 @@ function requiredBetaHeaders(body) {
|
|
|
1440
1469
|
const replaysCompaction = body.messages.some((message) => message.content.some((block) => block.type === "compaction"));
|
|
1441
1470
|
if (requestsCompaction || replaysCompaction)
|
|
1442
1471
|
betas.push("compact-2026-01-12");
|
|
1472
|
+
if (body.messages.some((message) => message.role === "system" && message.output_config !== undefined))
|
|
1473
|
+
betas.push("mid-conversation-output-config-2026-07-01");
|
|
1443
1474
|
const thinking = body.thinking;
|
|
1444
1475
|
if (thinking && thinking.type !== "disabled" && thinking.block_binding)
|
|
1445
1476
|
betas.push("thinking-binding-controls-2026-08-01");
|
|
@@ -175,7 +175,6 @@ export declare const protocol: Protocol<{
|
|
|
175
175
|
readonly content: string | null;
|
|
176
176
|
})[];
|
|
177
177
|
} | {
|
|
178
|
-
readonly role: "system";
|
|
179
178
|
readonly content: readonly {
|
|
180
179
|
readonly type: "text";
|
|
181
180
|
readonly text: string;
|
|
@@ -184,6 +183,10 @@ export declare const protocol: Protocol<{
|
|
|
184
183
|
readonly ttl?: "1h" | "5m" | undefined;
|
|
185
184
|
} | undefined;
|
|
186
185
|
}[];
|
|
186
|
+
readonly role: "system";
|
|
187
|
+
readonly output_config?: {
|
|
188
|
+
readonly effort: string;
|
|
189
|
+
} | undefined;
|
|
187
190
|
})[];
|
|
188
191
|
readonly stream: true;
|
|
189
192
|
readonly metadata?: {
|
|
@@ -153,7 +153,7 @@ export declare const protocol: Protocol<{
|
|
|
153
153
|
readonly instructions?: string | undefined;
|
|
154
154
|
readonly reasoning?: {
|
|
155
155
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
156
|
-
readonly effort?: import("
|
|
156
|
+
readonly effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
157
157
|
} | undefined;
|
|
158
158
|
readonly tools?: readonly ({
|
|
159
159
|
readonly type: "function";
|
|
@@ -409,7 +409,7 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
409
409
|
readonly instructions?: string | undefined;
|
|
410
410
|
readonly reasoning?: {
|
|
411
411
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
412
|
-
readonly effort?: import("
|
|
412
|
+
readonly effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
413
413
|
} | undefined;
|
|
414
414
|
readonly tools?: readonly ({
|
|
415
415
|
readonly type: "function";
|
|
@@ -90,6 +90,13 @@ export declare const CompactionItem: Schema.Struct<{
|
|
|
90
90
|
readonly id: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
91
91
|
readonly encrypted_content: Schema.String;
|
|
92
92
|
}>;
|
|
93
|
+
export declare const ConfigurationUpdate: Schema.Struct<{
|
|
94
|
+
readonly type: Schema.Literal<"configuration_update">;
|
|
95
|
+
readonly reasoning: Schema.Struct<{
|
|
96
|
+
readonly effort: Schema.declare<OpenResponsesOptions.ReasoningEffort, OpenResponsesOptions.ReasoningEffort>;
|
|
97
|
+
}>;
|
|
98
|
+
}>;
|
|
99
|
+
type ConfigurationUpdate = Schema.Schema.Type<typeof ConfigurationUpdate>;
|
|
93
100
|
export declare const InputItem: Schema.Union<readonly [Schema.Struct<{
|
|
94
101
|
readonly type: Schema.Literal<"compaction">;
|
|
95
102
|
readonly id: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
@@ -198,7 +205,7 @@ export type HostedToolReplayItem = {
|
|
|
198
205
|
readonly id: string;
|
|
199
206
|
readonly [key: string]: unknown;
|
|
200
207
|
};
|
|
201
|
-
type LoweredInputItem = OpenResponsesInputItem | HostedToolReplayItem | {
|
|
208
|
+
type LoweredInputItem = OpenResponsesInputItem | HostedToolReplayItem | ConfigurationUpdate | {
|
|
202
209
|
readonly type: "message";
|
|
203
210
|
readonly id?: string;
|
|
204
211
|
readonly role: "assistant";
|
|
@@ -845,7 +852,7 @@ export declare const lowerConversation: (request: LLMRequest<import("../schema/o
|
|
|
845
852
|
model: string & import("effect/Brand").Brand<"AI.ModelID">;
|
|
846
853
|
input: LoweredInputItem[];
|
|
847
854
|
}, AIError, never>;
|
|
848
|
-
export declare const lowerGeneration: (request: LLMRequest) => {
|
|
855
|
+
export declare const lowerGeneration: (request: LLMRequest, options?: OpenResponsesOptions.Resolved) => {
|
|
849
856
|
truncation?: "auto" | "disabled" | undefined;
|
|
850
857
|
parallel_tool_calls?: boolean | undefined;
|
|
851
858
|
max_tool_calls?: number | undefined;
|
|
@@ -4,6 +4,7 @@ import { Protocol } from "../route/protocol.js";
|
|
|
4
4
|
import { AIError, LLMEvent, ProviderInternalError, Usage, } from "../schema/index.js";
|
|
5
5
|
import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
|
|
6
6
|
import { classifyProviderFailure } from "../provider-error.js";
|
|
7
|
+
import { effortUpdate } from "../effort-updates.js";
|
|
7
8
|
import { OpenResponsesOptions } from "./utils/open-responses-options.js";
|
|
8
9
|
import { Lifecycle } from "./utils/lifecycle.js";
|
|
9
10
|
import { ToolSchemaProjection } from "./utils/tool-schema.js";
|
|
@@ -117,6 +118,11 @@ export const CompactionItem = Schema.Struct({
|
|
|
117
118
|
id: optionalNull(Schema.String),
|
|
118
119
|
encrypted_content: Schema.String,
|
|
119
120
|
});
|
|
121
|
+
// Kept out of the baseline `InputItem` union: only the OpenAI extension accepts it.
|
|
122
|
+
export const ConfigurationUpdate = Schema.Struct({
|
|
123
|
+
type: Schema.Literal("configuration_update"),
|
|
124
|
+
reasoning: Schema.Struct({ effort: OpenResponsesOptions.ReasoningEffort }),
|
|
125
|
+
});
|
|
120
126
|
export const InputItem = Schema.Union([
|
|
121
127
|
CompactionItem,
|
|
122
128
|
Schema.Struct({ role: Schema.tag("system"), content: Schema.String }),
|
|
@@ -423,12 +429,22 @@ const lowerToolResultOutput = Effect.fnUntraced(function* (part, request, adapte
|
|
|
423
429
|
const content = part.result.value;
|
|
424
430
|
return yield* Effect.forEach(content, (item) => lowerToolResultContentItem(item, request, adapter));
|
|
425
431
|
});
|
|
432
|
+
const DEFAULT_EFFORT = "medium";
|
|
426
433
|
const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (request, adapter) {
|
|
427
434
|
const input = [];
|
|
428
435
|
const providerMetadataKey = metadataKey(request.model);
|
|
429
436
|
for (const message of request.messages) {
|
|
430
437
|
const metadata = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Schema.UndefinedOr(MessageMetadata)))(message.providerMetadata?.[providerMetadataKey]);
|
|
431
438
|
if (message.role === "system") {
|
|
439
|
+
const update = effortUpdate(message);
|
|
440
|
+
if (update) {
|
|
441
|
+
// Consecutive updates are rejected, so a newer one replaces its predecessor.
|
|
442
|
+
const last = input.at(-1);
|
|
443
|
+
if (last !== undefined && "type" in last && last.type === "configuration_update")
|
|
444
|
+
input.pop();
|
|
445
|
+
input.push({ type: "configuration_update", reasoning: { effort: update.effort ?? DEFAULT_EFFORT } });
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
432
448
|
input.push({
|
|
433
449
|
role: "developer",
|
|
434
450
|
content: ProviderShared.joinText(yield* ProviderShared.systemUpdateText(adapter.name, message)),
|
|
@@ -561,8 +577,7 @@ export const lowerConversation = Effect.fn("OpenResponses.lowerConversation")(fu
|
|
|
561
577
|
...(instructions ? { instructions } : {}),
|
|
562
578
|
};
|
|
563
579
|
});
|
|
564
|
-
export const lowerGeneration = (request) => {
|
|
565
|
-
const options = OpenResponsesOptions.resolve(request);
|
|
580
|
+
export const lowerGeneration = (request, options = OpenResponsesOptions.resolve(request)) => {
|
|
566
581
|
const generation = request.generation;
|
|
567
582
|
const cacheKey = ProviderShared.promptCacheKey(request);
|
|
568
583
|
const parallelToolCalls = resolveParallelToolCalls(request);
|
|
@@ -97,7 +97,7 @@ export declare const bodyFields: {
|
|
|
97
97
|
}>>;
|
|
98
98
|
store: Schema.optional<Schema.Boolean>;
|
|
99
99
|
prompt_cache_key: Schema.optional<Schema.String>;
|
|
100
|
-
reasoning_effort: Schema.optional<Schema.declare<import("
|
|
100
|
+
reasoning_effort: Schema.optional<Schema.declare<import("../schema/options.js").ReasoningEffort, import("../schema/options.js").ReasoningEffort>>;
|
|
101
101
|
tool_stream: Schema.optional<Schema.Boolean>;
|
|
102
102
|
max_completion_tokens: Schema.optional<Schema.Number>;
|
|
103
103
|
max_tokens: Schema.optional<Schema.Number>;
|
|
@@ -193,7 +193,7 @@ declare const OpenAIChatBody: Schema.Struct<{
|
|
|
193
193
|
}>>;
|
|
194
194
|
store: Schema.optional<Schema.Boolean>;
|
|
195
195
|
prompt_cache_key: Schema.optional<Schema.String>;
|
|
196
|
-
reasoning_effort: Schema.optional<Schema.declare<import("
|
|
196
|
+
reasoning_effort: Schema.optional<Schema.declare<import("../schema/options.js").ReasoningEffort, import("../schema/options.js").ReasoningEffort>>;
|
|
197
197
|
tool_stream: Schema.optional<Schema.Boolean>;
|
|
198
198
|
max_completion_tokens: Schema.optional<Schema.Number>;
|
|
199
199
|
max_tokens: Schema.optional<Schema.Number>;
|
|
@@ -292,7 +292,7 @@ interface LoweringOptions {
|
|
|
292
292
|
export declare const fromRequest: (request: LLMRequest<import("../schema/options.js").LanguageModel<{
|
|
293
293
|
readonly [x: string]: unknown;
|
|
294
294
|
}, import("../route/client.js").CompactionOperations | undefined>>, options?: LoweringOptions | undefined) => Effect.Effect<{
|
|
295
|
-
reasoning_effort?: import("
|
|
295
|
+
reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
296
296
|
prompt_cache_key?: string | undefined;
|
|
297
297
|
store?: boolean | undefined;
|
|
298
298
|
temperature: number | undefined;
|
|
@@ -389,7 +389,7 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
389
389
|
} | undefined;
|
|
390
390
|
stream: true;
|
|
391
391
|
} | {
|
|
392
|
-
reasoning_effort?: import("
|
|
392
|
+
reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
393
393
|
prompt_cache_key?: string | undefined;
|
|
394
394
|
store?: boolean | undefined;
|
|
395
395
|
temperature: number | undefined;
|
|
@@ -584,7 +584,7 @@ export declare const protocol: Protocol<{
|
|
|
584
584
|
readonly frequency_penalty?: number | undefined;
|
|
585
585
|
readonly presence_penalty?: number | undefined;
|
|
586
586
|
readonly prompt_cache_key?: string | undefined;
|
|
587
|
-
readonly reasoning_effort?: import("
|
|
587
|
+
readonly reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
588
588
|
readonly store?: boolean | undefined;
|
|
589
589
|
readonly stream_options?: {
|
|
590
590
|
readonly include_usage: boolean;
|
|
@@ -751,7 +751,7 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
751
751
|
readonly frequency_penalty?: number | undefined;
|
|
752
752
|
readonly presence_penalty?: number | undefined;
|
|
753
753
|
readonly prompt_cache_key?: string | undefined;
|
|
754
|
-
readonly reasoning_effort?: import("
|
|
754
|
+
readonly reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
755
755
|
readonly store?: boolean | undefined;
|
|
756
756
|
readonly stream_options?: {
|
|
757
757
|
readonly include_usage: boolean;
|
|
@@ -850,7 +850,7 @@ export declare const route: Route<{
|
|
|
850
850
|
readonly frequency_penalty?: number | undefined;
|
|
851
851
|
readonly presence_penalty?: number | undefined;
|
|
852
852
|
readonly prompt_cache_key?: string | undefined;
|
|
853
|
-
readonly reasoning_effort?: import("
|
|
853
|
+
readonly reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
854
854
|
readonly store?: boolean | undefined;
|
|
855
855
|
readonly stream_options?: {
|
|
856
856
|
readonly include_usage: boolean;
|
|
@@ -99,7 +99,7 @@ export declare const route: Route<{
|
|
|
99
99
|
readonly frequency_penalty?: number | undefined;
|
|
100
100
|
readonly presence_penalty?: number | undefined;
|
|
101
101
|
readonly prompt_cache_key?: string | undefined;
|
|
102
|
-
readonly reasoning_effort?: import("
|
|
102
|
+
readonly reasoning_effort?: import("../index.js").ReasoningEffort | undefined;
|
|
103
103
|
readonly store?: boolean | undefined;
|
|
104
104
|
readonly stream_options?: {
|
|
105
105
|
readonly include_usage: boolean;
|
|
@@ -126,7 +126,7 @@ export declare const route: Route<{
|
|
|
126
126
|
readonly instructions?: string | undefined;
|
|
127
127
|
readonly reasoning?: {
|
|
128
128
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
129
|
-
readonly effort?: import("
|
|
129
|
+
readonly effort?: import("../index.js").ReasoningEffort | undefined;
|
|
130
130
|
} | undefined;
|
|
131
131
|
readonly tools?: readonly {
|
|
132
132
|
readonly type: "function";
|