@opencode/ai 0.0.0-dev-21255 → 0.0.0-dev-21266

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.
@@ -29,7 +29,6 @@ declare const Options: Schema.Struct<{
29
29
  export type OptionsInput = typeof Options.Type;
30
30
  export declare const compatibility: {
31
31
  maxTokensField: "max_completion_tokens";
32
- supportsStore: false;
33
32
  supportsStrictMode: false;
34
33
  reasoningField: string;
35
34
  zaiToolStream: false;
@@ -29,7 +29,6 @@ const Options = Schema.Struct({
29
29
  });
30
30
  export const compatibility = {
31
31
  maxTokensField: "max_completion_tokens",
32
- supportsStore: false,
33
32
  supportsStrictMode: false,
34
33
  reasoningField: "reasoning_content",
35
34
  zaiToolStream: false,
@@ -549,45 +549,19 @@ const detectMaxTokensField = (provider, baseURL) => {
549
549
  return "max_tokens";
550
550
  return "max_completion_tokens";
551
551
  };
552
+ // `store` defaults to false on OpenAI and Azure, but org-level logging can still
553
+ // store requests that omit it, so send an explicit `store: false` there. Strict
554
+ // OpenAI-style APIs reject the field with a 400, so omit it everywhere else.
552
555
  const detectSupportsStore = (provider, baseURL) => {
553
556
  const p = provider.toLowerCase();
554
557
  const url = (baseURL ?? "").toLowerCase();
555
- const isNvidia = p === "nvidia" || url.includes("integrate.api.nvidia.com");
556
- const isMoonshot = p === "moonshotai" || p === "moonshotai-cn" || url.includes("api.moonshot.");
557
- const isTogether = p === "togetherai" || p === "together" || url.includes("api.together.");
558
- const isZai = p === "zai" ||
559
- p === "zai-coding-plan" ||
560
- p === "zhipuai" ||
561
- p === "zhipuai-coding-plan" ||
562
- url.includes("api.z.ai") ||
563
- url.includes("open.bigmodel.cn");
564
- const isDeepSeek = p === "deepseek" || url.includes("deepseek.com");
565
- const isCerebras = p === "cerebras" || url.includes("cerebras.ai");
566
- const isXai = p === "xai" || url.includes("api.x.ai");
567
- const isChutes = p === "chutes" || url.includes("chutes.ai");
568
- const isCloudflareWorkersAI = p === "cloudflare-workers-ai" || url.includes("api.cloudflare.com");
569
- const isCloudflareAiGateway = p === "cloudflare-ai-gateway" || url.includes("gateway.ai.cloudflare.com");
570
- const isVercelAiGateway = p === "vercel-ai-gateway" || url.includes("ai-gateway.vercel.sh") || url.includes("vercel.sh");
571
- const isAntLing = p === "ant-ling" || url.includes("api.ant-ling.com");
572
- const isOpencode = p === "opencode" || url.includes("opencode.ai");
573
- const isGemini = url.includes("generativelanguage.googleapis.com");
574
- const isNonStandard = isGemini ||
575
- isNvidia ||
576
- isCerebras ||
577
- isXai ||
578
- isTogether ||
579
- isChutes ||
580
- isDeepSeek ||
581
- isZai ||
582
- isMoonshot ||
583
- isOpencode ||
584
- isCloudflareWorkersAI ||
585
- isCloudflareAiGateway ||
586
- isVercelAiGateway ||
587
- isAntLing;
588
- return !isNonStandard;
558
+ return (p === "openai" ||
559
+ p === "azure" ||
560
+ url.includes("api.openai.com") ||
561
+ url.includes(".openai.azure.com") ||
562
+ url.includes(".cognitiveservices.azure.com") ||
563
+ url.includes(".services.ai.azure.com"));
589
564
  };
590
- const detectSupportsUsageInStreaming = () => true;
591
565
  const detectSupportsStrictMode = (provider, baseURL) => {
592
566
  const p = provider.toLowerCase();
593
567
  const url = (baseURL ?? "").toLowerCase();
@@ -620,11 +594,7 @@ const lowerOptions = (request, supportsStore) => {
620
594
  // (x-session-affinity, x-grok-conv-id, ...) is unaffected.
621
595
  const cacheKey = (request.model.compatibility?.supportsPromptCacheKey ?? false) ? ProviderShared.promptCacheKey(request) : undefined;
622
596
  return {
623
- ...(supportsStore && options.store !== undefined ? { store: options.store } : {}),
624
- // For providers that support `store`, ensure stateless `store:false` is sent
625
- // even when no explicit `providerOptions.store` was supplied, mirroring the
626
- // native OpenAI Chat default. Non-standard providers omit `store` entirely.
627
- ...(supportsStore && options.store === undefined ? { store: false } : {}),
597
+ ...(supportsStore ? { store: options.store ?? false } : {}),
628
598
  ...(cacheKey ? { prompt_cache_key: cacheKey } : {}),
629
599
  ...(options.reasoningEffort ? { reasoning_effort: options.reasoningEffort } : {}),
630
600
  };
@@ -642,7 +612,6 @@ export const fromRequest = Effect.fn("OpenAIChat.fromRequest")(function* (reques
642
612
  const detectedMaxTokensField = detectMaxTokensField(provider, baseURL);
643
613
  const maxTokensField = request.model.compatibility?.maxTokensField ?? detectedMaxTokensField;
644
614
  const supportsStore = request.model.compatibility?.supportsStore ?? detectSupportsStore(provider, baseURL);
645
- const supportsUsageInStreaming = request.model.compatibility?.supportsUsageInStreaming ?? detectSupportsUsageInStreaming();
646
615
  const supportsStrictMode = request.model.compatibility?.supportsStrictMode ?? detectSupportsStrictMode(provider, baseURL);
647
616
  const zaiToolStream = request.model.compatibility?.zaiToolStream ?? detectZaiToolStream(provider, baseURL, request.model.id);
648
617
  const hasHistory = hasToolHistory(request.messages);
@@ -658,7 +627,7 @@ export const fromRequest = Effect.fn("OpenAIChat.fromRequest")(function* (reques
658
627
  : flattened.tools.map((tool) => lowerTool(tool, lowering, supportsStrictMode)),
659
628
  tool_choice: hasActiveTools && request.toolChoice ? yield* lowerToolChoice(request.toolChoice) : undefined,
660
629
  stream: true,
661
- ...(supportsUsageInStreaming ? { stream_options: { include_usage: true } } : {}),
630
+ ...((request.model.compatibility?.streamUsage ?? true) ? { stream_options: { include_usage: true } } : {}),
662
631
  ...(zaiToolStream && hasActiveTools ? { tool_stream: true } : {}),
663
632
  ...(maxTokensField === "max_completion_tokens"
664
633
  ? { max_completion_tokens: generation?.maxTokens }
@@ -49,7 +49,6 @@ interface State {
49
49
  }
50
50
  export declare const compatibility: {
51
51
  maxTokensField: "max_completion_tokens";
52
- supportsStore: false;
53
52
  supportsPromptCacheKey: true;
54
53
  };
55
54
  export declare const protocol: Protocol<{
@@ -260,7 +260,6 @@ const onHalt = Effect.fn("VeniceChat.onHalt")(function* (state) {
260
260
  });
261
261
  export const compatibility = {
262
262
  maxTokensField: "max_completion_tokens",
263
- supportsStore: false,
264
263
  supportsPromptCacheKey: true,
265
264
  };
266
265
  export const protocol = Protocol.make({
@@ -18,7 +18,6 @@ export type OptionsInput = {
18
18
  };
19
19
  export declare const compatibility: {
20
20
  maxTokensField: "max_tokens";
21
- supportsStore: false;
22
21
  supportsStrictMode: false;
23
22
  reasoningField: string;
24
23
  zaiToolStream: false;
@@ -39,7 +39,6 @@ const fromRequest = Effect.fn("ZAIChat.fromRequest")(function* (request) {
39
39
  });
40
40
  export const compatibility = {
41
41
  maxTokensField: "max_tokens",
42
- supportsStore: false,
43
42
  supportsStrictMode: false,
44
43
  reasoningField: "reasoning_content",
45
44
  zaiToolStream: false,
@@ -28,7 +28,6 @@ export const configure = (input = {}) => {
28
28
  compatibility: {
29
29
  maxTokensField: "max_tokens",
30
30
  reasoningField: "reasoning",
31
- supportsStore: false,
32
31
  supportsPromptCacheKey: true,
33
32
  },
34
33
  }),
@@ -28,8 +28,6 @@ export const configure = (input = {}) => {
28
28
  id: modelID,
29
29
  compatibility: {
30
30
  maxTokensField: "max_tokens",
31
- supportsStore: false,
32
- supportsUsageInStreaming: true,
33
31
  reasoningField: "reasoning_content",
34
32
  supportsStrictMode: false,
35
33
  },
@@ -31,7 +31,6 @@ export const configure = (input = {}) => {
31
31
  compatibility: {
32
32
  maxTokensField: "max_tokens",
33
33
  reasoningField: "reasoning_content",
34
- supportsStore: false,
35
34
  supportsPromptCacheKey: true,
36
35
  },
37
36
  }),
@@ -25,7 +25,7 @@ export const configure = (input = {}) => {
25
25
  id,
26
26
  model: (modelID) => configured.model({
27
27
  id: modelID,
28
- compatibility: { maxTokensField: "max_tokens", supportsStore: false },
28
+ compatibility: { maxTokensField: "max_tokens" },
29
29
  }),
30
30
  configure,
31
31
  };
@@ -63,7 +63,6 @@ export const configure = (input = {}) => {
63
63
  maxTokensField: "max_completion_tokens",
64
64
  reasoningField: "reasoning",
65
65
  requireReasoning: false,
66
- supportsStore: false,
67
66
  supportsStrictMode: false,
68
67
  },
69
68
  }),
@@ -79,7 +79,7 @@ export const configure = (input = {}) => {
79
79
  const responses = (modelID) => configuredResponses.model({ id: modelID });
80
80
  const chat = (modelID) => configuredChat.model({
81
81
  id: modelID,
82
- compatibility: { maxTokensField: "max_completion_tokens", supportsStore: false, supportsPromptCacheKey: true },
82
+ compatibility: { maxTokensField: "max_completion_tokens", supportsPromptCacheKey: true },
83
83
  });
84
84
  const messages = (modelID) => configuredMessages.model({
85
85
  id: modelID,
@@ -70,7 +70,7 @@ export const configure = (input = {}) => {
70
70
  const messages = (modelID) => messagesRoute.with(defaults).model({ id: modelID });
71
71
  const chat = (modelID) => chatRoute.with(defaults).model({
72
72
  id: modelID,
73
- compatibility: { supportsStore: false, supportsStrictMode: false },
73
+ compatibility: { supportsStrictMode: false },
74
74
  });
75
75
  const responses = (modelID) => responsesRoute.with(defaults).model({ id: modelID });
76
76
  return { id, model: messages, messages, chat, responses, configure };
@@ -61,7 +61,6 @@ export const configure = (input = {}) => {
61
61
  id: modelID,
62
62
  compatibility: {
63
63
  maxTokensField: "max_tokens",
64
- supportsStore: false,
65
64
  supportsStrictMode: false,
66
65
  supportsPromptCacheKey: true,
67
66
  sanitizer: "moonshot",
@@ -25,7 +25,7 @@ export const configure = (input = {}) => {
25
25
  id,
26
26
  model: (modelID) => configured.model({
27
27
  id: modelID,
28
- compatibility: { maxTokensField: "max_tokens", supportsStore: false, supportsStrictMode: false },
28
+ compatibility: { maxTokensField: "max_tokens", supportsStrictMode: false },
29
29
  }),
30
30
  configure,
31
31
  };
@@ -110,7 +110,8 @@ declare const LanguageModelCompatibility_base: Schema.Class<LanguageModelCompati
110
110
  readonly requireFinishReason: Schema.optional<Schema.Boolean>;
111
111
  readonly requireAssistantAfterTool: Schema.optional<Schema.Boolean>;
112
112
  readonly supportsStore: Schema.optional<Schema.Boolean>;
113
- readonly supportsUsageInStreaming: Schema.optional<Schema.Boolean>;
113
+ /** Request usage in the stream with `stream_options.include_usage`. Defaults to true. */
114
+ readonly streamUsage: Schema.optional<Schema.Boolean>;
114
115
  readonly supportsStrictMode: Schema.optional<Schema.Boolean>;
115
116
  readonly supportsPromptCacheKey: Schema.optional<Schema.Boolean>;
116
117
  /** Prompt-cache marker syntax the endpoint accepts. Overrides the route default; both send `cache_control`, and `alibaba` skips tool definitions. */
@@ -145,7 +145,8 @@ export class LanguageModelCompatibility extends Schema.Class("LLM.LanguageModelC
145
145
  requireFinishReason: Schema.optional(Schema.Boolean),
146
146
  requireAssistantAfterTool: Schema.optional(Schema.Boolean),
147
147
  supportsStore: Schema.optional(Schema.Boolean),
148
- supportsUsageInStreaming: Schema.optional(Schema.Boolean),
148
+ /** Request usage in the stream with `stream_options.include_usage`. Defaults to true. */
149
+ streamUsage: Schema.optional(Schema.Boolean),
149
150
  supportsStrictMode: Schema.optional(Schema.Boolean),
150
151
  // Accepts `prompt_cache_key` in the request body. Chat omits the key unless
151
152
  // this is true; other protocols omit it only when this is false.
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-21255",
3
+ "version": "0.0.0-dev-21266",
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-21255",
37
+ "@opencode/http-recorder": "0.0.0-dev-21266",
38
38
  "@tsconfig/bun": "1.0.9",
39
39
  "@types/bun": "1.4.0",
40
40
  "@typescript/native": "npm:typescript@7.0.2",
@@ -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-21255",
47
+ "@opencode/schema": "0.0.0-dev-21266",
48
48
  "aws4fetch": "1.0.20",
49
49
  "effect": "4.0.1",
50
50
  "google-auth-library": "10.5.0"