@rebon/cli-darwin-arm64 0.17.2 → 0.18.0

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.
Files changed (82) hide show
  1. package/bin/compose-runtime/package.json +17 -0
  2. package/bin/compose-runtime/payload/compose/credentials-runtime.js +38 -0
  3. package/bin/compose-runtime/payload/compose/llm-runtime.js +330 -0
  4. package/bin/compose-runtime/payload/compose/loop-assembly.js +149 -0
  5. package/bin/compose-runtime/payload/compose/serve-dispatch.js +82 -0
  6. package/bin/compose-runtime/payload/compose/shims/dsh-anonymous-user-id.js +10 -0
  7. package/bin/compose-runtime/payload/compose/shims/dsh-credentials.js +13 -0
  8. package/bin/compose-runtime/payload/compose/shims/dsh-launch-environment.js +21 -0
  9. package/bin/compose-runtime/payload/compose/shims/dsh-llm.js +313 -0
  10. package/bin/compose-runtime/payload/compose/shims/dsh-settings.js +43 -0
  11. package/bin/compose-runtime/payload/compose/shims/dsh-tools.js +20 -0
  12. package/bin/compose-runtime/payload/compose/shims/dsh-web.js +10 -0
  13. package/bin/compose-runtime/payload/compose/shims/llm-adapter.js +32 -0
  14. package/bin/compose-runtime/payload/compose/shims/zod-lite.js +49 -0
  15. package/bin/compose-runtime/payload/compose/systemprompt-runtime.js +74 -0
  16. package/bin/compose-runtime/payload/compose/tools-runtime.js +228 -0
  17. package/bin/compose-runtime/payload/compose/web-runtime.js +204 -0
  18. package/bin/compose-runtime/payload/vendor/cordis/index.js +1530 -0
  19. package/bin/compose-runtime/payload/vendor/cosmokit/LICENSE +21 -0
  20. package/bin/compose-runtime/payload/vendor/cosmokit/index.mjs +357 -0
  21. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-agent +21 -0
  22. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-agent-loop +21 -0
  23. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-llm-core +21 -0
  24. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-llm-deepseek +21 -0
  25. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-logger-console +21 -0
  26. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-scope +21 -0
  27. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-session +21 -0
  28. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-system-prompt +21 -0
  29. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-timeout +21 -0
  30. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-timer +21 -0
  31. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-tool-todo +21 -0
  32. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-tool-web +21 -0
  33. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-tools-schema +21 -0
  34. package/bin/compose-runtime/payload/vendor/dsh/LICENSE-web-search-exa +21 -0
  35. package/bin/compose-runtime/payload/vendor/dsh/agent-loop.js +1193 -0
  36. package/bin/compose-runtime/payload/vendor/dsh/agent.js +714 -0
  37. package/bin/compose-runtime/payload/vendor/dsh/llm-core.js +269 -0
  38. package/bin/compose-runtime/payload/vendor/dsh/llm-deepseek.js +672 -0
  39. package/bin/compose-runtime/payload/vendor/dsh/logger-console.js +83 -0
  40. package/bin/compose-runtime/payload/vendor/dsh/scope.js +287 -0
  41. package/bin/compose-runtime/payload/vendor/dsh/session.js +1668 -0
  42. package/bin/compose-runtime/payload/vendor/dsh/system-prompt.js +309 -0
  43. package/bin/compose-runtime/payload/vendor/dsh/timeout.js +100 -0
  44. package/bin/compose-runtime/payload/vendor/dsh/timer.js +128 -0
  45. package/bin/compose-runtime/payload/vendor/dsh/tool-todo.js +143 -0
  46. package/bin/compose-runtime/payload/vendor/dsh/tool-web.js +1527 -0
  47. package/bin/compose-runtime/payload/vendor/dsh/tools-schema.js +849 -0
  48. package/bin/compose-runtime/payload/vendor/dsh/web-search-exa.js +122 -0
  49. package/bin/compose-runtime/payload/vendor/eventsource-parser/LICENSE +21 -0
  50. package/bin/compose-runtime/payload/vendor/eventsource-parser/index.js +177 -0
  51. package/bin/compose-runtime/payload/vendor/eventsource-parser/stream.js +48 -0
  52. package/bin/compose-runtime/payload/vendor/schemastery/index.mjs +656 -0
  53. package/bin/compose-runtime/payload-manifests.json +48 -0
  54. package/bin/compose-runtime/src/bridge.mjs +142 -0
  55. package/bin/compose-runtime/src/credentials-runtime.mjs +50 -0
  56. package/bin/compose-runtime/src/eventsource-stream.mjs +48 -0
  57. package/bin/compose-runtime/src/index.mjs +7 -0
  58. package/bin/compose-runtime/src/llm-runtime.mjs +326 -0
  59. package/bin/compose-runtime/src/loader.mjs +78 -0
  60. package/bin/compose-runtime/src/loop-assembly.mjs +237 -0
  61. package/bin/compose-runtime/src/payload.mjs +49 -0
  62. package/bin/compose-runtime/src/plugin.mjs +59 -0
  63. package/bin/compose-runtime/src/realm.mjs +223 -0
  64. package/bin/compose-runtime/src/registry.mjs +191 -0
  65. package/bin/compose-runtime/src/resolve.mjs +115 -0
  66. package/bin/compose-runtime/src/systemprompt-runtime.mjs +67 -0
  67. package/bin/compose-runtime/src/tools-runtime.mjs +239 -0
  68. package/bin/compose-runtime/src/web-runtime.mjs +209 -0
  69. package/bin/plugin-host/package.json +11 -0
  70. package/bin/plugin-host/src/bridge.mjs +64 -0
  71. package/bin/plugin-host/src/cli.mjs +105 -0
  72. package/bin/plugin-host/src/framing.mjs +113 -0
  73. package/bin/plugin-host/src/host.mjs +624 -0
  74. package/bin/plugin-host/src/json.mjs +196 -0
  75. package/bin/plugin-host/src/lifecycle.mjs +114 -0
  76. package/bin/plugin-host/src/loader.mjs +142 -0
  77. package/bin/plugin-host/src/methods.mjs +256 -0
  78. package/bin/plugin-host/src/protocol.mjs +129 -0
  79. package/bin/plugin-host/src/sdk.mjs +7 -0
  80. package/bin/rebon +0 -0
  81. package/bin/rebon-boa-helper +0 -0
  82. package/package.json +4 -1
