@codeworksh/aikit 0.3.0 → 0.3.1

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/index.mjs CHANGED
@@ -6,15 +6,33 @@ import addFormats from "ajv-formats";
6
6
  import { uuidv7 } from "uuidv7";
7
7
  import Anthropic from "@anthropic-ai/sdk";
8
8
  import { parse } from "partial-json";
9
+ import OpenAI from "openai";
9
10
  import { transform } from "esbuild";
10
11
  //#region src/provider/provider.ts
11
12
  let Provider;
12
13
  (function(_Provider) {
13
14
  const KnownProviderEnum = _Provider.KnownProviderEnum = {
14
15
  anthropic: "anthropic",
15
- openai: "openai"
16
+ openai: "openai",
17
+ githubCopilot: "github-copilot",
18
+ openrouter: "openrouter",
19
+ groq: "groq",
20
+ xai: "xai",
21
+ cerebras: "cerebras",
22
+ zai: "zai",
23
+ opencode: "opencode"
16
24
  };
17
- const KnownProviderSchema = _Provider.KnownProviderSchema = Type.Union([Type.Literal(KnownProviderEnum.anthropic), Type.Literal(KnownProviderEnum.openai)]);
25
+ const KnownProviderSchema = _Provider.KnownProviderSchema = Type.Union([
26
+ Type.Literal(KnownProviderEnum.anthropic),
27
+ Type.Literal(KnownProviderEnum.openai),
28
+ Type.Literal(KnownProviderEnum.githubCopilot),
29
+ Type.Literal(KnownProviderEnum.openrouter),
30
+ Type.Literal(KnownProviderEnum.groq),
31
+ Type.Literal(KnownProviderEnum.xai),
32
+ Type.Literal(KnownProviderEnum.cerebras),
33
+ Type.Literal(KnownProviderEnum.zai),
34
+ Type.Literal(KnownProviderEnum.opencode)
35
+ ]);
18
36
  _Provider.Info = Type.Object({
19
37
  id: KnownProviderSchema,
20
38
  name: Type.String(),
@@ -76,6 +94,46 @@ let ModelCatalog;
76
94
  }, 60 * 1e3 * 60).unref();
77
95
  })(ModelCatalog || (ModelCatalog = {}));
78
96
  //#endregion
97
+ //#region src/model/transform.ts
98
+ function defaultBaseUrl(providerId) {
99
+ switch (providerId) {
100
+ case Provider.KnownProviderEnum.openai: return "https://api.openai.com/v1";
101
+ default: return;
102
+ }
103
+ }
104
+ function resolveDefaultProtocol(providerId) {
105
+ switch (providerId) {
106
+ case Provider.KnownProviderEnum.anthropic: return Model.KnownProtocolEnum.anthropicMessages;
107
+ case Provider.KnownProviderEnum.openai: return Model.KnownProtocolEnum.openaiResponses;
108
+ default: return Model.KnownProtocolEnum.openaiCompletions;
109
+ }
110
+ }
111
+ function applyModification(providerId, provider, model) {
112
+ const baseUrl = model.baseUrl ?? provider.baseUrl ?? provider.api ?? defaultBaseUrl(providerId);
113
+ const normalized = {
114
+ id: model.id,
115
+ name: model.name,
116
+ provider: Model.toProviderInfo(providerId, provider),
117
+ baseUrl,
118
+ reasoning: Boolean(model.reasoning),
119
+ input: Model.normalizeInput(model.modalities.input),
120
+ cost: {
121
+ input: model.cost?.input ?? 0,
122
+ output: model.cost?.output ?? 0,
123
+ cacheRead: model.cost?.cache_read ?? 0,
124
+ cacheWrite: model.cost?.cache_write ?? 0
125
+ },
126
+ contextWindow: model.limit?.context ?? 0,
127
+ maxTokens: model.limit?.output ?? 0,
128
+ headers: model.headers ?? provider.headers,
129
+ protocol: resolveDefaultProtocol(providerId)
130
+ };
131
+ if (providerId === Provider.KnownProviderEnum.openai) {
132
+ normalized.supportedProtocols = { openaiCompletions: Model.KnownProtocolEnum.openaiCompletions };
133
+ return normalized;
134
+ } else return normalized;
135
+ }
136
+ //#endregion
79
137
  //#region src/model/model.ts
80
138
  let Model;
81
139
  (function(_Model) {
@@ -97,6 +155,11 @@ let Model;
97
155
  cacheWrite: Type.Number()
98
156
  });
99
157
  const HeadersSchema = Type.Optional(Type.Record(Type.String(), Type.String()));
158
+ const SupportedProtocolsSchema = _Model.SupportedProtocolsSchema = Type.Object({
159
+ anthropicMessages: Type.Optional(Type.Literal(KnownProtocolEnum.anthropicMessages)),
160
+ openaiCompletions: Type.Optional(Type.Literal(KnownProtocolEnum.openaiCompletions)),
161
+ openaiResponses: Type.Optional(Type.Literal(KnownProtocolEnum.openaiResponses))
162
+ });
100
163
  const BaseSchema = _Model.BaseSchema = Type.Object({
101
164
  id: Type.String(),
102
165
  name: Type.String(),
@@ -107,7 +170,8 @@ let Model;
107
170
  cost: CostSchema,
108
171
  contextWindow: Type.Number(),
109
172
  maxTokens: Type.Number(),
110
- headers: HeadersSchema
173
+ headers: HeadersSchema,
174
+ supportedProtocols: Type.Optional(Type.Partial(SupportedProtocolsSchema))
111
175
  });
112
176
  const OpenAICompletionsCompatSchema = _Model.OpenAICompletionsCompatSchema = Type.Object({
113
177
  supportsStore: Type.Optional(Type.Boolean()),
@@ -128,6 +192,7 @@ let Model;
128
192
  ])),
129
193
  openRouterRouting: Type.Optional(Provider.OpenRouterRoutingSchema),
130
194
  vercelGatewayRouting: Type.Optional(Provider.VercelGatewayRoutingSchema),
195
+ zaiToolStream: Type.Optional(Type.Boolean()),
131
196
  supportsStrictMode: Type.Optional(Type.Boolean())
