@corbat-tech/coco 2.34.0 → 2.35.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/dist/cli/index.js +7087 -5240
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1805 -417
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -44,8 +44,13 @@ import yaml from 'highlight.js/lib/languages/yaml';
|
|
|
44
44
|
|
|
45
45
|
var __defProp = Object.defineProperty;
|
|
46
46
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
47
|
-
var __esm = (fn, res) => function __init() {
|
|
48
|
-
|
|
47
|
+
var __esm = (fn, res, err) => function __init() {
|
|
48
|
+
if (err) throw err[0];
|
|
49
|
+
try {
|
|
50
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
51
|
+
} catch (e) {
|
|
52
|
+
throw err = [e], e;
|
|
53
|
+
}
|
|
49
54
|
};
|
|
50
55
|
var __export = (target, all) => {
|
|
51
56
|
for (var name in all)
|
|
@@ -253,6 +258,793 @@ var init_logger = __esm({
|
|
|
253
258
|
globalLogger = null;
|
|
254
259
|
}
|
|
255
260
|
});
|
|
261
|
+
|
|
262
|
+
// src/providers/catalog.ts
|
|
263
|
+
function model(entry) {
|
|
264
|
+
return {
|
|
265
|
+
...entry,
|
|
266
|
+
source: entry.source ?? SOURCES.providerDocs
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function getProviderCatalogEntry(provider) {
|
|
270
|
+
return PROVIDER_CATALOG[provider];
|
|
271
|
+
}
|
|
272
|
+
function getCatalogDefaultModel(provider) {
|
|
273
|
+
return getProviderCatalogEntry(provider).defaultModel;
|
|
274
|
+
}
|
|
275
|
+
function getCatalogModel(provider, modelId) {
|
|
276
|
+
return getProviderCatalogEntry(provider).models.find((modelEntry) => modelEntry.id === modelId);
|
|
277
|
+
}
|
|
278
|
+
function getCatalogContextWindow(provider, modelId, fallback) {
|
|
279
|
+
if (!modelId) return fallback;
|
|
280
|
+
const exact = getCatalogModel(provider, modelId);
|
|
281
|
+
if (exact) return exact.contextWindow;
|
|
282
|
+
return fallback;
|
|
283
|
+
}
|
|
284
|
+
function getCatalogModelPricingMap() {
|
|
285
|
+
const pricing = {};
|
|
286
|
+
for (const provider of Object.values(PROVIDER_CATALOG)) {
|
|
287
|
+
for (const modelEntry of provider.models) {
|
|
288
|
+
if (!modelEntry.pricing) continue;
|
|
289
|
+
pricing[modelEntry.id] = {
|
|
290
|
+
...modelEntry.pricing,
|
|
291
|
+
contextWindow: modelEntry.contextWindow
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return pricing;
|
|
296
|
+
}
|
|
297
|
+
var VERIFIED_AT, SOURCES, PROVIDER_CATALOG;
|
|
298
|
+
var init_catalog = __esm({
|
|
299
|
+
"src/providers/catalog.ts"() {
|
|
300
|
+
VERIFIED_AT = "2026-06-18";
|
|
301
|
+
SOURCES = {
|
|
302
|
+
openaiModels: {
|
|
303
|
+
name: "OpenAI models",
|
|
304
|
+
url: "https://developers.openai.com/api/docs/models",
|
|
305
|
+
verifiedAt: VERIFIED_AT
|
|
306
|
+
},
|
|
307
|
+
openaiAllModels: {
|
|
308
|
+
name: "OpenAI all models",
|
|
309
|
+
url: "https://developers.openai.com/api/docs/models/all",
|
|
310
|
+
verifiedAt: VERIFIED_AT
|
|
311
|
+
},
|
|
312
|
+
codexModels: {
|
|
313
|
+
name: "OpenAI Codex models",
|
|
314
|
+
url: "https://developers.openai.com/codex/models",
|
|
315
|
+
verifiedAt: VERIFIED_AT
|
|
316
|
+
},
|
|
317
|
+
anthropicModels: {
|
|
318
|
+
name: "Anthropic models overview",
|
|
319
|
+
url: "https://docs.anthropic.com/en/docs/about-claude/models/overview",
|
|
320
|
+
verifiedAt: VERIFIED_AT
|
|
321
|
+
},
|
|
322
|
+
anthropicDeprecations: {
|
|
323
|
+
name: "Anthropic model deprecations",
|
|
324
|
+
url: "https://docs.anthropic.com/en/docs/about-claude/model-deprecations",
|
|
325
|
+
verifiedAt: VERIFIED_AT
|
|
326
|
+
},
|
|
327
|
+
geminiModels: {
|
|
328
|
+
name: "Gemini API models",
|
|
329
|
+
url: "https://ai.google.dev/gemini-api/docs/models",
|
|
330
|
+
verifiedAt: VERIFIED_AT
|
|
331
|
+
},
|
|
332
|
+
geminiGuide: {
|
|
333
|
+
name: "Gemini 3 developer guide",
|
|
334
|
+
url: "https://ai.google.dev/gemini-api/docs/gemini-3",
|
|
335
|
+
verifiedAt: VERIFIED_AT
|
|
336
|
+
},
|
|
337
|
+
githubCopilotModels: {
|
|
338
|
+
name: "GitHub Copilot supported models",
|
|
339
|
+
url: "https://docs.github.com/copilot/reference/ai-models/supported-models",
|
|
340
|
+
verifiedAt: VERIFIED_AT
|
|
341
|
+
},
|
|
342
|
+
githubCopilotComparison: {
|
|
343
|
+
name: "GitHub Copilot model comparison",
|
|
344
|
+
url: "https://docs.github.com/en/copilot/reference/ai-models/model-comparison",
|
|
345
|
+
verifiedAt: VERIFIED_AT
|
|
346
|
+
},
|
|
347
|
+
moonshotDocs: {
|
|
348
|
+
name: "Moonshot AI docs",
|
|
349
|
+
url: "https://platform.moonshot.ai/docs",
|
|
350
|
+
verifiedAt: VERIFIED_AT
|
|
351
|
+
},
|
|
352
|
+
qwenDocs: {
|
|
353
|
+
name: "Alibaba Cloud Model Studio docs",
|
|
354
|
+
url: "https://www.alibabacloud.com/help/en/model-studio/",
|
|
355
|
+
verifiedAt: VERIFIED_AT
|
|
356
|
+
},
|
|
357
|
+
providerDocs: {
|
|
358
|
+
name: "Provider API documentation",
|
|
359
|
+
url: "https://github.com/corbat/corbat-coco/blob/main/docs/guides/PROVIDERS.md",
|
|
360
|
+
verifiedAt: VERIFIED_AT
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
PROVIDER_CATALOG = {
|
|
364
|
+
anthropic: {
|
|
365
|
+
id: "anthropic",
|
|
366
|
+
defaultModel: "claude-sonnet-4-6",
|
|
367
|
+
models: [
|
|
368
|
+
model({
|
|
369
|
+
id: "claude-opus-4-8",
|
|
370
|
+
name: "Claude Opus 4.8",
|
|
371
|
+
description: "Most capable Opus-tier model for complex agentic work",
|
|
372
|
+
contextWindow: 2e5,
|
|
373
|
+
maxOutputTokens: 128e3,
|
|
374
|
+
status: "current",
|
|
375
|
+
capabilities: [
|
|
376
|
+
"streaming",
|
|
377
|
+
"tool-use",
|
|
378
|
+
"vision",
|
|
379
|
+
"adaptive-thinking",
|
|
380
|
+
"reasoning-effort",
|
|
381
|
+
"anthropic-messages"
|
|
382
|
+
],
|
|
383
|
+
source: SOURCES.anthropicModels
|
|
384
|
+
}),
|
|
385
|
+
model({
|
|
386
|
+
id: "claude-sonnet-4-6",
|
|
387
|
+
name: "Claude Sonnet 4.6",
|
|
388
|
+
description: "Balanced default for coding, tool use, and long-running tasks",
|
|
389
|
+
contextWindow: 2e5,
|
|
390
|
+
maxOutputTokens: 128e3,
|
|
391
|
+
recommended: true,
|
|
392
|
+
status: "current",
|
|
393
|
+
capabilities: [
|
|
394
|
+
"streaming",
|
|
395
|
+
"tool-use",
|
|
396
|
+
"vision",
|
|
397
|
+
"adaptive-thinking",
|
|
398
|
+
"reasoning-effort",
|
|
399
|
+
"anthropic-messages"
|
|
400
|
+
],
|
|
401
|
+
pricing: { inputPerMillion: 3, outputPerMillion: 15 },
|
|
402
|
+
source: SOURCES.anthropicModels
|
|
403
|
+
}),
|
|
404
|
+
model({
|
|
405
|
+
id: "claude-opus-4-6",
|
|
406
|
+
name: "Claude Opus 4.6",
|
|
407
|
+
description: "Legacy Opus option; prefer Opus 4.8 for new configurations",
|
|
408
|
+
contextWindow: 2e5,
|
|
409
|
+
maxOutputTokens: 128e3,
|
|
410
|
+
status: "legacy",
|
|
411
|
+
capabilities: [
|
|
412
|
+
"streaming",
|
|
413
|
+
"tool-use",
|
|
414
|
+
"vision",
|
|
415
|
+
"adaptive-thinking",
|
|
416
|
+
"reasoning-effort",
|
|
417
|
+
"anthropic-messages"
|
|
418
|
+
],
|
|
419
|
+
pricing: { inputPerMillion: 5, outputPerMillion: 25 },
|
|
420
|
+
source: SOURCES.anthropicModels
|
|
421
|
+
}),
|
|
422
|
+
model({
|
|
423
|
+
id: "claude-haiku-4-5-20251001",
|
|
424
|
+
name: "Claude Haiku 4.5",
|
|
425
|
+
description: "Fast low-cost Claude model",
|
|
426
|
+
contextWindow: 2e5,
|
|
427
|
+
maxOutputTokens: 64e3,
|
|
428
|
+
status: "current",
|
|
429
|
+
capabilities: ["streaming", "tool-use", "vision", "anthropic-messages"],
|
|
430
|
+
pricing: { inputPerMillion: 1, outputPerMillion: 5 },
|
|
431
|
+
source: SOURCES.anthropicModels
|
|
432
|
+
}),
|
|
433
|
+
model({
|
|
434
|
+
id: "claude-sonnet-4-20250514",
|
|
435
|
+
name: "Claude Sonnet 4",
|
|
436
|
+
description: "Retired on the Claude API; kept for config migration warnings",
|
|
437
|
+
contextWindow: 2e5,
|
|
438
|
+
maxOutputTokens: 64e3,
|
|
439
|
+
status: "deprecated",
|
|
440
|
+
capabilities: ["streaming", "tool-use", "vision", "thinking-budget", "anthropic-messages"],
|
|
441
|
+
pricing: { inputPerMillion: 3, outputPerMillion: 15 },
|
|
442
|
+
source: SOURCES.anthropicDeprecations
|
|
443
|
+
}),
|
|
444
|
+
model({
|
|
445
|
+
id: "claude-opus-4-20250514",
|
|
446
|
+
name: "Claude Opus 4",
|
|
447
|
+
description: "Retired on the Claude API; kept for config migration warnings",
|
|
448
|
+
contextWindow: 2e5,
|
|
449
|
+
maxOutputTokens: 64e3,
|
|
450
|
+
status: "deprecated",
|
|
451
|
+
capabilities: ["streaming", "tool-use", "vision", "thinking-budget", "anthropic-messages"],
|
|
452
|
+
pricing: { inputPerMillion: 15, outputPerMillion: 75 },
|
|
453
|
+
source: SOURCES.anthropicDeprecations
|
|
454
|
+
})
|
|
455
|
+
]
|
|
456
|
+
},
|
|
457
|
+
openai: {
|
|
458
|
+
id: "openai",
|
|
459
|
+
defaultModel: "gpt-5.5",
|
|
460
|
+
models: [
|
|
461
|
+
model({
|
|
462
|
+
id: "gpt-5.5",
|
|
463
|
+
name: "GPT-5.5",
|
|
464
|
+
description: "Default for complex coding, agentic workflows, and tool-heavy tasks",
|
|
465
|
+
contextWindow: 1e6,
|
|
466
|
+
maxOutputTokens: 128e3,
|
|
467
|
+
recommended: true,
|
|
468
|
+
status: "current",
|
|
469
|
+
capabilities: ["streaming", "tool-use", "vision", "reasoning-effort", "openai-responses"],
|
|
470
|
+
pricing: { inputPerMillion: 5, outputPerMillion: 30 },
|
|
471
|
+
source: SOURCES.openaiModels
|
|
472
|
+
}),
|
|
473
|
+
model({
|
|
474
|
+
id: "gpt-5.4",
|
|
475
|
+
name: "GPT-5.4",
|
|
476
|
+
description: "Affordable model for coding and professional work",
|
|
477
|
+
contextWindow: 1e6,
|
|
478
|
+
maxOutputTokens: 128e3,
|
|
479
|
+
status: "current",
|
|
480
|
+
capabilities: ["streaming", "tool-use", "vision", "reasoning-effort", "openai-responses"],
|
|
481
|
+
source: SOURCES.openaiAllModels
|
|
482
|
+
}),
|
|
483
|
+
model({
|
|
484
|
+
id: "gpt-5.4-mini",
|
|
485
|
+
name: "GPT-5.4 mini",
|
|
486
|
+
description: "Fast model for lighter coding tasks and subagents",
|
|
487
|
+
contextWindow: 1e6,
|
|
488
|
+
maxOutputTokens: 128e3,
|
|
489
|
+
status: "current",
|
|
490
|
+
capabilities: ["streaming", "tool-use", "vision", "reasoning-effort", "openai-responses"],
|
|
491
|
+
source: SOURCES.openaiAllModels
|
|
492
|
+
}),
|
|
493
|
+
model({
|
|
494
|
+
id: "gpt-5.3-codex",
|
|
495
|
+
name: "GPT-5.3 Codex",
|
|
496
|
+
description: "Agentic coding model; keep separate from older ChatGPT-only aliases",
|
|
497
|
+
contextWindow: 4e5,
|
|
498
|
+
maxOutputTokens: 128e3,
|
|
499
|
+
status: "current",
|
|
500
|
+
capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
|
|
501
|
+
source: SOURCES.openaiAllModels
|
|
502
|
+
}),
|
|
503
|
+
model({
|
|
504
|
+
id: "gpt-5.2-codex",
|
|
505
|
+
name: "GPT-5.2 Codex",
|
|
506
|
+
description: "Deprecated Codex model retained for existing configs",
|
|
507
|
+
contextWindow: 4e5,
|
|
508
|
+
maxOutputTokens: 128e3,
|
|
509
|
+
status: "deprecated",
|
|
510
|
+
capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
|
|
511
|
+
source: SOURCES.openaiAllModels
|
|
512
|
+
}),
|
|
513
|
+
model({
|
|
514
|
+
id: "gpt-4.1",
|
|
515
|
+
name: "GPT-4.1",
|
|
516
|
+
description: "Legacy long-context non-reasoning model",
|
|
517
|
+
contextWindow: 1048576,
|
|
518
|
+
maxOutputTokens: 32768,
|
|
519
|
+
status: "legacy",
|
|
520
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
521
|
+
pricing: { inputPerMillion: 2, outputPerMillion: 8 },
|
|
522
|
+
source: SOURCES.openaiAllModels
|
|
523
|
+
})
|
|
524
|
+
]
|
|
525
|
+
},
|
|
526
|
+
codex: {
|
|
527
|
+
id: "codex",
|
|
528
|
+
defaultModel: "gpt-5.5",
|
|
529
|
+
models: [
|
|
530
|
+
model({
|
|
531
|
+
id: "gpt-5.5",
|
|
532
|
+
name: "GPT-5.5",
|
|
533
|
+
description: "Recommended Codex model for complex coding work",
|
|
534
|
+
contextWindow: 1e6,
|
|
535
|
+
maxOutputTokens: 128e3,
|
|
536
|
+
recommended: true,
|
|
537
|
+
status: "current",
|
|
538
|
+
capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
|
|
539
|
+
source: SOURCES.codexModels
|
|
540
|
+
}),
|
|
541
|
+
model({
|
|
542
|
+
id: "gpt-5.4-mini",
|
|
543
|
+
name: "GPT-5.4 mini",
|
|
544
|
+
description: "Faster Codex option for lighter work and subagents",
|
|
545
|
+
contextWindow: 1e6,
|
|
546
|
+
maxOutputTokens: 128e3,
|
|
547
|
+
status: "current",
|
|
548
|
+
capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
|
|
549
|
+
source: SOURCES.codexModels
|
|
550
|
+
}),
|
|
551
|
+
model({
|
|
552
|
+
id: "gpt-5.3-codex-spark",
|
|
553
|
+
name: "GPT-5.3 Codex Spark",
|
|
554
|
+
description: "Research preview for near-instant coding iteration",
|
|
555
|
+
contextWindow: 4e5,
|
|
556
|
+
maxOutputTokens: 128e3,
|
|
557
|
+
status: "experimental",
|
|
558
|
+
capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
|
|
559
|
+
source: SOURCES.codexModels
|
|
560
|
+
}),
|
|
561
|
+
model({
|
|
562
|
+
id: "codex-mini-latest",
|
|
563
|
+
name: "Codex mini latest",
|
|
564
|
+
description: "Deprecated fast Codex CLI model retained for existing configs",
|
|
565
|
+
contextWindow: 128e3,
|
|
566
|
+
maxOutputTokens: 32e3,
|
|
567
|
+
status: "deprecated",
|
|
568
|
+
capabilities: ["streaming", "tool-use", "reasoning-effort", "openai-responses"],
|
|
569
|
+
source: SOURCES.openaiAllModels
|
|
570
|
+
})
|
|
571
|
+
]
|
|
572
|
+
},
|
|
573
|
+
copilot: {
|
|
574
|
+
id: "copilot",
|
|
575
|
+
defaultModel: "claude-sonnet-4.6",
|
|
576
|
+
models: [
|
|
577
|
+
model({
|
|
578
|
+
id: "claude-sonnet-4.6",
|
|
579
|
+
name: "Claude Sonnet 4.6",
|
|
580
|
+
description: "Reliable Copilot default for coding and review",
|
|
581
|
+
contextWindow: 168e3,
|
|
582
|
+
maxOutputTokens: 64e3,
|
|
583
|
+
recommended: true,
|
|
584
|
+
status: "current",
|
|
585
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
586
|
+
source: SOURCES.githubCopilotComparison
|
|
587
|
+
}),
|
|
588
|
+
model({
|
|
589
|
+
id: "gpt-5.5",
|
|
590
|
+
name: "GPT-5.5",
|
|
591
|
+
description: "Copilot model for complex reasoning and technical decisions",
|
|
592
|
+
contextWindow: 1e6,
|
|
593
|
+
maxOutputTokens: 128e3,
|
|
594
|
+
status: "current",
|
|
595
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
596
|
+
source: SOURCES.githubCopilotComparison
|
|
597
|
+
}),
|
|
598
|
+
model({
|
|
599
|
+
id: "gpt-5.4",
|
|
600
|
+
name: "GPT-5.4",
|
|
601
|
+
description: "Copilot coding model",
|
|
602
|
+
contextWindow: 1e6,
|
|
603
|
+
maxOutputTokens: 128e3,
|
|
604
|
+
status: "current",
|
|
605
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
606
|
+
source: SOURCES.githubCopilotModels
|
|
607
|
+
}),
|
|
608
|
+
model({
|
|
609
|
+
id: "gpt-5.4-mini",
|
|
610
|
+
name: "GPT-5.4 mini",
|
|
611
|
+
description: "Fast Copilot model for interactive coding",
|
|
612
|
+
contextWindow: 1e6,
|
|
613
|
+
maxOutputTokens: 128e3,
|
|
614
|
+
status: "current",
|
|
615
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
616
|
+
source: SOURCES.githubCopilotModels
|
|
617
|
+
}),
|
|
618
|
+
model({
|
|
619
|
+
id: "gpt-5.3-codex",
|
|
620
|
+
name: "GPT-5.3 Codex",
|
|
621
|
+
description: "Copilot agentic coding model",
|
|
622
|
+
contextWindow: 4e5,
|
|
623
|
+
maxOutputTokens: 128e3,
|
|
624
|
+
status: "current",
|
|
625
|
+
capabilities: ["streaming", "tool-use", "openai-chat"],
|
|
626
|
+
source: SOURCES.githubCopilotModels
|
|
627
|
+
}),
|
|
628
|
+
model({
|
|
629
|
+
id: "claude-opus-4.8",
|
|
630
|
+
name: "Claude Opus 4.8",
|
|
631
|
+
description: "Most capable Anthropic model exposed by Copilot when available",
|
|
632
|
+
contextWindow: 168e3,
|
|
633
|
+
maxOutputTokens: 64e3,
|
|
634
|
+
status: "current",
|
|
635
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
636
|
+
source: SOURCES.githubCopilotModels
|
|
637
|
+
}),
|
|
638
|
+
model({
|
|
639
|
+
id: "gemini-3.1-pro",
|
|
640
|
+
name: "Gemini 3.1 Pro",
|
|
641
|
+
description: "Gemini model exposed by Copilot",
|
|
642
|
+
contextWindow: 1e6,
|
|
643
|
+
maxOutputTokens: 64e3,
|
|
644
|
+
status: "current",
|
|
645
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
646
|
+
source: SOURCES.githubCopilotModels
|
|
647
|
+
}),
|
|
648
|
+
model({
|
|
649
|
+
id: "gemini-3.5-flash",
|
|
650
|
+
name: "Gemini 3.5 Flash",
|
|
651
|
+
description: "Fast Gemini model exposed by Copilot",
|
|
652
|
+
contextWindow: 1e6,
|
|
653
|
+
maxOutputTokens: 64e3,
|
|
654
|
+
status: "current",
|
|
655
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"],
|
|
656
|
+
source: SOURCES.githubCopilotModels
|
|
657
|
+
})
|
|
658
|
+
]
|
|
659
|
+
},
|
|
660
|
+
gemini: {
|
|
661
|
+
id: "gemini",
|
|
662
|
+
defaultModel: "gemini-3.1-pro-preview",
|
|
663
|
+
models: [
|
|
664
|
+
model({
|
|
665
|
+
id: "gemini-3.1-pro-preview",
|
|
666
|
+
name: "Gemini 3.1 Pro Preview",
|
|
667
|
+
description: "Most capable Gemini 3 model for agentic and coding workflows",
|
|
668
|
+
contextWindow: 1e6,
|
|
669
|
+
maxOutputTokens: 64e3,
|
|
670
|
+
recommended: true,
|
|
671
|
+
status: "experimental",
|
|
672
|
+
capabilities: [
|
|
673
|
+
"streaming",
|
|
674
|
+
"tool-use",
|
|
675
|
+
"vision",
|
|
676
|
+
"thinking-budget",
|
|
677
|
+
"gemini-generate-content"
|
|
678
|
+
],
|
|
679
|
+
source: SOURCES.geminiGuide
|
|
680
|
+
}),
|
|
681
|
+
model({
|
|
682
|
+
id: "gemini-3-flash-preview",
|
|
683
|
+
name: "Gemini 3 Flash Preview",
|
|
684
|
+
description: "Fast Gemini 3 preview model",
|
|
685
|
+
contextWindow: 1e6,
|
|
686
|
+
maxOutputTokens: 64e3,
|
|
687
|
+
status: "experimental",
|
|
688
|
+
capabilities: [
|
|
689
|
+
"streaming",
|
|
690
|
+
"tool-use",
|
|
691
|
+
"vision",
|
|
692
|
+
"thinking-budget",
|
|
693
|
+
"gemini-generate-content"
|
|
694
|
+
],
|
|
695
|
+
source: SOURCES.geminiGuide
|
|
696
|
+
}),
|
|
697
|
+
model({
|
|
698
|
+
id: "gemini-2.5-pro",
|
|
699
|
+
name: "Gemini 2.5 Pro",
|
|
700
|
+
description: "Stable Gemini Pro model",
|
|
701
|
+
contextWindow: 1048576,
|
|
702
|
+
maxOutputTokens: 65536,
|
|
703
|
+
status: "current",
|
|
704
|
+
capabilities: [
|
|
705
|
+
"streaming",
|
|
706
|
+
"tool-use",
|
|
707
|
+
"vision",
|
|
708
|
+
"thinking-budget",
|
|
709
|
+
"gemini-generate-content"
|
|
710
|
+
],
|
|
711
|
+
source: SOURCES.geminiModels
|
|
712
|
+
}),
|
|
713
|
+
model({
|
|
714
|
+
id: "gemini-2.5-flash",
|
|
715
|
+
name: "Gemini 2.5 Flash",
|
|
716
|
+
description: "Stable fast Gemini model",
|
|
717
|
+
contextWindow: 1048576,
|
|
718
|
+
maxOutputTokens: 65536,
|
|
719
|
+
status: "current",
|
|
720
|
+
capabilities: [
|
|
721
|
+
"streaming",
|
|
722
|
+
"tool-use",
|
|
723
|
+
"vision",
|
|
724
|
+
"thinking-budget",
|
|
725
|
+
"gemini-generate-content"
|
|
726
|
+
],
|
|
727
|
+
source: SOURCES.geminiModels
|
|
728
|
+
}),
|
|
729
|
+
model({
|
|
730
|
+
id: "gemini-2.5-flash-lite",
|
|
731
|
+
name: "Gemini 2.5 Flash-Lite",
|
|
732
|
+
description: "Lowest-cost stable Gemini option",
|
|
733
|
+
contextWindow: 1048576,
|
|
734
|
+
maxOutputTokens: 65536,
|
|
735
|
+
status: "current",
|
|
736
|
+
capabilities: [
|
|
737
|
+
"streaming",
|
|
738
|
+
"tool-use",
|
|
739
|
+
"vision",
|
|
740
|
+
"thinking-budget",
|
|
741
|
+
"gemini-generate-content"
|
|
742
|
+
],
|
|
743
|
+
source: SOURCES.geminiModels
|
|
744
|
+
})
|
|
745
|
+
]
|
|
746
|
+
},
|
|
747
|
+
vertex: {
|
|
748
|
+
id: "vertex",
|
|
749
|
+
defaultModel: "gemini-2.5-pro",
|
|
750
|
+
models: [
|
|
751
|
+
model({
|
|
752
|
+
id: "gemini-2.5-pro",
|
|
753
|
+
name: "Gemini 2.5 Pro",
|
|
754
|
+
description: "Stable Vertex model for coding and complex reasoning",
|
|
755
|
+
contextWindow: 1048576,
|
|
756
|
+
maxOutputTokens: 65536,
|
|
757
|
+
recommended: true,
|
|
758
|
+
status: "current",
|
|
759
|
+
capabilities: [
|
|
760
|
+
"streaming",
|
|
761
|
+
"tool-use",
|
|
762
|
+
"vision",
|
|
763
|
+
"thinking-budget",
|
|
764
|
+
"gemini-generate-content"
|
|
765
|
+
],
|
|
766
|
+
source: SOURCES.geminiModels
|
|
767
|
+
}),
|
|
768
|
+
model({
|
|
769
|
+
id: "gemini-3-pro-preview",
|
|
770
|
+
name: "Gemini 3 Pro Preview",
|
|
771
|
+
description: "Preview Vertex Gemini 3 model",
|
|
772
|
+
contextWindow: 1048576,
|
|
773
|
+
maxOutputTokens: 65536,
|
|
774
|
+
status: "experimental",
|
|
775
|
+
capabilities: [
|
|
776
|
+
"streaming",
|
|
777
|
+
"tool-use",
|
|
778
|
+
"vision",
|
|
779
|
+
"thinking-budget",
|
|
780
|
+
"gemini-generate-content"
|
|
781
|
+
],
|
|
782
|
+
source: SOURCES.geminiGuide
|
|
783
|
+
}),
|
|
784
|
+
model({
|
|
785
|
+
id: "gemini-3-flash-preview",
|
|
786
|
+
name: "Gemini 3 Flash Preview",
|
|
787
|
+
description: "Fast preview Vertex Gemini 3 model",
|
|
788
|
+
contextWindow: 1048576,
|
|
789
|
+
maxOutputTokens: 65536,
|
|
790
|
+
status: "experimental",
|
|
791
|
+
capabilities: [
|
|
792
|
+
"streaming",
|
|
793
|
+
"tool-use",
|
|
794
|
+
"vision",
|
|
795
|
+
"thinking-budget",
|
|
796
|
+
"gemini-generate-content"
|
|
797
|
+
],
|
|
798
|
+
source: SOURCES.geminiGuide
|
|
799
|
+
}),
|
|
800
|
+
model({
|
|
801
|
+
id: "gemini-2.5-flash",
|
|
802
|
+
name: "Gemini 2.5 Flash",
|
|
803
|
+
description: "Fast stable Vertex Gemini model",
|
|
804
|
+
contextWindow: 1048576,
|
|
805
|
+
maxOutputTokens: 65536,
|
|
806
|
+
status: "current",
|
|
807
|
+
capabilities: [
|
|
808
|
+
"streaming",
|
|
809
|
+
"tool-use",
|
|
810
|
+
"vision",
|
|
811
|
+
"thinking-budget",
|
|
812
|
+
"gemini-generate-content"
|
|
813
|
+
],
|
|
814
|
+
source: SOURCES.geminiModels
|
|
815
|
+
})
|
|
816
|
+
]
|
|
817
|
+
},
|
|
818
|
+
kimi: {
|
|
819
|
+
id: "kimi",
|
|
820
|
+
defaultModel: "kimi-k2.5",
|
|
821
|
+
models: [
|
|
822
|
+
model({
|
|
823
|
+
id: "kimi-k2.5",
|
|
824
|
+
name: "Kimi K2.5",
|
|
825
|
+
description: "Moonshot model for coding and agentic work",
|
|
826
|
+
contextWindow: 262144,
|
|
827
|
+
maxOutputTokens: 32e3,
|
|
828
|
+
recommended: true,
|
|
829
|
+
status: "current",
|
|
830
|
+
capabilities: ["streaming", "tool-use", "openai-chat"],
|
|
831
|
+
source: SOURCES.moonshotDocs
|
|
832
|
+
}),
|
|
833
|
+
model({
|
|
834
|
+
id: "kimi-k2-thinking",
|
|
835
|
+
name: "Kimi K2 Thinking",
|
|
836
|
+
description: "Reasoning variant",
|
|
837
|
+
contextWindow: 262144,
|
|
838
|
+
maxOutputTokens: 32e3,
|
|
839
|
+
status: "current",
|
|
840
|
+
capabilities: ["streaming", "tool-use", "openai-chat"],
|
|
841
|
+
source: SOURCES.moonshotDocs
|
|
842
|
+
}),
|
|
843
|
+
model({
|
|
844
|
+
id: "moonshot-v1-128k",
|
|
845
|
+
name: "Moonshot v1 128K",
|
|
846
|
+
description: "Legacy long-context Moonshot model",
|
|
847
|
+
contextWindow: 131072,
|
|
848
|
+
maxOutputTokens: 8192,
|
|
849
|
+
status: "legacy",
|
|
850
|
+
capabilities: ["streaming", "tool-use", "openai-chat"],
|
|
851
|
+
pricing: { inputPerMillion: 6, outputPerMillion: 6 },
|
|
852
|
+
source: SOURCES.moonshotDocs
|
|
853
|
+
})
|
|
854
|
+
]
|
|
855
|
+
},
|
|
856
|
+
"kimi-code": {
|
|
857
|
+
id: "kimi-code",
|
|
858
|
+
defaultModel: "kimi-for-coding",
|
|
859
|
+
models: [
|
|
860
|
+
model({
|
|
861
|
+
id: "kimi-for-coding",
|
|
862
|
+
name: "Kimi for Coding",
|
|
863
|
+
description: "Anthropic-compatible Kimi coding endpoint",
|
|
864
|
+
contextWindow: 131072,
|
|
865
|
+
maxOutputTokens: 32e3,
|
|
866
|
+
recommended: true,
|
|
867
|
+
status: "current",
|
|
868
|
+
capabilities: ["streaming", "tool-use", "anthropic-messages"],
|
|
869
|
+
source: SOURCES.moonshotDocs
|
|
870
|
+
})
|
|
871
|
+
]
|
|
872
|
+
},
|
|
873
|
+
lmstudio: {
|
|
874
|
+
id: "lmstudio",
|
|
875
|
+
defaultModel: "local-model",
|
|
876
|
+
models: [
|
|
877
|
+
model({
|
|
878
|
+
id: "local-model",
|
|
879
|
+
name: "Local model",
|
|
880
|
+
description: "Model selected in LM Studio",
|
|
881
|
+
contextWindow: 32768,
|
|
882
|
+
maxOutputTokens: 8192,
|
|
883
|
+
recommended: true,
|
|
884
|
+
status: "current",
|
|
885
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
886
|
+
})
|
|
887
|
+
]
|
|
888
|
+
},
|
|
889
|
+
ollama: {
|
|
890
|
+
id: "ollama",
|
|
891
|
+
defaultModel: "llama3.2",
|
|
892
|
+
models: [
|
|
893
|
+
model({
|
|
894
|
+
id: "llama3.2",
|
|
895
|
+
name: "Llama 3.2",
|
|
896
|
+
description: "Default local Ollama model",
|
|
897
|
+
contextWindow: 128e3,
|
|
898
|
+
maxOutputTokens: 8192,
|
|
899
|
+
recommended: true,
|
|
900
|
+
status: "current",
|
|
901
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
902
|
+
}),
|
|
903
|
+
model({
|
|
904
|
+
id: "qwen2.5-coder:14b",
|
|
905
|
+
name: "Qwen2.5 Coder 14B",
|
|
906
|
+
description: "Local coding model",
|
|
907
|
+
contextWindow: 32768,
|
|
908
|
+
maxOutputTokens: 8192,
|
|
909
|
+
status: "legacy",
|
|
910
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
911
|
+
})
|
|
912
|
+
]
|
|
913
|
+
},
|
|
914
|
+
groq: {
|
|
915
|
+
id: "groq",
|
|
916
|
+
defaultModel: "llama-3.3-70b-versatile",
|
|
917
|
+
models: [
|
|
918
|
+
model({
|
|
919
|
+
id: "llama-3.3-70b-versatile",
|
|
920
|
+
name: "Llama 3.3 70B Versatile",
|
|
921
|
+
contextWindow: 128e3,
|
|
922
|
+
maxOutputTokens: 8192,
|
|
923
|
+
recommended: true,
|
|
924
|
+
status: "current",
|
|
925
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
926
|
+
})
|
|
927
|
+
]
|
|
928
|
+
},
|
|
929
|
+
openrouter: {
|
|
930
|
+
id: "openrouter",
|
|
931
|
+
defaultModel: "anthropic/claude-sonnet-4.6",
|
|
932
|
+
models: [
|
|
933
|
+
model({
|
|
934
|
+
id: "anthropic/claude-sonnet-4.6",
|
|
935
|
+
name: "Claude Sonnet 4.6 via OpenRouter",
|
|
936
|
+
contextWindow: 2e5,
|
|
937
|
+
maxOutputTokens: 64e3,
|
|
938
|
+
recommended: true,
|
|
939
|
+
status: "current",
|
|
940
|
+
capabilities: ["streaming", "tool-use", "vision", "openai-chat"]
|
|
941
|
+
})
|
|
942
|
+
]
|
|
943
|
+
},
|
|
944
|
+
mistral: {
|
|
945
|
+
id: "mistral",
|
|
946
|
+
defaultModel: "mistral-large-latest",
|
|
947
|
+
models: [
|
|
948
|
+
model({
|
|
949
|
+
id: "mistral-large-latest",
|
|
950
|
+
name: "Mistral Large latest",
|
|
951
|
+
contextWindow: 131072,
|
|
952
|
+
maxOutputTokens: 8192,
|
|
953
|
+
recommended: true,
|
|
954
|
+
status: "current",
|
|
955
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
956
|
+
}),
|
|
957
|
+
model({
|
|
958
|
+
id: "codestral-latest",
|
|
959
|
+
name: "Codestral latest",
|
|
960
|
+
contextWindow: 32768,
|
|
961
|
+
maxOutputTokens: 8192,
|
|
962
|
+
status: "current",
|
|
963
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
964
|
+
})
|
|
965
|
+
]
|
|
966
|
+
},
|
|
967
|
+
deepseek: {
|
|
968
|
+
id: "deepseek",
|
|
969
|
+
defaultModel: "deepseek-chat",
|
|
970
|
+
models: [
|
|
971
|
+
model({
|
|
972
|
+
id: "deepseek-chat",
|
|
973
|
+
name: "DeepSeek Chat",
|
|
974
|
+
contextWindow: 65536,
|
|
975
|
+
maxOutputTokens: 8192,
|
|
976
|
+
recommended: true,
|
|
977
|
+
status: "current",
|
|
978
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
979
|
+
}),
|
|
980
|
+
model({
|
|
981
|
+
id: "deepseek-reasoner",
|
|
982
|
+
name: "DeepSeek Reasoner",
|
|
983
|
+
contextWindow: 65536,
|
|
984
|
+
maxOutputTokens: 8192,
|
|
985
|
+
status: "current",
|
|
986
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
987
|
+
})
|
|
988
|
+
]
|
|
989
|
+
},
|
|
990
|
+
together: {
|
|
991
|
+
id: "together",
|
|
992
|
+
defaultModel: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
993
|
+
models: [
|
|
994
|
+
model({
|
|
995
|
+
id: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
996
|
+
name: "Llama 3.3 70B Instruct Turbo",
|
|
997
|
+
contextWindow: 128e3,
|
|
998
|
+
maxOutputTokens: 8192,
|
|
999
|
+
recommended: true,
|
|
1000
|
+
status: "current",
|
|
1001
|
+
capabilities: ["streaming", "tool-use", "openai-chat"]
|
|
1002
|
+
})
|
|
1003
|
+
]
|
|
1004
|
+
},
|
|
1005
|
+
huggingface: {
|
|
1006
|
+
id: "huggingface",
|
|
1007
|
+
defaultModel: "meta-llama/Llama-3.1-70B-Instruct",
|
|
1008
|
+
models: [
|
|
1009
|
+
model({
|
|
1010
|
+
id: "meta-llama/Llama-3.1-70B-Instruct",
|
|
1011
|
+
name: "Llama 3.1 70B Instruct",
|
|
1012
|
+
contextWindow: 128e3,
|
|
1013
|
+
maxOutputTokens: 8192,
|
|
1014
|
+
recommended: true,
|
|
1015
|
+
status: "legacy",
|
|
1016
|
+
capabilities: ["streaming", "openai-chat"]
|
|
1017
|
+
})
|
|
1018
|
+
]
|
|
1019
|
+
},
|
|
1020
|
+
qwen: {
|
|
1021
|
+
id: "qwen",
|
|
1022
|
+
defaultModel: "qwen-coder-plus",
|
|
1023
|
+
models: [
|
|
1024
|
+
model({
|
|
1025
|
+
id: "qwen-coder-plus",
|
|
1026
|
+
name: "Qwen Coder Plus",
|
|
1027
|
+
contextWindow: 131072,
|
|
1028
|
+
maxOutputTokens: 8192,
|
|
1029
|
+
recommended: true,
|
|
1030
|
+
status: "current",
|
|
1031
|
+
capabilities: ["streaming", "tool-use", "openai-chat"],
|
|
1032
|
+
source: SOURCES.qwenDocs
|
|
1033
|
+
}),
|
|
1034
|
+
model({
|
|
1035
|
+
id: "qwen-max",
|
|
1036
|
+
name: "Qwen Max",
|
|
1037
|
+
contextWindow: 131072,
|
|
1038
|
+
maxOutputTokens: 8192,
|
|
1039
|
+
status: "current",
|
|
1040
|
+
capabilities: ["streaming", "tool-use", "openai-chat"],
|
|
1041
|
+
source: SOURCES.qwenDocs
|
|
1042
|
+
})
|
|
1043
|
+
]
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
256
1048
|
async function refreshAccessToken(provider, refreshToken) {
|
|
257
1049
|
const config = OAUTH_CONFIGS[provider];
|
|
258
1050
|
if (!config) {
|
|
@@ -939,6 +1731,7 @@ var init_copilot = __esm({
|
|
|
939
1731
|
this.permanent = permanent;
|
|
940
1732
|
this.name = "CopilotAuthError";
|
|
941
1733
|
}
|
|
1734
|
+
permanent;
|
|
942
1735
|
};
|
|
943
1736
|
CopilotCredentialsSchema = z.object({
|
|
944
1737
|
githubToken: z.string().min(1),
|
|
@@ -1514,8 +2307,8 @@ async function configExists(configPath, scope = "any") {
|
|
|
1514
2307
|
}
|
|
1515
2308
|
return false;
|
|
1516
2309
|
}
|
|
1517
|
-
function getConfigValue(config,
|
|
1518
|
-
const keys =
|
|
2310
|
+
function getConfigValue(config, path44) {
|
|
2311
|
+
const keys = path44.split(".");
|
|
1519
2312
|
let current = config;
|
|
1520
2313
|
for (const key of keys) {
|
|
1521
2314
|
if (current === null || current === void 0 || typeof current !== "object") {
|
|
@@ -1663,41 +2456,41 @@ function getBaseUrl(provider) {
|
|
|
1663
2456
|
function getDefaultModel(provider) {
|
|
1664
2457
|
switch (provider) {
|
|
1665
2458
|
case "anthropic":
|
|
1666
|
-
return process.env["ANTHROPIC_MODEL"] ??
|
|
2459
|
+
return process.env["ANTHROPIC_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1667
2460
|
case "openai":
|
|
1668
|
-
return process.env["OPENAI_MODEL"] ??
|
|
2461
|
+
return process.env["OPENAI_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1669
2462
|
case "gemini":
|
|
1670
|
-
return process.env["GEMINI_MODEL"] ??
|
|
2463
|
+
return process.env["GEMINI_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1671
2464
|
case "vertex":
|
|
1672
|
-
return process.env["VERTEX_MODEL"] ??
|
|
2465
|
+
return process.env["VERTEX_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1673
2466
|
case "kimi":
|
|
1674
|
-
return process.env["KIMI_MODEL"] ??
|
|
2467
|
+
return process.env["KIMI_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1675
2468
|
case "kimi-code":
|
|
1676
|
-
return process.env["KIMI_CODE_MODEL"] ??
|
|
2469
|
+
return process.env["KIMI_CODE_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1677
2470
|
case "lmstudio":
|
|
1678
|
-
return process.env["LMSTUDIO_MODEL"] ??
|
|
2471
|
+
return process.env["LMSTUDIO_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1679
2472
|
case "ollama":
|
|
1680
|
-
return process.env["OLLAMA_MODEL"] ??
|
|
2473
|
+
return process.env["OLLAMA_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1681
2474
|
case "codex":
|
|
1682
|
-
return process.env["CODEX_MODEL"] ??
|
|
2475
|
+
return process.env["CODEX_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1683
2476
|
case "copilot":
|
|
1684
|
-
return process.env["COPILOT_MODEL"] ??
|
|
2477
|
+
return process.env["COPILOT_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1685
2478
|
case "groq":
|
|
1686
|
-
return process.env["GROQ_MODEL"] ??
|
|
2479
|
+
return process.env["GROQ_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1687
2480
|
case "openrouter":
|
|
1688
|
-
return process.env["OPENROUTER_MODEL"] ??
|
|
2481
|
+
return process.env["OPENROUTER_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1689
2482
|
case "mistral":
|
|
1690
|
-
return process.env["MISTRAL_MODEL"] ??
|
|
2483
|
+
return process.env["MISTRAL_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1691
2484
|
case "deepseek":
|
|
1692
|
-
return process.env["DEEPSEEK_MODEL"] ??
|
|
2485
|
+
return process.env["DEEPSEEK_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1693
2486
|
case "together":
|
|
1694
|
-
return process.env["TOGETHER_MODEL"] ??
|
|
2487
|
+
return process.env["TOGETHER_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1695
2488
|
case "huggingface":
|
|
1696
|
-
return process.env["HF_MODEL"] ??
|
|
2489
|
+
return process.env["HF_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1697
2490
|
case "qwen":
|
|
1698
|
-
return process.env["QWEN_MODEL"] ??
|
|
2491
|
+
return process.env["QWEN_MODEL"] ?? getCatalogDefaultModel(provider);
|
|
1699
2492
|
default:
|
|
1700
|
-
return "
|
|
2493
|
+
return getCatalogDefaultModel("anthropic");
|
|
1701
2494
|
}
|
|
1702
2495
|
}
|
|
1703
2496
|
function getDefaultProvider() {
|
|
@@ -1724,6 +2517,7 @@ var init_env = __esm({
|
|
|
1724
2517
|
"src/config/env.ts"() {
|
|
1725
2518
|
init_loader();
|
|
1726
2519
|
init_paths();
|
|
2520
|
+
init_catalog();
|
|
1727
2521
|
loadGlobalCocoEnv();
|
|
1728
2522
|
VALID_PROVIDERS = [
|
|
1729
2523
|
"anthropic",
|
|
@@ -2060,9 +2854,9 @@ async function migrateGlobalConfig(oldDir, newConfigPath) {
|
|
|
2060
2854
|
);
|
|
2061
2855
|
}
|
|
2062
2856
|
}
|
|
2063
|
-
async function fileExists3(
|
|
2857
|
+
async function fileExists3(path44) {
|
|
2064
2858
|
try {
|
|
2065
|
-
await access(
|
|
2859
|
+
await access(path44);
|
|
2066
2860
|
return true;
|
|
2067
2861
|
} catch {
|
|
2068
2862
|
return false;
|
|
@@ -3095,10 +3889,10 @@ function inferTargetUsers(session) {
|
|
|
3095
3889
|
/(?:for|by)\s+(developers?|users?|administrators?|customers?)/gi,
|
|
3096
3890
|
/(developers?|users?|administrators?|customers?)\s+(?:can|will|should)/gi
|
|
3097
3891
|
];
|
|
3098
|
-
const
|
|
3892
|
+
const text2 = session.requirements.map((r) => r.description).join(" ");
|
|
3099
3893
|
for (const pattern of userPatterns) {
|
|
3100
3894
|
let match;
|
|
3101
|
-
while ((match = pattern.exec(
|
|
3895
|
+
while ((match = pattern.exec(text2)) !== null) {
|
|
3102
3896
|
const user = match[1]?.toLowerCase();
|
|
3103
3897
|
if (user && !users.includes(user)) {
|
|
3104
3898
|
users.push(user);
|
|
@@ -3111,13 +3905,13 @@ function inferTargetUsers(session) {
|
|
|
3111
3905
|
return users;
|
|
3112
3906
|
}
|
|
3113
3907
|
function inferProjectType(session) {
|
|
3114
|
-
const
|
|
3115
|
-
if (
|
|
3116
|
-
if (
|
|
3117
|
-
if (
|
|
3118
|
-
if (
|
|
3119
|
-
if (
|
|
3120
|
-
if (
|
|
3908
|
+
const text2 = session.initialInput.toLowerCase();
|
|
3909
|
+
if (text2.includes("cli") || text2.includes("command line")) return "cli";
|
|
3910
|
+
if (text2.includes("api") || text2.includes("rest") || text2.includes("graphql")) return "api";
|
|
3911
|
+
if (text2.includes("web app") || text2.includes("frontend")) return "web_app";
|
|
3912
|
+
if (text2.includes("library") || text2.includes("package")) return "library";
|
|
3913
|
+
if (text2.includes("service") || text2.includes("daemon")) return "service";
|
|
3914
|
+
if (text2.includes("full stack") || text2.includes("fullstack")) return "full_stack";
|
|
3121
3915
|
return "unknown";
|
|
3122
3916
|
}
|
|
3123
3917
|
function assessComplexity(session) {
|
|
@@ -4663,14 +5457,14 @@ function generateArchitectureMarkdown(doc) {
|
|
|
4663
5457
|
if (doc.dataModels.length > 0) {
|
|
4664
5458
|
sections.push("## Data Models");
|
|
4665
5459
|
sections.push("");
|
|
4666
|
-
for (const
|
|
4667
|
-
sections.push(`### ${
|
|
5460
|
+
for (const model2 of doc.dataModels) {
|
|
5461
|
+
sections.push(`### ${model2.name}`);
|
|
4668
5462
|
sections.push("");
|
|
4669
|
-
sections.push(
|
|
5463
|
+
sections.push(model2.description);
|
|
4670
5464
|
sections.push("");
|
|
4671
5465
|
sections.push("| Field | Type | Required |");
|
|
4672
5466
|
sections.push("|-------|------|----------|");
|
|
4673
|
-
for (const field of
|
|
5467
|
+
for (const field of model2.fields) {
|
|
4674
5468
|
sections.push(`| ${field.name} | ${field.type} | ${field.required ? "Yes" : "No"} |`);
|
|
4675
5469
|
}
|
|
4676
5470
|
sections.push("");
|
|
@@ -5894,6 +6688,7 @@ var CoverageAnalyzer = class {
|
|
|
5894
6688
|
constructor(projectPath) {
|
|
5895
6689
|
this.projectPath = projectPath;
|
|
5896
6690
|
}
|
|
6691
|
+
projectPath;
|
|
5897
6692
|
/**
|
|
5898
6693
|
* Analyze coverage by running tests with coverage enabled
|
|
5899
6694
|
*/
|
|
@@ -6236,6 +7031,7 @@ var SnykSecurityScanner = class {
|
|
|
6236
7031
|
constructor(projectPath) {
|
|
6237
7032
|
this.projectPath = projectPath;
|
|
6238
7033
|
}
|
|
7034
|
+
projectPath;
|
|
6239
7035
|
/**
|
|
6240
7036
|
* Scan project with Snyk (requires authentication)
|
|
6241
7037
|
*/
|
|
@@ -6447,6 +7243,8 @@ var ComplexityAnalyzer = class {
|
|
|
6447
7243
|
this.projectPath = projectPath;
|
|
6448
7244
|
this.threshold = threshold;
|
|
6449
7245
|
}
|
|
7246
|
+
projectPath;
|
|
7247
|
+
threshold;
|
|
6450
7248
|
/**
|
|
6451
7249
|
* Analyze complexity of project files
|
|
6452
7250
|
*/
|
|
@@ -6532,6 +7330,8 @@ var DuplicationAnalyzer = class {
|
|
|
6532
7330
|
this.projectPath = projectPath;
|
|
6533
7331
|
this.minLines = minLines;
|
|
6534
7332
|
}
|
|
7333
|
+
projectPath;
|
|
7334
|
+
minLines;
|
|
6535
7335
|
/**
|
|
6536
7336
|
* Detect code duplication
|
|
6537
7337
|
*/
|
|
@@ -6900,6 +7700,7 @@ var CorrectnessAnalyzer = class {
|
|
|
6900
7700
|
this.projectPath = projectPath;
|
|
6901
7701
|
this.buildVerifier = new BuildVerifier(projectPath);
|
|
6902
7702
|
}
|
|
7703
|
+
projectPath;
|
|
6903
7704
|
buildVerifier;
|
|
6904
7705
|
/**
|
|
6905
7706
|
* Analyze correctness by running tests and verifying build
|
|
@@ -7032,6 +7833,7 @@ var CompletenessAnalyzer = class {
|
|
|
7032
7833
|
constructor(projectPath) {
|
|
7033
7834
|
this.projectPath = projectPath;
|
|
7034
7835
|
}
|
|
7836
|
+
projectPath;
|
|
7035
7837
|
/**
|
|
7036
7838
|
* Analyze project completeness
|
|
7037
7839
|
*/
|
|
@@ -7265,6 +8067,7 @@ var RobustnessAnalyzer = class {
|
|
|
7265
8067
|
constructor(projectPath) {
|
|
7266
8068
|
this.projectPath = projectPath;
|
|
7267
8069
|
}
|
|
8070
|
+
projectPath;
|
|
7268
8071
|
/**
|
|
7269
8072
|
* Analyze robustness of project files
|
|
7270
8073
|
*/
|
|
@@ -7422,6 +8225,7 @@ var TestQualityAnalyzer = class {
|
|
|
7422
8225
|
constructor(projectPath) {
|
|
7423
8226
|
this.projectPath = projectPath;
|
|
7424
8227
|
}
|
|
8228
|
+
projectPath;
|
|
7425
8229
|
/**
|
|
7426
8230
|
* Analyze test quality across the project
|
|
7427
8231
|
*/
|
|
@@ -7551,6 +8355,7 @@ var DocumentationAnalyzer = class {
|
|
|
7551
8355
|
constructor(projectPath) {
|
|
7552
8356
|
this.projectPath = projectPath;
|
|
7553
8357
|
}
|
|
8358
|
+
projectPath;
|
|
7554
8359
|
/**
|
|
7555
8360
|
* Analyze documentation quality
|
|
7556
8361
|
*/
|
|
@@ -7705,6 +8510,7 @@ var StyleAnalyzer = class {
|
|
|
7705
8510
|
constructor(projectPath) {
|
|
7706
8511
|
this.projectPath = projectPath;
|
|
7707
8512
|
}
|
|
8513
|
+
projectPath;
|
|
7708
8514
|
/**
|
|
7709
8515
|
* Analyze style/linting quality
|
|
7710
8516
|
*/
|
|
@@ -7914,6 +8720,7 @@ var ReadabilityAnalyzer = class {
|
|
|
7914
8720
|
constructor(projectPath) {
|
|
7915
8721
|
this.projectPath = projectPath;
|
|
7916
8722
|
}
|
|
8723
|
+
projectPath;
|
|
7917
8724
|
/**
|
|
7918
8725
|
* Analyze readability of project files
|
|
7919
8726
|
*/
|
|
@@ -8051,6 +8858,7 @@ var MaintainabilityAnalyzer = class {
|
|
|
8051
8858
|
constructor(projectPath) {
|
|
8052
8859
|
this.projectPath = projectPath;
|
|
8053
8860
|
}
|
|
8861
|
+
projectPath;
|
|
8054
8862
|
/**
|
|
8055
8863
|
* Analyze maintainability of project files
|
|
8056
8864
|
*/
|
|
@@ -8418,6 +9226,7 @@ var JavaComplexityAnalyzer = class {
|
|
|
8418
9226
|
constructor(projectPath) {
|
|
8419
9227
|
this.projectPath = projectPath;
|
|
8420
9228
|
}
|
|
9229
|
+
projectPath;
|
|
8421
9230
|
async analyze(files) {
|
|
8422
9231
|
const javaFiles = files ?? await findJavaFiles(this.projectPath);
|
|
8423
9232
|
if (!javaFiles.length) {
|
|
@@ -8557,6 +9366,7 @@ var JavaSecurityAnalyzer = class {
|
|
|
8557
9366
|
constructor(projectPath) {
|
|
8558
9367
|
this.projectPath = projectPath;
|
|
8559
9368
|
}
|
|
9369
|
+
projectPath;
|
|
8560
9370
|
async analyze(files) {
|
|
8561
9371
|
const javaFiles = files ?? await findJavaFiles(this.projectPath, { includeTests: false });
|
|
8562
9372
|
if (!javaFiles.length) {
|
|
@@ -8621,6 +9431,7 @@ var JavaStyleAnalyzer = class {
|
|
|
8621
9431
|
constructor(projectPath) {
|
|
8622
9432
|
this.projectPath = projectPath;
|
|
8623
9433
|
}
|
|
9434
|
+
projectPath;
|
|
8624
9435
|
async analyze(files) {
|
|
8625
9436
|
const javaFiles = files ?? await findJavaFiles(this.projectPath);
|
|
8626
9437
|
if (!javaFiles.length) return { score: 100, violations: [] };
|
|
@@ -8719,6 +9530,7 @@ var JavaDocumentationAnalyzer = class {
|
|
|
8719
9530
|
constructor(projectPath) {
|
|
8720
9531
|
this.projectPath = projectPath;
|
|
8721
9532
|
}
|
|
9533
|
+
projectPath;
|
|
8722
9534
|
async analyze(files) {
|
|
8723
9535
|
const javaFiles = files ?? await findJavaFiles(this.projectPath, { srcPattern: "src/main/**/*.java" });
|
|
8724
9536
|
if (!javaFiles.length) {
|
|
@@ -8796,6 +9608,7 @@ var JavaCoverageAnalyzer = class {
|
|
|
8796
9608
|
constructor(projectPath) {
|
|
8797
9609
|
this.projectPath = projectPath;
|
|
8798
9610
|
}
|
|
9611
|
+
projectPath;
|
|
8799
9612
|
async analyze() {
|
|
8800
9613
|
for (const reportPath of JACOCO_REPORT_PATHS) {
|
|
8801
9614
|
try {
|
|
@@ -8927,6 +9740,7 @@ var ReactComponentAnalyzer = class {
|
|
|
8927
9740
|
constructor(projectPath) {
|
|
8928
9741
|
this.projectPath = projectPath;
|
|
8929
9742
|
}
|
|
9743
|
+
projectPath;
|
|
8930
9744
|
async analyze(files) {
|
|
8931
9745
|
const reactFiles = files ?? await findReactFiles(this.projectPath);
|
|
8932
9746
|
if (!reactFiles.length) return { score: 100, totalComponents: 0, issues: [] };
|
|
@@ -9026,6 +9840,7 @@ var ReactA11yAnalyzer = class {
|
|
|
9026
9840
|
constructor(projectPath) {
|
|
9027
9841
|
this.projectPath = projectPath;
|
|
9028
9842
|
}
|
|
9843
|
+
projectPath;
|
|
9029
9844
|
async analyze(files) {
|
|
9030
9845
|
const reactFiles = files ?? await findReactFiles(this.projectPath);
|
|
9031
9846
|
if (!reactFiles.length) return { score: 100, violations: [] };
|
|
@@ -9118,6 +9933,7 @@ var ReactHookAnalyzer = class {
|
|
|
9118
9933
|
constructor(projectPath) {
|
|
9119
9934
|
this.projectPath = projectPath;
|
|
9120
9935
|
}
|
|
9936
|
+
projectPath;
|
|
9121
9937
|
async analyze(files) {
|
|
9122
9938
|
const reactFiles = files ?? await findReactFiles(this.projectPath, "**/*.{tsx,jsx,ts,js}");
|
|
9123
9939
|
if (!reactFiles.length) return { score: 100, violations: [] };
|
|
@@ -9531,6 +10347,8 @@ var QualityEvaluator = class {
|
|
|
9531
10347
|
this.readabilityAnalyzer = new ReadabilityAnalyzer(projectPath);
|
|
9532
10348
|
this.maintainabilityAnalyzer = new MaintainabilityAnalyzer(projectPath);
|
|
9533
10349
|
}
|
|
10350
|
+
projectPath;
|
|
10351
|
+
registry;
|
|
9534
10352
|
coverageAnalyzer;
|
|
9535
10353
|
securityScanner;
|
|
9536
10354
|
complexityAnalyzer;
|
|
@@ -10148,12 +10966,12 @@ function humanizeError(message, toolName) {
|
|
|
10148
10966
|
return msg;
|
|
10149
10967
|
}
|
|
10150
10968
|
if (/ENOENT/i.test(msg)) {
|
|
10151
|
-
const
|
|
10152
|
-
return
|
|
10969
|
+
const path44 = extractQuotedPath(msg);
|
|
10970
|
+
return path44 ? `File or directory not found: ${path44}` : "File or directory not found";
|
|
10153
10971
|
}
|
|
10154
10972
|
if (/EACCES/i.test(msg)) {
|
|
10155
|
-
const
|
|
10156
|
-
return
|
|
10973
|
+
const path44 = extractQuotedPath(msg);
|
|
10974
|
+
return path44 ? `Permission denied: ${path44}` : "Permission denied \u2014 check file permissions";
|
|
10157
10975
|
}
|
|
10158
10976
|
if (/EISDIR/i.test(msg)) {
|
|
10159
10977
|
return "Expected a file but found a directory at the specified path";
|
|
@@ -11561,8 +12379,8 @@ function createLLMAdapter2(context) {
|
|
|
11561
12379
|
type: "done"
|
|
11562
12380
|
};
|
|
11563
12381
|
},
|
|
11564
|
-
countTokens(
|
|
11565
|
-
return Math.ceil(
|
|
12382
|
+
countTokens(text2) {
|
|
12383
|
+
return Math.ceil(text2.length / 4);
|
|
11566
12384
|
},
|
|
11567
12385
|
getContextWindow() {
|
|
11568
12386
|
return 2e5;
|
|
@@ -13630,30 +14448,110 @@ var GEMINI_BUDGET = {
|
|
|
13630
14448
|
medium: 8e3,
|
|
13631
14449
|
high: 16e3
|
|
13632
14450
|
};
|
|
13633
|
-
function isAnthropicThinkingModel(
|
|
13634
|
-
const m =
|
|
14451
|
+
function isAnthropicThinkingModel(model2) {
|
|
14452
|
+
const m = model2.toLowerCase();
|
|
13635
14453
|
if (m === "kimi-for-coding") return false;
|
|
13636
14454
|
return m.includes("claude-3-7") || m.includes("claude-opus-4") || m.includes("claude-sonnet-4") || m.includes("claude-haiku-4-5") || m.includes("claude-4");
|
|
13637
14455
|
}
|
|
13638
|
-
function
|
|
13639
|
-
const m =
|
|
14456
|
+
function isAnthropicAdaptiveThinkingModel(model2) {
|
|
14457
|
+
const m = model2.toLowerCase();
|
|
14458
|
+
return m.includes("claude-opus-4-8") || m.includes("claude-opus-4-7") || m.includes("claude-opus-4-6") || m.includes("claude-sonnet-4-6");
|
|
14459
|
+
}
|
|
14460
|
+
function isOpenAIReasoningModel(model2) {
|
|
14461
|
+
const m = model2.toLowerCase();
|
|
13640
14462
|
return m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.startsWith("gpt-5") || m.includes("codex");
|
|
13641
14463
|
}
|
|
13642
|
-
function isGeminiThinkingModel(
|
|
13643
|
-
const m =
|
|
13644
|
-
return m.includes("gemini-2.5-pro") || m.includes("gemini-2.5-flash") || m.includes("gemini-3")
|
|
14464
|
+
function isGeminiThinkingModel(model2) {
|
|
14465
|
+
const m = model2.toLowerCase();
|
|
14466
|
+
return m.includes("gemini-2.5-pro") || m.includes("gemini-2.5-flash") || m.includes("gemini-3") || m.includes("gemini-2.0-flash-thinking");
|
|
13645
14467
|
}
|
|
13646
|
-
function
|
|
13647
|
-
|
|
14468
|
+
function isGeminiLevelThinkingModel(model2) {
|
|
14469
|
+
return model2.toLowerCase().includes("gemini-3");
|
|
14470
|
+
}
|
|
14471
|
+
function isKimiThinkingModel(model2) {
|
|
14472
|
+
const m = model2.toLowerCase();
|
|
13648
14473
|
return m.includes("kimi-k2") || m === "kimi-latest";
|
|
13649
14474
|
}
|
|
14475
|
+
var UNSUPPORTED = {
|
|
14476
|
+
supported: false,
|
|
14477
|
+
kinds: [],
|
|
14478
|
+
levels: ["off"],
|
|
14479
|
+
defaultMode: "off"
|
|
14480
|
+
};
|
|
13650
14481
|
var ANTHROPIC_CAPABILITY = {
|
|
13651
|
-
|
|
14482
|
+
supported: true,
|
|
14483
|
+
kinds: ["budget"],
|
|
14484
|
+
levels: ["off", "auto", "low", "medium", "high"],
|
|
14485
|
+
budgetRange: { min: 1024, max: 64e3, default: ANTHROPIC_BUDGET.medium },
|
|
14486
|
+
defaultMode: "off"
|
|
14487
|
+
};
|
|
14488
|
+
var ANTHROPIC_ADAPTIVE_CAPABILITY = {
|
|
14489
|
+
supported: true,
|
|
14490
|
+
kinds: ["effort"],
|
|
14491
|
+
levels: ["off", "auto", "low", "medium", "high"],
|
|
14492
|
+
defaultMode: "off"
|
|
14493
|
+
};
|
|
14494
|
+
var OPENAI_CAPABILITY = {
|
|
14495
|
+
supported: true,
|
|
14496
|
+
kinds: ["effort"],
|
|
14497
|
+
levels: ["off", "auto", "low", "medium", "high"],
|
|
14498
|
+
defaultMode: "medium"
|
|
14499
|
+
};
|
|
13652
14500
|
var GEMINI_CAPABILITY = {
|
|
13653
|
-
|
|
13654
|
-
|
|
14501
|
+
supported: true,
|
|
14502
|
+
kinds: ["budget"],
|
|
14503
|
+
levels: ["off", "auto", "low", "medium", "high"],
|
|
14504
|
+
budgetRange: { min: 0, max: 32e3, default: GEMINI_BUDGET.medium },
|
|
14505
|
+
defaultMode: "auto"
|
|
14506
|
+
};
|
|
14507
|
+
var GEMINI_LEVEL_CAPABILITY = {
|
|
14508
|
+
supported: true,
|
|
14509
|
+
kinds: ["effort"],
|
|
14510
|
+
levels: ["auto", "low", "medium", "high"],
|
|
14511
|
+
defaultMode: "auto"
|
|
14512
|
+
};
|
|
14513
|
+
var KIMI_CAPABILITY = {
|
|
14514
|
+
supported: true,
|
|
14515
|
+
kinds: ["effort"],
|
|
14516
|
+
levels: ["off", "auto"],
|
|
14517
|
+
defaultMode: "off"
|
|
14518
|
+
};
|
|
14519
|
+
function getThinkingCapability(provider, model2) {
|
|
14520
|
+
switch (provider) {
|
|
14521
|
+
case "anthropic":
|
|
14522
|
+
case "kimi-code":
|
|
14523
|
+
if (isAnthropicAdaptiveThinkingModel(model2)) return ANTHROPIC_ADAPTIVE_CAPABILITY;
|
|
14524
|
+
return isAnthropicThinkingModel(model2) ? ANTHROPIC_CAPABILITY : UNSUPPORTED;
|
|
14525
|
+
case "openai":
|
|
14526
|
+
return isOpenAIReasoningModel(model2) ? OPENAI_CAPABILITY : UNSUPPORTED;
|
|
14527
|
+
case "kimi":
|
|
14528
|
+
return isKimiThinkingModel(model2) ? KIMI_CAPABILITY : UNSUPPORTED;
|
|
14529
|
+
case "gemini":
|
|
14530
|
+
case "vertex":
|
|
14531
|
+
if (isGeminiLevelThinkingModel(model2)) return GEMINI_LEVEL_CAPABILITY;
|
|
14532
|
+
return isGeminiThinkingModel(model2) ? GEMINI_CAPABILITY : UNSUPPORTED;
|
|
14533
|
+
case "copilot":
|
|
14534
|
+
case "groq":
|
|
14535
|
+
case "openrouter":
|
|
14536
|
+
case "mistral":
|
|
14537
|
+
case "deepseek":
|
|
14538
|
+
case "together":
|
|
14539
|
+
case "huggingface":
|
|
14540
|
+
case "qwen":
|
|
14541
|
+
case "lmstudio":
|
|
14542
|
+
case "ollama":
|
|
14543
|
+
case "codex":
|
|
14544
|
+
return UNSUPPORTED;
|
|
14545
|
+
default:
|
|
14546
|
+
return UNSUPPORTED;
|
|
14547
|
+
}
|
|
14548
|
+
}
|
|
14549
|
+
function mapToAnthropic(mode, model2) {
|
|
13655
14550
|
if (!mode || mode === "off") return void 0;
|
|
13656
|
-
if (!isAnthropicThinkingModel(
|
|
14551
|
+
if (!isAnthropicThinkingModel(model2)) return void 0;
|
|
14552
|
+
if (isAnthropicAdaptiveThinkingModel(model2)) {
|
|
14553
|
+
return { type: "adaptive" };
|
|
14554
|
+
}
|
|
13657
14555
|
const cap = ANTHROPIC_CAPABILITY;
|
|
13658
14556
|
const { min, max } = cap.budgetRange;
|
|
13659
14557
|
if (typeof mode === "object") {
|
|
@@ -13669,9 +14567,20 @@ function mapToAnthropic(mode, model) {
|
|
|
13669
14567
|
if (budget === void 0) return void 0;
|
|
13670
14568
|
return { type: "enabled", budget_tokens: budget };
|
|
13671
14569
|
}
|
|
13672
|
-
function
|
|
14570
|
+
function mapToAnthropicEffort(mode, model2) {
|
|
14571
|
+
if (!mode || mode === "off" || mode === "auto") return void 0;
|
|
14572
|
+
if (!isAnthropicAdaptiveThinkingModel(model2)) return void 0;
|
|
14573
|
+
if (typeof mode === "object") {
|
|
14574
|
+
if (mode.budget <= 2048) return "low";
|
|
14575
|
+
if (mode.budget <= 8e3) return "medium";
|
|
14576
|
+
return "high";
|
|
14577
|
+
}
|
|
14578
|
+
if (mode === "low" || mode === "medium" || mode === "high") return mode;
|
|
14579
|
+
return void 0;
|
|
14580
|
+
}
|
|
14581
|
+
function mapToOpenAIEffort(mode, model2) {
|
|
13673
14582
|
if (!mode || mode === "off") return void 0;
|
|
13674
|
-
if (!isOpenAIReasoningModel(
|
|
14583
|
+
if (!isOpenAIReasoningModel(model2)) return void 0;
|
|
13675
14584
|
if (typeof mode === "object") {
|
|
13676
14585
|
const { budget } = mode;
|
|
13677
14586
|
if (budget <= 2048) return "low";
|
|
@@ -13682,8 +14591,9 @@ function mapToOpenAIEffort(mode, model) {
|
|
|
13682
14591
|
if (mode === "low" || mode === "medium" || mode === "high") return mode;
|
|
13683
14592
|
return void 0;
|
|
13684
14593
|
}
|
|
13685
|
-
function mapToGeminiBudget(mode,
|
|
13686
|
-
if (
|
|
14594
|
+
function mapToGeminiBudget(mode, model2) {
|
|
14595
|
+
if (isGeminiLevelThinkingModel(model2)) return void 0;
|
|
14596
|
+
if (!isGeminiThinkingModel(model2)) return void 0;
|
|
13687
14597
|
if (!mode) return void 0;
|
|
13688
14598
|
if (mode === "off") return 0;
|
|
13689
14599
|
if (mode === "auto") return -1;
|
|
@@ -13698,15 +14608,33 @@ function mapToGeminiBudget(mode, model) {
|
|
|
13698
14608
|
};
|
|
13699
14609
|
return budgetMap[mode];
|
|
13700
14610
|
}
|
|
13701
|
-
function
|
|
13702
|
-
if (
|
|
14611
|
+
function mapToGeminiThinkingConfig(mode, model2) {
|
|
14612
|
+
if (isGeminiLevelThinkingModel(model2)) {
|
|
14613
|
+
if (!mode || mode === "auto") return void 0;
|
|
14614
|
+
if (mode === "off") return { thinkingLevel: "low" };
|
|
14615
|
+
if (mode === "low" || mode === "medium" || mode === "high") {
|
|
14616
|
+
return { thinkingLevel: mode };
|
|
14617
|
+
}
|
|
14618
|
+
if (typeof mode === "object") {
|
|
14619
|
+
if (mode.budget <= 2048) return { thinkingLevel: "low" };
|
|
14620
|
+
if (mode.budget <= 8e3) return { thinkingLevel: "medium" };
|
|
14621
|
+
return { thinkingLevel: "high" };
|
|
14622
|
+
}
|
|
14623
|
+
return void 0;
|
|
14624
|
+
}
|
|
14625
|
+
const thinkingBudget = mapToGeminiBudget(mode, model2);
|
|
14626
|
+
return thinkingBudget !== void 0 ? { thinkingBudget } : void 0;
|
|
14627
|
+
}
|
|
14628
|
+
function mapToKimiExtraBody(mode, model2) {
|
|
14629
|
+
if (!isKimiThinkingModel(model2)) return void 0;
|
|
13703
14630
|
const effectiveMode = mode ?? "off";
|
|
13704
14631
|
const enabled = effectiveMode !== "off";
|
|
13705
14632
|
return { thinking: { type: enabled ? "enabled" : "disabled" } };
|
|
13706
14633
|
}
|
|
13707
14634
|
|
|
13708
14635
|
// src/providers/anthropic.ts
|
|
13709
|
-
|
|
14636
|
+
init_catalog();
|
|
14637
|
+
var DEFAULT_MODEL = getCatalogDefaultModel("anthropic");
|
|
13710
14638
|
var CONTEXT_WINDOWS = {
|
|
13711
14639
|
// Kimi Code model (Anthropic-compatible endpoint)
|
|
13712
14640
|
"kimi-for-coding": 131072,
|
|
@@ -13732,6 +14660,20 @@ var CONTEXT_WINDOWS = {
|
|
|
13732
14660
|
"claude-3-sonnet-20240229": 2e5,
|
|
13733
14661
|
"claude-3-haiku-20240307": 2e5
|
|
13734
14662
|
};
|
|
14663
|
+
function getAnthropicMaxTokens(baseMaxTokens, thinkingParam) {
|
|
14664
|
+
if (thinkingParam?.type === "enabled") {
|
|
14665
|
+
return Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024);
|
|
14666
|
+
}
|
|
14667
|
+
return baseMaxTokens;
|
|
14668
|
+
}
|
|
14669
|
+
function getAnthropicTemperature(thinkingParam, configuredTemperature) {
|
|
14670
|
+
if (thinkingParam?.type === "enabled") return 1;
|
|
14671
|
+
return configuredTemperature;
|
|
14672
|
+
}
|
|
14673
|
+
function getAnthropicOutputConfig(mode, model2) {
|
|
14674
|
+
const effort = mapToAnthropicEffort(mode, model2);
|
|
14675
|
+
return effort ? { effort } : void 0;
|
|
14676
|
+
}
|
|
13735
14677
|
var AnthropicProvider = class {
|
|
13736
14678
|
id;
|
|
13737
14679
|
name;
|
|
@@ -13766,19 +14708,22 @@ var AnthropicProvider = class {
|
|
|
13766
14708
|
this.ensureInitialized();
|
|
13767
14709
|
return withRetry(async () => {
|
|
13768
14710
|
try {
|
|
13769
|
-
const
|
|
13770
|
-
const thinkingParam = mapToAnthropic(options?.thinking,
|
|
14711
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
|
|
14712
|
+
const thinkingParam = mapToAnthropic(options?.thinking, model2);
|
|
14713
|
+
const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
|
|
13771
14714
|
const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
13772
14715
|
const response = await this.client.messages.create({
|
|
13773
|
-
model,
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
13777
|
-
|
|
14716
|
+
model: model2,
|
|
14717
|
+
max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
|
|
14718
|
+
temperature: getAnthropicTemperature(
|
|
14719
|
+
thinkingParam,
|
|
14720
|
+
options?.temperature ?? this.config.temperature ?? 0
|
|
14721
|
+
),
|
|
13778
14722
|
system: this.extractSystem(messages, options?.system),
|
|
13779
14723
|
messages: this.convertMessages(messages),
|
|
13780
14724
|
stop_sequences: options?.stopSequences,
|
|
13781
|
-
...thinkingParam && { thinking: thinkingParam }
|
|
14725
|
+
...thinkingParam && { thinking: thinkingParam },
|
|
14726
|
+
...outputConfig && { output_config: outputConfig }
|
|
13782
14727
|
});
|
|
13783
14728
|
return {
|
|
13784
14729
|
id: response.id,
|
|
@@ -13802,18 +14747,23 @@ var AnthropicProvider = class {
|
|
|
13802
14747
|
this.ensureInitialized();
|
|
13803
14748
|
return withRetry(async () => {
|
|
13804
14749
|
try {
|
|
13805
|
-
const
|
|
13806
|
-
const thinkingParam = mapToAnthropic(options?.thinking,
|
|
14750
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
|
|
14751
|
+
const thinkingParam = mapToAnthropic(options?.thinking, model2);
|
|
14752
|
+
const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
|
|
13807
14753
|
const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
13808
14754
|
const response = await this.client.messages.create({
|
|
13809
|
-
model,
|
|
13810
|
-
max_tokens:
|
|
13811
|
-
temperature:
|
|
14755
|
+
model: model2,
|
|
14756
|
+
max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
|
|
14757
|
+
temperature: getAnthropicTemperature(
|
|
14758
|
+
thinkingParam,
|
|
14759
|
+
options?.temperature ?? this.config.temperature ?? 0
|
|
14760
|
+
),
|
|
13812
14761
|
system: this.extractSystem(messages, options?.system),
|
|
13813
14762
|
messages: this.convertMessages(messages),
|
|
13814
14763
|
tools: this.convertTools(options.tools),
|
|
13815
14764
|
tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0,
|
|
13816
|
-
...thinkingParam && { thinking: thinkingParam }
|
|
14765
|
+
...thinkingParam && { thinking: thinkingParam },
|
|
14766
|
+
...outputConfig && { output_config: outputConfig }
|
|
13817
14767
|
});
|
|
13818
14768
|
const toolCalls = this.extractToolCalls(response.content);
|
|
13819
14769
|
return {
|
|
@@ -13839,17 +14789,22 @@ var AnthropicProvider = class {
|
|
|
13839
14789
|
this.ensureInitialized();
|
|
13840
14790
|
let timeoutTriggered = false;
|
|
13841
14791
|
try {
|
|
13842
|
-
const
|
|
13843
|
-
const thinkingParam = mapToAnthropic(options?.thinking,
|
|
14792
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
|
|
14793
|
+
const thinkingParam = mapToAnthropic(options?.thinking, model2);
|
|
14794
|
+
const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
|
|
13844
14795
|
const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
13845
14796
|
const stream = await this.client.messages.stream(
|
|
13846
14797
|
{
|
|
13847
|
-
model,
|
|
13848
|
-
max_tokens:
|
|
13849
|
-
temperature:
|
|
14798
|
+
model: model2,
|
|
14799
|
+
max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
|
|
14800
|
+
temperature: getAnthropicTemperature(
|
|
14801
|
+
thinkingParam,
|
|
14802
|
+
options?.temperature ?? this.config.temperature ?? 0
|
|
14803
|
+
),
|
|
13850
14804
|
system: this.extractSystem(messages, options?.system),
|
|
13851
14805
|
messages: this.convertMessages(messages),
|
|
13852
|
-
...thinkingParam && { thinking: thinkingParam }
|
|
14806
|
+
...thinkingParam && { thinking: thinkingParam },
|
|
14807
|
+
...outputConfig && { output_config: outputConfig }
|
|
13853
14808
|
},
|
|
13854
14809
|
{ signal: options?.signal }
|
|
13855
14810
|
);
|
|
@@ -13905,19 +14860,24 @@ var AnthropicProvider = class {
|
|
|
13905
14860
|
this.ensureInitialized();
|
|
13906
14861
|
let timeoutTriggered = false;
|
|
13907
14862
|
try {
|
|
13908
|
-
const
|
|
13909
|
-
const thinkingParam = mapToAnthropic(options?.thinking,
|
|
14863
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL;
|
|
14864
|
+
const thinkingParam = mapToAnthropic(options?.thinking, model2);
|
|
14865
|
+
const outputConfig = getAnthropicOutputConfig(options?.thinking, model2);
|
|
13910
14866
|
const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
13911
14867
|
const stream = await this.client.messages.stream(
|
|
13912
14868
|
{
|
|
13913
|
-
model,
|
|
13914
|
-
max_tokens:
|
|
13915
|
-
temperature:
|
|
14869
|
+
model: model2,
|
|
14870
|
+
max_tokens: getAnthropicMaxTokens(baseMaxTokens, thinkingParam),
|
|
14871
|
+
temperature: getAnthropicTemperature(
|
|
14872
|
+
thinkingParam,
|
|
14873
|
+
options?.temperature ?? this.config.temperature ?? 0
|
|
14874
|
+
),
|
|
13916
14875
|
system: this.extractSystem(messages, options?.system),
|
|
13917
14876
|
messages: this.convertMessages(messages),
|
|
13918
14877
|
tools: this.convertTools(options.tools),
|
|
13919
14878
|
tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0,
|
|
13920
|
-
...thinkingParam && { thinking: thinkingParam }
|
|
14879
|
+
...thinkingParam && { thinking: thinkingParam },
|
|
14880
|
+
...outputConfig && { output_config: outputConfig }
|
|
13921
14881
|
},
|
|
13922
14882
|
{ signal: options?.signal }
|
|
13923
14883
|
);
|
|
@@ -14042,33 +15002,38 @@ var AnthropicProvider = class {
|
|
|
14042
15002
|
*
|
|
14043
15003
|
* This heuristic analyzes the text to provide a better estimate.
|
|
14044
15004
|
*/
|
|
14045
|
-
countTokens(
|
|
14046
|
-
if (!
|
|
15005
|
+
countTokens(text2) {
|
|
15006
|
+
if (!text2) return 0;
|
|
14047
15007
|
const codePatterns = /[{}[\]();=<>!&|+\-*/]/g;
|
|
14048
15008
|
const whitespacePattern = /\s/g;
|
|
14049
15009
|
const wordPattern = /\b\w+\b/g;
|
|
14050
|
-
const codeChars = (
|
|
14051
|
-
const whitespace = (
|
|
14052
|
-
const words = (
|
|
14053
|
-
const isCodeLike = codeChars >
|
|
15010
|
+
const codeChars = (text2.match(codePatterns) || []).length;
|
|
15011
|
+
const whitespace = (text2.match(whitespacePattern) || []).length;
|
|
15012
|
+
const words = (text2.match(wordPattern) || []).length;
|
|
15013
|
+
const isCodeLike = codeChars > text2.length * 0.05;
|
|
14054
15014
|
let charsPerToken;
|
|
14055
15015
|
if (isCodeLike) {
|
|
14056
15016
|
charsPerToken = 3.5;
|
|
14057
|
-
} else if (whitespace >
|
|
15017
|
+
} else if (whitespace > text2.length * 0.3) {
|
|
14058
15018
|
charsPerToken = 5;
|
|
14059
15019
|
} else {
|
|
14060
15020
|
charsPerToken = 4.5;
|
|
14061
15021
|
}
|
|
14062
15022
|
const wordBasedEstimate = words * 1.3;
|
|
14063
|
-
const charBasedEstimate =
|
|
15023
|
+
const charBasedEstimate = text2.length / charsPerToken;
|
|
14064
15024
|
return Math.ceil((wordBasedEstimate + charBasedEstimate) / 2);
|
|
14065
15025
|
}
|
|
14066
15026
|
/**
|
|
14067
15027
|
* Get context window size
|
|
14068
15028
|
*/
|
|
14069
15029
|
getContextWindow() {
|
|
14070
|
-
const
|
|
14071
|
-
|
|
15030
|
+
const model2 = this.config.model ?? DEFAULT_MODEL;
|
|
15031
|
+
const provider = this.id === "kimi-code" ? "kimi-code" : "anthropic";
|
|
15032
|
+
const catalogWindow = getCatalogContextWindow(provider, model2, 0);
|
|
15033
|
+
if (catalogWindow > 0) {
|
|
15034
|
+
return catalogWindow;
|
|
15035
|
+
}
|
|
15036
|
+
return CONTEXT_WINDOWS[model2] ?? 2e5;
|
|
14072
15037
|
}
|
|
14073
15038
|
/**
|
|
14074
15039
|
* Check if provider is available
|
|
@@ -14109,8 +15074,8 @@ var AnthropicProvider = class {
|
|
|
14109
15074
|
const systemMsg = messages.find((m) => m.role === "system");
|
|
14110
15075
|
if (!systemMsg) return void 0;
|
|
14111
15076
|
if (typeof systemMsg.content === "string") return systemMsg.content;
|
|
14112
|
-
const
|
|
14113
|
-
return
|
|
15077
|
+
const text2 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
15078
|
+
return text2 || void 0;
|
|
14114
15079
|
}
|
|
14115
15080
|
/**
|
|
14116
15081
|
* Convert messages to Anthropic format
|
|
@@ -14318,15 +15283,15 @@ var ChatToolCallAssembler = class {
|
|
|
14318
15283
|
if (delta.function?.name) {
|
|
14319
15284
|
builder.name = delta.function.name;
|
|
14320
15285
|
}
|
|
14321
|
-
const
|
|
14322
|
-
if (!
|
|
14323
|
-
builder.arguments +=
|
|
15286
|
+
const text2 = delta.function?.arguments ?? "";
|
|
15287
|
+
if (!text2) return { started };
|
|
15288
|
+
builder.arguments += text2;
|
|
14324
15289
|
return {
|
|
14325
15290
|
started,
|
|
14326
15291
|
argumentDelta: {
|
|
14327
15292
|
id: builder.id,
|
|
14328
15293
|
name: builder.name,
|
|
14329
|
-
text
|
|
15294
|
+
text: text2
|
|
14330
15295
|
}
|
|
14331
15296
|
};
|
|
14332
15297
|
}
|
|
@@ -14503,45 +15468,46 @@ var EVAL_TIERS = [
|
|
|
14503
15468
|
{ prefix: "raptor", tier: "mini" },
|
|
14504
15469
|
{ prefix: "goldeneye", tier: "standard" }
|
|
14505
15470
|
];
|
|
14506
|
-
function matchTier(
|
|
14507
|
-
const lower =
|
|
15471
|
+
function matchTier(model2, table) {
|
|
15472
|
+
const lower = model2.toLowerCase();
|
|
14508
15473
|
const sorted = [...table].sort((a, b) => b.prefix.length - a.prefix.length);
|
|
14509
15474
|
for (const { prefix, tier } of sorted) {
|
|
14510
15475
|
if (lower.startsWith(prefix.toLowerCase())) return tier;
|
|
14511
15476
|
}
|
|
14512
15477
|
return null;
|
|
14513
15478
|
}
|
|
14514
|
-
function getModelTier(provider,
|
|
14515
|
-
if (!
|
|
15479
|
+
function getModelTier(provider, model2) {
|
|
15480
|
+
if (!model2) return "standard";
|
|
14516
15481
|
const p5 = provider.toLowerCase();
|
|
14517
15482
|
if (p5 === "anthropic") {
|
|
14518
|
-
return matchTier(
|
|
15483
|
+
return matchTier(model2, ANTHROPIC_TIERS) ?? "standard";
|
|
14519
15484
|
}
|
|
14520
15485
|
if (p5 === "kimi-code") {
|
|
14521
|
-
return matchTier(
|
|
15486
|
+
return matchTier(model2, KIMI_TIERS) ?? matchTier(model2, ANTHROPIC_TIERS) ?? "standard";
|
|
14522
15487
|
}
|
|
14523
15488
|
if (p5 === "openai" || p5 === "copilot" || p5 === "codex") {
|
|
14524
|
-
if (
|
|
14525
|
-
return matchTier(
|
|
15489
|
+
if (model2.startsWith("claude-")) {
|
|
15490
|
+
return matchTier(model2, ANTHROPIC_TIERS) ?? "standard";
|
|
14526
15491
|
}
|
|
14527
|
-
const evalMatch = matchTier(
|
|
15492
|
+
const evalMatch = matchTier(model2, EVAL_TIERS);
|
|
14528
15493
|
if (evalMatch) return evalMatch;
|
|
14529
|
-
return matchTier(
|
|
15494
|
+
return matchTier(model2, OPENAI_TIERS) ?? "standard";
|
|
14530
15495
|
}
|
|
14531
15496
|
if (p5 === "gemini" || p5 === "vertex") {
|
|
14532
|
-
return matchTier(
|
|
15497
|
+
return matchTier(model2, GEMINI_TIERS) ?? "standard";
|
|
14533
15498
|
}
|
|
14534
15499
|
if (p5 === "kimi" || p5 === "moonshot") {
|
|
14535
|
-
return matchTier(
|
|
15500
|
+
return matchTier(model2, KIMI_TIERS) ?? "standard";
|
|
14536
15501
|
}
|
|
14537
15502
|
return "standard";
|
|
14538
15503
|
}
|
|
14539
|
-
function getTierConfig(provider,
|
|
14540
|
-
return TIER_CONFIGS[getModelTier(provider,
|
|
15504
|
+
function getTierConfig(provider, model2) {
|
|
15505
|
+
return TIER_CONFIGS[getModelTier(provider, model2)];
|
|
14541
15506
|
}
|
|
14542
15507
|
|
|
14543
15508
|
// src/providers/openai.ts
|
|
14544
|
-
|
|
15509
|
+
init_catalog();
|
|
15510
|
+
var DEFAULT_MODEL2 = getCatalogDefaultModel("openai");
|
|
14545
15511
|
var CONTEXT_WINDOWS2 = {
|
|
14546
15512
|
// OpenAI models
|
|
14547
15513
|
"gpt-4o": 128e3,
|
|
@@ -14652,14 +15618,14 @@ var LOCAL_MODEL_PATTERNS = [
|
|
|
14652
15618
|
"starcoder"
|
|
14653
15619
|
];
|
|
14654
15620
|
var MODELS_WITH_THINKING_MODE = ["kimi-k2.5", "kimi-k2-0324", "kimi-latest"];
|
|
14655
|
-
function needsResponsesApi(
|
|
14656
|
-
return
|
|
15621
|
+
function needsResponsesApi(model2) {
|
|
15622
|
+
return model2.includes("codex") || model2.startsWith("gpt-5") || model2.startsWith("o4-") || model2 === "o3";
|
|
14657
15623
|
}
|
|
14658
|
-
function needsMaxCompletionTokens(
|
|
14659
|
-
return
|
|
15624
|
+
function needsMaxCompletionTokens(model2) {
|
|
15625
|
+
return model2.startsWith("o1") || model2.startsWith("o3") || model2.startsWith("o4") || model2.startsWith("gpt-4o") || model2.startsWith("gpt-4.1") || model2.startsWith("gpt-5") || model2.startsWith("chatgpt-4o");
|
|
14660
15626
|
}
|
|
14661
|
-
function buildMaxTokensParam(
|
|
14662
|
-
if (needsMaxCompletionTokens(
|
|
15627
|
+
function buildMaxTokensParam(model2, maxTokens) {
|
|
15628
|
+
if (needsMaxCompletionTokens(model2)) {
|
|
14663
15629
|
return { max_completion_tokens: maxTokens };
|
|
14664
15630
|
}
|
|
14665
15631
|
return { max_tokens: maxTokens };
|
|
@@ -14701,26 +15667,45 @@ var OpenAIProvider = class {
|
|
|
14701
15667
|
/**
|
|
14702
15668
|
* Check if a model supports temperature parameter
|
|
14703
15669
|
*/
|
|
14704
|
-
supportsTemperature(
|
|
14705
|
-
return !MODELS_WITHOUT_TEMPERATURE.some((m) =>
|
|
15670
|
+
supportsTemperature(model2) {
|
|
15671
|
+
return !MODELS_WITHOUT_TEMPERATURE.some((m) => model2.toLowerCase().includes(m.toLowerCase()));
|
|
14706
15672
|
}
|
|
14707
15673
|
/**
|
|
14708
15674
|
* Whether this provider instance supports the Responses API for the given model.
|
|
14709
15675
|
* Subclasses (e.g. CopilotProvider) can override to force Chat Completions
|
|
14710
15676
|
* when their endpoint does not expose /v1/responses.
|
|
14711
15677
|
*/
|
|
14712
|
-
modelNeedsResponsesApi(
|
|
14713
|
-
return needsResponsesApi(
|
|
15678
|
+
modelNeedsResponsesApi(model2) {
|
|
15679
|
+
return this.id === "openai" && needsResponsesApi(model2);
|
|
15680
|
+
}
|
|
15681
|
+
/**
|
|
15682
|
+
* Map thinking mode to Chat Completions reasoning_effort.
|
|
15683
|
+
* Subclasses can override when an OpenAI-compatible endpoint exposes GPT-5
|
|
15684
|
+
* models but cannot safely combine reasoning_effort with tool calls.
|
|
15685
|
+
*/
|
|
15686
|
+
getChatCompletionsReasoningEffort(model2, thinking, _hasTools) {
|
|
15687
|
+
const capability = getThinkingCapability(this.id, model2);
|
|
15688
|
+
if (!capability.supported || !capability.kinds.includes("effort")) {
|
|
15689
|
+
return void 0;
|
|
15690
|
+
}
|
|
15691
|
+
return mapToOpenAIEffort(thinking, model2);
|
|
15692
|
+
}
|
|
15693
|
+
getResponsesReasoningEffort(model2, thinking) {
|
|
15694
|
+
const capability = getThinkingCapability(this.id, model2);
|
|
15695
|
+
if (!capability.supported || !capability.kinds.includes("effort")) {
|
|
15696
|
+
return void 0;
|
|
15697
|
+
}
|
|
15698
|
+
return mapToOpenAIEffort(thinking, model2);
|
|
14714
15699
|
}
|
|
14715
15700
|
/**
|
|
14716
15701
|
* Get extra body parameters for API calls.
|
|
14717
15702
|
* Honors the user's ThinkingMode for Kimi models; defaults to disabled
|
|
14718
15703
|
* (preserving existing behavior) when no mode is specified.
|
|
14719
15704
|
*/
|
|
14720
|
-
getExtraBody(
|
|
14721
|
-
const kimiBody = mapToKimiExtraBody(thinking,
|
|
15705
|
+
getExtraBody(model2, thinking) {
|
|
15706
|
+
const kimiBody = mapToKimiExtraBody(thinking, model2);
|
|
14722
15707
|
if (kimiBody) return kimiBody;
|
|
14723
|
-
if (MODELS_WITH_THINKING_MODE.some((m) =>
|
|
15708
|
+
if (MODELS_WITH_THINKING_MODE.some((m) => model2.toLowerCase().includes(m.toLowerCase()))) {
|
|
14724
15709
|
return { thinking: { type: "disabled" } };
|
|
14725
15710
|
}
|
|
14726
15711
|
return void 0;
|
|
@@ -14730,18 +15715,22 @@ var OpenAIProvider = class {
|
|
|
14730
15715
|
*/
|
|
14731
15716
|
async chat(messages, options) {
|
|
14732
15717
|
this.ensureInitialized();
|
|
14733
|
-
const
|
|
14734
|
-
if (this.modelNeedsResponsesApi(
|
|
15718
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
15719
|
+
if (this.modelNeedsResponsesApi(model2)) {
|
|
14735
15720
|
return this.chatViaResponses(messages, options);
|
|
14736
15721
|
}
|
|
14737
15722
|
return withRetry(async () => {
|
|
14738
15723
|
try {
|
|
14739
|
-
const supportsTemp = this.supportsTemperature(
|
|
15724
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
14740
15725
|
const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
14741
|
-
const reasoningEffort =
|
|
15726
|
+
const reasoningEffort = this.getChatCompletionsReasoningEffort(
|
|
15727
|
+
model2,
|
|
15728
|
+
options?.thinking,
|
|
15729
|
+
false
|
|
15730
|
+
);
|
|
14742
15731
|
const response = await this.client.chat.completions.create({
|
|
14743
|
-
model,
|
|
14744
|
-
...buildMaxTokensParam(
|
|
15732
|
+
model: model2,
|
|
15733
|
+
...buildMaxTokensParam(model2, maxTokens),
|
|
14745
15734
|
messages: this.convertMessages(messages, options?.system),
|
|
14746
15735
|
stop: options?.stopSequences,
|
|
14747
15736
|
...supportsTemp && {
|
|
@@ -14770,21 +15759,25 @@ var OpenAIProvider = class {
|
|
|
14770
15759
|
*/
|
|
14771
15760
|
async chatWithTools(messages, options) {
|
|
14772
15761
|
this.ensureInitialized();
|
|
14773
|
-
const
|
|
14774
|
-
if (this.modelNeedsResponsesApi(
|
|
15762
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
15763
|
+
if (this.modelNeedsResponsesApi(model2)) {
|
|
14775
15764
|
return this.chatWithToolsViaResponses(messages, options);
|
|
14776
15765
|
}
|
|
14777
|
-
const tierCfg = getTierConfig(this.id,
|
|
15766
|
+
const tierCfg = getTierConfig(this.id, model2);
|
|
14778
15767
|
return withRetry(async () => {
|
|
14779
15768
|
try {
|
|
14780
|
-
const supportsTemp = this.supportsTemperature(
|
|
14781
|
-
const extraBody = this.getExtraBody(
|
|
14782
|
-
const reasoningEffort =
|
|
15769
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
15770
|
+
const extraBody = this.getExtraBody(model2, options?.thinking);
|
|
15771
|
+
const reasoningEffort = this.getChatCompletionsReasoningEffort(
|
|
15772
|
+
model2,
|
|
15773
|
+
options?.thinking,
|
|
15774
|
+
true
|
|
15775
|
+
);
|
|
14783
15776
|
const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
14784
15777
|
const tools = this.limitTools(options.tools, tierCfg.maxTools);
|
|
14785
15778
|
const requestParams = {
|
|
14786
|
-
model,
|
|
14787
|
-
...buildMaxTokensParam(
|
|
15779
|
+
model: model2,
|
|
15780
|
+
...buildMaxTokensParam(model2, maxTokens),
|
|
14788
15781
|
messages: this.convertMessages(messages, options?.system),
|
|
14789
15782
|
tools: this.convertTools(tools),
|
|
14790
15783
|
tool_choice: this.convertToolChoice(options.toolChoice),
|
|
@@ -14825,18 +15818,22 @@ var OpenAIProvider = class {
|
|
|
14825
15818
|
*/
|
|
14826
15819
|
async *stream(messages, options) {
|
|
14827
15820
|
this.ensureInitialized();
|
|
14828
|
-
const
|
|
14829
|
-
if (this.modelNeedsResponsesApi(
|
|
15821
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
15822
|
+
if (this.modelNeedsResponsesApi(model2)) {
|
|
14830
15823
|
yield* this.streamViaResponses(messages, options);
|
|
14831
15824
|
return;
|
|
14832
15825
|
}
|
|
14833
15826
|
try {
|
|
14834
|
-
const supportsTemp = this.supportsTemperature(
|
|
15827
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
14835
15828
|
const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
14836
|
-
const reasoningEffort =
|
|
15829
|
+
const reasoningEffort = this.getChatCompletionsReasoningEffort(
|
|
15830
|
+
model2,
|
|
15831
|
+
options?.thinking,
|
|
15832
|
+
false
|
|
15833
|
+
);
|
|
14837
15834
|
const stream = await this.client.chat.completions.create({
|
|
14838
|
-
model,
|
|
14839
|
-
...buildMaxTokensParam(
|
|
15835
|
+
model: model2,
|
|
15836
|
+
...buildMaxTokensParam(model2, maxTokens),
|
|
14840
15837
|
messages: this.convertMessages(messages, options?.system),
|
|
14841
15838
|
stream: true,
|
|
14842
15839
|
...supportsTemp && { temperature: options?.temperature ?? this.config.temperature ?? 0 },
|
|
@@ -14863,22 +15860,26 @@ var OpenAIProvider = class {
|
|
|
14863
15860
|
*/
|
|
14864
15861
|
async *streamWithTools(messages, options) {
|
|
14865
15862
|
this.ensureInitialized();
|
|
14866
|
-
const
|
|
14867
|
-
if (this.modelNeedsResponsesApi(
|
|
15863
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
15864
|
+
if (this.modelNeedsResponsesApi(model2)) {
|
|
14868
15865
|
yield* this.streamWithToolsViaResponses(messages, options);
|
|
14869
15866
|
return;
|
|
14870
15867
|
}
|
|
14871
|
-
const tierCfg = getTierConfig(this.id,
|
|
15868
|
+
const tierCfg = getTierConfig(this.id, model2);
|
|
14872
15869
|
let timeoutTriggered = false;
|
|
14873
15870
|
try {
|
|
14874
|
-
const supportsTemp = this.supportsTemperature(
|
|
14875
|
-
const extraBody = this.getExtraBody(
|
|
14876
|
-
const reasoningEffort =
|
|
15871
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
15872
|
+
const extraBody = this.getExtraBody(model2, options?.thinking);
|
|
15873
|
+
const reasoningEffort = this.getChatCompletionsReasoningEffort(
|
|
15874
|
+
model2,
|
|
15875
|
+
options?.thinking,
|
|
15876
|
+
true
|
|
15877
|
+
);
|
|
14877
15878
|
const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
|
|
14878
15879
|
const tools = this.limitTools(options.tools, tierCfg.maxTools);
|
|
14879
15880
|
const requestParams = {
|
|
14880
|
-
model,
|
|
14881
|
-
...buildMaxTokensParam(
|
|
15881
|
+
model: model2,
|
|
15882
|
+
...buildMaxTokensParam(model2, maxTokens),
|
|
14882
15883
|
messages: this.convertMessages(messages, options?.system),
|
|
14883
15884
|
tools: this.convertTools(tools),
|
|
14884
15885
|
tool_choice: this.convertToolChoice(options.toolChoice),
|
|
@@ -14999,13 +16000,13 @@ var OpenAIProvider = class {
|
|
|
14999
16000
|
* Check if current model is a local model (LM Studio, Ollama, etc.)
|
|
15000
16001
|
*/
|
|
15001
16002
|
isLocalModel() {
|
|
15002
|
-
const
|
|
16003
|
+
const model2 = (this.config.model ?? "").toLowerCase();
|
|
15003
16004
|
const baseUrl = (this.config.baseUrl ?? "").toLowerCase();
|
|
15004
16005
|
if (baseUrl.includes("localhost") || baseUrl.includes("127.0.0.1") || baseUrl.includes(":1234") || // LM Studio default
|
|
15005
16006
|
baseUrl.includes(":11434")) {
|
|
15006
16007
|
return true;
|
|
15007
16008
|
}
|
|
15008
|
-
return LOCAL_MODEL_PATTERNS.some((pattern) =>
|
|
16009
|
+
return LOCAL_MODEL_PATTERNS.some((pattern) => model2.includes(pattern));
|
|
15009
16010
|
}
|
|
15010
16011
|
/**
|
|
15011
16012
|
* Count tokens (improved heuristic for OpenAI and local models)
|
|
@@ -15025,23 +16026,23 @@ var OpenAIProvider = class {
|
|
|
15025
16026
|
* For accurate counting, use the model's native tokenizer.
|
|
15026
16027
|
* This heuristic provides a reasonable estimate without dependencies.
|
|
15027
16028
|
*/
|
|
15028
|
-
countTokens(
|
|
15029
|
-
if (!
|
|
16029
|
+
countTokens(text2) {
|
|
16030
|
+
if (!text2) return 0;
|
|
15030
16031
|
const codePatterns = /[{}[\]();=<>!&|+\-*/]/g;
|
|
15031
16032
|
const whitespacePattern = /\s/g;
|
|
15032
16033
|
const wordPattern = /\b\w+\b/g;
|
|
15033
16034
|
const nonAsciiPattern = /[^\x00-\x7F]/g;
|
|
15034
|
-
const codeChars = (
|
|
15035
|
-
const whitespace = (
|
|
15036
|
-
const words = (
|
|
15037
|
-
const nonAscii = (
|
|
15038
|
-
const isCodeLike = codeChars >
|
|
16035
|
+
const codeChars = (text2.match(codePatterns) || []).length;
|
|
16036
|
+
const whitespace = (text2.match(whitespacePattern) || []).length;
|
|
16037
|
+
const words = (text2.match(wordPattern) || []).length;
|
|
16038
|
+
const nonAscii = (text2.match(nonAsciiPattern) || []).length;
|
|
16039
|
+
const isCodeLike = codeChars > text2.length * 0.05;
|
|
15039
16040
|
const isLocal = this.isLocalModel();
|
|
15040
16041
|
let charsPerToken;
|
|
15041
16042
|
if (isLocal) {
|
|
15042
16043
|
if (isCodeLike) {
|
|
15043
16044
|
charsPerToken = 3.2;
|
|
15044
|
-
} else if (nonAscii >
|
|
16045
|
+
} else if (nonAscii > text2.length * 0.1) {
|
|
15045
16046
|
charsPerToken = 2;
|
|
15046
16047
|
} else {
|
|
15047
16048
|
charsPerToken = 3.5;
|
|
@@ -15049,7 +16050,7 @@ var OpenAIProvider = class {
|
|
|
15049
16050
|
} else {
|
|
15050
16051
|
if (isCodeLike) {
|
|
15051
16052
|
charsPerToken = 3.3;
|
|
15052
|
-
} else if (whitespace >
|
|
16053
|
+
} else if (whitespace > text2.length * 0.3) {
|
|
15053
16054
|
charsPerToken = 4.5;
|
|
15054
16055
|
} else {
|
|
15055
16056
|
charsPerToken = 4;
|
|
@@ -15057,7 +16058,7 @@ var OpenAIProvider = class {
|
|
|
15057
16058
|
}
|
|
15058
16059
|
const tokensPerWord = isLocal ? 1.4 : 1.3;
|
|
15059
16060
|
const wordBasedEstimate = words * tokensPerWord;
|
|
15060
|
-
const charBasedEstimate =
|
|
16061
|
+
const charBasedEstimate = text2.length / charsPerToken;
|
|
15061
16062
|
const weight = isCodeLike ? 0.7 : 0.5;
|
|
15062
16063
|
return Math.ceil(charBasedEstimate * weight + wordBasedEstimate * (1 - weight));
|
|
15063
16064
|
}
|
|
@@ -15069,11 +16070,15 @@ var OpenAIProvider = class {
|
|
|
15069
16070
|
* conventions (e.g., "qwen3-coder-8b" vs "qwen3-coder-8b-instruct").
|
|
15070
16071
|
*/
|
|
15071
16072
|
getContextWindow() {
|
|
15072
|
-
const
|
|
15073
|
-
if (CONTEXT_WINDOWS2[
|
|
15074
|
-
return CONTEXT_WINDOWS2[
|
|
16073
|
+
const model2 = this.config.model ?? DEFAULT_MODEL2;
|
|
16074
|
+
if (CONTEXT_WINDOWS2[model2]) {
|
|
16075
|
+
return CONTEXT_WINDOWS2[model2];
|
|
16076
|
+
}
|
|
16077
|
+
const catalogWindow = getCatalogContextWindow(this.id, model2, 0);
|
|
16078
|
+
if (catalogWindow > 0) {
|
|
16079
|
+
return catalogWindow;
|
|
15075
16080
|
}
|
|
15076
|
-
const modelLower =
|
|
16081
|
+
const modelLower = model2.toLowerCase();
|
|
15077
16082
|
for (const [key, value] of Object.entries(CONTEXT_WINDOWS2)) {
|
|
15078
16083
|
if (modelLower.includes(key.toLowerCase()) || key.toLowerCase().includes(modelLower)) {
|
|
15079
16084
|
return value;
|
|
@@ -15118,19 +16123,19 @@ var OpenAIProvider = class {
|
|
|
15118
16123
|
return true;
|
|
15119
16124
|
} catch {
|
|
15120
16125
|
try {
|
|
15121
|
-
const
|
|
15122
|
-
if (this.modelNeedsResponsesApi(
|
|
16126
|
+
const model2 = this.config.model || DEFAULT_MODEL2;
|
|
16127
|
+
if (this.modelNeedsResponsesApi(model2)) {
|
|
15123
16128
|
await this.client.responses.create({
|
|
15124
|
-
model,
|
|
16129
|
+
model: model2,
|
|
15125
16130
|
input: [{ role: "user", content: [{ type: "input_text", text: "Hi" }] }],
|
|
15126
16131
|
max_output_tokens: 1,
|
|
15127
16132
|
store: false
|
|
15128
16133
|
});
|
|
15129
16134
|
} else {
|
|
15130
16135
|
await this.client.chat.completions.create({
|
|
15131
|
-
model,
|
|
16136
|
+
model: model2,
|
|
15132
16137
|
messages: [{ role: "user", content: "Hi" }],
|
|
15133
|
-
...buildMaxTokensParam(
|
|
16138
|
+
...buildMaxTokensParam(model2, 1)
|
|
15134
16139
|
});
|
|
15135
16140
|
}
|
|
15136
16141
|
return true;
|
|
@@ -15367,12 +16372,12 @@ var OpenAIProvider = class {
|
|
|
15367
16372
|
this.ensureInitialized();
|
|
15368
16373
|
return withRetry(async () => {
|
|
15369
16374
|
try {
|
|
15370
|
-
const
|
|
16375
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
15371
16376
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
15372
|
-
const supportsTemp = this.supportsTemperature(
|
|
15373
|
-
const reasoningEffort =
|
|
16377
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
16378
|
+
const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
|
|
15374
16379
|
const response = await this.client.responses.create({
|
|
15375
|
-
model,
|
|
16380
|
+
model: model2,
|
|
15376
16381
|
input,
|
|
15377
16382
|
instructions: instructions ?? void 0,
|
|
15378
16383
|
max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
|
|
@@ -15405,16 +16410,16 @@ var OpenAIProvider = class {
|
|
|
15405
16410
|
this.ensureInitialized();
|
|
15406
16411
|
return withRetry(async () => {
|
|
15407
16412
|
try {
|
|
15408
|
-
const
|
|
15409
|
-
const tierCfg = getTierConfig(this.id,
|
|
16413
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
16414
|
+
const tierCfg = getTierConfig(this.id, model2);
|
|
15410
16415
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
15411
16416
|
const tools = this.convertToolsForResponses(
|
|
15412
16417
|
this.limitTools(options.tools, tierCfg.maxTools)
|
|
15413
16418
|
);
|
|
15414
|
-
const supportsTemp = this.supportsTemperature(
|
|
15415
|
-
const reasoningEffort =
|
|
16419
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
16420
|
+
const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
|
|
15416
16421
|
const response = await this.client.responses.create({
|
|
15417
|
-
model,
|
|
16422
|
+
model: model2,
|
|
15418
16423
|
input,
|
|
15419
16424
|
instructions: instructions ?? void 0,
|
|
15420
16425
|
tools,
|
|
@@ -15465,12 +16470,12 @@ var OpenAIProvider = class {
|
|
|
15465
16470
|
this.ensureInitialized();
|
|
15466
16471
|
let timeoutTriggered = false;
|
|
15467
16472
|
try {
|
|
15468
|
-
const
|
|
16473
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
15469
16474
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
15470
|
-
const supportsTemp = this.supportsTemperature(
|
|
15471
|
-
const reasoningEffort =
|
|
16475
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
16476
|
+
const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
|
|
15472
16477
|
const stream = await this.client.responses.create({
|
|
15473
|
-
model,
|
|
16478
|
+
model: model2,
|
|
15474
16479
|
input,
|
|
15475
16480
|
instructions: instructions ?? void 0,
|
|
15476
16481
|
max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
|
|
@@ -15529,15 +16534,15 @@ var OpenAIProvider = class {
|
|
|
15529
16534
|
this.ensureInitialized();
|
|
15530
16535
|
let timeoutTriggered = false;
|
|
15531
16536
|
try {
|
|
15532
|
-
const
|
|
15533
|
-
const tierCfg = getTierConfig(this.id,
|
|
16537
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
16538
|
+
const tierCfg = getTierConfig(this.id, model2);
|
|
15534
16539
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
15535
16540
|
const limitedTools = this.limitTools(options.tools, tierCfg.maxTools);
|
|
15536
16541
|
const tools = limitedTools.length > 0 ? this.convertToolsForResponses(limitedTools) : void 0;
|
|
15537
|
-
const supportsTemp = this.supportsTemperature(
|
|
15538
|
-
const reasoningEffort =
|
|
16542
|
+
const supportsTemp = this.supportsTemperature(model2);
|
|
16543
|
+
const reasoningEffort = this.getResponsesReasoningEffort(model2, options?.thinking);
|
|
15539
16544
|
const requestParams = {
|
|
15540
|
-
model,
|
|
16545
|
+
model: model2,
|
|
15541
16546
|
input,
|
|
15542
16547
|
instructions: instructions ?? void 0,
|
|
15543
16548
|
max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
|
|
@@ -15792,8 +16797,9 @@ function createKimiProvider(config) {
|
|
|
15792
16797
|
// src/providers/codex.ts
|
|
15793
16798
|
init_errors();
|
|
15794
16799
|
init_auth();
|
|
16800
|
+
init_catalog();
|
|
15795
16801
|
var CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
|
|
15796
|
-
var DEFAULT_MODEL3 = "
|
|
16802
|
+
var DEFAULT_MODEL3 = getCatalogDefaultModel("codex");
|
|
15797
16803
|
var CONTEXT_WINDOWS3 = {
|
|
15798
16804
|
"gpt-5.4-codex": 2e5,
|
|
15799
16805
|
"gpt-5.3-codex": 2e5,
|
|
@@ -15860,16 +16866,23 @@ var CodexProvider = class {
|
|
|
15860
16866
|
/**
|
|
15861
16867
|
* Get context window size for a model
|
|
15862
16868
|
*/
|
|
15863
|
-
getContextWindow(
|
|
15864
|
-
const m =
|
|
15865
|
-
|
|
16869
|
+
getContextWindow(model2) {
|
|
16870
|
+
const m = model2 ?? this.config.model ?? DEFAULT_MODEL3;
|
|
16871
|
+
if (CONTEXT_WINDOWS3[m]) {
|
|
16872
|
+
return CONTEXT_WINDOWS3[m];
|
|
16873
|
+
}
|
|
16874
|
+
const catalogWindow = getCatalogContextWindow("codex", m, 0);
|
|
16875
|
+
if (catalogWindow > 0) {
|
|
16876
|
+
return catalogWindow;
|
|
16877
|
+
}
|
|
16878
|
+
return 128e3;
|
|
15866
16879
|
}
|
|
15867
16880
|
/**
|
|
15868
16881
|
* Count tokens in text (approximate)
|
|
15869
16882
|
* Uses GPT-4 approximation: ~4 chars per token
|
|
15870
16883
|
*/
|
|
15871
|
-
countTokens(
|
|
15872
|
-
return Math.ceil(
|
|
16884
|
+
countTokens(text2) {
|
|
16885
|
+
return Math.ceil(text2.length / 4);
|
|
15873
16886
|
}
|
|
15874
16887
|
/**
|
|
15875
16888
|
* Check if provider is available (has valid OAuth tokens)
|
|
@@ -15997,9 +17010,9 @@ var CodexProvider = class {
|
|
|
15997
17010
|
/**
|
|
15998
17011
|
* Build the request body for the Codex Responses API
|
|
15999
17012
|
*/
|
|
16000
|
-
buildRequestBody(
|
|
17013
|
+
buildRequestBody(model2, input, instructions, options) {
|
|
16001
17014
|
const body = {
|
|
16002
|
-
model,
|
|
17015
|
+
model: model2,
|
|
16003
17016
|
input,
|
|
16004
17017
|
instructions: instructions ?? "You are a helpful coding assistant.",
|
|
16005
17018
|
store: false,
|
|
@@ -16064,9 +17077,9 @@ var CodexProvider = class {
|
|
|
16064
17077
|
*/
|
|
16065
17078
|
async chat(messages, options) {
|
|
16066
17079
|
return withRetry(async () => {
|
|
16067
|
-
const
|
|
17080
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
|
|
16068
17081
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
16069
|
-
const body = this.buildRequestBody(
|
|
17082
|
+
const body = this.buildRequestBody(model2, input, instructions, {
|
|
16070
17083
|
maxTokens: options?.maxTokens,
|
|
16071
17084
|
temperature: options?.temperature
|
|
16072
17085
|
});
|
|
@@ -16097,7 +17110,7 @@ var CodexProvider = class {
|
|
|
16097
17110
|
id: responseId,
|
|
16098
17111
|
content,
|
|
16099
17112
|
stopReason,
|
|
16100
|
-
model,
|
|
17113
|
+
model: model2,
|
|
16101
17114
|
usage: { inputTokens, outputTokens }
|
|
16102
17115
|
};
|
|
16103
17116
|
}, this.retryConfig);
|
|
@@ -16107,9 +17120,9 @@ var CodexProvider = class {
|
|
|
16107
17120
|
*/
|
|
16108
17121
|
async chatWithTools(messages, options) {
|
|
16109
17122
|
return withRetry(async () => {
|
|
16110
|
-
const
|
|
17123
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
|
|
16111
17124
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
16112
|
-
const body = this.buildRequestBody(
|
|
17125
|
+
const body = this.buildRequestBody(model2, input, instructions, {
|
|
16113
17126
|
tools: options.tools,
|
|
16114
17127
|
maxTokens: options?.maxTokens
|
|
16115
17128
|
});
|
|
@@ -16184,7 +17197,7 @@ var CodexProvider = class {
|
|
|
16184
17197
|
id: responseId,
|
|
16185
17198
|
content,
|
|
16186
17199
|
stopReason: toolCalls.length > 0 ? "tool_use" : "end_turn",
|
|
16187
|
-
model,
|
|
17200
|
+
model: model2,
|
|
16188
17201
|
usage: { inputTokens, outputTokens },
|
|
16189
17202
|
toolCalls
|
|
16190
17203
|
};
|
|
@@ -16194,9 +17207,9 @@ var CodexProvider = class {
|
|
|
16194
17207
|
* Stream a chat response (no tools)
|
|
16195
17208
|
*/
|
|
16196
17209
|
async *stream(messages, options) {
|
|
16197
|
-
const
|
|
17210
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
|
|
16198
17211
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
16199
|
-
const body = this.buildRequestBody(
|
|
17212
|
+
const body = this.buildRequestBody(model2, input, instructions, {
|
|
16200
17213
|
maxTokens: options?.maxTokens
|
|
16201
17214
|
});
|
|
16202
17215
|
const response = await this.makeRequest(body);
|
|
@@ -16256,9 +17269,9 @@ var CodexProvider = class {
|
|
|
16256
17269
|
* item_id which references the output item's id field, not call_id.
|
|
16257
17270
|
*/
|
|
16258
17271
|
async *streamWithTools(messages, options) {
|
|
16259
|
-
const
|
|
17272
|
+
const model2 = options?.model ?? this.config.model ?? DEFAULT_MODEL3;
|
|
16260
17273
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
16261
|
-
const body = this.buildRequestBody(
|
|
17274
|
+
const body = this.buildRequestBody(model2, input, instructions, {
|
|
16262
17275
|
tools: options.tools,
|
|
16263
17276
|
maxTokens: options?.maxTokens
|
|
16264
17277
|
});
|
|
@@ -16407,6 +17420,7 @@ var CodexProvider = class {
|
|
|
16407
17420
|
// src/providers/copilot.ts
|
|
16408
17421
|
init_errors();
|
|
16409
17422
|
init_copilot();
|
|
17423
|
+
init_catalog();
|
|
16410
17424
|
var CONTEXT_WINDOWS4 = {
|
|
16411
17425
|
// Claude models — Copilot API caps these at 168 000 (not 200 000 like Anthropic direct)
|
|
16412
17426
|
"claude-sonnet-4.6": 168e3,
|
|
@@ -16440,10 +17454,10 @@ var CONTEXT_WINDOWS4 = {
|
|
|
16440
17454
|
"raptor-mini": 4e5,
|
|
16441
17455
|
goldeneye: 4e5
|
|
16442
17456
|
};
|
|
16443
|
-
var DEFAULT_MODEL4 = "
|
|
16444
|
-
function normalizeModel(
|
|
16445
|
-
if (typeof
|
|
16446
|
-
const trimmed =
|
|
17457
|
+
var DEFAULT_MODEL4 = getCatalogDefaultModel("copilot");
|
|
17458
|
+
function normalizeModel(model2) {
|
|
17459
|
+
if (typeof model2 !== "string") return void 0;
|
|
17460
|
+
const trimmed = model2.trim();
|
|
16447
17461
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
16448
17462
|
}
|
|
16449
17463
|
var COPILOT_HEADERS = {
|
|
@@ -16550,16 +17564,31 @@ var CopilotProvider = class extends OpenAIProvider {
|
|
|
16550
17564
|
modelNeedsResponsesApi(_model) {
|
|
16551
17565
|
return false;
|
|
16552
17566
|
}
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
17567
|
+
/**
|
|
17568
|
+
* Copilot's OpenAI-compatible endpoint currently routes through
|
|
17569
|
+
* Chat Completions. For GPT-5.x models, combining function tools with
|
|
17570
|
+
* reasoning_effort is rejected by the upstream API. Keep tools working by
|
|
17571
|
+
* omitting reasoning_effort on tool calls instead of advertising a broken
|
|
17572
|
+
* combination.
|
|
17573
|
+
*/
|
|
17574
|
+
getChatCompletionsReasoningEffort(_model, _thinking, hasTools) {
|
|
17575
|
+
if (hasTools) return void 0;
|
|
17576
|
+
return void 0;
|
|
17577
|
+
}
|
|
17578
|
+
countTokens(text2) {
|
|
17579
|
+
if (!text2) return 0;
|
|
17580
|
+
return Math.ceil(text2.length / 3.5);
|
|
16556
17581
|
}
|
|
16557
17582
|
/**
|
|
16558
17583
|
* Get context window for the current model
|
|
16559
17584
|
*/
|
|
16560
17585
|
getContextWindow() {
|
|
16561
|
-
const
|
|
16562
|
-
|
|
17586
|
+
const model2 = this.config.model ?? DEFAULT_MODEL4;
|
|
17587
|
+
const catalogWindow = getCatalogContextWindow("copilot", model2, 0);
|
|
17588
|
+
if (catalogWindow > 0) {
|
|
17589
|
+
return catalogWindow;
|
|
17590
|
+
}
|
|
17591
|
+
return CONTEXT_WINDOWS4[model2] ?? 128e3;
|
|
16563
17592
|
}
|
|
16564
17593
|
/**
|
|
16565
17594
|
* Check if Copilot credentials are available
|
|
@@ -16576,7 +17605,8 @@ var CopilotProvider = class extends OpenAIProvider {
|
|
|
16576
17605
|
|
|
16577
17606
|
// src/providers/gemini.ts
|
|
16578
17607
|
init_errors();
|
|
16579
|
-
|
|
17608
|
+
init_catalog();
|
|
17609
|
+
var DEFAULT_MODEL5 = getCatalogDefaultModel("gemini");
|
|
16580
17610
|
var SKIP_THOUGHT_SIGNATURE_VALIDATOR = "skip_thought_signature_validator";
|
|
16581
17611
|
var CONTEXT_WINDOWS5 = {
|
|
16582
17612
|
"gemini-3.1-pro-preview": 1e6,
|
|
@@ -16640,9 +17670,9 @@ var GeminiProvider = class {
|
|
|
16640
17670
|
});
|
|
16641
17671
|
let streamStopReason = "end_turn";
|
|
16642
17672
|
for await (const chunk of stream) {
|
|
16643
|
-
const
|
|
16644
|
-
if (
|
|
16645
|
-
yield { type: "text", text };
|
|
17673
|
+
const text2 = chunk.text;
|
|
17674
|
+
if (text2) {
|
|
17675
|
+
yield { type: "text", text: text2 };
|
|
16646
17676
|
}
|
|
16647
17677
|
const finishReason = chunk.candidates?.[0]?.finishReason;
|
|
16648
17678
|
if (finishReason) {
|
|
@@ -16666,9 +17696,9 @@ var GeminiProvider = class {
|
|
|
16666
17696
|
let fallbackToolCounter = 0;
|
|
16667
17697
|
const emittedToolIds = /* @__PURE__ */ new Set();
|
|
16668
17698
|
for await (const chunk of stream) {
|
|
16669
|
-
const
|
|
16670
|
-
if (
|
|
16671
|
-
yield { type: "text", text };
|
|
17699
|
+
const text2 = chunk.text;
|
|
17700
|
+
if (text2) {
|
|
17701
|
+
yield { type: "text", text: text2 };
|
|
16672
17702
|
}
|
|
16673
17703
|
const toolCalls = this.extractToolCalls(chunk, { includeLegacyFunctionCalls: true });
|
|
16674
17704
|
for (const toolCall of toolCalls) {
|
|
@@ -16703,13 +17733,17 @@ var GeminiProvider = class {
|
|
|
16703
17733
|
throw this.handleError(error);
|
|
16704
17734
|
}
|
|
16705
17735
|
}
|
|
16706
|
-
countTokens(
|
|
16707
|
-
if (!
|
|
16708
|
-
return Math.ceil(
|
|
17736
|
+
countTokens(text2) {
|
|
17737
|
+
if (!text2) return 0;
|
|
17738
|
+
return Math.ceil(text2.length / 3.5);
|
|
16709
17739
|
}
|
|
16710
17740
|
getContextWindow() {
|
|
16711
|
-
const
|
|
16712
|
-
|
|
17741
|
+
const model2 = this.config.model ?? DEFAULT_MODEL5;
|
|
17742
|
+
const catalogWindow = getCatalogContextWindow("gemini", model2, 0);
|
|
17743
|
+
if (catalogWindow > 0) {
|
|
17744
|
+
return catalogWindow;
|
|
17745
|
+
}
|
|
17746
|
+
return CONTEXT_WINDOWS5[model2] ?? 1e6;
|
|
16713
17747
|
}
|
|
16714
17748
|
async isAvailable() {
|
|
16715
17749
|
if (!this.client) return false;
|
|
@@ -16730,20 +17764,20 @@ var GeminiProvider = class {
|
|
|
16730
17764
|
});
|
|
16731
17765
|
}
|
|
16732
17766
|
}
|
|
16733
|
-
getModel(
|
|
16734
|
-
return
|
|
17767
|
+
getModel(model2) {
|
|
17768
|
+
return model2 ?? this.config.model ?? DEFAULT_MODEL5;
|
|
16735
17769
|
}
|
|
16736
17770
|
buildConfig(messages, options, tools, toolChoice) {
|
|
16737
|
-
const
|
|
16738
|
-
const
|
|
17771
|
+
const model2 = this.getModel(options?.model);
|
|
17772
|
+
const thinkingConfig = mapToGeminiThinkingConfig(options?.thinking, model2);
|
|
16739
17773
|
const config = {
|
|
16740
17774
|
maxOutputTokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
|
|
16741
17775
|
temperature: options?.temperature ?? this.config.temperature ?? 0,
|
|
16742
17776
|
stopSequences: options?.stopSequences,
|
|
16743
17777
|
systemInstruction: this.extractSystem(messages, options?.system)
|
|
16744
17778
|
};
|
|
16745
|
-
if (
|
|
16746
|
-
config.thinkingConfig =
|
|
17779
|
+
if (thinkingConfig !== void 0) {
|
|
17780
|
+
config.thinkingConfig = thinkingConfig;
|
|
16747
17781
|
}
|
|
16748
17782
|
if (tools && tools.length > 0) {
|
|
16749
17783
|
config.tools = [{ functionDeclarations: this.convertTools(tools) }];
|
|
@@ -16758,8 +17792,8 @@ var GeminiProvider = class {
|
|
|
16758
17792
|
const systemMsg = messages.find((m) => m.role === "system");
|
|
16759
17793
|
if (!systemMsg) return void 0;
|
|
16760
17794
|
if (typeof systemMsg.content === "string") return systemMsg.content;
|
|
16761
|
-
const
|
|
16762
|
-
return
|
|
17795
|
+
const text2 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
17796
|
+
return text2 || void 0;
|
|
16763
17797
|
}
|
|
16764
17798
|
convertContents(messages) {
|
|
16765
17799
|
const toolNameByUseId = this.buildToolUseNameMap(messages);
|
|
@@ -16882,7 +17916,7 @@ var GeminiProvider = class {
|
|
|
16882
17916
|
})
|
|
16883
17917
|
}));
|
|
16884
17918
|
}
|
|
16885
|
-
parseResponse(response,
|
|
17919
|
+
parseResponse(response, model2) {
|
|
16886
17920
|
const usage = response.usageMetadata;
|
|
16887
17921
|
return {
|
|
16888
17922
|
id: `gemini-${Date.now()}`,
|
|
@@ -16892,10 +17926,10 @@ var GeminiProvider = class {
|
|
|
16892
17926
|
inputTokens: usage?.promptTokenCount ?? 0,
|
|
16893
17927
|
outputTokens: usage?.candidatesTokenCount ?? 0
|
|
16894
17928
|
},
|
|
16895
|
-
model: this.getModel(
|
|
17929
|
+
model: this.getModel(model2)
|
|
16896
17930
|
};
|
|
16897
17931
|
}
|
|
16898
|
-
parseResponseWithTools(response,
|
|
17932
|
+
parseResponseWithTools(response, model2) {
|
|
16899
17933
|
const usage = response.usageMetadata;
|
|
16900
17934
|
const toolCalls = this.extractToolCalls(response, { includeLegacyFunctionCalls: true });
|
|
16901
17935
|
return {
|
|
@@ -16906,7 +17940,7 @@ var GeminiProvider = class {
|
|
|
16906
17940
|
inputTokens: usage?.promptTokenCount ?? 0,
|
|
16907
17941
|
outputTokens: usage?.candidatesTokenCount ?? 0
|
|
16908
17942
|
},
|
|
16909
|
-
model: this.getModel(
|
|
17943
|
+
model: this.getModel(model2),
|
|
16910
17944
|
toolCalls
|
|
16911
17945
|
};
|
|
16912
17946
|
}
|
|
@@ -16945,7 +17979,8 @@ var GeminiProvider = class {
|
|
|
16945
17979
|
// src/providers/vertex.ts
|
|
16946
17980
|
init_errors();
|
|
16947
17981
|
init_gcloud();
|
|
16948
|
-
|
|
17982
|
+
init_catalog();
|
|
17983
|
+
var DEFAULT_MODEL6 = getCatalogDefaultModel("vertex");
|
|
16949
17984
|
var DEFAULT_BASE_URL = "https://aiplatform.googleapis.com/v1";
|
|
16950
17985
|
var DEFAULT_LOCATION = "global";
|
|
16951
17986
|
var CONTEXT_WINDOWS6 = {
|
|
@@ -17091,11 +18126,16 @@ var VertexProvider = class {
|
|
|
17091
18126
|
}
|
|
17092
18127
|
yield { type: "done", stopReason };
|
|
17093
18128
|
}
|
|
17094
|
-
countTokens(
|
|
17095
|
-
return Math.ceil(
|
|
18129
|
+
countTokens(text2) {
|
|
18130
|
+
return Math.ceil(text2.length / 4);
|
|
17096
18131
|
}
|
|
17097
18132
|
getContextWindow() {
|
|
17098
|
-
|
|
18133
|
+
const model2 = this.config.model ?? DEFAULT_MODEL6;
|
|
18134
|
+
const catalogWindow = getCatalogContextWindow("vertex", model2, 0);
|
|
18135
|
+
if (catalogWindow > 0) {
|
|
18136
|
+
return catalogWindow;
|
|
18137
|
+
}
|
|
18138
|
+
return CONTEXT_WINDOWS6[model2] ?? 1048576;
|
|
17099
18139
|
}
|
|
17100
18140
|
async isAvailable() {
|
|
17101
18141
|
try {
|
|
@@ -17112,8 +18152,8 @@ var VertexProvider = class {
|
|
|
17112
18152
|
});
|
|
17113
18153
|
}
|
|
17114
18154
|
}
|
|
17115
|
-
getModel(
|
|
17116
|
-
return
|
|
18155
|
+
getModel(model2) {
|
|
18156
|
+
return model2 ?? this.config.model ?? DEFAULT_MODEL6;
|
|
17117
18157
|
}
|
|
17118
18158
|
getResolvedBaseUrl() {
|
|
17119
18159
|
if (this.config.baseUrl && this.config.baseUrl.trim()) {
|
|
@@ -17124,9 +18164,9 @@ var VertexProvider = class {
|
|
|
17124
18164
|
}
|
|
17125
18165
|
return `https://${encodeURIComponent(this.location)}-aiplatform.googleapis.com/v1`;
|
|
17126
18166
|
}
|
|
17127
|
-
buildEndpoint(
|
|
18167
|
+
buildEndpoint(model2, stream = false) {
|
|
17128
18168
|
const action = stream ? "streamGenerateContent?alt=sse" : "generateContent";
|
|
17129
|
-
return `${this.getResolvedBaseUrl()}/projects/${encodeURIComponent(this.project)}/locations/${encodeURIComponent(this.location)}/publishers/google/models/${encodeURIComponent(this.getModel(
|
|
18169
|
+
return `${this.getResolvedBaseUrl()}/projects/${encodeURIComponent(this.project)}/locations/${encodeURIComponent(this.location)}/publishers/google/models/${encodeURIComponent(this.getModel(model2))}:${action}`;
|
|
17130
18170
|
}
|
|
17131
18171
|
async getHeaders() {
|
|
17132
18172
|
if (this.apiKey?.trim()) {
|
|
@@ -17154,8 +18194,8 @@ var VertexProvider = class {
|
|
|
17154
18194
|
const systemMsg = messages.find((m) => m.role === "system");
|
|
17155
18195
|
if (!systemMsg) return void 0;
|
|
17156
18196
|
if (typeof systemMsg.content === "string") return systemMsg.content;
|
|
17157
|
-
const
|
|
17158
|
-
return
|
|
18197
|
+
const text2 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
18198
|
+
return text2 || void 0;
|
|
17159
18199
|
}
|
|
17160
18200
|
buildToolUseNameMap(messages) {
|
|
17161
18201
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -17338,21 +18378,21 @@ var VertexProvider = class {
|
|
|
17338
18378
|
}
|
|
17339
18379
|
}
|
|
17340
18380
|
}
|
|
17341
|
-
parseResponse(response,
|
|
18381
|
+
parseResponse(response, model2) {
|
|
17342
18382
|
const candidate = response.candidates?.[0];
|
|
17343
|
-
const
|
|
18383
|
+
const text2 = (candidate?.content?.parts ?? []).filter((part) => part.text).map((part) => part.text).join("");
|
|
17344
18384
|
return {
|
|
17345
18385
|
id: `vertex-${Date.now()}`,
|
|
17346
|
-
content:
|
|
18386
|
+
content: text2,
|
|
17347
18387
|
stopReason: this.mapFinishReason(candidate?.finishReason),
|
|
17348
18388
|
usage: {
|
|
17349
18389
|
inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
|
|
17350
18390
|
outputTokens: response.usageMetadata?.candidatesTokenCount ?? 0
|
|
17351
18391
|
},
|
|
17352
|
-
model: this.getModel(
|
|
18392
|
+
model: this.getModel(model2)
|
|
17353
18393
|
};
|
|
17354
18394
|
}
|
|
17355
|
-
parseResponseWithTools(response,
|
|
18395
|
+
parseResponseWithTools(response, model2) {
|
|
17356
18396
|
const candidate = response.candidates?.[0];
|
|
17357
18397
|
const parts = candidate?.content?.parts ?? [];
|
|
17358
18398
|
const toolCalls = [];
|
|
@@ -17380,7 +18420,7 @@ var VertexProvider = class {
|
|
|
17380
18420
|
inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
|
|
17381
18421
|
outputTokens: response.usageMetadata?.candidatesTokenCount ?? 0
|
|
17382
18422
|
},
|
|
17383
|
-
model: this.getModel(
|
|
18423
|
+
model: this.getModel(model2),
|
|
17384
18424
|
toolCalls
|
|
17385
18425
|
};
|
|
17386
18426
|
}
|
|
@@ -17409,6 +18449,10 @@ var VertexProvider = class {
|
|
|
17409
18449
|
}
|
|
17410
18450
|
};
|
|
17411
18451
|
|
|
18452
|
+
// src/providers/pricing.ts
|
|
18453
|
+
init_catalog();
|
|
18454
|
+
getCatalogModelPricingMap();
|
|
18455
|
+
|
|
17412
18456
|
// src/providers/circuit-breaker.ts
|
|
17413
18457
|
init_errors();
|
|
17414
18458
|
var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
|
|
@@ -17614,8 +18658,8 @@ var ResilientProvider = class {
|
|
|
17614
18658
|
async *streamWithTools(messages, options) {
|
|
17615
18659
|
yield* this.streamWithPolicy(() => this.provider.streamWithTools(messages, options));
|
|
17616
18660
|
}
|
|
17617
|
-
countTokens(
|
|
17618
|
-
return this.provider.countTokens(
|
|
18661
|
+
countTokens(text2) {
|
|
18662
|
+
return this.provider.countTokens(text2);
|
|
17619
18663
|
}
|
|
17620
18664
|
getContextWindow() {
|
|
17621
18665
|
return this.provider.getContextWindow();
|
|
@@ -17701,13 +18745,16 @@ function createResilientProvider(provider, config) {
|
|
|
17701
18745
|
return new ResilientProvider(provider, getDefaultResilienceConfig(provider.id));
|
|
17702
18746
|
}
|
|
17703
18747
|
|
|
18748
|
+
// src/providers/runtime-capabilities.ts
|
|
18749
|
+
init_catalog();
|
|
18750
|
+
|
|
17704
18751
|
// src/providers/index.ts
|
|
17705
18752
|
init_copilot();
|
|
17706
18753
|
init_errors();
|
|
17707
18754
|
init_env();
|
|
17708
|
-
function normalizeProviderModel(
|
|
17709
|
-
if (typeof
|
|
17710
|
-
const trimmed =
|
|
18755
|
+
function normalizeProviderModel(model2) {
|
|
18756
|
+
if (typeof model2 !== "string") return void 0;
|
|
18757
|
+
const trimmed = model2.trim();
|
|
17711
18758
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
17712
18759
|
}
|
|
17713
18760
|
function normalizeOptional(value) {
|
|
@@ -17916,9 +18963,9 @@ function createInitialState(config) {
|
|
|
17916
18963
|
}
|
|
17917
18964
|
async function loadExistingState(projectPath) {
|
|
17918
18965
|
try {
|
|
17919
|
-
const
|
|
18966
|
+
const fs41 = await import('fs/promises');
|
|
17920
18967
|
const statePath = `${projectPath}/.coco/state/project.json`;
|
|
17921
|
-
const content = await
|
|
18968
|
+
const content = await fs41.readFile(statePath, "utf-8");
|
|
17922
18969
|
const data = JSON.parse(content);
|
|
17923
18970
|
data.createdAt = new Date(data.createdAt);
|
|
17924
18971
|
data.updatedAt = new Date(data.updatedAt);
|
|
@@ -17928,13 +18975,13 @@ async function loadExistingState(projectPath) {
|
|
|
17928
18975
|
}
|
|
17929
18976
|
}
|
|
17930
18977
|
async function saveState(state) {
|
|
17931
|
-
const
|
|
18978
|
+
const fs41 = await import('fs/promises');
|
|
17932
18979
|
const statePath = `${state.path}/.coco/state`;
|
|
17933
|
-
await
|
|
18980
|
+
await fs41.mkdir(statePath, { recursive: true });
|
|
17934
18981
|
const filePath = `${statePath}/project.json`;
|
|
17935
18982
|
const tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
17936
|
-
await
|
|
17937
|
-
await
|
|
18983
|
+
await fs41.writeFile(tmpPath, JSON.stringify(state, null, 2), "utf-8");
|
|
18984
|
+
await fs41.rename(tmpPath, filePath);
|
|
17938
18985
|
}
|
|
17939
18986
|
function getPhaseExecutor(phase) {
|
|
17940
18987
|
switch (phase) {
|
|
@@ -17993,35 +19040,35 @@ async function createPhaseContext(config, state) {
|
|
|
17993
19040
|
};
|
|
17994
19041
|
const tools = {
|
|
17995
19042
|
file: {
|
|
17996
|
-
async read(
|
|
17997
|
-
const
|
|
17998
|
-
return
|
|
19043
|
+
async read(path44) {
|
|
19044
|
+
const fs41 = await import('fs/promises');
|
|
19045
|
+
return fs41.readFile(path44, "utf-8");
|
|
17999
19046
|
},
|
|
18000
|
-
async write(
|
|
18001
|
-
const
|
|
19047
|
+
async write(path44, content) {
|
|
19048
|
+
const fs41 = await import('fs/promises');
|
|
18002
19049
|
const nodePath = await import('path');
|
|
18003
|
-
await
|
|
18004
|
-
await
|
|
19050
|
+
await fs41.mkdir(nodePath.dirname(path44), { recursive: true });
|
|
19051
|
+
await fs41.writeFile(path44, content, "utf-8");
|
|
18005
19052
|
},
|
|
18006
|
-
async exists(
|
|
18007
|
-
const
|
|
19053
|
+
async exists(path44) {
|
|
19054
|
+
const fs41 = await import('fs/promises');
|
|
18008
19055
|
try {
|
|
18009
|
-
await
|
|
19056
|
+
await fs41.access(path44);
|
|
18010
19057
|
return true;
|
|
18011
19058
|
} catch {
|
|
18012
19059
|
return false;
|
|
18013
19060
|
}
|
|
18014
19061
|
},
|
|
18015
19062
|
async glob(pattern) {
|
|
18016
|
-
const { glob:
|
|
18017
|
-
return
|
|
19063
|
+
const { glob: glob18 } = await import('glob');
|
|
19064
|
+
return glob18(pattern, { cwd: state.path });
|
|
18018
19065
|
}
|
|
18019
19066
|
},
|
|
18020
19067
|
bash: {
|
|
18021
19068
|
async exec(command, options = {}) {
|
|
18022
|
-
const { execa:
|
|
19069
|
+
const { execa: execa12 } = await import('execa');
|
|
18023
19070
|
try {
|
|
18024
|
-
const result = await
|
|
19071
|
+
const result = await execa12(command, {
|
|
18025
19072
|
shell: true,
|
|
18026
19073
|
cwd: options.cwd || state.path,
|
|
18027
19074
|
timeout: options.timeout,
|
|
@@ -18044,8 +19091,8 @@ async function createPhaseContext(config, state) {
|
|
|
18044
19091
|
},
|
|
18045
19092
|
git: {
|
|
18046
19093
|
async status() {
|
|
18047
|
-
const { execa:
|
|
18048
|
-
const result = await
|
|
19094
|
+
const { execa: execa12 } = await import('execa');
|
|
19095
|
+
const result = await execa12("git", ["status", "--porcelain", "-b"], { cwd: state.path });
|
|
18049
19096
|
const lines = result.stdout.split("\n");
|
|
18050
19097
|
const branchLine = lines[0] || "";
|
|
18051
19098
|
const branch = branchLine.replace("## ", "").split("...")[0] || "main";
|
|
@@ -18058,24 +19105,24 @@ async function createPhaseContext(config, state) {
|
|
|
18058
19105
|
};
|
|
18059
19106
|
},
|
|
18060
19107
|
async commit(message, files) {
|
|
18061
|
-
const { execa:
|
|
19108
|
+
const { execa: execa12 } = await import('execa');
|
|
18062
19109
|
if (files && files.length > 0) {
|
|
18063
|
-
await
|
|
19110
|
+
await execa12("git", ["add", ...files], { cwd: state.path });
|
|
18064
19111
|
}
|
|
18065
|
-
await
|
|
19112
|
+
await execa12("git", ["commit", "-m", message], { cwd: state.path });
|
|
18066
19113
|
},
|
|
18067
19114
|
async push() {
|
|
18068
|
-
const { execa:
|
|
18069
|
-
await
|
|
19115
|
+
const { execa: execa12 } = await import('execa');
|
|
19116
|
+
await execa12("git", ["push"], { cwd: state.path });
|
|
18070
19117
|
}
|
|
18071
19118
|
},
|
|
18072
19119
|
test: {
|
|
18073
19120
|
async run(pattern) {
|
|
18074
|
-
const { execa:
|
|
19121
|
+
const { execa: execa12 } = await import('execa');
|
|
18075
19122
|
try {
|
|
18076
19123
|
const args = ["test", "--reporter=json"];
|
|
18077
19124
|
if (pattern) args.push(pattern);
|
|
18078
|
-
await
|
|
19125
|
+
await execa12("pnpm", args, { cwd: state.path });
|
|
18079
19126
|
return {
|
|
18080
19127
|
passed: 0,
|
|
18081
19128
|
failed: 0,
|
|
@@ -18155,9 +19202,9 @@ async function createSnapshot(state) {
|
|
|
18155
19202
|
var MAX_CHECKPOINT_VERSIONS = 5;
|
|
18156
19203
|
async function getCheckpointFiles(state, phase) {
|
|
18157
19204
|
try {
|
|
18158
|
-
const
|
|
19205
|
+
const fs41 = await import('fs/promises');
|
|
18159
19206
|
const checkpointDir = `${state.path}/.coco/checkpoints`;
|
|
18160
|
-
const files = await
|
|
19207
|
+
const files = await fs41.readdir(checkpointDir);
|
|
18161
19208
|
const phaseFiles = files.filter((f) => f.startsWith(`snapshot-pre-${phase}-`) && f.endsWith(".json")).sort((a, b) => {
|
|
18162
19209
|
const tsA = parseInt(a.split("-").pop()?.replace(".json", "") ?? "0", 10);
|
|
18163
19210
|
const tsB = parseInt(b.split("-").pop()?.replace(".json", "") ?? "0", 10);
|
|
@@ -18170,11 +19217,11 @@ async function getCheckpointFiles(state, phase) {
|
|
|
18170
19217
|
}
|
|
18171
19218
|
async function cleanupOldCheckpoints(state, phase) {
|
|
18172
19219
|
try {
|
|
18173
|
-
const
|
|
19220
|
+
const fs41 = await import('fs/promises');
|
|
18174
19221
|
const files = await getCheckpointFiles(state, phase);
|
|
18175
19222
|
if (files.length > MAX_CHECKPOINT_VERSIONS) {
|
|
18176
19223
|
const filesToDelete = files.slice(MAX_CHECKPOINT_VERSIONS);
|
|
18177
|
-
await Promise.all(filesToDelete.map((f) =>
|
|
19224
|
+
await Promise.all(filesToDelete.map((f) => fs41.unlink(f).catch(() => {
|
|
18178
19225
|
})));
|
|
18179
19226
|
}
|
|
18180
19227
|
} catch {
|
|
@@ -18182,13 +19229,13 @@ async function cleanupOldCheckpoints(state, phase) {
|
|
|
18182
19229
|
}
|
|
18183
19230
|
async function saveSnapshot(state, snapshotId) {
|
|
18184
19231
|
try {
|
|
18185
|
-
const
|
|
19232
|
+
const fs41 = await import('fs/promises');
|
|
18186
19233
|
const snapshotPath = `${state.path}/.coco/checkpoints/snapshot-${snapshotId}.json`;
|
|
18187
19234
|
const snapshotDir = `${state.path}/.coco/checkpoints`;
|
|
18188
|
-
await
|
|
19235
|
+
await fs41.mkdir(snapshotDir, { recursive: true });
|
|
18189
19236
|
const createdAt = state.createdAt instanceof Date ? state.createdAt.toISOString() : String(state.createdAt);
|
|
18190
19237
|
const updatedAt = state.updatedAt instanceof Date ? state.updatedAt.toISOString() : String(state.updatedAt);
|
|
18191
|
-
await
|
|
19238
|
+
await fs41.writeFile(
|
|
18192
19239
|
snapshotPath,
|
|
18193
19240
|
JSON.stringify(
|
|
18194
19241
|
{
|
|
@@ -19395,15 +20442,15 @@ ${message}
|
|
|
19395
20442
|
let stdoutBuffer = "";
|
|
19396
20443
|
let stderrBuffer = "";
|
|
19397
20444
|
subprocess.stdout?.on("data", (chunk) => {
|
|
19398
|
-
const
|
|
19399
|
-
stdoutBuffer +=
|
|
19400
|
-
process.stdout.write(
|
|
20445
|
+
const text2 = chunk.toString();
|
|
20446
|
+
stdoutBuffer += text2;
|
|
20447
|
+
process.stdout.write(text2);
|
|
19401
20448
|
heartbeat.activity();
|
|
19402
20449
|
});
|
|
19403
20450
|
subprocess.stderr?.on("data", (chunk) => {
|
|
19404
|
-
const
|
|
19405
|
-
stderrBuffer +=
|
|
19406
|
-
process.stderr.write(
|
|
20451
|
+
const text2 = chunk.toString();
|
|
20452
|
+
stderrBuffer += text2;
|
|
20453
|
+
process.stderr.write(text2);
|
|
19407
20454
|
heartbeat.activity();
|
|
19408
20455
|
});
|
|
19409
20456
|
const result = await subprocess;
|
|
@@ -20888,7 +21935,7 @@ Examples:
|
|
|
20888
21935
|
}
|
|
20889
21936
|
});
|
|
20890
21937
|
async function findSourceFiles(cwd) {
|
|
20891
|
-
const { glob:
|
|
21938
|
+
const { glob: glob18 } = await import('glob');
|
|
20892
21939
|
let isJava = false;
|
|
20893
21940
|
try {
|
|
20894
21941
|
await fs16__default.access(path17__default.join(cwd, "pom.xml"));
|
|
@@ -20906,12 +21953,12 @@ async function findSourceFiles(cwd) {
|
|
|
20906
21953
|
}
|
|
20907
21954
|
}
|
|
20908
21955
|
if (isJava) {
|
|
20909
|
-
return
|
|
21956
|
+
return glob18("src/main/java/**/*.java", {
|
|
20910
21957
|
cwd,
|
|
20911
21958
|
absolute: true
|
|
20912
21959
|
});
|
|
20913
21960
|
}
|
|
20914
|
-
return
|
|
21961
|
+
return glob18("src/**/*.{ts,js,tsx,jsx}", {
|
|
20915
21962
|
cwd,
|
|
20916
21963
|
absolute: true,
|
|
20917
21964
|
ignore: ["**/*.test.*", "**/*.spec.*", "**/node_modules/**"]
|
|
@@ -21424,15 +22471,15 @@ ${message}
|
|
|
21424
22471
|
let stdoutBuffer = "";
|
|
21425
22472
|
let stderrBuffer = "";
|
|
21426
22473
|
subprocess.stdout?.on("data", (chunk) => {
|
|
21427
|
-
const
|
|
21428
|
-
stdoutBuffer +=
|
|
21429
|
-
process.stdout.write(
|
|
22474
|
+
const text2 = chunk.toString();
|
|
22475
|
+
stdoutBuffer += text2;
|
|
22476
|
+
process.stdout.write(text2);
|
|
21430
22477
|
heartbeat.activity();
|
|
21431
22478
|
});
|
|
21432
22479
|
subprocess.stderr?.on("data", (chunk) => {
|
|
21433
|
-
const
|
|
21434
|
-
stderrBuffer +=
|
|
21435
|
-
process.stderr.write(
|
|
22480
|
+
const text2 = chunk.toString();
|
|
22481
|
+
stderrBuffer += text2;
|
|
22482
|
+
process.stderr.write(text2);
|
|
21436
22483
|
heartbeat.activity();
|
|
21437
22484
|
});
|
|
21438
22485
|
const result = await subprocess;
|
|
@@ -21549,15 +22596,15 @@ ${message}
|
|
|
21549
22596
|
let stdoutBuffer = "";
|
|
21550
22597
|
let stderrBuffer = "";
|
|
21551
22598
|
subprocess.stdout?.on("data", (chunk) => {
|
|
21552
|
-
const
|
|
21553
|
-
stdoutBuffer +=
|
|
21554
|
-
process.stdout.write(
|
|
22599
|
+
const text2 = chunk.toString();
|
|
22600
|
+
stdoutBuffer += text2;
|
|
22601
|
+
process.stdout.write(text2);
|
|
21555
22602
|
heartbeat.activity();
|
|
21556
22603
|
});
|
|
21557
22604
|
subprocess.stderr?.on("data", (chunk) => {
|
|
21558
|
-
const
|
|
21559
|
-
stderrBuffer +=
|
|
21560
|
-
process.stderr.write(
|
|
22605
|
+
const text2 = chunk.toString();
|
|
22606
|
+
stderrBuffer += text2;
|
|
22607
|
+
process.stderr.write(text2);
|
|
21561
22608
|
heartbeat.activity();
|
|
21562
22609
|
});
|
|
21563
22610
|
const result = await subprocess;
|
|
@@ -21651,15 +22698,15 @@ ${message}
|
|
|
21651
22698
|
let stdoutBuffer = "";
|
|
21652
22699
|
let stderrBuffer = "";
|
|
21653
22700
|
subprocess.stdout?.on("data", (chunk) => {
|
|
21654
|
-
const
|
|
21655
|
-
stdoutBuffer +=
|
|
21656
|
-
process.stdout.write(
|
|
22701
|
+
const text2 = chunk.toString();
|
|
22702
|
+
stdoutBuffer += text2;
|
|
22703
|
+
process.stdout.write(text2);
|
|
21657
22704
|
heartbeat.activity();
|
|
21658
22705
|
});
|
|
21659
22706
|
subprocess.stderr?.on("data", (chunk) => {
|
|
21660
|
-
const
|
|
21661
|
-
stderrBuffer +=
|
|
21662
|
-
process.stderr.write(
|
|
22707
|
+
const text2 = chunk.toString();
|
|
22708
|
+
stderrBuffer += text2;
|
|
22709
|
+
process.stderr.write(text2);
|
|
21663
22710
|
heartbeat.activity();
|
|
21664
22711
|
});
|
|
21665
22712
|
const result = await subprocess;
|
|
@@ -21754,15 +22801,15 @@ ${message}
|
|
|
21754
22801
|
let stdoutBuffer = "";
|
|
21755
22802
|
let stderrBuffer = "";
|
|
21756
22803
|
subprocess.stdout?.on("data", (chunk) => {
|
|
21757
|
-
const
|
|
21758
|
-
stdoutBuffer +=
|
|
21759
|
-
process.stdout.write(
|
|
22804
|
+
const text2 = chunk.toString();
|
|
22805
|
+
stdoutBuffer += text2;
|
|
22806
|
+
process.stdout.write(text2);
|
|
21760
22807
|
heartbeat.activity();
|
|
21761
22808
|
});
|
|
21762
22809
|
subprocess.stderr?.on("data", (chunk) => {
|
|
21763
|
-
const
|
|
21764
|
-
stderrBuffer +=
|
|
21765
|
-
process.stderr.write(
|
|
22810
|
+
const text2 = chunk.toString();
|
|
22811
|
+
stderrBuffer += text2;
|
|
22812
|
+
process.stderr.write(text2);
|
|
21766
22813
|
heartbeat.activity();
|
|
21767
22814
|
});
|
|
21768
22815
|
const result = await subprocess;
|
|
@@ -21858,15 +22905,15 @@ ${message}
|
|
|
21858
22905
|
let stdoutBuffer = "";
|
|
21859
22906
|
let stderrBuffer = "";
|
|
21860
22907
|
subprocess.stdout?.on("data", (chunk) => {
|
|
21861
|
-
const
|
|
21862
|
-
stdoutBuffer +=
|
|
21863
|
-
process.stdout.write(
|
|
22908
|
+
const text2 = chunk.toString();
|
|
22909
|
+
stdoutBuffer += text2;
|
|
22910
|
+
process.stdout.write(text2);
|
|
21864
22911
|
heartbeat.activity();
|
|
21865
22912
|
});
|
|
21866
22913
|
subprocess.stderr?.on("data", (chunk) => {
|
|
21867
|
-
const
|
|
21868
|
-
stderrBuffer +=
|
|
21869
|
-
process.stderr.write(
|
|
22914
|
+
const text2 = chunk.toString();
|
|
22915
|
+
stderrBuffer += text2;
|
|
22916
|
+
process.stderr.write(text2);
|
|
21870
22917
|
heartbeat.activity();
|
|
21871
22918
|
});
|
|
21872
22919
|
const result = await subprocess;
|
|
@@ -21945,15 +22992,15 @@ ${message}
|
|
|
21945
22992
|
let stdoutBuffer = "";
|
|
21946
22993
|
let stderrBuffer = "";
|
|
21947
22994
|
subprocess.stdout?.on("data", (chunk) => {
|
|
21948
|
-
const
|
|
21949
|
-
stdoutBuffer +=
|
|
21950
|
-
process.stdout.write(
|
|
22995
|
+
const text2 = chunk.toString();
|
|
22996
|
+
stdoutBuffer += text2;
|
|
22997
|
+
process.stdout.write(text2);
|
|
21951
22998
|
heartbeat.activity();
|
|
21952
22999
|
});
|
|
21953
23000
|
subprocess.stderr?.on("data", (chunk) => {
|
|
21954
|
-
const
|
|
21955
|
-
stderrBuffer +=
|
|
21956
|
-
process.stderr.write(
|
|
23001
|
+
const text2 = chunk.toString();
|
|
23002
|
+
stderrBuffer += text2;
|
|
23003
|
+
process.stderr.write(text2);
|
|
21957
23004
|
heartbeat.activity();
|
|
21958
23005
|
});
|
|
21959
23006
|
const result = await subprocess;
|
|
@@ -22012,6 +23059,12 @@ z.object({
|
|
|
22012
23059
|
"allowed-tools": z.union([z.string(), z.array(z.string())]).optional(),
|
|
22013
23060
|
"argument-hint": z.string().optional(),
|
|
22014
23061
|
compatibility: z.string().max(500).optional(),
|
|
23062
|
+
triggers: z.union([z.string(), z.array(z.string())]).optional(),
|
|
23063
|
+
risk: z.enum(["read-only", "write", "network", "destructive", "secrets-sensitive"]).optional(),
|
|
23064
|
+
"supported-agents": z.union([
|
|
23065
|
+
z.enum(["coco", "claude", "codex", "gemini", "opencode"]),
|
|
23066
|
+
z.array(z.enum(["coco", "claude", "codex", "gemini", "opencode"]))
|
|
23067
|
+
]).optional(),
|
|
22015
23068
|
model: z.string().optional(),
|
|
22016
23069
|
context: z.enum(["fork", "agent", "inline"]).optional(),
|
|
22017
23070
|
// Top-level tags/author (skills.sh style) — also accepted inside metadata
|
|
@@ -22814,16 +23867,16 @@ function htmlToMarkdown(html) {
|
|
|
22814
23867
|
const prefix = "#".repeat(i);
|
|
22815
23868
|
const regex = new RegExp(`<h${i}[^>]*>([\\s\\S]*?)<\\/h${i}>`, "gi");
|
|
22816
23869
|
md = md.replace(regex, (_, content) => {
|
|
22817
|
-
const
|
|
22818
|
-
return
|
|
23870
|
+
const text2 = content.replace(/<[^>]*>/g, "").trim();
|
|
23871
|
+
return text2 ? `
|
|
22819
23872
|
|
|
22820
|
-
${prefix} ${
|
|
23873
|
+
${prefix} ${text2}
|
|
22821
23874
|
|
|
22822
23875
|
` : "";
|
|
22823
23876
|
});
|
|
22824
23877
|
}
|
|
22825
|
-
md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href,
|
|
22826
|
-
const cleanText =
|
|
23878
|
+
md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href, text2) => {
|
|
23879
|
+
const cleanText = text2.replace(/<[^>]*>/g, "").trim();
|
|
22827
23880
|
if (!cleanText) return "";
|
|
22828
23881
|
if (href.startsWith("#") || href.startsWith("javascript:")) return cleanText;
|
|
22829
23882
|
return `[${cleanText}](${href})`;
|
|
@@ -22850,8 +23903,8 @@ ${decoded.trim()}
|
|
|
22850
23903
|
});
|
|
22851
23904
|
md = md.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (_, items) => {
|
|
22852
23905
|
return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
|
|
22853
|
-
const
|
|
22854
|
-
return
|
|
23906
|
+
const text2 = item.replace(/<[^>]*>/g, "").trim();
|
|
23907
|
+
return text2 ? `- ${text2}
|
|
22855
23908
|
` : "";
|
|
22856
23909
|
}) + "\n";
|
|
22857
23910
|
});
|
|
@@ -22859,29 +23912,29 @@ ${decoded.trim()}
|
|
|
22859
23912
|
let counter = 0;
|
|
22860
23913
|
return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
|
|
22861
23914
|
counter++;
|
|
22862
|
-
const
|
|
22863
|
-
return
|
|
23915
|
+
const text2 = item.replace(/<[^>]*>/g, "").trim();
|
|
23916
|
+
return text2 ? `${counter}. ${text2}
|
|
22864
23917
|
` : "";
|
|
22865
23918
|
}) + "\n";
|
|
22866
23919
|
});
|
|
22867
23920
|
md = md.replace(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/gi, (_, content) => {
|
|
22868
|
-
const
|
|
22869
|
-
return
|
|
23921
|
+
const text2 = content.replace(/<[^>]*>/g, "").trim();
|
|
23922
|
+
return text2 ? "\n" + text2.split("\n").map((line) => `> ${line.trim()}`).join("\n") + "\n" : "";
|
|
22870
23923
|
});
|
|
22871
23924
|
md = md.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, (_, content) => {
|
|
22872
|
-
const
|
|
22873
|
-
return
|
|
23925
|
+
const text2 = content.replace(/<[^>]*>/g, "").trim();
|
|
23926
|
+
return text2 ? `
|
|
22874
23927
|
|
|
22875
|
-
${
|
|
23928
|
+
${text2}
|
|
22876
23929
|
|
|
22877
23930
|
` : "";
|
|
22878
23931
|
});
|
|
22879
23932
|
md = md.replace(/<br\s*\/?>/gi, "\n");
|
|
22880
23933
|
md = md.replace(
|
|
22881
23934
|
/<(?:strong|b)[^>]*>([\s\S]*?)<\/(?:strong|b)>/gi,
|
|
22882
|
-
(_,
|
|
23935
|
+
(_, text2) => `**${text2.trim()}**`
|
|
22883
23936
|
);
|
|
22884
|
-
md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_,
|
|
23937
|
+
md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_, text2) => `*${text2.trim()}*`);
|
|
22885
23938
|
md = md.replace(/<hr\s*\/?>/gi, "\n---\n");
|
|
22886
23939
|
md = md.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, tableContent) => {
|
|
22887
23940
|
const rows = [];
|
|
@@ -23563,9 +24616,9 @@ async function fileExists(filePath) {
|
|
|
23563
24616
|
return false;
|
|
23564
24617
|
}
|
|
23565
24618
|
}
|
|
23566
|
-
async function fileExists2(
|
|
24619
|
+
async function fileExists2(path44) {
|
|
23567
24620
|
try {
|
|
23568
|
-
await access(
|
|
24621
|
+
await access(path44);
|
|
23569
24622
|
return true;
|
|
23570
24623
|
} catch {
|
|
23571
24624
|
return false;
|
|
@@ -23655,7 +24708,7 @@ async function detectMaturity(cwd) {
|
|
|
23655
24708
|
if (!hasLintConfig && hasPackageJson) {
|
|
23656
24709
|
try {
|
|
23657
24710
|
const pkgRaw = await import('fs/promises').then(
|
|
23658
|
-
(
|
|
24711
|
+
(fs41) => fs41.readFile(join(cwd, "package.json"), "utf-8")
|
|
23659
24712
|
);
|
|
23660
24713
|
const pkg = JSON.parse(pkgRaw);
|
|
23661
24714
|
if (pkg.scripts?.lint || pkg.scripts?.["lint:fix"]) {
|
|
@@ -24499,9 +25552,10 @@ Examples:
|
|
|
24499
25552
|
exclude: z.array(z.string()).optional().describe("Additional patterns to exclude"),
|
|
24500
25553
|
languages: z.array(z.enum(["typescript", "javascript", "python", "java", "go", "rust"])).optional().describe("Languages to parse (auto-detected if not specified)"),
|
|
24501
25554
|
maxFiles: z.number().min(1).max(1e3).optional().default(DEFAULT_MAX_FILES).describe("Maximum files to process"),
|
|
24502
|
-
depth: z.enum(["overview", "detailed"]).optional().default("overview").describe("Level of detail")
|
|
25555
|
+
depth: z.enum(["overview", "detailed"]).optional().default("overview").describe("Level of detail"),
|
|
25556
|
+
includeTests: z.boolean().optional().default(false).describe("Include test/spec files in the map")
|
|
24503
25557
|
}),
|
|
24504
|
-
async execute({ path: rootPath, include, exclude, languages, maxFiles, depth }) {
|
|
25558
|
+
async execute({ path: rootPath, include, exclude, languages, maxFiles, depth, includeTests }) {
|
|
24505
25559
|
const startTime = performance.now();
|
|
24506
25560
|
const absPath = path27.resolve(rootPath);
|
|
24507
25561
|
try {
|
|
@@ -24529,7 +25583,12 @@ Examples:
|
|
|
24529
25583
|
const allExts = Object.values(LANGUAGE_EXTENSIONS).flat();
|
|
24530
25584
|
pattern = `**/*{${allExts.join(",")}}`;
|
|
24531
25585
|
}
|
|
24532
|
-
const excludePatterns = [
|
|
25586
|
+
const excludePatterns = [
|
|
25587
|
+
...DEFAULT_EXCLUDES.filter(
|
|
25588
|
+
(pattern2) => includeTests ? !pattern2.includes("*.test.") && !pattern2.includes("*.spec.") : true
|
|
25589
|
+
),
|
|
25590
|
+
...exclude ?? []
|
|
25591
|
+
];
|
|
24533
25592
|
const files = await glob14(pattern, {
|
|
24534
25593
|
cwd: absPath,
|
|
24535
25594
|
ignore: excludePatterns,
|
|
@@ -25027,10 +26086,10 @@ function chunkContent(content, chunkSize) {
|
|
|
25027
26086
|
const chunks = [];
|
|
25028
26087
|
for (let i = 0; i < lines.length; i += chunkSize) {
|
|
25029
26088
|
const chunkLines = lines.slice(i, Math.min(i + chunkSize, lines.length));
|
|
25030
|
-
const
|
|
25031
|
-
if (
|
|
26089
|
+
const text2 = chunkLines.join("\n").trim();
|
|
26090
|
+
if (text2.length > 10) {
|
|
25032
26091
|
chunks.push({
|
|
25033
|
-
text,
|
|
26092
|
+
text: text2,
|
|
25034
26093
|
startLine: i + 1,
|
|
25035
26094
|
endLine: Math.min(i + chunkSize, lines.length)
|
|
25036
26095
|
});
|
|
@@ -25038,8 +26097,8 @@ function chunkContent(content, chunkSize) {
|
|
|
25038
26097
|
}
|
|
25039
26098
|
return chunks;
|
|
25040
26099
|
}
|
|
25041
|
-
function simpleEmbedding(
|
|
25042
|
-
const words =
|
|
26100
|
+
function simpleEmbedding(text2) {
|
|
26101
|
+
const words = text2.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((w) => w.length > 1);
|
|
25043
26102
|
const freq = /* @__PURE__ */ new Map();
|
|
25044
26103
|
for (const word of words) {
|
|
25045
26104
|
freq.set(word, (freq.get(word) ?? 0) + 1);
|
|
@@ -25065,7 +26124,7 @@ function simpleEmbedding(text) {
|
|
|
25065
26124
|
}
|
|
25066
26125
|
var embedFn = null;
|
|
25067
26126
|
var usingFallbackEmbedding = false;
|
|
25068
|
-
async function getEmbedding(
|
|
26127
|
+
async function getEmbedding(text2) {
|
|
25069
26128
|
if (!embedFn) {
|
|
25070
26129
|
try {
|
|
25071
26130
|
const transformers = await import('@xenova/transformers');
|
|
@@ -25082,7 +26141,7 @@ async function getEmbedding(text) {
|
|
|
25082
26141
|
usingFallbackEmbedding = true;
|
|
25083
26142
|
}
|
|
25084
26143
|
}
|
|
25085
|
-
return embedFn(
|
|
26144
|
+
return embedFn(text2);
|
|
25086
26145
|
}
|
|
25087
26146
|
async function loadIndex2(indexDir) {
|
|
25088
26147
|
try {
|
|
@@ -25629,23 +26688,23 @@ Examples:
|
|
|
25629
26688
|
const pdfData = await pdfParse.default(dataBuffer, {
|
|
25630
26689
|
max: maxPages
|
|
25631
26690
|
});
|
|
25632
|
-
let
|
|
26691
|
+
let text2 = pdfData.text;
|
|
25633
26692
|
let truncated = false;
|
|
25634
26693
|
const totalPages = pdfData.numpages;
|
|
25635
26694
|
if (pages) {
|
|
25636
26695
|
const range = parsePageRange(pages, totalPages);
|
|
25637
|
-
const pageTexts =
|
|
26696
|
+
const pageTexts = text2.split(/\f/);
|
|
25638
26697
|
if (pageTexts.length > 1) {
|
|
25639
26698
|
const selectedPages = pageTexts.slice(range.start - 1, range.end);
|
|
25640
|
-
|
|
26699
|
+
text2 = selectedPages.join("\n\n--- Page Break ---\n\n");
|
|
25641
26700
|
}
|
|
25642
26701
|
}
|
|
25643
|
-
if (
|
|
25644
|
-
|
|
26702
|
+
if (text2.length > 5e5) {
|
|
26703
|
+
text2 = text2.slice(0, 5e5);
|
|
25645
26704
|
truncated = true;
|
|
25646
26705
|
}
|
|
25647
26706
|
return {
|
|
25648
|
-
text,
|
|
26707
|
+
text: text2,
|
|
25649
26708
|
pages: totalPages,
|
|
25650
26709
|
metadata: {
|
|
25651
26710
|
title: pdfData.info?.Title,
|
|
@@ -25744,14 +26803,14 @@ Examples:
|
|
|
25744
26803
|
const mimeType = MIME_TYPES[ext] ?? "image/png";
|
|
25745
26804
|
const selectedProvider = provider ?? "anthropic";
|
|
25746
26805
|
let description;
|
|
25747
|
-
let
|
|
26806
|
+
let model2;
|
|
25748
26807
|
try {
|
|
25749
26808
|
if (selectedProvider === "anthropic") {
|
|
25750
|
-
|
|
26809
|
+
model2 = "claude-sonnet-4-20250514";
|
|
25751
26810
|
const { default: Anthropic2 } = await import('@anthropic-ai/sdk');
|
|
25752
26811
|
const client = new Anthropic2();
|
|
25753
26812
|
const response = await client.messages.create({
|
|
25754
|
-
model,
|
|
26813
|
+
model: model2,
|
|
25755
26814
|
max_tokens: 4096,
|
|
25756
26815
|
messages: [
|
|
25757
26816
|
{
|
|
@@ -25775,7 +26834,7 @@ Examples:
|
|
|
25775
26834
|
});
|
|
25776
26835
|
description = response.content.filter((block) => block.type === "text").map((block) => block.text).join("\n") || "No description generated";
|
|
25777
26836
|
} else if (selectedProvider === "openai") {
|
|
25778
|
-
|
|
26837
|
+
model2 = "gpt-4o";
|
|
25779
26838
|
const { default: OpenAI3 } = await import('openai');
|
|
25780
26839
|
const client = new OpenAI3();
|
|
25781
26840
|
const openaiMessages = [
|
|
@@ -25796,13 +26855,13 @@ Examples:
|
|
|
25796
26855
|
}
|
|
25797
26856
|
];
|
|
25798
26857
|
const response = await client.chat.completions.create({
|
|
25799
|
-
model,
|
|
26858
|
+
model: model2,
|
|
25800
26859
|
max_tokens: 4096,
|
|
25801
26860
|
messages: openaiMessages
|
|
25802
26861
|
});
|
|
25803
26862
|
description = response.choices[0]?.message?.content ?? "No description generated";
|
|
25804
26863
|
} else if (selectedProvider === "gemini") {
|
|
25805
|
-
|
|
26864
|
+
model2 = "gemini-2.0-flash";
|
|
25806
26865
|
const { GoogleGenAI: GoogleGenAI2 } = await import('@google/genai');
|
|
25807
26866
|
const apiKey = process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
|
|
25808
26867
|
if (!apiKey) {
|
|
@@ -25813,7 +26872,7 @@ Examples:
|
|
|
25813
26872
|
}
|
|
25814
26873
|
const genAI = new GoogleGenAI2({ apiKey });
|
|
25815
26874
|
const result = await genAI.models.generateContent({
|
|
25816
|
-
model,
|
|
26875
|
+
model: model2,
|
|
25817
26876
|
contents: [
|
|
25818
26877
|
{
|
|
25819
26878
|
role: "user",
|
|
@@ -25856,7 +26915,7 @@ Examples:
|
|
|
25856
26915
|
return {
|
|
25857
26916
|
description,
|
|
25858
26917
|
provider: selectedProvider,
|
|
25859
|
-
model,
|
|
26918
|
+
model: model2,
|
|
25860
26919
|
duration: performance.now() - startTime,
|
|
25861
26920
|
imageSize: imageBuffer.length,
|
|
25862
26921
|
format: ext.slice(1)
|
|
@@ -26136,8 +27195,8 @@ async function analyzeFile(filePath, includeAst = false) {
|
|
|
26136
27195
|
};
|
|
26137
27196
|
}
|
|
26138
27197
|
async function analyzeDirectory(dirPath) {
|
|
26139
|
-
const { glob:
|
|
26140
|
-
const files = await
|
|
27198
|
+
const { glob: glob18 } = await import('glob');
|
|
27199
|
+
const files = await glob18("**/*.{ts,tsx,js,jsx}", {
|
|
26141
27200
|
cwd: dirPath,
|
|
26142
27201
|
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
|
|
26143
27202
|
absolute: true
|
|
@@ -26209,6 +27268,329 @@ var analyzeDirectoryTool = defineTool({
|
|
|
26209
27268
|
}
|
|
26210
27269
|
});
|
|
26211
27270
|
var codeAnalyzerTools = [analyzeFileTool, analyzeDirectoryTool];
|
|
27271
|
+
var SOURCE_GLOBS = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.mjs", "**/*.cjs"];
|
|
27272
|
+
var DEFAULT_EXCLUDES3 = [
|
|
27273
|
+
"**/node_modules/**",
|
|
27274
|
+
"**/.git/**",
|
|
27275
|
+
"**/dist/**",
|
|
27276
|
+
"**/build/**",
|
|
27277
|
+
"**/coverage/**",
|
|
27278
|
+
"**/*.d.ts"
|
|
27279
|
+
];
|
|
27280
|
+
async function commandAvailable(command) {
|
|
27281
|
+
try {
|
|
27282
|
+
await execa(command, ["--version"], { timeout: 3e3 });
|
|
27283
|
+
return true;
|
|
27284
|
+
} catch {
|
|
27285
|
+
return false;
|
|
27286
|
+
}
|
|
27287
|
+
}
|
|
27288
|
+
async function getSourceFiles(root, maxFiles) {
|
|
27289
|
+
const files = await glob(SOURCE_GLOBS, {
|
|
27290
|
+
cwd: root,
|
|
27291
|
+
absolute: false,
|
|
27292
|
+
ignore: DEFAULT_EXCLUDES3,
|
|
27293
|
+
nodir: true
|
|
27294
|
+
});
|
|
27295
|
+
return files.slice(0, maxFiles);
|
|
27296
|
+
}
|
|
27297
|
+
async function getFileSymbols(filePath) {
|
|
27298
|
+
const absolutePath = path17__default.resolve(filePath);
|
|
27299
|
+
const content = await fs16__default.readFile(absolutePath, "utf-8");
|
|
27300
|
+
const language = detectLanguage3(absolutePath);
|
|
27301
|
+
if (language !== "typescript" && language !== "javascript") {
|
|
27302
|
+
return [];
|
|
27303
|
+
}
|
|
27304
|
+
return parseTypeScript(content).definitions.map((definition) => ({
|
|
27305
|
+
file: filePath,
|
|
27306
|
+
name: definition.name,
|
|
27307
|
+
type: definition.type,
|
|
27308
|
+
line: definition.line,
|
|
27309
|
+
exported: definition.exported,
|
|
27310
|
+
signature: definition.signature
|
|
27311
|
+
}));
|
|
27312
|
+
}
|
|
27313
|
+
var lspStatusTool = defineTool({
|
|
27314
|
+
name: "lsp_status",
|
|
27315
|
+
description: "Check optional language-server availability. Use before LSP-style navigation when you need to know whether Coco is using static fallbacks.",
|
|
27316
|
+
category: "search",
|
|
27317
|
+
parameters: z.object({}),
|
|
27318
|
+
async execute() {
|
|
27319
|
+
return {
|
|
27320
|
+
languageServers: [
|
|
27321
|
+
{
|
|
27322
|
+
name: "typescript-language-server",
|
|
27323
|
+
available: await commandAvailable("typescript-language-server")
|
|
27324
|
+
},
|
|
27325
|
+
{ name: "tsserver", available: await commandAvailable("tsserver") }
|
|
27326
|
+
],
|
|
27327
|
+
fallbackMode: "static-analysis"
|
|
27328
|
+
};
|
|
27329
|
+
}
|
|
27330
|
+
});
|
|
27331
|
+
var lspDocumentSymbolsTool = defineTool({
|
|
27332
|
+
name: "lsp_document_symbols",
|
|
27333
|
+
description: "Return LSP-style document symbols for a TypeScript/JavaScript file using static analysis fallback.",
|
|
27334
|
+
category: "search",
|
|
27335
|
+
parameters: z.object({
|
|
27336
|
+
file: z.string().describe("File path to inspect")
|
|
27337
|
+
}),
|
|
27338
|
+
async execute({ file }) {
|
|
27339
|
+
return { symbols: await getFileSymbols(file) };
|
|
27340
|
+
}
|
|
27341
|
+
});
|
|
27342
|
+
var lspWorkspaceSymbolsTool = defineTool({
|
|
27343
|
+
name: "lsp_workspace_symbols",
|
|
27344
|
+
description: "Find LSP-style workspace symbols by name across TypeScript/JavaScript files using static analysis fallback.",
|
|
27345
|
+
category: "search",
|
|
27346
|
+
parameters: z.object({
|
|
27347
|
+
query: z.string().describe("Symbol name or substring to find"),
|
|
27348
|
+
path: z.string().optional().describe("Workspace directory, defaults to cwd"),
|
|
27349
|
+
maxFiles: z.number().optional().default(300),
|
|
27350
|
+
maxResults: z.number().optional().default(100)
|
|
27351
|
+
}),
|
|
27352
|
+
async execute({ query, path: workspacePath, maxFiles = 300, maxResults = 100 }) {
|
|
27353
|
+
const root = path17__default.resolve(workspacePath ?? process.cwd());
|
|
27354
|
+
const files = await getSourceFiles(root, maxFiles);
|
|
27355
|
+
const lowerQuery = query.toLowerCase();
|
|
27356
|
+
const symbols = [];
|
|
27357
|
+
for (const file of files) {
|
|
27358
|
+
const fileSymbols = await getFileSymbols(path17__default.join(root, file));
|
|
27359
|
+
for (const symbol of fileSymbols) {
|
|
27360
|
+
if (!symbol.name.toLowerCase().includes(lowerQuery)) continue;
|
|
27361
|
+
symbols.push({ ...symbol, file });
|
|
27362
|
+
if (symbols.length >= maxResults) {
|
|
27363
|
+
return { symbols, searchedFiles: files.length, truncated: true };
|
|
27364
|
+
}
|
|
27365
|
+
}
|
|
27366
|
+
}
|
|
27367
|
+
return { symbols, searchedFiles: files.length, truncated: false };
|
|
27368
|
+
}
|
|
27369
|
+
});
|
|
27370
|
+
var lspDefinitionTool = defineTool({
|
|
27371
|
+
name: "lsp_definition",
|
|
27372
|
+
description: "Find the likely definition of a symbol using exported symbols first, then local definitions.",
|
|
27373
|
+
category: "search",
|
|
27374
|
+
parameters: z.object({
|
|
27375
|
+
symbol: z.string().describe("Exact symbol name to locate"),
|
|
27376
|
+
path: z.string().optional().describe("Workspace directory, defaults to cwd"),
|
|
27377
|
+
maxFiles: z.number().optional().default(300)
|
|
27378
|
+
}),
|
|
27379
|
+
async execute({ symbol, path: workspacePath, maxFiles = 300 }) {
|
|
27380
|
+
const root = path17__default.resolve(workspacePath ?? process.cwd());
|
|
27381
|
+
const files = await getSourceFiles(root, maxFiles);
|
|
27382
|
+
const candidates = [];
|
|
27383
|
+
for (const file of files) {
|
|
27384
|
+
const fileSymbols = await getFileSymbols(path17__default.join(root, file));
|
|
27385
|
+
for (const candidate of fileSymbols) {
|
|
27386
|
+
if (candidate.name !== symbol) continue;
|
|
27387
|
+
candidates.push({ ...candidate, file });
|
|
27388
|
+
}
|
|
27389
|
+
}
|
|
27390
|
+
const definition = candidates.find((candidate) => candidate.exported) ?? candidates[0];
|
|
27391
|
+
return { definition, candidates };
|
|
27392
|
+
}
|
|
27393
|
+
});
|
|
27394
|
+
var lspReferencesTool = defineTool({
|
|
27395
|
+
name: "lsp_references",
|
|
27396
|
+
description: "Find likely references to a symbol across TypeScript/JavaScript files using whole-word text search.",
|
|
27397
|
+
category: "search",
|
|
27398
|
+
parameters: z.object({
|
|
27399
|
+
symbol: z.string().describe("Symbol name to find"),
|
|
27400
|
+
path: z.string().optional().describe("Workspace directory, defaults to cwd"),
|
|
27401
|
+
maxFiles: z.number().optional().default(300),
|
|
27402
|
+
maxResults: z.number().optional().default(100)
|
|
27403
|
+
}),
|
|
27404
|
+
async execute({ symbol, path: workspacePath, maxFiles = 300, maxResults = 100 }) {
|
|
27405
|
+
const root = path17__default.resolve(workspacePath ?? process.cwd());
|
|
27406
|
+
const files = await getSourceFiles(root, maxFiles);
|
|
27407
|
+
const pattern = new RegExp(`\\b${escapeRegExp(symbol)}\\b`);
|
|
27408
|
+
const references = [];
|
|
27409
|
+
for (const file of files) {
|
|
27410
|
+
const absolutePath = path17__default.join(root, file);
|
|
27411
|
+
const content = await fs16__default.readFile(absolutePath, "utf-8");
|
|
27412
|
+
const lines = content.split("\n");
|
|
27413
|
+
for (let index = 0; index < lines.length; index++) {
|
|
27414
|
+
const line = lines[index] ?? "";
|
|
27415
|
+
const match = pattern.exec(line);
|
|
27416
|
+
if (!match) continue;
|
|
27417
|
+
references.push({
|
|
27418
|
+
file,
|
|
27419
|
+
line: index + 1,
|
|
27420
|
+
column: match.index + 1,
|
|
27421
|
+
content: line.trim()
|
|
27422
|
+
});
|
|
27423
|
+
if (references.length >= maxResults) {
|
|
27424
|
+
return { references, searchedFiles: files.length, truncated: true };
|
|
27425
|
+
}
|
|
27426
|
+
}
|
|
27427
|
+
}
|
|
27428
|
+
return { references, searchedFiles: files.length, truncated: false };
|
|
27429
|
+
}
|
|
27430
|
+
});
|
|
27431
|
+
function escapeRegExp(value) {
|
|
27432
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
27433
|
+
}
|
|
27434
|
+
var lspTools = [
|
|
27435
|
+
lspStatusTool,
|
|
27436
|
+
lspDocumentSymbolsTool,
|
|
27437
|
+
lspWorkspaceSymbolsTool,
|
|
27438
|
+
lspDefinitionTool,
|
|
27439
|
+
lspReferencesTool
|
|
27440
|
+
];
|
|
27441
|
+
var fs34 = await import('fs/promises');
|
|
27442
|
+
var path36 = await import('path');
|
|
27443
|
+
function cachePath(root) {
|
|
27444
|
+
return path36.join(root, ".coco", "cache", "repo-index.json");
|
|
27445
|
+
}
|
|
27446
|
+
function normalizeText(value) {
|
|
27447
|
+
return value.toLowerCase().replace(/[^a-z0-9_./:-]+/g, " ");
|
|
27448
|
+
}
|
|
27449
|
+
function queryTerms(query) {
|
|
27450
|
+
return [
|
|
27451
|
+
...new Set(
|
|
27452
|
+
normalizeText(query).split(/\s+/).filter((term) => term.length >= 2)
|
|
27453
|
+
)
|
|
27454
|
+
];
|
|
27455
|
+
}
|
|
27456
|
+
function importTargetToPath(importTarget) {
|
|
27457
|
+
return importTarget.replace(/^\.\//, "").replace(/\.(js|ts|tsx|jsx|mjs|cjs)$/, "");
|
|
27458
|
+
}
|
|
27459
|
+
function buildGraph(root, map) {
|
|
27460
|
+
const inbound = /* @__PURE__ */ new Map();
|
|
27461
|
+
const files = new Set(map.files.map((file) => file.path.replace(/\.[^.]+$/, "")));
|
|
27462
|
+
for (const file of map.files) {
|
|
27463
|
+
for (const importTarget of file.imports) {
|
|
27464
|
+
const normalized = importTargetToPath(importTarget);
|
|
27465
|
+
for (const candidate of files) {
|
|
27466
|
+
if (candidate.endsWith(normalized) || normalized.endsWith(candidate)) {
|
|
27467
|
+
inbound.set(candidate, (inbound.get(candidate) ?? 0) + 1);
|
|
27468
|
+
}
|
|
27469
|
+
}
|
|
27470
|
+
}
|
|
27471
|
+
}
|
|
27472
|
+
return {
|
|
27473
|
+
root,
|
|
27474
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27475
|
+
files: map.files.map((file) => {
|
|
27476
|
+
const withoutExt = file.path.replace(/\.[^.]+$/, "");
|
|
27477
|
+
return {
|
|
27478
|
+
...file,
|
|
27479
|
+
inboundImports: inbound.get(withoutExt) ?? 0,
|
|
27480
|
+
testRelated: /(?:^|[/.-])(test|spec|__tests__)(?:[/.-]|$)/i.test(file.path)
|
|
27481
|
+
};
|
|
27482
|
+
}),
|
|
27483
|
+
summary: map.summary
|
|
27484
|
+
};
|
|
27485
|
+
}
|
|
27486
|
+
async function readCachedGraph(root) {
|
|
27487
|
+
try {
|
|
27488
|
+
const raw = await fs34.readFile(cachePath(root), "utf-8");
|
|
27489
|
+
return JSON.parse(raw);
|
|
27490
|
+
} catch {
|
|
27491
|
+
return null;
|
|
27492
|
+
}
|
|
27493
|
+
}
|
|
27494
|
+
async function writeCachedGraph(root, graph) {
|
|
27495
|
+
const file = cachePath(root);
|
|
27496
|
+
await fs34.mkdir(path36.dirname(file), { recursive: true });
|
|
27497
|
+
await fs34.writeFile(file, JSON.stringify(graph, null, 2) + "\n", "utf-8");
|
|
27498
|
+
}
|
|
27499
|
+
async function loadGraph(root, refresh) {
|
|
27500
|
+
if (!refresh) {
|
|
27501
|
+
const cached = await readCachedGraph(root);
|
|
27502
|
+
if (cached) return cached;
|
|
27503
|
+
}
|
|
27504
|
+
const map = await codebaseMapTool.execute({
|
|
27505
|
+
path: root,
|
|
27506
|
+
maxFiles: 500,
|
|
27507
|
+
depth: "detailed",
|
|
27508
|
+
includeTests: true
|
|
27509
|
+
});
|
|
27510
|
+
const graph = buildGraph(root, map);
|
|
27511
|
+
await writeCachedGraph(root, graph);
|
|
27512
|
+
return graph;
|
|
27513
|
+
}
|
|
27514
|
+
function scoreFile(file, terms, mode, changedFiles) {
|
|
27515
|
+
let score = 0;
|
|
27516
|
+
const reasons = [];
|
|
27517
|
+
const pathText = normalizeText(file.path);
|
|
27518
|
+
const symbolText = normalizeText(file.definitions.map((def) => def.name).join(" "));
|
|
27519
|
+
const importText = normalizeText([...file.imports, ...file.exports].join(" "));
|
|
27520
|
+
for (const term of terms) {
|
|
27521
|
+
if (pathText.includes(term)) {
|
|
27522
|
+
score += 8;
|
|
27523
|
+
reasons.push(`path:${term}`);
|
|
27524
|
+
}
|
|
27525
|
+
if (symbolText.includes(term)) {
|
|
27526
|
+
score += 6;
|
|
27527
|
+
reasons.push(`symbol:${term}`);
|
|
27528
|
+
}
|
|
27529
|
+
if (importText.includes(term)) {
|
|
27530
|
+
score += 3;
|
|
27531
|
+
reasons.push(`import/export:${term}`);
|
|
27532
|
+
}
|
|
27533
|
+
}
|
|
27534
|
+
if (changedFiles.has(file.path)) {
|
|
27535
|
+
score += 10;
|
|
27536
|
+
reasons.push("changed-file");
|
|
27537
|
+
}
|
|
27538
|
+
if (file.inboundImports > 0) {
|
|
27539
|
+
score += Math.min(6, file.inboundImports);
|
|
27540
|
+
reasons.push(`centrality:${file.inboundImports}`);
|
|
27541
|
+
}
|
|
27542
|
+
if ((mode === "debug" || mode === "review") && file.testRelated) {
|
|
27543
|
+
score += 4;
|
|
27544
|
+
reasons.push("test-related");
|
|
27545
|
+
}
|
|
27546
|
+
if (file.exports.length > 0) {
|
|
27547
|
+
score += 1;
|
|
27548
|
+
}
|
|
27549
|
+
return {
|
|
27550
|
+
path: file.path,
|
|
27551
|
+
score,
|
|
27552
|
+
reasons: [...new Set(reasons)],
|
|
27553
|
+
language: file.language,
|
|
27554
|
+
lineCount: file.lineCount,
|
|
27555
|
+
definitions: file.definitions.slice(0, 20),
|
|
27556
|
+
imports: file.imports.slice(0, 20),
|
|
27557
|
+
exports: file.exports.slice(0, 20)
|
|
27558
|
+
};
|
|
27559
|
+
}
|
|
27560
|
+
async function getRepoContext(request) {
|
|
27561
|
+
const root = path36.resolve(request.path ?? ".");
|
|
27562
|
+
const budget = request.budget ?? 12;
|
|
27563
|
+
const graph = await loadGraph(root, request.refresh ?? false);
|
|
27564
|
+
const terms = queryTerms(request.query);
|
|
27565
|
+
const changedFiles = new Set(request.changedFiles ?? []);
|
|
27566
|
+
const items = graph.files.map((file) => scoreFile(file, terms, request.mode, changedFiles)).filter((item) => item.score > 0).sort((a, b) => b.score - a.score || a.path.localeCompare(b.path)).slice(0, budget);
|
|
27567
|
+
return {
|
|
27568
|
+
graph: {
|
|
27569
|
+
root: graph.root,
|
|
27570
|
+
generatedAt: graph.generatedAt,
|
|
27571
|
+
totalFiles: graph.summary.totalFiles,
|
|
27572
|
+
totalDefinitions: graph.summary.totalDefinitions
|
|
27573
|
+
},
|
|
27574
|
+
query: request.query,
|
|
27575
|
+
budget,
|
|
27576
|
+
items
|
|
27577
|
+
};
|
|
27578
|
+
}
|
|
27579
|
+
var repoContextTool = defineTool({
|
|
27580
|
+
name: "repo_context",
|
|
27581
|
+
description: "Return ranked, token-efficient repository context for a task using symbols, imports, tests, and centrality.",
|
|
27582
|
+
category: "search",
|
|
27583
|
+
parameters: z.object({
|
|
27584
|
+
path: z.string().optional().default(".").describe("Repository root"),
|
|
27585
|
+
query: z.string().min(1).describe("Task or search query to rank files against"),
|
|
27586
|
+
budget: z.number().min(1).max(50).optional().default(12).describe("Maximum files to return"),
|
|
27587
|
+
mode: z.enum(["ask", "plan", "build", "debug", "review", "architect"]).optional().describe("Agent mode to bias ranking"),
|
|
27588
|
+
changedFiles: z.array(z.string()).optional().describe("Files already changed or selected"),
|
|
27589
|
+
refresh: z.boolean().optional().default(false).describe("Refresh persistent repo index cache")
|
|
27590
|
+
}),
|
|
27591
|
+
execute: getRepoContext
|
|
27592
|
+
});
|
|
27593
|
+
var repoIntelligenceTools = [repoContextTool];
|
|
26212
27594
|
var AgentTaskQueue = class {
|
|
26213
27595
|
tasks = /* @__PURE__ */ new Map();
|
|
26214
27596
|
completionOrder = [];
|
|
@@ -26517,15 +27899,15 @@ ${completed.map((r) => `- ${r.agentId}: Success`).join("\n")}`;
|
|
|
26517
27899
|
}
|
|
26518
27900
|
});
|
|
26519
27901
|
var agentCoordinatorTools = [createAgentPlanTool, delegateTaskTool, aggregateResultsTool];
|
|
26520
|
-
var
|
|
27902
|
+
var fs35 = await import('fs/promises');
|
|
26521
27903
|
var SuggestImprovementsSchema = z.object({
|
|
26522
27904
|
filePath: z.string().describe("File to analyze for improvement suggestions"),
|
|
26523
27905
|
context: z.string().optional().describe("Additional context about the code")
|
|
26524
27906
|
});
|
|
26525
27907
|
async function analyzeAndSuggest(filePath, _context) {
|
|
26526
|
-
let rawContent = await
|
|
27908
|
+
let rawContent = await fs35.readFile(filePath, "utf-8");
|
|
26527
27909
|
if (typeof rawContent !== "string") {
|
|
26528
|
-
const defaultReadFile =
|
|
27910
|
+
const defaultReadFile = fs35.default?.readFile;
|
|
26529
27911
|
if (typeof defaultReadFile === "function") {
|
|
26530
27912
|
rawContent = await defaultReadFile(filePath, "utf-8");
|
|
26531
27913
|
}
|
|
@@ -26622,7 +28004,7 @@ async function analyzeAndSuggest(filePath, _context) {
|
|
|
26622
28004
|
if (filePath.endsWith(".ts") && !filePath.includes("test") && !filePath.includes(".d.ts") && line.includes("export ")) {
|
|
26623
28005
|
const testPath = filePath.replace(".ts", ".test.ts");
|
|
26624
28006
|
try {
|
|
26625
|
-
await
|
|
28007
|
+
await fs35.access(testPath);
|
|
26626
28008
|
} catch {
|
|
26627
28009
|
suggestions.push({
|
|
26628
28010
|
type: "testing",
|
|
@@ -26679,7 +28061,7 @@ var calculateCodeScoreTool = defineTool({
|
|
|
26679
28061
|
async execute(input) {
|
|
26680
28062
|
const { filePath } = input;
|
|
26681
28063
|
const suggestions = await analyzeAndSuggest(filePath);
|
|
26682
|
-
const content = await
|
|
28064
|
+
const content = await fs35.readFile(filePath, "utf-8");
|
|
26683
28065
|
const lines = content.split("\n");
|
|
26684
28066
|
const nonEmptyLines = lines.filter((l) => l.trim()).length;
|
|
26685
28067
|
let score = 100;
|
|
@@ -26713,8 +28095,8 @@ var calculateCodeScoreTool = defineTool({
|
|
|
26713
28095
|
}
|
|
26714
28096
|
});
|
|
26715
28097
|
var smartSuggestionsTools = [suggestImprovementsTool, calculateCodeScoreTool];
|
|
26716
|
-
var
|
|
26717
|
-
var
|
|
28098
|
+
var fs36 = await import('fs/promises');
|
|
28099
|
+
var path37 = await import('path');
|
|
26718
28100
|
var ContextMemoryStore = class {
|
|
26719
28101
|
items = /* @__PURE__ */ new Map();
|
|
26720
28102
|
learnings = /* @__PURE__ */ new Map();
|
|
@@ -26726,7 +28108,7 @@ var ContextMemoryStore = class {
|
|
|
26726
28108
|
}
|
|
26727
28109
|
async load() {
|
|
26728
28110
|
try {
|
|
26729
|
-
const content = await
|
|
28111
|
+
const content = await fs36.readFile(this.storePath, "utf-8");
|
|
26730
28112
|
const data = JSON.parse(content);
|
|
26731
28113
|
this.items = new Map(Object.entries(data.items || {}));
|
|
26732
28114
|
this.learnings = new Map(Object.entries(data.learnings || {}));
|
|
@@ -26734,15 +28116,15 @@ var ContextMemoryStore = class {
|
|
|
26734
28116
|
}
|
|
26735
28117
|
}
|
|
26736
28118
|
async save() {
|
|
26737
|
-
const dir =
|
|
26738
|
-
await
|
|
28119
|
+
const dir = path37.dirname(this.storePath);
|
|
28120
|
+
await fs36.mkdir(dir, { recursive: true });
|
|
26739
28121
|
const data = {
|
|
26740
28122
|
sessionId: this.sessionId,
|
|
26741
28123
|
items: Object.fromEntries(this.items),
|
|
26742
28124
|
learnings: Object.fromEntries(this.learnings),
|
|
26743
28125
|
savedAt: Date.now()
|
|
26744
28126
|
};
|
|
26745
|
-
await
|
|
28127
|
+
await fs36.writeFile(this.storePath, JSON.stringify(data, null, 2));
|
|
26746
28128
|
}
|
|
26747
28129
|
addContext(id, item) {
|
|
26748
28130
|
this.items.set(id, item);
|
|
@@ -26907,11 +28289,11 @@ var contextEnhancerTools = [
|
|
|
26907
28289
|
recordLearningTool,
|
|
26908
28290
|
getLearnedPatternsTool
|
|
26909
28291
|
];
|
|
26910
|
-
var
|
|
26911
|
-
var
|
|
28292
|
+
var fs37 = await import('fs/promises');
|
|
28293
|
+
var path38 = await import('path');
|
|
26912
28294
|
async function discoverSkills(skillsDir) {
|
|
26913
28295
|
try {
|
|
26914
|
-
const files = await
|
|
28296
|
+
const files = await fs37.readdir(skillsDir);
|
|
26915
28297
|
return files.filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
|
|
26916
28298
|
} catch {
|
|
26917
28299
|
return [];
|
|
@@ -26919,12 +28301,12 @@ async function discoverSkills(skillsDir) {
|
|
|
26919
28301
|
}
|
|
26920
28302
|
async function loadSkillMetadata(skillPath) {
|
|
26921
28303
|
try {
|
|
26922
|
-
const content = await
|
|
28304
|
+
const content = await fs37.readFile(skillPath, "utf-8");
|
|
26923
28305
|
const nameMatch = content.match(/@name\s+(\S+)/);
|
|
26924
28306
|
const descMatch = content.match(/@description\s+(.+)/);
|
|
26925
28307
|
const versionMatch = content.match(/@version\s+(\S+)/);
|
|
26926
28308
|
return {
|
|
26927
|
-
name: nameMatch?.[1] ||
|
|
28309
|
+
name: nameMatch?.[1] || path38.basename(skillPath, path38.extname(skillPath)),
|
|
26928
28310
|
description: descMatch?.[1] || "No description",
|
|
26929
28311
|
version: versionMatch?.[1] || "1.0.0",
|
|
26930
28312
|
dependencies: []
|
|
@@ -26968,7 +28350,7 @@ var discoverSkillsTool = defineTool({
|
|
|
26968
28350
|
const { skillsDir } = input;
|
|
26969
28351
|
const skills = await discoverSkills(skillsDir);
|
|
26970
28352
|
const metadata = await Promise.all(
|
|
26971
|
-
skills.map((s) => loadSkillMetadata(
|
|
28353
|
+
skills.map((s) => loadSkillMetadata(path38.join(skillsDir, s)))
|
|
26972
28354
|
);
|
|
26973
28355
|
return {
|
|
26974
28356
|
skillsDir,
|
|
@@ -27708,8 +29090,8 @@ var MCPRegistryImpl = class {
|
|
|
27708
29090
|
/**
|
|
27709
29091
|
* Ensure directory exists
|
|
27710
29092
|
*/
|
|
27711
|
-
async ensureDir(
|
|
27712
|
-
await mkdir(dirname(
|
|
29093
|
+
async ensureDir(path44) {
|
|
29094
|
+
await mkdir(dirname(path44), { recursive: true });
|
|
27713
29095
|
}
|
|
27714
29096
|
};
|
|
27715
29097
|
|
|
@@ -27725,6 +29107,8 @@ var MCPClientImpl = class {
|
|
|
27725
29107
|
this.requestTimeout = requestTimeout;
|
|
27726
29108
|
this.setupTransportHandlers();
|
|
27727
29109
|
}
|
|
29110
|
+
transport;
|
|
29111
|
+
requestTimeout;
|
|
27728
29112
|
requestId = 0;
|
|
27729
29113
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
27730
29114
|
initialized = false;
|
|
@@ -27896,6 +29280,7 @@ var StdioTransport = class {
|
|
|
27896
29280
|
constructor(config) {
|
|
27897
29281
|
this.config = config;
|
|
27898
29282
|
}
|
|
29283
|
+
config;
|
|
27899
29284
|
process = null;
|
|
27900
29285
|
messageCallback = null;
|
|
27901
29286
|
errorCallback = null;
|
|
@@ -28435,6 +29820,7 @@ var HTTPTransport = class {
|
|
|
28435
29820
|
this.config.timeout = config.timeout ?? 6e4;
|
|
28436
29821
|
this.config.retries = config.retries ?? 3;
|
|
28437
29822
|
}
|
|
29823
|
+
config;
|
|
28438
29824
|
messageCallback = null;
|
|
28439
29825
|
errorCallback = null;
|
|
28440
29826
|
// Used to report transport errors to the client
|
|
@@ -29503,6 +30889,8 @@ function registerAllTools(registry) {
|
|
|
29503
30889
|
...databaseTools,
|
|
29504
30890
|
...astValidatorTools,
|
|
29505
30891
|
...codeAnalyzerTools,
|
|
30892
|
+
...lspTools,
|
|
30893
|
+
...repoIntelligenceTools,
|
|
29506
30894
|
...agentCoordinatorTools,
|
|
29507
30895
|
...smartSuggestionsTools,
|
|
29508
30896
|
...contextEnhancerTools,
|