@dan-ai-studio/dshopencodego 0.1.73 → 0.1.75

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/lib/index.js CHANGED
@@ -229,19 +229,38 @@ function createSetupErrorMessage(model, error, timestamp) {
229
229
  function hasResult(source) {
230
230
  return typeof source.result === "function";
231
231
  }
232
- async function forwardStream(target, source) {
232
+ async function forwardStream(target, source, observer2, observeResult) {
233
+ let result;
233
234
  for await (const event of source) {
234
235
  target.push(event);
235
- }
236
- target.end(hasResult(source) ? await source.result() : void 0);
237
- }
238
- function lazyStream(model, setup) {
236
+ observer2?.onEvent?.(event);
237
+ if (event.type === "done")
238
+ result = event.message;
239
+ else if (event.type === "error")
240
+ result = event.error;
241
+ }
242
+ if (hasResult(source))
243
+ result = await source.result();
244
+ target.end(result);
245
+ observeResult(result);
246
+ }
247
+ function lazyStream(model, setup, observer2) {
239
248
  const startedAt = Date.now();
240
249
  const outer = new AssistantMessageEventStream();
241
- setup().then((inner) => forwardStream(outer, inner)).catch((error) => {
250
+ let observedResult = false;
251
+ const observeResult = (result) => {
252
+ if (observedResult)
253
+ return;
254
+ observedResult = true;
255
+ observer2?.onResult?.(result);
256
+ };
257
+ setup().then((inner) => forwardStream(outer, inner, observer2, observeResult)).catch((error) => {
242
258
  const message = createSetupErrorMessage(model, error, startedAt);
243
- outer.push({ type: "error", reason: "error", error: message });
259
+ const event = { type: "error", reason: "error", error: message };
260
+ outer.push(event);
261
+ observer2?.onEvent?.(event);
244
262
  outer.end(message);
263
+ observeResult(message);
245
264
  });
246
265
  return outer;
247
266
  }
@@ -323,6 +342,84 @@ var init_resolve = __esm({
323
342
  }
324
343
  });
325
344
 
345
+ // node_modules/@earendil-works/pi-ai/dist/utils/version.js
346
+ var PI_AI_VERSION;
347
+ var init_version = __esm({
348
+ "node_modules/@earendil-works/pi-ai/dist/utils/version.js"() {
349
+ PI_AI_VERSION = "1.4.0";
350
+ }
351
+ });
352
+
353
+ // node_modules/@earendil-works/pi-ai/dist/utils/identity.js
354
+ function getClientVersion(identity) {
355
+ return identity?.version ?? PI_AI_VERSION;
356
+ }
357
+ function runtimeDescription() {
358
+ if (typeof process === "undefined")
359
+ return void 0;
360
+ const versions = process.versions;
361
+ if (versions?.bun)
362
+ return `bun/${versions.bun}`;
363
+ if (versions?.node)
364
+ return `node/${process.version}`;
365
+ return void 0;
366
+ }
367
+ function formatUserAgent(identity) {
368
+ const mode = identity?.userAgent ?? "detailed";
369
+ if (typeof mode === "object")
370
+ return mode.custom;
371
+ if (mode === "short")
372
+ return "pi";
373
+ const product = `pi/${getClientVersion(identity)}`;
374
+ const runtime = runtimeDescription();
375
+ return runtime ? `${product} (${process.platform}; ${runtime}; ${process.arch})` : `${product} (browser)`;
376
+ }
377
+ function matchesHost(baseUrl, expectedHost) {
378
+ try {
379
+ return new URL(baseUrl).hostname === expectedHost;
380
+ } catch {
381
+ return false;
382
+ }
383
+ }
384
+ function isOpenRouter(target) {
385
+ return target.provider === "openrouter" || target.baseUrl.includes("openrouter.ai");
386
+ }
387
+ function isNvidiaNim(target) {
388
+ return target.provider === "nvidia" || matchesHost(target.baseUrl, NVIDIA_NIM_HOST);
389
+ }
390
+ function isOpenCode(target) {
391
+ return target.provider === "opencode" || target.provider === "opencode-go" || matchesHost(target.baseUrl, OPENCODE_HOST);
392
+ }
393
+ function getAttributionHeaders(target, identity) {
394
+ const attribution = identity?.attribution;
395
+ if (!attribution)
396
+ return {};
397
+ const { name: name2, url, categories } = attribution;
398
+ if (isOpenRouter(target)) {
399
+ return {
400
+ "HTTP-Referer": url,
401
+ "X-OpenRouter-Title": name2,
402
+ ...categories === void 0 || categories.length === 0 ? {} : { "X-OpenRouter-Categories": categories.join(",") }
403
+ };
404
+ }
405
+ if (isNvidiaNim(target))
406
+ return { "X-BILLING-INVOKE-ORIGIN": name2.charAt(0).toUpperCase() + name2.slice(1) };
407
+ if (isOpenCode(target))
408
+ return { "x-opencode-client": name2 };
409
+ return {};
410
+ }
411
+ function getIdentityHeaders(target, identity) {
412
+ return { "User-Agent": formatUserAgent(identity), ...getAttributionHeaders(target, identity) };
413
+ }
414
+ var NVIDIA_NIM_HOST, OPENCODE_HOST;
415
+ var init_identity = __esm({
416
+ "node_modules/@earendil-works/pi-ai/dist/utils/identity.js"() {
417
+ init_version();
418
+ NVIDIA_NIM_HOST = "integrate.api.nvidia.com";
419
+ OPENCODE_HOST = "opencode.ai";
420
+ }
421
+ });
422
+
326
423
  // node_modules/@earendil-works/pi-ai/dist/utils/model-operations.js
327
424
  function getModelType(model) {
328
425
  return model.type ?? "chat";
@@ -472,27 +569,30 @@ function getDeclaredTools(messages) {
472
569
  }
473
570
  return [...definitions.values()];
474
571
  }
475
- function hasNonAdditiveToolChanges(messages) {
572
+ function findLastNonAdditiveToolChange(systemMessages) {
476
573
  const declared = /* @__PURE__ */ new Set();
477
- for (const message of messages) {
478
- if (!isSystemMessage(message))
479
- continue;
574
+ let last = -1;
575
+ for (let index = 0; index < systemMessages.length; index++) {
576
+ const message = systemMessages[index];
480
577
  if ((message.toolsRemoved?.length ?? 0) > 0)
481
- return true;
578
+ last = index;
482
579
  for (const tool of message.toolsAdded ?? []) {
483
580
  if (declared.has(tool.name))
484
- return true;
581
+ last = index;
485
582
  declared.add(tool.name);
486
583
  }
487
584
  }
488
- return false;
585
+ return last;
489
586
  }
490
- function resolveTranscriptTools(messages, supportsToolAdditions) {
491
- const anchorsAdditions = supportsToolAdditions && !hasNonAdditiveToolChanges(messages);
492
- return {
493
- requestTools: anchorsAdditions ? getInitialSystemMessage(messages)?.toolsAdded ?? [] : getCurrentTools(messages),
494
- anchorsAdditions
495
- };
587
+ function resolveTranscriptTools(messages, support) {
588
+ const systemMessages = messages.filter(isSystemMessage);
589
+ if (support === "none") {
590
+ return { requestTools: getCurrentTools(systemMessages), foldedSystemMessages: systemMessages.length };
591
+ }
592
+ if (support === "changes")
593
+ return { requestTools: [], foldedSystemMessages: 0 };
594
+ const folded = Math.max(getInitialSystemMessage(messages) ? 1 : 0, findLastNonAdditiveToolChange(systemMessages) + 1);
595
+ return { requestTools: getCurrentTools(systemMessages.slice(0, folded)), foldedSystemMessages: folded };
496
596
  }
497
597
  var init_transcript = __esm({
498
598
  "node_modules/@earendil-works/pi-ai/dist/utils/transcript.js"() {
@@ -916,7 +1016,7 @@ var init_sleep = __esm({
916
1016
 
917
1017
  // node_modules/@anthropic-ai/sdk/version.mjs
918
1018
  var VERSION;
919
- var init_version = __esm({
1019
+ var init_version2 = __esm({
920
1020
  "node_modules/@anthropic-ai/sdk/version.mjs"() {
921
1021
  VERSION = "0.129.0";
922
1022
  }
@@ -961,7 +1061,7 @@ function getBrowserInfo() {
961
1061
  var isRunningInBrowser, getPlatformProperties, normalizeArch, normalizePlatform, _platformHeaders, getPlatformHeaders;
962
1062
  var init_detect_platform = __esm({
963
1063
  "node_modules/@anthropic-ai/sdk/internal/detect-platform.mjs"() {
964
- init_version();
1064
+ init_version2();
965
1065
  isRunningInBrowser = () => {
966
1066
  return (
967
1067
  // @ts-ignore
@@ -2339,7 +2439,7 @@ var init_oidc_federation = __esm({
2339
2439
  "node_modules/@anthropic-ai/sdk/lib/credentials/oidc-federation.mjs"() {
2340
2440
  init_types();
2341
2441
  init_time();
2342
- init_version();
2442
+ init_version2();
2343
2443
  }
2344
2444
  });
2345
2445
 
@@ -2421,7 +2521,7 @@ var init_user_oauth = __esm({
2421
2521
  init_credentials();
2422
2522
  init_types();
2423
2523
  init_time();
2424
- init_version();
2524
+ init_version2();
2425
2525
  }
2426
2526
  });
2427
2527
 
@@ -16974,7 +17074,7 @@ var init_client = __esm({
16974
17074
  init_shims();
16975
17075
  init_request_options();
16976
17076
  init_query();
16977
- init_version();
17077
+ init_version2();
16978
17078
  init_error();
16979
17079
  init_types();
16980
17080
  init_token_cache();
@@ -18221,23 +18321,6 @@ var init_json_parse = __esm({
18221
18321
  }
18222
18322
  });
18223
18323
 
18224
- // node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js
18225
- function loadNodeOs() {
18226
- if (typeof process === "undefined" || !(process.versions?.node || process.versions?.bun)) {
18227
- return null;
18228
- }
18229
- return process.getBuiltinModule?.("node:os") ?? null;
18230
- }
18231
- function getPiUserAgent() {
18232
- return nodeOs ? `pi (${nodeOs.platform()} ${nodeOs.release()}; ${nodeOs.arch()})` : "pi (browser)";
18233
- }
18234
- var nodeOs;
18235
- var init_pi_user_agent = __esm({
18236
- "node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js"() {
18237
- nodeOs = loadNodeOs();
18238
- }
18239
- });
18240
-
18241
18324
  // node_modules/@earendil-works/pi-ai/dist/utils/provider-retry.js
18242
18325
  function isProviderError(error) {
18243
18326
  if (!(error instanceof Error) || !("status" in error) || !("headers" in error))
@@ -18704,13 +18787,14 @@ function buildBaseOptions(model, context, options, apiKey) {
18704
18787
  samplingParams,
18705
18788
  maxTokens: clampMaxTokensToContext(model, context, options?.maxTokens ?? model.maxTokens),
18706
18789
  signal: options?.signal,
18707
- telemetryContext: options?.telemetryContext,
18790
+ telemetry: options?.telemetry,
18708
18791
  apiKey: apiKey || options?.apiKey,
18709
18792
  fetch: options?.fetch,
18710
18793
  transport: options?.transport,
18711
18794
  cacheRetention: options?.cacheRetention,
18712
18795
  sessionId: options?.sessionId,
18713
18796
  headers: options?.headers,
18797
+ identity: options?.identity,
18714
18798
  onPayload: options?.onPayload,
18715
18799
  onResponse: options?.onResponse,
18716
18800
  onProviderStreamEvent: options?.onProviderStreamEvent,
@@ -18997,12 +19081,12 @@ function shouldUseServerSideFallbackBeta(model) {
18997
19081
  return (model.compat?.allowedFallbackModels?.length ?? 0) > 0;
18998
19082
  }
18999
19083
  function getAnthropicCompat(model) {
19000
- const isOpenRouter = model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai");
19084
+ const isOpenRouter2 = model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai");
19001
19085
  return {
19002
19086
  supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? true,
19003
19087
  supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
19004
- sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? isOpenRouter,
19005
- sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter ? "openrouter" : void 0),
19088
+ sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? isOpenRouter2,
19089
+ sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter2 ? "openrouter" : void 0),
19006
19090
  supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? true,
19007
19091
  supportsTemperature: model.compat?.supportsTemperature ?? true,
19008
19092
  allowEmptySignature: model.compat?.allowEmptySignature ?? false,
@@ -19020,9 +19104,6 @@ function mergeHeaders(...headerSources) {
19020
19104
  }
19021
19105
  return merged;
19022
19106
  }
19023
- function mergeClientHeaders(...headerSources) {
19024
- return mergeHeaders({ "User-Agent": getPiUserAgent() }, ...headerSources);
19025
- }
19026
19107
  function hasHeader(headers, name2) {
19027
19108
  if (!headers)
19028
19109
  return false;
@@ -19217,7 +19298,7 @@ function mapThinkingLevelToEffort(model, level) {
19217
19298
  function isOAuthToken(apiKey) {
19218
19299
  return apiKey.includes("sk-ant-oat");
19219
19300
  }
19220
- function createClient(model, apiKey, optionsHeaders, fetch2, dynamicHeaders, sessionId, federation) {
19301
+ function createClient(model, apiKey, optionsHeaders, fetch2, dynamicHeaders, sessionId, federation, identity) {
19221
19302
  if (model.provider === "github-copilot") {
19222
19303
  const client2 = new PiAnthropic({
19223
19304
  apiKey: null,
@@ -19225,7 +19306,7 @@ function createClient(model, apiKey, optionsHeaders, fetch2, dynamicHeaders, ses
19225
19306
  baseURL: model.baseUrl,
19226
19307
  dangerouslyAllowBrowser: true,
19227
19308
  fetch: fetch2,
19228
- defaultHeaders: mergeClientHeaders({
19309
+ defaultHeaders: mergeHeaders(getIdentityHeaders(model, identity), {
19229
19310
  accept: "application/json",
19230
19311
  "anthropic-dangerous-direct-browser-access": "true"
19231
19312
  }, model.headers, dynamicHeaders, optionsHeaders)
@@ -19239,7 +19320,7 @@ function createClient(model, apiKey, optionsHeaders, fetch2, dynamicHeaders, ses
19239
19320
  baseURL: model.baseUrl,
19240
19321
  dangerouslyAllowBrowser: true,
19241
19322
  fetch: fetch2,
19242
- defaultHeaders: mergeClientHeaders({
19323
+ defaultHeaders: mergeHeaders({
19243
19324
  accept: "application/json",
19244
19325
  "anthropic-dangerous-direct-browser-access": "true",
19245
19326
  "user-agent": `claude-cli/${claudeCodeVersion}`,
@@ -19254,7 +19335,7 @@ function createClient(model, apiKey, optionsHeaders, fetch2, dynamicHeaders, ses
19254
19335
  const header = compat.sessionAffinityFormat === "openrouter" ? "x-session-id" : "x-session-affinity";
19255
19336
  sessionAffinityHeaders[header] = sessionId;
19256
19337
  }
19257
- const defaultHeaders = mergeClientHeaders({
19338
+ const defaultHeaders = mergeHeaders(getIdentityHeaders(model, identity), {
19258
19339
  accept: "application/json",
19259
19340
  "anthropic-dangerous-direct-browser-access": "true"
19260
19341
  }, sessionAffinityHeaders, model.headers, optionsHeaders);
@@ -19679,8 +19760,8 @@ var init_anthropic_messages = __esm({
19679
19760
  init_diagnostics();
19680
19761
  init_event_stream();
19681
19762
  init_headers2();
19763
+ init_identity();
19682
19764
  init_json_parse();
19683
- init_pi_user_agent();
19684
19765
  init_provider_env();
19685
19766
  init_provider_retry();
19686
19767
  init_sanitize_unicode();
@@ -19791,7 +19872,7 @@ var init_anthropic_messages = __esm({
19791
19872
  }
19792
19873
  const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
19793
19874
  const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
19794
- const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation);
19875
+ const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation, options?.identity);
19795
19876
  client = created.client;
19796
19877
  isOAuth = created.isOAuthToken;
19797
19878
  }
@@ -21582,7 +21663,7 @@ var init_parse2 = __esm({
21582
21663
 
21583
21664
  // node_modules/openai/version.mjs
21584
21665
  var VERSION2;
21585
- var init_version2 = __esm({
21666
+ var init_version3 = __esm({
21586
21667
  "node_modules/openai/version.mjs"() {
21587
21668
  VERSION2 = "7.19.0";
21588
21669
  }
@@ -21627,7 +21708,7 @@ function getBrowserInfo2() {
21627
21708
  var isRunningInBrowser2, getPlatformProperties2, normalizeArch2, normalizePlatform2, _platformHeaders2, getPlatformHeaders2;
21628
21709
  var init_detect_platform2 = __esm({
21629
21710
  "node_modules/openai/internal/detect-platform.mjs"() {
21630
- init_version2();
21711
+ init_version3();
21631
21712
  isRunningInBrowser2 = () => {
21632
21713
  return (
21633
21714
  // @ts-ignore
@@ -39053,7 +39134,7 @@ var init_client2 = __esm({
39053
39134
  init_shims2();
39054
39135
  init_request_options2();
39055
39136
  init_query2();
39056
- init_version2();
39137
+ init_version3();
39057
39138
  init_data_residency();
39058
39139
  init_error3();
39059
39140
  init_pagination2();
@@ -40465,8 +40546,8 @@ function resolveCacheRetention2(cacheRetention, env) {
40465
40546
  }
40466
40547
  return "short";
40467
40548
  }
40468
- function createClient2(model, context, apiKey, optionsHeaders, fetch2, sessionId, compat = getCompat(model)) {
40469
- const headers = { "User-Agent": getPiUserAgent(), ...model.headers };
40549
+ function createClient2(model, context, apiKey, optionsHeaders, identity, fetch2, sessionId, compat = getCompat(model)) {
40550
+ const headers = { ...getIdentityHeaders(model, identity), ...model.headers };
40470
40551
  if (model.provider === "github-copilot") {
40471
40552
  const hasImages = hasCopilotVisionInput(context.messages);
40472
40553
  const copilotHeaders = buildCopilotDynamicHeaders({
@@ -40498,7 +40579,7 @@ function createClient2(model, context, apiKey, optionsHeaders, fetch2, sessionId
40498
40579
  });
40499
40580
  }
40500
40581
  function buildParams2(model, context, options, compat = getCompat(model), cacheRetention = resolveCacheRetention2(options?.cacheRetention, options?.env), grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(context.messages), compat.supportsOpenAIGrammarTools)) {
40501
- const transcriptTools = resolveTranscriptTools(context.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true);
40582
+ const transcriptTools = resolveTranscriptTools(context.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true ? "additions" : "none");
40502
40583
  const messages = convertMessages2(model, context, compat, {
40503
40584
  grammarToolInputProperties
40504
40585
  });
@@ -40790,9 +40871,10 @@ function convertMessages2(model, context, compat, options) {
40790
40871
  return id;
40791
40872
  };
40792
40873
  const transformedMessages = transformMessages(normalizedContext.messages, model, (id) => normalizeToolCallId2(id));
40793
- const transcriptTools = resolveTranscriptTools(normalizedContext.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true);
40874
+ const transcriptTools = resolveTranscriptTools(normalizedContext.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true ? "additions" : "none");
40794
40875
  const instructionRole = model.reasoning && compat.supportsDeveloperRole ? "developer" : "system";
40795
40876
  let lastRole = null;
40877
+ let systemIndex = 0;
40796
40878
  for (let i = 0; i < transformedMessages.length; i++) {
40797
40879
  const msg = transformedMessages[i];
40798
40880
  if (compat.requiresAssistantAfterToolResult && lastRole === "toolResult" && msg.role === "user") {
@@ -40802,7 +40884,7 @@ function convertMessages2(model, context, compat, options) {
40802
40884
  });
40803
40885
  }
40804
40886
  if (msg.role === "system") {
40805
- const addedTools = i > 0 && transcriptTools.anchorsAdditions ? msg.toolsAdded ?? [] : [];
40887
+ const addedTools = systemIndex++ >= transcriptTools.foldedSystemMessages ? msg.toolsAdded ?? [] : [];
40806
40888
  if (addedTools.length > 0) {
40807
40889
  const kimiToolMessage = {
40808
40890
  role: "system",
@@ -40922,7 +41004,7 @@ function convertMessages2(model, context, compat, options) {
40922
41004
  const toolMsg = transformedMessages[j];
40923
41005
  const textResult = toolMsg.content.filter(isTextContentBlock).map((block) => block.text).join("\n");
40924
41006
  const hasImages = toolMsg.content.some((c) => c.type === "image");
40925
- const hasText = textResult.length > 0;
41007
+ const hasText = textResult.trim().length > 0;
40926
41008
  const toolResultText = hasText ? textResult : hasImages ? "(see attached image)" : "(no tool output)";
40927
41009
  const toolResultMsg = {
40928
41010
  role: "tool",
@@ -41053,7 +41135,7 @@ function detectCompat(model) {
41053
41135
  const isZai = provider === "zai" || provider === "zai-coding-cn" || baseUrl.includes("api.z.ai") || baseUrl.includes("open.bigmodel.cn");
41054
41136
  const isTogether = provider === "together" || baseUrl.includes("api.together.ai") || baseUrl.includes("api.together.xyz");
41055
41137
  const isMoonshot = provider === "moonshotai" || provider === "moonshotai-cn" || baseUrl.includes("api.moonshot.");
41056
- const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
41138
+ const isOpenRouter2 = provider === "openrouter" || baseUrl.includes("openrouter.ai");
41057
41139
  const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
41058
41140
  const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
41059
41141
  const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
@@ -41063,11 +41145,11 @@ function detectCompat(model) {
41063
41145
  const isNonStandard = isNvidia || isCerebras || provider === "xai" || baseUrl.includes("api.x.ai") || isTogether || baseUrl.includes("chutes.ai") || isDeepSeek || isZai || isMoonshot || provider === "opencode" || baseUrl.includes("opencode.ai") || isCloudflareWorkersAI || isCloudflareAiGateway || isAntLing;
41064
41146
  const useMaxTokens = baseUrl.includes("chutes.ai") || isDeepSeek || isMoonshot || isCloudflareAiGateway || isTogether || isNvidia || isAntLing || isZai;
41065
41147
  const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
41066
- const isOpenRouterDeveloperRoleModel = isOpenRouter && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
41148
+ const isOpenRouterDeveloperRoleModel = isOpenRouter2 && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
41067
41149
  const cacheControlFormat = provider === "openrouter" && model.id.startsWith("anthropic/") ? "anthropic" : void 0;
41068
41150
  return {
41069
41151
  supportsStore: !isNonStandard,
41070
- supportsDeveloperRole: isOpenRouterDeveloperRoleModel || !isNonStandard && !isOpenRouter,
41152
+ supportsDeveloperRole: isOpenRouterDeveloperRoleModel || !isNonStandard && !isOpenRouter2,
41071
41153
  supportsReasoningEffort: !isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isAntLing,
41072
41154
  supportsUsageInStreaming: true,
41073
41155
  supportsFinishReason: true,
@@ -41076,7 +41158,7 @@ function detectCompat(model) {
41076
41158
  requiresAssistantAfterToolResult: false,
41077
41159
  requiresThinkingAsText: false,
41078
41160
  requiresReasoningContentOnAssistantMessages: isDeepSeek,
41079
- thinkingFormat: isDeepSeek ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isAntLing ? "ant-ling" : isOpenRouter ? "openrouter" : "openai",
41161
+ thinkingFormat: isDeepSeek ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isAntLing ? "ant-ling" : isOpenRouter2 ? "openrouter" : "openai",
41080
41162
  openRouterRouting: {},
41081
41163
  vercelGatewayRouting: {},
41082
41164
  chatTemplateKwargs: {},
@@ -41090,8 +41172,8 @@ function detectCompat(model) {
41090
41172
  supportsMidConvoSystemMessages: false,
41091
41173
  supportsMidConvoToolAdditions: false,
41092
41174
  cacheControlFormat,
41093
- sendSessionAffinityHeaders: isOpenRouter,
41094
- sessionAffinityFormat: isOpenRouter ? "openrouter" : "openai",
41175
+ sendSessionAffinityHeaders: isOpenRouter2,
41176
+ sessionAffinityFormat: isOpenRouter2 ? "openrouter" : "openai",
41095
41177
  supportsLongCacheRetention: !(isTogether || isCloudflareWorkersAI || isCloudflareAiGateway || isNvidia || isAntLing)
41096
41178
  };
41097
41179
  }
@@ -41138,8 +41220,8 @@ var init_openai_completions = __esm({
41138
41220
  init_event_stream();
41139
41221
  init_hash();
41140
41222
  init_headers2();
41223
+ init_identity();
41141
41224
  init_json_parse();
41142
- init_pi_user_agent();
41143
41225
  init_provider_env();
41144
41226
  init_provider_retry();
41145
41227
  init_sanitize_unicode();
@@ -41184,7 +41266,7 @@ var init_openai_completions = __esm({
41184
41266
  const grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages), compat.supportsOpenAIGrammarTools);
41185
41267
  const cacheRetention = resolveCacheRetention2(options?.cacheRetention, options?.env);
41186
41268
  const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
41187
- const client = createClient2(model, normalizedContext, apiKey, options?.headers, options?.fetch, cacheSessionId, compat);
41269
+ const client = createClient2(model, normalizedContext, apiKey, options?.headers, options?.identity, options?.fetch, cacheSessionId, compat);
41188
41270
  let params = buildParams2(model, normalizedContext, options, compat, cacheRetention, grammarToolInputProperties);
41189
41271
  const nextParams = await options?.onPayload?.(params, model);
41190
41272
  if (nextParams !== void 0) {
@@ -41530,7 +41612,7 @@ function parseTextSignature(signature) {
41530
41612
  function convertToolResultOutput(model, content) {
41531
41613
  const textResult = content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
41532
41614
  const images = content.filter((c) => c.type === "image");
41533
- const hasText = textResult.length > 0;
41615
+ const hasText = textResult.trim().length > 0;
41534
41616
  if (images.length === 0 || !model.input.includes("image")) {
41535
41617
  return sanitizeSurrogates(hasText ? textResult : images.length > 0 ? "(see attached image)" : "(no tool output)");
41536
41618
  }
@@ -41547,6 +41629,20 @@ function convertToolResultOutput(model, content) {
41547
41629
  }
41548
41630
  return output;
41549
41631
  }
41632
+ function getResponsesToolSupport(options) {
41633
+ if (options.supportsMidConvoSystemMessages && options.supportsAdditionalTools)
41634
+ return "changes";
41635
+ return options.supportsToolSearch ? "additions" : "none";
41636
+ }
41637
+ function renderIncrementalToolsNotice(unavailable) {
41638
+ const notice = "This is an incremental tools update. Previously declared tools remain available unless explicitly marked unavailable. A tool declared again here is available again, and its latest definition replaces the earlier one.";
41639
+ return unavailable.size > 0 ? `${notice}
41640
+ Still unavailable: ${[...unavailable].join(", ")}.` : notice;
41641
+ }
41642
+ function renderToolRemovalNotice(names) {
41643
+ return `The following tools are no longer available. Do not call them:
41644
+ ${names.map((name2) => `- ${name2}`).join("\n")}`;
41645
+ }
41550
41646
  function convertResponsesMessages(model, context, allowedToolCallProviders, options) {
41551
41647
  const normalizedContext = resolveTranscript(context, options?.supportsMidConvoSystemMessages);
41552
41648
  const messages = [];
@@ -41574,20 +41670,29 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
41574
41670
  return `${normalizedCallId}|${normalizedItemId}`;
41575
41671
  };
41576
41672
  const transformedMessages = transformMessages(normalizedContext.messages, model, normalizeToolCallId2);
41577
- const transcriptTools = resolveTranscriptTools(normalizedContext.messages, (options?.supportsAdditionalTools ?? false) || (options?.supportsToolSearch ?? false));
41673
+ const toolSupport = getResponsesToolSupport(options ?? {});
41674
+ const transcriptTools = resolveTranscriptTools(normalizedContext.messages, toolSupport);
41675
+ let declaredAdditionalTools = false;
41676
+ const unavailableTools = /* @__PURE__ */ new Set();
41578
41677
  const appendSystemToolAdditions = (message, seed) => {
41579
- const tools = transcriptTools.anchorsAdditions ? message.toolsAdded ?? [] : [];
41678
+ const tools = message.toolsAdded ?? [];
41679
+ for (const tool of tools)
41680
+ unavailableTools.delete(tool.name);
41580
41681
  if (tools.length === 0)
41581
41682
  return;
41582
- if (options?.supportsAdditionalTools) {
41683
+ if (toolSupport === "changes") {
41684
+ if (declaredAdditionalTools) {
41685
+ messages.push({ role: instructionRole, content: renderIncrementalToolsNotice(unavailableTools) });
41686
+ }
41687
+ declaredAdditionalTools = true;
41583
41688
  messages.push({
41584
41689
  type: "additional_tools",
41585
41690
  role: "developer",
41586
- tools: convertResponsesTools(tools, options.toolOptions)
41691
+ tools: convertResponsesTools(tools, options?.toolOptions)
41587
41692
  });
41588
41693
  return;
41589
41694
  }
41590
- if (!options?.supportsToolSearch)
41695
+ if (toolSupport !== "additions")
41591
41696
  return;
41592
41697
  const names = tools.map((tool) => tool.name);
41593
41698
  const callId = `pi_tool_load_${shortHash(`${seed}:${names.join(",")}`)}`;
@@ -41603,7 +41708,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
41603
41708
  call_id: callId,
41604
41709
  execution: "client",
41605
41710
  status: "completed",
41606
- tools: convertResponsesTools(tools, { ...options.toolOptions, toolSearchResult: true })
41711
+ tools: convertResponsesTools(tools, { ...options?.toolOptions, toolSearchResult: true })
41607
41712
  });
41608
41713
  };
41609
41714
  const includeInitialSystemMessage = options?.includeSystemPrompt ?? true;
@@ -41617,13 +41722,24 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
41617
41722
  const instructionRole = model.reasoning && compat?.supportsDeveloperRole !== false ? "developer" : "system";
41618
41723
  let msgIndex = 0;
41619
41724
  let sourceIndex = 0;
41725
+ let systemIndex = 0;
41620
41726
  for (const msg of transformedMessages) {
41621
41727
  const isLeadingSystemMessage = sourceIndex++ === 0 && msg.role === "system";
41622
41728
  if (msg.role === "system") {
41623
- if (!isLeadingSystemMessage)
41729
+ const anchorsToolChanges = systemIndex++ >= transcriptTools.foldedSystemMessages;
41730
+ if (anchorsToolChanges)
41624
41731
  appendSystemToolAdditions(msg, `system:${msgIndex}`);
41625
41732
  if (!isLeadingSystemMessage || includeInitialSystemMessage) {
41626
- const text2 = isLeadingSystemMessage ? getSystemMessageText(msg) : renderSystemMessageUpdate(msg);
41733
+ const parts = [isLeadingSystemMessage ? getSystemMessageText(msg) : renderSystemMessageUpdate(msg)];
41734
+ if (anchorsToolChanges) {
41735
+ const added = new Set((msg.toolsAdded ?? []).map((tool) => tool.name));
41736
+ const removed = (msg.toolsRemoved ?? []).map((tool) => tool.name).filter((name2) => !added.has(name2));
41737
+ if (removed.length > 0)
41738
+ parts.push(renderToolRemovalNotice(removed));
41739
+ for (const name2 of removed)
41740
+ unavailableTools.add(name2);
41741
+ }
41742
+ const text2 = parts.filter((part) => part.length > 0).join("\n\n");
41627
41743
  if (text2.length > 0) {
41628
41744
  messages.push({ role: instructionRole, content: sanitizeSurrogates(text2) });
41629
41745
  }
@@ -42226,9 +42342,9 @@ function getPromptCacheOptions(compat, cacheRetention) {
42226
42342
  return { ttl: "30m" };
42227
42343
  return void 0;
42228
42344
  }
42229
- function createClient3(model, context, apiKey, optionsHeaders, fetch2, sessionId) {
42345
+ function createClient3(model, context, apiKey, optionsHeaders, identity, fetch2, sessionId) {
42230
42346
  const compat = getCompat2(model);
42231
- const headers = { "User-Agent": getPiUserAgent(), ...model.headers };
42347
+ const headers = { ...getIdentityHeaders(model, identity), ...model.headers };
42232
42348
  if (model.provider === "github-copilot") {
42233
42349
  const hasImages = hasCopilotVisionInput(context.messages);
42234
42350
  const copilotHeaders = buildCopilotDynamicHeaders({
@@ -42259,7 +42375,7 @@ function createClient3(model, context, apiKey, optionsHeaders, fetch2, sessionId
42259
42375
  });
42260
42376
  }
42261
42377
  function buildParams3(model, context, options, compat, grammarToolInputProperties, configurationUpdateEffort) {
42262
- const transcriptTools = resolveTranscriptTools(context.messages, compat.supportsAdditionalTools || compat.supportsToolSearch);
42378
+ const transcriptTools = resolveTranscriptTools(context.messages, getResponsesToolSupport(compat));
42263
42379
  const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {
42264
42380
  grammarToolInputProperties,
42265
42381
  supportsMidConvoSystemMessages: compat.supportsMidConvoSystemMessages,
@@ -42345,7 +42461,7 @@ function applyServiceTierPricing(usage, serviceTier, model) {
42345
42461
  usage.cost.cacheWrite *= multiplier;
42346
42462
  usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
42347
42463
  }
42348
- var OPENAI_TOOL_CALL_PROVIDERS, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS, CHATGPT_USAGE_URL, CONFIGURATION_UPDATE_REQUEST_EFFORT, stream4, streamSimple3;
42464
+ var OPENAI_TOOL_CALL_PROVIDERS, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS, CHATGPT_USAGE_URL, CHATGPT_WORKSPACE_LIMIT_HINT, CONFIGURATION_UPDATE_REQUEST_EFFORT, stream4, streamSimple3;
42349
42465
  var init_openai_responses = __esm({
42350
42466
  "node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js"() {
42351
42467
  init_openai();
@@ -42353,7 +42469,7 @@ var init_openai_responses = __esm({
42353
42469
  init_error_body();
42354
42470
  init_event_stream();
42355
42471
  init_headers2();
42356
- init_pi_user_agent();
42472
+ init_identity();
42357
42473
  init_provider_env();
42358
42474
  init_provider_retry();
42359
42475
  init_transcript();
@@ -42365,6 +42481,7 @@ var init_openai_responses = __esm({
42365
42481
  OPENAI_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openai-codex", "opencode"]);
42366
42482
  OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;
42367
42483
  CHATGPT_USAGE_URL = "https://chatgpt.com/settings/usage";
42484
+ CHATGPT_WORKSPACE_LIMIT_HINT = "You've reached your ChatGPT workspace's usage limit. Ask your workspace admin to increase it at admin.openai.com \u2192 Workspace \u2192 Usage limits.";
42368
42485
  CONFIGURATION_UPDATE_REQUEST_EFFORT = "medium";
42369
42486
  stream4 = (model, context, options) => {
42370
42487
  const stream5 = new AssistantMessageEventStream();
@@ -42395,7 +42512,7 @@ var init_openai_responses = __esm({
42395
42512
  const cacheRetention = resolveCacheRetention3(options?.cacheRetention, options?.env);
42396
42513
  const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
42397
42514
  const grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages), compat.supportsOpenAIGrammarTools);
42398
- const client = createClient3(model, normalizedContext, apiKey, options?.headers, options?.fetch, cacheSessionId);
42515
+ const client = createClient3(model, normalizedContext, apiKey, options?.headers, options?.identity, options?.fetch, cacheSessionId);
42399
42516
  let params = buildParams3(model, normalizedContext, options, compat, grammarToolInputProperties, configurationUpdateEffort);
42400
42517
  const nextParams = await options?.onPayload?.(params, model);
42401
42518
  if (nextParams !== void 0) {
@@ -42438,8 +42555,15 @@ var init_openai_responses = __esm({
42438
42555
  }
42439
42556
  output.stopReason = options?.signal?.aborted ? "aborted" : "error";
42440
42557
  const errorMessage = formatProviderError(normalizeProviderError(error), `${model.provider === "openai" ? "OpenAI" : model.provider} API error`);
42441
- output.errorMessage = errorMessage.includes("subscription_sharing_usage_limit_exceeded") ? `${errorMessage}
42442
- Check your ChatGPT usage: ${CHATGPT_USAGE_URL}` : errorMessage;
42558
+ if (errorMessage.includes("subscription_sharing_usage_limit_exceeded")) {
42559
+ output.errorMessage = `${errorMessage}
42560
+ Check your ChatGPT usage: ${CHATGPT_USAGE_URL}`;
42561
+ } else if (errorMessage.includes("subscription_sharing_workplace_individual_usage_limit_exceeded")) {
42562
+ output.errorMessage = `${errorMessage}
42563
+ ${CHATGPT_WORKSPACE_LIMIT_HINT}`;
42564
+ } else {
42565
+ output.errorMessage = errorMessage;
42566
+ }
42443
42567
  stream5.push({ type: "error", reason: output.stopReason, error: output });
42444
42568
  stream5.end();
42445
42569
  }
@@ -73548,7 +73672,7 @@ import dc from "node:diagnostics_channel";
73548
73672
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
73549
73673
  import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
73550
73674
  import * as llm2 from "@deepseek-ai/dsh-llm";
73551
- import { LlmError as LlmError12 } from "@deepseek-ai/dsh-llm";
73675
+ import { LlmError as LlmError13 } from "@deepseek-ai/dsh-llm";
73552
73676
 
73553
73677
  // src/adapter.ts
73554
73678
  init_models();
@@ -73558,7 +73682,7 @@ import {
73558
73682
  contentHasImage as contentHasImage2,
73559
73683
  isTokenDelta,
73560
73684
  LlmAdapter,
73561
- LlmError as LlmError8,
73685
+ LlmError as LlmError9,
73562
73686
  ReasoningEffortId,
73563
73687
  resolveRetryPolicy
73564
73688
  } from "@deepseek-ai/dsh-llm";
@@ -73568,7 +73692,7 @@ import { idleWatchdog, timeoutOf } from "@deepseek-ai/dsh-timeout";
73568
73692
  init_models();
73569
73693
 
73570
73694
  // node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json
73571
- var opencode_go_default = { "anthropic-messages": { "chat:claude-haiku-5-5": { id: "claude-haiku-5-5", name: "Claude Haiku 5.5", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.5, cacheRead: 0.01, cacheWrite: 0.125, tiers: [{ inputTokensAbove: 1e5, input: 0.5, output: 2.5, cacheRead: 0.05, cacheWrite: 0.625 }] }, contextWindow: 1e6, maxTokens: 128e3, thinkingLevelMap: { xhigh: "xhigh", max: "max" }, compat: { forceAdaptiveThinking: true, supportsTemperature: false }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:minimax-m3": { id: "minimax-m3", name: "MiniMax-M3", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0, tiers: [{ inputTokensAbove: 512e3, input: 0.6, output: 2.4, cacheRead: 0.12, cacheWrite: 0 }] }, contextWindow: 1e6, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:qwen3.7-plus": { id: "qwen3.7-plus", name: "Qwen3.7 Plus", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 1.6, cacheRead: 0.04, cacheWrite: 0.5, tiers: [{ inputTokensAbove: 256e3, input: 1.2, output: 4.8, cacheRead: 0.12, cacheWrite: 1.5 }] }, contextWindow: 1e6, maxTokens: 65536, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:qwen3.8-flash": { id: "qwen3.8-flash", name: "Qwen3.8 Flash", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 0.47, cacheRead: 0.016, cacheWrite: 0.2 }, contextWindow: 1e6, maxTokens: 131072, compat: { allowEmptySignature: true }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:qwen3.8-max": { id: "qwen3.8-max", name: "Qwen3.8 Max", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } }, "google-generative-ai": { "chat:gemini-4-argon-contributor": { id: "gemini-4-argon-contributor", name: "Gemini 4 Argon Contributor", api: "google-generative-ai", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 4, output: 20, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } }, "openai-completions": { "chat:cat-jam-free": { id: "cat-jam-free", name: "Cat Jam Free", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 262144, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, type: "chat" }, "chat:deepseek-v4-pro": { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro (New)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" }, type: "chat" }, "chat:deepseek-v4.1-flash": { id: "deepseek-v4.1-flash", name: "DeepSeek V4.1 Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" }, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 3e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:glm-5.2": { id: "glm-5.2", name: "GLM-5.2", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: "high", xhigh: null, max: "max" }, type: "chat" }, "chat:glm-5.3": { id: "glm-5.3", name: "GLM-5.3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" }, type: "chat" }, "chat:glm-5.3-flash": { id: "glm-5.3-flash", name: "GLM-5.3-Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:hy3": { id: "hy3", name: "Hy3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.14, output: 0.58, cacheRead: 0.035, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 256e3, maxTokens: 128e3, thinkingLevelMap: { off: "none", minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: null }, type: "chat" }, "chat:hy4-preview": { id: "hy4-preview", name: "Hy4 preview", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.834, output: 2.501, cacheRead: 0.042, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1024e3, maxTokens: 64e3, thinkingLevelMap: { off: "none", minimal: null, low: null, medium: null, high: "high", xhigh: null, max: null }, type: "chat" }, "chat:kimi-k2.7-code": { id: "kimi-k2.7-code", name: "Kimi K2.7 Code", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 262144, maxTokens: 262144, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:kimi-k3": { id: "kimi-k3", name: "Kimi K3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens", supportsMidConvoSystemMessages: true, supportsMidConvoToolAdditions: true }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: null, xhigh: null, max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:longcat-2.0": { id: "longcat-2.0", name: "LongCat-2.0", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 6e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, type: "chat" }, "chat:longcat-2.5-preview-free": { id: "longcat-2.5-preview-free", name: "LongCat 2.5 Preview Free", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:mimo-v2.5": { id: "mimo-v2.5", name: "MiMo V2.5", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 128e3, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:mimo-v2.5-pro": { id: "mimo-v2.5-pro", name: "MiMo V2.5 Pro", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.435, output: 0.87, cacheRead: 3625e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 128e3, type: "chat" }, "chat:mimo-v2.6-flash": { id: "mimo-v2.6-flash", name: "MiMo-V2.6-Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:mimo-v2.6-pro": { id: "mimo-v2.6-pro", name: "MiMo-V2.6-Pro", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.435, output: 0.87, cacheRead: 3625e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:space-bunny": { id: "space-bunny", name: "Space Bunny", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 0.03, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 524288, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:step-5-preview-free": { id: "step-5-preview-free", name: "Step 5 Preview Free", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } }, "openai-responses": { "chat:gpt-5.6-luna": { id: "gpt-5.6-luna", name: "GPT-5.6 Luna", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25, tiers: [{ inputTokensAbove: 272e3, input: 0.4, output: 1.8, cacheRead: 0.04, cacheWrite: 0.5 }] }, compat: { sessionAffinityFormat: "openai-nosession", supportsMidConvoSystemMessages: true, supportsAdditionalTools: true }, contextWindow: 105e4, maxTokens: 128e3, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gpt-6-luna": { id: "gpt-6-luna", name: "GPT-6 Luna", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.5, cacheRead: 0.01, cacheWrite: 0.125, tiers: [{ inputTokensAbove: 272e3, input: 0.2, output: 0.75, cacheRead: 0.02, cacheWrite: 0.25 }] }, compat: { sessionAffinityFormat: "openai-nosession", supportsMidConvoSystemMessages: true, supportsAdditionalTools: true }, contextWindow: 105e4, maxTokens: 128e3, thinkingLevelMap: { off: "none", minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:grok-4.7": { id: "grok-4.7", name: "Grok 4.7", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 4, output: 12, cacheRead: 1, cacheWrite: 0 }] }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 5e5, maxTokens: 5e5, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:muse-spark-1.2-contributor": { id: "muse-spark-1.2-contributor", name: "Muse Spark 1.2 Contributor", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:muse-spark-1.3-contributor": { id: "muse-spark-1.3-contributor", name: "Muse Spark 1.3 Contributor", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } } };
73695
+ var opencode_go_default = { "anthropic-messages": { "chat:claude-haiku-5-5": { id: "claude-haiku-5-5", name: "Claude Haiku 5.5", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.5, cacheRead: 0.01, cacheWrite: 0.125, tiers: [{ inputTokensAbove: 1e5, input: 0.5, output: 2.5, cacheRead: 0.05, cacheWrite: 0.625 }] }, contextWindow: 1e6, maxTokens: 128e3, thinkingLevelMap: { xhigh: "xhigh", max: "max" }, compat: { forceAdaptiveThinking: true, supportsTemperature: false }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:minimax-m3": { id: "minimax-m3", name: "MiniMax-M3", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0, tiers: [{ inputTokensAbove: 512e3, input: 0.6, output: 2.4, cacheRead: 0.12, cacheWrite: 0 }] }, contextWindow: 1e6, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:qwen3.7-plus": { id: "qwen3.7-plus", name: "Qwen3.7 Plus", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.4, output: 1.6, cacheRead: 0.04, cacheWrite: 0.5, tiers: [{ inputTokensAbove: 256e3, input: 1.2, output: 4.8, cacheRead: 0.12, cacheWrite: 1.5 }] }, contextWindow: 1e6, maxTokens: 65536, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:qwen3.8-flash": { id: "qwen3.8-flash", name: "Qwen3.8 Flash", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 0.47, cacheRead: 0.016, cacheWrite: 0.2 }, contextWindow: 1e6, maxTokens: 131072, compat: { allowEmptySignature: true }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:qwen3.8-max": { id: "qwen3.8-max", name: "Qwen3.8 Max", api: "anthropic-messages", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, contextWindow: 1e6, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } }, "google-generative-ai": { "chat:gemini-4-argon-contributor": { id: "gemini-4-argon-contributor", name: "Gemini 4 Argon Contributor", api: "google-generative-ai", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 4, output: 20, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } }, "openai-completions": { "chat:beam-free": { id: "beam-free", name: "Beam Free", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, type: "chat" }, "chat:deepseek-v4-pro": { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro (New)", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high", max: "max" }, type: "chat" }, "chat:deepseek-v4.1-flash": { id: "deepseek-v4.1-flash", name: "DeepSeek V4.1 Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" }, input: ["text", "image"], cost: { input: 0.15, output: 0.6, cacheRead: 3e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens", requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek" }, contextWindow: 1e6, maxTokens: 384e3, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:glm-5.2": { id: "glm-5.2", name: "GLM-5.2", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: "high", xhigh: null, max: "max" }, type: "chat" }, "chat:glm-5.3": { id: "glm-5.3", name: "GLM-5.3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" }, type: "chat" }, "chat:glm-5.3-flash": { id: "glm-5.3-flash", name: "GLM-5.3-Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:hy3": { id: "hy3", name: "Hy3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.14, output: 0.58, cacheRead: 0.035, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 256e3, maxTokens: 128e3, thinkingLevelMap: { off: "none", minimal: null, low: "low", medium: null, high: "high", xhigh: null, max: null }, type: "chat" }, "chat:hy4-preview": { id: "hy4-preview", name: "Hy4 preview", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.834, output: 2.501, cacheRead: 0.042, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1024e3, maxTokens: 64e3, thinkingLevelMap: { off: "none", minimal: null, low: null, medium: null, high: "high", xhigh: null, max: null }, type: "chat" }, "chat:kimi-k2.7-code": { id: "kimi-k2.7-code", name: "Kimi K2.7 Code", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 262144, maxTokens: 262144, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:kimi-k3": { id: "kimi-k3", name: "Kimi K3", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens", supportsMidConvoSystemMessages: true, supportsMidConvoToolAdditions: true }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: null, low: null, medium: null, high: null, xhigh: null, max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:longcat-2.0": { id: "longcat-2.0", name: "LongCat-2.0", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.3, output: 1.2, cacheRead: 6e-3, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, type: "chat" }, "chat:longcat-2.5-preview-free": { id: "longcat-2.5-preview-free", name: "LongCat 2.5 Preview Free", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:mimo-v2.5": { id: "mimo-v2.5", name: "MiMo V2.5", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 128e3, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:mimo-v2.5-pro": { id: "mimo-v2.5-pro", name: "MiMo V2.5 Pro", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text"], cost: { input: 0.435, output: 0.87, cacheRead: 3625e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 128e3, type: "chat" }, "chat:mimo-v2.6-flash": { id: "mimo-v2.6-flash", name: "MiMo-V2.6-Flash", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.14, output: 0.28, cacheRead: 28e-4, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:mimo-v2.6-pro": { id: "mimo-v2.6-pro", name: "MiMo-V2.6-Pro", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.435, output: 0.87, cacheRead: 3625e-6, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1048576, maxTokens: 131072, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:minimax-m3.1-flash-free": { id: "minimax-m3.1-flash-free", name: "MiniMax M3.1 Flash Free", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 512e3, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:step-5-preview": { id: "step-5-preview", name: "Step 5 Preview", api: "openai-completions", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 1, output: 2.7, cacheRead: 0.1, cacheWrite: 0 }, compat: { supportsStore: false, supportsDeveloperRole: false, supportsStrictMode: true, maxTokensField: "max_tokens" }, contextWindow: 1e6, maxTokens: 65536, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } }, "openai-responses": { "chat:gpt-5.6-luna": { id: "gpt-5.6-luna", name: "GPT-5.6 Luna", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25, tiers: [{ inputTokensAbove: 272e3, input: 0.4, output: 1.8, cacheRead: 0.04, cacheWrite: 0.5 }] }, compat: { sessionAffinityFormat: "openai-nosession", supportsMidConvoSystemMessages: true, supportsAdditionalTools: true }, contextWindow: 105e4, maxTokens: 128e3, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gpt-6-luna": { id: "gpt-6-luna", name: "GPT-6 Luna", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.5, cacheRead: 0.01, cacheWrite: 0.125, tiers: [{ inputTokensAbove: 272e3, input: 0.2, output: 0.75, cacheRead: 0.02, cacheWrite: 0.25 }] }, compat: { sessionAffinityFormat: "openai-nosession", supportsMidConvoSystemMessages: true, supportsAdditionalTools: true }, contextWindow: 105e4, maxTokens: 128e3, thinkingLevelMap: { off: "none", minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: "max" }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:grok-4.7": { id: "grok-4.7", name: "Grok 4.7", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 4, output: 12, cacheRead: 1, cacheWrite: 0 }] }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 5e5, maxTokens: 5e5, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:muse-spark-1.2-contributor": { id: "muse-spark-1.2-contributor", name: "Muse Spark 1.2 Contributor", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:muse-spark-1.3-contributor": { id: "muse-spark-1.3-contributor", name: "Muse Spark 1.3 Contributor", api: "openai-responses", provider: "opencode-go", baseUrl: "https://opencode.ai/inference/go/v1", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.2, cacheRead: 2e-3, cacheWrite: 0 }, compat: { sessionAffinityFormat: "openai-nosession" }, contextWindow: 1048576, maxTokens: 131072, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: "xhigh", max: null }, inputLimits: { images: { resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } } };
73572
73696
 
73573
73697
  // node_modules/@earendil-works/pi-ai/dist/model-catalog.js
73574
73698
  function flattenModelCatalog(groups, type) {
@@ -74849,7 +74973,7 @@ async function discoverCatalogModels(catalog, signal) {
74849
74973
  }
74850
74974
 
74851
74975
  // src/config.ts
74852
- import { RetryPolicySchema } from "@deepseek-ai/dsh-llm";
74976
+ import { LlmError as LlmError5, RetryPolicySchema } from "@deepseek-ai/dsh-llm";
74853
74977
  import { MAX_TIMER_DELAY_MS } from "@deepseek-ai/dsh-timeout";
74854
74978
 
74855
74979
  // node_modules/@deepseek-ai/cosmokit/lib/index.js
@@ -75733,9 +75857,6 @@ var MAX_REQUEST_LOG_MAX_ENTRIES = 500;
75733
75857
  var DEFAULT_API_KEY_ENV = "OPENCODE_GO_API_KEY";
75734
75858
  var DEFAULT_REFRESH_MINUTES = 60;
75735
75859
  var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
75736
- var DEFAULT_MAX_REQUEST_IMAGE_BYTES = 6 * 1024 * 1024;
75737
- var DEFAULT_REQUEST_IMAGE_PIXEL_BUDGET = 144e4;
75738
- var DEFAULT_REQUEST_IMAGE_MAX_BYTES = 4e5;
75739
75860
  var fields = {
75740
75861
  enabled: Schema.boolean().default(true),
75741
75862
  modelVisibility: Schema.dict(Schema.boolean().required()).default({}),
@@ -75749,9 +75870,7 @@ var fields = {
75749
75870
  // once and say so only in a warning on stderr. The bound here is what
75750
75871
  // keeps that unreachable.
75751
75872
  keepAliveTimeoutMs: Schema.number().step(1).min(1).max(MAX_KEEP_ALIVE_TIMEOUT_MS).default(DEFAULT_KEEP_ALIVE_TIMEOUT_MS),
75752
- maxRequestImageBytes: Schema.number().step(1).min(1).default(DEFAULT_MAX_REQUEST_IMAGE_BYTES),
75753
- requestImagePixelBudget: Schema.number().step(1).min(1).default(DEFAULT_REQUEST_IMAGE_PIXEL_BUDGET),
75754
- requestImageMaxBytes: Schema.number().step(1).min(1).default(DEFAULT_REQUEST_IMAGE_MAX_BYTES),
75873
+ imageBudgetPreset: Schema.union([Schema.const("dsh"), Schema.const("dshopencodego"), Schema.const("pi-ai")]).default("dsh"),
75755
75874
  modelLimits: Schema.dict(Schema.union([Schema.const(null), Schema.object({
75756
75875
  contextWindow: Schema.union([Schema.const(null), Schema.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER)]),
75757
75876
  maxTokens: Schema.union([Schema.const(null), Schema.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER)])
@@ -75771,6 +75890,14 @@ var PlainConfig = Schema.object(fields);
75771
75890
  var Config = Schema.object(Object.fromEntries(
75772
75891
  Object.entries(fields).map(([key, schema]) => [key, schema.volatile()])
75773
75892
  ));
75893
+ function assertStreamIdleTimeoutMs(value) {
75894
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0 || value > MAX_TIMER_DELAY_MS) {
75895
+ throw new LlmError5(
75896
+ `dshopencodego: streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`,
75897
+ "INVALID_CONFIG"
75898
+ );
75899
+ }
75900
+ }
75774
75901
  function readConfig(config) {
75775
75902
  return Object.fromEntries(Object.keys(fields).flatMap((key) => {
75776
75903
  const field = config[key];
@@ -75802,11 +75929,11 @@ function assertBaseURL(raw) {
75802
75929
  // src/conversion/context.ts
75803
75930
  import { brandString } from "@deepseek-ai/dsh-brand";
75804
75931
  import * as llm from "@deepseek-ai/dsh-llm";
75805
- import { contentHasImage, LlmError as LlmError6, requestImageHandleText } from "@deepseek-ai/dsh-llm";
75932
+ import { contentHasImage, LlmError as LlmError7, requestImageHandleText } from "@deepseek-ai/dsh-llm";
75806
75933
  import { requestImageDimensions } from "@deepseek-ai/dsh-attachment";
75807
75934
 
75808
75935
  // src/conversion/replay.ts
75809
- import { LlmError as LlmError5 } from "@deepseek-ai/dsh-llm";
75936
+ import { LlmError as LlmError6 } from "@deepseek-ai/dsh-llm";
75810
75937
  var REPLAYABLE_STOP_REASONS = ["stop", "length", "toolUse", "error", "aborted"];
75811
75938
  function replayableStopReason(stopReason) {
75812
75939
  return REPLAYABLE_STOP_REASONS.includes(stopReason) ? stopReason : "error";
@@ -75869,7 +75996,7 @@ function toPiReplayState(message, requestedModel = message.model) {
75869
75996
  };
75870
75997
  }
75871
75998
  function invalidReplay(message) {
75872
- throw new LlmError5(`invalid pi-ai replay state: ${message}`, "INVALID_REPLAY_STATE");
75999
+ throw new LlmError6(`invalid pi-ai replay state: ${message}`, "INVALID_REPLAY_STATE");
75873
76000
  }
75874
76001
  function readReplayState(value) {
75875
76002
  if (typeof value !== "object" || value === null || Array.isArray(value)) return invalidReplay("expected a replay envelope");
@@ -75929,7 +76056,7 @@ function foreignAssistant(message) {
75929
76056
  });
75930
76057
  break;
75931
76058
  case "image":
75932
- throw new LlmError5("pi-ai chat history cannot represent structured assistant image output", "UNSUPPORTED_CONTENT");
76059
+ throw new LlmError6("pi-ai chat history cannot represent structured assistant image output", "UNSUPPORTED_CONTENT");
75933
76060
  default:
75934
76061
  break;
75935
76062
  }
@@ -76003,7 +76130,7 @@ function toPiAssistant(message, onDegrade) {
76003
76130
  try {
76004
76131
  return replayedAssistant(message, source, source.replayState);
76005
76132
  } catch (error) {
76006
- if (!(error instanceof LlmError5) || error.code !== "INVALID_REPLAY_STATE") throw error;
76133
+ if (!(error instanceof LlmError6) || error.code !== "INVALID_REPLAY_STATE") throw error;
76007
76134
  onDegrade?.(error.message);
76008
76135
  return foreignAssistant(message);
76009
76136
  }
@@ -76019,7 +76146,7 @@ function toolMessage(message) {
76019
76146
  function assertSupportedImageRoles(messages) {
76020
76147
  for (const message of messages) {
76021
76148
  if (message.role !== "user" && toolMessage(message) === void 0 && contentHasImage(message.content)) {
76022
- throw new LlmError6(`pi-ai cannot represent an image in an in-history ${message.role} message`, "UNSUPPORTED_CONTENT");
76149
+ throw new LlmError7(`pi-ai cannot represent an image in an in-history ${message.role} message`, "UNSUPPORTED_CONTENT");
76023
76150
  }
76024
76151
  }
76025
76152
  }
@@ -76067,7 +76194,7 @@ async function userContent(blocks, requestImages, resolveImageAccess) {
76067
76194
  if (block.type === "image") {
76068
76195
  const version = requestImages.get(block.attachment.attachmentId);
76069
76196
  if (version === void 0) {
76070
- throw new LlmError6(
76197
+ throw new LlmError7(
76071
76198
  "dshopencodego: an image in this request has no prepared bytes; image input requires the attachment service",
76072
76199
  "UNSUPPORTED_CONTENT"
76073
76200
  );
@@ -76091,7 +76218,7 @@ function projectImagesForRequest(messages, images, requestImages) {
76091
76218
  (block) => requestImages.get(block.attachment.attachmentId).bytes
76092
76219
  );
76093
76220
  if (over > 0) {
76094
- throw new LlmError6(
76221
+ throw new LlmError7(
76095
76222
  `request images exceed the ${images.maxRequestImageBytes}-byte base64 bound; ${over} more oldest occurrence(s) must be offloaded`,
76096
76223
  llm.IMAGE_OFFLOAD_REQUIRED_CODE,
76097
76224
  { offloadImages: over }
@@ -76153,7 +76280,7 @@ import {
76153
76280
  EMPTY_RESPONSE_CODE,
76154
76281
  isContextWindowExceededError,
76155
76282
  isQuotaExceededError,
76156
- LlmError as LlmError7
76283
+ LlmError as LlmError8
76157
76284
  } from "@deepseek-ai/dsh-llm";
76158
76285
 
76159
76286
  // node_modules/@earendil-works/pi-ai/dist/utils/overflow.js
@@ -76206,8 +76333,11 @@ var OVERFLOW_PATTERNS = [
76206
76333
  // Generic fallback
76207
76334
  /too many tokens/i,
76208
76335
  // Generic fallback
76209
- /token limit exceeded/i
76336
+ /token limit exceeded/i,
76210
76337
  // Generic fallback
76338
+ // HTTP 413 means request-size overflow regardless of provider or body text.
76339
+ // Match raw SDK errors and formatProviderError's prefix, not a status mentioned in the body.
76340
+ /^(?:[\w -]+ API error \(413\):|413(?:\s|:|$))/i
76211
76341
  ];
76212
76342
  var CEREBRAS_BODYLESS_OVERFLOW_PATTERN = /^4(?:00|13)\s*(?:status code)?\s*\(no body\)/i;
76213
76343
  var NON_OVERFLOW_PATTERNS = [
@@ -76398,7 +76528,7 @@ async function* toStreamChunks(events, contextWindow, callerSignal, requestedMod
76398
76528
  return;
76399
76529
  }
76400
76530
  }
76401
- throw new LlmError7("pi-ai event stream ended without a terminal event", "STREAM_CLOSED");
76531
+ throw new LlmError8("pi-ai event stream ended without a terminal event", "STREAM_CLOSED");
76402
76532
  }
76403
76533
 
76404
76534
  // src/go-limits.ts
@@ -76497,6 +76627,13 @@ function providerHeaders(sessionId) {
76497
76627
  };
76498
76628
  }
76499
76629
 
76630
+ // src/image-budget.ts
76631
+ var IMAGE_BUDGETS = {
76632
+ dsh: { maxPixels: 2048 * 2048, maxBytes: 1024 * 1024, maxRequestBytes: 20 * 1024 * 1024 },
76633
+ dshopencodego: { maxPixels: 144e4, maxBytes: 4e5, maxRequestBytes: 6 * 1024 * 1024 },
76634
+ "pi-ai": { maxPixels: 2e3 * 2e3, maxBytes: 4718592, maxRequestBytes: 20 * 1024 * 1024 }
76635
+ };
76636
+
76500
76637
  // src/usage/meter.ts
76501
76638
  function usableRates(cost) {
76502
76639
  if (cost === void 0) return void 0;
@@ -76594,7 +76731,7 @@ function withModelLimit(model, limits) {
76594
76731
  function stopSequencesFor(model, stop) {
76595
76732
  if (stop === void 0) return void 0;
76596
76733
  if (model.api === "openai-completions") return stop;
76597
- throw new LlmError8(
76734
+ throw new LlmError9(
76598
76735
  `opencode-go model "${model.id}" speaks ${model.api}, which has no stop-sequence parameter this adapter can reach; drop GenerateOptions.stop for this model`,
76599
76736
  "UNSUPPORTED_OPTION"
76600
76737
  );
@@ -76707,7 +76844,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76707
76844
  const config = this.options.config();
76708
76845
  const snapshot2 = await this.catalogOf(config).forModel(model);
76709
76846
  const facts = snapshot2.facts.get(model);
76710
- if (facts === void 0) throw new LlmError8(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
76847
+ if (facts === void 0) throw new LlmError9(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
76711
76848
  return this.modelInfo(withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits));
76712
76849
  }
76713
76850
  /** Describe one model: capacities plus the reasoning levels it really offers. */
@@ -76753,16 +76890,17 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76753
76890
  if (effort === void 0 || effort === "off") return void 0;
76754
76891
  const supported = getSupportedThinkingLevels(model);
76755
76892
  if (supported.some((level) => level === effort)) return effort;
76756
- throw new LlmError8(
76893
+ throw new LlmError9(
76757
76894
  `opencode-go model "${model.id}" does not support reasoning effort "${effort}"`,
76758
76895
  "UNSUPPORTED_REASONING_EFFORT"
76759
76896
  );
76760
76897
  }
76761
76898
  async prepareCall(_provider, model, _signal) {
76762
76899
  const config = this.options.config();
76900
+ assertStreamIdleTimeoutMs(config.streamIdleTimeoutMs);
76763
76901
  const snapshot2 = await this.catalogOf(config).forModel(model);
76764
76902
  const facts = snapshot2.facts.get(model);
76765
- if (facts === void 0) throw new LlmError8(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
76903
+ if (facts === void 0) throw new LlmError9(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
76766
76904
  const prepared = this.modelInfo(withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits));
76767
76905
  return {
76768
76906
  model: prepared,
@@ -76771,14 +76909,16 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76771
76909
  }
76772
76910
  async *stream(options) {
76773
76911
  const config = this.options.config();
76912
+ assertStreamIdleTimeoutMs(config.streamIdleTimeoutMs);
76774
76913
  const snapshot2 = await this.catalogOf(config).forModel(options.model);
76775
76914
  yield* this.streamWithSnapshot(options, config, snapshot2);
76776
76915
  }
76777
76916
  async *streamWithSnapshot(options, config, snapshot2) {
76778
76917
  var _stack = [];
76779
76918
  try {
76919
+ assertStreamIdleTimeoutMs(config.streamIdleTimeoutMs);
76780
76920
  const facts = snapshot2.facts.get(options.model);
76781
- if (facts === void 0) throw new LlmError8(`opencode-go has no model "${options.model}"`, "UNKNOWN_MODEL");
76921
+ if (facts === void 0) throw new LlmError9(`opencode-go has no model "${options.model}"`, "UNKNOWN_MODEL");
76782
76922
  const model = withModelLimit(toPiModel(facts, config.baseURL), config.modelLimits);
76783
76923
  const rates2 = usableRates(facts.cost);
76784
76924
  const stop = stopSequencesFor(model, options.stop);
@@ -76786,7 +76926,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76786
76926
  const maxTokens = options.maxTokens === void 0 || ceiling === null || ceiling === void 0 ? options.maxTokens : Math.min(options.maxTokens, ceiling);
76787
76927
  const apiKey = await this.options.resolveApiKey();
76788
76928
  if (apiKey === void 0 || apiKey.length === 0) {
76789
- throw new LlmError8("dshopencodego: no credential resolved for the opencode-go route", "MISSING_CREDENTIAL");
76929
+ throw new LlmError9("dshopencodego: no credential resolved for the opencode-go route", "MISSING_CREDENTIAL");
76790
76930
  }
76791
76931
  const reasoning = this.resolveReasoningLevel(model, options.reasoningEffort);
76792
76932
  const consumer = new AbortController();
@@ -76795,7 +76935,8 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76795
76935
  let timedOut = false;
76796
76936
  const containsImage = options.messages.some((message) => contentHasImage2(message.content));
76797
76937
  const headers = providerHeaders(options.sessionId === void 0 ? void 0 : String(options.sessionId));
76798
- const imageBytes = containsImage ? estimateImageWireBytes(options.messages, config.requestImageMaxBytes) : void 0;
76938
+ const imageBudget = IMAGE_BUDGETS[config.imageBudgetPreset];
76939
+ const imageBytes = containsImage ? estimateImageWireBytes(options.messages, imageBudget.maxBytes) : void 0;
76799
76940
  const span = this.options.requestLog?.start({
76800
76941
  model: options.model,
76801
76942
  sessionId: options.sessionId === void 0 ? void 0 : String(options.sessionId),
@@ -76823,20 +76964,20 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76823
76964
  };
76824
76965
  try {
76825
76966
  if (containsImage && !model.input.includes("image")) {
76826
- throw new LlmError8(`opencode-go model "${model.id}" does not support image input`, "UNSUPPORTED_CONTENT");
76967
+ throw new LlmError9(`opencode-go model "${model.id}" does not support image input`, "UNSUPPORTED_CONTENT");
76827
76968
  }
76828
76969
  let imageRequest;
76829
76970
  if (containsImage) {
76830
76971
  const access2 = this.options.imageAccess;
76831
76972
  const store = access2?.resolveAttachments();
76832
76973
  if (access2 === void 0 || store === void 0) {
76833
- throw new LlmError8("dshopencodego image input requires the durable attachment service", "UNSUPPORTED_CONTENT");
76974
+ throw new LlmError9("dshopencodego image input requires the durable attachment service", "UNSUPPORTED_CONTENT");
76834
76975
  }
76835
76976
  imageRequest = {
76836
76977
  attachments: store,
76837
76978
  resolveImageAccess: (ref) => access2.resolveImageAccess(store, ref),
76838
- maxRequestImageBytes: config.maxRequestImageBytes,
76839
- requestImagePolicy: { maxPixels: config.requestImagePixelBudget, maxBytes: config.requestImageMaxBytes }
76979
+ maxRequestImageBytes: imageBudget.maxRequestBytes,
76980
+ requestImagePolicy: { maxPixels: imageBudget.maxPixels, maxBytes: imageBudget.maxBytes }
76840
76981
  };
76841
76982
  }
76842
76983
  const context = imageRequest === void 0 ? await toPiContext(options, void 0, this.options.onReplayDegrade) : await toPiContext({ ...options, signal: watchdog.signal }, imageRequest, this.options.onReplayDegrade);
@@ -76874,7 +77015,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76874
77015
  while (true) {
76875
77016
  const result = await watchdog.next(iterator);
76876
77017
  if (timeoutOf(watchdog.signal, "LLM_STREAM_IDLE_TIMEOUT") !== void 0) {
76877
- throw new LlmError8("opencode-go stream idle timeout", "TIMEOUT");
77018
+ throw new LlmError9("opencode-go stream idle timeout", "TIMEOUT");
76878
77019
  }
76879
77020
  if (result.done) {
76880
77021
  exhausted = true;
@@ -76926,13 +77067,13 @@ var OpencodeGoAdapter = class extends LlmAdapter {
76926
77067
  } catch (error) {
76927
77068
  if (timedOut || timeoutOf(watchdog.signal, "LLM_STREAM_IDLE_TIMEOUT") !== void 0) {
76928
77069
  span?.finish(false, "TIMEOUT");
76929
- throw new LlmError8("opencode-go stream idle timeout", "TIMEOUT", { cause: error });
77070
+ throw new LlmError9("opencode-go stream idle timeout", "TIMEOUT", { cause: error });
76930
77071
  }
76931
77072
  if (options.signal?.aborted) {
76932
77073
  span?.finish(false, "ABORTED");
76933
- throw new LlmError8("opencode-go request aborted by caller", "ABORTED", { cause: error });
77074
+ throw new LlmError9("opencode-go request aborted by caller", "ABORTED", { cause: error });
76934
77075
  }
76935
- span?.finish(false, error instanceof LlmError8 ? error.code : void 0);
77076
+ span?.finish(false, error instanceof LlmError9 ? error.code : void 0);
76936
77077
  throw error;
76937
77078
  } finally {
76938
77079
  consumer.abort("opencode-go stream consumer stopped");
@@ -77401,7 +77542,7 @@ function registerRemotes(ctx) {
77401
77542
 
77402
77543
  // src/catalog/service.ts
77403
77544
  import { RemoteError, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
77404
- import { LlmError as LlmError9 } from "@deepseek-ai/dsh-llm";
77545
+ import { LlmError as LlmError10 } from "@deepseek-ai/dsh-llm";
77405
77546
 
77406
77547
  // src/catalog/reading.ts
77407
77548
  function catalogReading(snapshot2, visibility, listingFailure, now) {
@@ -77482,7 +77623,7 @@ var OpencodeGoCatalogService = class extends TypertRemoteService {
77482
77623
  const reading = catalogReading(
77483
77624
  snapshot2,
77484
77625
  visibility,
77485
- failure === void 0 ? void 0 : failure instanceof LlmError9 || failure instanceof Error ? failure.message : String(failure)
77626
+ failure === void 0 ? void 0 : failure instanceof LlmError10 || failure instanceof Error ? failure.message : String(failure)
77486
77627
  );
77487
77628
  this.reportUnadvertised(snapshot2, visibility);
77488
77629
  return reading;
@@ -77944,7 +78085,7 @@ function createUpdateChecker(deps) {
77944
78085
  }
77945
78086
 
77946
78087
  // src/update/version.ts
77947
- var PLUGIN_VERSION = true ? "0.1.73" : "0.0.0-dev";
78088
+ var PLUGIN_VERSION = true ? "0.1.75" : "0.0.0-dev";
77948
78089
 
77949
78090
  // src/update/service.ts
77950
78091
  import { TypertRemoteService as TypertRemoteService4 } from "@deepseek-ai/dsh-typert-protocol";
@@ -77973,7 +78114,7 @@ var OpencodeGoUpdateService = class extends TypertRemoteService4 {
77973
78114
  };
77974
78115
 
77975
78116
  // src/usage/windows.ts
77976
- import { attributionHeaders as attributionHeaders6, LlmError as LlmError10 } from "@deepseek-ai/dsh-llm";
78117
+ import { attributionHeaders as attributionHeaders6, LlmError as LlmError11 } from "@deepseek-ai/dsh-llm";
77977
78118
  var USAGE_MAX_BYTES = 1024 * 1024;
77978
78119
  var USAGE_TIMEOUT_MS = 1e4;
77979
78120
  function parseGoUsage(value) {
@@ -77991,7 +78132,7 @@ function parseGoUsage(value) {
77991
78132
  }
77992
78133
  async function readUsageWindows(options) {
77993
78134
  if (options.apiKey === void 0 || options.apiKey.length === 0) {
77994
- throw new LlmError10("dshopencodego: no credential is configured for the opencode-go route", "USAGE_UNAVAILABLE");
78135
+ throw new LlmError11("dshopencodego: no credential is configured for the opencode-go route", "USAGE_UNAVAILABLE");
77995
78136
  }
77996
78137
  const url = `${options.baseURL.replace(/\/+$/, "")}/usage`;
77997
78138
  const timeout = AbortSignal.timeout(USAGE_TIMEOUT_MS);
@@ -78008,12 +78149,12 @@ async function readUsageWindows(options) {
78008
78149
  signal: options.signal === void 0 ? timeout : AbortSignal.any([options.signal, timeout])
78009
78150
  });
78010
78151
  } catch (error) {
78011
- throw new LlmError10(`could not reach ${url}`, "USAGE_UNAVAILABLE", { cause: error });
78152
+ throw new LlmError11(`could not reach ${url}`, "USAGE_UNAVAILABLE", { cause: error });
78012
78153
  }
78013
78154
  if (!response.ok) {
78014
78155
  await response.body?.cancel().catch(() => {
78015
78156
  });
78016
- throw new LlmError10(`${url} answered HTTP ${response.status}`, "USAGE_UNAVAILABLE");
78157
+ throw new LlmError11(`${url} answered HTTP ${response.status}`, "USAGE_UNAVAILABLE");
78017
78158
  }
78018
78159
  const body = await readBoundedJson(response, url, USAGE_MAX_BYTES);
78019
78160
  try {
@@ -78022,16 +78163,16 @@ async function readUsageWindows(options) {
78022
78163
  ...options.source === void 0 ? {} : { source: options.source }
78023
78164
  };
78024
78165
  } catch (error) {
78025
- throw new LlmError10(`${url} returned an invalid usage document`, "USAGE_UNAVAILABLE", { cause: error });
78166
+ throw new LlmError11(`${url} returned an invalid usage document`, "USAGE_UNAVAILABLE", { cause: error });
78026
78167
  }
78027
78168
  }
78028
78169
 
78029
78170
  // src/usage/service.ts
78030
78171
  import { randomUUID as randomUUID3 } from "node:crypto";
78031
78172
  import { RemoteError as RemoteError2, TypertRemoteService as TypertRemoteService5 } from "@deepseek-ai/dsh-typert-protocol";
78032
- import { LlmError as LlmError11 } from "@deepseek-ai/dsh-llm";
78173
+ import { LlmError as LlmError12 } from "@deepseek-ai/dsh-llm";
78033
78174
  function usageFailure(error, source) {
78034
- const missing = error instanceof LlmError11 && error.code === "MISSING_CREDENTIAL";
78175
+ const missing = error instanceof LlmError12 && error.code === "MISSING_CREDENTIAL";
78035
78176
  return new RemoteError2(
78036
78177
  "dshopencodego/usage-unavailable",
78037
78178
  error instanceof Error ? error.message : "OpenCode Go usage is unavailable",
@@ -78058,7 +78199,7 @@ var OpencodeGoUsageService = class extends TypertRemoteService5 {
78058
78199
  }
78059
78200
  if (key === void 0 || key.length === 0) {
78060
78201
  this.identity = void 0;
78061
- throw usageFailure(new LlmError11("No OpenCode Go API key is configured", "MISSING_CREDENTIAL"), void 0);
78202
+ throw usageFailure(new LlmError12("No OpenCode Go API key is configured", "MISSING_CREDENTIAL"), void 0);
78062
78203
  }
78063
78204
  if (this.identity?.baseURL !== baseURL || this.identity.key !== key) {
78064
78205
  this.identity = { baseURL, key, source: randomUUID3() };
@@ -78107,7 +78248,7 @@ function apply(ctx, raw) {
78107
78248
  const credentials = ctx.get("credentials");
78108
78249
  const hit = credentials !== void 0 ? (await credentials.resolve(credentialRef(ref)))?.value : launchEnvironmentOf(ctx).get(ref)?.value;
78109
78250
  if (hit !== void 0 && hit.length > 0) return llm2.assertUsableApiKey(hit, name, ref);
78110
- throw new LlmError12(
78251
+ throw new LlmError13(
78111
78252
  `dshopencodego: no credential; the profile resolves ${ref}, which is not set \u2014 store ${ref} through the credentials service (the Web Models page writes it) or export it`,
78112
78253
  "MISSING_CREDENTIAL"
78113
78254
  );
@@ -78197,7 +78338,8 @@ function apply(ctx, raw) {
78197
78338
  };
78198
78339
  }, "dshopencodego: catalog warm-up");
78199
78340
  let registration;
78200
- let visibilityFacts = JSON.stringify(current2().modelVisibility);
78341
+ const registrationFacts = () => JSON.stringify({ visibility: current2().modelVisibility, retryPolicy: current2().retryPolicy ?? null });
78342
+ let registeredFacts = registrationFacts();
78201
78343
  const applyRoute = (credentialConfigured) => {
78202
78344
  const enabled = current2().enabled;
78203
78345
  if (enabled && credentialConfigured && registration === void 0) {
@@ -78218,9 +78360,9 @@ function apply(ctx, raw) {
78218
78360
  };
78219
78361
  const syncRoute = () => {
78220
78362
  try {
78221
- const visibility = JSON.stringify(current2().modelVisibility);
78222
- if (visibility !== visibilityFacts) {
78223
- visibilityFacts = visibility;
78363
+ const facts = registrationFacts();
78364
+ if (facts !== registeredFacts) {
78365
+ registeredFacts = facts;
78224
78366
  registration?.replace([PROVIDER_ID]);
78225
78367
  }
78226
78368
  const credentials = ctx.get("credentials");
@@ -78245,7 +78387,7 @@ function apply(ctx, raw) {
78245
78387
  settingsNs,
78246
78388
  async (request, signal) => {
78247
78389
  if (request.provider !== PROVIDER_ID && !(request.baseURL ?? "").includes("opencode.ai")) {
78248
- throw new LlmError12(
78390
+ throw new LlmError13(
78249
78391
  "dshopencodego discovers only OpenCode Go/Console endpoints; enter this provider's models by hand",
78250
78392
  "DISCOVERY_UNSUPPORTED"
78251
78393
  );
@@ -78286,6 +78428,7 @@ export {
78286
78428
  SESSION_HEADER,
78287
78429
  apply,
78288
78430
  assertBaseURL,
78431
+ assertStreamIdleTimeoutMs,
78289
78432
  discoverCatalogModels,
78290
78433
  fetchModelIds,
78291
78434
  inject,