@kernel.chat/kbot 4.0.1 → 4.1.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.
Files changed (55) hide show
  1. package/dist/futures/debate/index.d.ts +7 -0
  2. package/dist/futures/debate/index.js +6 -0
  3. package/dist/futures/debate/runner.d.ts +34 -0
  4. package/dist/futures/debate/runner.js +140 -0
  5. package/dist/futures/debate/synthesis.d.ts +25 -0
  6. package/dist/futures/debate/synthesis.js +81 -0
  7. package/dist/futures/debate/types.d.ts +72 -0
  8. package/dist/futures/debate/types.js +12 -0
  9. package/dist/futures/forecast/index.d.ts +5 -0
  10. package/dist/futures/forecast/index.js +5 -0
  11. package/dist/futures/forecast/projection.d.ts +31 -0
  12. package/dist/futures/forecast/projection.js +177 -0
  13. package/dist/futures/forecast/synthesize.d.ts +19 -0
  14. package/dist/futures/forecast/synthesize.js +89 -0
  15. package/dist/futures/forecast/types.d.ts +59 -0
  16. package/dist/futures/forecast/types.js +15 -0
  17. package/dist/futures/harness/critic-evaluator.d.ts +39 -0
  18. package/dist/futures/harness/critic-evaluator.js +131 -0
  19. package/dist/futures/harness/evolution-loop.d.ts +41 -0
  20. package/dist/futures/harness/evolution-loop.js +168 -0
  21. package/dist/futures/harness/index.d.ts +16 -0
  22. package/dist/futures/harness/index.js +13 -0
  23. package/dist/futures/harness/meta-evolution.d.ts +32 -0
  24. package/dist/futures/harness/meta-evolution.js +52 -0
  25. package/dist/futures/harness/noop-evolution.d.ts +23 -0
  26. package/dist/futures/harness/noop-evolution.js +29 -0
  27. package/dist/futures/harness/persistence.d.ts +30 -0
  28. package/dist/futures/harness/persistence.js +99 -0
  29. package/dist/futures/harness/types.d.ts +147 -0
  30. package/dist/futures/harness/types.js +18 -0
  31. package/dist/futures/index.d.ts +16 -0
  32. package/dist/futures/index.js +22 -0
  33. package/dist/futures/latent-state/envelope.d.ts +39 -0
  34. package/dist/futures/latent-state/envelope.js +178 -0
  35. package/dist/futures/latent-state/index.d.ts +5 -0
  36. package/dist/futures/latent-state/index.js +3 -0
  37. package/dist/futures/latent-state/types.d.ts +47 -0
  38. package/dist/futures/latent-state/types.js +13 -0
  39. package/dist/futures/persona/check.d.ts +45 -0
  40. package/dist/futures/persona/check.js +205 -0
  41. package/dist/futures/persona/index.d.ts +5 -0
  42. package/dist/futures/persona/index.js +5 -0
  43. package/dist/futures/persona/registry.d.ts +22 -0
  44. package/dist/futures/persona/registry.js +124 -0
  45. package/dist/futures/persona/types.d.ts +68 -0
  46. package/dist/futures/persona/types.js +28 -0
  47. package/dist/futures/skill-graph/graph.d.ts +31 -0
  48. package/dist/futures/skill-graph/graph.js +151 -0
  49. package/dist/futures/skill-graph/index.d.ts +13 -0
  50. package/dist/futures/skill-graph/index.js +10 -0
  51. package/dist/futures/skill-graph/synthesis.d.ts +20 -0
  52. package/dist/futures/skill-graph/synthesis.js +83 -0
  53. package/dist/futures/skill-graph/types.d.ts +53 -0
  54. package/dist/futures/skill-graph/types.js +19 -0
  55. package/package.json +1 -1
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Skill graph — runtime ops.
3
+ *
4
+ * Pure functions over the SkillGraph data structure. Mutators return new
5
+ * instances rather than mutating in place; the underlying Maps and arrays
6
+ * are copied. Random walks use a seeded LCG for deterministic tests.
7
+ */
8
+ function lcg(seed) {
9
+ let state = seed >>> 0;
10
+ return {
11
+ next() {
12
+ state = (state * 1664525 + 1013904223) >>> 0;
13
+ return state / 0xffffffff;
14
+ },
15
+ };
16
+ }
17
+ function defaultRng() {
18
+ return { next: () => Math.random() };
19
+ }
20
+ // ─────────────────────────────────────────────────────────────────────────────
21
+ // Construction
22
+ // ─────────────────────────────────────────────────────────────────────────────
23
+ export function buildGraph() {
24
+ return {
25
+ skills: new Map(),
26
+ scenarios: new Map(),
27
+ edges: [],
28
+ };
29
+ }
30
+ export function addSkill(g, skill) {
31
+ const next = new Map(g.skills);
32
+ next.set(skill.id, skill);
33
+ return { ...g, skills: next };
34
+ }
35
+ export function addScenario(g, scenario) {
36
+ const next = new Map(g.scenarios);
37
+ next.set(scenario.id, scenario);
38
+ return { ...g, scenarios: next };
39
+ }
40
+ export function addEdge(g, edge) {
41
+ return { ...g, edges: [...g.edges, edge] };
42
+ }
43
+ // ─────────────────────────────────────────────────────────────────────────────
44
+ // Lookup helpers
45
+ // ─────────────────────────────────────────────────────────────────────────────
46
+ function getNode(g, id) {
47
+ return g.skills.get(id) ?? g.scenarios.get(id);
48
+ }
49
+ function outgoing(g, fromId) {
50
+ return g.edges.filter((e) => e.from === fromId);
51
+ }
52
+ export function samplePath(g, opts = {}) {
53
+ const rng = opts.seed !== undefined ? lcg(opts.seed) : defaultRng();
54
+ const maxLength = opts.maxLength ?? 6;
55
+ const startId = opts.start ?? pickStartNode(g, rng);
56
+ if (!startId)
57
+ return { nodes: [], edges: [], pathLength: 0 };
58
+ const startNode = getNode(g, startId);
59
+ if (!startNode)
60
+ return { nodes: [], edges: [], pathLength: 0 };
61
+ const nodes = [startNode];
62
+ const edges = [];
63
+ const visited = new Set([startId]);
64
+ let currentId = startId;
65
+ while (nodes.length < maxLength) {
66
+ const candidates = outgoing(g, currentId).filter((e) => !visited.has(e.to));
67
+ if (candidates.length === 0)
68
+ break;
69
+ const edge = weightedPick(candidates, rng);
70
+ const nextNode = getNode(g, edge.to);
71
+ if (!nextNode)
72
+ break;
73
+ edges.push(edge);
74
+ nodes.push(nextNode);
75
+ visited.add(edge.to);
76
+ currentId = edge.to;
77
+ }
78
+ return { nodes, edges, pathLength: nodes.length };
79
+ }
80
+ function pickStartNode(g, rng) {
81
+ const all = [...g.skills.keys(), ...g.scenarios.keys()];
82
+ if (all.length === 0)
83
+ return undefined;
84
+ return all[Math.floor(rng.next() * all.length)];
85
+ }
86
+ function weightedPick(edges, rng) {
87
+ const total = edges.reduce((s, e) => s + (e.weight ?? 1), 0);
88
+ let pick = rng.next() * total;
89
+ for (const edge of edges) {
90
+ pick -= edge.weight ?? 1;
91
+ if (pick <= 0)
92
+ return edge;
93
+ }
94
+ return edges[edges.length - 1];
95
+ }
96
+ // ─────────────────────────────────────────────────────────────────────────────
97
+ // Path finding — DFS with depth limit
98
+ // ─────────────────────────────────────────────────────────────────────────────
99
+ export function findPaths(g, fromId, toId, maxDepth = 5) {
100
+ const startNode = getNode(g, fromId);
101
+ if (!startNode)
102
+ return [];
103
+ const results = [];
104
+ const stack = [
105
+ { id: fromId, nodes: [startNode], edges: [] },
106
+ ];
107
+ while (stack.length > 0) {
108
+ const { id, nodes, edges } = stack.pop();
109
+ if (id === toId && nodes.length > 1) {
110
+ results.push({ nodes, edges, pathLength: nodes.length });
111
+ continue;
112
+ }
113
+ if (nodes.length >= maxDepth)
114
+ continue;
115
+ const visited = new Set(nodes.map((n) => n.id));
116
+ for (const edge of outgoing(g, id)) {
117
+ if (visited.has(edge.to))
118
+ continue;
119
+ const next = getNode(g, edge.to);
120
+ if (!next)
121
+ continue;
122
+ stack.push({
123
+ id: edge.to,
124
+ nodes: [...nodes, next],
125
+ edges: [...edges, edge],
126
+ });
127
+ }
128
+ }
129
+ return results;
130
+ }
131
+ export function pathLengthDistribution(g, samples = 100, opts = {}) {
132
+ if (samples <= 0) {
133
+ return { min: 0, max: 0, avg: 0, p50: 0, p95: 0, samples: 0 };
134
+ }
135
+ const baseSeed = opts.seed ?? Date.now();
136
+ const lengths = [];
137
+ for (let i = 0; i < samples; i++) {
138
+ const path = samplePath(g, { seed: baseSeed + i });
139
+ lengths.push(path.pathLength);
140
+ }
141
+ lengths.sort((a, b) => a - b);
142
+ const min = lengths[0] ?? 0;
143
+ const max = lengths[lengths.length - 1] ?? 0;
144
+ const sum = lengths.reduce((s, n) => s + n, 0);
145
+ const avg = sum / lengths.length;
146
+ const p50 = lengths[Math.floor(lengths.length * 0.5)] ?? 0;
147
+ const p95Idx = Math.min(lengths.length - 1, Math.floor(lengths.length * 0.95));
148
+ const p95 = lengths[p95Idx] ?? 0;
149
+ return { min, max, avg, p50, p95, samples };
150
+ }
151
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Public surface for the skill-graph module.
3
+ *
4
+ * Tencent Hunyuan SkillSynth-style graph formalism over kbot's skill set.
5
+ * Path sampling produces synthetic Tasks for the harness/ evolution loop.
6
+ */
7
+ export type { Edge, GraphPath, Scenario, Skill, SkillGraph, } from './types.js';
8
+ export { isSkill } from './types.js';
9
+ export { buildGraph, addSkill, addScenario, addEdge, samplePath, findPaths, pathLengthDistribution, } from './graph.js';
10
+ export type { SampleOptions, PathLengthStats } from './graph.js';
11
+ export { pathToTask } from './synthesis.js';
12
+ export type { PathToTaskOptions } from './synthesis.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public surface for the skill-graph module.
3
+ *
4
+ * Tencent Hunyuan SkillSynth-style graph formalism over kbot's skill set.
5
+ * Path sampling produces synthetic Tasks for the harness/ evolution loop.
6
+ */
7
+ export { isSkill } from './types.js';
8
+ export { buildGraph, addSkill, addScenario, addEdge, samplePath, findPaths, pathLengthDistribution, } from './graph.js';
9
+ export { pathToTask } from './synthesis.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Skill graph → synthetic task synthesis.
3
+ *
4
+ * Translates a sampled GraphPath into a Task instance compatible with the
5
+ * harness module's `Task` interface. The acceptance criteria are derived
6
+ * from the path's edges; the instructions describe the workflow in human-
7
+ * readable form.
8
+ */
9
+ import type { Task } from '../harness/types.js';
10
+ import type { GraphPath } from './types.js';
11
+ export interface PathToTaskOptions {
12
+ /** Optional id prefix; defaults to "synth-". */
13
+ prefix?: string;
14
+ /** Optional context line prepended to instructions. */
15
+ contextHeader?: string;
16
+ /** Extra metadata to merge into Task.meta. */
17
+ meta?: Record<string, unknown>;
18
+ }
19
+ export declare function pathToTask(path: GraphPath, opts?: PathToTaskOptions): Task;
20
+ //# sourceMappingURL=synthesis.d.ts.map
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Skill graph → synthetic task synthesis.
3
+ *
4
+ * Translates a sampled GraphPath into a Task instance compatible with the
5
+ * harness module's `Task` interface. The acceptance criteria are derived
6
+ * from the path's edges; the instructions describe the workflow in human-
7
+ * readable form.
8
+ */
9
+ export function pathToTask(path, opts = {}) {
10
+ const prefix = opts.prefix ?? 'synth-';
11
+ const id = `${prefix}${shortHash(path)}`;
12
+ const instructions = buildInstructions(path, opts.contextHeader);
13
+ const acceptance = buildAcceptance(path);
14
+ const meta = {
15
+ source: 'skill-graph',
16
+ pathLength: path.pathLength,
17
+ nodeIds: path.nodes.map((n) => n.id),
18
+ ...opts.meta,
19
+ };
20
+ return { id, instructions, acceptance, meta };
21
+ }
22
+ function buildInstructions(path, header) {
23
+ const parts = [];
24
+ if (header)
25
+ parts.push(header);
26
+ if (path.nodes.length === 0) {
27
+ parts.push('No nodes in path; nothing to do.');
28
+ return parts.join('\n\n');
29
+ }
30
+ parts.push(`Workflow with ${path.nodes.length} step(s):`);
31
+ path.nodes.forEach((node, i) => {
32
+ parts.push(` ${i + 1}. ${describeNode(node)}`);
33
+ });
34
+ if (path.edges.length > 0) {
35
+ parts.push('');
36
+ parts.push('Transitions:');
37
+ path.edges.forEach((edge) => {
38
+ parts.push(` - ${edge.from} → ${edge.to} (${edge.kind})`);
39
+ });
40
+ }
41
+ return parts.join('\n');
42
+ }
43
+ function buildAcceptance(path) {
44
+ if (path.nodes.length === 0)
45
+ return ['No nodes to verify.'];
46
+ const criteria = [];
47
+ for (const node of path.nodes) {
48
+ if (isSkillNode(node)) {
49
+ const tool = node.toolName ? ` (${node.toolName})` : '';
50
+ criteria.push(`Skill exercised: ${node.description}${tool}`);
51
+ }
52
+ else {
53
+ criteria.push(`Scenario context entered: ${node.description}`);
54
+ }
55
+ }
56
+ for (const edge of path.edges) {
57
+ if (edge.kind === 'requires') {
58
+ criteria.push(`Prerequisite satisfied: ${edge.from} before ${edge.to}`);
59
+ }
60
+ }
61
+ return criteria;
62
+ }
63
+ function describeNode(node) {
64
+ if (isSkillNode(node)) {
65
+ return node.toolName
66
+ ? `${node.description} (tool: ${node.toolName})`
67
+ : node.description;
68
+ }
69
+ return `${node.description}${node.tags?.length ? ` [${node.tags.join(', ')}]` : ''}`;
70
+ }
71
+ function isSkillNode(node) {
72
+ return !('tags' in node);
73
+ }
74
+ function shortHash(path) {
75
+ // Simple deterministic hash over node ids; not crypto.
76
+ const key = path.nodes.map((n) => n.id).join('|');
77
+ let h = 0;
78
+ for (let i = 0; i < key.length; i++) {
79
+ h = (h * 31 + key.charCodeAt(i)) >>> 0;
80
+ }
81
+ return h.toString(36).slice(0, 8);
82
+ }
83
+ //# sourceMappingURL=synthesis.js.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Skill graph — explicit graph formalism over skills + scenarios.
3
+ *
4
+ * Maps onto Tencent Hunyuan's "Toward Scalable Terminal Task Synthesis via
5
+ * Skill Graphs" (arXiv:2604.25727). Wraps the Bayesian flat-skill ratings in
6
+ * `packages/skill-router/` with structure: skill nodes, scenario nodes
7
+ * (intermediate workflow contexts), and weighted edges between them.
8
+ *
9
+ * A path through the graph is a candidate workflow. Sampling paths produces
10
+ * synthetic Tasks (compatible with `harness/types.ts`) for evaluation and
11
+ * training.
12
+ *
13
+ * This module is types-only. Runtime lives in graph.ts and synthesis.ts.
14
+ */
15
+ /** A skill node — typically maps 1:1 to a registered kbot tool. */
16
+ export interface Skill {
17
+ id: string;
18
+ description: string;
19
+ /** Optional name of the underlying tool (from packages/kbot/src/tools/). */
20
+ toolName?: string;
21
+ }
22
+ /**
23
+ * A scenario node — an intermediate workflow context that connects skills.
24
+ * Example: "after-cloning-a-repo", "in-an-ableton-set", "researching-a-paper".
25
+ */
26
+ export interface Scenario {
27
+ id: string;
28
+ description: string;
29
+ tags?: string[];
30
+ }
31
+ /** A directed edge between two nodes (skill or scenario). */
32
+ export interface Edge {
33
+ from: string;
34
+ to: string;
35
+ /** Sampling weight; defaults to 1. Higher = more likely on a random walk. */
36
+ weight?: number;
37
+ kind: 'invokes' | 'follows' | 'requires';
38
+ }
39
+ /** Result of a graph traversal: ordered nodes + edges + length. */
40
+ export interface GraphPath {
41
+ nodes: Array<Skill | Scenario>;
42
+ edges: Edge[];
43
+ pathLength: number;
44
+ }
45
+ /** Immutable-ish graph container. Mutators return new instances. */
46
+ export interface SkillGraph {
47
+ skills: Map<string, Skill>;
48
+ scenarios: Map<string, Scenario>;
49
+ edges: Edge[];
50
+ }
51
+ /** Type guard: skill vs scenario. */
52
+ export declare function isSkill(node: Skill | Scenario): node is Skill;
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Skill graph — explicit graph formalism over skills + scenarios.
3
+ *
4
+ * Maps onto Tencent Hunyuan's "Toward Scalable Terminal Task Synthesis via
5
+ * Skill Graphs" (arXiv:2604.25727). Wraps the Bayesian flat-skill ratings in
6
+ * `packages/skill-router/` with structure: skill nodes, scenario nodes
7
+ * (intermediate workflow contexts), and weighted edges between them.
8
+ *
9
+ * A path through the graph is a candidate workflow. Sampling paths produces
10
+ * synthetic Tasks (compatible with `harness/types.ts`) for evaluation and
11
+ * training.
12
+ *
13
+ * This module is types-only. Runtime lives in graph.ts and synthesis.ts.
14
+ */
15
+ /** Type guard: skill vs scenario. */
16
+ export function isSkill(node) {
17
+ return 'description' in node && !('tags' in node) && !('id' in node && node.tags !== undefined);
18
+ }
19
+ //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kernel.chat/kbot",
3
- "version": "4.0.1",
3
+ "version": "4.1.0",
4
4
  "description": "Open-source terminal AI agent. 100+ specialist skills, 35 specialist agents, 20 providers. Dreams, learns, watches your system. Controls your phone. Fully local, fully sovereign. MIT. v4.0 — evidence-based curation.",
5
5
  "type": "module",
6
6
  "repository": {