codiedev 0.9.78 → 0.9.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +4 -1
- package/dist/commands/traces.js +57 -1
- package/dist/commands/tracesLabel.d.ts +24 -0
- package/dist/commands/tracesLabel.js +356 -0
- package/dist/utils.js +7 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -95,11 +95,14 @@ Starter packs:
|
|
|
95
95
|
|
|
96
96
|
Traces (agents on the gateway):
|
|
97
97
|
codiedev traces agents Agents you maintain, with saved test cases
|
|
98
|
-
codiedev traces cases <agent> [--dataset name] [--model id]
|
|
98
|
+
codiedev traces cases <agent> [--dataset name [--version n]] [--model id]
|
|
99
99
|
Pull an agent's test cases (or one dataset)
|
|
100
100
|
into this repo for your coding agent to
|
|
101
101
|
run, optionally on another model
|
|
102
102
|
codiedev traces report <results.json> Send the results back to Traces
|
|
103
|
+
codiedev traces overview | runs | run | score | scores | score-kinds | queue | judge | import | add-example | versions | save-version
|
|
104
|
+
Agents, runs, failures, scores, review queues,
|
|
105
|
+
automatic scoring and datasets (codiedev traces help)
|
|
103
106
|
codiedev evals report <run.json> File one variant's eval scores under an experiment
|
|
104
107
|
codiedev evals last <subject> Latest experiment on a subject + its champion
|
|
105
108
|
|
package/dist/commands/traces.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// `codiedev traces agents`
|
|
3
3
|
// `codiedev traces cases <agent> [--dataset name] [--model id] [--out dir] [--json]`
|
|
4
4
|
// `codiedev traces report <results.json> [--harness name]`
|
|
5
|
+
// (scores, review queues, automatic scoring and datasets: ./tracesLabel.ts)
|
|
5
6
|
//
|
|
6
7
|
// Test cases are runs an engineer saved from Codiedev → Traces. They run in
|
|
7
8
|
// the engineer's coding agent, not in the portal: `cases` writes them into the
|
|
@@ -51,8 +52,9 @@ exports.runTraces = runTraces;
|
|
|
51
52
|
const fs = __importStar(require("fs"));
|
|
52
53
|
const path = __importStar(require("path"));
|
|
53
54
|
const shared_1 = require("./shared");
|
|
55
|
+
const tracesLabel_1 = require("./tracesLabel");
|
|
54
56
|
exports.TRACES_HELP = `
|
|
55
|
-
codiedev traces — test cases
|
|
57
|
+
codiedev traces — test cases, scores, review queues and automatic scoring from Codiedev → Traces
|
|
56
58
|
|
|
57
59
|
codiedev traces agents Agents you maintain, with saved case counts
|
|
58
60
|
codiedev traces cases <agent> [--dataset name [--version n]] [--case id[,id]] [--model id] [--out dir] [--json]
|
|
@@ -66,6 +68,36 @@ codiedev traces — test cases saved from Codiedev → Traces
|
|
|
66
68
|
Send the filled-in results back, so
|
|
67
69
|
Traces shows the pass rate for that model
|
|
68
70
|
|
|
71
|
+
codiedev traces overview [--days n] [--json]
|
|
72
|
+
Every agent you can see: runs, failures,
|
|
73
|
+
spend, and what's going wrong most
|
|
74
|
+
codiedev traces runs <agent> [--failed] [--flag name] [--model id] [--verdict pass|fail] [--days n] [--limit n] [--json]
|
|
75
|
+
An agent's runs, newest first
|
|
76
|
+
codiedev traces run <run> [--agent name] [--json]
|
|
77
|
+
One run: steps, what went wrong and the fix,
|
|
78
|
+
scores, prompts and replies (maintainers)
|
|
79
|
+
codiedev traces score-kinds [add <name> --type number|categories|boolean [--min n --max n] [--categories a,b]]
|
|
80
|
+
List or add the kinds of score your team uses
|
|
81
|
+
codiedev traces queue create <name> [--scores a,b] [--description text]
|
|
82
|
+
codiedev traces score <run> <score> <value> [--agent name] [--comment text] [--step n]
|
|
83
|
+
Score a run (a portal run id agent~run, or
|
|
84
|
+
the agent's own run id with --agent)
|
|
85
|
+
codiedev traces scores <agent> [--days n] [--json]
|
|
86
|
+
Each score's average or mix, and the score kinds
|
|
87
|
+
codiedev traces queue list Review queues and how many are left
|
|
88
|
+
codiedev traces queue add <queue> --agent <name> [--failed] [--days n] [--run id ...]
|
|
89
|
+
File runs into a queue for people to review
|
|
90
|
+
codiedev traces judge <agent> [--on | --off] [--scores a,b] [--instructions text]
|
|
91
|
+
[--model id] [--sample percent] [--daily n] [--budget usd | --key cdvm_…]
|
|
92
|
+
Show or set automatic scoring (a judge model
|
|
93
|
+
scores a sample of runs, billed to your key)
|
|
94
|
+
codiedev traces import <agent> <file.csv|file.jsonl> --dataset <name>
|
|
95
|
+
Add examples from a file (input, expected, name)
|
|
96
|
+
codiedev traces add-example <agent> --dataset <name> --input <text> [--expected <text>] [--name <text>]
|
|
97
|
+
codiedev traces versions <dataset> A dataset's saved versions and what changed
|
|
98
|
+
codiedev traces save-version <dataset> [--note text]
|
|
99
|
+
Save the dataset as its next version
|
|
100
|
+
|
|
69
101
|
<agent> is the agent's name (its API key name) or id. Only an agent's
|
|
70
102
|
maintainers can pull its cases or report on them.
|
|
71
103
|
`.trim();
|
|
@@ -295,6 +327,30 @@ async function runTraces(args, configOverride) {
|
|
|
295
327
|
return runCases(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
296
328
|
if (sub === "report")
|
|
297
329
|
return runReport(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
330
|
+
if (sub === "overview")
|
|
331
|
+
return (0, tracesLabel_1.runOverview)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
332
|
+
if (sub === "runs")
|
|
333
|
+
return (0, tracesLabel_1.runRuns)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
334
|
+
if (sub === "run")
|
|
335
|
+
return (0, tracesLabel_1.runRun)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
336
|
+
if (sub === "score-kinds")
|
|
337
|
+
return (0, tracesLabel_1.runScoreKinds)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
338
|
+
if (sub === "score")
|
|
339
|
+
return (0, tracesLabel_1.runScore)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
340
|
+
if (sub === "scores")
|
|
341
|
+
return (0, tracesLabel_1.runScores)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
342
|
+
if (sub === "queue")
|
|
343
|
+
return (0, tracesLabel_1.runQueue)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
344
|
+
if (sub === "judge")
|
|
345
|
+
return (0, tracesLabel_1.runJudge)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
346
|
+
if (sub === "import")
|
|
347
|
+
return (0, tracesLabel_1.runImport)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
348
|
+
if (sub === "add-example")
|
|
349
|
+
return (0, tracesLabel_1.runAddExample)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
350
|
+
if (sub === "versions")
|
|
351
|
+
return (0, tracesLabel_1.runVersions)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
352
|
+
if (sub === "save-version")
|
|
353
|
+
return (0, tracesLabel_1.runSaveVersion)(rest, configOverride ?? (0, shared_1.requireConfig)());
|
|
298
354
|
console.log(exports.TRACES_HELP);
|
|
299
355
|
if (sub && sub !== "help")
|
|
300
356
|
process.exit(1);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CodiedevConfig } from "../utils";
|
|
2
|
+
type Parsed = {
|
|
3
|
+
positional: string[];
|
|
4
|
+
flags: Record<string, string>;
|
|
5
|
+
bools: Set<string>;
|
|
6
|
+
runs: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare function parseArgs(args: string[]): Parsed;
|
|
9
|
+
/** "4" → 4, "true" → true, anything else as text (a category). */
|
|
10
|
+
export declare function scoreValue(raw: string): number | boolean | string;
|
|
11
|
+
export declare function runScore(args: string[], config: CodiedevConfig): Promise<void>;
|
|
12
|
+
export declare function runScores(args: string[], config: CodiedevConfig): Promise<void>;
|
|
13
|
+
export declare function runQueue(args: string[], config: CodiedevConfig): Promise<void>;
|
|
14
|
+
export declare function runJudge(args: string[], config: CodiedevConfig): Promise<void>;
|
|
15
|
+
export declare function runImport(args: string[], config: CodiedevConfig): Promise<void>;
|
|
16
|
+
export declare function runAddExample(args: string[], config: CodiedevConfig): Promise<void>;
|
|
17
|
+
export declare function runVersions(args: string[], config: CodiedevConfig): Promise<void>;
|
|
18
|
+
export declare function runSaveVersion(args: string[], config: CodiedevConfig): Promise<void>;
|
|
19
|
+
export declare function runOverview(args: string[], config: CodiedevConfig): Promise<void>;
|
|
20
|
+
export declare function runRuns(args: string[], config: CodiedevConfig): Promise<void>;
|
|
21
|
+
export declare function runRun(args: string[], config: CodiedevConfig): Promise<void>;
|
|
22
|
+
export declare function runScoreKinds(args: string[], config: CodiedevConfig): Promise<void>;
|
|
23
|
+
export declare function runQueueCreate(args: string[], config: CodiedevConfig): Promise<void>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// `codiedev traces overview | runs | run | score | scores | score-kinds |
|
|
3
|
+
// queue | judge | import | add-example | versions | save-version`: what the
|
|
4
|
+
// Traces portal shows and does (agents, runs, failures, scores, review
|
|
5
|
+
// queues, automatic scoring, datasets), so a coding agent can do it from
|
|
6
|
+
// plain words ("put this week's failed runs in the Week 44 queue"). Each
|
|
7
|
+
// calls a /api/cli/traces/* route that runs the portal's own code, with the
|
|
8
|
+
// same permissions.
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.parseArgs = parseArgs;
|
|
44
|
+
exports.scoreValue = scoreValue;
|
|
45
|
+
exports.runScore = runScore;
|
|
46
|
+
exports.runScores = runScores;
|
|
47
|
+
exports.runQueue = runQueue;
|
|
48
|
+
exports.runJudge = runJudge;
|
|
49
|
+
exports.runImport = runImport;
|
|
50
|
+
exports.runAddExample = runAddExample;
|
|
51
|
+
exports.runVersions = runVersions;
|
|
52
|
+
exports.runSaveVersion = runSaveVersion;
|
|
53
|
+
exports.runOverview = runOverview;
|
|
54
|
+
exports.runRuns = runRuns;
|
|
55
|
+
exports.runRun = runRun;
|
|
56
|
+
exports.runScoreKinds = runScoreKinds;
|
|
57
|
+
exports.runQueueCreate = runQueueCreate;
|
|
58
|
+
const fs = __importStar(require("fs"));
|
|
59
|
+
const path = __importStar(require("path"));
|
|
60
|
+
const shared_1 = require("./shared");
|
|
61
|
+
const BOOL_FLAGS = new Set(["--failed", "--on", "--off", "--json"]);
|
|
62
|
+
function parseArgs(args) {
|
|
63
|
+
const out = { positional: [], flags: {}, bools: new Set(), runs: [] };
|
|
64
|
+
for (let i = 0; i < args.length; i++) {
|
|
65
|
+
const a = args[i];
|
|
66
|
+
if (BOOL_FLAGS.has(a)) {
|
|
67
|
+
out.bools.add(a);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (a.startsWith("--")) {
|
|
71
|
+
const eq = a.indexOf("=");
|
|
72
|
+
const name = eq > 0 ? a.slice(0, eq) : a;
|
|
73
|
+
const value = eq > 0 ? a.slice(eq + 1) : args[++i];
|
|
74
|
+
if (value === undefined)
|
|
75
|
+
throw new Error(`${name} needs a value`);
|
|
76
|
+
if (name === "--run")
|
|
77
|
+
out.runs.push(value);
|
|
78
|
+
else
|
|
79
|
+
out.flags[name] = value;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
out.positional.push(a);
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
/** "4" → 4, "true" → true, anything else as text (a category). */
|
|
87
|
+
function scoreValue(raw) {
|
|
88
|
+
const t = raw.trim();
|
|
89
|
+
if (/^(true|false)$/i.test(t))
|
|
90
|
+
return t.toLowerCase() === "true";
|
|
91
|
+
if (t !== "" && Number.isFinite(Number(t)))
|
|
92
|
+
return Number(t);
|
|
93
|
+
return t;
|
|
94
|
+
}
|
|
95
|
+
async function call(config, tool, method, route, opts) {
|
|
96
|
+
const start = Date.now();
|
|
97
|
+
try {
|
|
98
|
+
const res = await (0, shared_1.apiRequest)(method, `/api/cli/traces/${route}`, { config, ...opts });
|
|
99
|
+
(0, shared_1.recordAgentEvent)(config, { tool, ok: true, latencyMs: Date.now() - start });
|
|
100
|
+
return res;
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
const e = err;
|
|
104
|
+
(0, shared_1.recordAgentEvent)(config, { tool, ok: false, latencyMs: Date.now() - start, error: e.message });
|
|
105
|
+
console.error(e.message);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function usage(text) {
|
|
110
|
+
console.error(`Usage: ${text}`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
async function runScore(args, config) {
|
|
114
|
+
const p = parseArgs(args);
|
|
115
|
+
const [run, name, value] = p.positional;
|
|
116
|
+
if (!run || !name || value === undefined)
|
|
117
|
+
usage("codiedev traces score <run> <score> <value> [--agent name] [--comment text] [--step n]");
|
|
118
|
+
const res = await call(config, "codiedev_traces_score", "POST", "score", {
|
|
119
|
+
body: { run, name, value: scoreValue(value), agent: p.flags["--agent"], comment: p.flags["--comment"], ...(p.flags["--step"] ? { step: Number(p.flags["--step"]) } : {}) },
|
|
120
|
+
});
|
|
121
|
+
console.log(`✓ Scored ${res.runId}: ${name} = ${value}`);
|
|
122
|
+
}
|
|
123
|
+
async function runScores(args, config) {
|
|
124
|
+
const p = parseArgs(args);
|
|
125
|
+
const agent = p.positional[0];
|
|
126
|
+
if (!agent)
|
|
127
|
+
usage("codiedev traces scores <agent> [--days n] [--json]");
|
|
128
|
+
const res = await call(config, "codiedev_traces_scores", "GET", "scores", { query: { agent, days: p.flags["--days"] ?? "7" } });
|
|
129
|
+
if (p.bools.has("--json")) {
|
|
130
|
+
process.stdout.write(JSON.stringify(res, null, 2) + "\n");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (!res.summary.length)
|
|
134
|
+
console.log(`No scores on ${res.agent} in the last ${p.flags["--days"] ?? 7} days.`);
|
|
135
|
+
for (const s of res.summary) {
|
|
136
|
+
const head = s.dataType === "boolean" && s.average !== null ? `${Math.round(s.average * 100)}% true`
|
|
137
|
+
: s.dataType === "numeric" && s.average !== null ? `avg ${Math.round(s.average * 100) / 100}`
|
|
138
|
+
: s.categories.map((c) => `${c.label} ${c.count}`).join(", ");
|
|
139
|
+
const from = [s.bySource.annotation ? `${s.bySource.annotation} people` : "", s.bySource.api ? `${s.bySource.api} your app` : "", s.bySource.judge ? `${s.bySource.judge} judge` : ""].filter(Boolean).join(", ");
|
|
140
|
+
console.log(`${s.name.padEnd(24)} ${head.padEnd(28)} ${s.count} scores (${from})`);
|
|
141
|
+
}
|
|
142
|
+
if (res.kinds.length)
|
|
143
|
+
console.log(`\nScore kinds: ${res.kinds.map((k) => `${k.name} (${k.dataType === "numeric" ? `${k.min ?? ""}–${k.max ?? ""}` : k.dataType === "boolean" ? "true/false" : k.categories.join("/")})`).join(", ")}`);
|
|
144
|
+
}
|
|
145
|
+
async function runQueue(args, config) {
|
|
146
|
+
const [verb, ...rest] = args;
|
|
147
|
+
if (verb === "list" || verb === undefined) {
|
|
148
|
+
const res = await call(config, "codiedev_traces_queue_list", "GET", "queues", {});
|
|
149
|
+
const live = res.queues.filter((q) => !q.archived);
|
|
150
|
+
if (!live.length)
|
|
151
|
+
console.log("No review queues yet. Make one in Codiedev → Traces → Review.");
|
|
152
|
+
for (const q of live)
|
|
153
|
+
console.log(`${q.name.padEnd(28)} ${String(q.pending).padStart(4)} to review ${String(q.done).padStart(4)} done ${q.scoreNames.join(", ")}`);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (verb === "create")
|
|
157
|
+
return runQueueCreate(rest, config);
|
|
158
|
+
if (verb !== "add")
|
|
159
|
+
usage("codiedev traces queue list | queue create <name> [--scores a,b] | queue add <queue> --agent <name> [--failed] [--days n] [--run id ...]");
|
|
160
|
+
const p = parseArgs(rest);
|
|
161
|
+
const queue = p.positional[0];
|
|
162
|
+
if (!queue || (!p.flags["--agent"] && !p.runs.length))
|
|
163
|
+
usage("codiedev traces queue add <queue> --agent <name> [--failed] [--days n] [--run id ...]");
|
|
164
|
+
const res = await call(config, "codiedev_traces_queue_add", "POST", "queue", {
|
|
165
|
+
body: { queue, agent: p.flags["--agent"], failed: p.bools.has("--failed"), ...(p.flags["--days"] ? { days: Number(p.flags["--days"]) } : {}), ...(p.runs.length ? { runs: p.runs } : {}) },
|
|
166
|
+
});
|
|
167
|
+
console.log(`✓ Added ${res.added} ${res.added === 1 ? "run" : "runs"} to ${res.queue}${res.skipped ? ` (${res.skipped} already there or not yours)` : ""}. Review them in Codiedev → Traces → Review.`);
|
|
168
|
+
}
|
|
169
|
+
function printJudge(agent, judge) {
|
|
170
|
+
if (!judge || judge === "none") {
|
|
171
|
+
console.log(`Automatic scoring isn't set up for ${agent}.`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
console.log(`${agent}: automatic scoring ${judge.enabled ? "on" : "off"}`);
|
|
175
|
+
console.log(` scores ${judge.scoreNames.join(", ")} · ${Math.round(judge.sampleRate * 100)}% of runs, up to ${judge.dailyMaxRuns}/day · ${judge.model}`);
|
|
176
|
+
if (judge.judgeKey)
|
|
177
|
+
console.log(` billed to ${judge.judgeKey.name}${judge.judgeKey.monthlyBudgetUsd !== null ? ` ($${judge.judgeKey.monthlyBudgetUsd}/mo)` : ""} · ${judge.judgedToday} judged in 24h${judge.errorsToday ? `, ${judge.errorsToday} failed` : ""}`);
|
|
178
|
+
if (judge.lastError)
|
|
179
|
+
console.log(` last problem: ${judge.lastError}`);
|
|
180
|
+
}
|
|
181
|
+
async function runJudge(args, config) {
|
|
182
|
+
const p = parseArgs(args);
|
|
183
|
+
const agent = p.positional[0];
|
|
184
|
+
const help = "codiedev traces judge <agent> [--on | --off] [--scores a,b] [--instructions text] [--model id] [--sample percent] [--daily n] [--budget usd | --key cdvm_…]";
|
|
185
|
+
if (!agent)
|
|
186
|
+
usage(help);
|
|
187
|
+
const changing = p.bools.has("--on") || p.bools.has("--off") || Object.keys(p.flags).length > 0;
|
|
188
|
+
if (!changing) {
|
|
189
|
+
const res = await call(config, "codiedev_traces_judge", "GET", "judge", { query: { agent } });
|
|
190
|
+
printJudge(res.agent, res.judge);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const res = await call(config, "codiedev_traces_judge_set", "POST", "judge", {
|
|
194
|
+
body: {
|
|
195
|
+
agent,
|
|
196
|
+
...(p.bools.has("--on") ? { enabled: true } : p.bools.has("--off") ? { enabled: false } : {}),
|
|
197
|
+
...(p.flags["--scores"] ? { scores: p.flags["--scores"].split(",").map((s) => s.trim()).filter(Boolean) } : {}),
|
|
198
|
+
...(p.flags["--instructions"] ? { instructions: p.flags["--instructions"] } : {}),
|
|
199
|
+
...(p.flags["--model"] ? { model: p.flags["--model"] } : {}),
|
|
200
|
+
...(p.flags["--sample"] ? { sampleRate: Number(p.flags["--sample"]) / 100 } : {}),
|
|
201
|
+
...(p.flags["--daily"] ? { dailyMaxRuns: Number(p.flags["--daily"]) } : {}),
|
|
202
|
+
...(p.flags["--budget"] ? { newKeyBudgetUsd: Number(p.flags["--budget"]) } : {}),
|
|
203
|
+
...(p.flags["--key"] ? { pastedKey: p.flags["--key"] } : {}),
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
printJudge(res.agent, res.judge);
|
|
207
|
+
}
|
|
208
|
+
async function runImport(args, config) {
|
|
209
|
+
const p = parseArgs(args);
|
|
210
|
+
const [agent, file] = p.positional;
|
|
211
|
+
const dataset = p.flags["--dataset"];
|
|
212
|
+
if (!agent || !file || !dataset)
|
|
213
|
+
usage("codiedev traces import <agent> <file.csv|file.jsonl> --dataset <name>");
|
|
214
|
+
let text;
|
|
215
|
+
try {
|
|
216
|
+
text = fs.readFileSync(path.resolve(process.cwd(), file), "utf8");
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
console.error(`Couldn't read ${file}: ${err.message}`);
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
const res = await call(config, "codiedev_traces_import", "POST", "examples", { body: { agent, dataset, text } });
|
|
223
|
+
console.log(`✓ Imported ${res.added} ${res.added === 1 ? "example" : "examples"} into ${dataset} for ${agent}.`);
|
|
224
|
+
for (const e of res.errors.slice(0, 10))
|
|
225
|
+
console.log(` skipped${e.line ? ` line ${e.line}` : ""}: ${e.error}`);
|
|
226
|
+
}
|
|
227
|
+
async function runAddExample(args, config) {
|
|
228
|
+
const p = parseArgs(args);
|
|
229
|
+
const agent = p.positional[0];
|
|
230
|
+
const dataset = p.flags["--dataset"];
|
|
231
|
+
const input = p.flags["--input"];
|
|
232
|
+
if (!agent || !dataset || !input)
|
|
233
|
+
usage("codiedev traces add-example <agent> --dataset <name> --input <text> [--expected <text>] [--name <text>]");
|
|
234
|
+
await call(config, "codiedev_traces_add_example", "POST", "examples", { body: { agent, dataset, input, expected: p.flags["--expected"], name: p.flags["--name"] } });
|
|
235
|
+
console.log(`✓ Added an example to ${dataset} for ${agent}.`);
|
|
236
|
+
}
|
|
237
|
+
async function runVersions(args, config) {
|
|
238
|
+
const dataset = parseArgs(args).positional[0];
|
|
239
|
+
if (!dataset)
|
|
240
|
+
usage("codiedev traces versions <dataset>");
|
|
241
|
+
const res = await call(config, "codiedev_traces_versions", "GET", "versions", { query: { dataset } });
|
|
242
|
+
if (!res.versions.length)
|
|
243
|
+
console.log(`${dataset} has no saved versions. Save one with: codiedev traces save-version "${dataset}"`);
|
|
244
|
+
for (const v of res.versions)
|
|
245
|
+
console.log(`v${v.version} ${String(v.cases).padStart(4)} cases ${new Date(v.createdAt).toISOString().slice(0, 10)} +${v.added} −${v.removed} ${v.changed} edited${v.note ? ` ${v.note}` : ""}`);
|
|
246
|
+
if (res.unsaved)
|
|
247
|
+
console.log(`Unsaved since v${res.versions[0].version}: +${res.unsaved.added} −${res.unsaved.removed} ${res.unsaved.changed} edited`);
|
|
248
|
+
}
|
|
249
|
+
async function runSaveVersion(args, config) {
|
|
250
|
+
const p = parseArgs(args);
|
|
251
|
+
const dataset = p.positional[0];
|
|
252
|
+
if (!dataset)
|
|
253
|
+
usage("codiedev traces save-version <dataset> [--note text]");
|
|
254
|
+
const res = await call(config, "codiedev_traces_save_version", "POST", "versions", { body: { dataset, note: p.flags["--note"] } });
|
|
255
|
+
console.log(`✓ Saved ${dataset} as v${res.version} (${res.cases} cases). Run it later with --dataset "${dataset}" --version ${res.version}.`);
|
|
256
|
+
}
|
|
257
|
+
const usd = (n) => (n === 0 ? "$0" : n < 0.01 ? "<$0.01" : `$${n.toFixed(2)}`);
|
|
258
|
+
const json = (p, value) => { if (p.bools.has("--json")) {
|
|
259
|
+
process.stdout.write(JSON.stringify(value, null, 2) + "\n");
|
|
260
|
+
return true;
|
|
261
|
+
} return false; };
|
|
262
|
+
async function runOverview(args, config) {
|
|
263
|
+
const p = parseArgs(args);
|
|
264
|
+
const res = await call(config, "codiedev_traces_overview", "GET", "overview", { query: { days: p.flags["--days"] ?? "7" } });
|
|
265
|
+
if (json(p, res))
|
|
266
|
+
return;
|
|
267
|
+
if (!res.agents.length) {
|
|
268
|
+
console.log("No agents you can see yet. Connect one in Codiedev → Traces.");
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
console.log(`Agents, last ${res.range}:`);
|
|
272
|
+
for (const a of res.agents)
|
|
273
|
+
console.log(` ${a.name.padEnd(28)} ${String(a.runs).padStart(6)} runs ${String(a.failedRuns).padStart(5)} failed ${usd(a.spend7dUsd).padStart(9)} 7d spend ${a.keepsPromptsDays ? `prompts ${a.keepsPromptsDays}d` : "metadata only"}${a.spike ? " spend spike" : ""}${a.budgetBlock ? " budget block" : ""}`);
|
|
274
|
+
if (res.issues.length) {
|
|
275
|
+
console.log("\nWhat's going wrong:");
|
|
276
|
+
for (const i of res.issues)
|
|
277
|
+
console.log(` ${i.label.padEnd(18)} ${String(i.runs).padStart(5)} runs ${usd(i.wastedUsd).padStart(9)} wasted ${i.agents.join(", ")}${i.exampleRun ? ` e.g. ${i.exampleRun}` : ""}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async function runRuns(args, config) {
|
|
281
|
+
const p = parseArgs(args);
|
|
282
|
+
const agent = p.positional[0];
|
|
283
|
+
if (!agent)
|
|
284
|
+
usage("codiedev traces runs <agent> [--failed] [--flag errors|truncated|tool_loop|context_overflow|budget_block] [--model id] [--verdict pass|fail] [--days n] [--limit n] [--json]");
|
|
285
|
+
const res = await call(config, "codiedev_traces_runs", "GET", "runs", {
|
|
286
|
+
query: { agent, days: p.flags["--days"] ?? "7", ...(p.bools.has("--failed") ? { failed: "1" } : {}), ...(p.flags["--flag"] ? { flag: p.flags["--flag"] } : {}), ...(p.flags["--model"] ? { model: p.flags["--model"] } : {}), ...(p.flags["--verdict"] ? { verdict: p.flags["--verdict"] } : {}), limit: p.flags["--limit"] ?? "50" },
|
|
287
|
+
});
|
|
288
|
+
if (json(p, res))
|
|
289
|
+
return;
|
|
290
|
+
console.log(`${res.total} ${res.total === 1 ? "run" : "runs"} for ${res.agent}, last ${res.range}${res.total > res.runs.length ? ` (newest ${res.runs.length})` : ""}:`);
|
|
291
|
+
for (const r of res.runs)
|
|
292
|
+
console.log(` ${r.startedAt.slice(0, 16).replace("T", " ")} ${r.status === "failed" ? "FAIL" : " ok "} ${r.runId.padEnd(24)} ${String(r.steps).padStart(3)} calls ${usd(r.costUsd).padStart(8)} ${r.model ?? ""}${r.flags.length ? ` [${r.flags.join(", ")}]` : ""}${r.verdict ? ` marked ${r.verdict}` : ""}`);
|
|
293
|
+
if (res.runs.length)
|
|
294
|
+
console.log(`\nOpen one: codiedev traces run ${res.runs[0].runId} --agent "${res.agent}"`);
|
|
295
|
+
}
|
|
296
|
+
async function runRun(args, config) {
|
|
297
|
+
const p = parseArgs(args);
|
|
298
|
+
const run = p.positional[0];
|
|
299
|
+
if (!run)
|
|
300
|
+
usage("codiedev traces run <run> [--agent name] [--json]");
|
|
301
|
+
const res = await call(config, "codiedev_traces_run", "GET", "run", { query: { run, ...(p.flags["--agent"] ? { agent: p.flags["--agent"] } : {}) } });
|
|
302
|
+
if (json(p, res))
|
|
303
|
+
return;
|
|
304
|
+
const r = res.run;
|
|
305
|
+
console.log(`${r.title} · ${r.id}`);
|
|
306
|
+
console.log(`${new Date(r.startedAt).toISOString().slice(0, 16).replace("T", " ")} · ${r.status === "failed" ? "FAILED" : "ok"} · ${Math.round(r.durationMs / 100) / 10}s · ${usd(r.costUsd)}${r.flags.length ? ` · ${r.flags.join(", ")}` : ""}`);
|
|
307
|
+
if (r.diagnosis)
|
|
308
|
+
console.log(`\nWhat went wrong: ${r.diagnosis.title}\n ${r.diagnosis.why}\n\nFix (for your coding agent):\n${r.diagnosis.fix.split("\n").map((l) => ` ${l}`).join("\n")}`);
|
|
309
|
+
if (r.annotation)
|
|
310
|
+
console.log(`\nMarked ${r.annotation.verdict} by ${r.annotation.by}${r.annotation.reason ? `: ${r.annotation.reason}` : ""}`);
|
|
311
|
+
if (res.scores.length)
|
|
312
|
+
console.log(`\nScores: ${res.scores.map((s) => `${s.name} ${s.text}${s.step ? ` (step ${s.step})` : ""} by ${s.by ?? s.source}${s.comment ? ` "${s.comment}"` : ""}`).join("; ")}`);
|
|
313
|
+
console.log("\nSteps:");
|
|
314
|
+
for (const s of r.spans.filter((x) => x.kind !== "run")) {
|
|
315
|
+
console.log(` ${s.kind === "tool" ? "tool" : "call"} ${s.name} ${Math.round(s.durationMs)}ms${s.costUsd !== undefined ? ` ${usd(s.costUsd)}` : ""}${s.finishReason ? ` finish: ${s.finishReason}` : ""}${s.statusCode && s.statusCode >= 400 ? ` HTTP ${s.statusCode}` : ""}${s.flag ? ` [${s.flag}]` : ""}${s.note ? ` ${s.note}` : ""}`);
|
|
316
|
+
if (s.input)
|
|
317
|
+
console.log(` prompt: ${s.input.replace(/\s+/g, " ").slice(0, 300)}`);
|
|
318
|
+
if (s.output)
|
|
319
|
+
console.log(` reply: ${s.output.replace(/\s+/g, " ").slice(0, 300)}`);
|
|
320
|
+
}
|
|
321
|
+
if (!r.bodiesVisible)
|
|
322
|
+
console.log("\n(Prompts and replies are shown only to the agent's maintainers.)");
|
|
323
|
+
}
|
|
324
|
+
async function runScoreKinds(args, config) {
|
|
325
|
+
const [verb, ...rest] = args;
|
|
326
|
+
if (verb === "add") {
|
|
327
|
+
const p = parseArgs(rest);
|
|
328
|
+
const name = p.positional[0];
|
|
329
|
+
const type = p.flags["--type"];
|
|
330
|
+
if (!name || !type)
|
|
331
|
+
usage("codiedev traces score-kinds add <name> --type number|categories|boolean [--min n --max n] [--categories a,b,c] [--description text]");
|
|
332
|
+
const dataType = type === "number" || type === "numeric" ? "numeric" : type === "categories" || type === "categorical" ? "categorical" : type === "boolean" || type === "bool" ? "boolean" : type;
|
|
333
|
+
await call(config, "codiedev_traces_score_kind_add", "POST", "score-kinds", {
|
|
334
|
+
body: { name, type: dataType, ...(p.flags["--min"] ? { min: Number(p.flags["--min"]) } : {}), ...(p.flags["--max"] ? { max: Number(p.flags["--max"]) } : {}), ...(p.flags["--categories"] ? { categories: p.flags["--categories"].split(",").map((c) => c.trim()) } : {}), ...(p.flags["--description"] ? { description: p.flags["--description"] } : {}) },
|
|
335
|
+
});
|
|
336
|
+
console.log(`✓ Added score kind ${name}.`);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const p = parseArgs(verb === undefined || verb === "list" ? rest : args);
|
|
340
|
+
const res = await call(config, "codiedev_traces_score_kinds", "GET", "score-kinds", {});
|
|
341
|
+
if (json(p, res))
|
|
342
|
+
return;
|
|
343
|
+
const live = res.kinds.filter((k) => !k.archived);
|
|
344
|
+
if (!live.length)
|
|
345
|
+
console.log("No score kinds yet. Add one: codiedev traces score-kinds add helpfulness --type number --min 1 --max 5");
|
|
346
|
+
for (const k of live)
|
|
347
|
+
console.log(` ${k.name.padEnd(24)} ${k.dataType === "numeric" ? `number ${k.min ?? ""}–${k.max ?? ""}` : k.dataType === "boolean" ? "true / false" : k.categories.join(" / ")}${k.description ? ` ${k.description}` : ""}`);
|
|
348
|
+
}
|
|
349
|
+
async function runQueueCreate(args, config) {
|
|
350
|
+
const p = parseArgs(args);
|
|
351
|
+
const name = p.positional[0];
|
|
352
|
+
if (!name)
|
|
353
|
+
usage("codiedev traces queue create <name> [--scores a,b] [--description text]");
|
|
354
|
+
await call(config, "codiedev_traces_queue_create", "POST", "queues", { body: { name, scores: (p.flags["--scores"] ?? "").split(",").map((s) => s.trim()).filter(Boolean), ...(p.flags["--description"] ? { description: p.flags["--description"] } : {}) } });
|
|
355
|
+
console.log(`✓ Created review queue ${name}. Add runs: codiedev traces queue add "${name}" --agent <name> --failed`);
|
|
356
|
+
}
|
package/dist/utils.js
CHANGED
|
@@ -1681,7 +1681,13 @@ thought, use the \`codiedev\` CLI via Bash:**
|
|
|
1681
1681
|
| "find something about X" / "has anyone solved Y?" | \`codiedev search "<query>" [--limit N]\` |
|
|
1682
1682
|
| "why did we…?" / "what does the team know about X?" | \`codiedev ask "<question>"\` (synthesized answer + citations) |
|
|
1683
1683
|
| "show my library" / "what artifacts exist?" | \`codiedev library [--scope mine\\|shared\\|all] [--kind doc\\|skill]\` |
|
|
1684
|
-
| "run my agent's test cases" / "check the dataset on model Y" | \`codiedev traces cases <agent> [--dataset <name>] [--model <id>]\` (writes cases + RUN_CASES.md + results.json; follow it, then \`codiedev traces report <results.json>\`) |
|
|
1684
|
+
| "run my agent's test cases" / "check the dataset on model Y" / "run v2 of the dataset" | \`codiedev traces cases <agent> [--dataset <name> [--version <n>]] [--model <id>]\` (writes cases + RUN_CASES.md + results.json; follow it, then \`codiedev traces report <results.json>\`) |
|
|
1685
|
+
| "how are my agents doing?" / "what's failing this week?" / "show the booking agent's failed runs" / "why did run X fail?" | \`codiedev traces overview\`; \`codiedev traces runs <agent> [--failed] [--flag <issue>] [--days n]\`; \`codiedev traces run <run> --agent <name>\` (add \`--json\` to read the data yourself) |
|
|
1686
|
+
| "add a helpfulness 1–5 score" / "make a review queue for tone" | \`codiedev traces score-kinds add <name> --type number --min 1 --max 5\`; \`codiedev traces queue create <name> --scores <a,b>\` |
|
|
1687
|
+
| "score that run 4 for helpfulness" / "how is my agent scoring?" | \`codiedev traces score <run> <score> <value> [--agent <name>] [--comment <why>]\`; \`codiedev traces scores <agent>\` |
|
|
1688
|
+
| "put this week's failed runs in the review queue" | \`codiedev traces queue list\`; \`codiedev traces queue add <queue> --agent <name> [--failed] [--days n]\` |
|
|
1689
|
+
| "have a judge score 10% of my agent's runs" / "turn off automatic scoring" | \`codiedev traces judge <agent> --on --scores <a,b> --sample 10 [--budget 25]\`; \`--off\`; no flags shows it |
|
|
1690
|
+
| "import these test cases from a CSV" / "add an example to the dataset" / "save the dataset as a version" | \`codiedev traces import <agent> <file> --dataset <name>\`; \`codiedev traces add-example <agent> --dataset <name> --input "…" [--expected "…"]\`; \`codiedev traces save-version <dataset>\`; \`codiedev traces versions <dataset>\` |
|
|
1685
1691
|
| "what was the last eval on X?" / "file these eval results" | \`codiedev evals last <subject>\` before starting a related eval; \`codiedev evals report <run.json>\` after each variant runs (scores only — \`codiedev evals help\` for the shape) |
|
|
1686
1692
|
|
|
1687
1693
|
**Just push the file — we'll figure out where it goes.** Every artifact
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codiedev",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.79",
|
|
4
4
|
"description": "Connect Claude Code, Codex, Cursor, OpenCode, or VS Code Copilot to Codiedev for team session capture and artifact collaboration — and run the governed Codie harness",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codiedev": "dist/cli.js",
|