132
197
  });
133
198
  const OpenAIResponsesCompatSchema = _Model.OpenAIResponsesCompatSchema = Type.Object({});
@@ -141,7 +206,7 @@ let Model;
141
206
  protocol: Type.Literal(KnownProtocolEnum.openaiResponses),
142
207
  compat: Type.Optional(OpenAIResponsesCompatSchema)
143
208
  })]);
144
- _Model.Schema = Type.Union([
209
+ _Model.Info = Type.Union([
145
210
  AnthropicSchema,
146
211
  OpenAICompletionsSchema,
147
212
  OpenAIResponsesSchema
@@ -155,18 +220,13 @@ let Model;
155
220
  usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
156
221
  }
157
222
  _Model.calculateCost = calculateCost;
158
- function resolveProtocol(providerId) {
159
- switch (providerId) {
160
- case Provider.KnownProviderEnum.anthropic: return KnownProtocolEnum.anthropicMessages;
161
- case Provider.KnownProviderEnum.openai: return KnownProtocolEnum.openaiResponses;
162
- }
163
- }
164
223
  function normalizeInput(input) {
165
224
  const normalized = /* @__PURE__ */ new Set();
166
225
  for (const modality of input ?? ["text"]) if (modality === "text" || modality === "image") normalized.add(modality);
167
226
  if (normalized.size === 0) normalized.add("text");
168
227
  return [...normalized];
169
228
  }
229
+ _Model.normalizeInput = normalizeInput;
170
230
  function toProviderInfo(providerId, provider) {
171
231
  return {
172
232
  id: providerId,
@@ -176,26 +236,9 @@ let Model;
176
236
  options: provider.headers
177
237
  };
178
238
  }
239
+ _Model.toProviderInfo = toProviderInfo;
179
240
  function toModelValue(providerId, provider, model) {
180
- const baseUrl = model.baseUrl ?? provider.baseUrl ?? provider.api;
181
- return {
182
- id: model.id,
183
- name: model.name,
184
- provider: toProviderInfo(providerId, provider),
185
- baseUrl,
186
- reasoning: Boolean(model.reasoning),
187
- input: normalizeInput(model.modalities.input),
188
- cost: {
189
- input: model.cost?.input ?? 0,
190
- output: model.cost?.output ?? 0,
191
- cacheRead: model.cost?.cache_read ?? 0,
192
- cacheWrite: model.cost?.cache_write ?? 0
193
- },
194
- contextWindow: model.limit?.context ?? 0,
195
- maxTokens: model.limit?.output ?? 0,
196
- headers: model.headers ?? provider.headers,
197
- protocol: resolveProtocol(providerId)
198
- };
241
+ return applyModification(providerId, provider, model);
199
242
  }
200
243
  async function getBuiltInModels() {
201
244
  return pipe(await ModelCatalog.get(), pick(BUILTINS), mapValues((provider, providerId) => mapValues(provider.models, (model) => toModelValue(providerId, provider, model))));
@@ -211,8 +254,13 @@ let Model;
211
254
  }
212
255
  return registry;
213
256
  });
214
- async function getModel(provider, model) {
215
- return (await registry()).get(provider)?.get(model);
257
+ async function getModel(provider, model, overrides) {
258
+ const result = (await registry()).get(provider)?.get(model);
259
+ if (result && overrides) return {
260
+ ...result,
261
+ ...overrides
262
+ };
263
+ return result;
216
264
  }
217
265
  _Model.getModel = getModel;
218
266
  async function getProviders() {
@@ -1296,8 +1344,10 @@ function sanitizeSurrogates(text) {
1296
1344
  return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
1297
1345
  }
1298
1346
  //#endregion
1299
- //#region src/provider/providers/anthropic/index.ts
1347
+ //#region src/provider/providers/utils.ts
1300
1348
  function getEnvApiKey(_provider) {}
1349
+ //#endregion
1350
+ //#region src/provider/providers/anthropic/index.ts
1301
1351
  function resolveCacheRetention(cacheRetention) {
1302
1352
  if (cacheRetention) return cacheRetention;
1303
1353
  if (typeof process !== "undefined" && process.env.CODEWORK_CACHE_RETENTION === "long") return "long";
@@ -1374,7 +1424,7 @@ function mergeHeaders(...headerSources) {
1374
1424
  function isOAuthToken(apiKey) {
1375
1425
  return apiKey.includes("sk-ant-oat");
1376
1426
  }
1377
- function createClient(model, apiKey, interleavedThinking, optionsHeaders) {
1427
+ function createClient$1(model, apiKey, interleavedThinking, optionsHeaders) {
1378
1428
  const betaFeatures = ["fine-grained-tool-streaming-2025-05-14"];
1379
1429
  if (interleavedThinking) betaFeatures.push("interleaved-thinking-2025-05-14");
1380
1430
  if (isOAuthToken(apiKey)) {
@@ -1432,7 +1482,7 @@ function assertReplayableAssistant(message) {
1432
1482
  if (!sawToolCall && message.stopReason === "toolUse") throw new Error("Assistant message with stopReason 'toolUse' must contain at least one toolCall");
1433
1483
  if (sawTerminalToolCall && sawNonTerminalToolCall) throw new Error("Assistant message cannot mix terminal and non-terminal toolCall states");
1434
1484
  }
1435
- function buildSyntheticToolResult(block) {
1485
+ function buildSyntheticToolResult$1(block) {
1436
1486
  return {
1437
1487
  type: "tool_result",
1438
1488
  tool_use_id: block.callID,
@@ -1447,7 +1497,7 @@ function buildSyntheticToolResult(block) {
1447
1497
  is_error: true
1448
1498
  };
1449
1499
  }
1450
- function convertMessages(messages, model, isOAuthToken, cacheControl) {
1500
+ function convertMessages$1(messages, model, isOAuthToken, cacheControl) {
1451
1501
  const params = [];
1452
1502
  const transformedMessages = Message.transformMessages(messages, model, normalizeToolCallId);
1453
1503
  for (const msg of transformedMessages) {
@@ -1503,7 +1553,7 @@ function convertMessages(messages, model, isOAuthToken, cacheControl) {
1503
1553
  name: isOAuthToken ? toClaudeCodeName(block.name) : block.name,
1504
1554
  input: block.arguments ?? {}
1505
1555
  });
1506
- if (block.status === "pending" || block.status === "running") toolResults.push(buildSyntheticToolResult(block));
1556
+ if (block.status === "pending" || block.status === "running") toolResults.push(buildSyntheticToolResult$1(block));
1507
1557
  else toolResults.push({
1508
1558
  type: "tool_result",
1509
1559
  tool_use_id: block.callID,
@@ -1535,7 +1585,7 @@ function convertMessages(messages, model, isOAuthToken, cacheControl) {
1535
1585
  }
1536
1586
  return params;
1537
1587
  }
1538
- function convertTools(tools, isOAuthToken) {
1588
+ function convertTools$1(tools, isOAuthToken) {
1539
1589
  if (!tools) return [];
1540
1590
  return tools.map((tool) => {
1541
1591
  const jsonSchema = tool.parameters;
@@ -1550,7 +1600,7 @@ function convertTools(tools, isOAuthToken) {
1550
1600
  };
1551
1601
  });
1552
1602
  }
1553
- function mapStopReason(reason) {
1603
+ function mapStopReason$1(reason) {
1554
1604
  switch (reason) {
1555
1605
  case "end_turn": return "stop";
1556
1606
  case "max_tokens": return "length";
@@ -1562,11 +1612,11 @@ function mapStopReason(reason) {
1562
1612
  default: throw new Error("Unhandled Anthropic stop reason");
1563
1613
  }
1564
1614
  }
1565
- function buildParams(model, context, isOAuthToken, options) {
1615
+ function buildParams$1(model, context, isOAuthToken, options) {
1566
1616
  const { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);
1567
1617
  const params = {
1568
1618
  model: model.id,
1569
- messages: convertMessages(context.messages, model, isOAuthToken, cacheControl),
1619
+ messages: convertMessages$1(context.messages, model, isOAuthToken, cacheControl),
1570
1620
  max_tokens: options?.maxTokens || model.maxTokens / 3 | 0,
1571
1621
  stream: true
1572
1622
  };
@@ -1587,7 +1637,7 @@ function buildParams(model, context, isOAuthToken, options) {
1587
1637
  ...cacheControl ? { cache_control: cacheControl } : {}
1588
1638
  }];
1589
1639
  if (options?.temperature !== void 0 && !options?.thinkingEnabled) params.temperature = options.temperature;
1590
- if (context.tools) params.tools = convertTools(context.tools, isOAuthToken);
1640
+ if (context.tools) params.tools = convertTools$1(context.tools, isOAuthToken);
1591
1641
  if (options?.thinkingEnabled && model.reasoning) params.thinking = {
1592
1642
  type: "enabled",
1593
1643
  budget_tokens: options.thinkingBudgetTokens || 1024
@@ -1635,13 +1685,13 @@ const streamAnthropic = (model, context, options) => {
1635
1685
  client = options.client;
1636
1686
  isOAuthToken = false;
1637
1687
  } else {
1638
- const apiKey = options?.apiKey ?? getEnvApiKey(model.provider);
1688
+ const apiKey = options?.apiKey ?? /* @__PURE__ */ getEnvApiKey(model.provider);
1639
1689
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider.id}`);
1640
- const created = createClient(model, apiKey, options?.interleavedThinking ?? true, options?.headers);
1690
+ const created = createClient$1(model, apiKey, options?.interleavedThinking ?? true, options?.headers);
1641
1691
  client = created.client;
1642
1692
  isOAuthToken = created.isOAuthToken;
1643
1693
  }
1644
- let params = buildParams(model, context, isOAuthToken, options);
1694
+ let params = buildParams$1(model, context, isOAuthToken, options);
1645
1695
  const nextParams = await options?.onPayload?.(params, model);
1646
1696
  if (nextParams !== void 0) params = nextParams;
1647
1697
  const anthropicStream = client.messages.stream({
@@ -1784,7 +1834,7 @@ const streamAnthropic = (model, context, options) => {
1784
1834
  }
1785
1835
  }
1786
1836
  } else if (event.type === "message_delta") {
1787
- if (event.delta.stop_reason) output.stopReason = mapStopReason(event.delta.stop_reason);
1837
+ if (event.delta.stop_reason) output.stopReason = mapStopReason$1(event.delta.stop_reason);
1788
1838
  if (event.usage.input_tokens != null) output.usage.input = event.usage.input_tokens;
1789
1839
  if (event.usage.output_tokens != null) output.usage.output = event.usage.output_tokens;
1790
1840
  if (event.usage.cache_read_input_tokens != null) output.usage.cacheRead = event.usage.cache_read_input_tokens;
@@ -1817,7 +1867,7 @@ const streamAnthropic = (model, context, options) => {
1817
1867
  return stream;
1818
1868
  };
1819
1869
  const streamSimpleAnthropic = (model, context, options) => {
1820
- const apiKey = options?.apiKey || getEnvApiKey(model.provider);
1870
+ const apiKey = options?.apiKey || /* @__PURE__ */ getEnvApiKey(model.provider);
1821
1871
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider.id}`);
1822
1872
  const base = Stream.buildBaseOptions(model, options, apiKey);
1823
1873
  if (!options?.reasoning) return streamAnthropic(model, context, {
@@ -1832,14 +1882,651 @@ const streamSimpleAnthropic = (model, context, options) => {
1832
1882
  thinkingBudgetTokens: adjusted.thinkingBudget
1833
1883
  });
1834
1884
  };
1835
- //#endregion
1836
- //#region src/provider/register.ts
1837
- const providerModules = [["providers/anthropic/index.ts", {
1885
+ const anthropicProtocolProvider = {
1838
1886
  protocol: Model.KnownProtocolEnum.anthropicMessages,
1839
1887
  stream: streamAnthropic,
1840
1888
  streamSimple: streamSimpleAnthropic
1841
- }]];
1842
- for (const [path, provider] of providerModules) Stream.registerProtocolProvider(provider, path);
1889
+ };
1890
+ //#endregion
1891
+ //#region src/provider/providers/github/github.ts
1892
+ function inferCopilotInitiator(messages) {
1893
+ const last = messages[messages.length - 1];
1894
+ return last && last.role !== "user" ? "agent" : "user";
1895
+ }
1896
+ function hasCopilotVisionInput(messages) {
1897
+ return messages.some((msg) => {
1898
+ if (msg.role === "user") return msg.parts.some((c) => c.type === "image");
1899
+ return false;
1900
+ });
1901
+ }
1902
+ function buildCopilotDynamicHeaders(params) {
1903
+ const headers = {
1904
+ "X-Initiator": inferCopilotInitiator(params.messages),
1905
+ "Openai-Intent": "conversation-edits"
1906
+ };
1907
+ if (params.hasImages) headers["Copilot-Vision-Request"] = "true";
1908
+ return headers;
1909
+ }
1910
+ //#endregion
1911
+ //#region src/provider/providers/openai/completions.ts
1912
+ function hasToolHistory(messages) {
1913
+ for (const msg of messages) {
1914
+ if (msg.role !== "assistant") continue;
1915
+ if (msg.parts.some((block) => block.type === "toolCall")) return true;
1916
+ }
1917
+ return false;
1918
+ }
1919
+ function buildSyntheticToolResult(block, compat) {
1920
+ const message = {
1921
+ role: "tool",
1922
+ content: [
1923
+ "<result>",
1924
+ "No Result Provided",
1925
+ "</result>"
1926
+ ].join("\n"),
1927
+ tool_call_id: block.callID
1928
+ };
1929
+ if (compat.requiresToolResultName) message.name = block.name;
1930
+ return message;
1931
+ }
1932
+ function resolveBaseUrl(model) {
1933
+ return model.baseUrl || (model.provider.id === Provider.KnownProviderEnum.openai ? "https://api.openai.com/v1" : "");
1934
+ }
1935
+ const streamOpenAICompletions = (model, context, options) => {
1936
+ const stream = new AssistantMessageEventStream();
1937
+ (async () => {
1938
+ const output = Message.createAssistantMessage({
1939
+ role: "assistant",
1940
+ parts: [],
1941
+ protocol: model.protocol,
1942
+ provider: model.provider,
1943
+ model: model.id,
1944
+ usage: {
1945
+ input: 0,
1946
+ output: 0,
1947
+ cacheRead: 0,
1948
+ cacheWrite: 0,
1949
+ totalTokens: 0,
1950
+ cost: {
1951
+ input: 0,
1952
+ output: 0,
1953
+ cacheRead: 0,
1954
+ cacheWrite: 0,
1955
+ total: 0
1956
+ }
1957
+ },
1958
+ stopReason: "stop",
1959
+ time: {
1960
+ created: Date.now(),
1961
+ completed: Date.now()
1962
+ }
1963
+ });
1964
+ try {
1965
+ const client = createClient(model, context, options?.apiKey || /* @__PURE__ */ getEnvApiKey(model.provider) || "", options?.headers);
1966
+ let params = buildParams(model, context, options);
1967
+ const nextParams = await options?.onPayload?.(params, model);
1968
+ if (nextParams !== void 0) params = nextParams;
1969
+ const openaiStream = await client.chat.completions.create(params, { signal: options?.signal });
1970
+ stream.push({
1971
+ type: "start",
1972
+ partial: output
1973
+ });
1974
+ let currentBlock = null;
1975
+ const blocks = output.parts;
1976
+ const activeToolCalls = /* @__PURE__ */ new Map();
1977
+ const finishCurrentBlock = (block) => {
1978
+ if (block) {
1979
+ const partIndex = block.index ?? blocks.indexOf(block);
1980
+ delete block.index;
1981
+ if (block.type === "text") stream.push({
1982
+ type: "text.end",
1983
+ partIndex,
1984
+ content: block.text,
1985
+ partial: output
1986
+ });
1987
+ else if (block.type === "thinking") stream.push({
1988
+ type: "thinking.end",
1989
+ partIndex,
1990
+ content: block.thinking,
1991
+ partial: output
1992
+ });
1993
+ else if (block.type === "toolCall") {
1994
+ if (block.streamIndex !== void 0) activeToolCalls.delete(block.streamIndex);
1995
+ block.arguments = parseStreamingJson(block.partialArgs);
1996
+ delete block.partialArgs;
1997
+ delete block.streamIndex;
1998
+ stream.push({
1999
+ type: "toolcall.end",
2000
+ partIndex,
2001
+ toolCall: block,
2002
+ partial: output
2003
+ });
2004
+ }
2005
+ }
2006
+ };
2007
+ const flushActiveToolCalls = () => {
2008
+ for (const toolBlock of [...activeToolCalls.values()].sort((a, b) => (a.index ?? 0) - (b.index ?? 0))) finishCurrentBlock(toolBlock);
2009
+ };
2010
+ for await (const chunk of openaiStream) {
2011
+ if (!chunk || typeof chunk !== "object") continue;
2012
+ output.responseId ||= chunk.id;
2013
+ if (chunk.usage) output.usage = parseChunkUsage(chunk.usage, model);
2014
+ const choice = Array.isArray(chunk.choices) ? chunk.choices[0] : void 0;
2015
+ if (!choice) continue;
2016
+ const choiceWithUsage = choice;
2017
+ if (!chunk.usage && choiceWithUsage.usage) output.usage = parseChunkUsage(choiceWithUsage.usage, model);
2018
+ if (choice.finish_reason) {
2019
+ const finishReasonResult = mapStopReason(choice.finish_reason);
2020
+ output.stopReason = finishReasonResult.stopReason;
2021
+ if (finishReasonResult.errorMessage) output.errorMessage = finishReasonResult.errorMessage;
2022
+ }
2023
+ if (!choice.delta) continue;
2024
+ if (choice.delta.content !== null && choice.delta.content !== void 0 && choice.delta.content.length > 0) {
2025
+ if (activeToolCalls.size > 0) flushActiveToolCalls();
2026
+ if (!currentBlock || currentBlock.type !== "text") {
2027
+ finishCurrentBlock(currentBlock);
2028
+ currentBlock = {
2029
+ type: "text",
2030
+ text: "",
2031
+ index: output.parts.length
2032
+ };
2033
+ output.parts.push(currentBlock);
2034
+ stream.push({
2035
+ type: "text.start",
2036
+ partIndex: currentBlock.index,
2037
+ partial: output
2038
+ });
2039
+ }
2040
+ if (currentBlock.type === "text") {
2041
+ currentBlock.text += choice.delta.content;
2042
+ stream.push({
2043
+ type: "text.delta",
2044
+ partIndex: currentBlock.index,
2045
+ delta: choice.delta.content,
2046
+ partial: output
2047
+ });
2048
+ }
2049
+ }
2050
+ const reasoningFields = [
2051
+ "reasoning_content",
2052
+ "reasoning",
2053
+ "reasoning_text"
2054
+ ];
2055
+ let foundReasoningField = null;
2056
+ for (const field of reasoningFields) {
2057
+ const value = choice.delta[field];
2058
+ if (typeof value === "string" && value.length > 0) {
2059
+ foundReasoningField = field;
2060
+ break;
2061
+ }
2062
+ }
2063
+ if (foundReasoningField) {
2064
+ if (activeToolCalls.size > 0) flushActiveToolCalls();
2065
+ if (!currentBlock || currentBlock.type !== "thinking") {
2066
+ finishCurrentBlock(currentBlock);
2067
+ currentBlock = {
2068
+ type: "thinking",
2069
+ thinking: "",
2070
+ thinkingSignature: foundReasoningField,
2071
+ index: output.parts.length
2072
+ };
2073
+ output.parts.push(currentBlock);
2074
+ stream.push({
2075
+ type: "thinking.start",
2076
+ partIndex: currentBlock.index,
2077
+ partial: output
2078
+ });
2079
+ }
2080
+ if (currentBlock.type === "thinking") {
2081
+ const delta = choice.delta[foundReasoningField];
2082
+ if (typeof delta === "string") {
2083
+ currentBlock.thinking += delta;
2084
+ stream.push({
2085
+ type: "thinking.delta",
2086
+ partIndex: currentBlock.index,
2087
+ delta,
2088
+ partial: output
2089
+ });
2090
+ }
2091
+ }
2092
+ }
2093
+ if (choice.delta.tool_calls) {
2094
+ if (currentBlock) {
2095
+ finishCurrentBlock(currentBlock);
2096
+ currentBlock = null;
2097
+ }
2098
+ for (const toolCall of choice.delta.tool_calls) {
2099
+ const streamIndex = toolCall.index ?? activeToolCalls.size;
2100
+ let toolBlock = activeToolCalls.get(streamIndex);
2101
+ if (!toolBlock) {
2102
+ toolBlock = {
2103
+ type: "toolCall",
2104
+ callID: toolCall.id || "",
2105
+ name: toolCall.function?.name || "",
2106
+ arguments: {},
2107
+ partialArgs: "",
2108
+ index: output.parts.length,
2109
+ streamIndex,
2110
+ status: "pending",
2111
+ time: {
2112
+ start: Date.now(),
2113
+ end: Date.now()
2114
+ }
2115
+ };
2116
+ activeToolCalls.set(streamIndex, toolBlock);
2117
+ output.parts.push(toolBlock);
2118
+ stream.push({
2119
+ type: "toolcall.start",
2120
+ partIndex: toolBlock.index,
2121
+ partial: output
2122
+ });
2123
+ }
2124
+ if (toolCall.id) toolBlock.callID = toolCall.id;
2125
+ if (toolCall.function?.name) toolBlock.name = toolCall.function.name;
2126
+ let delta = "";
2127
+ if (toolCall.function?.arguments) {
2128
+ delta = toolCall.function.arguments;
2129
+ toolBlock.partialArgs = (toolBlock.partialArgs || "") + delta;
2130
+ toolBlock.arguments = parseStreamingJson(toolBlock.partialArgs);
2131
+ }
2132
+ toolBlock.time.end = Date.now();
2133
+ stream.push({
2134
+ type: "toolcall.delta",
2135
+ partIndex: toolBlock.index,
2136
+ delta,
2137
+ partial: output
2138
+ });
2139
+ }
2140
+ }
2141
+ const reasoningDetails = choice.delta.reasoning_details;
2142
+ if (reasoningDetails && Array.isArray(reasoningDetails)) {
2143
+ for (const detail of reasoningDetails) if (detail.type === "reasoning.encrypted" && typeof detail.id === "string" && detail.data !== void 0) {
2144
+ const matchingToolCall = output.parts.find((block) => block.type === "toolCall" && block.callID === detail.id);
2145
+ if (matchingToolCall) matchingToolCall.thoughtSignature = JSON.stringify(detail);
2146
+ }
2147
+ }
2148
+ }
2149
+ finishCurrentBlock(currentBlock);
2150
+ flushActiveToolCalls();
2151
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
2152
+ if (output.stopReason === "aborted") throw new Error("Request was aborted");
2153
+ if (output.stopReason === "error") throw new Error(output.errorMessage || "Provider returned an error stop reason");
2154
+ output.time.completed = Date.now();
2155
+ stream.push({
2156
+ type: "done",
2157
+ reason: output.stopReason,
2158
+ message: output
2159
+ });
2160
+ stream.end();
2161
+ } catch (error) {
2162
+ for (const block of output.parts) {
2163
+ delete block.index;
2164
+ delete block.partialArgs;
2165
+ delete block.streamIndex;
2166
+ }
2167
+ output.time.completed = Date.now();
2168
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
2169
+ output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
2170
+ const rawMetadata = error?.error?.metadata?.raw;
2171
+ if (rawMetadata) output.errorMessage += `\n${rawMetadata}`;
2172
+ stream.push({
2173
+ type: "error",
2174
+ reason: output.stopReason,
2175
+ error: output
2176
+ });
2177
+ stream.end();
2178
+ }
2179
+ })();
2180
+ return stream;
2181
+ };
2182
+ const streamSimpleOpenAICompletions = (model, context, options) => {
2183
+ const apiKey = options?.apiKey || /* @__PURE__ */ getEnvApiKey(model.provider);
2184
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider.id}`);
2185
+ const base = Stream.buildBaseOptions(model, options, apiKey);
2186
+ const simpleReasoning = Model.supportsXhigh(model) ? options?.reasoning : Stream.clampReasoning(options?.reasoning);
2187
+ const reasoningEffort = simpleReasoning && simpleReasoning !== Stream.ThinkingLevelEnum.off ? simpleReasoning : void 0;
2188
+ const toolChoice = options?.toolChoice;
2189
+ return streamOpenAICompletions(model, context, {
2190
+ ...base,
2191
+ reasoningEffort,
2192
+ toolChoice
2193
+ });
2194
+ };
2195
+ function buildParams(model, context, options) {
2196
+ const compat = getCompat(model);
2197
+ const messages = convertMessages(model, context, compat);
2198
+ maybeAddOpenRouterAnthropicCacheControl(model, messages);
2199
+ const baseUrl = resolveBaseUrl(model);
2200
+ const params = {
2201
+ model: model.id,
2202
+ messages,
2203
+ stream: true
2204
+ };
2205
+ if (compat.supportsUsageInStreaming !== false) params.stream_options = { include_usage: true };
2206
+ if (compat.supportsStore) params.store = false;
2207
+ if (options?.maxTokens) if (compat.maxTokensField === "max_tokens") params.max_tokens = options.maxTokens;
2208
+ else params.max_completion_tokens = options.maxTokens;
2209
+ if (options?.temperature !== void 0) params.temperature = options.temperature;
2210
+ if (context.tools) {
2211
+ params.tools = convertTools(context.tools, compat);
2212
+ if (compat.zaiToolStream) params.tool_stream = true;
2213
+ } else if (hasToolHistory(context.messages)) params.tools = [];
2214
+ if (options?.toolChoice) params.tool_choice = options.toolChoice;
2215
+ if ((compat.thinkingFormat === "zai" || compat.thinkingFormat === "qwen") && model.reasoning) params.enable_thinking = !!options?.reasoningEffort;
2216
+ else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = { enable_thinking: !!options?.reasoningEffort };
2217
+ else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
2218
+ const openRouterParams = params;
2219
+ if (options?.reasoningEffort) openRouterParams.reasoning = { effort: mapReasoningEffort(options.reasoningEffort, compat.reasoningEffortMap) };
2220
+ else openRouterParams.reasoning = { effort: "none" };
2221
+ } else if (options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = mapReasoningEffort(options.reasoningEffort, compat.reasoningEffortMap);
2222
+ if (baseUrl.includes("openrouter.ai") && model.compat?.openRouterRouting) params.provider = model.compat.openRouterRouting;
2223
+ if (baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
2224
+ const routing = model.compat.vercelGatewayRouting;
2225
+ if (routing.only || routing.order) {
2226
+ const gatewayOptions = {};
2227
+ if (routing.only) gatewayOptions.only = routing.only;
2228
+ if (routing.order) gatewayOptions.order = routing.order;
2229
+ params.providerOptions = { gateway: gatewayOptions };
2230
+ }
2231
+ }
2232
+ return params;
2233
+ }
2234
+ function createClient(model, context, apiKey, optsHeaders) {
2235
+ const baseUrl = resolveBaseUrl(model);
2236
+ if (!apiKey) {
2237
+ if (!process.env.OPENAI_API_KEY) throw new Error("OpenAI API key is required. set OPENAI_API_KEY environment variable or pass it as an argument");
2238
+ apiKey = process.env.OPENAI_API_KEY;
2239
+ }
2240
+ const headers = { ...model.headers };
2241
+ if (model.provider.id === Provider.KnownProviderEnum.githubCopilot) {
2242
+ const hasImages = hasCopilotVisionInput(context.messages);
2243
+ const copilotHeaders = buildCopilotDynamicHeaders({
2244
+ messages: context.messages,
2245
+ hasImages
2246
+ });
2247
+ Object.assign(headers, copilotHeaders);
2248
+ }
2249
+ if (optsHeaders) Object.assign(headers, optsHeaders);
2250
+ return new OpenAI({
2251
+ apiKey,
2252
+ baseURL: baseUrl,
2253
+ dangerouslyAllowBrowser: true,
2254
+ defaultHeaders: headers
2255
+ });
2256
+ }
2257
+ function mapReasoningEffort(effort, reasoningEffortMap) {
2258
+ return reasoningEffortMap[effort] ?? effort;
2259
+ }
2260
+ function maybeAddOpenRouterAnthropicCacheControl(model, messages) {
2261
+ if (model.provider.id !== Provider.KnownProviderEnum.openrouter || !model.id.startsWith("anthropic/")) return;
2262
+ for (let i = messages.length - 1; i >= 0; i--) {
2263
+ const msg = messages[i];
2264
+ if (!msg) continue;
2265
+ if (msg.role !== "user" && msg.role !== "assistant") continue;
2266
+ const content = msg.content;
2267
+ if (typeof content === "string") {
2268
+ msg.content = [Object.assign({
2269
+ type: "text",
2270
+ text: content
2271
+ }, { cache_control: { type: "ephemeral" } })];
2272
+ return;
2273
+ }
2274
+ if (!Array.isArray(content)) continue;
2275
+ for (let j = content.length - 1; j >= 0; j--) {
2276
+ const part = content[j];
2277
+ if (part?.type === "text") {
2278
+ Object.assign(part, { cache_control: { type: "ephemeral" } });
2279
+ return;
2280
+ }
2281
+ }
2282
+ }
2283
+ }
2284
+ function convertMessages(model, context, compat) {
2285
+ const params = [];
2286
+ const normalizeToolCallId = (id) => {
2287
+ if (id.includes("|")) return (id.split("|")[0] ?? id).replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
2288
+ if (model.provider.id === Provider.KnownProviderEnum.openai) return id.length > 40 ? id.slice(0, 40) : id;
2289
+ return id;
2290
+ };
2291
+ const transformedMessages = Message.transformMessages(context.messages, model, normalizeToolCallId);
2292
+ if (context.systemPrompt) {
2293
+ const role = model.reasoning && compat.supportsDeveloperRole ? "developer" : "system";
2294
+ params.push({
2295
+ role,
2296
+ content: sanitizeSurrogates(context.systemPrompt)
2297
+ });
2298
+ }
2299
+ let lastRole = null;
2300
+ for (const msg of transformedMessages) {
2301
+ if (compat.requiresAssistantAfterToolResult && lastRole === "tool" && msg.role === "user") {
2302
+ params.push({
2303
+ role: "assistant",
2304
+ content: "I have processed the tool results."
2305
+ });
2306
+ lastRole = "assistant";
2307
+ }
2308
+ if (msg.role === "user") {
2309
+ const content = msg.parts.flatMap((item) => {
2310
+ if (item.type === "text") {
2311
+ const text = sanitizeSurrogates(item.text);
2312
+ if (text.trim().length === 0) return [];
2313
+ return [{
2314
+ type: "text",
2315
+ text
2316
+ }];
2317
+ }
2318
+ if (!model.input.includes("image")) return [];
2319
+ return [{
2320
+ type: "image_url",
2321
+ image_url: { url: `data:${item.mimeType};base64,${item.data}` }
2322
+ }];
2323
+ });
2324
+ if (content.length === 0) continue;
2325
+ params.push({
2326
+ role: "user",
2327
+ content
2328
+ });
2329
+ lastRole = "user";
2330
+ continue;
2331
+ }
2332
+ const assistantMsg = {
2333
+ role: "assistant",
2334
+ content: compat.requiresAssistantAfterToolResult ? "" : null
2335
+ };
2336
+ const textSegments = msg.parts.filter((block) => block.type === "text").map((block) => sanitizeSurrogates(block.text)).filter((text) => text.trim().length > 0);
2337
+ const nonEmptyThinkingBlocks = msg.parts.filter((block) => block.type === "thinking").filter((block) => block.thinking.trim().length > 0);
2338
+ if (compat.requiresThinkingAsText && nonEmptyThinkingBlocks.length > 0) textSegments.unshift(...nonEmptyThinkingBlocks.map((block) => sanitizeSurrogates(block.thinking)));
2339
+ else if (nonEmptyThinkingBlocks.length > 0) {
2340
+ const signature = nonEmptyThinkingBlocks[0]?.thinkingSignature;
2341
+ if (signature && signature.length > 0) assistantMsg[signature] = nonEmptyThinkingBlocks.map((block) => sanitizeSurrogates(block.thinking)).join("\n");
2342
+ }
2343
+ if (textSegments.length > 0) assistantMsg.content = textSegments.join("");
2344
+ const toolCalls = msg.parts.filter((block) => block.type === "toolCall");
2345
+ if (toolCalls.length > 0) {
2346
+ assistantMsg.tool_calls = toolCalls.map((toolCall) => ({
2347
+ id: toolCall.callID,
2348
+ type: "function",
2349
+ function: {
2350
+ name: toolCall.name,
2351
+ arguments: JSON.stringify(toolCall.arguments)
2352
+ }
2353
+ }));
2354
+ const reasoningDetails = toolCalls.filter((toolCall) => toolCall.thoughtSignature).map((toolCall) => {
2355
+ try {
2356
+ return JSON.parse(toolCall.thoughtSignature);
2357
+ } catch {
2358
+ return null;
2359
+ }
2360
+ }).filter(Boolean);
2361
+ if (reasoningDetails.length > 0) assistantMsg.reasoning_details = reasoningDetails;
2362
+ }
2363
+ const assistantContent = assistantMsg.content;
2364
+ if (!(assistantContent !== null && assistantContent !== void 0 && (typeof assistantContent === "string" ? assistantContent.length > 0 : assistantContent.length > 0)) && !assistantMsg.tool_calls) continue;
2365
+ params.push(assistantMsg);
2366
+ lastRole = "assistant";
2367
+ const imageBlocks = [];
2368
+ for (const toolCall of toolCalls) {
2369
+ if (toolCall.status === "pending" || toolCall.status === "running") {
2370
+ params.push(buildSyntheticToolResult(toolCall, compat));
2371
+ lastRole = "tool";
2372
+ continue;
2373
+ }
2374
+ const textResult = toolCall.result.content.filter((content) => content.type === "text").map((content) => content.text).join("\n");
2375
+ const hasImages = toolCall.result.content.some((content) => content.type === "image");
2376
+ const toolResultMsg = {
2377
+ role: "tool",
2378
+ content: sanitizeSurrogates(textResult.length > 0 ? textResult : "(see attached image)"),
2379
+ tool_call_id: toolCall.callID
2380
+ };
2381
+ if (compat.requiresToolResultName) toolResultMsg.name = toolCall.name;
2382
+ params.push(toolResultMsg);
2383
+ lastRole = "tool";
2384
+ if (hasImages && model.input.includes("image")) {
2385
+ for (const block of toolCall.result.content) if (block.type === "image") imageBlocks.push({
2386
+ type: "image_url",
2387
+ image_url: { url: `data:${block.mimeType};base64,${block.data}` }
2388
+ });
2389
+ }
2390
+ }
2391
+ if (imageBlocks.length > 0) {
2392
+ if (compat.requiresAssistantAfterToolResult) params.push({
2393
+ role: "assistant",
2394
+ content: "I have processed the tool results."
2395
+ });
2396
+ params.push({
2397
+ role: "user",
2398
+ content: [{
2399
+ type: "text",
2400
+ text: "Attached image(s) from tool result:"
2401
+ }, ...imageBlocks]
2402
+ });
2403
+ lastRole = "user";
2404
+ }
2405
+ }
2406
+ return params;
2407
+ }
2408
+ function convertTools(tools, compat) {
2409
+ return tools.map((tool) => ({
2410
+ type: "function",
2411
+ function: {
2412
+ name: tool.name,
2413
+ description: tool.description,
2414
+ parameters: tool.parameters,
2415
+ ...compat.supportsStrictMode !== false && { strict: false }
2416
+ }
2417
+ }));
2418
+ }
2419
+ function parseChunkUsage(rawUsage, model) {
2420
+ const promptTokens = rawUsage.prompt_tokens || 0;
2421
+ const reportedCachedTokens = rawUsage.prompt_tokens_details?.cached_tokens || 0;
2422
+ const cacheWriteTokens = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
2423
+ const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens || 0;
2424
+ const cacheReadTokens = cacheWriteTokens > 0 ? Math.max(0, reportedCachedTokens - cacheWriteTokens) : reportedCachedTokens;
2425
+ const input = Math.max(0, promptTokens - cacheReadTokens - cacheWriteTokens);
2426
+ const outputTokens = (rawUsage.completion_tokens || 0) + reasoningTokens;
2427
+ const usage = {
2428
+ input,
2429
+ output: outputTokens,
2430
+ cacheRead: cacheReadTokens,
2431
+ cacheWrite: cacheWriteTokens,
2432
+ totalTokens: input + outputTokens + cacheReadTokens + cacheWriteTokens,
2433
+ cost: {
2434
+ input: 0,
2435
+ output: 0,
2436
+ cacheRead: 0,
2437
+ cacheWrite: 0,
2438
+ total: 0
2439
+ }
2440
+ };
2441
+ Model.calculateCost(model, usage);
2442
+ return usage;
2443
+ }
2444
+ function mapStopReason(reason) {
2445
+ if (reason === null) return { stopReason: "stop" };
2446
+ switch (reason) {
2447
+ case "stop":
2448
+ case "end": return { stopReason: "stop" };
2449
+ case "length": return { stopReason: "length" };
2450
+ case "function_call":
2451
+ case "tool_calls": return { stopReason: "toolUse" };
2452
+ case "content_filter": return {
2453
+ stopReason: "error",
2454
+ errorMessage: "Provider finish_reason: content_filter"
2455
+ };
2456
+ case "network_error": return {
2457
+ stopReason: "error",
2458
+ errorMessage: "Provider finish_reason: network_error"
2459
+ };
2460
+ default: return {
2461
+ stopReason: "error",
2462
+ errorMessage: `Provider finish_reason: ${reason}`
2463
+ };
2464
+ }
2465
+ }
2466
+ function detectCompat(model) {
2467
+ const provider = model.provider.id;
2468
+ const baseUrl = resolveBaseUrl(model);
2469
+ const isZai = provider === "zai" || baseUrl.includes("api.z.ai");
2470
+ const isNonStandard = provider === "cerebras" || baseUrl.includes("cerebras.ai") || provider === "xai" || baseUrl.includes("api.x.ai") || baseUrl.includes("chutes.ai") || baseUrl.includes("deepseek.com") || isZai || provider === "opencode" || baseUrl.includes("opencode.ai");
2471
+ const useMaxTokens = baseUrl.includes("chutes.ai");
2472
+ const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
2473
+ const reasoningEffortMap = (provider === "groq" || baseUrl.includes("groq.com")) && model.id === "qwen/qwen3-32b" ? {
2474
+ minimal: "default",
2475
+ low: "default",
2476
+ medium: "default",
2477
+ high: "default",
2478
+ xhigh: "default"
2479
+ } : {};
2480
+ return {
2481
+ supportsStore: !isNonStandard,
2482
+ supportsDeveloperRole: !isNonStandard,
2483
+ supportsReasoningEffort: !isGrok && !isZai,
2484
+ reasoningEffortMap,
2485
+ supportsUsageInStreaming: true,
2486
+ maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
2487
+ requiresToolResultName: false,
2488
+ requiresAssistantAfterToolResult: false,
2489
+ requiresThinkingAsText: false,
2490
+ thinkingFormat: isZai ? "zai" : provider === "openrouter" || baseUrl.includes("openrouter.ai") ? "openrouter" : "openai",
2491
+ openRouterRouting: {},
2492
+ vercelGatewayRouting: {},
2493
+ zaiToolStream: false,
2494
+ supportsStrictMode: true
2495
+ };
2496
+ }
2497
+ /**
2498
+ * Get resolved compatibility settings for a model.
2499
+ * Uses explicit model.compat if provided, otherwise auto-detects from provider/URL.
2500
+ */
2501
+ function getCompat(model) {
2502
+ const detected = detectCompat(model);
2503
+ if (!model.compat) return detected;
2504
+ return {
2505
+ supportsStore: model.compat.supportsStore ?? detected.supportsStore,
2506
+ supportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,
2507
+ supportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,
2508
+ reasoningEffortMap: model.compat.reasoningEffortMap ?? detected.reasoningEffortMap,
2509
+ supportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
2510
+ maxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,
2511
+ requiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,
2512
+ requiresAssistantAfterToolResult: model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
2513
+ requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
2514
+ thinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,
2515
+ openRouterRouting: model.compat.openRouterRouting ?? {},
2516
+ vercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,
2517
+ zaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,
2518
+ supportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode
2519
+ };
2520
+ }
2521
+ const openAICompletionsProtocolProvider = {
2522
+ protocol: Model.KnownProtocolEnum.openaiCompletions,
2523
+ stream: streamOpenAICompletions,
2524
+ streamSimple: streamSimpleOpenAICompletions
2525
+ };
2526
+ //#endregion
2527
+ //#region src/provider/register.ts
2528
+ Stream.registerProtocolProvider(anthropicProtocolProvider, "providers/anthropic/index.ts");
2529
+ Stream.registerProtocolProvider(openAICompletionsProtocolProvider, "providers/openai/completions.ts");
1843
2530
  //#endregion
1844
2531
  //#region src/agent/agent.ts
1845
2532
  let Agent;
@@ -2656,7 +3343,7 @@ let CodeMode;
2656
3343
  })(CodeMode || (CodeMode = {}));
2657
3344
  //#endregion
2658
3345
  //#region src/llm.ts
2659
- const llmImpl = async (provider, model) => Model.getModel(provider, model);
3346
+ const llmImpl = async (provider, model, overrides) => Model.getModel(provider, model, overrides);
2660
3347
  const llm = Object.assign(llmImpl, {
2661
3348
  model: Model.getModel,
2662
3349
  models: Model.getModels,