@kodax-ai/kodax 0.7.95 → 0.7.96-alpha.2
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/CHANGELOG.md +178 -1
- package/LICENSE +158 -158
- package/README.md +149 -24
- package/README_CN.md +117 -24
- package/config-templates/config.example.jsonc +2 -1
- package/config-templates/integrations/a2a.example.jsonc +91 -91
- package/config-templates/integrations/extensions.example.jsonc +7 -7
- package/config-templates/integrations/mcp.example.jsonc +16 -16
- package/dist/builtin/code-review/SKILL.md +82 -82
- package/dist/builtin/git-workflow/SKILL.md +84 -84
- package/dist/builtin/skill-creator/SKILL.md +127 -127
- package/dist/builtin/skill-creator/agents/analyzer.md +12 -12
- package/dist/builtin/skill-creator/agents/comparator.md +13 -13
- package/dist/builtin/skill-creator/agents/grader.md +13 -13
- package/dist/builtin/skill-creator/references/schemas.md +227 -227
- package/dist/builtin/skill-creator/scripts/aggregate-benchmark.d.ts +46 -46
- package/dist/builtin/skill-creator/scripts/aggregate-benchmark.js +208 -208
- package/dist/builtin/skill-creator/scripts/analyze-benchmark.d.ts +46 -46
- package/dist/builtin/skill-creator/scripts/analyze-benchmark.js +286 -286
- package/dist/builtin/skill-creator/scripts/compare-runs.d.ts +62 -62
- package/dist/builtin/skill-creator/scripts/compare-runs.js +330 -330
- package/dist/builtin/skill-creator/scripts/generate-review.d.ts +33 -33
- package/dist/builtin/skill-creator/scripts/generate-review.js +414 -414
- package/dist/builtin/skill-creator/scripts/grade-evals.d.ts +73 -73
- package/dist/builtin/skill-creator/scripts/grade-evals.js +402 -402
- package/dist/builtin/skill-creator/scripts/improve-description.d.ts +23 -23
- package/dist/builtin/skill-creator/scripts/improve-description.js +160 -160
- package/dist/builtin/skill-creator/scripts/init-skill.d.ts +14 -14
- package/dist/builtin/skill-creator/scripts/init-skill.js +155 -155
- package/dist/builtin/skill-creator/scripts/install-skill.d.ts +29 -29
- package/dist/builtin/skill-creator/scripts/install-skill.js +173 -173
- package/dist/builtin/skill-creator/scripts/package-skill.d.ts +38 -38
- package/dist/builtin/skill-creator/scripts/package-skill.js +121 -121
- package/dist/builtin/skill-creator/scripts/quick-validate.d.ts +8 -8
- package/dist/builtin/skill-creator/scripts/quick-validate.js +163 -163
- package/dist/builtin/skill-creator/scripts/run-eval.d.ts +66 -66
- package/dist/builtin/skill-creator/scripts/run-eval.js +353 -353
- package/dist/builtin/skill-creator/scripts/run-loop.d.ts +49 -49
- package/dist/builtin/skill-creator/scripts/run-loop.js +242 -242
- package/dist/builtin/skill-creator/scripts/run-trigger-eval.d.ts +58 -58
- package/dist/builtin/skill-creator/scripts/run-trigger-eval.js +224 -224
- package/dist/builtin/tdd/SKILL.md +56 -56
- package/dist/chunks/agent-4FABF6WK.js +2 -0
- package/dist/chunks/argument-completer-72VHB2VL.js +2 -0
- package/dist/chunks/{chunk-7JXA3533.js → chunk-4OIQZWA5.js} +223 -226
- package/dist/chunks/{chunk-BNVSKIAB.js → chunk-6BVF3HZ7.js} +136 -136
- package/dist/chunks/chunk-7JZZIFZH.js +501 -0
- package/dist/chunks/chunk-AC7Z2OIY.js +2 -0
- package/dist/chunks/{chunk-JS452J2F.js → chunk-C4KYZAFU.js} +2 -2
- package/dist/chunks/chunk-CHUPIWIF.js +251 -0
- package/dist/chunks/{chunk-C4DTUKTR.js → chunk-GYUU7XLH.js} +5 -4
- package/dist/chunks/{chunk-OK4AXDC5.js → chunk-HAX55GOQ.js} +1 -1
- package/dist/chunks/chunk-JKTJCGO2.js +418 -0
- package/dist/chunks/{chunk-O743AJ5V.js → chunk-LQYETRFK.js} +171 -175
- package/dist/chunks/{chunk-2PEDBGKN.js → chunk-LTUZTQ6W.js} +1 -1
- package/dist/chunks/chunk-LYWDUSKO.js +2 -0
- package/dist/chunks/chunk-NGH6T4FD.js +92 -0
- package/dist/chunks/{chunk-SRIJX5ZP.js → chunk-NVRWCSA5.js} +1 -1
- package/dist/chunks/chunk-O4DS7RIQ.js +384 -0
- package/dist/chunks/chunk-ORXU6OWZ.js +2 -0
- package/dist/chunks/chunk-POTW3O65.js +124 -0
- package/dist/chunks/{chunk-2TM3W3GK.js → chunk-RIQSS56Y.js} +1 -1
- package/dist/chunks/chunk-U27XKEN5.js +407 -0
- package/dist/chunks/{chunk-6ABQJUK6.js → chunk-XUX6OUCA.js} +2 -2
- package/dist/chunks/{client-JDOS3YJR.js → client-4C456K4O.js} +1 -1
- package/dist/chunks/compaction-config-3VQRDFF4.js +2 -0
- package/dist/chunks/{construction-bootstrap-YCWHHUYO.js → construction-bootstrap-AHN7EDGG.js} +1 -1
- package/dist/chunks/dist-BCBQXAGI.js +2 -0
- package/dist/chunks/dist-QK2YDWU6.js +2 -0
- package/dist/chunks/host-VIHV7ADG.js +2 -0
- package/dist/chunks/run-manager-NBVMU3KV.js +2 -0
- package/dist/chunks/utils-MEJZ2IGI.js +2 -0
- package/dist/index.d.ts +22 -21
- package/dist/index.js +7 -7
- package/dist/kodax_bootstrap.js +26 -26
- package/dist/kodax_cli.js +1905 -1882
- package/dist/native/darwin-arm64/LICENSE-APACHE.txt +13 -0
- package/dist/native/darwin-arm64/kodax-text-transaction.node +0 -0
- package/dist/native/darwin-arm64/manifest.json +16 -0
- package/dist/native/darwin-x64/LICENSE-APACHE.txt +13 -0
- package/dist/native/darwin-x64/kodax-text-transaction.node +0 -0
- package/dist/native/darwin-x64/manifest.json +16 -0
- package/dist/native/linux-arm64/LICENSE-APACHE.txt +13 -0
- package/dist/native/linux-arm64/kodax-text-transaction.node +0 -0
- package/dist/native/linux-arm64/manifest.json +16 -0
- package/dist/native/linux-x64/LICENSE-APACHE.txt +13 -0
- package/dist/native/linux-x64/kodax-text-transaction.node +0 -0
- package/dist/native/linux-x64/manifest.json +16 -0
- package/dist/native/win32-x64/LICENSE-APACHE.txt +13 -0
- package/dist/native/win32-x64/NOTICE-windows-sandbox.txt +8 -0
- package/dist/native/win32-x64/kodax-windows-sandbox.exe +0 -0
- package/dist/native/win32-x64/kodax-windows-text-transaction.node +0 -0
- package/dist/native/win32-x64/manifest.json +30 -0
- package/dist/provider-capabilities.json +108 -2
- package/dist/runtime-worker.js +1745 -1727
- package/dist/sandbox-network-broker.js +1715 -0
- package/dist/sdk-a2a.d.ts +13 -12
- package/dist/sdk-a2a.js +1 -1
- package/dist/sdk-agent.d.ts +27 -18
- package/dist/sdk-agent.js +1 -1
- package/dist/sdk-coding.d.ts +107 -58
- package/dist/sdk-coding.js +1 -1
- package/dist/sdk-experimental-memory.d.ts +4 -4
- package/dist/sdk-experimental-memory.js +1 -1
- package/dist/sdk-llm.d.ts +9 -10
- package/dist/sdk-llm.js +1 -1
- package/dist/sdk-mcp.js +1 -1
- package/dist/sdk-media.d.ts +1 -1
- package/dist/sdk-media.js +1 -1
- package/dist/sdk-repl.d.ts +25 -17
- package/dist/sdk-repl.js +1 -1
- package/dist/sdk-runtime.d.ts +41 -17
- package/dist/sdk-runtime.js +1 -1
- package/dist/sdk-sandbox.d.ts +17 -3
- package/dist/sdk-sandbox.js +1 -1
- package/dist/sdk-session.d.ts +8 -7
- package/dist/sdk-session.js +1 -1
- package/dist/sdk-skills.js +1 -1
- package/dist/semantic-worker.js +61 -61
- package/dist/types-chunks/{base.d-vopO1rml.d.ts → base.d-COo8E2dk.d.ts} +18 -27
- package/dist/types-chunks/{bash-prefix-extractor.d-B2rxNI4L.d.ts → bash-prefix-extractor.d-DQOlA8cy.d.ts} +72 -52
- package/dist/types-chunks/{capability-learning.d-CE1tm29C.d.ts → capability-learning.d-lRPgA3Or.d.ts} +1 -1
- package/dist/types-chunks/{capsule.d-Y7QRS4J2.d.ts → capsule.d-0zxsgXg_.d.ts} +3 -3
- package/dist/types-chunks/{controller.d-BR-UVeUR.d.ts → controller.d-BTtyIIC1.d.ts} +1 -1
- package/dist/types-chunks/{controller.d-C5noq5-w.d.ts → controller.d-C7tXUcXo.d.ts} +2 -2
- package/dist/types-chunks/{guardrail.d-DqHD-61O.d.ts → guardrail.d-DKTyEHJa.d.ts} +5 -5
- package/dist/types-chunks/{history-retrieval.d-CKU8zmt_.d.ts → history-retrieval.d-CHnL99S7.d.ts} +2 -2
- package/dist/types-chunks/{public-api.d-D7fXaWW8.d.ts → public-api.d-Dx3L3W4Z.d.ts} +7 -4
- package/dist/types-chunks/{repl.d-BYDb14s6.d.ts → repl.d-mO01olIa.d.ts} +5 -5
- package/dist/types-chunks/{resolver.d-CwHUwbdE.d.ts → resolver.d-DlXPjeyx.d.ts} +38 -6
- package/dist/types-chunks/{review-inbox.d-BSgFewyj.d.ts → review-inbox.d-WDSe1nze.d.ts} +1 -1
- package/dist/types-chunks/{run-manager.d-BVJSntpS.d.ts → run-manager.d-DENbbzgR.d.ts} +1 -1
- package/dist/types-chunks/{sdk-session-CqEG84oP.d.ts → sdk-session-DYHGXXH4.d.ts} +3 -3
- package/dist/types-chunks/{shell-command-sets.d-DqaaBwhU.d.ts → shell-command-sets.d-CjFqS4dp.d.ts} +1 -1
- package/dist/types-chunks/{side-query.d-iH0P9ASy.d.ts → side-query.d-j8A3sFv_.d.ts} +2 -2
- package/dist/types-chunks/{types.d-rUOjXych.d.ts → types.d-BbZjR0Wr.d.ts} +1 -1
- package/dist/types-chunks/{types.d-CaTXAW_Q.d.ts → types.d-BkTIKdH6.d.ts} +2 -2
- package/dist/types-chunks/{types.d-C5xQEFcj.d.ts → types.d-DncLrpu_.d.ts} +4 -4
- package/dist/types-chunks/{types.d-CK9A9rpP.d.ts → types.d-Xy0f3x4i.d.ts} +9 -0
- package/dist/types-chunks/{utils.d-CWUyLiXo.d.ts → utils.d-CnxefMos.d.ts} +6 -6
- package/package.json +10 -3
- package/public_docs/README.md +130 -0
- package/public_docs/configuration/sandbox.md +289 -0
- package/public_docs/sdk/embedder-guide.md +6674 -0
- package/scripts/kodax-bin.cjs +28 -28
- package/scripts/production-env.cjs +25 -25
- package/dist/chunks/agent-XXZMXKKA.js +0 -2
- package/dist/chunks/argument-completer-KCYDGTQW.js +0 -2
- package/dist/chunks/chunk-77PNP27P.js +0 -92
- package/dist/chunks/chunk-7QBWHCIZ.js +0 -2
- package/dist/chunks/chunk-BHE66SP3.js +0 -123
- package/dist/chunks/chunk-BR2OSB2I.js +0 -722
- package/dist/chunks/chunk-DSMONSVB.js +0 -407
- package/dist/chunks/chunk-Q5VRWSKG.js +0 -418
- package/dist/chunks/chunk-XWRPOGJN.js +0 -4
- package/dist/chunks/chunk-Y5VIQBT6.js +0 -383
- package/dist/chunks/compaction-config-EGS4577X.js +0 -2
- package/dist/chunks/dist-ITTXQHRJ.js +0 -2
- package/dist/chunks/dist-KFYN3OKD.js +0 -2
- package/dist/chunks/host-VAYADIPW.js +0 -2
- package/dist/chunks/run-manager-52IJZMZJ.js +0 -2
- package/dist/chunks/utils-P7PBSL3R.js +0 -2
- package/dist/sandbox-workspace-session.js +0 -1705
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import type { ImproveDescriptionOptions, ImproveDescriptionResult } from './improve-description.js';
|
|
2
|
-
import type { TriggerEvalOptions, TriggerEvalReport } from './run-trigger-eval.js';
|
|
3
|
-
|
|
4
|
-
export interface DescriptionLoopRecord {
|
|
5
|
-
iteration: number;
|
|
6
|
-
description: string;
|
|
7
|
-
score: string;
|
|
8
|
-
train: TriggerEvalReport['summary'];
|
|
9
|
-
test: TriggerEvalReport['summary'] | null;
|
|
10
|
-
train_results: TriggerEvalReport['results'];
|
|
11
|
-
test_results: TriggerEvalReport['results'];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface DescriptionLoopReport {
|
|
15
|
-
skill_name: string;
|
|
16
|
-
original_description: string;
|
|
17
|
-
final_description: string;
|
|
18
|
-
best_description: string;
|
|
19
|
-
history: DescriptionLoopRecord[];
|
|
20
|
-
train_size: number;
|
|
21
|
-
test_size: number;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface DescriptionLoopOptions extends TriggerEvalOptions {
|
|
25
|
-
workspaceDir: string;
|
|
26
|
-
maxIterations: number;
|
|
27
|
-
holdout?: number;
|
|
28
|
-
seed?: number;
|
|
29
|
-
writeBest?: boolean;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function splitEvalSet(
|
|
33
|
-
evals: Array<Record<string, unknown> & { should_trigger?: boolean }>,
|
|
34
|
-
holdout?: number,
|
|
35
|
-
seed?: number
|
|
36
|
-
): {
|
|
37
|
-
train: Array<Record<string, unknown> & { should_trigger?: boolean }>;
|
|
38
|
-
test: Array<Record<string, unknown> & { should_trigger?: boolean }>;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export function runDescriptionLoop(
|
|
42
|
-
options: DescriptionLoopOptions,
|
|
43
|
-
dependencies?: {
|
|
44
|
-
runTriggerEvalFn?: (options: TriggerEvalOptions) => Promise<TriggerEvalReport>;
|
|
45
|
-
improveDescriptionFn?: (
|
|
46
|
-
options: ImproveDescriptionOptions
|
|
47
|
-
) => Promise<ImproveDescriptionResult>;
|
|
48
|
-
}
|
|
49
|
-
): Promise<DescriptionLoopReport>;
|
|
1
|
+
import type { ImproveDescriptionOptions, ImproveDescriptionResult } from './improve-description.js';
|
|
2
|
+
import type { TriggerEvalOptions, TriggerEvalReport } from './run-trigger-eval.js';
|
|
3
|
+
|
|
4
|
+
export interface DescriptionLoopRecord {
|
|
5
|
+
iteration: number;
|
|
6
|
+
description: string;
|
|
7
|
+
score: string;
|
|
8
|
+
train: TriggerEvalReport['summary'];
|
|
9
|
+
test: TriggerEvalReport['summary'] | null;
|
|
10
|
+
train_results: TriggerEvalReport['results'];
|
|
11
|
+
test_results: TriggerEvalReport['results'];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface DescriptionLoopReport {
|
|
15
|
+
skill_name: string;
|
|
16
|
+
original_description: string;
|
|
17
|
+
final_description: string;
|
|
18
|
+
best_description: string;
|
|
19
|
+
history: DescriptionLoopRecord[];
|
|
20
|
+
train_size: number;
|
|
21
|
+
test_size: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface DescriptionLoopOptions extends TriggerEvalOptions {
|
|
25
|
+
workspaceDir: string;
|
|
26
|
+
maxIterations: number;
|
|
27
|
+
holdout?: number;
|
|
28
|
+
seed?: number;
|
|
29
|
+
writeBest?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function splitEvalSet(
|
|
33
|
+
evals: Array<Record<string, unknown> & { should_trigger?: boolean }>,
|
|
34
|
+
holdout?: number,
|
|
35
|
+
seed?: number
|
|
36
|
+
): {
|
|
37
|
+
train: Array<Record<string, unknown> & { should_trigger?: boolean }>;
|
|
38
|
+
test: Array<Record<string, unknown> & { should_trigger?: boolean }>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function runDescriptionLoop(
|
|
42
|
+
options: DescriptionLoopOptions,
|
|
43
|
+
dependencies?: {
|
|
44
|
+
runTriggerEvalFn?: (options: TriggerEvalOptions) => Promise<TriggerEvalReport>;
|
|
45
|
+
improveDescriptionFn?: (
|
|
46
|
+
options: ImproveDescriptionOptions
|
|
47
|
+
) => Promise<ImproveDescriptionResult>;
|
|
48
|
+
}
|
|
49
|
+
): Promise<DescriptionLoopReport>;
|
|
@@ -1,244 +1,244 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { loadSkill, pathExists, writeSkill } from './utils.js';
|
|
7
|
-
import { improveDescription } from './improve-description.js';
|
|
8
|
-
import { runTriggerEval } from './run-trigger-eval.js';
|
|
9
|
-
|
|
10
|
-
export function splitEvalSet(evals, holdout = 0.25, seed = 42) {
|
|
11
|
-
if (holdout <= 0 || evals.length < 4) {
|
|
12
|
-
return { train: [...evals], test: [] };
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let random = seed;
|
|
16
|
-
const nextRandom = () => {
|
|
17
|
-
random = (random * 1664525 + 1013904223) % 4294967296;
|
|
18
|
-
return random / 4294967296;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const shuffle = (items) => {
|
|
22
|
-
const result = [...items];
|
|
23
|
-
for (let index = result.length - 1; index > 0; index -= 1) {
|
|
24
|
-
const swapIndex = Math.floor(nextRandom() * (index + 1));
|
|
25
|
-
[result[index], result[swapIndex]] = [result[swapIndex], result[index]];
|
|
26
|
-
}
|
|
27
|
-
return result;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const positives = evals.filter((item) => item.should_trigger === true);
|
|
31
|
-
const negatives = evals.filter((item) => item.should_trigger !== true);
|
|
32
|
-
const shuffledPositives = shuffle(positives);
|
|
33
|
-
const shuffledNegatives = shuffle(negatives);
|
|
34
|
-
|
|
35
|
-
const pickCount = (items) => {
|
|
36
|
-
if (items.length <= 1) {
|
|
37
|
-
return 0;
|
|
38
|
-
}
|
|
39
|
-
return Math.max(1, Math.floor(items.length * holdout));
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const posCount = pickCount(shuffledPositives);
|
|
43
|
-
const negCount = pickCount(shuffledNegatives);
|
|
44
|
-
|
|
45
|
-
const test = [
|
|
46
|
-
...shuffledPositives.slice(0, posCount),
|
|
47
|
-
...shuffledNegatives.slice(0, negCount),
|
|
48
|
-
];
|
|
49
|
-
const train = [
|
|
50
|
-
...shuffledPositives.slice(posCount),
|
|
51
|
-
...shuffledNegatives.slice(negCount),
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
return { train, test };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function writeTempEvalFile(workspaceDir, name, skillName, evals) {
|
|
58
|
-
const filePath = path.join(workspaceDir, `${name}.json`);
|
|
59
|
-
await writeFile(filePath, JSON.stringify({ skill_name: skillName, evals }, null, 2), 'utf8');
|
|
60
|
-
return filePath;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export async function runDescriptionLoop(
|
|
64
|
-
options,
|
|
65
|
-
dependencies = {
|
|
66
|
-
runTriggerEvalFn: runTriggerEval,
|
|
67
|
-
improveDescriptionFn: improveDescription,
|
|
68
|
-
}
|
|
69
|
-
) {
|
|
70
|
-
const resolvedDependencies = {
|
|
71
|
-
runTriggerEvalFn: runTriggerEval,
|
|
72
|
-
improveDescriptionFn: improveDescription,
|
|
73
|
-
...dependencies,
|
|
74
|
-
};
|
|
75
|
-
const skill = await loadSkill(options.skillPath);
|
|
76
|
-
const evalFile = JSON.parse(await readFile(options.evalsPath, 'utf8'));
|
|
77
|
-
const allEvals = Array.isArray(evalFile.evals) ? evalFile.evals : [];
|
|
78
|
-
const { train, test } = splitEvalSet(allEvals, options.holdout, options.seed);
|
|
79
|
-
const historyPath = path.join(options.workspaceDir, 'description-history.json');
|
|
80
|
-
|
|
81
|
-
let currentDescription = String(skill.frontmatter.description ?? '');
|
|
82
|
-
const history = [];
|
|
83
|
-
let best = null;
|
|
84
|
-
|
|
85
|
-
for (let iteration = 1; iteration <= options.maxIterations; iteration += 1) {
|
|
86
|
-
const trainFile = await writeTempEvalFile(options.workspaceDir, `train-iteration-${iteration}`, skill.frontmatter.name, train);
|
|
87
|
-
const trainResults = await resolvedDependencies.runTriggerEvalFn({
|
|
88
|
-
...options,
|
|
89
|
-
evalsPath: trainFile,
|
|
90
|
-
descriptionOverride: currentDescription,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
let testResults = null;
|
|
94
|
-
if (test.length > 0) {
|
|
95
|
-
const testFile = await writeTempEvalFile(options.workspaceDir, `test-iteration-${iteration}`, skill.frontmatter.name, test);
|
|
96
|
-
testResults = await resolvedDependencies.runTriggerEvalFn({
|
|
97
|
-
...options,
|
|
98
|
-
evalsPath: testFile,
|
|
99
|
-
descriptionOverride: currentDescription,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const score = `${trainResults.summary.passed}/${trainResults.summary.total}`;
|
|
104
|
-
const record = {
|
|
105
|
-
iteration,
|
|
106
|
-
description: currentDescription,
|
|
107
|
-
score,
|
|
108
|
-
train: trainResults.summary,
|
|
109
|
-
test: testResults?.summary ?? null,
|
|
110
|
-
train_results: trainResults.results,
|
|
111
|
-
test_results: testResults?.results ?? [],
|
|
112
|
-
};
|
|
113
|
-
history.push(record);
|
|
114
|
-
|
|
115
|
-
const currentComparable = testResults?.summary.passed ?? trainResults.summary.passed;
|
|
116
|
-
const bestComparable = best?.comparable ?? -1;
|
|
117
|
-
if (currentComparable > bestComparable) {
|
|
118
|
-
best = {
|
|
119
|
-
comparable: currentComparable,
|
|
120
|
-
record,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (trainResults.summary.failed === 0 || iteration === options.maxIterations) {
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const improveInputPath = path.join(options.workspaceDir, `iteration-${iteration}-train-results.json`);
|
|
129
|
-
await writeFile(improveInputPath, JSON.stringify(trainResults, null, 2), 'utf8');
|
|
130
|
-
if (!await pathExists(historyPath)) {
|
|
131
|
-
await writeFile(historyPath, JSON.stringify({ history }, null, 2), 'utf8');
|
|
132
|
-
}
|
|
133
|
-
const improved = await resolvedDependencies.improveDescriptionFn({
|
|
134
|
-
...options,
|
|
135
|
-
evalResultsPath: improveInputPath,
|
|
136
|
-
historyPath,
|
|
137
|
-
});
|
|
138
|
-
currentDescription = improved.description;
|
|
139
|
-
await writeFile(
|
|
140
|
-
historyPath,
|
|
141
|
-
JSON.stringify({ history }, null, 2),
|
|
142
|
-
'utf8'
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (options.writeBest) {
|
|
147
|
-
const finalDescription = best?.record.description ?? currentDescription;
|
|
148
|
-
skill.frontmatter.description = finalDescription;
|
|
149
|
-
await writeSkill(options.skillPath, skill.frontmatter, skill.body);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
skill_name: skill.frontmatter.name,
|
|
154
|
-
original_description: skill.frontmatter.description,
|
|
155
|
-
final_description: currentDescription,
|
|
156
|
-
best_description: best?.record.description ?? currentDescription,
|
|
157
|
-
history,
|
|
158
|
-
train_size: train.length,
|
|
159
|
-
test_size: test.length,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function parseArgs(argv) {
|
|
164
|
-
const args = {
|
|
165
|
-
skillPath: '',
|
|
166
|
-
evalsPath: '',
|
|
167
|
-
workspaceDir: '',
|
|
168
|
-
provider: 'anthropic',
|
|
169
|
-
model: undefined,
|
|
170
|
-
maxIterations: 3,
|
|
171
|
-
runsPerQuery: 1,
|
|
172
|
-
triggerThreshold: 0.5,
|
|
173
|
-
holdout: 0.25,
|
|
174
|
-
seed: 42,
|
|
175
|
-
maxIter: 18,
|
|
176
|
-
reasoningMode: 'off',
|
|
177
|
-
output: undefined,
|
|
178
|
-
writeBest: false,
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
for (let index = 2; index < argv.length; index += 1) {
|
|
182
|
-
const token = argv[index];
|
|
183
|
-
if (token === '--skill-path' && argv[index + 1]) {
|
|
184
|
-
args.skillPath = argv[++index];
|
|
185
|
-
} else if (token === '--evals' && argv[index + 1]) {
|
|
186
|
-
args.evalsPath = argv[++index];
|
|
187
|
-
} else if (token === '--workspace' && argv[index + 1]) {
|
|
188
|
-
args.workspaceDir = argv[++index];
|
|
189
|
-
} else if (token === '--provider' && argv[index + 1]) {
|
|
190
|
-
args.provider = argv[++index];
|
|
191
|
-
} else if (token === '--model' && argv[index + 1]) {
|
|
192
|
-
args.model = argv[++index];
|
|
193
|
-
} else if (token === '--max-iterations' && argv[index + 1]) {
|
|
194
|
-
args.maxIterations = Number(argv[++index]);
|
|
195
|
-
} else if (token === '--runs-per-query' && argv[index + 1]) {
|
|
196
|
-
args.runsPerQuery = Number(argv[++index]);
|
|
197
|
-
} else if (token === '--trigger-threshold' && argv[index + 1]) {
|
|
198
|
-
args.triggerThreshold = Number(argv[++index]);
|
|
199
|
-
} else if (token === '--holdout' && argv[index + 1]) {
|
|
200
|
-
args.holdout = Number(argv[++index]);
|
|
201
|
-
} else if (token === '--seed' && argv[index + 1]) {
|
|
202
|
-
args.seed = Number(argv[++index]);
|
|
203
|
-
} else if (token === '--max-iter' && argv[index + 1]) {
|
|
204
|
-
args.maxIter = Number(argv[++index]);
|
|
205
|
-
} else if (token === '--reasoning' && argv[index + 1]) {
|
|
206
|
-
args.reasoningMode = argv[++index];
|
|
207
|
-
} else if (token === '--output' && argv[index + 1]) {
|
|
208
|
-
args.output = argv[++index];
|
|
209
|
-
} else if (token === '--write-best') {
|
|
210
|
-
args.writeBest = true;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return args;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
async function main() {
|
|
218
|
-
const args = parseArgs(process.argv);
|
|
219
|
-
if (!args.skillPath || !args.evalsPath || !args.workspaceDir) {
|
|
220
|
-
console.error('Usage: node scripts/run-loop.js --skill-path <dir> --evals <evals.json> --workspace <dir> [--max-iterations 3]');
|
|
221
|
-
process.exit(1);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const report = await runDescriptionLoop(args);
|
|
225
|
-
const outputText = `${JSON.stringify(report, null, 2)}\n`;
|
|
226
|
-
|
|
227
|
-
if (args.output) {
|
|
228
|
-
await writeFile(args.output, outputText, 'utf8');
|
|
229
|
-
console.log(`Wrote ${path.resolve(args.output)}`);
|
|
230
|
-
} else {
|
|
231
|
-
process.stdout.write(outputText);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { loadSkill, pathExists, writeSkill } from './utils.js';
|
|
7
|
+
import { improveDescription } from './improve-description.js';
|
|
8
|
+
import { runTriggerEval } from './run-trigger-eval.js';
|
|
9
|
+
|
|
10
|
+
export function splitEvalSet(evals, holdout = 0.25, seed = 42) {
|
|
11
|
+
if (holdout <= 0 || evals.length < 4) {
|
|
12
|
+
return { train: [...evals], test: [] };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let random = seed;
|
|
16
|
+
const nextRandom = () => {
|
|
17
|
+
random = (random * 1664525 + 1013904223) % 4294967296;
|
|
18
|
+
return random / 4294967296;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const shuffle = (items) => {
|
|
22
|
+
const result = [...items];
|
|
23
|
+
for (let index = result.length - 1; index > 0; index -= 1) {
|
|
24
|
+
const swapIndex = Math.floor(nextRandom() * (index + 1));
|
|
25
|
+
[result[index], result[swapIndex]] = [result[swapIndex], result[index]];
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const positives = evals.filter((item) => item.should_trigger === true);
|
|
31
|
+
const negatives = evals.filter((item) => item.should_trigger !== true);
|
|
32
|
+
const shuffledPositives = shuffle(positives);
|
|
33
|
+
const shuffledNegatives = shuffle(negatives);
|
|
34
|
+
|
|
35
|
+
const pickCount = (items) => {
|
|
36
|
+
if (items.length <= 1) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
return Math.max(1, Math.floor(items.length * holdout));
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const posCount = pickCount(shuffledPositives);
|
|
43
|
+
const negCount = pickCount(shuffledNegatives);
|
|
44
|
+
|
|
45
|
+
const test = [
|
|
46
|
+
...shuffledPositives.slice(0, posCount),
|
|
47
|
+
...shuffledNegatives.slice(0, negCount),
|
|
48
|
+
];
|
|
49
|
+
const train = [
|
|
50
|
+
...shuffledPositives.slice(posCount),
|
|
51
|
+
...shuffledNegatives.slice(negCount),
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
return { train, test };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function writeTempEvalFile(workspaceDir, name, skillName, evals) {
|
|
58
|
+
const filePath = path.join(workspaceDir, `${name}.json`);
|
|
59
|
+
await writeFile(filePath, JSON.stringify({ skill_name: skillName, evals }, null, 2), 'utf8');
|
|
60
|
+
return filePath;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function runDescriptionLoop(
|
|
64
|
+
options,
|
|
65
|
+
dependencies = {
|
|
66
|
+
runTriggerEvalFn: runTriggerEval,
|
|
67
|
+
improveDescriptionFn: improveDescription,
|
|
68
|
+
}
|
|
69
|
+
) {
|
|
70
|
+
const resolvedDependencies = {
|
|
71
|
+
runTriggerEvalFn: runTriggerEval,
|
|
72
|
+
improveDescriptionFn: improveDescription,
|
|
73
|
+
...dependencies,
|
|
74
|
+
};
|
|
75
|
+
const skill = await loadSkill(options.skillPath);
|
|
76
|
+
const evalFile = JSON.parse(await readFile(options.evalsPath, 'utf8'));
|
|
77
|
+
const allEvals = Array.isArray(evalFile.evals) ? evalFile.evals : [];
|
|
78
|
+
const { train, test } = splitEvalSet(allEvals, options.holdout, options.seed);
|
|
79
|
+
const historyPath = path.join(options.workspaceDir, 'description-history.json');
|
|
80
|
+
|
|
81
|
+
let currentDescription = String(skill.frontmatter.description ?? '');
|
|
82
|
+
const history = [];
|
|
83
|
+
let best = null;
|
|
84
|
+
|
|
85
|
+
for (let iteration = 1; iteration <= options.maxIterations; iteration += 1) {
|
|
86
|
+
const trainFile = await writeTempEvalFile(options.workspaceDir, `train-iteration-${iteration}`, skill.frontmatter.name, train);
|
|
87
|
+
const trainResults = await resolvedDependencies.runTriggerEvalFn({
|
|
88
|
+
...options,
|
|
89
|
+
evalsPath: trainFile,
|
|
90
|
+
descriptionOverride: currentDescription,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
let testResults = null;
|
|
94
|
+
if (test.length > 0) {
|
|
95
|
+
const testFile = await writeTempEvalFile(options.workspaceDir, `test-iteration-${iteration}`, skill.frontmatter.name, test);
|
|
96
|
+
testResults = await resolvedDependencies.runTriggerEvalFn({
|
|
97
|
+
...options,
|
|
98
|
+
evalsPath: testFile,
|
|
99
|
+
descriptionOverride: currentDescription,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const score = `${trainResults.summary.passed}/${trainResults.summary.total}`;
|
|
104
|
+
const record = {
|
|
105
|
+
iteration,
|
|
106
|
+
description: currentDescription,
|
|
107
|
+
score,
|
|
108
|
+
train: trainResults.summary,
|
|
109
|
+
test: testResults?.summary ?? null,
|
|
110
|
+
train_results: trainResults.results,
|
|
111
|
+
test_results: testResults?.results ?? [],
|
|
112
|
+
};
|
|
113
|
+
history.push(record);
|
|
114
|
+
|
|
115
|
+
const currentComparable = testResults?.summary.passed ?? trainResults.summary.passed;
|
|
116
|
+
const bestComparable = best?.comparable ?? -1;
|
|
117
|
+
if (currentComparable > bestComparable) {
|
|
118
|
+
best = {
|
|
119
|
+
comparable: currentComparable,
|
|
120
|
+
record,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (trainResults.summary.failed === 0 || iteration === options.maxIterations) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const improveInputPath = path.join(options.workspaceDir, `iteration-${iteration}-train-results.json`);
|
|
129
|
+
await writeFile(improveInputPath, JSON.stringify(trainResults, null, 2), 'utf8');
|
|
130
|
+
if (!await pathExists(historyPath)) {
|
|
131
|
+
await writeFile(historyPath, JSON.stringify({ history }, null, 2), 'utf8');
|
|
132
|
+
}
|
|
133
|
+
const improved = await resolvedDependencies.improveDescriptionFn({
|
|
134
|
+
...options,
|
|
135
|
+
evalResultsPath: improveInputPath,
|
|
136
|
+
historyPath,
|
|
137
|
+
});
|
|
138
|
+
currentDescription = improved.description;
|
|
139
|
+
await writeFile(
|
|
140
|
+
historyPath,
|
|
141
|
+
JSON.stringify({ history }, null, 2),
|
|
142
|
+
'utf8'
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (options.writeBest) {
|
|
147
|
+
const finalDescription = best?.record.description ?? currentDescription;
|
|
148
|
+
skill.frontmatter.description = finalDescription;
|
|
149
|
+
await writeSkill(options.skillPath, skill.frontmatter, skill.body);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
skill_name: skill.frontmatter.name,
|
|
154
|
+
original_description: skill.frontmatter.description,
|
|
155
|
+
final_description: currentDescription,
|
|
156
|
+
best_description: best?.record.description ?? currentDescription,
|
|
157
|
+
history,
|
|
158
|
+
train_size: train.length,
|
|
159
|
+
test_size: test.length,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function parseArgs(argv) {
|
|
164
|
+
const args = {
|
|
165
|
+
skillPath: '',
|
|
166
|
+
evalsPath: '',
|
|
167
|
+
workspaceDir: '',
|
|
168
|
+
provider: 'anthropic',
|
|
169
|
+
model: undefined,
|
|
170
|
+
maxIterations: 3,
|
|
171
|
+
runsPerQuery: 1,
|
|
172
|
+
triggerThreshold: 0.5,
|
|
173
|
+
holdout: 0.25,
|
|
174
|
+
seed: 42,
|
|
175
|
+
maxIter: 18,
|
|
176
|
+
reasoningMode: 'off',
|
|
177
|
+
output: undefined,
|
|
178
|
+
writeBest: false,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
for (let index = 2; index < argv.length; index += 1) {
|
|
182
|
+
const token = argv[index];
|
|
183
|
+
if (token === '--skill-path' && argv[index + 1]) {
|
|
184
|
+
args.skillPath = argv[++index];
|
|
185
|
+
} else if (token === '--evals' && argv[index + 1]) {
|
|
186
|
+
args.evalsPath = argv[++index];
|
|
187
|
+
} else if (token === '--workspace' && argv[index + 1]) {
|
|
188
|
+
args.workspaceDir = argv[++index];
|
|
189
|
+
} else if (token === '--provider' && argv[index + 1]) {
|
|
190
|
+
args.provider = argv[++index];
|
|
191
|
+
} else if (token === '--model' && argv[index + 1]) {
|
|
192
|
+
args.model = argv[++index];
|
|
193
|
+
} else if (token === '--max-iterations' && argv[index + 1]) {
|
|
194
|
+
args.maxIterations = Number(argv[++index]);
|
|
195
|
+
} else if (token === '--runs-per-query' && argv[index + 1]) {
|
|
196
|
+
args.runsPerQuery = Number(argv[++index]);
|
|
197
|
+
} else if (token === '--trigger-threshold' && argv[index + 1]) {
|
|
198
|
+
args.triggerThreshold = Number(argv[++index]);
|
|
199
|
+
} else if (token === '--holdout' && argv[index + 1]) {
|
|
200
|
+
args.holdout = Number(argv[++index]);
|
|
201
|
+
} else if (token === '--seed' && argv[index + 1]) {
|
|
202
|
+
args.seed = Number(argv[++index]);
|
|
203
|
+
} else if (token === '--max-iter' && argv[index + 1]) {
|
|
204
|
+
args.maxIter = Number(argv[++index]);
|
|
205
|
+
} else if (token === '--reasoning' && argv[index + 1]) {
|
|
206
|
+
args.reasoningMode = argv[++index];
|
|
207
|
+
} else if (token === '--output' && argv[index + 1]) {
|
|
208
|
+
args.output = argv[++index];
|
|
209
|
+
} else if (token === '--write-best') {
|
|
210
|
+
args.writeBest = true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return args;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function main() {
|
|
218
|
+
const args = parseArgs(process.argv);
|
|
219
|
+
if (!args.skillPath || !args.evalsPath || !args.workspaceDir) {
|
|
220
|
+
console.error('Usage: node scripts/run-loop.js --skill-path <dir> --evals <evals.json> --workspace <dir> [--max-iterations 3]');
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const report = await runDescriptionLoop(args);
|
|
225
|
+
const outputText = `${JSON.stringify(report, null, 2)}\n`;
|
|
226
|
+
|
|
227
|
+
if (args.output) {
|
|
228
|
+
await writeFile(args.output, outputText, 'utf8');
|
|
229
|
+
console.log(`Wrote ${path.resolve(args.output)}`);
|
|
230
|
+
} else {
|
|
231
|
+
process.stdout.write(outputText);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
235
|
const isDirectRun = process.env.KODAX_MODULE_BUNDLE !== 'true'
|
|
236
236
|
&& process.argv[1]
|
|
237
|
-
&& fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
238
|
-
|
|
239
|
-
if (isDirectRun) {
|
|
240
|
-
main().catch((error) => {
|
|
241
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
242
|
-
process.exit(1);
|
|
243
|
-
});
|
|
244
|
-
}
|
|
237
|
+
&& fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
238
|
+
|
|
239
|
+
if (isDirectRun) {
|
|
240
|
+
main().catch((error) => {
|
|
241
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
242
|
+
process.exit(1);
|
|
243
|
+
});
|
|
244
|
+
}
|