@@ -0,0 +1,672 @@
1
+ var __knownSymbol = (name2, symbol) => (symbol = Symbol[name2]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name2);
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __using = (stack, value, async) => {
6
+ if (value != null) {
7
+ if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
8
+ var dispose, inner;
9
+ if (async) dispose = value[__knownSymbol("asyncDispose")];
10
+ if (dispose === void 0) {
11
+ dispose = value[__knownSymbol("dispose")];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") __typeError("Object not disposable");
15
+ if (inner) dispose = function() {
16
+ try {
17
+ inner.call(this);
18
+ } catch (e) {
19
+ return Promise.reject(e);
20
+ }
21
+ };
22
+ stack.push([async, dispose, value]);
23
+ } else if (async) {
24
+ stack.push([async]);
25
+ }
26
+ return value;
27
+ };
28
+ var __callDispose = (stack, error, hasError) => {
29
+ var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
30
+ return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
31
+ };
32
+ var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
33
+ var next = (it) => {
34
+ while (it = stack.pop()) {
35
+ try {
36
+ var result = it[1] && it[1].call(it[2]);
37
+ if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
38
+ } catch (e) {
39
+ fail(e);
40
+ }
41
+ }
42
+ if (hasError) throw error;
43
+ };
44
+ return next();
45
+ };
46
+
47
+ // packages/llm/llm-deepseek/src/index.ts
48
+ import z from "@deepseek-ai/schemastery";
49
+ import { assertUsableApiKey, LlmError as LlmError5, resolveRetryPolicy, RetryPolicySchema } from "@deepseek-ai/dsh-llm";
50
+ import { credentialRef } from "@deepseek-ai/dsh-credentials";
51
+ import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
52
+ import { deepEqualJson, installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
53
+ import { MAX_TIMER_DELAY_MS } from "@deepseek-ai/dsh-timeout";
54
+ import { getOrCreateAnonymousUserId } from "@deepseek-ai/dsh-anonymous-user-id";
55
+
56
+ // packages/llm/llm-deepseek/src/adapter.ts
57
+ import { attributionHeaders, CONTEXT_WINDOW_EXCEEDED_CODE, isContextWindowExceededError, isQuotaExceededError, LlmAdapter, LlmError as LlmError4, ProviderRequestId, QUOTA_EXCEEDED_CODE, ReasoningEffortId } from "@deepseek-ai/dsh-llm";
58
+ import { idleWatchdog, timeoutOf } from "@deepseek-ai/dsh-timeout";
59
+
60
+ // packages/llm/llm-deepseek/src/serialize.ts
61
+ import { contentHasImage, LlmError } from "@deepseek-ai/dsh-llm";
62
+ function reasoningEffort(effort) {
63
+ if (effort === "off" || effort === "high" || effort === "max") {
64
+ return effort;
65
+ }
66
+ throw new LlmError(
67
+ `DeepSeek does not support reasoning effort "${effort}"`,
68
+ "UNSUPPORTED_REASONING_EFFORT"
69
+ );
70
+ }
71
+ function resolveThinking(options, defaults) {
72
+ if (options.purpose === "session-title") return { thinking: "disabled" };
73
+ const effort = options.reasoningEffort === void 0 ? defaults.reasoningEffort : reasoningEffort(options.reasoningEffort);
74
+ if (defaults.thinking === "disabled" && effort !== void 0 && effort !== "off") {
75
+ throw new LlmError(
76
+ `DeepSeek deployment does not support reasoning effort "${effort}"`,
77
+ "UNSUPPORTED_REASONING_EFFORT"
78
+ );
79
+ }
80
+ if (effort === "off") return { thinking: "disabled" };
81
+ if (effort === "high" || effort === "max") {
82
+ return { thinking: "enabled", reasoningEffort: effort };
83
+ }
84
+ return defaults.thinking === void 0 ? {} : { thinking: defaults.thinking };
85
+ }
86
+ function flattenText(blocks) {
87
+ return blocks.filter((block) => block.type === "text").map((block) => block.text).join("");
88
+ }
89
+ function assertTextOnly(blocks) {
90
+ if (contentHasImage(blocks)) {
91
+ throw new LlmError("The DeepSeek chat-completions adapter does not support image content.", "UNSUPPORTED_CONTENT");
92
+ }
93
+ }
94
+ function serializeAssistant(message) {
95
+ const text = flattenText(message.content);
96
+ const reasoning = message.content.filter((block) => block.type === "reasoning").map((block) => block.text).join("");
97
+ const toolCalls = message.content.filter((block) => block.type === "tool-call").map((block) => ({
98
+ id: block.id,
99
+ type: "function",
100
+ function: { name: block.name, arguments: block.arguments }
101
+ }));
102
+ return {
103
+ role: "assistant",
104
+ // Text-less turns send "" — NEVER null. Pure tool-call turns: the
105
+ // official samples replay message.content verbatim (which is "") and
106
+ // some gateways reject null outright. Reasoning-ONLY turns (the model
107
+ // can answer entirely in the reasoning channel, e.g. a v4-flash
108
+ // greeting): the live API rejects null-content/no-tool_calls assistant
109
+ // messages with a 400 ("content or tool_calls must be set"), and since
110
+ // the message sits durably in the session log, a null here bricks every
111
+ // later turn of that session.
112
+ content: text,
113
+ // Official passback rule (guides/thinking_mode.mdx): reasoning_content
114
+ // must return on tool-call turns; it is ignored on plain turns, so we
115
+ // drop it there to save tokens.
116
+ ...toolCalls.length > 0 && reasoning.length > 0 ? { reasoning_content: reasoning } : {},
117
+ ...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
118
+ };
119
+ }
120
+ function serializeMessages(messages) {
121
+ const wire = [];
122
+ for (const message of messages) {
123
+ assertTextOnly(message.content);
124
+ if (message.role === "system") {
125
+ wire.push({ role: "system", content: flattenText(message.content) });
126
+ continue;
127
+ }
128
+ if (message.role === "assistant") {
129
+ wire.push(serializeAssistant(message));
130
+ continue;
131
+ }
132
+ const toolResults = message.content.filter((block) => block.type === "tool-result");
133
+ const text = flattenText(message.content);
134
+ if (text.length > 0 || toolResults.length === 0) {
135
+ wire.push({ role: "user", content: text });
136
+ }
137
+ for (const result of toolResults) {
138
+ wire.push({
139
+ role: "tool",
140
+ tool_call_id: result.toolCallId,
141
+ // Empty tool output still needs SOME content on the wire.
142
+ content: flattenText(result.content) || "(no output)"
143
+ });
144
+ }
145
+ }
146
+ return wire;
147
+ }
148
+ function serializeRequest(options, defaults = {}) {
149
+ const messages = [];
150
+ if (options.system !== void 0) {
151
+ messages.push({ role: "system", content: options.system });
152
+ }
153
+ messages.push(...serializeMessages(options.messages));
154
+ const tools = options.tools?.map((tool) => ({
155
+ type: "function",
156
+ function: {
157
+ name: tool.name,
158
+ description: tool.description,
159
+ parameters: tool.parameters
160
+ }
161
+ }));
162
+ const resolvedThinking = resolveThinking(options, defaults);
163
+ return {
164
+ model: options.model,
165
+ messages,
166
+ stream: true,
167
+ stream_options: { include_usage: true },
168
+ ...resolvedThinking.thinking !== void 0 ? { thinking: { type: resolvedThinking.thinking } } : {},
169
+ ...resolvedThinking.reasoningEffort !== void 0 ? { reasoning_effort: resolvedThinking.reasoningEffort } : {},
170
+ ...tools !== void 0 && tools.length > 0 ? { tools } : {},
171
+ ...options.temperature !== void 0 ? { temperature: options.temperature } : {},
172
+ ...options.maxTokens === void 0 ? {} : { max_tokens: options.maxTokens },
173
+ ...options.stop !== void 0 ? { stop: options.stop } : {}
174
+ };
175
+ }
176
+
177
+ // packages/llm/llm-deepseek/src/sse.ts
178
+ import { EventSourceParserStream } from "eventsource-parser/stream";
179
+ import { LlmError as LlmError2 } from "@deepseek-ai/dsh-llm";
180
+ var DONE = "[DONE]";
181
+ async function* parseSse(stream, onComment) {
182
+ const events = stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream({ onComment }));
183
+ for await (const { data } of events) {
184
+ yield data;
185
+ if (data === DONE) return;
186
+ }
187
+ throw new LlmError2("SSE stream ended without [DONE]", "STREAM_CLOSED");
188
+ }
189
+
190
+ // packages/llm/llm-deepseek/src/translate.ts
191
+ import { CallId, EMPTY_RESPONSE_CODE, LlmError as LlmError3 } from "@deepseek-ai/dsh-llm";
192
+ function mapFinishReason(reason) {
193
+ switch (reason) {
194
+ case "stop":
195
+ return { kind: "stop" };
196
+ case "tool_calls":
197
+ return { kind: "tool-calls" };
198
+ case "length":
199
+ return { kind: "max-tokens" };
200
+ default:
201
+ return {
202
+ kind: "error",
203
+ failure: { message: `model stopped: ${reason}`, code: reason.toUpperCase() }
204
+ };
205
+ }
206
+ }
207
+ function mapUsage(usage) {
208
+ const cacheRead = usage.prompt_tokens_details?.cached_tokens ?? usage.prompt_cache_hit_tokens;
209
+ const reasoning = usage.completion_tokens_details?.reasoning_tokens;
210
+ return {
211
+ inputTokens: usage.prompt_tokens - (cacheRead ?? 0),
212
+ outputTokens: usage.completion_tokens,
213
+ ...cacheRead !== void 0 ? { cacheReadTokens: cacheRead } : {},
214
+ ...reasoning !== void 0 ? { reasoningTokens: reasoning } : {}
215
+ };
216
+ }
217
+ function closeBlock(block) {
218
+ switch (block.kind) {
219
+ case "text":
220
+ return { type: "text", text: block.text };
221
+ case "reasoning":
222
+ return { type: "reasoning", text: block.text };
223
+ case "tool-call":
224
+ return {
225
+ type: "tool-call",
226
+ id: CallId(block.callId ?? ""),
227
+ name: block.name ?? "",
228
+ arguments: block.text
229
+ };
230
+ }
231
+ }
232
+ async function* translate(payloads) {
233
+ let nextIndex = 0;
234
+ let textBlock;
235
+ let reasoningBlock;
236
+ const toolBlocks = /* @__PURE__ */ new Map();
237
+ const order = [];
238
+ let pendingFinish;
239
+ let pendingUsage;
240
+ function open(kind) {
241
+ const block = { index: nextIndex++, kind, text: "" };
242
+ order.push(block);
243
+ return block;
244
+ }
245
+ for await (const payload of payloads) {
246
+ if (payload === DONE) {
247
+ for (const block of order) {
248
+ yield { type: "block-end", index: block.index, block: closeBlock(block) };
249
+ }
250
+ if (pendingUsage) yield { type: "usage", usage: pendingUsage };
251
+ const reason = pendingFinish ?? { kind: "stop" };
252
+ yield {
253
+ type: "finish",
254
+ reason: reason.kind === "stop" && order.length === 0 ? {
255
+ kind: "error",
256
+ failure: { message: "model returned a completed response with no content", code: EMPTY_RESPONSE_CODE }
257
+ } : reason
258
+ };
259
+ return;
260
+ }
261
+ let chunk;
262
+ try {
263
+ chunk = JSON.parse(payload);
264
+ } catch {
265
+ throw new LlmError3(`malformed SSE payload: ${payload.slice(0, 120)}`, "MALFORMED_RESPONSE");
266
+ }
267
+ for (const choice of chunk.choices ?? []) {
268
+ const delta = choice.delta;
269
+ const reasoning = delta?.reasoning_content;
270
+ if (typeof reasoning === "string" && reasoning.length > 0) {
271
+ if (!reasoningBlock) {
272
+ reasoningBlock = open("reasoning");
273
+ yield { type: "block-start", index: reasoningBlock.index, blockType: "reasoning" };
274
+ }
275
+ reasoningBlock.text += reasoning;
276
+ yield { type: "reasoning-delta", index: reasoningBlock.index, text: reasoning };
277
+ }
278
+ const content = delta?.content;
279
+ if (typeof content === "string" && content.length > 0) {
280
+ if (!textBlock) {
281
+ textBlock = open("text");
282
+ yield { type: "block-start", index: textBlock.index, blockType: "text" };
283
+ }
284
+ textBlock.text += content;
285
+ yield { type: "text-delta", index: textBlock.index, text: content };
286
+ }
287
+ for (const call of delta?.tool_calls ?? []) {
288
+ let block = toolBlocks.get(call.index);
289
+ if (!block) {
290
+ block = open("tool-call");
291
+ toolBlocks.set(call.index, block);
292
+ yield { type: "block-start", index: block.index, blockType: "tool-call" };
293
+ }
294
+ if (call.id !== void 0) block.callId = call.id;
295
+ if (call.function?.name !== void 0) block.name = call.function.name;
296
+ const fragment = call.function?.arguments ?? "";
297
+ block.text += fragment;
298
+ yield {
299
+ type: "tool-call-delta",
300
+ index: block.index,
301
+ id: CallId(block.callId ?? ""),
302
+ ...block.name !== void 0 ? { name: block.name } : {},
303
+ argumentsDelta: fragment
304
+ };
305
+ }
306
+ if (typeof choice.finish_reason === "string") {
307
+ pendingFinish = mapFinishReason(choice.finish_reason);
308
+ }
309
+ }
310
+ if (chunk.usage) pendingUsage = mapUsage(chunk.usage);
311
+ }
312
+ throw new LlmError3("SSE payload stream ended without [DONE]", "STREAM_CLOSED");
313
+ }
314
+
315
+ // packages/llm/llm-deepseek/src/adapter.ts
316
+ var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
317
+ var DEFAULT_CONTEXT_WINDOW = 1e6;
318
+ var DEFAULT_MAX_TOKENS = 256e3;
319
+ var STREAM_IDLE_TIMEOUT_CODE = "LLM_STREAM_IDLE_TIMEOUT";
320
+ var OFF_REASONING_EFFORT = ReasoningEffortId("off");
321
+ var HIGH_REASONING_EFFORT = ReasoningEffortId("high");
322
+ var MAX_REASONING_EFFORT = ReasoningEffortId("max");
323
+ var REASONING_EFFORTS = [
324
+ { id: OFF_REASONING_EFFORT, name: "Off" },
325
+ { id: HIGH_REASONING_EFFORT, name: "High" },
326
+ { id: MAX_REASONING_EFFORT, name: "Max" }
327
+ ];
328
+ var OFF_ONLY_REASONING_EFFORTS = [
329
+ { id: OFF_REASONING_EFFORT, name: "Off" }
330
+ ];
331
+ function modelInfo(provider, model) {
332
+ return {
333
+ provider,
334
+ id: model.id,
335
+ name: model.name ?? model.id,
336
+ ...model.description === void 0 ? {} : { description: model.description },
337
+ inputModalities: ["text"]
338
+ };
339
+ }
340
+ function providerRetryAfterMs(value) {
341
+ if (value === null) return void 0;
342
+ if (/^\d+$/.test(value)) {
343
+ const delay2 = Number(value) * 1e3;
344
+ return Number.isFinite(delay2) && delay2 > 0 ? delay2 : void 0;
345
+ }
346
+ const delay = Date.parse(value) - Date.now();
347
+ return Number.isFinite(delay) && delay > 0 ? delay : void 0;
348
+ }
349
+ function requestId(headers) {
350
+ const value = headers.get("x-request-id") ?? headers.get("x-deepseek-request-id");
351
+ return value === null || value.length === 0 ? void 0 : ProviderRequestId(value);
352
+ }
353
+ function httpErrorCode(status, error) {
354
+ if (status === 401 || status === 403) return "AUTH";
355
+ const detail = [error?.code, error?.type, error?.message].filter(Boolean).join(" ");
356
+ if (isQuotaExceededError(detail)) return QUOTA_EXCEEDED_CODE;
357
+ if (status === 429) return "RATE_LIMIT";
358
+ if (status === 400) {
359
+ if (isContextWindowExceededError(detail)) return CONTEXT_WINDOW_EXCEEDED_CODE;
360
+ return "INVALID_REQUEST";
361
+ }
362
+ if (status >= 500) return "SERVER";
363
+ return `HTTP_${status}`;
364
+ }
365
+ var DeepSeekAdapter = class extends LlmAdapter {
366
+ constructor(config) {
367
+ super();
368
+ this.config = config;
369
+ }
370
+ config;
371
+ providerInfo(provider) {
372
+ return { id: provider, name: "DeepSeek" };
373
+ }
374
+ providerRetryPolicy(_provider) {
375
+ return this.config.options().retryPolicy;
376
+ }
377
+ listModels(provider) {
378
+ return Promise.resolve(this.config.options().models.map((model) => modelInfo(provider, model)));
379
+ }
380
+ resolveModel(provider, model, _signal) {
381
+ const connection = this.config.options();
382
+ const configured = connection.models.find((entry) => entry.id === model);
383
+ const contextWindow = configured?.contextWindow ?? connection.defaultContextWindow;
384
+ return Promise.resolve({
385
+ // The chat-completions wire route is text-only regardless of catalog
386
+ // membership, so the uncatalogued fallback declares the same negative
387
+ // capability — "unknown" here would let the host accept and persist
388
+ // images the serializer must then reject.
389
+ ...configured === void 0 ? { provider, id: model, name: model, inputModalities: ["text"] } : modelInfo(provider, configured),
390
+ context: { contextWindow },
391
+ defaultMaxTokens: configured?.maxTokens ?? connection.maxTokens,
392
+ ...connection.defaults.thinking === "disabled" ? {
393
+ reasoning: {
394
+ efforts: OFF_ONLY_REASONING_EFFORTS,
395
+ defaultEffort: OFF_REASONING_EFFORT
396
+ }
397
+ } : {
398
+ reasoning: {
399
+ efforts: REASONING_EFFORTS,
400
+ defaultEffort: connection.defaults.reasoningEffort === "off" ? OFF_REASONING_EFFORT : connection.defaults.reasoningEffort === "max" ? MAX_REASONING_EFFORT : HIGH_REASONING_EFFORT
401
+ }
402
+ }
403
+ });
404
+ }
405
+ async *stream(options) {
406
+ var _stack = [];
407
+ try {
408
+ const connection = this.config.options();
409
+ const apiKey = await this.config.resolveApiKey(connection);
410
+ const userId = this.config.resolveUserId();
411
+ const consumer = new AbortController();
412
+ const upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);
413
+ const watchdog = __using(_stack, idleWatchdog(upstream, connection.streamIdleTimeoutMs, STREAM_IDLE_TIMEOUT_CODE));
414
+ const iterator = this.request(
415
+ options,
416
+ watchdog.signal,
417
+ connection,
418
+ apiKey,
419
+ userId,
420
+ () => {
421
+ watchdog.pulse();
422
+ }
423
+ )[Symbol.asyncIterator]();
424
+ let exhausted = false;
425
+ try {
426
+ while (true) {
427
+ const result = await watchdog.next(iterator);
428
+ if (result.done) {
429
+ exhausted = true;
430
+ return;
431
+ }
432
+ yield result.value;
433
+ }
434
+ } catch (error) {
435
+ if (timeoutOf(watchdog.signal, STREAM_IDLE_TIMEOUT_CODE) !== void 0) {
436
+ throw new LlmError4(
437
+ `DeepSeek stream idle timeout after ${connection.streamIdleTimeoutMs}ms`,
438
+ "TIMEOUT",
439
+ { cause: error }
440
+ );
441
+ }
442
+ if (options.signal?.aborted) {
443
+ throw new LlmError4("DeepSeek request aborted by caller", "ABORTED", { cause: error });
444
+ }
445
+ if (error instanceof LlmError4) throw error;
446
+ throw new LlmError4(`DeepSeek API stream from ${connection.baseURL} failed`, "TRANSPORT", { cause: error });
447
+ } finally {
448
+ consumer.abort("DeepSeek stream consumer stopped");
449
+ if (!exhausted && iterator.return !== void 0) {
450
+ try {
451
+ await iterator.return();
452
+ } catch (_abortedTransportTeardown) {
453
+ }
454
+ }
455
+ }
456
+ } catch (_) {
457
+ var _error = _, _hasError = true;
458
+ } finally {
459
+ __callDispose(_stack, _error, _hasError);
460
+ }
461
+ }
462
+ async *request(options, signal, connection, apiKey, userId, onComment) {
463
+ const body = serializeRequest(options, connection.defaults);
464
+ const payload = JSON.stringify(body);
465
+ const headers = {
466
+ "authorization": `Bearer ${apiKey}`,
467
+ "content-type": "application/json",
468
+ "accept": "text/event-stream",
469
+ ...attributionHeaders(),
470
+ "x-deepseek-harness-user-id": String(userId),
471
+ ...options.sessionId !== void 0 ? { "x-deepseek-harness-session-id": String(options.sessionId) } : {},
472
+ ...options.purpose === "compaction" ? { "x-deepseek-harness-compact": "1" } : {}
473
+ };
474
+ let response;
475
+ try {
476
+ response = await fetch(`${connection.baseURL}/chat/completions`, {
477
+ method: "POST",
478
+ headers,
479
+ body: payload,
480
+ signal
481
+ });
482
+ } catch (error) {
483
+ if (signal.aborted) throw error;
484
+ throw new LlmError4(
485
+ `DeepSeek API request to ${connection.baseURL} failed`,
486
+ "TRANSPORT",
487
+ { cause: error }
488
+ );
489
+ }
490
+ if (!response.ok) {
491
+ let message = `DeepSeek API error (HTTP ${response.status})`;
492
+ let providerError;
493
+ try {
494
+ const parsed = await response.json();
495
+ providerError = parsed.error;
496
+ if (providerError?.message) message = providerError.message;
497
+ } catch {
498
+ }
499
+ const delay = providerRetryAfterMs(response.headers.get("retry-after"));
500
+ const id = requestId(response.headers);
501
+ throw new LlmError4(message, httpErrorCode(response.status, providerError), {
502
+ status: response.status,
503
+ ...delay === void 0 ? {} : { providerRetryAfterMs: delay },
504
+ ...id === void 0 ? {} : { requestId: id }
505
+ });
506
+ }
507
+ if (!response.body) {
508
+ throw new LlmError4("DeepSeek API returned no response body", "EMPTY_RESPONSE");
509
+ }
510
+ yield* translate(parseSse(response.body, onComment));
511
+ }
512
+ };
513
+
514
+ // packages/llm/llm-deepseek/src/index.ts
515
+ var name = "llm-deepseek";
516
+ var inject = ["llm"];
517
+ var NS = settingsNamespace("llm-deepseek");
518
+ var DEFAULT_API_KEY_ENV = "DEEPSEEK_API_KEY";
519
+ var PROVIDER = "deepseek-official";
520
+ var DEFAULT_MODELS = [
521
+ { id: "deepseek-v4-flash", name: "DeepSeek-V4-Flash", contextWindow: DEFAULT_CONTEXT_WINDOW },
522
+ { id: "deepseek-v4-pro", name: "DeepSeek-V4-Pro", contextWindow: DEFAULT_CONTEXT_WINDOW }
523
+ ];
524
+ var catalogModel = z.object({
525
+ id: z.string().required(),
526
+ name: z.string(),
527
+ description: z.string(),
528
+ contextWindow: z.number().step(1).min(1),
529
+ maxTokens: z.number().step(1).min(1)
530
+ });
531
+ var Config = z.object({
532
+ apiKeyEnv: z.string().role("credential-ref").default(DEFAULT_API_KEY_ENV),
533
+ baseURL: z.string(),
534
+ thinking: z.union(["enabled", "disabled"]),
535
+ reasoningEffort: z.union(["off", "high", "max"]),
536
+ maxTokens: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER).default(DEFAULT_MAX_TOKENS),
537
+ defaultContextWindow: z.number().step(1).min(1).default(DEFAULT_CONTEXT_WINDOW),
538
+ models: z.array(catalogModel).default(DEFAULT_MODELS),
539
+ streamIdleTimeoutMs: z.number().min(Number.MIN_VALUE).max(MAX_TIMER_DELAY_MS).default(DEFAULT_STREAM_IDLE_TIMEOUT_MS),
540
+ retryPolicy: RetryPolicySchema
541
+ });
542
+ var PUBLIC_BASE_URL = "https://api.deepseek.com";
543
+ var BASE_URL_ENV = "DEEPSEEK_BASE_URL";
544
+ function resolveModels(models) {
545
+ const seen = /* @__PURE__ */ new Set();
546
+ return (models ?? DEFAULT_MODELS).map((model) => {
547
+ if (model.id.length === 0) throw new Error("llm-deepseek: catalog model ids must be non-empty");
548
+ if (model.name !== void 0 && model.name.length === 0) {
549
+ throw new Error(`llm-deepseek: catalog model "${model.id}" has an empty name`);
550
+ }
551
+ if (model.contextWindow !== void 0 && (!Number.isInteger(model.contextWindow) || model.contextWindow <= 0)) {
552
+ throw new Error(
553
+ `llm-deepseek: catalog model "${model.id}" contextWindow must be a positive integer`
554
+ );
555
+ }
556
+ if (model.maxTokens !== void 0 && (!Number.isInteger(model.maxTokens) || model.maxTokens <= 0)) {
557
+ throw new Error(
558
+ `llm-deepseek: catalog model "${model.id}" maxTokens must be a positive integer`
559
+ );
560
+ }
561
+ if (seen.has(model.id)) throw new Error(`llm-deepseek: duplicate catalog model "${model.id}"`);
562
+ seen.add(model.id);
563
+ return {
564
+ id: model.id,
565
+ ...model.name === void 0 ? {} : { name: model.name },
566
+ ...model.description === void 0 ? {} : { description: model.description },
567
+ ...model.contextWindow === void 0 ? {} : { contextWindow: model.contextWindow },
568
+ ...model.maxTokens === void 0 ? {} : { maxTokens: model.maxTokens }
569
+ };
570
+ });
571
+ }
572
+ function resolveAdapterOptions(config, environment) {
573
+ if (config.thinking === "disabled" && config.reasoningEffort !== void 0 && config.reasoningEffort !== "off") {
574
+ throw new Error('llm-deepseek: only reasoningEffort "off" can be configured when thinking is disabled');
575
+ }
576
+ if (config.defaultContextWindow !== void 0 && (!Number.isInteger(config.defaultContextWindow) || config.defaultContextWindow <= 0)) {
577
+ throw new Error("llm-deepseek: defaultContextWindow must be a positive integer");
578
+ }
579
+ if (config.maxTokens !== void 0 && (!Number.isSafeInteger(config.maxTokens) || config.maxTokens <= 0)) {
580
+ throw new Error("llm-deepseek: maxTokens must be a positive safe integer");
581
+ }
582
+ const streamIdleTimeoutMs = config.streamIdleTimeoutMs ?? DEFAULT_STREAM_IDLE_TIMEOUT_MS;
583
+ if (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) {
584
+ throw new Error(
585
+ `llm-deepseek: streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`
586
+ );
587
+ }
588
+ return {
589
+ apiKeyEnv: credentialRef(config.apiKeyEnv ?? DEFAULT_API_KEY_ENV),
590
+ baseURL: config.baseURL ?? environment?.get(BASE_URL_ENV)?.value ?? PUBLIC_BASE_URL,
591
+ defaults: {
592
+ thinking: config.thinking,
593
+ reasoningEffort: config.reasoningEffort
594
+ },
595
+ maxTokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
596
+ defaultContextWindow: config.defaultContextWindow ?? DEFAULT_CONTEXT_WINDOW,
597
+ models: resolveModels(config.models),
598
+ streamIdleTimeoutMs,
599
+ retryPolicy: resolveRetryPolicy(config.retryPolicy, "llm-deepseek: retryPolicy")
600
+ };
601
+ }
602
+ function apply(ctx, config) {
603
+ let current = () => config;
604
+ let lastRaw;
605
+ let lastGood;
606
+ const options = () => {
607
+ const raw = current();
608
+ if (raw === lastRaw && lastGood !== void 0) return lastGood;
609
+ try {
610
+ const next = resolveAdapterOptions(raw, launchEnvironmentOf(ctx));
611
+ lastRaw = raw;
612
+ lastGood = next;
613
+ return next;
614
+ } catch (error) {
615
+ if (lastGood === void 0) throw error;
616
+ lastRaw = raw;
617
+ ctx.logger.error("llm-deepseek: keeping the last good configuration after an invalid settings section");
618
+ ctx.logger.error(error);
619
+ return lastGood;
620
+ }
621
+ };
622
+ options();
623
+ const resolveApiKey = async (connection) => {
624
+ const ref = connection.apiKeyEnv;
625
+ const credentials = ctx.get("credentials");
626
+ if (credentials !== void 0) {
627
+ const hit = await credentials.resolve(ref);
628
+ if (hit !== void 0) return assertUsableApiKey(hit.value, "llm-deepseek", ref);
629
+ } else {
630
+ const ambient = launchEnvironmentOf(ctx).get(ref);
631
+ if (ambient !== void 0 && ambient.value.length > 0) {
632
+ return assertUsableApiKey(ambient.value, "llm-deepseek", ref);
633
+ }
634
+ }
635
+ throw new LlmError5(
636
+ `llm-deepseek: no API key for provider route "${PROVIDER}"; store ${ref} through the credentials service (the web Models page writes it), or export ${ref} in the launching environment`,
637
+ "MISSING_CREDENTIAL"
638
+ );
639
+ };
640
+ let userId;
641
+ const resolveUserId = () => userId ??= getOrCreateAnonymousUserId();
642
+ const adapter = new DeepSeekAdapter({ options, resolveApiKey, resolveUserId });
643
+ ctx.llm.registerConfigurableProviders([
644
+ { provider: PROVIDER, displayName: "DeepSeek", settingsNs: NS, settingsPath: [] }
645
+ ]);
646
+ const registration = ctx.llm.registerAdapter([PROVIDER], adapter);
647
+ let registeredPolicy = options().retryPolicy;
648
+ const ensureRegistrationFacts = () => {
649
+ const policy = options().retryPolicy;
650
+ if (deepEqualJson(policy, registeredPolicy)) return;
651
+ registration.replace([PROVIDER]);
652
+ registeredPolicy = policy;
653
+ };
654
+ installSettingsSection(ctx, NS, Config, config, {
655
+ setSource: (source) => {
656
+ current = source;
657
+ },
658
+ onChange: ensureRegistrationFacts
659
+ });
660
+ }
661
+ export {
662
+ Config,
663
+ DEFAULT_CONTEXT_WINDOW,
664
+ DEFAULT_MAX_TOKENS,
665
+ DEFAULT_STREAM_IDLE_TIMEOUT_MS,
666
+ DeepSeekAdapter,
667
+ PUBLIC_BASE_URL,
668
+ apply,
669
+ inject,
670
+ name,
671
+ resolveAdapterOptions
672
+ };