@kernel.chat/kbot 2.5.0 → 2.7.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/README.md +98 -42
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +116 -21
- package/dist/agent.js.map +1 -1
- package/dist/auth.d.ts +11 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +165 -7
- package/dist/auth.js.map +1 -1
- package/dist/cli.js +207 -22
- package/dist/cli.js.map +1 -1
- package/dist/ide/acp-server.js +2 -2
- package/dist/ide/acp-server.js.map +1 -1
- package/dist/ide/mcp-server.js +1 -1
- package/dist/matrix.d.ts +6 -0
- package/dist/matrix.d.ts.map +1 -1
- package/dist/matrix.js +98 -0
- package/dist/matrix.js.map +1 -1
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +29 -0
- package/dist/planner.js.map +1 -1
- package/dist/provider-fallback.d.ts +51 -0
- package/dist/provider-fallback.d.ts.map +1 -0
- package/dist/provider-fallback.js +237 -0
- package/dist/provider-fallback.js.map +1 -0
- package/dist/repo-map.d.ts +9 -0
- package/dist/repo-map.d.ts.map +1 -0
- package/dist/repo-map.js +280 -0
- package/dist/repo-map.js.map +1 -0
- package/dist/self-eval.d.ts +45 -0
- package/dist/self-eval.d.ts.map +1 -0
- package/dist/self-eval.js +232 -0
- package/dist/self-eval.js.map +1 -0
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +22 -2
- package/dist/streaming.js.map +1 -1
- package/dist/task-ledger.d.ts +71 -0
- package/dist/task-ledger.d.ts.map +1 -0
- package/dist/task-ledger.js +282 -0
- package/dist/task-ledger.js.map +1 -0
- package/dist/tools/computer.js +3 -3
- package/dist/tools/computer.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/memory-tools.d.ts +2 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +228 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/quality.d.ts +2 -0
- package/dist/tools/quality.d.ts.map +1 -0
- package/dist/tools/quality.js +313 -0
- package/dist/tools/quality.js.map +1 -0
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +33 -18
- package/dist/ui.js.map +1 -1
- package/package.json +27 -3
package/dist/cli.js
CHANGED
|
@@ -16,20 +16,20 @@ import { gatherContext } from './context.js';
|
|
|
16
16
|
import { registerAllTools } from './tools/index.js';
|
|
17
17
|
import { clearHistory, clearMemory, compactHistory, restoreHistory } from './memory.js';
|
|
18
18
|
import { saveSession, loadSession, listSessions, deleteSession, formatSessionList, } from './sessions.js';
|
|
19
|
-
import { createAgent, removeAgent, getAgent, formatAgentList, formatAgentDetail, PRESETS, getMatrixAgentIds, activateMimic, listMimicProfiles, getMimicProfile, } from './matrix.js';
|
|
19
|
+
import { createAgent, removeAgent, getAgent, formatAgentList, formatAgentDetail, PRESETS, getMatrixAgentIds, activateMimic, listMimicProfiles, getMimicProfile, registerBuiltinAgents, formatBuiltinAgentList, formatBuiltinAgentDetail, } from './matrix.js';
|
|
20
20
|
import { getExtendedStats, incrementSessions, learnFact, selfTrain, getTrainingLog, flushPendingWrites } from './learning.js';
|
|
21
21
|
import { banner, bannerCompact, bannerAuth, prompt as kbotPrompt, printError, printSuccess, printInfo, printResponse, printHelp, printGoodbye, setQuiet, } from './ui.js';
|
|
22
22
|
import { checkForUpdate, selfUpdate } from './updater.js';
|
|
23
23
|
import { syncOnStartup, schedulePush, flushCloudSync, isCloudSyncEnabled, setCloudToken, getCloudToken } from './cloud-sync.js';
|
|
24
24
|
import chalk from 'chalk';
|
|
25
|
-
const VERSION = '2.
|
|
25
|
+
const VERSION = '2.7.0';
|
|
26
26
|
async function main() {
|
|
27
27
|
const program = new Command();
|
|
28
28
|
program
|
|
29
29
|
.name('kbot')
|
|
30
30
|
.description('K:BOT — Open-source terminal AI agent. Bring your own key, pick your model, run locally.')
|
|
31
31
|
.version(VERSION)
|
|
32
|
-
.option('-a, --agent <agent>', 'Force a specific agent (kernel, researcher, coder, writer, analyst)')
|
|
32
|
+
.option('-a, --agent <agent>', 'Force a specific agent (kernel, researcher, coder, writer, analyst, hacker, operator, dreamer)')
|
|
33
33
|
.option('-m, --model <model>', 'Override AI model (auto, sonnet, haiku)')
|
|
34
34
|
.option('-s, --stream', 'Stream the response')
|
|
35
35
|
.option('-p, --pipe', 'Pipe mode — raw text output for scripting')
|
|
@@ -40,6 +40,7 @@ async function main() {
|
|
|
40
40
|
.option('--computer-use', 'Enable computer use tools')
|
|
41
41
|
.option('-t, --thinking', 'Show AI reasoning steps')
|
|
42
42
|
.option('--thinking-budget <tokens>', 'Thinking token budget (default: 10000)')
|
|
43
|
+
.option('--self-eval', 'Enable self-evaluation loop (score and retry low-quality responses)')
|
|
43
44
|
.option('--safe', 'Confirm destructive operations')
|
|
44
45
|
.option('--strict', 'Confirm ALL operations')
|
|
45
46
|
.argument('[prompt...]', 'One-shot prompt')
|
|
@@ -86,7 +87,7 @@ async function main() {
|
|
|
86
87
|
});
|
|
87
88
|
program
|
|
88
89
|
.command('byok')
|
|
89
|
-
.description('Bring Your Own Key — configure your LLM API key (
|
|
90
|
+
.description('Bring Your Own Key — configure your LLM API key (19 providers)')
|
|
90
91
|
.option('--off', 'Disable BYOK mode')
|
|
91
92
|
.action(async (opts) => {
|
|
92
93
|
if (opts.off) {
|
|
@@ -370,7 +371,7 @@ async function main() {
|
|
|
370
371
|
});
|
|
371
372
|
program
|
|
372
373
|
.command('serve')
|
|
373
|
-
.description('Start HTTP server — expose all
|
|
374
|
+
.description('Start HTTP server — expose all 93 tools for kernel.chat or any client')
|
|
374
375
|
.option('-p, --port <port>', 'Port to listen on', '7437')
|
|
375
376
|
.option('--token <token>', 'Require auth token for all requests')
|
|
376
377
|
.option('--computer-use', 'Enable computer use tools')
|
|
@@ -401,6 +402,27 @@ async function main() {
|
|
|
401
402
|
printError('Cannot connect to OpenClaw gateway. Start it first.');
|
|
402
403
|
}
|
|
403
404
|
});
|
|
405
|
+
program
|
|
406
|
+
.command('agents [name]')
|
|
407
|
+
.description('List all available agents, or show details for one')
|
|
408
|
+
.action(async (name) => {
|
|
409
|
+
registerBuiltinAgents();
|
|
410
|
+
if (name) {
|
|
411
|
+
const detail = formatBuiltinAgentDetail(name);
|
|
412
|
+
if (detail) {
|
|
413
|
+
console.log(detail);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
printError(`Agent "${name}" not found.`);
|
|
417
|
+
printInfo('Run `kbot agents` to see all available agents.');
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
console.log(formatBuiltinAgentList());
|
|
422
|
+
console.log();
|
|
423
|
+
printInfo('Use: kbot --agent <name> "prompt"');
|
|
424
|
+
}
|
|
425
|
+
});
|
|
404
426
|
program.parse(process.argv);
|
|
405
427
|
const opts = program.opts();
|
|
406
428
|
const promptArgs = program.args;
|
|
@@ -408,7 +430,7 @@ async function main() {
|
|
|
408
430
|
if (opts.quiet)
|
|
409
431
|
setQuiet(true);
|
|
410
432
|
// If a sub-command was run, we're done
|
|
411
|
-
if (['byok', 'auth', 'ide', 'ollama', 'openclaw', 'pull', 'doctor', 'serve'].includes(program.args[0]))
|
|
433
|
+
if (['byok', 'auth', 'ide', 'ollama', 'openclaw', 'pull', 'doctor', 'serve', 'agents'].includes(program.args[0]))
|
|
412
434
|
return;
|
|
413
435
|
// Check for API key (BYOK or local provider)
|
|
414
436
|
let byokActive = isByokEnabled();
|
|
@@ -422,9 +444,10 @@ async function main() {
|
|
|
422
444
|
localActive = isLocalProvider(envDetected);
|
|
423
445
|
printSuccess(`Auto-detected ${PROVIDERS[envDetected].name} from environment.`);
|
|
424
446
|
}
|
|
425
|
-
// Priority 2: Check local providers in PARALLEL (
|
|
447
|
+
// Priority 2: Check local providers in PARALLEL (all at once, use whichever responds first)
|
|
426
448
|
if (!byokActive) {
|
|
427
|
-
const
|
|
449
|
+
const { isLmStudioRunning, isJanRunning, setupLmStudio, setupJan } = await import('./auth.js');
|
|
450
|
+
const [ollamaResult, lmstudioResult, janResult, openclawResult] = await Promise.allSettled([
|
|
428
451
|
// Check Ollama
|
|
429
452
|
(async () => {
|
|
430
453
|
const up = await isOllamaRunning();
|
|
@@ -436,6 +459,22 @@ async function main() {
|
|
|
436
459
|
const ok = await setupOllama();
|
|
437
460
|
return ok ? { provider: 'ollama', models: models.length } : null;
|
|
438
461
|
})(),
|
|
462
|
+
// Check LM Studio
|
|
463
|
+
(async () => {
|
|
464
|
+
const up = await isLmStudioRunning();
|
|
465
|
+
if (!up)
|
|
466
|
+
return null;
|
|
467
|
+
const ok = await setupLmStudio();
|
|
468
|
+
return ok ? { provider: 'lmstudio' } : null;
|
|
469
|
+
})(),
|
|
470
|
+
// Check Jan
|
|
471
|
+
(async () => {
|
|
472
|
+
const up = await isJanRunning();
|
|
473
|
+
if (!up)
|
|
474
|
+
return null;
|
|
475
|
+
const ok = await setupJan();
|
|
476
|
+
return ok ? { provider: 'jan' } : null;
|
|
477
|
+
})(),
|
|
439
478
|
// Check OpenClaw
|
|
440
479
|
(async () => {
|
|
441
480
|
try {
|
|
@@ -450,14 +489,26 @@ async function main() {
|
|
|
450
489
|
}
|
|
451
490
|
})(),
|
|
452
491
|
]);
|
|
453
|
-
// Prefer Ollama
|
|
492
|
+
// Prefer Ollama > LM Studio > Jan > OpenClaw
|
|
454
493
|
const ollamaOk = ollamaResult.status === 'fulfilled' && ollamaResult.value;
|
|
494
|
+
const lmstudioOk = lmstudioResult.status === 'fulfilled' && lmstudioResult.value;
|
|
495
|
+
const janOk = janResult.status === 'fulfilled' && janResult.value;
|
|
455
496
|
const openclawOk = openclawResult.status === 'fulfilled' && openclawResult.value;
|
|
456
497
|
if (ollamaOk) {
|
|
457
498
|
byokActive = true;
|
|
458
499
|
localActive = true;
|
|
459
500
|
printSuccess(`Auto-configured Ollama (${ollamaOk.models} models). Ready — $0 cost!`);
|
|
460
501
|
}
|
|
502
|
+
else if (lmstudioOk) {
|
|
503
|
+
byokActive = true;
|
|
504
|
+
localActive = true;
|
|
505
|
+
printSuccess('Auto-configured LM Studio. Ready — $0 cost!');
|
|
506
|
+
}
|
|
507
|
+
else if (janOk) {
|
|
508
|
+
byokActive = true;
|
|
509
|
+
localActive = true;
|
|
510
|
+
printSuccess('Auto-configured Jan. Ready — $0 cost!');
|
|
511
|
+
}
|
|
461
512
|
else if (openclawOk) {
|
|
462
513
|
byokActive = true;
|
|
463
514
|
localActive = true;
|
|
@@ -488,6 +539,9 @@ async function main() {
|
|
|
488
539
|
{ env: 'PERPLEXITY_API_KEY', provider: 'perplexity' },
|
|
489
540
|
{ env: 'COHERE_API_KEY', provider: 'cohere' },
|
|
490
541
|
{ env: 'NVIDIA_API_KEY', provider: 'nvidia' },
|
|
542
|
+
{ env: 'SAMBANOVA_API_KEY', provider: 'sambanova' },
|
|
543
|
+
{ env: 'CEREBRAS_API_KEY', provider: 'cerebras' },
|
|
544
|
+
{ env: 'OPENROUTER_API_KEY', provider: 'openrouter' },
|
|
491
545
|
];
|
|
492
546
|
for (const { env, provider } of envKeys) {
|
|
493
547
|
if (process.env[env])
|
|
@@ -513,6 +567,8 @@ async function main() {
|
|
|
513
567
|
setPermissionMode('permissive');
|
|
514
568
|
}
|
|
515
569
|
}
|
|
570
|
+
// Register built-in agents (hacker, operator, dreamer) so --agent flag works
|
|
571
|
+
registerBuiltinAgents();
|
|
516
572
|
// Parallel startup: register tools, gather context, check updates, and cloud sync
|
|
517
573
|
const [, context, , syncMsg] = await Promise.all([
|
|
518
574
|
registerAllTools({ computerUse: opts.computerUse }),
|
|
@@ -542,6 +598,11 @@ async function main() {
|
|
|
542
598
|
thinking: opts.thinking || false,
|
|
543
599
|
thinkingBudget: opts.thinkingBudget ? (parseInt(opts.thinkingBudget, 10) || 10000) : undefined,
|
|
544
600
|
};
|
|
601
|
+
// Enable self-evaluation if requested
|
|
602
|
+
if (opts.selfEval) {
|
|
603
|
+
const { setSelfEvalEnabled } = await import('./self-eval.js');
|
|
604
|
+
setSelfEvalEnabled(true);
|
|
605
|
+
}
|
|
545
606
|
// Pipe mode: echo "prompt" | kbot -p OR kbot -p "prompt"
|
|
546
607
|
if (opts.pipe) {
|
|
547
608
|
let message = promptArgs.join(' ');
|
|
@@ -739,12 +800,13 @@ async function byokFlow() {
|
|
|
739
800
|
async function guidedSetup() {
|
|
740
801
|
console.log(banner(VERSION));
|
|
741
802
|
console.log();
|
|
742
|
-
console.log(chalk.bold('
|
|
803
|
+
console.log(chalk.bold(' Hey! I\'m K:BOT — your AI assistant for the terminal.'));
|
|
743
804
|
console.log();
|
|
744
|
-
console.log(chalk.dim('
|
|
805
|
+
console.log(chalk.dim(' I can write code, answer questions, search the web, manage git,'));
|
|
806
|
+
console.log(chalk.dim(' and a lot more. First, I need an AI brain. Pick one:'));
|
|
745
807
|
console.log();
|
|
746
|
-
console.log(` ${chalk.bold('1.')} ${chalk.hex('#6B8E6B')('Free & Private')} — Run AI on your computer (no account
|
|
747
|
-
console.log(` ${chalk.bold('2.')} ${chalk.hex('#5B8BA0')('Cloud AI')} — Use an API key
|
|
808
|
+
console.log(` ${chalk.bold('1.')} ${chalk.hex('#6B8E6B')('Free & Private')} — Run AI on your computer (no account, no cost)`);
|
|
809
|
+
console.log(` ${chalk.bold('2.')} ${chalk.hex('#5B8BA0')('Cloud AI')} — Use an API key (OpenAI, Google, Anthropic, etc.)`);
|
|
748
810
|
console.log();
|
|
749
811
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
750
812
|
const choice = await new Promise((resolve) => {
|
|
@@ -885,14 +947,48 @@ async function startRepl(agentOpts, context, tier, byokActive = false, localActi
|
|
|
885
947
|
printInfo(`${p.name}`);
|
|
886
948
|
}
|
|
887
949
|
const sessionCount = incrementSessions();
|
|
950
|
+
// Return-visit greeting — show kbot's growth
|
|
951
|
+
if (sessionCount > 1) {
|
|
952
|
+
const stats = getExtendedStats();
|
|
953
|
+
const parts = [];
|
|
954
|
+
if (stats.patternsCount > 0)
|
|
955
|
+
parts.push(`${stats.patternsCount} patterns learned`);
|
|
956
|
+
if (stats.solutionsCount > 0)
|
|
957
|
+
parts.push(`${stats.solutionsCount} solutions cached`);
|
|
958
|
+
if (stats.knowledgeCount > 0)
|
|
959
|
+
parts.push(`${stats.knowledgeCount} facts remembered`);
|
|
960
|
+
if (parts.length > 0) {
|
|
961
|
+
printInfo(`Session ${stats.sessions} · ${parts.join(' · ')}`);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
888
964
|
const rl = createInterface({
|
|
889
965
|
input: process.stdin,
|
|
890
966
|
output: process.stdout,
|
|
891
967
|
prompt: kbotPrompt(),
|
|
892
968
|
});
|
|
893
|
-
// First time? Show a
|
|
969
|
+
// First time? Show a friendly walkthrough
|
|
894
970
|
if (sessionCount <= 1) {
|
|
895
|
-
|
|
971
|
+
console.log();
|
|
972
|
+
console.log(chalk.dim(' ┌─────────────────────────────────────────────┐'));
|
|
973
|
+
console.log(chalk.dim(' │') + chalk.bold(' Welcome! Here are some things you can try: ') + chalk.dim(' │'));
|
|
974
|
+
console.log(chalk.dim(' │ │'));
|
|
975
|
+
console.log(chalk.dim(' │') + ' "explain this project" ' + chalk.dim(' │'));
|
|
976
|
+
console.log(chalk.dim(' │') + ' "write a function that sorts names" ' + chalk.dim(' │'));
|
|
977
|
+
console.log(chalk.dim(' │') + ' "find all TODO comments in this repo" ' + chalk.dim(' │'));
|
|
978
|
+
console.log(chalk.dim(' │') + ' "what files are in this directory?" ' + chalk.dim(' │'));
|
|
979
|
+
console.log(chalk.dim(' │ │'));
|
|
980
|
+
console.log(chalk.dim(' │') + chalk.dim(' Type /help for more commands. ') + chalk.dim(' │'));
|
|
981
|
+
console.log(chalk.dim(' └─────────────────────────────────────────────┘'));
|
|
982
|
+
console.log();
|
|
983
|
+
}
|
|
984
|
+
else if (sessionCount <= 3) {
|
|
985
|
+
// Second and third time — show a quick tip they might not know
|
|
986
|
+
const tips = [
|
|
987
|
+
'Tip: kbot picks the right specialist for you. Try asking about science, code, or writing.',
|
|
988
|
+
'Tip: Type /save to keep this conversation. /resume to pick it up later.',
|
|
989
|
+
'Tip: kbot learns from you. The more you use it, the better it gets.',
|
|
990
|
+
];
|
|
991
|
+
printInfo(tips[Math.min(sessionCount - 1, tips.length - 1)]);
|
|
896
992
|
}
|
|
897
993
|
console.log();
|
|
898
994
|
rl.prompt();
|
|
@@ -929,12 +1025,28 @@ async function startRepl(agentOpts, context, tier, byokActive = false, localActi
|
|
|
929
1025
|
if (!response.streamed) {
|
|
930
1026
|
printResponse(response.agent, response.content);
|
|
931
1027
|
}
|
|
932
|
-
//
|
|
933
|
-
|
|
934
|
-
const
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1028
|
+
// Mentor footer — teach the user what kbot did (agent, tools, cost)
|
|
1029
|
+
{
|
|
1030
|
+
const parts = [];
|
|
1031
|
+
// Show which agent handled it (teaches routing)
|
|
1032
|
+
if (response.agent && response.agent !== 'kernel') {
|
|
1033
|
+
parts.push(`${response.agent} agent`);
|
|
1034
|
+
}
|
|
1035
|
+
if (response.toolCalls > 0) {
|
|
1036
|
+
parts.push(`${response.toolCalls} tool${response.toolCalls > 1 ? 's' : ''} used`);
|
|
1037
|
+
}
|
|
1038
|
+
if (response.usage) {
|
|
1039
|
+
const tokens = response.usage.input_tokens + response.usage.output_tokens;
|
|
1040
|
+
const cost = response.usage.cost_usd === 0 ? 'free' : `$${response.usage.cost_usd.toFixed(4)}`;
|
|
1041
|
+
parts.push(`${tokens} tokens · ${cost}`);
|
|
1042
|
+
}
|
|
1043
|
+
if (parts.length > 0) {
|
|
1044
|
+
printInfo(parts.join(' · '));
|
|
1045
|
+
}
|
|
1046
|
+
// On first 5 sessions, teach what just happened
|
|
1047
|
+
if (sessionCount <= 5 && response.agent && response.agent !== 'kernel') {
|
|
1048
|
+
printInfo(chalk.dim(` I picked the ${response.agent} agent for this. You can also say /agent ${response.agent} to use it directly.`));
|
|
1049
|
+
}
|
|
938
1050
|
}
|
|
939
1051
|
// Schedule cloud sync push (debounced — batches writes)
|
|
940
1052
|
schedulePush();
|
|
@@ -1071,6 +1183,47 @@ async function handleSlashCommand(input, opts, rl) {
|
|
|
1071
1183
|
case 'help':
|
|
1072
1184
|
printHelp();
|
|
1073
1185
|
break;
|
|
1186
|
+
case 'tutorial': {
|
|
1187
|
+
console.log();
|
|
1188
|
+
console.log(chalk.bold(' Let\'s build something together. Pick a track:'));
|
|
1189
|
+
console.log();
|
|
1190
|
+
console.log(` ${chalk.bold('1.')} ${chalk.hex('#4ADE80')('Build a website')} — Create an HTML page from scratch`);
|
|
1191
|
+
console.log(` ${chalk.bold('2.')} ${chalk.hex('#60A5FA')('Fix a bug')} — Find and fix a problem in code`);
|
|
1192
|
+
console.log(` ${chalk.bold('3.')} ${chalk.hex('#FB923C')('Write a script')} — Automate something with Python or JavaScript`);
|
|
1193
|
+
console.log(` ${chalk.bold('4.')} ${chalk.hex('#F472B6')('Research a topic')} — Deep-dive into any subject`);
|
|
1194
|
+
console.log(` ${chalk.bold('5.')} ${chalk.hex('#A78BFA')('Explore this project')} — Understand the code in this folder`);
|
|
1195
|
+
console.log();
|
|
1196
|
+
console.log(chalk.dim(' Pick a number, or just type what you want to build.'));
|
|
1197
|
+
console.log();
|
|
1198
|
+
const tutorialInput = await new Promise((resolve) => {
|
|
1199
|
+
rl.question(' Your choice: ', (answer) => resolve(answer.trim()));
|
|
1200
|
+
});
|
|
1201
|
+
const tutorialPrompts = {
|
|
1202
|
+
'1': 'Create a simple, beautiful HTML page with a heading, a paragraph about me, and some CSS styling. Save it as index.html. Walk me through what each part does.',
|
|
1203
|
+
'2': 'Look at the files in this directory. Find any issues, bugs, or things that could be improved. Explain what you found and fix the most important one.',
|
|
1204
|
+
'3': 'Write a short script that lists all files in the current directory, sorted by size. Use the language that makes the most sense for this project. Explain each line.',
|
|
1205
|
+
'4': 'I want to understand how AI agents work. Research this topic and explain it simply — what are agents, how do they think, and what tools do they use? Give real examples.',
|
|
1206
|
+
'5': 'Explore this project directory. What language is it written in? What does it do? What are the most important files? Give me a quick tour.',
|
|
1207
|
+
};
|
|
1208
|
+
const prompt = tutorialPrompts[tutorialInput] || tutorialInput;
|
|
1209
|
+
if (prompt) {
|
|
1210
|
+
console.log();
|
|
1211
|
+
printInfo('Great choice! Let me work on that...');
|
|
1212
|
+
console.log();
|
|
1213
|
+
try {
|
|
1214
|
+
const response = await runAgent(prompt, opts);
|
|
1215
|
+
if (!response.streamed) {
|
|
1216
|
+
printResponse(response.agent, response.content);
|
|
1217
|
+
}
|
|
1218
|
+
console.log();
|
|
1219
|
+
printInfo(chalk.dim('That\'s the basics! Keep asking questions — I learn from every conversation.'));
|
|
1220
|
+
}
|
|
1221
|
+
catch (err) {
|
|
1222
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
break;
|
|
1226
|
+
}
|
|
1074
1227
|
case 'agent':
|
|
1075
1228
|
if (args[0]) {
|
|
1076
1229
|
opts.agent = args[0];
|
|
@@ -1241,6 +1394,37 @@ async function handleSlashCommand(input, opts, rl) {
|
|
|
1241
1394
|
if (opts.thinking)
|
|
1242
1395
|
printInfo('AI will show reasoning steps before responding.');
|
|
1243
1396
|
break;
|
|
1397
|
+
case 'self-eval':
|
|
1398
|
+
case 'selfeval': {
|
|
1399
|
+
const { isSelfEvalEnabled, setSelfEvalEnabled } = await import('./self-eval.js');
|
|
1400
|
+
const newState = !isSelfEvalEnabled();
|
|
1401
|
+
setSelfEvalEnabled(newState);
|
|
1402
|
+
printSuccess(`Self-evaluation: ${newState ? 'ON' : 'OFF'}`);
|
|
1403
|
+
if (newState)
|
|
1404
|
+
printInfo('Responses will be scored for quality and retried if below threshold.');
|
|
1405
|
+
break;
|
|
1406
|
+
}
|
|
1407
|
+
case 'health':
|
|
1408
|
+
case 'providers': {
|
|
1409
|
+
const { getProviderHealth } = await import('./provider-fallback.js');
|
|
1410
|
+
const health = getProviderHealth();
|
|
1411
|
+
const active = health.filter(h => h.lastSuccess || h.lastFailure);
|
|
1412
|
+
if (active.length === 0) {
|
|
1413
|
+
printInfo('No provider calls recorded yet.');
|
|
1414
|
+
}
|
|
1415
|
+
else {
|
|
1416
|
+
console.log();
|
|
1417
|
+
printInfo('Provider Health:');
|
|
1418
|
+
for (const h of active) {
|
|
1419
|
+
const status = h.isHealthy ? chalk.green('healthy') : chalk.red('unhealthy');
|
|
1420
|
+
const latency = h.avgLatencyMs ? `${h.avgLatencyMs}ms` : '-';
|
|
1421
|
+
const failures = h.consecutiveFailures > 0 ? chalk.yellow(` (${h.consecutiveFailures} failures)`) : '';
|
|
1422
|
+
printInfo(` ${h.provider}: ${status} · ${latency}${failures}`);
|
|
1423
|
+
}
|
|
1424
|
+
console.log();
|
|
1425
|
+
}
|
|
1426
|
+
break;
|
|
1427
|
+
}
|
|
1244
1428
|
case 'plan': {
|
|
1245
1429
|
const planTask = args.join(' ');
|
|
1246
1430
|
if (!planTask) {
|
|
@@ -1513,7 +1697,8 @@ async function handleSlashCommand(input, opts, rl) {
|
|
|
1513
1697
|
rl.close();
|
|
1514
1698
|
break;
|
|
1515
1699
|
default:
|
|
1516
|
-
printError(`
|
|
1700
|
+
printError(`I don't know "/${cmd}". Here are some you can try:`);
|
|
1701
|
+
printInfo(' /save — save this chat | /agent — pick a specialist | /help — see everything');
|
|
1517
1702
|
}
|
|
1518
1703
|
}
|
|
1519
1704
|
// Prevent unhandled rejections from killing the process
|