@zenera/cli 1.1.24 → 1.1.26
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 +65 -0
- package/dist/ask.js +28 -5
- package/dist/banner.js +2 -2
- package/dist/batch.d.ts +6 -0
- package/dist/batch.js +76 -1
- package/dist/catalog.d.ts +31 -1
- package/dist/catalog.js +140 -7
- package/dist/commands/index.js +2 -0
- package/dist/commands/inspect.d.ts +52 -2
- package/dist/commands/inspect.js +220 -31
- package/dist/commands/memory.js +156 -32
- package/dist/commands/meta.js +333 -24
- package/dist/commands/models.js +97 -12
- package/dist/commands/open.js +4 -4
- package/dist/commands/run.js +38 -4
- package/dist/commands/sandbox.js +148 -16
- package/dist/commands/view.d.ts +8 -0
- package/dist/commands/view.js +114 -0
- package/dist/engine.d.ts +8 -1
- package/dist/engine.js +7 -0
- package/dist/eventlog.d.ts +64 -0
- package/dist/eventlog.js +170 -0
- package/dist/liveness.d.ts +7 -0
- package/dist/liveness.js +35 -3
- package/dist/main.js +0 -0
- package/dist/meta/editor.d.ts +9 -0
- package/dist/meta/editor.js +43 -0
- package/dist/meta/finetune/analyze-brief.d.ts +26 -0
- package/dist/meta/finetune/analyze-brief.js +131 -0
- package/dist/meta/finetune/apply-brief.d.ts +23 -0
- package/dist/meta/finetune/apply-brief.js +247 -0
- package/dist/meta/finetune/brief.d.ts +45 -0
- package/dist/meta/finetune/brief.js +158 -0
- package/dist/meta/finetune/children.d.ts +8 -0
- package/dist/meta/finetune/children.js +76 -0
- package/dist/meta/finetune/command.d.ts +30 -0
- package/dist/meta/finetune/command.js +516 -0
- package/dist/meta/finetune/cost.d.ts +46 -0
- package/dist/meta/finetune/cost.js +105 -0
- package/dist/meta/finetune/dataset/anchors.d.ts +41 -0
- package/dist/meta/finetune/dataset/anchors.js +239 -0
- package/dist/meta/finetune/dataset/changes.d.ts +36 -0
- package/dist/meta/finetune/dataset/changes.js +319 -0
- package/dist/meta/finetune/dataset/command.d.ts +17 -0
- package/dist/meta/finetune/dataset/command.js +1011 -0
- package/dist/meta/finetune/dataset/drift.d.ts +33 -0
- package/dist/meta/finetune/dataset/drift.js +71 -0
- package/dist/meta/finetune/dataset/export.d.ts +26 -0
- package/dist/meta/finetune/dataset/export.js +51 -0
- package/dist/meta/finetune/dataset/index.d.ts +2 -0
- package/dist/meta/finetune/dataset/index.js +2 -0
- package/dist/meta/finetune/dataset/sample.d.ts +50 -0
- package/dist/meta/finetune/dataset/sample.js +197 -0
- package/dist/meta/finetune/dataset/schema.d.ts +33 -0
- package/dist/meta/finetune/dataset/schema.js +216 -0
- package/dist/meta/finetune/dataset/store.d.ts +35 -0
- package/dist/meta/finetune/dataset/store.js +177 -0
- package/dist/meta/finetune/dataset/types.d.ts +127 -0
- package/dist/meta/finetune/dataset/types.js +39 -0
- package/dist/meta/finetune/failure.d.ts +15 -0
- package/dist/meta/finetune/failure.js +26 -0
- package/dist/meta/finetune/feedback.d.ts +57 -0
- package/dist/meta/finetune/feedback.js +104 -0
- package/dist/meta/finetune/guard.d.ts +29 -0
- package/dist/meta/finetune/guard.js +104 -0
- package/dist/meta/finetune/improvements.d.ts +98 -0
- package/dist/meta/finetune/improvements.js +501 -0
- package/dist/meta/finetune/index.d.ts +2 -0
- package/dist/meta/finetune/index.js +2 -0
- package/dist/meta/finetune/journal.d.ts +35 -0
- package/dist/meta/finetune/journal.js +135 -0
- package/dist/meta/finetune/live.d.ts +84 -0
- package/dist/meta/finetune/live.js +272 -0
- package/dist/meta/finetune/loop.d.ts +3 -0
- package/dist/meta/finetune/loop.js +163 -0
- package/dist/meta/finetune/memories.d.ts +47 -0
- package/dist/meta/finetune/memories.js +154 -0
- package/dist/meta/finetune/recheck.d.ts +58 -0
- package/dist/meta/finetune/recheck.js +311 -0
- package/dist/meta/finetune/report.d.ts +40 -0
- package/dist/meta/finetune/report.js +1397 -0
- package/dist/meta/finetune/retry.d.ts +24 -0
- package/dist/meta/finetune/retry.js +96 -0
- package/dist/meta/finetune/sampler.d.ts +18 -0
- package/dist/meta/finetune/sampler.js +47 -0
- package/dist/meta/finetune/system.d.ts +27 -0
- package/dist/meta/finetune/system.js +132 -0
- package/dist/meta/finetune/train.d.ts +43 -0
- package/dist/meta/finetune/train.js +425 -0
- package/dist/meta/finetune/tui.d.ts +16 -0
- package/dist/meta/finetune/tui.js +316 -0
- package/dist/meta/finetune/tuning.d.ts +193 -0
- package/dist/meta/finetune/tuning.js +308 -0
- package/dist/meta/finetune/usage.d.ts +66 -0
- package/dist/meta/finetune/usage.js +260 -0
- package/dist/meta/finetune/view.d.ts +9 -0
- package/dist/meta/finetune/view.js +27 -0
- package/dist/meta/host.d.ts +15 -0
- package/dist/meta/host.js +21 -0
- package/dist/meta/index.d.ts +11 -0
- package/dist/meta/index.js +11 -0
- package/dist/meta/launch.d.ts +81 -0
- package/dist/meta/launch.js +286 -0
- package/dist/meta/model.d.ts +44 -0
- package/dist/meta/model.js +119 -0
- package/dist/meta/prompts.d.ts +18 -0
- package/dist/meta/prompts.js +61 -0
- package/dist/meta/relay.d.ts +20 -0
- package/dist/meta/relay.js +123 -0
- package/dist/meta/tokens.d.ts +52 -0
- package/dist/meta/tokens.js +226 -0
- package/dist/meta/window.d.ts +61 -0
- package/dist/meta/window.js +198 -0
- package/dist/meta/wire.d.ts +42 -0
- package/dist/meta/wire.js +129 -0
- package/dist/meta.d.ts +71 -1
- package/dist/meta.js +303 -6
- package/dist/modelref.d.ts +16 -0
- package/dist/modelref.js +41 -0
- package/dist/narrate.js +5 -2
- package/dist/podman.d.ts +26 -0
- package/dist/podman.js +83 -3
- package/dist/projects.d.ts +0 -5
- package/dist/projects.js +2 -15
- package/dist/resources.d.ts +215 -0
- package/dist/resources.js +856 -0
- package/dist/sandbox.d.ts +2 -0
- package/dist/sandbox.js +10 -3
- package/dist/scaffold.d.ts +15 -7
- package/dist/scaffold.js +24 -67
- package/dist/session.js +4 -29
- package/dist/term.d.ts +2 -0
- package/dist/term.js +11 -2
- package/dist/trace.d.ts +5 -0
- package/dist/trace.js +107 -7
- package/dist/tui/app.js +19 -5
- package/dist/tui/links.d.ts +27 -0
- package/dist/tui/links.js +142 -0
- package/dist/tui/models.d.ts +35 -0
- package/dist/tui/models.js +447 -0
- package/dist/tui/sandbox.d.ts +10 -0
- package/dist/tui/sandbox.js +131 -0
- package/dist/tui/wrap.d.ts +5 -0
- package/dist/tui/wrap.js +12 -0
- package/dist/usage.d.ts +78 -0
- package/dist/usage.js +51 -0
- package/package.json +4 -2
- package/templates/editor/.github/copilot-instructions.md +60 -145
- package/templates/editor/.github/prompts/analyze.prompt.md +33 -0
- package/templates/editor/.github/prompts/dataset.prompt.md +108 -0
- package/templates/editor/.github/prompts/finetune-apply.prompt.md +270 -0
- package/templates/editor/.github/prompts/finetune.prompt.md +691 -198
- package/templates/editor/.github/prompts/new-agent.prompt.md +3 -1
- package/templates/editor/.github/prompts/new-skill.prompt.md +2 -0
- package/templates/editor/.github/prompts/project-review.prompt.md +5 -4
- package/templates/editor/.github/skills/zen-analyze-run/SKILL.md +588 -0
- package/templates/editor/.github/skills/zen-cli/SKILL.md +9 -1
- package/templates/editor/.github/skills/zen-cli/references/dataset.md +34 -0
- package/templates/editor/.github/skills/zen-cli/references/finetune.md +137 -0
- package/templates/editor/.github/skills/zen-cli/references/inspect.md +63 -11
- package/templates/editor/.github/skills/zen-cli/references/memory.md +33 -10
- package/templates/editor/.github/skills/zen-cli/references/meta.md +61 -0
- package/templates/editor/.github/skills/zen-cli/references/models.md +5 -1
- package/templates/editor/.github/skills/zen-cli/references/projects.md +4 -6
- package/templates/editor/.github/skills/zen-cli/references/rag.md +24 -6
- package/templates/editor/.github/skills/zen-cli/references/sandbox.md +35 -14
- package/templates/editor/.github/skills/zen-code-python/SKILL.md +123 -0
- package/templates/editor/.github/skills/zen-code-python/references/code_python.md +48 -0
- package/templates/editor/.github/skills/zen-dataset/SKILL.md +253 -0
- package/templates/editor/.github/skills/zen-finetune/SKILL.md +1492 -660
- package/templates/editor/.github/skills/zen-finetune/references/readme-template.md +268 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/batch.mjs +390 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/difficult.mjs +243 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/memory.mjs +280 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/next.mjs +398 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/report.mjs +797 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/select.mjs +354 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/usage.mjs +722 -0
- package/templates/editor/.github/skills/zen-inspect/SKILL.md +74 -26
- package/templates/editor/.github/skills/zen-inspect-ask/SKILL.md +271 -0
- package/templates/editor/.github/skills/zen-instructions/SKILL.md +4 -12
- package/templates/editor/.github/skills/zen-memory/SKILL.md +82 -53
- package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +20 -8
- package/templates/editor/.github/skills/zen-review/SKILL.md +8 -31
- package/templates/editor/.github/skills/zen-review/scripts/check-paths.sh +5 -5
- package/templates/editor/.github/skills/zen-review/scripts/review.sh +3 -12
- package/templates/editor/.github/skills/zen-sandbox/SKILL.md +9 -4
- package/templates/editor/.github/skills/zen-sandbox-capacity/SKILL.md +2 -2
- package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +2 -4
- package/templates/editor/.github/skills/zen-topology/SKILL.md +283 -0
- package/templates/editor/.vscode/settings.json +1 -0
- package/templates/project/agents/files-instructions.md +29 -20
- package/templates/project/agents/fork-instructions.md +78 -28
- package/templates/project/agents/memory-instructions.md +222 -494
- package/templates/project/agents/tools-instructions.md +14 -4
- package/templates/project/gitignore +2 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/collect.sh +0 -432
- package/templates/editor/.github/skills/zen-finetune/scripts/sample.sh +0 -199
- package/templates/editor/.github/skills/zen-memory/scripts/check-instructions.sh +0 -116
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, render, Text, useInput, useWindowSize } from 'ink';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
|
+
import { resolveTheme } from "../host.js";
|
|
6
|
+
import { since } from "./report.js";
|
|
7
|
+
import { short } from "./usage.js";
|
|
8
|
+
const BAR = 20;
|
|
9
|
+
const fit = (text, width) => text.length > width ? `${text.slice(0, Math.max(0, width - 1))}…` : text.padEnd(width);
|
|
10
|
+
const clock = (iso) => {
|
|
11
|
+
const d = new Date(iso);
|
|
12
|
+
return Number.isNaN(d.getTime()) ? ' ' : d.toTimeString().slice(0, 8);
|
|
13
|
+
};
|
|
14
|
+
const seconds = (ms) => ms === undefined
|
|
15
|
+
? ''
|
|
16
|
+
: ms < 60_000
|
|
17
|
+
? `${(ms / 1000).toFixed(ms < 10_000 ? 1 : 0)}s`
|
|
18
|
+
: since(ms);
|
|
19
|
+
function footer(width, keys, theme) {
|
|
20
|
+
return [
|
|
21
|
+
[{ text: '─'.repeat(Math.max(0, width)), color: theme.chrome.color }],
|
|
22
|
+
[{ text: keys, color: theme.chrome.color }],
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
function keysFor(s, following, url) {
|
|
26
|
+
if (s.state === 'stopping') {
|
|
27
|
+
return 'stopping: the steps under way finish first · ctrl-c again kills them';
|
|
28
|
+
}
|
|
29
|
+
if (s.state !== 'running') {
|
|
30
|
+
return s.state;
|
|
31
|
+
}
|
|
32
|
+
const open = url ? 'o open in browser · ' : '';
|
|
33
|
+
return following
|
|
34
|
+
? `esc back · ${open}s stop · ctrl-c stop, twice kills`
|
|
35
|
+
: `up/down choose · enter follow · ${open}s stop · ctrl-c stop, twice kills`;
|
|
36
|
+
}
|
|
37
|
+
/** The platform opener, without a shell, so the address stays one argument. */
|
|
38
|
+
function openInBrowser(url) {
|
|
39
|
+
const command = process.platform === 'darwin'
|
|
40
|
+
? 'open'
|
|
41
|
+
: process.platform === 'win32'
|
|
42
|
+
? 'explorer'
|
|
43
|
+
: 'xdg-open';
|
|
44
|
+
spawn(command, [url], { stdio: 'ignore', detached: true })
|
|
45
|
+
.on('error', () => { })
|
|
46
|
+
.unref();
|
|
47
|
+
}
|
|
48
|
+
function header(s, theme) {
|
|
49
|
+
const c = s.counts;
|
|
50
|
+
const n = (k) => c[k] ?? 0;
|
|
51
|
+
const done = n('completed') + n('difficult');
|
|
52
|
+
const filled = s.total ? Math.round((done / s.total) * BAR) : 0;
|
|
53
|
+
const quiet = theme.chrome.color;
|
|
54
|
+
const tally = [
|
|
55
|
+
{ text: '█'.repeat(filled), color: theme.accent },
|
|
56
|
+
{ text: '░'.repeat(BAR - filled), color: quiet },
|
|
57
|
+
{ text: ` ${done} of ${s.total} done` },
|
|
58
|
+
];
|
|
59
|
+
const add = (text, color) => {
|
|
60
|
+
tally.push({ text: ` · ${text}`, color });
|
|
61
|
+
};
|
|
62
|
+
if (n('completed')) {
|
|
63
|
+
add(`${n('completed')} completed`);
|
|
64
|
+
}
|
|
65
|
+
if (n('difficult')) {
|
|
66
|
+
add(`${n('difficult')} difficult`, theme.warn);
|
|
67
|
+
}
|
|
68
|
+
if (n('failed')) {
|
|
69
|
+
add(`${n('failed')} failed`, theme.line.error.color);
|
|
70
|
+
}
|
|
71
|
+
if (s.parked) {
|
|
72
|
+
add(`${s.parked} parked, apply at ${s.applyAt}`);
|
|
73
|
+
}
|
|
74
|
+
return [
|
|
75
|
+
[
|
|
76
|
+
{ text: `Fine-tuning ${s.project}`, bold: true },
|
|
77
|
+
{
|
|
78
|
+
text: ` · ${s.state} · ${since(s.elapsedMs)} · system v${s.system} · ${s.workers.busy} of ${s.workers.all} workers busy`,
|
|
79
|
+
color: quiet,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
tally,
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
const STAGE_HUE = {
|
|
86
|
+
dark: { run: 'green', analyze: 'magentaBright', apply: 'blueBright' },
|
|
87
|
+
light: { run: 'green', analyze: 'magenta', apply: 'blue' },
|
|
88
|
+
};
|
|
89
|
+
/** One hue per stage in every section: run/ran, analyze/analyzed, apply/applied. */
|
|
90
|
+
function hue(word, theme) {
|
|
91
|
+
const stage = /^(run|ran)\b/.test(word)
|
|
92
|
+
? 'run'
|
|
93
|
+
: word.startsWith('analy')
|
|
94
|
+
? 'analyze'
|
|
95
|
+
: word.startsWith('appl')
|
|
96
|
+
? 'apply'
|
|
97
|
+
: undefined;
|
|
98
|
+
return stage && STAGE_HUE[theme.appearance][stage];
|
|
99
|
+
}
|
|
100
|
+
/** worker, task, action, elapsed, tokens, model, latest - split around the action cell. */
|
|
101
|
+
function nowCells(cells, width) {
|
|
102
|
+
const [who = '', what = '', step = '', elapsed = '', tokens = '', model = '', last = ''] = cells;
|
|
103
|
+
return [
|
|
104
|
+
`${fit(who, 9)} ${fit(what, 26)} `,
|
|
105
|
+
fit(step, 8),
|
|
106
|
+
` ${fit(elapsed, 7)} ${fit(tokens, 6)} ${fit(model, width >= 110 ? 22 : 16)} ${last}`,
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
const nowRow = (r) => [
|
|
110
|
+
r.who,
|
|
111
|
+
r.what,
|
|
112
|
+
r.step,
|
|
113
|
+
since(r.sinceMs),
|
|
114
|
+
r.act?.calls ? short(r.act.input + r.act.output) : '',
|
|
115
|
+
r.act?.model ?? '',
|
|
116
|
+
r.act?.last ?? '',
|
|
117
|
+
];
|
|
118
|
+
/** case, result, took, tokens after the action: the result takes what the others leave. */
|
|
119
|
+
const logCells = (cells, width) => {
|
|
120
|
+
const [where, result, took, tokens] = cells;
|
|
121
|
+
return `${fit(where, 31)} ${fit(result, Math.max(10, width - 75))} ${fit(took, 7)} ${tokens}`;
|
|
122
|
+
};
|
|
123
|
+
/** The overview: under way, tokens, log - as many log rows as the height leaves. */
|
|
124
|
+
export function mainLines(s, selected, width, height, theme, url) {
|
|
125
|
+
const quiet = theme.chrome.color;
|
|
126
|
+
const out = [...header(s, theme)];
|
|
127
|
+
if (s.now.length > 0) {
|
|
128
|
+
out.push([], [{ text: 'In progress', bold: true }]);
|
|
129
|
+
out.push([
|
|
130
|
+
{
|
|
131
|
+
text: ` ${nowCells(['worker', 'task', 'action', 'elapsed', 'tokens', 'model', 'latest'], width).join('')}`,
|
|
132
|
+
color: quiet,
|
|
133
|
+
},
|
|
134
|
+
]);
|
|
135
|
+
s.now.forEach((r, i) => {
|
|
136
|
+
const [before, step, after] = nowCells(nowRow(r), width);
|
|
137
|
+
out.push([
|
|
138
|
+
i === selected ? { text: '> ', color: theme.accent, bold: true } : { text: ' ' },
|
|
139
|
+
{ text: before },
|
|
140
|
+
{ text: step, color: hue(r.step, theme) },
|
|
141
|
+
{ text: after },
|
|
142
|
+
]);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (s.tokens.length > 0) {
|
|
146
|
+
out.push([], [{ text: 'Tokens so far', bold: true }]);
|
|
147
|
+
out.push([
|
|
148
|
+
{
|
|
149
|
+
text: `${fit('stage', 8)} ${fit('model', 26)} ${'calls'.padStart(6)} ${'in'.padStart(7)} ${'out'.padStart(7)}`,
|
|
150
|
+
color: quiet,
|
|
151
|
+
},
|
|
152
|
+
]);
|
|
153
|
+
for (const r of s.tokens) {
|
|
154
|
+
out.push([
|
|
155
|
+
{ text: fit(r.stage, 8), color: hue(r.stage, theme) },
|
|
156
|
+
{
|
|
157
|
+
text: ` ${fit(r.model, 26)} ${String(r.calls).padStart(6)} ${short(r.input).padStart(7)} ${short(r.output).padStart(7)}`,
|
|
158
|
+
},
|
|
159
|
+
]);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (s.errors.length > 0) {
|
|
163
|
+
const red = theme.line.error.color;
|
|
164
|
+
out.push([], [{ text: 'Errors', bold: true, color: red }]);
|
|
165
|
+
for (const e of s.errors) {
|
|
166
|
+
out.push([
|
|
167
|
+
{ text: `${clock(e.at)} `, color: quiet },
|
|
168
|
+
{ text: `${fit(e.where, 28)} ` },
|
|
169
|
+
{ text: e.message, color: red },
|
|
170
|
+
]);
|
|
171
|
+
if (e.log) {
|
|
172
|
+
out.push([{ text: `${' '.repeat(9)}log ${e.log}`, color: quiet }]);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const room = height - out.length - 2 - 3;
|
|
177
|
+
if (s.log.length > 0 && room > 0) {
|
|
178
|
+
out.push([], [{ text: 'Log', bold: true }]);
|
|
179
|
+
out.push([
|
|
180
|
+
{
|
|
181
|
+
text: `${fit('time', 8)} ${fit('action', 18)} ${logCells(['case', 'result', 'took', 'tokens'], width)}`,
|
|
182
|
+
color: quiet,
|
|
183
|
+
},
|
|
184
|
+
]);
|
|
185
|
+
for (const r of s.log.slice(0, room)) {
|
|
186
|
+
out.push([
|
|
187
|
+
{ text: `${clock(r.at)} `, color: quiet },
|
|
188
|
+
{ text: fit(r.action, 18), color: hue(r.action, theme) },
|
|
189
|
+
{
|
|
190
|
+
text: ` ${logCells([r.case, r.result, seconds(r.took), r.tokens ? short(r.tokens) : ''], width)}`,
|
|
191
|
+
},
|
|
192
|
+
]);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return [...out, ...footer(width, keysFor(s, false, url), theme)];
|
|
196
|
+
}
|
|
197
|
+
function activity(e, theme) {
|
|
198
|
+
const at = { text: `${clock(e.t)} `, color: theme.chrome.color };
|
|
199
|
+
switch (e.type) {
|
|
200
|
+
case 'llm':
|
|
201
|
+
return [
|
|
202
|
+
at,
|
|
203
|
+
{
|
|
204
|
+
text: `model ${e.model} ${short(e.in)} in, ${short(e.out)} out${e.ms ? `, ${seconds(e.ms)}` : ''}`,
|
|
205
|
+
color: theme.chrome.color,
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
case 'tool':
|
|
209
|
+
return e.phase === 'start'
|
|
210
|
+
? [at, { text: `tool ${e.name} `, color: theme.accent }, { text: e.subject }]
|
|
211
|
+
: [
|
|
212
|
+
at,
|
|
213
|
+
{
|
|
214
|
+
text: ` ${e.ok ? 'done' : 'failed'} ${e.name}${e.ms ? ` ${seconds(e.ms)}` : ''}`,
|
|
215
|
+
color: e.ok ? theme.chrome.color : theme.line.error.color,
|
|
216
|
+
},
|
|
217
|
+
];
|
|
218
|
+
case 'say':
|
|
219
|
+
return [at, { text: 'says ', color: theme.accent }, { text: e.text }];
|
|
220
|
+
case 'think':
|
|
221
|
+
return [
|
|
222
|
+
at,
|
|
223
|
+
{ text: 'thinks ', color: theme.accent },
|
|
224
|
+
{ text: e.text, color: theme.chrome.color },
|
|
225
|
+
];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/** One step's agent, line by line as it works. */
|
|
229
|
+
export function followLines(s, key, width, height, theme, url) {
|
|
230
|
+
const r = s.now.find((x) => x.key === key);
|
|
231
|
+
const out = [];
|
|
232
|
+
if (!r) {
|
|
233
|
+
out.push([{ text: 'Nothing is under way there now.', bold: true }]);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
out.push([
|
|
237
|
+
{ text: `Following ${r.who}`, bold: true },
|
|
238
|
+
{
|
|
239
|
+
text: ` · ${r.what} · ${r.step} · ${since(r.sinceMs)}${r.act?.model ? ` · ${r.act.model}` : ''}${r.act?.calls ? ` · ${short(r.act.input + r.act.output)} tokens in ${r.act.calls} calls` : ''}`,
|
|
240
|
+
color: theme.chrome.color,
|
|
241
|
+
},
|
|
242
|
+
]);
|
|
243
|
+
out.push([]);
|
|
244
|
+
const lines = r.act?.lines ?? [];
|
|
245
|
+
if (lines.length === 0) {
|
|
246
|
+
out.push([{ text: 'nothing yet', color: theme.chrome.color }]);
|
|
247
|
+
}
|
|
248
|
+
for (const e of lines.slice(-Math.max(1, height - out.length - 3))) {
|
|
249
|
+
out.push(activity(e, theme));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return [...out, ...footer(width, keysFor(s, true, url), theme)];
|
|
253
|
+
}
|
|
254
|
+
function Live({ t, theme, interrupt, url, }) {
|
|
255
|
+
const [snap, setSnap] = useState();
|
|
256
|
+
const [selected, setSelected] = useState(0);
|
|
257
|
+
const [follow, setFollow] = useState();
|
|
258
|
+
const { columns, rows } = useWindowSize();
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
t.watchers.add(setSnap);
|
|
261
|
+
return () => {
|
|
262
|
+
t.watchers.delete(setSnap);
|
|
263
|
+
};
|
|
264
|
+
}, [t]);
|
|
265
|
+
const count = snap?.now.length ?? 0;
|
|
266
|
+
const at = Math.min(selected, Math.max(0, count - 1));
|
|
267
|
+
useInput((input, key) => {
|
|
268
|
+
if ((key.ctrl && input === 'c') || input === 's') {
|
|
269
|
+
interrupt();
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (input === 'o') {
|
|
273
|
+
if (url) {
|
|
274
|
+
openInBrowser(url);
|
|
275
|
+
}
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (follow) {
|
|
279
|
+
if (key.escape) {
|
|
280
|
+
setFollow(undefined);
|
|
281
|
+
}
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (key.upArrow) {
|
|
285
|
+
setSelected(Math.max(0, at - 1));
|
|
286
|
+
}
|
|
287
|
+
else if (key.downArrow) {
|
|
288
|
+
setSelected(Math.min(count - 1, at + 1));
|
|
289
|
+
}
|
|
290
|
+
else if (key.return && snap?.now[at]) {
|
|
291
|
+
setFollow(snap.now[at].key);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
if (!snap) {
|
|
295
|
+
return _jsx(Text, { color: theme.chrome.color, children: "starting" });
|
|
296
|
+
}
|
|
297
|
+
const height = Math.max(8, rows - 1);
|
|
298
|
+
const all = follow
|
|
299
|
+
? followLines(snap, follow, columns, height, theme, url)
|
|
300
|
+
: mainLines(snap, at, columns, height, theme, url);
|
|
301
|
+
// Too short a terminal loses rows from the middle, never the keys at the bottom.
|
|
302
|
+
const lines = all.length > height ? [...all.slice(0, height - 2), ...all.slice(-2)] : all;
|
|
303
|
+
return (_jsx(Box, { flexDirection: "column", children: lines.map((parts, i) => (_jsx(Text, { wrap: "truncate-end", children: parts.length === 0
|
|
304
|
+
? ' '
|
|
305
|
+
: parts.map((p, j) => (_jsx(Text, { color: p.color, bold: p.bold, children: p.text }, j))) }, i))) }));
|
|
306
|
+
}
|
|
307
|
+
/** Draws the tuning until the returned function is called. */
|
|
308
|
+
export async function watch(t, interrupt, url) {
|
|
309
|
+
const theme = await resolveTheme();
|
|
310
|
+
const instance = render(_jsx(Live, { t: t, theme: theme, interrupt: interrupt, url: url }), {
|
|
311
|
+
stdout: process.stderr,
|
|
312
|
+
exitOnCtrlC: false,
|
|
313
|
+
});
|
|
314
|
+
return () => instance.unmount();
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=tui.js.map
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { type ChildProcess } from 'node:child_process';
|
|
2
|
+
import type { Case } from './dataset/types.ts';
|
|
3
|
+
import type { Phase } from './feedback.ts';
|
|
4
|
+
import { Improvements } from './improvements.ts';
|
|
5
|
+
import { Journal } from './journal.ts';
|
|
6
|
+
import type { Snapshot } from './live.ts';
|
|
7
|
+
import { Memories } from './memories.ts';
|
|
8
|
+
import { Rechecks } from './recheck.ts';
|
|
9
|
+
import { SystemVersions } from './system.ts';
|
|
10
|
+
import type { ByStage } from './usage.ts';
|
|
11
|
+
export declare const FINETUNE_DIR = "finetune";
|
|
12
|
+
/** Where a tuning was kept before it moved to {@link FINETUNE_DIR}. */
|
|
13
|
+
export declare const LEGACY_FINETUNE_DIR = ".finetune";
|
|
14
|
+
export interface Config {
|
|
15
|
+
workers: number;
|
|
16
|
+
/** apply once this many requests are waiting */
|
|
17
|
+
applyAt: number;
|
|
18
|
+
tries: number;
|
|
19
|
+
memTries: number;
|
|
20
|
+
/** merge the submitted memories after this many more arrive */
|
|
21
|
+
mergeEvery: number;
|
|
22
|
+
seed: number;
|
|
23
|
+
/** completed cases run again after each apply, to catch what it broke */
|
|
24
|
+
recheck: number;
|
|
25
|
+
/** bytes one apply may add to what the agents always read */
|
|
26
|
+
budget: number;
|
|
27
|
+
/** percent over the start past which an apply may add nothing */
|
|
28
|
+
maxGrowth: number;
|
|
29
|
+
/** bytes one on-demand skill may hold */
|
|
30
|
+
skillCap: number;
|
|
31
|
+
/** skills one agent may see */
|
|
32
|
+
maxSkills: number;
|
|
33
|
+
classes?: string[];
|
|
34
|
+
ids?: string[];
|
|
35
|
+
rubric?: boolean;
|
|
36
|
+
limit?: number;
|
|
37
|
+
}
|
|
38
|
+
export declare const DEFAULTS: Config;
|
|
39
|
+
export type Step = 'idle' | 'run' | 'analyze' | 'parked';
|
|
40
|
+
export interface Worker {
|
|
41
|
+
slot: number;
|
|
42
|
+
case?: Case;
|
|
43
|
+
phase?: Phase;
|
|
44
|
+
attempt?: number;
|
|
45
|
+
step: Step;
|
|
46
|
+
since: number;
|
|
47
|
+
/** a recheck: the apply whose version it runs on, and the try's folder */
|
|
48
|
+
recheck?: {
|
|
49
|
+
apply: string;
|
|
50
|
+
dir: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** A case in flight. It holds a worker only while it runs or is analyzed; parked, it holds none. */
|
|
54
|
+
export interface Seat {
|
|
55
|
+
case: Case;
|
|
56
|
+
worker?: Worker;
|
|
57
|
+
phase?: Phase;
|
|
58
|
+
}
|
|
59
|
+
/** Runs `zen <args>` in the project, stderr into `log`; stdout is returned. */
|
|
60
|
+
export type Zen = (args: string[], log: string) => Promise<{
|
|
61
|
+
code: number;
|
|
62
|
+
stdout: string;
|
|
63
|
+
}>;
|
|
64
|
+
export declare class Stopped extends Error {
|
|
65
|
+
constructor();
|
|
66
|
+
}
|
|
67
|
+
export interface Event {
|
|
68
|
+
at: string;
|
|
69
|
+
what: string;
|
|
70
|
+
worker?: number;
|
|
71
|
+
case?: string;
|
|
72
|
+
rev?: number;
|
|
73
|
+
phase?: Phase;
|
|
74
|
+
attempt?: number;
|
|
75
|
+
detail?: string;
|
|
76
|
+
/** a step that ended: what it came to, how long it took, what it spent */
|
|
77
|
+
result?: string;
|
|
78
|
+
took?: number;
|
|
79
|
+
tokens?: number;
|
|
80
|
+
}
|
|
81
|
+
/** Failed cases in a row, with nothing going through between, that stop the loop. */
|
|
82
|
+
export declare const FAILURES_IN_A_ROW = 3;
|
|
83
|
+
export interface StepFailure {
|
|
84
|
+
at: string;
|
|
85
|
+
/** `merge-20 · no memory try 1`, `apply 004`, `memory m03` */
|
|
86
|
+
where: string;
|
|
87
|
+
message: string;
|
|
88
|
+
log?: string;
|
|
89
|
+
}
|
|
90
|
+
export declare class Tuning {
|
|
91
|
+
readonly root: string;
|
|
92
|
+
readonly dir: string;
|
|
93
|
+
readonly config: Config;
|
|
94
|
+
readonly zen: Zen;
|
|
95
|
+
readonly tickMs: number;
|
|
96
|
+
readonly workers: Worker[];
|
|
97
|
+
readonly claimed: Set<string>;
|
|
98
|
+
readonly startedAt: number;
|
|
99
|
+
readonly recent: Event[];
|
|
100
|
+
readonly system: SystemVersions;
|
|
101
|
+
readonly journal: Journal;
|
|
102
|
+
readonly improvements: Improvements;
|
|
103
|
+
readonly rechecks: Rechecks;
|
|
104
|
+
readonly memories: Memories;
|
|
105
|
+
stopping: boolean;
|
|
106
|
+
finished: boolean;
|
|
107
|
+
fatal: Error | undefined;
|
|
108
|
+
/** woken cases waiting for a worker: they go before any new case */
|
|
109
|
+
resuming: number;
|
|
110
|
+
/** every case of the selection has been started */
|
|
111
|
+
drained: boolean;
|
|
112
|
+
/** cases started by this process: a failed one is not taken twice in one start */
|
|
113
|
+
readonly tried: Set<string>;
|
|
114
|
+
/** `--more`: cases of any kind this start may take; not kept in loop.json */
|
|
115
|
+
more: number | undefined;
|
|
116
|
+
/** cases failed since the last step that went through */
|
|
117
|
+
failures: number;
|
|
118
|
+
/** what the last status page counted */
|
|
119
|
+
progress: {
|
|
120
|
+
counts: Record<string, number>;
|
|
121
|
+
total: number;
|
|
122
|
+
spent: ByStage;
|
|
123
|
+
} | undefined;
|
|
124
|
+
/** called with every live snapshot */
|
|
125
|
+
readonly watchers: Set<(s: Snapshot) => void>;
|
|
126
|
+
/** the latest live snapshot */
|
|
127
|
+
live: Snapshot | undefined;
|
|
128
|
+
/** the latest step failures, newest first */
|
|
129
|
+
readonly errors: StepFailure[];
|
|
130
|
+
constructor(root: string, config: Config, zen: Zen, tickMs?: number);
|
|
131
|
+
get stopFile(): string;
|
|
132
|
+
tick(): Promise<void>;
|
|
133
|
+
stop(why: string): void;
|
|
134
|
+
/** Between steps: a stop takes effect here, never in the middle of one. */
|
|
135
|
+
checkStopping(): void;
|
|
136
|
+
caseDir(c: {
|
|
137
|
+
id: string;
|
|
138
|
+
rev: number;
|
|
139
|
+
}): string;
|
|
140
|
+
/** Where `retry` puts a case's earlier rounds: `r<rev>.<round>`. */
|
|
141
|
+
roundsDir(c: {
|
|
142
|
+
id: string;
|
|
143
|
+
}): string;
|
|
144
|
+
/** 1 for a case never retried at this revision. */
|
|
145
|
+
round(c: {
|
|
146
|
+
id: string;
|
|
147
|
+
rev: number;
|
|
148
|
+
}): number;
|
|
149
|
+
/** A step went through: the sandbox and the providers are up. */
|
|
150
|
+
succeeded(): void;
|
|
151
|
+
/** A case failed for a reason outside the prose. Enough in a row means nothing will go through. */
|
|
152
|
+
failed(why: string): void;
|
|
153
|
+
/** No run goes through without the container engine: stop at the first sign, not the third. */
|
|
154
|
+
sandboxDown(why: string): void;
|
|
155
|
+
attemptDir(c: {
|
|
156
|
+
id: string;
|
|
157
|
+
rev: number;
|
|
158
|
+
}, phase: Phase, attempt: number): string;
|
|
159
|
+
/** The folder of the try a worker is on: the case's own, or a recheck's. */
|
|
160
|
+
workDir(w: Worker & {
|
|
161
|
+
case: Case;
|
|
162
|
+
}): string;
|
|
163
|
+
/** What the loop knows of a try, which a feedback file is never trusted for. */
|
|
164
|
+
known(c: {
|
|
165
|
+
id: string;
|
|
166
|
+
rev: number;
|
|
167
|
+
}, phase: Phase, attempt: number): {
|
|
168
|
+
phase: Phase;
|
|
169
|
+
attempt: number;
|
|
170
|
+
round?: number | undefined;
|
|
171
|
+
case: string;
|
|
172
|
+
caseRev: number;
|
|
173
|
+
};
|
|
174
|
+
freeWorker(): Worker | undefined;
|
|
175
|
+
busy(): number;
|
|
176
|
+
/** Puts a case on a free worker, waiting for one; a woken case goes before a new one. */
|
|
177
|
+
seat(s: Seat, woken: boolean): Promise<void>;
|
|
178
|
+
/** Gives the case's worker back, for another case to use. */
|
|
179
|
+
unseat(s: Seat): void;
|
|
180
|
+
/** A case moved to another step on its worker. */
|
|
181
|
+
at(s: Seat, phase: Phase, attempt: number, step: Step): void;
|
|
182
|
+
/** A step ended: the worker is between steps until the next `at`, and the event says how it went. */
|
|
183
|
+
ended(s: Seat, e: Omit<Event, 'at' | 'worker' | 'case' | 'rev'>): void;
|
|
184
|
+
/** A step failed: kept for the live view, and in events.jsonl with its log. */
|
|
185
|
+
error(where: string, message: string, log?: string): void;
|
|
186
|
+
event(e: Omit<Event, 'at'>): void;
|
|
187
|
+
/** `live`: only what moves by the second is read again; the rest comes from the last full report. */
|
|
188
|
+
report(live?: boolean): void;
|
|
189
|
+
}
|
|
190
|
+
/** The real `zen`: this same binary, in its own process group so Ctrl-C reaches only us. */
|
|
191
|
+
export declare function spawnZen(root: string, children: Set<ChildProcess>): Zen;
|
|
192
|
+
export declare function readJson<T>(file: string): T | undefined;
|
|
193
|
+
//# sourceMappingURL=tuning.d.ts.map
|