swarm-code 0.1.9 → 0.1.11
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/interactive-swarm.js +138 -0
- package/package.json +1 -1
|
@@ -244,6 +244,7 @@ function cmdHelp() {
|
|
|
244
244
|
out.write(` ${cyan("/dag")} ${dim("Show thread DAG with status indicators")}\n`);
|
|
245
245
|
out.write(` ${cyan("/budget")} ${dim("Show budget state")}\n`);
|
|
246
246
|
out.write(` ${cyan("/status")} ${dim("Overall session status")}\n`);
|
|
247
|
+
out.write(` ${cyan("/configure")} ${dim("(/c)")} ${dim("Change agent, model, or backend")}\n`);
|
|
247
248
|
out.write(` ${cyan("/help")} ${dim("Show this help")}\n`);
|
|
248
249
|
out.write(` ${cyan("/quit")} ${dim("(/exit)")} ${dim("Cleanup and exit")}\n`);
|
|
249
250
|
out.write("\n");
|
|
@@ -536,6 +537,138 @@ function cmdStatus(threadManager, sessionStartTime, taskCount) {
|
|
|
536
537
|
}
|
|
537
538
|
out.write("\n");
|
|
538
539
|
}
|
|
540
|
+
// ── Configure command ───────────────────────────────────────────────────────
|
|
541
|
+
async function cmdConfigure(config, resolved, rl) {
|
|
542
|
+
const out = process.stderr;
|
|
543
|
+
const ask = (q) => new Promise((res) => rl.question(q, (a) => res(a.trim())));
|
|
544
|
+
out.write("\n");
|
|
545
|
+
out.write(` ${bold(cyan("Configuration"))}\n`);
|
|
546
|
+
out.write(` ${dim(symbols.horizontal.repeat(40))}\n\n`);
|
|
547
|
+
out.write(` ${dim("Current settings:")}\n`);
|
|
548
|
+
out.write(` ${cyan("1")} Agent ${bold(config.default_agent)}\n`);
|
|
549
|
+
const displayModel = resolved.provider === "ollama"
|
|
550
|
+
? `ollama/${resolved.model.id}`
|
|
551
|
+
: resolved.provider === "openrouter"
|
|
552
|
+
? `openrouter/${resolved.model.id}`
|
|
553
|
+
: resolved.model.id;
|
|
554
|
+
out.write(` ${cyan("2")} Model ${bold(displayModel)}${displayModel !== config.default_model ? dim(` (config: ${config.default_model})`) : ""}\n`);
|
|
555
|
+
out.write(` ${cyan("3")} Max threads ${bold(String(config.max_threads))}\n`);
|
|
556
|
+
out.write(` ${cyan("4")} Auto routing ${bold(config.auto_model_selection ? "on" : "off")}\n`);
|
|
557
|
+
out.write(` ${cyan("5")} Session budget ${bold(`$${config.max_session_budget_usd.toFixed(2)}`)}\n`);
|
|
558
|
+
out.write(` ${cyan("6")} Thread budget ${bold(`$${config.max_thread_budget_usd.toFixed(2)}`)}\n`);
|
|
559
|
+
out.write(` ${cyan("7")} Compression ${bold(config.compression_strategy)}\n`);
|
|
560
|
+
out.write("\n");
|
|
561
|
+
const choice = await ask(` ${coral(symbols.arrow)} Setting to change [1-7, or enter to cancel]: `);
|
|
562
|
+
if (!choice) {
|
|
563
|
+
out.write(` ${dim("No changes made.")}\n\n`);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
switch (choice) {
|
|
567
|
+
case "1": {
|
|
568
|
+
const agents = (await import("./agents/provider.js")).listAgents();
|
|
569
|
+
out.write(`\n ${dim("Available agents:")} ${agents.join(", ")}\n`);
|
|
570
|
+
const val = await ask(` ${coral(symbols.arrow)} New agent [${config.default_agent}]: `);
|
|
571
|
+
if (val && agents.includes(val)) {
|
|
572
|
+
config.default_agent = val;
|
|
573
|
+
logSuccess(`Agent set to ${bold(val)}`);
|
|
574
|
+
}
|
|
575
|
+
else if (val) {
|
|
576
|
+
logWarn(`Unknown agent "${val}"`);
|
|
577
|
+
}
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
case "2": {
|
|
581
|
+
out.write(`\n ${dim("Enter model ID (e.g. ollama/deepseek-coder-v2, anthropic/claude-sonnet-4-6, openrouter/auto)")}\n`);
|
|
582
|
+
const val = await ask(` ${coral(symbols.arrow)} New model [${displayModel}]: `);
|
|
583
|
+
if (val) {
|
|
584
|
+
// Check for OpenRouter API key
|
|
585
|
+
if (val.startsWith("openrouter/") && !process.env.OPENROUTER_API_KEY) {
|
|
586
|
+
out.write(`\n ${dim("OpenRouter requires an API key (https://openrouter.ai/keys)")}\n`);
|
|
587
|
+
const key = await ask(` ${coral(symbols.arrow)} OPENROUTER_API_KEY: `);
|
|
588
|
+
if (key) {
|
|
589
|
+
process.env.OPENROUTER_API_KEY = key;
|
|
590
|
+
logSuccess("OpenRouter API key set for this session");
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
logWarn("No API key provided — cannot use OpenRouter");
|
|
594
|
+
break;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
const lookupId = val.startsWith("ollama/") || val.startsWith("openrouter/")
|
|
598
|
+
? val
|
|
599
|
+
: val.replace(/^(anthropic|openai|google)\//, "");
|
|
600
|
+
const newResolved = resolveModel(lookupId, logWarn);
|
|
601
|
+
if (newResolved) {
|
|
602
|
+
config.default_model = val;
|
|
603
|
+
resolved.model = newResolved.model;
|
|
604
|
+
resolved.provider = newResolved.provider;
|
|
605
|
+
logSuccess(`Model set to ${bold(val)}`);
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
logWarn(`Could not resolve model "${val}"`);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
case "3": {
|
|
614
|
+
const val = await ask(` ${coral(symbols.arrow)} Max concurrent threads [${config.max_threads}]: `);
|
|
615
|
+
const n = parseInt(val, 10);
|
|
616
|
+
if (n >= 1 && n <= 20) {
|
|
617
|
+
config.max_threads = n;
|
|
618
|
+
logSuccess(`Max threads set to ${bold(String(n))}`);
|
|
619
|
+
}
|
|
620
|
+
else if (val) {
|
|
621
|
+
logWarn("Must be between 1 and 20");
|
|
622
|
+
}
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
case "4": {
|
|
626
|
+
config.auto_model_selection = !config.auto_model_selection;
|
|
627
|
+
logSuccess(`Auto routing ${bold(config.auto_model_selection ? "enabled" : "disabled")}`);
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
case "5": {
|
|
631
|
+
const val = await ask(` ${coral(symbols.arrow)} Session budget USD [${config.max_session_budget_usd}]: `);
|
|
632
|
+
const n = parseFloat(val);
|
|
633
|
+
if (Number.isFinite(n) && n > 0) {
|
|
634
|
+
config.max_session_budget_usd = n;
|
|
635
|
+
logSuccess(`Session budget set to ${bold(`$${n.toFixed(2)}`)}`);
|
|
636
|
+
}
|
|
637
|
+
else if (val) {
|
|
638
|
+
logWarn("Must be a positive number");
|
|
639
|
+
}
|
|
640
|
+
break;
|
|
641
|
+
}
|
|
642
|
+
case "6": {
|
|
643
|
+
const val = await ask(` ${coral(symbols.arrow)} Per-thread budget USD [${config.max_thread_budget_usd}]: `);
|
|
644
|
+
const n = parseFloat(val);
|
|
645
|
+
if (Number.isFinite(n) && n > 0) {
|
|
646
|
+
config.max_thread_budget_usd = n;
|
|
647
|
+
logSuccess(`Thread budget set to ${bold(`$${n.toFixed(2)}`)}`);
|
|
648
|
+
}
|
|
649
|
+
else if (val) {
|
|
650
|
+
logWarn("Must be a positive number");
|
|
651
|
+
}
|
|
652
|
+
break;
|
|
653
|
+
}
|
|
654
|
+
case "7": {
|
|
655
|
+
const strategies = ["structured", "llm-summary", "diff-only", "truncate"];
|
|
656
|
+
out.write(`\n ${dim("Options:")} ${strategies.join(", ")}\n`);
|
|
657
|
+
const val = await ask(` ${coral(symbols.arrow)} Compression [${config.compression_strategy}]: `);
|
|
658
|
+
if (val && strategies.includes(val)) {
|
|
659
|
+
config.compression_strategy = val;
|
|
660
|
+
logSuccess(`Compression set to ${bold(val)}`);
|
|
661
|
+
}
|
|
662
|
+
else if (val) {
|
|
663
|
+
logWarn(`Unknown strategy "${val}"`);
|
|
664
|
+
}
|
|
665
|
+
break;
|
|
666
|
+
}
|
|
667
|
+
default:
|
|
668
|
+
logWarn("Invalid option");
|
|
669
|
+
}
|
|
670
|
+
out.write("\n");
|
|
671
|
+
}
|
|
539
672
|
// ── Interactive banner ──────────────────────────────────────────────────────
|
|
540
673
|
function renderInteractiveBanner(config) {
|
|
541
674
|
const w = Math.max(Math.min(termWidth(), 60), 24);
|
|
@@ -932,6 +1065,11 @@ export async function runInteractiveSwarm(rawArgs) {
|
|
|
932
1065
|
case "/s":
|
|
933
1066
|
cmdStatus(threadManager, sessionStartTime, taskCount);
|
|
934
1067
|
break;
|
|
1068
|
+
case "/configure":
|
|
1069
|
+
case "/config":
|
|
1070
|
+
case "/c":
|
|
1071
|
+
await cmdConfigure(config, resolved, rl);
|
|
1072
|
+
break;
|
|
935
1073
|
case "/quit":
|
|
936
1074
|
case "/exit":
|
|
937
1075
|
case "/q":
|
package/package.json
CHANGED