@kernel.chat/kbot 3.97.1 → 3.98.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 +1 -1
- package/dist/agent.js +21 -0
- package/dist/cli.js +119 -0
- package/dist/teacher-logger.d.ts +71 -0
- package/dist/teacher-logger.js +162 -0
- package/dist/tools/ableton.js +176 -42
- package/dist/tools/estimation.d.ts +2 -0
- package/dist/tools/estimation.js +21 -0
- package/dist/tools/idempotency-check.d.ts +2 -0
- package/dist/tools/idempotency-check.js +31 -0
- package/dist/tools/idempotency-checker.d.ts +2 -0
- package/dist/tools/idempotency-checker.js +23 -0
- package/dist/tools/image-variation.d.ts +2 -0
- package/dist/tools/image-variation.js +31 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/one-prompt-producer.d.ts +2 -0
- package/dist/tools/one-prompt-producer.js +723 -0
- package/dist/tools/schedule-persistence.d.ts +2 -0
- package/dist/tools/schedule-persistence.js +19 -0
- package/dist/tools/sound-designer.js +278 -3
- 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 +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// kbot Schedule Persistence Tool — Reliable task scheduling
|
|
2
|
+
import { registerTool } from './index.js';
|
|
3
|
+
export function registerSchedulePersistenceTools() {
|
|
4
|
+
registerTool({
|
|
5
|
+
name: 'schedule_persist',
|
|
6
|
+
description: 'Persistently stores and retrieves schedules, ensuring tasks are executed even after interruptions.',
|
|
7
|
+
parameters: {
|
|
8
|
+
schedule: { type: 'string', description: 'The schedule to persist (JSON format)', required: true },
|
|
9
|
+
},
|
|
10
|
+
tier: 'pro',
|
|
11
|
+
async execute(args) {
|
|
12
|
+
const schedule = JSON.parse(String(args.schedule));
|
|
13
|
+
// Placeholder for persistence logic (replace with actual implementation)
|
|
14
|
+
console.log(`Persisting schedule: ${JSON.stringify(schedule)}`);
|
|
15
|
+
return 'Schedule persisted (implementation placeholder)';
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=schedule-persistence.js.map
|
|
@@ -537,6 +537,252 @@ const SOUND_RECIPES = {
|
|
|
537
537
|
},
|
|
538
538
|
description: 'Metallic pluck — inharmonic FM, bell-like attack, short decay',
|
|
539
539
|
},
|
|
540
|
+
// ─── Drift (analog-modeled synth) ───────────────────────────────────────
|
|
541
|
+
'drift_dark_bass': {
|
|
542
|
+
synth: 'Drift',
|
|
543
|
+
params: {
|
|
544
|
+
'Osc 1 Shape': 0.8, // Near-saw, harmonically rich
|
|
545
|
+
'Osc 2 On': 1,
|
|
546
|
+
'Osc 2 Shape': 0.6,
|
|
547
|
+
'Osc 2 Detune': 0.05,
|
|
548
|
+
'Osc 2 Level': 0.7,
|
|
549
|
+
'Filter Freq': 300,
|
|
550
|
+
'Filter Res': 0.25,
|
|
551
|
+
'Filter Drive': 0.4,
|
|
552
|
+
'Filter Type': 0, // LP
|
|
553
|
+
'Drift Amount': 0.3,
|
|
554
|
+
'LFO Rate': 0.4,
|
|
555
|
+
'LFO Amount': 0.1,
|
|
556
|
+
'LFO Dest': 0, // Filter
|
|
557
|
+
'Amp Attack': 0.005,
|
|
558
|
+
'Amp Decay': 0.4,
|
|
559
|
+
'Amp Sustain': 0.8,
|
|
560
|
+
'Amp Release': 0.2,
|
|
561
|
+
'Volume': 0.85,
|
|
562
|
+
},
|
|
563
|
+
description: 'Dark Drift bass — filtered saw with analog drift and subtle movement',
|
|
564
|
+
},
|
|
565
|
+
'drift_warm_bass': {
|
|
566
|
+
synth: 'Drift',
|
|
567
|
+
params: {
|
|
568
|
+
'Osc 1 Shape': 0.4, // Between triangle and saw
|
|
569
|
+
'Osc 2 On': 1,
|
|
570
|
+
'Osc 2 Shape': 0.3,
|
|
571
|
+
'Osc 2 Detune': 0.08,
|
|
572
|
+
'Osc 2 Level': 0.6,
|
|
573
|
+
'Filter Freq': 500,
|
|
574
|
+
'Filter Res': 0.15,
|
|
575
|
+
'Filter Drive': 0.2,
|
|
576
|
+
'Filter Type': 0, // LP
|
|
577
|
+
'Drift Amount': 0.5,
|
|
578
|
+
'LFO Rate': 0.2,
|
|
579
|
+
'LFO Amount': 0.08,
|
|
580
|
+
'LFO Dest': 0, // Filter
|
|
581
|
+
'Amp Attack': 0.01,
|
|
582
|
+
'Amp Decay': 0.3,
|
|
583
|
+
'Amp Sustain': 0.85,
|
|
584
|
+
'Amp Release': 0.25,
|
|
585
|
+
'Volume': 0.85,
|
|
586
|
+
},
|
|
587
|
+
description: 'Warm Drift bass — round and fat, gentle analog drift',
|
|
588
|
+
},
|
|
589
|
+
'drift_analog_lead': {
|
|
590
|
+
synth: 'Drift',
|
|
591
|
+
params: {
|
|
592
|
+
'Osc 1 Shape': 1.0, // Full saw
|
|
593
|
+
'Osc 2 On': 1,
|
|
594
|
+
'Osc 2 Shape': 0.9,
|
|
595
|
+
'Osc 2 Detune': 0.12,
|
|
596
|
+
'Osc 2 Level': 0.8,
|
|
597
|
+
'Filter Freq': 2500,
|
|
598
|
+
'Filter Res': 0.35,
|
|
599
|
+
'Filter Drive': 0.3,
|
|
600
|
+
'Filter Type': 0, // LP
|
|
601
|
+
'Drift Amount': 0.25,
|
|
602
|
+
'LFO Rate': 3.0,
|
|
603
|
+
'LFO Amount': 0.05,
|
|
604
|
+
'LFO Dest': 0, // Filter
|
|
605
|
+
'Amp Attack': 0.01,
|
|
606
|
+
'Amp Decay': 0.2,
|
|
607
|
+
'Amp Sustain': 0.85,
|
|
608
|
+
'Amp Release': 0.15,
|
|
609
|
+
'Volume': 0.75,
|
|
610
|
+
},
|
|
611
|
+
description: 'Analog Drift lead — detuned saws, resonant filter, vintage character',
|
|
612
|
+
},
|
|
613
|
+
'drift_lo_fi': {
|
|
614
|
+
synth: 'Drift',
|
|
615
|
+
params: {
|
|
616
|
+
'Osc 1 Shape': 0.5,
|
|
617
|
+
'Osc 2 On': 0,
|
|
618
|
+
'Filter Freq': 1200,
|
|
619
|
+
'Filter Res': 0.1,
|
|
620
|
+
'Filter Drive': 0.6, // Drive for lo-fi saturation
|
|
621
|
+
'Filter Type': 0, // LP
|
|
622
|
+
'Drift Amount': 0.7, // Heavy drift for wobble
|
|
623
|
+
'LFO Rate': 0.15,
|
|
624
|
+
'LFO Amount': 0.2,
|
|
625
|
+
'LFO Dest': 0, // Filter
|
|
626
|
+
'Amp Attack': 0.01,
|
|
627
|
+
'Amp Decay': 0.5,
|
|
628
|
+
'Amp Sustain': 0.6,
|
|
629
|
+
'Amp Release': 0.3,
|
|
630
|
+
'Volume': 0.7,
|
|
631
|
+
},
|
|
632
|
+
description: 'Lo-fi Drift — heavy drift, filter drive, warped and vintage',
|
|
633
|
+
effects: [{
|
|
634
|
+
name: 'Saturator',
|
|
635
|
+
params: { 'Drive': 8, 'Type': 1, 'Output': -3, 'Dry/Wet': 0.4 },
|
|
636
|
+
}],
|
|
637
|
+
},
|
|
638
|
+
'drift_ethereal_pad': {
|
|
639
|
+
synth: 'Drift',
|
|
640
|
+
params: {
|
|
641
|
+
'Osc 1 Shape': 0.3, // Soft, triangle-ish
|
|
642
|
+
'Osc 2 On': 1,
|
|
643
|
+
'Osc 2 Shape': 0.2,
|
|
644
|
+
'Osc 2 Detune': 0.15,
|
|
645
|
+
'Osc 2 Level': 0.6,
|
|
646
|
+
'Filter Freq': 1800,
|
|
647
|
+
'Filter Res': 0.2,
|
|
648
|
+
'Filter Drive': 0.1,
|
|
649
|
+
'Filter Type': 0, // LP
|
|
650
|
+
'Drift Amount': 0.6, // High drift for organic movement
|
|
651
|
+
'LFO Rate': 0.1,
|
|
652
|
+
'LFO Amount': 0.25,
|
|
653
|
+
'LFO Dest': 0, // Filter
|
|
654
|
+
'Amp Attack': 2.0,
|
|
655
|
+
'Amp Decay': 2.5,
|
|
656
|
+
'Amp Sustain': 0.5,
|
|
657
|
+
'Amp Release': 3.0,
|
|
658
|
+
'Volume': 0.65,
|
|
659
|
+
},
|
|
660
|
+
description: 'Ethereal Drift pad — slow, drifting, organic and alive',
|
|
661
|
+
effects: [{
|
|
662
|
+
name: 'Reverb',
|
|
663
|
+
params: { 'Decay Time': 5.0, 'Room Size': 0.85, 'Dry/Wet': 0.45 },
|
|
664
|
+
}],
|
|
665
|
+
},
|
|
666
|
+
// ─── Meld (MPE-capable bi-timbral synth) ──────────────────────────────
|
|
667
|
+
'meld_bright_pad': {
|
|
668
|
+
synth: 'Meld',
|
|
669
|
+
params: {
|
|
670
|
+
'Engine 1 Type': 0, // Harmonic engine
|
|
671
|
+
'Engine 1 Brightness': 0.7,
|
|
672
|
+
'Engine 1 Color': 0.6,
|
|
673
|
+
'Engine 1 Level': 0.8,
|
|
674
|
+
'Engine 2 On': 1,
|
|
675
|
+
'Engine 2 Type': 0, // Harmonic engine
|
|
676
|
+
'Engine 2 Brightness': 0.8,
|
|
677
|
+
'Engine 2 Color': 0.4,
|
|
678
|
+
'Engine 2 Level': 0.6,
|
|
679
|
+
'Filter Type': 0, // LP
|
|
680
|
+
'Filter Freq': 4000,
|
|
681
|
+
'Filter Res': 0.15,
|
|
682
|
+
'Amp Attack': 1.0,
|
|
683
|
+
'Amp Decay': 1.5,
|
|
684
|
+
'Amp Sustain': 0.7,
|
|
685
|
+
'Amp Release': 2.5,
|
|
686
|
+
'Volume': 0.7,
|
|
687
|
+
},
|
|
688
|
+
description: 'Bright Meld pad — dual harmonic engines, open and airy',
|
|
689
|
+
effects: [{
|
|
690
|
+
name: 'Chorus',
|
|
691
|
+
params: { 'Rate 1': 0.4, 'Amount 1': 0.25, 'Dry/Wet': 0.3 },
|
|
692
|
+
}],
|
|
693
|
+
},
|
|
694
|
+
'meld_dark_pad': {
|
|
695
|
+
synth: 'Meld',
|
|
696
|
+
params: {
|
|
697
|
+
'Engine 1 Type': 1, // Noise engine
|
|
698
|
+
'Engine 1 Brightness': 0.2,
|
|
699
|
+
'Engine 1 Color': 0.3,
|
|
700
|
+
'Engine 1 Level': 0.7,
|
|
701
|
+
'Engine 2 On': 1,
|
|
702
|
+
'Engine 2 Type': 0, // Harmonic engine
|
|
703
|
+
'Engine 2 Brightness': 0.2,
|
|
704
|
+
'Engine 2 Color': 0.5,
|
|
705
|
+
'Engine 2 Level': 0.8,
|
|
706
|
+
'Filter Type': 0, // LP
|
|
707
|
+
'Filter Freq': 600,
|
|
708
|
+
'Filter Res': 0.2,
|
|
709
|
+
'Amp Attack': 1.5,
|
|
710
|
+
'Amp Decay': 2.0,
|
|
711
|
+
'Amp Sustain': 0.6,
|
|
712
|
+
'Amp Release': 2.5,
|
|
713
|
+
'Volume': 0.7,
|
|
714
|
+
},
|
|
715
|
+
description: 'Dark Meld pad — noise + harmonic blend, moody and textured',
|
|
716
|
+
},
|
|
717
|
+
'meld_fm_bass': {
|
|
718
|
+
synth: 'Meld',
|
|
719
|
+
params: {
|
|
720
|
+
'Engine 1 Type': 2, // FM engine
|
|
721
|
+
'Engine 1 Brightness': 0.4,
|
|
722
|
+
'Engine 1 Color': 0.6,
|
|
723
|
+
'Engine 1 Level': 1.0,
|
|
724
|
+
'Engine 2 On': 0,
|
|
725
|
+
'Filter Type': 0, // LP
|
|
726
|
+
'Filter Freq': 450,
|
|
727
|
+
'Filter Res': 0.3,
|
|
728
|
+
'Amp Attack': 0.005,
|
|
729
|
+
'Amp Decay': 0.5,
|
|
730
|
+
'Amp Sustain': 0.7,
|
|
731
|
+
'Amp Release': 0.2,
|
|
732
|
+
'Volume': 0.85,
|
|
733
|
+
},
|
|
734
|
+
description: 'Meld FM bass — single FM engine, warm and punchy low end',
|
|
735
|
+
},
|
|
736
|
+
'meld_harmonic_lead': {
|
|
737
|
+
synth: 'Meld',
|
|
738
|
+
params: {
|
|
739
|
+
'Engine 1 Type': 0, // Harmonic engine
|
|
740
|
+
'Engine 1 Brightness': 0.6,
|
|
741
|
+
'Engine 1 Color': 0.7,
|
|
742
|
+
'Engine 1 Level': 1.0,
|
|
743
|
+
'Engine 2 On': 1,
|
|
744
|
+
'Engine 2 Type': 2, // FM engine
|
|
745
|
+
'Engine 2 Brightness': 0.5,
|
|
746
|
+
'Engine 2 Color': 0.5,
|
|
747
|
+
'Engine 2 Level': 0.4,
|
|
748
|
+
'Filter Type': 0, // LP
|
|
749
|
+
'Filter Freq': 3500,
|
|
750
|
+
'Filter Res': 0.25,
|
|
751
|
+
'Amp Attack': 0.01,
|
|
752
|
+
'Amp Decay': 0.3,
|
|
753
|
+
'Amp Sustain': 0.85,
|
|
754
|
+
'Amp Release': 0.15,
|
|
755
|
+
'Volume': 0.75,
|
|
756
|
+
},
|
|
757
|
+
description: 'Meld harmonic lead — bright harmonic engine with FM shimmer',
|
|
758
|
+
},
|
|
759
|
+
'meld_noise_texture': {
|
|
760
|
+
synth: 'Meld',
|
|
761
|
+
params: {
|
|
762
|
+
'Engine 1 Type': 1, // Noise engine
|
|
763
|
+
'Engine 1 Brightness': 0.5,
|
|
764
|
+
'Engine 1 Color': 0.4,
|
|
765
|
+
'Engine 1 Level': 0.8,
|
|
766
|
+
'Engine 2 On': 1,
|
|
767
|
+
'Engine 2 Type': 1, // Noise engine
|
|
768
|
+
'Engine 2 Brightness': 0.6,
|
|
769
|
+
'Engine 2 Color': 0.7,
|
|
770
|
+
'Engine 2 Level': 0.6,
|
|
771
|
+
'Filter Type': 1, // HP
|
|
772
|
+
'Filter Freq': 500,
|
|
773
|
+
'Filter Res': 0.15,
|
|
774
|
+
'Amp Attack': 2.0,
|
|
775
|
+
'Amp Decay': 3.0,
|
|
776
|
+
'Amp Sustain': 0.4,
|
|
777
|
+
'Amp Release': 3.5,
|
|
778
|
+
'Volume': 0.6,
|
|
779
|
+
},
|
|
780
|
+
description: 'Meld noise texture — dual noise engines, evolving ambient atmosphere',
|
|
781
|
+
effects: [{
|
|
782
|
+
name: 'Reverb',
|
|
783
|
+
params: { 'Decay Time': 6.0, 'Room Size': 0.9, 'Dry/Wet': 0.55 },
|
|
784
|
+
}],
|
|
785
|
+
},
|
|
540
786
|
// ─── FX ────────────────────────────────────────────────────────────────
|
|
541
787
|
'fx_riser': {
|
|
542
788
|
synth: 'Wavetable',
|
|
@@ -684,6 +930,32 @@ const MATCH_RULES = [
|
|
|
684
930
|
{ keywords: ['pluck', 'acoustic'], recipe: 'pluck_acoustic' },
|
|
685
931
|
{ keywords: ['pluck', 'natural'], recipe: 'pluck_acoustic' },
|
|
686
932
|
{ keywords: ['pluck'], recipe: 'pluck_acoustic' },
|
|
933
|
+
// Drift synth
|
|
934
|
+
{ keywords: ['drift', 'bass', 'dark'], recipe: 'drift_dark_bass' },
|
|
935
|
+
{ keywords: ['drift', 'bass', 'warm'], recipe: 'drift_warm_bass' },
|
|
936
|
+
{ keywords: ['drift', 'bass'], recipe: 'drift_dark_bass' },
|
|
937
|
+
{ keywords: ['drift', 'lead'], recipe: 'drift_analog_lead' },
|
|
938
|
+
{ keywords: ['drift', 'lo', 'fi'], recipe: 'drift_lo_fi' },
|
|
939
|
+
{ keywords: ['drift', 'lofi'], recipe: 'drift_lo_fi' },
|
|
940
|
+
{ keywords: ['drift', 'pad', 'dark'], recipe: 'dark_pad' },
|
|
941
|
+
{ keywords: ['drift', 'pad', 'ethereal'], recipe: 'drift_ethereal_pad' },
|
|
942
|
+
{ keywords: ['drift', 'pad'], recipe: 'drift_ethereal_pad' },
|
|
943
|
+
{ keywords: ['drift', 'analog'], recipe: 'drift_analog_lead' },
|
|
944
|
+
{ keywords: ['drift'], recipe: 'drift_dark_bass' },
|
|
945
|
+
// Meld synth
|
|
946
|
+
{ keywords: ['meld', 'pad', 'bright'], recipe: 'meld_bright_pad' },
|
|
947
|
+
{ keywords: ['meld', 'pad', 'dark'], recipe: 'meld_dark_pad' },
|
|
948
|
+
{ keywords: ['meld', 'pad'], recipe: 'meld_bright_pad' },
|
|
949
|
+
{ keywords: ['meld', 'bass'], recipe: 'meld_fm_bass' },
|
|
950
|
+
{ keywords: ['meld', 'fm'], recipe: 'meld_fm_bass' },
|
|
951
|
+
{ keywords: ['meld', 'lead'], recipe: 'meld_harmonic_lead' },
|
|
952
|
+
{ keywords: ['meld', 'harmonic'], recipe: 'meld_harmonic_lead' },
|
|
953
|
+
{ keywords: ['meld', 'noise'], recipe: 'meld_noise_texture' },
|
|
954
|
+
{ keywords: ['meld', 'texture'], recipe: 'meld_noise_texture' },
|
|
955
|
+
{ keywords: ['meld', 'ambient'], recipe: 'meld_noise_texture' },
|
|
956
|
+
{ keywords: ['meld', 'bright'], recipe: 'meld_bright_pad' },
|
|
957
|
+
{ keywords: ['meld', 'dark'], recipe: 'meld_dark_pad' },
|
|
958
|
+
{ keywords: ['meld'], recipe: 'meld_bright_pad' },
|
|
687
959
|
// FX
|
|
688
960
|
{ keywords: ['riser'], recipe: 'fx_riser' },
|
|
689
961
|
{ keywords: ['rise'], recipe: 'fx_riser' },
|
|
@@ -702,6 +974,7 @@ const SYNTH_NAME_MAP = {
|
|
|
702
974
|
'drift': 'Drift',
|
|
703
975
|
'analog': 'Analog',
|
|
704
976
|
'electric': 'Electric',
|
|
977
|
+
'meld': 'Meld',
|
|
705
978
|
'serum2': 'Serum 2',
|
|
706
979
|
'serum': 'Serum 2',
|
|
707
980
|
'vital': 'Vital',
|
|
@@ -775,7 +1048,7 @@ export function registerSoundDesignerTools() {
|
|
|
775
1048
|
},
|
|
776
1049
|
synth: {
|
|
777
1050
|
type: 'string',
|
|
778
|
-
description: 'Override synth choice: "operator", "wavetable", "drift", "analog", "electric", "serum2". If omitted, the best synth is chosen automatically from the recipe.',
|
|
1051
|
+
description: 'Override synth choice: "operator", "wavetable", "drift", "meld", "analog", "electric", "serum2". If omitted, the best synth is chosen automatically from the recipe.',
|
|
779
1052
|
},
|
|
780
1053
|
},
|
|
781
1054
|
tier: 'free',
|
|
@@ -797,8 +1070,10 @@ export function registerSoundDesignerTools() {
|
|
|
797
1070
|
const categories = [
|
|
798
1071
|
'**808 bass**: "808", "dark 808", "808 slide", "808 hard clip"',
|
|
799
1072
|
'**Sub bass**: "sub bass", "warm sub", "triangle sub"',
|
|
800
|
-
'**Leads**: "bright lead", "acid lead", "supersaw", "dark bell"',
|
|
801
|
-
'**Pads**: "dark pad", "warm pad", "ambient pad", "shimmer pad", "string pad"',
|
|
1073
|
+
'**Leads**: "bright lead", "acid lead", "supersaw", "dark bell", "drift lead", "meld lead"',
|
|
1074
|
+
'**Pads**: "dark pad", "warm pad", "ambient pad", "shimmer pad", "string pad", "drift pad", "meld pad"',
|
|
1075
|
+
'**Drift synth**: "drift bass", "drift lead", "drift lo-fi", "drift pad"',
|
|
1076
|
+
'**Meld synth**: "meld pad", "meld bass", "meld lead", "meld noise texture"',
|
|
802
1077
|
'**Keys**: "rhodes", "wurlitzer", "organ", "electric piano"',
|
|
803
1078
|
'**Plucks**: "pluck", "digital pluck", "metallic pluck"',
|
|
804
1079
|
'**FX**: "riser", "noise sweep", "impact"',
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const TOOL_TOKENS: {
|
|
2
|
+
readonly think_open: "<think>";
|
|
3
|
+
readonly think_close: "</think>";
|
|
4
|
+
readonly tool_open: "<tool>";
|
|
5
|
+
readonly tool_close: "</tool>";
|
|
6
|
+
readonly args_open: "<args>";
|
|
7
|
+
readonly args_close: "</args>";
|
|
8
|
+
readonly result_open: "<result>";
|
|
9
|
+
readonly result_close: "</result>";
|
|
10
|
+
readonly answer_open: "<answer>";
|
|
11
|
+
readonly answer_close: "</answer>";
|
|
12
|
+
};
|
|
13
|
+
export interface AgentTraceOptions {
|
|
14
|
+
input?: string;
|
|
15
|
+
output?: string;
|
|
16
|
+
minTools?: number;
|
|
17
|
+
maxResultLen?: number;
|
|
18
|
+
verifiedOnly?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface AgentTraceResult {
|
|
21
|
+
output: string;
|
|
22
|
+
trajectories: number;
|
|
23
|
+
examples: number;
|
|
24
|
+
skipped_no_tools: number;
|
|
25
|
+
skipped_errors: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function formatAgentTraces(opts?: AgentTraceOptions): AgentTraceResult;
|
|
28
|
+
export declare function formatAgentTraceReport(r: AgentTraceResult): string;
|
|
29
|
+
//# sourceMappingURL=train-agent-trace.d.ts.map
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// train-agent-trace — reformat multi-turn tool-use sessions into training examples
|
|
2
|
+
// with explicit tool tokens. Used by train-self --mode agent-trace.
|
|
3
|
+
//
|
|
4
|
+
// Output format (one example per completed trajectory):
|
|
5
|
+
// {"messages": [
|
|
6
|
+
// {"role":"user","content":"..."},
|
|
7
|
+
// {"role":"assistant","content":"<think>...</think><tool>name</tool><args>{...}</args>"},
|
|
8
|
+
// {"role":"tool","content":"<result>...</result>"},
|
|
9
|
+
// {"role":"assistant","content":"<think>...</think><answer>...</answer>"}
|
|
10
|
+
// ]}
|
|
11
|
+
//
|
|
12
|
+
// Tool tokens we inject:
|
|
13
|
+
// <think>...</think> — reasoning
|
|
14
|
+
// <tool>name</tool> — tool selected
|
|
15
|
+
// <args>{...}</args> — JSON arguments
|
|
16
|
+
// <result>...</result> — tool output (truncated)
|
|
17
|
+
// <answer>...</answer> — final assistant turn
|
|
18
|
+
import { existsSync, readFileSync, writeFileSync, appendFileSync } from 'node:fs';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { homedir } from 'node:os';
|
|
21
|
+
export const TOOL_TOKENS = {
|
|
22
|
+
think_open: '<think>', think_close: '</think>',
|
|
23
|
+
tool_open: '<tool>', tool_close: '</tool>',
|
|
24
|
+
args_open: '<args>', args_close: '</args>',
|
|
25
|
+
result_open: '<result>', result_close: '</result>',
|
|
26
|
+
answer_open: '<answer>', answer_close: '</answer>',
|
|
27
|
+
};
|
|
28
|
+
function truncate(s, n) {
|
|
29
|
+
if (s.length <= n)
|
|
30
|
+
return s;
|
|
31
|
+
return s.slice(0, n) + ` …[+${s.length - n} chars]`;
|
|
32
|
+
}
|
|
33
|
+
/** Build an assistant turn with think + tool call tokens. */
|
|
34
|
+
function assistantToolTurn(thinking, toolName, args) {
|
|
35
|
+
const thinkPart = thinking
|
|
36
|
+
? `${TOOL_TOKENS.think_open}${thinking.trim()}${TOOL_TOKENS.think_close}\n`
|
|
37
|
+
: '';
|
|
38
|
+
const argsJson = JSON.stringify(args);
|
|
39
|
+
return `${thinkPart}${TOOL_TOKENS.tool_open}${toolName}${TOOL_TOKENS.tool_close}\n${TOOL_TOKENS.args_open}${argsJson}${TOOL_TOKENS.args_close}`;
|
|
40
|
+
}
|
|
41
|
+
/** Build a tool-result turn. */
|
|
42
|
+
function toolResultTurn(result, maxLen) {
|
|
43
|
+
return `${TOOL_TOKENS.result_open}${truncate(result, maxLen)}${TOOL_TOKENS.result_close}`;
|
|
44
|
+
}
|
|
45
|
+
/** Build the final assistant answer turn. */
|
|
46
|
+
function answerTurn(thinking, content) {
|
|
47
|
+
const thinkPart = thinking
|
|
48
|
+
? `${TOOL_TOKENS.think_open}${thinking.trim()}${TOOL_TOKENS.think_close}\n`
|
|
49
|
+
: '';
|
|
50
|
+
return `${thinkPart}${TOOL_TOKENS.answer_open}${content.trim()}${TOOL_TOKENS.answer_close}`;
|
|
51
|
+
}
|
|
52
|
+
/** Convert one teacher trace into an agent-trace example. */
|
|
53
|
+
function formatTrace(t, maxResult) {
|
|
54
|
+
const toolCalls = t.response.tool_calls || [];
|
|
55
|
+
if (toolCalls.length === 0)
|
|
56
|
+
return null;
|
|
57
|
+
const messages = [];
|
|
58
|
+
// Seed with conversation context (excluding the final assistant turn)
|
|
59
|
+
for (const m of t.messages) {
|
|
60
|
+
if (m.role === 'user' || m.role === 'system') {
|
|
61
|
+
messages.push({ role: m.role, content: m.content });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Inject assistant tool-call turn
|
|
65
|
+
const firstCall = toolCalls[0];
|
|
66
|
+
messages.push({
|
|
67
|
+
role: 'assistant',
|
|
68
|
+
content: assistantToolTurn(t.response.thinking || '', firstCall.name, firstCall.arguments),
|
|
69
|
+
});
|
|
70
|
+
// We don't have the actual tool result in teacher traces — synthesize a placeholder
|
|
71
|
+
// that the model can learn to parse. In production, the tool executor would fill this
|
|
72
|
+
// when replaying recorded sessions.
|
|
73
|
+
messages.push({
|
|
74
|
+
role: 'tool',
|
|
75
|
+
content: toolResultTurn('[result from ' + firstCall.name + ']', maxResult),
|
|
76
|
+
});
|
|
77
|
+
// Final answer
|
|
78
|
+
messages.push({
|
|
79
|
+
role: 'assistant',
|
|
80
|
+
content: answerTurn('', t.response.content),
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
messages,
|
|
84
|
+
_tool_count: toolCalls.length,
|
|
85
|
+
_trace_id: t.id,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export function formatAgentTraces(opts = {}) {
|
|
89
|
+
const input = opts.input ?? join(homedir(), '.kbot', 'teacher', 'traces.jsonl');
|
|
90
|
+
const output = opts.output ?? join(homedir(), '.kbot', 'teacher', 'dataset-agent-trace.jsonl');
|
|
91
|
+
const minTools = opts.minTools ?? 1;
|
|
92
|
+
const maxResult = opts.maxResultLen ?? 1200;
|
|
93
|
+
const result = {
|
|
94
|
+
output,
|
|
95
|
+
trajectories: 0,
|
|
96
|
+
examples: 0,
|
|
97
|
+
skipped_no_tools: 0,
|
|
98
|
+
skipped_errors: 0,
|
|
99
|
+
};
|
|
100
|
+
if (!existsSync(input))
|
|
101
|
+
return result;
|
|
102
|
+
// Truncate output
|
|
103
|
+
writeFileSync(output, '');
|
|
104
|
+
const lines = readFileSync(input, 'utf-8').split('\n').filter(l => l.trim());
|
|
105
|
+
for (const line of lines) {
|
|
106
|
+
try {
|
|
107
|
+
const t = JSON.parse(line);
|
|
108
|
+
result.trajectories++;
|
|
109
|
+
if (opts.verifiedOnly && !t.outcome?.verified) {
|
|
110
|
+
result.skipped_errors++;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const toolCount = t.response.tool_calls?.length || 0;
|
|
114
|
+
if (toolCount < minTools) {
|
|
115
|
+
result.skipped_no_tools++;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const ex = formatTrace(t, maxResult);
|
|
119
|
+
if (ex) {
|
|
120
|
+
appendFileSync(output, JSON.stringify(ex) + '\n');
|
|
121
|
+
result.examples++;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
result.skipped_errors++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
export function formatAgentTraceReport(r) {
|
|
131
|
+
return [
|
|
132
|
+
'agent-trace formatter',
|
|
133
|
+
'─'.repeat(40),
|
|
134
|
+
` Output: ${r.output}`,
|
|
135
|
+
` Trajectories seen: ${r.trajectories}`,
|
|
136
|
+
` Examples emitted: ${r.examples}`,
|
|
137
|
+
` Skipped (no tools): ${r.skipped_no_tools}`,
|
|
138
|
+
` Skipped (errors): ${r.skipped_errors}`,
|
|
139
|
+
].join('\n');
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=train-agent-trace.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type CurateMode = 'default' | 'reasoning' | 'agent-trace' | 'code-only';
|
|
2
|
+
export interface CurateOptions {
|
|
3
|
+
sources?: string[];
|
|
4
|
+
output?: string;
|
|
5
|
+
mode?: CurateMode;
|
|
6
|
+
maxExamples?: number;
|
|
7
|
+
minScore?: number;
|
|
8
|
+
minResponseLen?: number;
|
|
9
|
+
maxResponseLen?: number;
|
|
10
|
+
dedupe?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface CurateResult {
|
|
13
|
+
output: string;
|
|
14
|
+
total_examined: number;
|
|
15
|
+
kept: number;
|
|
16
|
+
rejected: number;
|
|
17
|
+
duplicates: number;
|
|
18
|
+
mean_score: number;
|
|
19
|
+
by_source: Record<string, number>;
|
|
20
|
+
}
|
|
21
|
+
/** Run the curator end-to-end. Returns a report. */
|
|
22
|
+
export declare function curate(opts?: CurateOptions): CurateResult;
|
|
23
|
+
/** Format as a human-readable report */
|
|
24
|
+
export declare function formatCurateReport(r: CurateResult): string;
|
|
25
|
+
//# sourceMappingURL=train-curate.d.ts.map
|