@opencode/ai 0.0.0-dev-20867 → 0.0.0-dev-20869
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
CHANGED
|
@@ -143,17 +143,7 @@ const countHints = (request) => countToolHints(request.tools) +
|
|
|
143
143
|
request.messages.reduce((count, message) => count +
|
|
144
144
|
message.content.reduce((contentCount, part) => contentCount + ("cache" in part && part.cache !== undefined ? 1 : 0), 0), 0);
|
|
145
145
|
export const applyCachePolicy = (request) => {
|
|
146
|
-
const
|
|
147
|
-
if (!RESPECTS_INLINE_HINTS.has(route))
|
|
148
|
-
return request;
|
|
149
|
-
const policy = (route === "openrouter" || route === "vercel-ai-gateway-messages") &&
|
|
150
|
-
(request.cache === undefined || request.cache === "auto")
|
|
151
|
-
? gatewayPolicy(request.model.id)
|
|
152
|
-
: route === "alibaba-chat" && (request.cache === undefined || request.cache === "auto")
|
|
153
|
-
? request.model.id.toLowerCase().startsWith("qwen")
|
|
154
|
-
? QWEN
|
|
155
|
-
: NONE
|
|
156
|
-
: resolve(request.cache);
|
|
146
|
+
const policy = selectPolicy(request);
|
|
157
147
|
if (!policy.tools && !policy.system && !policy.messages)
|
|
158
148
|
return request;
|
|
159
149
|
const hint = makeHint(policy.ttlSeconds);
|
|
@@ -165,3 +155,22 @@ export const applyCachePolicy = (request) => {
|
|
|
165
155
|
return request;
|
|
166
156
|
return LLMRequest.update(request, { tools, system, messages });
|
|
167
157
|
};
|
|
158
|
+
// A declared cache format overrides the route allowlist and its model-ID heuristics.
|
|
159
|
+
const selectPolicy = (request) => {
|
|
160
|
+
const format = request.model.compatibility?.cacheFormat;
|
|
161
|
+
const route = request.model.route.id;
|
|
162
|
+
const auto = request.cache === undefined || request.cache === "auto";
|
|
163
|
+
if (format === "alibaba")
|
|
164
|
+
return auto ? QWEN : { ...resolve(request.cache), tools: false };
|
|
165
|
+
if (format === "anthropic")
|
|
166
|
+
return resolve(request.cache);
|
|
167
|
+
if (!RESPECTS_INLINE_HINTS.has(route))
|
|
168
|
+
return NONE;
|
|
169
|
+
if (!auto)
|
|
170
|
+
return resolve(request.cache);
|
|
171
|
+
if (route === "openrouter" || route === "vercel-ai-gateway-messages")
|
|
172
|
+
return gatewayPolicy(request.model.id);
|
|
173
|
+
if (route === "alibaba-chat")
|
|
174
|
+
return request.model.id.toLowerCase().startsWith("qwen") ? QWEN : NONE;
|
|
175
|
+
return AUTO;
|
|
176
|
+
};
|
|
@@ -9,6 +9,7 @@ import { Protocol } from "../route/protocol.js";
|
|
|
9
9
|
import { AIError, AIErrorReason, InvalidProviderOutputError, LLMEvent, ProviderInternalError, UnknownProviderError, Usage, } from "../schema/index.js";
|
|
10
10
|
import { classifyProviderFailure } from "../provider-error.js";
|
|
11
11
|
import { isRecord, JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
|
|
12
|
+
import { cacheControl } from "./utils/cache.js";
|
|
12
13
|
import { OpenAIOptions } from "./utils/openai-options.js";
|
|
13
14
|
import { Lifecycle } from "./utils/lifecycle.js";
|
|
14
15
|
import { ToolStream } from "./utils/tool-stream.js";
|
|
@@ -646,14 +647,15 @@ export const fromRequest = Effect.fn("OpenAIChat.fromRequest")(function* (reques
|
|
|
646
647
|
const zaiToolStream = request.model.compatibility?.zaiToolStream ?? detectZaiToolStream(provider, baseURL, request.model.id);
|
|
647
648
|
const hasHistory = hasToolHistory(request.messages);
|
|
648
649
|
const hasActiveTools = flattened.tools.length > 0;
|
|
650
|
+
const lowering = { ...options, cacheControl: options.cacheControl ?? declaredCacheControl(request) };
|
|
649
651
|
return {
|
|
650
652
|
model: request.model.id,
|
|
651
|
-
messages: yield* lowerMessages(flattened.request,
|
|
653
|
+
messages: yield* lowerMessages(flattened.request, lowering),
|
|
652
654
|
tools: flattened.tools.length === 0
|
|
653
655
|
? hasHistory
|
|
654
656
|
? []
|
|
655
657
|
: undefined
|
|
656
|
-
: flattened.tools.map((tool) => lowerTool(tool,
|
|
658
|
+
: flattened.tools.map((tool) => lowerTool(tool, lowering, supportsStrictMode)),
|
|
657
659
|
tool_choice: hasActiveTools && request.toolChoice ? yield* lowerToolChoice(request.toolChoice) : undefined,
|
|
658
660
|
stream: true,
|
|
659
661
|
...(supportsUsageInStreaming ? { stream_options: { include_usage: true } } : {}),
|
|
@@ -670,6 +672,8 @@ export const fromRequest = Effect.fn("OpenAIChat.fromRequest")(function* (reques
|
|
|
670
672
|
...lowerOptions(request, supportsStore),
|
|
671
673
|
};
|
|
672
674
|
});
|
|
675
|
+
// Provider wrappers that pass their own marker writer keep it; otherwise a declared cache format adds one.
|
|
676
|
+
const declaredCacheControl = (request) => request.model.compatibility?.cacheFormat === undefined ? undefined : cacheControl();
|
|
673
677
|
// =============================================================================
|
|
674
678
|
// Stream Parsing
|
|
675
679
|
// =============================================================================
|
package/dist/schema/options.d.ts
CHANGED
|
@@ -94,6 +94,8 @@ export declare const LanguageModelSanitizerCompatibility: Schema.Literals<readon
|
|
|
94
94
|
export type LanguageModelSanitizerCompatibility = Schema.Schema.Type<typeof LanguageModelSanitizerCompatibility>;
|
|
95
95
|
export declare const LanguageModelMaxTokensFieldCompatibility: Schema.Literals<readonly ["max_completion_tokens", "max_tokens"]>;
|
|
96
96
|
export type LanguageModelMaxTokensFieldCompatibility = Schema.Schema.Type<typeof LanguageModelMaxTokensFieldCompatibility>;
|
|
97
|
+
export declare const LanguageModelCacheFormatCompatibility: Schema.Literals<readonly ["anthropic", "alibaba"]>;
|
|
98
|
+
export type LanguageModelCacheFormatCompatibility = Schema.Schema.Type<typeof LanguageModelCacheFormatCompatibility>;
|
|
97
99
|
declare const LanguageModelCompatibility_base: Schema.Class<LanguageModelCompatibility, Schema.Struct<{
|
|
98
100
|
readonly sanitizer: Schema.optional<Schema.Literals<readonly ["gemini", "moonshot", "none"]>>;
|
|
99
101
|
readonly reasoningField: Schema.optional<Schema.String>;
|
|
@@ -106,6 +108,8 @@ declare const LanguageModelCompatibility_base: Schema.Class<LanguageModelCompati
|
|
|
106
108
|
readonly supportsUsageInStreaming: Schema.optional<Schema.Boolean>;
|
|
107
109
|
readonly supportsStrictMode: Schema.optional<Schema.Boolean>;
|
|
108
110
|
readonly supportsPromptCacheKey: Schema.optional<Schema.Boolean>;
|
|
111
|
+
/** Prompt-cache marker syntax the endpoint accepts. Overrides the route default; both send `cache_control`, and `alibaba` skips tool definitions. */
|
|
112
|
+
readonly cacheFormat: Schema.optional<Schema.Literals<readonly ["anthropic", "alibaba"]>>;
|
|
109
113
|
readonly zaiToolStream: Schema.optional<Schema.Boolean>;
|
|
110
114
|
readonly requireSignature: Schema.optional<Schema.Boolean>;
|
|
111
115
|
/** Supports Anthropic's thinking-prefix mismatch controls. Overrides model-ID detection. */
|
package/dist/schema/options.js
CHANGED
|
@@ -130,6 +130,7 @@ export const ReasoningEffort = Schema.declare((value) => typeof value === "strin
|
|
|
130
130
|
/** Tool schema sanitizer for a model family. `none` opts out of the protocol and model-name defaults. */
|
|
131
131
|
export const LanguageModelSanitizerCompatibility = Schema.Literals(["gemini", "moonshot", "none"]);
|
|
132
132
|
export const LanguageModelMaxTokensFieldCompatibility = Schema.Literals(["max_completion_tokens", "max_tokens"]);
|
|
133
|
+
export const LanguageModelCacheFormatCompatibility = Schema.Literals(["anthropic", "alibaba"]);
|
|
133
134
|
export class LanguageModelCompatibility extends Schema.Class("LLM.LanguageModelCompatibility")({
|
|
134
135
|
sanitizer: Schema.optional(LanguageModelSanitizerCompatibility),
|
|
135
136
|
reasoningField: Schema.optional(Schema.String),
|
|
@@ -145,6 +146,8 @@ export class LanguageModelCompatibility extends Schema.Class("LLM.LanguageModelC
|
|
|
145
146
|
// this is true; other protocols omit it only when this is false.
|
|
146
147
|
// Session-affinity headers still flow regardless.
|
|
147
148
|
supportsPromptCacheKey: Schema.optional(Schema.Boolean),
|
|
149
|
+
/** Prompt-cache marker syntax the endpoint accepts. Overrides the route default; both send `cache_control`, and `alibaba` skips tool definitions. */
|
|
150
|
+
cacheFormat: Schema.optional(LanguageModelCacheFormatCompatibility),
|
|
148
151
|
zaiToolStream: Schema.optional(Schema.Boolean),
|
|
149
152
|
requireSignature: Schema.optional(Schema.Boolean),
|
|
150
153
|
/** Supports Anthropic's thinking-prefix mismatch controls. Overrides model-ID detection. */
|
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-20869",
|
|
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.1",
|
|
37
|
-
"@opencode/http-recorder": "0.0.0-dev-
|
|
37
|
+
"@opencode/http-recorder": "0.0.0-dev-20869",
|
|
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-20869",
|
|
48
48
|
"aws4fetch": "1.0.20",
|
|
49
49
|
"effect": "4.0.1",
|
|
50
50
|
"google-auth-library": "10.5.0"
|