@kernel.chat/kbot 3.97.4 → 3.99.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/agent.js +22 -1
- package/dist/cli.js +163 -0
- package/dist/skills-loader.d.ts +37 -5
- package/dist/skills-loader.js +342 -50
- package/dist/teacher-logger.d.ts +71 -0
- package/dist/teacher-logger.js +162 -0
- package/dist/tools/idempotency-check.d.ts +2 -0
- package/dist/tools/idempotency-check.js +31 -0
- package/dist/tools/schedule-persistence.d.ts +2 -0
- package/dist/tools/schedule-persistence.js +19 -0
- package/dist/train-agent-trace.d.ts +29 -0
- package/dist/train-agent-trace.js +141 -0
- package/dist/train-curate.d.ts +25 -0
- package/dist/train-curate.js +354 -0
- package/dist/train-cycle.d.ts +22 -0
- package/dist/train-cycle.js +230 -0
- package/dist/train-grpo.d.ts +68 -0
- package/dist/train-grpo.js +206 -0
- package/dist/train-merge.d.ts +26 -0
- package/dist/train-merge.js +148 -0
- package/dist/train-self.d.ts +38 -0
- package/dist/train-self.js +232 -0
- package/package.json +2 -1
- package/skills/deployment/daemon-deployment/SKILL.md +70 -0
- package/skills/deployment/ship-pipeline/SKILL.md +81 -0
- package/skills/emergent/forge-reflex/SKILL.md +53 -0
- package/skills/emergent/mimic-hybrid/SKILL.md +56 -0
- package/skills/memory/dream-to-commit/SKILL.md +52 -0
- package/skills/memory/memory-cascade/SKILL.md +59 -0
- package/skills/music-production/ableton-session-build/SKILL.md +61 -0
- package/skills/orchestration/cross-agent-blackboard/SKILL.md +58 -0
- package/skills/orchestration/specialist-routing/SKILL.md +57 -0
- package/skills/self-improvement/autopoiesis-loop/SKILL.md +47 -0
- package/skills/self-improvement/skill-self-authorship/SKILL.md +70 -0
- package/skills/self-improvement/teacher-trace-curation/SKILL.md +54 -0
- package/skills/software-development/systematic-debugging/SKILL.md +86 -0
- package/skills/software-development/test-driven-development/SKILL.md +74 -0
package/dist/agent.js
CHANGED
|
@@ -654,6 +654,19 @@ function isComplexTask(message) {
|
|
|
654
654
|
async function callProvider(provider, apiKey, model, systemContext, messages, tools, options) {
|
|
655
655
|
const p = getProvider(provider);
|
|
656
656
|
const startTime = Date.now();
|
|
657
|
+
// Teacher logger — captures (prompt, response) pairs for later distillation.
|
|
658
|
+
// Disabled for local providers (already free) and when KBOT_TEACHER_LOG=0.
|
|
659
|
+
const { getTeacherLogger } = await import('./teacher-logger.js');
|
|
660
|
+
const teacher = getTeacherLogger();
|
|
661
|
+
const teacherId = (teacher.isEnabled() && !isLocalProvider(provider))
|
|
662
|
+
? teacher.begin({
|
|
663
|
+
sessionId: options?.sessionId,
|
|
664
|
+
provider,
|
|
665
|
+
model,
|
|
666
|
+
system: systemContext,
|
|
667
|
+
messages: messages.map(m => ({ role: m.role, content: m.content })),
|
|
668
|
+
})
|
|
669
|
+
: '';
|
|
657
670
|
try {
|
|
658
671
|
let result;
|
|
659
672
|
// Embedded inference — runs in-process via node-llama-cpp, no HTTP
|
|
@@ -692,6 +705,14 @@ async function callProvider(provider, apiKey, model, systemContext, messages, to
|
|
|
692
705
|
}
|
|
693
706
|
}
|
|
694
707
|
recordSuccess(provider, Date.now() - startTime);
|
|
708
|
+
if (teacherId) {
|
|
709
|
+
teacher.end(teacherId, {
|
|
710
|
+
content: result.content,
|
|
711
|
+
thinking: result.thinking,
|
|
712
|
+
tool_calls: result.tool_calls,
|
|
713
|
+
stop_reason: result.stop_reason,
|
|
714
|
+
}, result.usage);
|
|
715
|
+
}
|
|
695
716
|
return result;
|
|
696
717
|
}
|
|
697
718
|
catch (err) {
|
|
@@ -854,7 +875,7 @@ export async function runAgent(message, options = {}) {
|
|
|
854
875
|
// Step 2: Build context (cached — only rebuilt when inputs change)
|
|
855
876
|
const matrixPrompt = options.agent ? getMatrixSystemPrompt(options.agent) : null;
|
|
856
877
|
const contextSnippet = options.context ? formatContextForPrompt(options.context) : '';
|
|
857
|
-
const skillsSnippet = loadSkills(process.cwd());
|
|
878
|
+
const skillsSnippet = loadSkills(process.cwd(), message);
|
|
858
879
|
const memorySnippet = getMemoryPrompt();
|
|
859
880
|
const learningContext = buildFullLearningContext(message, process.cwd());
|
|
860
881
|
const synthesisSnippet = getSynthesisContext(8); // Three-tier memory: reflection layer insights
|
package/dist/cli.js
CHANGED
|
@@ -835,6 +835,50 @@ async function main() {
|
|
|
835
835
|
ignorePatterns,
|
|
836
836
|
});
|
|
837
837
|
});
|
|
838
|
+
const skillsCmd = program.command('skills').description('Manage agent skills (agentskills.io format — compatible with Claude Skills, Hermes, Copilot)');
|
|
839
|
+
skillsCmd
|
|
840
|
+
.command('list')
|
|
841
|
+
.description('List all discovered skills')
|
|
842
|
+
.action(async () => {
|
|
843
|
+
const { discoverSkillFiles } = await import('./skills-loader.js');
|
|
844
|
+
const skills = discoverSkillFiles(process.cwd());
|
|
845
|
+
if (skills.length === 0) {
|
|
846
|
+
printInfo('No skills found. Run `kbot skills import --from hermes` to import 76 Hermes skills.');
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
printInfo(`Found ${skills.length} skill${skills.length === 1 ? '' : 's'}:\n`);
|
|
850
|
+
for (const s of skills) {
|
|
851
|
+
const desc = s.description ? ` — ${s.description.slice(0, 70)}` : '';
|
|
852
|
+
printInfo(` ${s.name}${desc}`);
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
skillsCmd
|
|
856
|
+
.command('import')
|
|
857
|
+
.description('Import skills from an external agent (Hermes, Claude, or a custom directory)')
|
|
858
|
+
.option('--from <source>', 'Source: hermes, claude, or an absolute path', 'hermes')
|
|
859
|
+
.action(async (opts) => {
|
|
860
|
+
const { importExternalSkills } = await import('./skills-loader.js');
|
|
861
|
+
const { homedir } = await import('node:os');
|
|
862
|
+
const { join } = await import('node:path');
|
|
863
|
+
const { existsSync } = await import('node:fs');
|
|
864
|
+
const sources = {
|
|
865
|
+
hermes: join(homedir(), '.hermes', 'skills'),
|
|
866
|
+
claude: join(homedir(), '.claude', 'skills'),
|
|
867
|
+
};
|
|
868
|
+
const from = opts.from || 'hermes';
|
|
869
|
+
const src = sources[from] || from;
|
|
870
|
+
if (!existsSync(src)) {
|
|
871
|
+
printError(`Source not found: ${src}`);
|
|
872
|
+
if (from === 'hermes')
|
|
873
|
+
printInfo('Install Hermes: `ollama launch hermes --yes --model hermes3:8b`');
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
const result = await importExternalSkills(src);
|
|
877
|
+
printSuccess(`Imported ${result.imported} skill${result.imported === 1 ? '' : 's'} from ${src}`);
|
|
878
|
+
if (result.skipped > 0)
|
|
879
|
+
printInfo(` ${result.skipped} skipped (existing user-authored files preserved)`);
|
|
880
|
+
printInfo(` → ${result.destination}`);
|
|
881
|
+
});
|
|
838
882
|
program
|
|
839
883
|
.command('doctor')
|
|
840
884
|
.description('Diagnose your kbot setup — check everything is working')
|
|
@@ -3875,6 +3919,125 @@ async function main() {
|
|
|
3875
3919
|
pikaCmd.action(() => {
|
|
3876
3920
|
pikaCmd.commands.find(c => c.name() === 'status')?.parse(['', '', 'status']);
|
|
3877
3921
|
});
|
|
3922
|
+
// ── train-self / train-cycle / train-merge / train-grpo ──
|
|
3923
|
+
// Fine-tune a local model on your own agent sessions.
|
|
3924
|
+
program
|
|
3925
|
+
.command('train-self')
|
|
3926
|
+
.description('Fine-tune a local model on your own kbot sessions (MLX LoRA)')
|
|
3927
|
+
.option('--mode <mode>', 'default | reasoning | agent-trace | code-only', 'default')
|
|
3928
|
+
.option('--base-model <model>', 'Override base model (HF path or mlx-community/*)')
|
|
3929
|
+
.option('--output-name <name>', 'Ollama model name to register')
|
|
3930
|
+
.option('--backend <backend>', 'mlx | unsloth | llama-cpp | together', 'mlx')
|
|
3931
|
+
.option('--iters <n>', 'Training iterations', (v) => parseInt(v, 10))
|
|
3932
|
+
.option('--batch-size <n>', 'Batch size', (v) => parseInt(v, 10))
|
|
3933
|
+
.option('--num-layers <n>', 'LoRA layers', (v) => parseInt(v, 10))
|
|
3934
|
+
.option('--learning-rate <lr>', 'Learning rate', parseFloat)
|
|
3935
|
+
.option('--max-examples <n>', 'Cap curated examples', (v) => parseInt(v, 10))
|
|
3936
|
+
.option('--dry-run', 'Curate only, do not train')
|
|
3937
|
+
.option('--skip-curate', 'Skip curation (use existing dataset)')
|
|
3938
|
+
.option('--skip-train', 'Skip training (prepare + deploy only)')
|
|
3939
|
+
.option('--skip-deploy', 'Skip Ollama deploy')
|
|
3940
|
+
.option('--no-grad-checkpoint', 'Disable gradient checkpointing')
|
|
3941
|
+
.action(async (opts) => {
|
|
3942
|
+
const { trainSelf, formatTrainSelfReport } = await import('./train-self.js');
|
|
3943
|
+
const r = await trainSelf({
|
|
3944
|
+
mode: opts.mode,
|
|
3945
|
+
baseModel: opts.baseModel,
|
|
3946
|
+
outputName: opts.outputName,
|
|
3947
|
+
backend: opts.backend,
|
|
3948
|
+
iters: opts.iters,
|
|
3949
|
+
batchSize: opts.batchSize,
|
|
3950
|
+
numLayers: opts.numLayers,
|
|
3951
|
+
learningRate: opts.learningRate,
|
|
3952
|
+
maxExamples: opts.maxExamples,
|
|
3953
|
+
dryRun: Boolean(opts.dryRun),
|
|
3954
|
+
skipCurate: Boolean(opts.skipCurate),
|
|
3955
|
+
skipTrain: Boolean(opts.skipTrain),
|
|
3956
|
+
skipDeploy: Boolean(opts.skipDeploy),
|
|
3957
|
+
gradCheckpoint: opts.gradCheckpoint !== false,
|
|
3958
|
+
});
|
|
3959
|
+
console.log(formatTrainSelfReport(r));
|
|
3960
|
+
});
|
|
3961
|
+
program
|
|
3962
|
+
.command('train-cycle')
|
|
3963
|
+
.description('On-policy distillation: student generates → Claude grades/corrects → retrain')
|
|
3964
|
+
.option('--student <model>', 'Local student model (Ollama)', 'kernel-coder:latest')
|
|
3965
|
+
.option('--teacher <model>', 'Teacher model', 'claude-opus-4-6')
|
|
3966
|
+
.option('--samples <n>', 'Prompts to sample per cycle', (v) => parseInt(v, 10), 50)
|
|
3967
|
+
.option('--threshold <score>', 'Pass threshold 0..1', parseFloat, 0.6)
|
|
3968
|
+
.option('--retrain', 'Trigger train-self after collecting corrections')
|
|
3969
|
+
.option('--dry-run', 'Skip teacher grading, just test student generation')
|
|
3970
|
+
.action(async (opts) => {
|
|
3971
|
+
const { runCycle, formatCycleReport } = await import('./train-cycle.js');
|
|
3972
|
+
const r = await runCycle({
|
|
3973
|
+
studentModel: opts.student,
|
|
3974
|
+
teacherModel: opts.teacher,
|
|
3975
|
+
samples: opts.samples,
|
|
3976
|
+
passThreshold: opts.threshold,
|
|
3977
|
+
retrain: Boolean(opts.retrain),
|
|
3978
|
+
dryRun: Boolean(opts.dryRun),
|
|
3979
|
+
});
|
|
3980
|
+
console.log(formatCycleReport(r));
|
|
3981
|
+
});
|
|
3982
|
+
program
|
|
3983
|
+
.command('train-merge')
|
|
3984
|
+
.description('Merge models via MergeKit (TIES/SLERP/DARE)')
|
|
3985
|
+
.option('--method <method>', 'ties | slerp | dare_ties | linear', 'ties')
|
|
3986
|
+
.option('--base <model>', 'Base model (HF path)', 'Qwen/Qwen2.5-Coder-7B-Instruct')
|
|
3987
|
+
.option('--output <name>', 'Output name')
|
|
3988
|
+
.option('--default', 'Use kbot triad defaults (qwen-coder + deepseek-r1 + self)')
|
|
3989
|
+
.option('--deploy', 'Register with Ollama after merge')
|
|
3990
|
+
.action(async (opts) => {
|
|
3991
|
+
const { mergeKbotDefault, mergeModels, formatMergeReport } = await import('./train-merge.js');
|
|
3992
|
+
if (opts.default) {
|
|
3993
|
+
const r = await mergeKbotDefault();
|
|
3994
|
+
console.log(formatMergeReport(r));
|
|
3995
|
+
return;
|
|
3996
|
+
}
|
|
3997
|
+
const r = await mergeModels({
|
|
3998
|
+
method: opts.method,
|
|
3999
|
+
baseModel: opts.base,
|
|
4000
|
+
models: [
|
|
4001
|
+
{ model: opts.base, weight: 1, density: 0.5 },
|
|
4002
|
+
],
|
|
4003
|
+
outputName: opts.output,
|
|
4004
|
+
deploy: Boolean(opts.deploy),
|
|
4005
|
+
});
|
|
4006
|
+
console.log(formatMergeReport(r));
|
|
4007
|
+
});
|
|
4008
|
+
program
|
|
4009
|
+
.command('train-grpo')
|
|
4010
|
+
.description('GRPO on verifiable tasks (build-pass, test-pass, regex-match, json-valid)')
|
|
4011
|
+
.option('--student <model>', 'Student model', 'kernel-coder:latest')
|
|
4012
|
+
.option('--group-size <n>', 'Rollouts per prompt', (v) => parseInt(v, 10), 8)
|
|
4013
|
+
.option('--iters <n>', 'Outer iterations', (v) => parseInt(v, 10), 100)
|
|
4014
|
+
.option('--dry-run', 'Collect rollouts only, do not update weights')
|
|
4015
|
+
.option('--runner-cmd <cmd>', 'External GRPO runner command')
|
|
4016
|
+
.action(async (opts) => {
|
|
4017
|
+
const { runGrpoRollouts, DEFAULT_VERIFIER_SUITE, formatGrpoReport } = await import('./train-grpo.js');
|
|
4018
|
+
const r = await runGrpoRollouts({
|
|
4019
|
+
studentModel: opts.student,
|
|
4020
|
+
prompts: DEFAULT_VERIFIER_SUITE,
|
|
4021
|
+
groupSize: opts.groupSize,
|
|
4022
|
+
iters: opts.iters,
|
|
4023
|
+
dryRun: Boolean(opts.dryRun),
|
|
4024
|
+
runnerCmd: opts.runnerCmd,
|
|
4025
|
+
});
|
|
4026
|
+
console.log(formatGrpoReport(r));
|
|
4027
|
+
});
|
|
4028
|
+
program
|
|
4029
|
+
.command('train-agent-trace')
|
|
4030
|
+
.description('Reformat tool-use traces as agent training examples')
|
|
4031
|
+
.option('--min-tools <n>', 'Minimum tool calls per trajectory', (v) => parseInt(v, 10), 1)
|
|
4032
|
+
.option('--verified-only', 'Only use trajectories tagged verified')
|
|
4033
|
+
.action(async (opts) => {
|
|
4034
|
+
const { formatAgentTraces, formatAgentTraceReport } = await import('./train-agent-trace.js');
|
|
4035
|
+
const r = formatAgentTraces({
|
|
4036
|
+
minTools: opts.minTools,
|
|
4037
|
+
verifiedOnly: Boolean(opts.verifiedOnly),
|
|
4038
|
+
});
|
|
4039
|
+
console.log(formatAgentTraceReport(r));
|
|
4040
|
+
});
|
|
3878
4041
|
program.parse(process.argv);
|
|
3879
4042
|
const opts = program.opts();
|
|
3880
4043
|
const promptArgs = program.args;
|
package/dist/skills-loader.d.ts
CHANGED
|
@@ -2,16 +2,48 @@ export interface SkillFile {
|
|
|
2
2
|
name: string;
|
|
3
3
|
path: string;
|
|
4
4
|
content: string;
|
|
5
|
+
description: string;
|
|
6
|
+
tags: string[];
|
|
5
7
|
tokens: number;
|
|
8
|
+
/** Skill only activates when these toolsets are available (Hermes: requires_toolsets) */
|
|
9
|
+
requiresToolsets: string[];
|
|
10
|
+
/** Skill only activates when these toolsets are UNAVAILABLE (fallback path) */
|
|
11
|
+
fallbackForToolsets: string[];
|
|
12
|
+
/** OS platforms this skill supports; empty = all */
|
|
13
|
+
platforms: string[];
|
|
14
|
+
/** Related skill names */
|
|
15
|
+
relatedSkills: string[];
|
|
16
|
+
/** True for skills that ship with kbot or declare `metadata.kbot.*` — boosted in ranking */
|
|
17
|
+
native: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface SkillLoadContext {
|
|
20
|
+
/** Toolsets currently available — skills can require/fall-back based on these */
|
|
21
|
+
availableToolsets?: string[];
|
|
22
|
+
/** Current OS platform, e.g. 'darwin' | 'linux' | 'win32' */
|
|
23
|
+
platform?: string;
|
|
6
24
|
}
|
|
7
25
|
/**
|
|
8
|
-
* Discover and load skill files
|
|
9
|
-
*
|
|
26
|
+
* Discover and load skill files. Returns a prompt-ready string.
|
|
27
|
+
* When `message` is provided, skills are scored for relevance and only the
|
|
28
|
+
* most relevant are included (keeps token budget tight with a large library).
|
|
10
29
|
*/
|
|
11
|
-
export declare function loadSkills(projectRoot: string): string;
|
|
30
|
+
export declare function loadSkills(projectRoot: string, message?: string, ctx?: SkillLoadContext): string;
|
|
12
31
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
32
|
+
* Walk both skill roots and return every skill document found.
|
|
33
|
+
* Handles flat files (name.md) AND subdirectory layouts (cat/name/SKILL.md).
|
|
34
|
+
* Project skills take precedence over global skills with the same name.
|
|
15
35
|
*/
|
|
16
36
|
export declare function discoverSkillFiles(projectRoot: string): SkillFile[];
|
|
37
|
+
export interface ImportResult {
|
|
38
|
+
imported: number;
|
|
39
|
+
skipped: number;
|
|
40
|
+
source: string;
|
|
41
|
+
destination: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Copy (as symlinks) every SKILL.md under a foreign skills directory
|
|
45
|
+
* into ~/.kbot/skills/imported/<category>/<name>/SKILL.md.
|
|
46
|
+
* Non-destructive: existing symlinks are replaced, real files are skipped.
|
|
47
|
+
*/
|
|
48
|
+
export declare function importExternalSkills(sourceRoot: string): Promise<ImportResult>;
|
|
17
49
|
//# sourceMappingURL=skills-loader.d.ts.map
|