@mars-sea/dsh-commandcode-provider 0.1.8 → 0.2.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.
- package/CHANGELOG.md +25 -0
- package/README.md +53 -13
- package/README.zh-CN.md +52 -13
- package/lib/client.js +57 -0
- package/lib/client.js.map +1 -0
- package/lib/index.d.ts +127 -1
- package/lib/index.js +363 -13
- package/lib/index.js.map +1 -1
- package/package.json +17 -6
package/lib/index.js
CHANGED
|
@@ -35,6 +35,11 @@ const KNOWN_EFFORTS = {
|
|
|
35
35
|
"medium",
|
|
36
36
|
"xhigh"
|
|
37
37
|
],
|
|
38
|
+
"MiniMaxAI/MiniMax-M2.5": [
|
|
39
|
+
"low",
|
|
40
|
+
"medium",
|
|
41
|
+
"xhigh"
|
|
42
|
+
],
|
|
38
43
|
"claude-fable-5": [
|
|
39
44
|
"low",
|
|
40
45
|
"medium",
|
|
@@ -42,6 +47,13 @@ const KNOWN_EFFORTS = {
|
|
|
42
47
|
"xhigh",
|
|
43
48
|
"max"
|
|
44
49
|
],
|
|
50
|
+
"claude-haiku-4-5-20251001": [
|
|
51
|
+
"low",
|
|
52
|
+
"medium",
|
|
53
|
+
"high",
|
|
54
|
+
"xhigh",
|
|
55
|
+
"max"
|
|
56
|
+
],
|
|
45
57
|
"claude-opus-4-7": [
|
|
46
58
|
"low",
|
|
47
59
|
"medium",
|
|
@@ -148,7 +160,37 @@ const KNOWN_EFFORTS = {
|
|
|
148
160
|
"xhigh",
|
|
149
161
|
"max"
|
|
150
162
|
],
|
|
163
|
+
"meta/muse-spark-1.2-contributor": [
|
|
164
|
+
"low",
|
|
165
|
+
"medium",
|
|
166
|
+
"high"
|
|
167
|
+
],
|
|
168
|
+
"moonshotai/Kimi-K2.5": [
|
|
169
|
+
"low",
|
|
170
|
+
"high",
|
|
171
|
+
"max"
|
|
172
|
+
],
|
|
173
|
+
"moonshotai/Kimi-K2.6": [
|
|
174
|
+
"low",
|
|
175
|
+
"high",
|
|
176
|
+
"max"
|
|
177
|
+
],
|
|
178
|
+
"moonshotai/Kimi-K2.7-Code-Highspeed": [
|
|
179
|
+
"low",
|
|
180
|
+
"high",
|
|
181
|
+
"max"
|
|
182
|
+
],
|
|
151
183
|
"sakana/fugu-ultra": ["high", "xhigh"],
|
|
184
|
+
"tencent/Hy3": [
|
|
185
|
+
"low",
|
|
186
|
+
"medium",
|
|
187
|
+
"high"
|
|
188
|
+
],
|
|
189
|
+
"tencent/hy3-paid": [
|
|
190
|
+
"low",
|
|
191
|
+
"medium",
|
|
192
|
+
"high"
|
|
193
|
+
],
|
|
152
194
|
"xai/grok-4.5": [
|
|
153
195
|
"low",
|
|
154
196
|
"medium",
|
|
@@ -160,6 +202,16 @@ const KNOWN_EFFORTS = {
|
|
|
160
202
|
"high",
|
|
161
203
|
"xhigh"
|
|
162
204
|
],
|
|
205
|
+
"xiaomi/mimo-v2.5": [
|
|
206
|
+
"low",
|
|
207
|
+
"medium",
|
|
208
|
+
"xhigh"
|
|
209
|
+
],
|
|
210
|
+
"xiaomi/mimo-v2.5-pro": [
|
|
211
|
+
"low",
|
|
212
|
+
"medium",
|
|
213
|
+
"xhigh"
|
|
214
|
+
],
|
|
163
215
|
"zai-org/GLM-5.2": ["high", "max"],
|
|
164
216
|
"zai-org/GLM-5.3": [
|
|
165
217
|
"low",
|
|
@@ -167,6 +219,213 @@ const KNOWN_EFFORTS = {
|
|
|
167
219
|
"max"
|
|
168
220
|
]
|
|
169
221
|
};
|
|
222
|
+
/**
|
|
223
|
+
* Models whose Capabilities include Vision, per the official Command Code
|
|
224
|
+
* model registry (`https://commandcode.ai/docs/reference/cli/models`, generated
|
|
225
|
+
* from the same registry as `cmd --list-models` / the `/model` picker).
|
|
226
|
+
*
|
|
227
|
+
* The Provider API does not expose modality metadata, so this snapshot is the
|
|
228
|
+
* source of truth for image-input gating. Command Code's own CLI falls back to
|
|
229
|
+
* a client-side VISION side-call for text-only models; this adapter does not
|
|
230
|
+
* reproduce that interactive feature, so images sent to a model outside this
|
|
231
|
+
* list are refused loudly (`UNSUPPORTED_CONTENT`) instead of being dropped or
|
|
232
|
+
* sent to a model that cannot read them.
|
|
233
|
+
*
|
|
234
|
+
* Keep in sync with the official registry when new models ship (see the
|
|
235
|
+
* dsh-commandcode-upstream skill).
|
|
236
|
+
*/
|
|
237
|
+
const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
238
|
+
"MiniMaxAI/MiniMax-M3",
|
|
239
|
+
"Qwen/Qwen3.6-Plus",
|
|
240
|
+
"Qwen/Qwen3.7-Flash",
|
|
241
|
+
"Qwen/Qwen3.7-Plus",
|
|
242
|
+
"Qwen/Qwen3.8-Max",
|
|
243
|
+
"claude-fable-5",
|
|
244
|
+
"claude-haiku-4-5-20251001",
|
|
245
|
+
"claude-opus-4-7",
|
|
246
|
+
"claude-opus-4-8",
|
|
247
|
+
"claude-opus-5",
|
|
248
|
+
"claude-sonnet-4-6",
|
|
249
|
+
"claude-sonnet-5",
|
|
250
|
+
"google/gemini-3.1-flash-lite",
|
|
251
|
+
"google/gemini-3.5-flash",
|
|
252
|
+
"google/gemini-3.5-flash-lite",
|
|
253
|
+
"google/gemini-3.6-flash",
|
|
254
|
+
"google/gemini-3.7-flash",
|
|
255
|
+
"gpt-5.3-codex",
|
|
256
|
+
"gpt-5.4",
|
|
257
|
+
"gpt-5.4-mini",
|
|
258
|
+
"gpt-5.5",
|
|
259
|
+
"gpt-5.6-luna",
|
|
260
|
+
"gpt-5.6-sol",
|
|
261
|
+
"gpt-5.6-terra",
|
|
262
|
+
"meta/muse-spark-1.1",
|
|
263
|
+
"meta/muse-spark-1.2",
|
|
264
|
+
"meta/muse-spark-1.2-contributor",
|
|
265
|
+
"moonshotai/Kimi-K2.5",
|
|
266
|
+
"moonshotai/Kimi-K2.6",
|
|
267
|
+
"moonshotai/Kimi-K2.7-Code",
|
|
268
|
+
"moonshotai/Kimi-K2.7-Code-Highspeed",
|
|
269
|
+
"moonshotai/Kimi-K3",
|
|
270
|
+
"sakana/fugu-ultra",
|
|
271
|
+
"stepfun/Step-3.7-Flash",
|
|
272
|
+
"thinkingmachines/inkling",
|
|
273
|
+
"thinkingmachines/inkling-small",
|
|
274
|
+
"xai/grok-4.5",
|
|
275
|
+
"xiaomi/mimo-v2.5"
|
|
276
|
+
]);
|
|
277
|
+
/**
|
|
278
|
+
* Models whose official registry entry lists the `Reasoning` capability but
|
|
279
|
+
* for which the official CLI defines no selectable `reasoning_effort` levels
|
|
280
|
+
* (they are absent from the CLI's model-table efforts; see the authoritative
|
|
281
|
+
* `ZA` table in command-code@1.26.0). The model still thinks — Command Code
|
|
282
|
+
* drives its reasoning depth automatically — so the picker labels them
|
|
283
|
+
* "Supports thinking (auto)" instead of the misleading "Text only", while
|
|
284
|
+
* `KNOWN_EFFORTS` (which mirrors the CLI's effort map exactly) stays the sole
|
|
285
|
+
* source for selectable effort levels.
|
|
286
|
+
*
|
|
287
|
+
* Source: https://commandcode.ai/docs/reference/cli/models (Reasoning flag) and
|
|
288
|
+
* the command-code@1.26.0 bundled model table. Keep in sync via the
|
|
289
|
+
* dsh-commandcode-upstream skill.
|
|
290
|
+
*/
|
|
291
|
+
const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
292
|
+
"MiniMaxAI/MiniMax-M3",
|
|
293
|
+
"Qwen/Qwen3.6-Max-Preview",
|
|
294
|
+
"Qwen/Qwen3.6-Plus",
|
|
295
|
+
"Qwen/Qwen3.7-Flash",
|
|
296
|
+
"Qwen/Qwen3.7-Max",
|
|
297
|
+
"Qwen/Qwen3.7-Plus",
|
|
298
|
+
"moonshotai/Kimi-K3",
|
|
299
|
+
"moonshotai/Kimi-K2.7-Code",
|
|
300
|
+
"stepfun/Step-3.5-Flash",
|
|
301
|
+
"stepfun/Step-3.7-Flash",
|
|
302
|
+
"zai-org/GLM-5",
|
|
303
|
+
"zai-org/GLM-5.1",
|
|
304
|
+
"zai-org/GLM-5.2-Fast",
|
|
305
|
+
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
306
|
+
"thinkingmachines/inkling",
|
|
307
|
+
"thinkingmachines/inkling-small",
|
|
308
|
+
"poolside/laguna-s-2.1-free",
|
|
309
|
+
"meta/muse-spark-1.1",
|
|
310
|
+
"meta/muse-spark-1.2"
|
|
311
|
+
]);
|
|
312
|
+
/**
|
|
313
|
+
* The minimum subscription plan a model is included in, per the official plan
|
|
314
|
+
* pages (`/docs/plans/go`, `/docs/plans/goat`, `/docs/plans/pro`, `/docs/plans/max`
|
|
315
|
+
* and `/docs/resources/pricing-limits`). Each plan's model list is a superset of
|
|
316
|
+
* the one below it: Go ⊂ GOAT ⊂ Pro ⊂ Provider/Max. Models absent from every
|
|
317
|
+
* plan list (Claude Opus/Fable, Fugu Ultra) are Provider-tier.
|
|
318
|
+
*
|
|
319
|
+
* The Provider API exposes no plan metadata, so this snapshot is the source of
|
|
320
|
+
* truth for the picker's plan annotation — it answers "which plan do I need to
|
|
321
|
+
* actually use this model?" at a glance. Plan labels use the official tier
|
|
322
|
+
* names (`Go`, `GOAT`, `Pro`, `Provider`), with `Max` implying Provider.
|
|
323
|
+
*
|
|
324
|
+
* Keep in sync with the official plan pages when they change (see the
|
|
325
|
+
* dsh-commandcode-upstream skill).
|
|
326
|
+
*/
|
|
327
|
+
const KNOWN_PLANS = {
|
|
328
|
+
"MiniMaxAI/MiniMax-M2.5": "go",
|
|
329
|
+
"MiniMaxAI/MiniMax-M2.7": "go",
|
|
330
|
+
"MiniMaxAI/MiniMax-M3": "go",
|
|
331
|
+
"Qwen/Qwen3.6-Max-Preview": "go",
|
|
332
|
+
"Qwen/Qwen3.6-Plus": "go",
|
|
333
|
+
"Qwen/Qwen3.7-Flash": "go",
|
|
334
|
+
"Qwen/Qwen3.7-Max": "go",
|
|
335
|
+
"Qwen/Qwen3.7-Plus": "go",
|
|
336
|
+
"Qwen/Qwen3.8-Max": "go",
|
|
337
|
+
"deepseek/deepseek-v4-flash": "go",
|
|
338
|
+
"deepseek/deepseek-v4-pro": "go",
|
|
339
|
+
"gpt-5.6-luna": "go",
|
|
340
|
+
"meta/muse-spark-1.2-contributor": "go",
|
|
341
|
+
"moonshotai/Kimi-K2.5": "go",
|
|
342
|
+
"moonshotai/Kimi-K2.6": "go",
|
|
343
|
+
"moonshotai/Kimi-K2.7-Code": "go",
|
|
344
|
+
"moonshotai/Kimi-K2.7-Code-Highspeed": "go",
|
|
345
|
+
"moonshotai/Kimi-K3": "go",
|
|
346
|
+
"nvidia/nemotron-3-ultra-550b-a55b": "go",
|
|
347
|
+
"poolside/laguna-s-2.1-free": "go",
|
|
348
|
+
"stepfun/Step-3.5-Flash": "go",
|
|
349
|
+
"stepfun/Step-3.7-Flash": "go",
|
|
350
|
+
"tencent/hy3-paid": "go",
|
|
351
|
+
"thinkingmachines/inkling": "go",
|
|
352
|
+
"thinkingmachines/inkling-small": "go",
|
|
353
|
+
"xai/grok-4.5": "go",
|
|
354
|
+
"xiaomi/mimo-v2.5": "go",
|
|
355
|
+
"xiaomi/mimo-v2.5-pro": "go",
|
|
356
|
+
"zai-org/GLM-5": "go",
|
|
357
|
+
"zai-org/GLM-5.1": "go",
|
|
358
|
+
"zai-org/GLM-5.2": "go",
|
|
359
|
+
"zai-org/GLM-5.2-Fast": "go",
|
|
360
|
+
"zai-org/GLM-5.3": "go",
|
|
361
|
+
"google/gemini-3.7-flash": "goat",
|
|
362
|
+
"meta/muse-spark-1.2": "goat",
|
|
363
|
+
"xai/grok-4.6": "goat",
|
|
364
|
+
"claude-haiku-4-5-20251001": "pro",
|
|
365
|
+
"claude-sonnet-4-6": "pro",
|
|
366
|
+
"claude-sonnet-5": "pro",
|
|
367
|
+
"google/gemini-3.1-flash-lite": "pro",
|
|
368
|
+
"google/gemini-3.5-flash": "pro",
|
|
369
|
+
"google/gemini-3.5-flash-lite": "pro",
|
|
370
|
+
"google/gemini-3.6-flash": "pro",
|
|
371
|
+
"gpt-5.3-codex": "pro",
|
|
372
|
+
"gpt-5.4": "pro",
|
|
373
|
+
"gpt-5.4-mini": "pro",
|
|
374
|
+
"gpt-5.5": "pro",
|
|
375
|
+
"gpt-5.6-sol": "pro",
|
|
376
|
+
"gpt-5.6-terra": "pro",
|
|
377
|
+
"meta/muse-spark-1.1": "pro",
|
|
378
|
+
"claude-fable-5": "provider",
|
|
379
|
+
"claude-opus-4-7": "provider",
|
|
380
|
+
"claude-opus-4-8": "provider",
|
|
381
|
+
"claude-opus-5": "provider",
|
|
382
|
+
"sakana/fugu-ultra": "provider"
|
|
383
|
+
};
|
|
384
|
+
/** Official display labels for each plan tier. */
|
|
385
|
+
const PLAN_LABELS = {
|
|
386
|
+
go: "Go",
|
|
387
|
+
goat: "GOAT",
|
|
388
|
+
pro: "Pro",
|
|
389
|
+
provider: "Provider",
|
|
390
|
+
max: "Max"
|
|
391
|
+
};
|
|
392
|
+
/**
|
|
393
|
+
* Plan-tier sort weights, low to high. Models outside the snapshot (unknown
|
|
394
|
+
* plans) sort after every known tier, keeping known models predictable.
|
|
395
|
+
*/
|
|
396
|
+
const PLAN_ORDER = {
|
|
397
|
+
go: 0,
|
|
398
|
+
goat: 1,
|
|
399
|
+
pro: 2,
|
|
400
|
+
provider: 3,
|
|
401
|
+
max: 4
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* Comparator for the model picker: sort by plan tier (lowest first), then by
|
|
405
|
+
* model name, then by id as a tiebreak. Models with no known plan sort last.
|
|
406
|
+
*/
|
|
407
|
+
function compareByPlan(a, b) {
|
|
408
|
+
const pa = PLAN_ORDER[KNOWN_PLANS[a.id] ?? ""] ?? Number.MAX_SAFE_INTEGER;
|
|
409
|
+
const pb = PLAN_ORDER[KNOWN_PLANS[b.id] ?? ""] ?? Number.MAX_SAFE_INTEGER;
|
|
410
|
+
if (pa !== pb) return pa - pb;
|
|
411
|
+
const nameDiff = a.name.localeCompare(b.name);
|
|
412
|
+
if (nameDiff !== 0) return nameDiff;
|
|
413
|
+
return a.id.localeCompare(b.id);
|
|
414
|
+
}
|
|
415
|
+
const KNOWN_DEALS = {
|
|
416
|
+
"deepseek/deepseek-v4-pro": { label: "75% off" },
|
|
417
|
+
"google/gemini-3.7-flash": {
|
|
418
|
+
label: "50% off",
|
|
419
|
+
expiresAt: "2026-12-31T23:59:59Z"
|
|
420
|
+
},
|
|
421
|
+
"MiniMaxAI/MiniMax-M3": { label: "50% off" },
|
|
422
|
+
"xiaomi/mimo-v2.5-pro": { label: "99% off" },
|
|
423
|
+
"xiaomi/mimo-v2.5": { label: "98% off" },
|
|
424
|
+
"poolside/laguna-s-2.1-free": {
|
|
425
|
+
label: "FREE",
|
|
426
|
+
free: true
|
|
427
|
+
}
|
|
428
|
+
};
|
|
170
429
|
const COMMAND_CODE_CLI_VERSION = "1.26.0";
|
|
171
430
|
const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
172
431
|
const DEFAULT_GENERATE_MAX_TOKENS = 64e3;
|
|
@@ -179,6 +438,58 @@ const MODEL_CACHE_VERSION = 1;
|
|
|
179
438
|
function isRecord(value) {
|
|
180
439
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
181
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* Official display label for a model's minimum plan, or undefined for models
|
|
443
|
+
* outside the snapshot (e.g. future catalog additions).
|
|
444
|
+
*/
|
|
445
|
+
function planLabel(modelId) {
|
|
446
|
+
const plan = KNOWN_PLANS[modelId];
|
|
447
|
+
return plan === void 0 ? void 0 : PLAN_LABELS[plan];
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* The active deal label for a model, or undefined when the model has no deal
|
|
451
|
+
* or the deal has expired. Expiry is judged against `now` (defaults to
|
|
452
|
+
* `Date.now()`), so a snapshot that has gone stale stops showing its discount
|
|
453
|
+
* the moment the official end date passes — the user never believes a lapsed
|
|
454
|
+
* deal is still live. Permanent deals (no `expiresAt`) never lapse.
|
|
455
|
+
*/
|
|
456
|
+
function dealLabel(modelId, now = Date.now()) {
|
|
457
|
+
const deal = KNOWN_DEALS[modelId];
|
|
458
|
+
if (deal === void 0) return void 0;
|
|
459
|
+
if (deal.expiresAt !== void 0 && now >= Date.parse(deal.expiresAt)) return void 0;
|
|
460
|
+
return deal.label;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Compact human-readable context window, e.g. `1_000_000 -> "1M"`,
|
|
464
|
+
* `256_000 -> "256K"`, `262_144 -> "256K"` (floor to the nearest K).
|
|
465
|
+
* Returns undefined for unknown/absent sizes.
|
|
466
|
+
*/
|
|
467
|
+
function formatContext(contextWindow) {
|
|
468
|
+
if (contextWindow === void 0 || !Number.isFinite(contextWindow) || contextWindow <= 0) return;
|
|
469
|
+
if (contextWindow >= 1e6) {
|
|
470
|
+
const m = contextWindow / 1e6;
|
|
471
|
+
const rounded = Math.round(m * 10) / 10;
|
|
472
|
+
return `${Number.isInteger(rounded) ? rounded : rounded.toFixed(1)}M`;
|
|
473
|
+
}
|
|
474
|
+
return `${Math.floor(contextWindow / 1e3)}K`;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Compact one-line summary for the model picker: plan tier, then any active
|
|
478
|
+
* deal (discount or FREE), then `Image` for Vision-capable models, then the
|
|
479
|
+
* context window. Text-only models simply omit the Image marker — "Text only"
|
|
480
|
+
* adds nothing the picker needs to show.
|
|
481
|
+
*/
|
|
482
|
+
function capabilityDescription(modelId, contextWindow, now = Date.now()) {
|
|
483
|
+
const parts = [];
|
|
484
|
+
const plan = planLabel(modelId);
|
|
485
|
+
if (plan !== void 0) parts.push(plan);
|
|
486
|
+
const deal = dealLabel(modelId, now);
|
|
487
|
+
if (deal !== void 0) parts.push(deal);
|
|
488
|
+
if (KNOWN_IMAGE_MODELS.has(modelId)) parts.push("Image");
|
|
489
|
+
const ctx = formatContext(contextWindow);
|
|
490
|
+
if (ctx !== void 0) parts.push(ctx);
|
|
491
|
+
return parts.join(" · ");
|
|
492
|
+
}
|
|
182
493
|
function stringValue(value) {
|
|
183
494
|
return typeof value === "string" ? value : void 0;
|
|
184
495
|
}
|
|
@@ -286,7 +597,24 @@ function hasImageContent(message) {
|
|
|
286
597
|
const check = (blocks) => blocks.some((b) => b.type === "image" || b.type === "tool-result" && check(b.content));
|
|
287
598
|
return check(message.content);
|
|
288
599
|
}
|
|
289
|
-
|
|
600
|
+
/**
|
|
601
|
+
* Convert one image reference to the Command Code wire format, as the official
|
|
602
|
+
* CLI does: `{ type: 'image', source: { type: 'base64', media_type, data } }`.
|
|
603
|
+
* Bytes come from the durable attachment service; the media type is the one
|
|
604
|
+
* verified at save time.
|
|
605
|
+
*/
|
|
606
|
+
async function imageToCommandCode(ref, readImage) {
|
|
607
|
+
const data = await readImage(ref);
|
|
608
|
+
return {
|
|
609
|
+
type: "image",
|
|
610
|
+
source: {
|
|
611
|
+
type: "base64",
|
|
612
|
+
media_type: ref.mediaType,
|
|
613
|
+
data: Buffer.from(data).toString("base64")
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
async function messagesToCC(messages, readImage) {
|
|
290
618
|
const out = [];
|
|
291
619
|
const paired = pairedToolCallIds(messages);
|
|
292
620
|
for (const message of messages) {
|
|
@@ -298,7 +626,10 @@ function messagesToCC(messages) {
|
|
|
298
626
|
type: "text",
|
|
299
627
|
text: block.text
|
|
300
628
|
});
|
|
301
|
-
if (block.type === "image")
|
|
629
|
+
if (block.type === "image") {
|
|
630
|
+
if (!readImage) throw new LlmError("Image input requires the durable attachment service", "UNSUPPORTED_CONTENT");
|
|
631
|
+
parts.push(await imageToCommandCode(block.attachment, readImage));
|
|
632
|
+
}
|
|
302
633
|
}
|
|
303
634
|
out.push({
|
|
304
635
|
role: "user",
|
|
@@ -350,10 +681,12 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
350
681
|
deps;
|
|
351
682
|
catalog = [];
|
|
352
683
|
fetchImpl;
|
|
684
|
+
resolveAttachments;
|
|
353
685
|
constructor(deps) {
|
|
354
686
|
super();
|
|
355
687
|
this.deps = deps;
|
|
356
688
|
this.fetchImpl = deps.fetchImpl ?? fetch;
|
|
689
|
+
this.resolveAttachments = deps.resolveAttachments;
|
|
357
690
|
}
|
|
358
691
|
/**
|
|
359
692
|
* Command Code is a metered subscription API: 429 (rate limit) and 5xx
|
|
@@ -387,21 +720,27 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
387
720
|
return this.catalog;
|
|
388
721
|
}
|
|
389
722
|
async listModels(provider) {
|
|
390
|
-
return (await this.loadCatalog()).map((model) =>
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
723
|
+
return (await this.loadCatalog()).map((model) => {
|
|
724
|
+
const vision = KNOWN_IMAGE_MODELS.has(model.id);
|
|
725
|
+
return {
|
|
726
|
+
provider,
|
|
727
|
+
id: model.id,
|
|
728
|
+
name: `${model.name} (CC)`,
|
|
729
|
+
description: capabilityDescription(model.id, model.contextWindow),
|
|
730
|
+
inputModalities: vision ? ["text", "image"] : ["text"]
|
|
731
|
+
};
|
|
732
|
+
}).sort(compareByPlan);
|
|
396
733
|
}
|
|
397
734
|
async resolveModel(provider, model, signal) {
|
|
398
735
|
const entry = this.catalog.find((m) => m.id === model) ?? (await this.loadCatalog(signal)).find((m) => m.id === model);
|
|
399
736
|
const efforts = KNOWN_EFFORTS[model];
|
|
737
|
+
const vision = KNOWN_IMAGE_MODELS.has(model);
|
|
400
738
|
return {
|
|
401
739
|
provider,
|
|
402
740
|
id: model,
|
|
403
741
|
name: entry ? `${entry.name} (CC)` : model,
|
|
404
|
-
|
|
742
|
+
description: capabilityDescription(model, entry?.contextWindow),
|
|
743
|
+
inputModalities: vision ? ["text", "image"] : ["text"],
|
|
405
744
|
...entry ? {
|
|
406
745
|
context: { contextWindow: entry.contextWindow },
|
|
407
746
|
defaultMaxTokens: Math.min(entry.maxTokens, DEFAULT_GENERATE_MAX_TOKENS)
|
|
@@ -490,7 +829,14 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
490
829
|
}
|
|
491
830
|
async *stream(options) {
|
|
492
831
|
if (options.stop?.length) throw new LlmError("Command Code adapter does not support stop sequences", "UNSUPPORTED_OPTION");
|
|
493
|
-
|
|
832
|
+
const hasImages = options.messages.some(hasImageContent);
|
|
833
|
+
let readImage;
|
|
834
|
+
if (hasImages) {
|
|
835
|
+
if (!KNOWN_IMAGE_MODELS.has(options.model)) throw new LlmError(`Command Code model "${options.model}" does not support image input; switch to a Vision-capable model (see the model registry)`, "UNSUPPORTED_CONTENT");
|
|
836
|
+
const attachments = this.resolveAttachments?.();
|
|
837
|
+
if (attachments === void 0) throw new LlmError("Command Code image input requires the durable attachment service", "UNSUPPORTED_CONTENT");
|
|
838
|
+
readImage = (ref) => attachments.readImage(ref).then((stored) => stored.data);
|
|
839
|
+
}
|
|
494
840
|
const connection = this.deps.options();
|
|
495
841
|
const apiKey = await this.deps.resolveApiKey(connection);
|
|
496
842
|
const modelMax = this.catalog.find((m) => m.id === options.model)?.maxTokens ?? 65536;
|
|
@@ -516,7 +862,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
516
862
|
skills: null,
|
|
517
863
|
params: {
|
|
518
864
|
model: options.model,
|
|
519
|
-
messages: messagesToCC(options.messages),
|
|
865
|
+
messages: await messagesToCC(options.messages, readImage),
|
|
520
866
|
tools: (options.tools ?? []).map((tool) => ({
|
|
521
867
|
type: "function",
|
|
522
868
|
name: tool.name,
|
|
@@ -947,7 +1293,11 @@ function apply(ctx, config) {
|
|
|
947
1293
|
};
|
|
948
1294
|
const adapter = new CommandCodeAdapter({
|
|
949
1295
|
options,
|
|
950
|
-
resolveApiKey
|
|
1296
|
+
resolveApiKey,
|
|
1297
|
+
resolveAttachments: () => {
|
|
1298
|
+
const attachments = ctx.get("attachments");
|
|
1299
|
+
return attachments === void 0 ? void 0 : attachments;
|
|
1300
|
+
}
|
|
951
1301
|
});
|
|
952
1302
|
ctx.llm.registerConfigurableProviders([{
|
|
953
1303
|
provider: PROVIDER,
|
|
@@ -967,6 +1317,6 @@ function apply(ctx, config) {
|
|
|
967
1317
|
});
|
|
968
1318
|
}
|
|
969
1319
|
//#endregion
|
|
970
|
-
export { COMMAND_CODE_CLI_VERSION, CommandCodeAdapter, Config, DEFAULT_API_BASE, DEFAULT_GENERATE_MAX_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_MODELS_CACHE_PATH, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_STREAM_IDLE_TIMEOUT_MS, KNOWN_EFFORTS, PROVIDER, apply, applyCommands, commandDefinition, inject, name, projectSlugFromPath, resolveAdapterOptions, resolveAuthFileApiKey };
|
|
1320
|
+
export { COMMAND_CODE_CLI_VERSION, CommandCodeAdapter, Config, DEFAULT_API_BASE, DEFAULT_GENERATE_MAX_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_MODELS_CACHE_PATH, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_STREAM_IDLE_TIMEOUT_MS, KNOWN_DEALS, KNOWN_EFFORTS, KNOWN_IMAGE_MODELS, KNOWN_PLANS, KNOWN_THINKING_MODELS, PLAN_LABELS, PLAN_ORDER, PROVIDER, apply, applyCommands, capabilityDescription, commandDefinition, compareByPlan, dealLabel, formatContext, inject, name, planLabel, projectSlugFromPath, resolveAdapterOptions, resolveAuthFileApiKey };
|
|
971
1321
|
|
|
972
1322
|
//# sourceMappingURL=index.js.map
|