bitfab-cli 0.2.227 → 0.2.229
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/index.js +131 -103
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4974,7 +4974,7 @@ var require_compile = __commonJS({
|
|
|
4974
4974
|
const schOrFunc = root.refs[ref];
|
|
4975
4975
|
if (schOrFunc)
|
|
4976
4976
|
return schOrFunc;
|
|
4977
|
-
let _sch =
|
|
4977
|
+
let _sch = resolve4.call(this, root, ref);
|
|
4978
4978
|
if (_sch === void 0) {
|
|
4979
4979
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
4980
4980
|
const { schemaId } = this.opts;
|
|
@@ -5001,7 +5001,7 @@ var require_compile = __commonJS({
|
|
|
5001
5001
|
function sameSchemaEnv(s1, s2) {
|
|
5002
5002
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
5003
5003
|
}
|
|
5004
|
-
function
|
|
5004
|
+
function resolve4(root, ref) {
|
|
5005
5005
|
let sch;
|
|
5006
5006
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
5007
5007
|
ref = sch;
|
|
@@ -5632,7 +5632,7 @@ var require_fast_uri = __commonJS({
|
|
|
5632
5632
|
}
|
|
5633
5633
|
return uri;
|
|
5634
5634
|
}
|
|
5635
|
-
function
|
|
5635
|
+
function resolve4(baseURI, relativeURI, options) {
|
|
5636
5636
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
5637
5637
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
5638
5638
|
schemelessOptions.skipEscape = true;
|
|
@@ -5890,7 +5890,7 @@ var require_fast_uri = __commonJS({
|
|
|
5890
5890
|
var fastUri = {
|
|
5891
5891
|
SCHEMES,
|
|
5892
5892
|
normalize,
|
|
5893
|
-
resolve:
|
|
5893
|
+
resolve: resolve4,
|
|
5894
5894
|
resolveComponent,
|
|
5895
5895
|
equal,
|
|
5896
5896
|
serialize: serialize2,
|
|
@@ -9028,14 +9028,14 @@ async function pollAgentSessionEvents(opts) {
|
|
|
9028
9028
|
opts.onError(err instanceof Error ? err : new Error(String(err)));
|
|
9029
9029
|
}
|
|
9030
9030
|
}
|
|
9031
|
-
await new Promise((
|
|
9031
|
+
await new Promise((resolve4) => {
|
|
9032
9032
|
const onAbort = () => {
|
|
9033
9033
|
clearTimeout(timer);
|
|
9034
|
-
|
|
9034
|
+
resolve4();
|
|
9035
9035
|
};
|
|
9036
9036
|
const timer = setTimeout(() => {
|
|
9037
9037
|
opts.abortSignal.removeEventListener("abort", onAbort);
|
|
9038
|
-
|
|
9038
|
+
resolve4();
|
|
9039
9039
|
}, interval);
|
|
9040
9040
|
opts.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
9041
9041
|
});
|
|
@@ -9097,9 +9097,9 @@ var PING_PONG_TIMEOUT_MS = 5e3;
|
|
|
9097
9097
|
function awaitNavigateAck(client, path21, ackTimeoutMs, startCursor) {
|
|
9098
9098
|
const abortController = new AbortController();
|
|
9099
9099
|
let timer = null;
|
|
9100
|
-
const result = new Promise((
|
|
9100
|
+
const result = new Promise((resolve4) => {
|
|
9101
9101
|
timer = setTimeout(() => {
|
|
9102
|
-
|
|
9102
|
+
resolve4({ acked: false, reason: "timeout" });
|
|
9103
9103
|
abortController.abort();
|
|
9104
9104
|
}, ackTimeoutMs);
|
|
9105
9105
|
const pathOnly = path21.split("?")[0];
|
|
@@ -9119,7 +9119,7 @@ function awaitNavigateAck(client, path21, ackTimeoutMs, startCursor) {
|
|
|
9119
9119
|
if (timer) {
|
|
9120
9120
|
clearTimeout(timer);
|
|
9121
9121
|
}
|
|
9122
|
-
|
|
9122
|
+
resolve4({ acked: true });
|
|
9123
9123
|
abortController.abort();
|
|
9124
9124
|
return;
|
|
9125
9125
|
}
|
|
@@ -9127,7 +9127,7 @@ function awaitNavigateAck(client, path21, ackTimeoutMs, startCursor) {
|
|
|
9127
9127
|
if (timer) {
|
|
9128
9128
|
clearTimeout(timer);
|
|
9129
9129
|
}
|
|
9130
|
-
|
|
9130
|
+
resolve4({
|
|
9131
9131
|
acked: false,
|
|
9132
9132
|
reason: "blocked",
|
|
9133
9133
|
blockedReason: event.data.reason
|
|
@@ -9139,7 +9139,7 @@ function awaitNavigateAck(client, path21, ackTimeoutMs, startCursor) {
|
|
|
9139
9139
|
if (timer) {
|
|
9140
9140
|
clearTimeout(timer);
|
|
9141
9141
|
}
|
|
9142
|
-
|
|
9142
|
+
resolve4({ acked: false, reason: "window-closed" });
|
|
9143
9143
|
abortController.abort();
|
|
9144
9144
|
}
|
|
9145
9145
|
},
|
|
@@ -9152,18 +9152,18 @@ function awaitNavigateAck(client, path21, ackTimeoutMs, startCursor) {
|
|
|
9152
9152
|
if (timer) {
|
|
9153
9153
|
clearTimeout(timer);
|
|
9154
9154
|
}
|
|
9155
|
-
|
|
9155
|
+
resolve4({ acked: false, reason: "timeout" });
|
|
9156
9156
|
});
|
|
9157
9157
|
});
|
|
9158
9158
|
return result;
|
|
9159
9159
|
}
|
|
9160
9160
|
function awaitPong(client, pingTs) {
|
|
9161
|
-
return new Promise((
|
|
9161
|
+
return new Promise((resolve4) => {
|
|
9162
9162
|
const abortController = new AbortController();
|
|
9163
9163
|
let received = false;
|
|
9164
9164
|
const timer = setTimeout(() => {
|
|
9165
9165
|
abortController.abort();
|
|
9166
|
-
|
|
9166
|
+
resolve4(false);
|
|
9167
9167
|
}, PING_PONG_TIMEOUT_MS);
|
|
9168
9168
|
pollAgentSessionEvents({
|
|
9169
9169
|
serviceUrl: client.serviceUrl,
|
|
@@ -9175,7 +9175,7 @@ function awaitPong(client, pingTs) {
|
|
|
9175
9175
|
received = true;
|
|
9176
9176
|
clearTimeout(timer);
|
|
9177
9177
|
abortController.abort();
|
|
9178
|
-
|
|
9178
|
+
resolve4(true);
|
|
9179
9179
|
}
|
|
9180
9180
|
},
|
|
9181
9181
|
onError: () => {
|
|
@@ -9183,7 +9183,7 @@ function awaitPong(client, pingTs) {
|
|
|
9183
9183
|
}).catch(() => {
|
|
9184
9184
|
if (!received) {
|
|
9185
9185
|
clearTimeout(timer);
|
|
9186
|
-
|
|
9186
|
+
resolve4(false);
|
|
9187
9187
|
}
|
|
9188
9188
|
});
|
|
9189
9189
|
});
|
|
@@ -10413,10 +10413,10 @@ function readPid(pidPath) {
|
|
|
10413
10413
|
}
|
|
10414
10414
|
}
|
|
10415
10415
|
async function pingSocket(socketPath) {
|
|
10416
|
-
return new Promise((
|
|
10416
|
+
return new Promise((resolve4) => {
|
|
10417
10417
|
const timeout = setTimeout(() => {
|
|
10418
10418
|
socket.destroy();
|
|
10419
|
-
|
|
10419
|
+
resolve4({ alive: false, build: null });
|
|
10420
10420
|
}, PING_TIMEOUT_MS);
|
|
10421
10421
|
const socket = net.createConnection(socketPath, () => {
|
|
10422
10422
|
socket.write('{"cmd":"ping"}\n');
|
|
@@ -10429,15 +10429,15 @@ async function pingSocket(socketPath) {
|
|
|
10429
10429
|
socket.destroy();
|
|
10430
10430
|
try {
|
|
10431
10431
|
const msg = JSON.parse(buffer.split("\n")[0]);
|
|
10432
|
-
|
|
10432
|
+
resolve4({ alive: msg.ok === true, build: msg.build ?? null });
|
|
10433
10433
|
} catch {
|
|
10434
|
-
|
|
10434
|
+
resolve4({ alive: false, build: null });
|
|
10435
10435
|
}
|
|
10436
10436
|
}
|
|
10437
10437
|
});
|
|
10438
10438
|
socket.on("error", () => {
|
|
10439
10439
|
clearTimeout(timeout);
|
|
10440
|
-
|
|
10440
|
+
resolve4({ alive: false, build: null });
|
|
10441
10441
|
});
|
|
10442
10442
|
});
|
|
10443
10443
|
}
|
|
@@ -10668,10 +10668,10 @@ var DaemonClient = class {
|
|
|
10668
10668
|
}
|
|
10669
10669
|
async connect() {
|
|
10670
10670
|
await ensureDaemon(this.paths);
|
|
10671
|
-
return new Promise((
|
|
10671
|
+
return new Promise((resolve4, reject) => {
|
|
10672
10672
|
const socket = net2.createConnection(this.socketPath, () => {
|
|
10673
10673
|
this.socket = socket;
|
|
10674
|
-
|
|
10674
|
+
resolve4();
|
|
10675
10675
|
});
|
|
10676
10676
|
socket.on("data", (chunk2) => {
|
|
10677
10677
|
this.buffer += chunk2.toString();
|
|
@@ -10725,7 +10725,7 @@ var DaemonClient = class {
|
|
|
10725
10725
|
}
|
|
10726
10726
|
const timeoutMs = opts.timeoutMs ?? this.commandTimeoutMs;
|
|
10727
10727
|
const cmdName = cmd.cmd ?? "command";
|
|
10728
|
-
return new Promise((
|
|
10728
|
+
return new Promise((resolve4, reject) => {
|
|
10729
10729
|
let settled = false;
|
|
10730
10730
|
const timer = setTimeout(() => {
|
|
10731
10731
|
if (settled) {
|
|
@@ -10752,7 +10752,7 @@ var DaemonClient = class {
|
|
|
10752
10752
|
}
|
|
10753
10753
|
settled = true;
|
|
10754
10754
|
clearTimeout(timer);
|
|
10755
|
-
|
|
10755
|
+
resolve4(msg);
|
|
10756
10756
|
};
|
|
10757
10757
|
this.responseQueue.push(resolver);
|
|
10758
10758
|
try {
|
|
@@ -10926,9 +10926,9 @@ function readStudioEventLogTail(key, fromLine = 1) {
|
|
|
10926
10926
|
function tailStudioEvents(key, onLine, opts) {
|
|
10927
10927
|
const pollMs = opts.pollMs ?? 200;
|
|
10928
10928
|
let cursor = opts.fromLine ?? 1;
|
|
10929
|
-
return new Promise((
|
|
10929
|
+
return new Promise((resolve4) => {
|
|
10930
10930
|
if (opts.abortSignal.aborted) {
|
|
10931
|
-
|
|
10931
|
+
resolve4();
|
|
10932
10932
|
return;
|
|
10933
10933
|
}
|
|
10934
10934
|
const tick = () => {
|
|
@@ -10948,7 +10948,7 @@ function tailStudioEvents(key, onLine, opts) {
|
|
|
10948
10948
|
}, pollMs);
|
|
10949
10949
|
opts.abortSignal.addEventListener("abort", () => {
|
|
10950
10950
|
clearInterval(timer);
|
|
10951
|
-
|
|
10951
|
+
resolve4();
|
|
10952
10952
|
}, { once: true });
|
|
10953
10953
|
tick();
|
|
10954
10954
|
});
|
|
@@ -11134,8 +11134,8 @@ var DaemonChannel = class _DaemonChannel {
|
|
|
11134
11134
|
});
|
|
11135
11135
|
}
|
|
11136
11136
|
subscribe(_sessionId, onEvent, onError) {
|
|
11137
|
-
const done = new Promise((
|
|
11138
|
-
this.doneResolve =
|
|
11137
|
+
const done = new Promise((resolve4) => {
|
|
11138
|
+
this.doneResolve = resolve4;
|
|
11139
11139
|
});
|
|
11140
11140
|
this.client.onEvent((push) => {
|
|
11141
11141
|
const event = {
|
|
@@ -11718,7 +11718,7 @@ async function openStudioTo(path21, opts = {}) {
|
|
|
11718
11718
|
emit({ event: "navigated", sessionId: sessionId2, path: buildSignInPath(sessionId2) });
|
|
11719
11719
|
}
|
|
11720
11720
|
emit({ event: "auth-required", sessionId: sessionId2, signInUrl });
|
|
11721
|
-
const loginApiKey = await new Promise((
|
|
11721
|
+
const loginApiKey = await new Promise((resolve4, reject) => {
|
|
11722
11722
|
const timer = setTimeout(() => {
|
|
11723
11723
|
sub.abort();
|
|
11724
11724
|
reject(new Error("Login polling aborted"));
|
|
@@ -11732,7 +11732,7 @@ async function openStudioTo(path21, opts = {}) {
|
|
|
11732
11732
|
if (event.type === "studio:authenticated" && typeof event.data?.token === "string") {
|
|
11733
11733
|
cleanup();
|
|
11734
11734
|
sub.abort();
|
|
11735
|
-
|
|
11735
|
+
resolve4(event.data.token);
|
|
11736
11736
|
}
|
|
11737
11737
|
}, (err) => {
|
|
11738
11738
|
cleanup();
|
|
@@ -26433,11 +26433,21 @@ import net3 from "net";
|
|
|
26433
26433
|
|
|
26434
26434
|
// ../bitfab-plugin-lib/dist/commands/replayProgress.js
|
|
26435
26435
|
import { spawn as spawn4 } from "child_process";
|
|
26436
|
-
import {
|
|
26437
|
-
import {
|
|
26438
|
-
import { dirname, join as join2, resolve } from "path";
|
|
26436
|
+
import { createWriteStream, mkdirSync as mkdirSync4, rmSync as rmSync2 } from "fs";
|
|
26437
|
+
import { dirname as dirname3, resolve as resolve3 } from "path";
|
|
26439
26438
|
import { createInterface } from "readline";
|
|
26440
|
-
|
|
26439
|
+
|
|
26440
|
+
// ../bitfab-plugin-lib/dist/replayItemWriter.js
|
|
26441
|
+
import { mkdirSync as mkdirSync2, renameSync, writeFileSync as writeFileSync3 } from "fs";
|
|
26442
|
+
import { join as join2 } from "path";
|
|
26443
|
+
|
|
26444
|
+
// ../bitfab-plugin-lib/dist/bestEffortFs.js
|
|
26445
|
+
import { mkdirSync, writeFileSync as writeFileSync2 } from "fs";
|
|
26446
|
+
import { dirname } from "path";
|
|
26447
|
+
|
|
26448
|
+
// ../bitfab-plugin-lib/dist/replayResultResolver.js
|
|
26449
|
+
import { readFileSync as readFileSync2, rmSync } from "fs";
|
|
26450
|
+
import { resolve } from "path";
|
|
26441
26451
|
var replayResultSchema = external_exports.object({
|
|
26442
26452
|
items: external_exports.array(external_exports.unknown()),
|
|
26443
26453
|
testRunId: external_exports.string().optional(),
|
|
@@ -26446,6 +26456,14 @@ var replayResultSchema = external_exports.object({
|
|
|
26446
26456
|
test_run_url: external_exports.string().optional()
|
|
26447
26457
|
}).passthrough().refine(({ testRunId, test_run_id }) => testRunId !== void 0 || test_run_id !== void 0);
|
|
26448
26458
|
|
|
26459
|
+
// ../bitfab-plugin-lib/dist/replayRunDir.js
|
|
26460
|
+
import { randomUUID } from "crypto";
|
|
26461
|
+
import { appendFileSync, existsSync, mkdirSync as mkdirSync3, readFileSync as readFileSync3, statSync } from "fs";
|
|
26462
|
+
import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
|
|
26463
|
+
|
|
26464
|
+
// ../bitfab-plugin-lib/dist/commands/replayProgress.js
|
|
26465
|
+
var HEARTBEAT_MS = Number(process.env.BITFAB_REPLAY_HEARTBEAT_MS) || 12e3;
|
|
26466
|
+
|
|
26449
26467
|
// ../bitfab-plugin-lib/dist/activePreviewSession.js
|
|
26450
26468
|
import fs15 from "fs";
|
|
26451
26469
|
import os12 from "os";
|
|
@@ -27988,8 +28006,8 @@ var dateOnlyStringSchema = external_exports.string().regex(DATE_PATTERN, "Must b
|
|
|
27988
28006
|
const date5 = parseDateOnly(value);
|
|
27989
28007
|
return date5.getFullYear() === year && date5.getMonth() === month - 1 && date5.getDate() === day;
|
|
27990
28008
|
}, "Must be a valid calendar date");
|
|
27991
|
-
var
|
|
27992
|
-
var
|
|
28009
|
+
var GET_TRACE_LABELS_MAX_IDS = 100;
|
|
28010
|
+
var GET_GRADER_LABELS_MAX_IDS = 100;
|
|
27993
28011
|
var DEFAULT_GRADER_LABEL_LIMIT = 50;
|
|
27994
28012
|
var MAX_GRADER_LABEL_LIMIT = 200;
|
|
27995
28013
|
function parseJsonString(val) {
|
|
@@ -28099,7 +28117,7 @@ var listTraceFunctions = {
|
|
|
28099
28117
|
var searchTraces = {
|
|
28100
28118
|
name: "search_traces",
|
|
28101
28119
|
title: "Search Traces",
|
|
28102
|
-
description: "Search and filter traces for a traced function. Returns matching traces with IDs, status, timestamps, total duration (ms), total token usage (in/out/cached/total), model, and output preview (all when available). Replay traces (from test runs) carry the same totals. Use
|
|
28120
|
+
description: "Search and filter traces for a traced function. Returns matching traces with IDs, status, timestamps, total duration (ms), total token usage (in/out/cached/total), model, and output preview (all when available). Replay traces (from test runs) carry the same totals. Use get_traces for per-span duration, tokens, time-to-first-token, and model. Supports keyword search, date range, status filter, and regex matching. Use drillDown to refine previous results.",
|
|
28103
28121
|
inputSchema: {
|
|
28104
28122
|
traceFunctionKey: external_exports.string().describe("The trace function key to search"),
|
|
28105
28123
|
searchQuery: external_exports.string().optional().describe("Full-text keyword search"),
|
|
@@ -28120,38 +28138,38 @@ var searchTraces = {
|
|
|
28120
28138
|
hasDbSnapshot: external_exports.preprocess(parseJsonString, external_exports.boolean()).optional().describe("Filter by whether the trace captured a database snapshot reference. true returns only traces that can be replayed against a pinned historical DB branch (the 'Snapshot captured' traces); false returns only traces with no snapshot. Omit to include both.")
|
|
28121
28139
|
}
|
|
28122
28140
|
};
|
|
28123
|
-
var
|
|
28124
|
-
name: "
|
|
28125
|
-
title: "
|
|
28126
|
-
description: 'Read one or more traces by ID. Includes inputs, outputs, status, environment tag, trace-level duration (ms), token usage (in/out/cached/total), and model (when available). Use these to compare latency and cost between a trace and its replay. Returns span details (input, output, reasoning, content, context, errors) plus per-span duration, tokens, time-to-first-token, and model when available. Use `scope: "summary"` when scanning many traces to keep the response small; `scope: "full"` when you need the complete untruncated detail of a few traces. To load only labels + annotations for many traces at once (no span content), use
|
|
28141
|
+
var getTraces = {
|
|
28142
|
+
name: "get_traces",
|
|
28143
|
+
title: "Get Traces",
|
|
28144
|
+
description: 'Read one or more traces by ID. Includes inputs, outputs, status, environment tag, trace-level duration (ms), token usage (in/out/cached/total), and model (when available). Use these to compare latency and cost between a trace and its replay. Returns span details (input, output, reasoning, content, context, errors) plus per-span duration, tokens, time-to-first-token, and model when available. Use `scope: "summary"` when scanning many traces to keep the response small; `scope: "full"` when you need the complete untruncated detail of a few traces. To load only labels + annotations for many traces at once (no span content), use get_trace_labels instead.',
|
|
28127
28145
|
inputSchema: {
|
|
28128
28146
|
traceIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(10)).describe("Trace IDs to read (1-10)"),
|
|
28129
28147
|
scope: external_exports.enum(["summary", "full"]).optional().default("summary").describe('Level of span detail. "summary" (default) renders the same span structure as full but caps each span (its fields share a ~1500-char budget) and each trace-level field (~2000 chars), keeping the response small enough not to spill to disk: prefer it when scanning or identifying candidate traces. "full" renders every field untruncated up to 10k chars each, with no per-span ceiling, so reading several large traces can produce a big response: use it when you need complete detail on a handful of traces.')
|
|
28130
28148
|
}
|
|
28131
28149
|
};
|
|
28132
|
-
var
|
|
28133
|
-
name: "
|
|
28134
|
-
title: "
|
|
28135
|
-
description: `Read just the labels for one or more traces by ID: returns each trace's pass/fail verdict, its annotation (the reviewer's reasoning), and whether the label is human-validated (a human authored or approved it). No span content, inputs, or outputs are loaded, so the response is small and one call accepts up to ${
|
|
28150
|
+
var getTraceLabels = {
|
|
28151
|
+
name: "get_trace_labels",
|
|
28152
|
+
title: "Get Trace Labels",
|
|
28153
|
+
description: `Read just the labels for one or more traces by ID: returns each trace's pass/fail verdict, its annotation (the reviewer's reasoning), and whether the label is human-validated (a human authored or approved it). No span content, inputs, or outputs are loaded, so the response is small and one call accepts up to ${GET_TRACE_LABELS_MAX_IDS} IDs. Use this to load a whole dataset's verdicts into context in a single call (e.g. when building or confirming a dataset). When you need a trace's actual inputs/outputs/spans, use get_traces instead.`,
|
|
28136
28154
|
inputSchema: {
|
|
28137
|
-
traceIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(
|
|
28155
|
+
traceIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(GET_TRACE_LABELS_MAX_IDS)).describe(`Trace IDs to read labels for (1-${GET_TRACE_LABELS_MAX_IDS})`)
|
|
28138
28156
|
}
|
|
28139
28157
|
};
|
|
28140
|
-
var
|
|
28141
|
-
name: "
|
|
28142
|
-
title: "
|
|
28143
|
-
description: "Fetch the COMPLETE, untruncated value of a single span field.
|
|
28158
|
+
var getSpanField = {
|
|
28159
|
+
name: "get_span_field",
|
|
28160
|
+
title: "Get Span Field",
|
|
28161
|
+
description: "Fetch the COMPLETE, untruncated value of a single span field. get_traces truncates large span fields and prints a note telling you to call this when you need the full text. Pass the traceId, the spanId (the `[ID: ...]` shown for that span in get_traces output), and the field to retrieve. Returns up to 100k chars by default; pass a higher maxChars to read more of an extremely large field. Prefer this over re-reading the whole trace when you only need one large field in full.",
|
|
28144
28162
|
inputSchema: {
|
|
28145
28163
|
traceId: external_exports.uuid().describe("The trace ID the span belongs to"),
|
|
28146
|
-
spanId: external_exports.uuid().describe("The span ID to read, taken from the `[ID: ...]` shown for the span in
|
|
28164
|
+
spanId: external_exports.uuid().describe("The span ID to read, taken from the `[ID: ...]` shown for the span in get_traces output"),
|
|
28147
28165
|
field: external_exports.enum(["input", "output", "reasoning", "content", "errors", "contexts"]).describe("Which span field to return in full: input, output, reasoning, content, errors, or contexts"),
|
|
28148
28166
|
maxChars: external_exports.preprocess(parseJsonString, external_exports.number().int().positive()).optional().describe("Maximum characters to return (default 100000). Raise it to read further into an extremely large field.")
|
|
28149
28167
|
}
|
|
28150
28168
|
};
|
|
28151
|
-
var
|
|
28152
|
-
name: "
|
|
28153
|
-
title: "
|
|
28154
|
-
description: "Set, skip, or archive the agent's pass/fail verdict on one or more traces (`labelSource=\"agent\"`). Use this AFTER you have read the traces with
|
|
28169
|
+
var saveAgentLabels = {
|
|
28170
|
+
name: "save_agent_labels",
|
|
28171
|
+
title: "Save Agent Labels",
|
|
28172
|
+
description: "Set, skip, or archive the agent's pass/fail verdict on one or more traces (`labelSource=\"agent\"`). Use this AFTER you have read the traces with get_traces and decided yourself whether each one looks like a pass, a fail, or genuinely cannot be judged. To set a verdict, pass `label` (true=PASS, false=FAIL) and `annotation` (your reasoning, shown to the human reviewer in the labeling UI). Optionally pass `confidence` (`VeryLow|Low|Medium|High|VeryHigh`) to record how confident you are - surfaced in the labeling UI so reviewers can prioritize low-confidence verdicts. To explicitly skip a trace you cannot decide on (instead of leaving it unlabeled), pass `skip: true` and omit label/annotation - this records an explicit skip so coverage checks know you intentionally did not verdict it. To clear a previously-set agent verdict (e.g., you changed your mind or labeled the wrong trace), pass `archive: true` and omit label/annotation. New verdicts start unapproved (`approvedAt=null`); once a human approves one, it joins the validated dataset (queryable via `search_traces` with `validated: true`). Archiving is non-destructive - the row is hidden from all reads but kept for audit, and you can immediately re-label the trace from scratch. For replay results, key each label by the replay item's `originalTraceId` (the original trace it was replayed from; `sourceTraceId` is accepted as a deprecated alias) plus the top-level `testRunId` instead of a `traceId`: the server resolves it to the replay trace via lineage, so you never need a server-generated replay trace id. Returns an agent-readable summary with one parseable effective label line per updated trace, keyed by the id you supplied (`originalTraceId` for replay verdicts, otherwise `traceId`), so command callers can verify persistence.",
|
|
28155
28173
|
inputSchema: {
|
|
28156
28174
|
testRunId: external_exports.uuid().optional().describe("The replay test run id. Required when any label targets a trace by originalTraceId (replay verdicts); ignored otherwise."),
|
|
28157
28175
|
labels: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.object({
|
|
@@ -28166,10 +28184,10 @@ var updateAgentLabels = {
|
|
|
28166
28184
|
})).min(1).max(50)).describe("One update per trace (1-50)")
|
|
28167
28185
|
}
|
|
28168
28186
|
};
|
|
28169
|
-
var
|
|
28170
|
-
name: "
|
|
28171
|
-
title: "
|
|
28172
|
-
description: 'Record one or more human-authored pass/fail verdicts that are VALIDATED immediately (`labelSource="human"`, no approval step). Unlike
|
|
28187
|
+
var saveHumanLabels = {
|
|
28188
|
+
name: "save_human_labels",
|
|
28189
|
+
title: "Save Human Labels",
|
|
28190
|
+
description: 'Record one or more human-authored pass/fail verdicts that are VALIDATED immediately (`labelSource="human"`, no approval step). Unlike save_agent_labels (which writes agent suggestions that start unapproved), labels set here join the validated dataset the instant they are written and satisfy `search_traces` with `validated: true`. Pass `label` (true=PASS, false=FAIL), `annotation` (the reasoning behind the verdict), and optionally `confidence` (`VeryLow|Low|Medium|High|VeryHigh`). USE ONLY when a human has explicitly decided the verdict, for example saving a known production bug as a test case. Do NOT use this for the agent\'s own first-pass guesses on traces awaiting human review; use save_agent_labels for those so they go through the normal approve/edit loop.',
|
|
28173
28191
|
inputSchema: {
|
|
28174
28192
|
labels: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.object({
|
|
28175
28193
|
traceId: external_exports.uuid().describe("The trace ID to label"),
|
|
@@ -28210,10 +28228,10 @@ var listGraders = {
|
|
|
28210
28228
|
cursor: external_exports.string().min(1).optional().describe("Opaque cursor from the previous page; reuse the same filters")
|
|
28211
28229
|
}
|
|
28212
28230
|
};
|
|
28213
|
-
var
|
|
28214
|
-
name: "
|
|
28215
|
-
title: "
|
|
28216
|
-
description: "Create a labeled dataset for a traced function. Datasets are named buckets of traces (e.g. 'Hallucination failures', 'Edge cases for grader X') that humans review and that experiments replay against. Pass traceFunctionKey, a short human-readable name, and an optional description.
|
|
28231
|
+
var saveDataset = {
|
|
28232
|
+
name: "save_dataset",
|
|
28233
|
+
title: "Save Dataset",
|
|
28234
|
+
description: "Create or edit a labeled dataset for a traced function. Datasets are named buckets of traces (e.g. 'Hallucination failures', 'Edge cases for grader X') that humans review and that experiments replay against. Pass traceFunctionKey, a short human-readable name, and an optional description. Saving with the name of an existing dataset on the same trace function updates that dataset instead of creating a duplicate, so re-running a flow is safe; pass a new description to change it, or omit it to leave the current one. Returns the dataset id; use it with add_traces_to_dataset to populate. Call list_datasets first when you need to see what already exists.",
|
|
28217
28235
|
inputSchema: {
|
|
28218
28236
|
traceFunctionKey: external_exports.string().min(1).describe("The trace function key the dataset is scoped to (must match traces you'll add)"),
|
|
28219
28237
|
name: external_exports.string().min(1).describe("Short human-readable name shown in the labeling UI (e.g. 'Hallucination failures')"),
|
|
@@ -28223,7 +28241,7 @@ var createDataset = {
|
|
|
28223
28241
|
var listDatasets = {
|
|
28224
28242
|
name: "list_datasets",
|
|
28225
28243
|
title: "List Datasets",
|
|
28226
|
-
description: "List all datasets for a traced function, with id, name, description, current trace count, and assigned graders for each. Call this before changing trace or grader assignments to discover dataset ids and current membership, or before
|
|
28244
|
+
description: "List all datasets for a traced function, with id, name, description, current trace count, and assigned graders for each. Call this before changing trace or grader assignments to discover dataset ids and current membership, or before save_dataset to avoid duplicates.",
|
|
28227
28245
|
inputSchema: {
|
|
28228
28246
|
traceFunctionKey: external_exports.string().min(1).describe("The trace function key to list datasets for")
|
|
28229
28247
|
}
|
|
@@ -28233,7 +28251,7 @@ var addTracesToDataset = {
|
|
|
28233
28251
|
title: "Add Traces to Dataset",
|
|
28234
28252
|
description: "Add one or more traces to a dataset. Idempotent: re-adding a trace already in the dataset is a no-op. Traces are validated against the dataset's traceFunctionKey; ids that don't belong to this organization, or to the dataset's trace function, are silently skipped (the response reports how many were added vs skipped).",
|
|
28235
28253
|
inputSchema: {
|
|
28236
|
-
datasetId: external_exports.uuid().describe("The dataset id (from
|
|
28254
|
+
datasetId: external_exports.uuid().describe("The dataset id (from save_dataset or list_datasets)"),
|
|
28237
28255
|
traceIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(100)).describe("Trace ids to add (1-100)")
|
|
28238
28256
|
}
|
|
28239
28257
|
};
|
|
@@ -28251,7 +28269,7 @@ var addGradersToDataset = {
|
|
|
28251
28269
|
title: "Add Graders to Dataset",
|
|
28252
28270
|
description: "Assign one or more graders to a dataset. Idempotent: assigning a grader that is already attached is a no-op. Graders must belong to this organization and match the dataset's traceFunctionKey; invalid ids are skipped and reported.",
|
|
28253
28271
|
inputSchema: {
|
|
28254
|
-
datasetId: external_exports.uuid().describe("The dataset id (from
|
|
28272
|
+
datasetId: external_exports.uuid().describe("The dataset id (from save_dataset or list_datasets)"),
|
|
28255
28273
|
graderIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(100)).describe("Grader ids to assign (1-100)")
|
|
28256
28274
|
}
|
|
28257
28275
|
};
|
|
@@ -28282,13 +28300,22 @@ var removeGradersFromExperiment = {
|
|
|
28282
28300
|
graderIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(100)).describe("Grader ids to detach (1-100)")
|
|
28283
28301
|
}
|
|
28284
28302
|
};
|
|
28285
|
-
var
|
|
28286
|
-
name: "
|
|
28287
|
-
title: "Add
|
|
28288
|
-
description: "Assign one
|
|
28303
|
+
var addGradersToExperimentGroup = {
|
|
28304
|
+
name: "add_graders_to_experiment_group",
|
|
28305
|
+
title: "Add Graders to Experiment Group",
|
|
28306
|
+
description: "Assign one or more graders to every experiment (test run) currently in an experiment group. Grader assignments are stored on each experiment, not on the group, so experiments added later do not inherit them automatically. Completed experiments immediately queue any missing grader evaluations; pending experiments use the graders when they complete. Idempotent: assigning a grader already attached to an experiment is a no-op.",
|
|
28307
|
+
inputSchema: {
|
|
28308
|
+
experimentGroupId: external_exports.uuid().describe("The experiment group id"),
|
|
28309
|
+
graderIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(100)).describe("Grader ids to assign (1-100)")
|
|
28310
|
+
}
|
|
28311
|
+
};
|
|
28312
|
+
var removeGradersFromExperimentGroup = {
|
|
28313
|
+
name: "remove_graders_from_experiment_group",
|
|
28314
|
+
title: "Remove Graders from Experiment Group",
|
|
28315
|
+
description: "Detach one or more graders from every experiment (test run) currently in an experiment group, undoing add_graders_to_experiment_group. Grader ids not assigned to any experiment in the group are ignored and reported. The graders themselves are not deleted, and archived graders can still be detached. Because assignments live on each experiment rather than on the group, this only affects experiments currently in the group. Effect depends on run state, matching remove_graders_from_experiment: an in-progress experiment re-adds a detached grader from its dataset when it completes if the dataset still assigns it, while an already-completed experiment has a finalized grader set, so detaching permanently drops that grader from its results.",
|
|
28289
28316
|
inputSchema: {
|
|
28290
28317
|
experimentGroupId: external_exports.uuid().describe("The experiment group id"),
|
|
28291
|
-
|
|
28318
|
+
graderIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(100)).describe("Grader ids to detach (1-100)")
|
|
28292
28319
|
}
|
|
28293
28320
|
};
|
|
28294
28321
|
var listExperiments = {
|
|
@@ -28300,9 +28327,9 @@ var listExperiments = {
|
|
|
28300
28327
|
limit: external_exports.preprocess(parseJsonString, external_exports.number().int().min(1).max(50)).optional().describe("Max experiments to return (default 20, max 50)")
|
|
28301
28328
|
}
|
|
28302
28329
|
};
|
|
28303
|
-
var
|
|
28304
|
-
name: "
|
|
28305
|
-
title: "
|
|
28330
|
+
var listExperimentTraces = {
|
|
28331
|
+
name: "list_experiment_traces",
|
|
28332
|
+
title: "List Experiment Traces",
|
|
28306
28333
|
description: "Get individual trace results for an experiment (test run), including each replay trace's verdict (fixed, regressed, still-passing, still-failing, unpaired) by comparing against the original trace's label, plus token usage (input, output, cached, total) for the replay and the paired original so you can reason about cost and cache-read deltas. Use after list_experiments to drill into a specific experiment's results.",
|
|
28307
28334
|
inputSchema: {
|
|
28308
28335
|
testRunId: external_exports.uuid().describe("The experiment (test run) ID to get traces for")
|
|
@@ -28319,21 +28346,21 @@ var getReplayStatus = {
|
|
|
28319
28346
|
var getTemplateReference = {
|
|
28320
28347
|
name: "get_template_reference",
|
|
28321
28348
|
title: "Get Template Reference",
|
|
28322
|
-
description: "Read the agent-facing reference for Bitfab span templates: the engine (Nunjucks), the render-context schema (variables bound at render time), the composition model (no `{% extends %}` - assembler injects into base.njk), the registered custom filters and tests, common patterns from the live default templates, and error behavior. **Call this once per session before your first `get_template` or `
|
|
28349
|
+
description: "Read the agent-facing reference for Bitfab span templates: the engine (Nunjucks), the render-context schema (variables bound at render time), the composition model (no `{% extends %}` - assembler injects into base.njk), the registered custom filters and tests, common patterns from the live default templates, and error behavior. **Call this once per session before your first `get_template` or `save_template`** - without it, edits typically use the wrong syntax dialect, the wrong variable names, or break the layout. Read-only, no organization data, safe to cache.",
|
|
28323
28350
|
inputSchema: {}
|
|
28324
28351
|
};
|
|
28325
28352
|
var getTemplate = {
|
|
28326
28353
|
name: "get_template",
|
|
28327
28354
|
title: "Get Template",
|
|
28328
|
-
description: "Read the rendering template for a span type. Templates control how a span's input/output renders in the Bitfab UI. **Pass `traceFunctionKey` to scope to a specific trace function** (this is the normal mode for the `templates` skill). Resolution: per-key row \u2192 org-global override \u2192 file default. The response labels the source so you know whether you're editing a per-key row, seeding from the org-global, or starting from the file default. Without `traceFunctionKey`, returns the org-global override. Span types: llm, agent, function, guardrail, handoff, custom. Always call this before
|
|
28355
|
+
description: "Read the rendering template for a span type. Templates control how a span's input/output renders in the Bitfab UI. **Pass `traceFunctionKey` to scope to a specific trace function** (this is the normal mode for the `templates` skill). Resolution: per-key row \u2192 org-global override \u2192 file default. The response labels the source so you know whether you're editing a per-key row, seeding from the org-global, or starting from the file default. Without `traceFunctionKey`, returns the org-global override. Span types: llm, agent, function, guardrail, handoff, custom. Always call this before save_template so your edit starts from the live content. **If you haven't called `get_template_reference` this session, call it first** - it documents the Nunjucks engine, available variables, and base-template composition model, which you'll need to write a correct edit.",
|
|
28329
28356
|
inputSchema: {
|
|
28330
28357
|
spanType: external_exports.enum(["llm", "agent", "function", "guardrail", "handoff", "custom"]).describe("Span type whose template to read (llm | agent | function | guardrail | handoff | custom)"),
|
|
28331
28358
|
traceFunctionKey: external_exports.string().min(1).optional().describe("Trace function key to scope the template to. When set, returns the per-key row if present; otherwise seeds from the org-global override; otherwise the file default. Omit to read the org-global template.")
|
|
28332
28359
|
}
|
|
28333
28360
|
};
|
|
28334
|
-
var
|
|
28335
|
-
name: "
|
|
28336
|
-
title: "
|
|
28361
|
+
var saveTemplate = {
|
|
28362
|
+
name: "save_template",
|
|
28363
|
+
title: "Save Template",
|
|
28337
28364
|
description: "Upsert the rendering template for a span type. **Pass `traceFunctionKey` to scope the override to a single trace function** (this is the normal mode for the `templates` skill); the per-key row is created on first save and applied at render time only for spans on traces of that function. Without `traceFunctionKey`, edits the org-global override (applies when no per-key row matches). Updates are in-place: no version bump, no row juggling. The `template` body is the full template source you want stored, passed verbatim - do NOT wrap in `<![CDATA[ ... ]]>`, triple-backtick code fences, or any other escape construct; the value is stored exactly as received and a stray wrapper will silently break rendering (e.g. an opening `<![CDATA[` swallows the next `<style>` tag). Optional `name` and `description` are metadata shown in the templates UI. Span types: llm, agent, function, guardrail, handoff, custom. Always call get_template first so you're editing the current content rather than overwriting unrelated changes. **If you haven't called `get_template_reference` this session, call it first** - edits that don't match the documented Nunjucks variable shape will silently render empty in production.",
|
|
28338
28365
|
inputSchema: {
|
|
28339
28366
|
spanType: external_exports.enum(["llm", "agent", "function", "guardrail", "handoff", "custom"]).describe("Span type whose template to upsert (llm | agent | function | guardrail | handoff | custom)"),
|
|
@@ -28397,18 +28424,18 @@ var getExperiment = {
|
|
|
28397
28424
|
testRunId: external_exports.uuid().describe("The experiment (test run) id, from list_experiments")
|
|
28398
28425
|
}
|
|
28399
28426
|
};
|
|
28400
|
-
var
|
|
28401
|
-
name: "
|
|
28402
|
-
title: "
|
|
28403
|
-
description: `Read the INDIVIDUAL verdicts each automated grader (LLM-as-judge) recorded, one row per grader per trace, with the grader's reason, its failure diagnostic, the confidence, and whether the verdict came from a human or from a grader run. This is the per-grader breakdown that
|
|
28427
|
+
var getGraderLabels = {
|
|
28428
|
+
name: "get_grader_labels",
|
|
28429
|
+
title: "Get Grader Labels",
|
|
28430
|
+
description: `Read the INDIVIDUAL verdicts each automated grader (LLM-as-judge) recorded, one row per grader per trace, with the grader's reason, its failure diagnostic, the confidence, and whether the verdict came from a human or from a grader run. This is the per-grader breakdown that get_trace_labels does not show: that tool returns one grader-agnostic verdict per trace, so use it for a dataset's overall pass/fail and use this one to see WHICH check failed and why. Pass traceIds to see every grader's verdict on those traces, graderId to see that grader's most recent verdicts across traces (newest first, use it to diagnose a grader that is misfiring), or both to narrow to one grader on specific traces. Call list_graders first if you need grader ids.`,
|
|
28404
28431
|
inputSchema: {
|
|
28405
|
-
traceIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(
|
|
28432
|
+
traceIds: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.uuid()).min(1).max(GET_GRADER_LABELS_MAX_IDS)).optional().describe(`Trace IDs to read grader verdicts for (1-${GET_GRADER_LABELS_MAX_IDS}). Omit to read by grader instead.`),
|
|
28406
28433
|
graderId: external_exports.uuid().optional().describe("Restrict to one grader (from list_graders). On its own, returns that grader's most recent verdicts across all traces."),
|
|
28407
28434
|
limit: external_exports.preprocess(parseJsonString, external_exports.number().int().min(1).max(MAX_GRADER_LABEL_LIMIT)).optional().describe(`Max labels to return when reading by grader alone (default ${DEFAULT_GRADER_LABEL_LIMIT}, max ${MAX_GRADER_LABEL_LIMIT}). Ignored when traceIds is given.`)
|
|
28408
28435
|
}
|
|
28409
28436
|
};
|
|
28410
28437
|
var ALL_TOOL_CONTRACTS = [
|
|
28411
|
-
|
|
28438
|
+
getGraderLabels,
|
|
28412
28439
|
getExperiment,
|
|
28413
28440
|
saveExperimentGroup,
|
|
28414
28441
|
getBitfabApiKey,
|
|
@@ -28417,14 +28444,14 @@ var ALL_TOOL_CONTRACTS = [
|
|
|
28417
28444
|
getDatabaseConnectionStatus,
|
|
28418
28445
|
listTraceFunctions,
|
|
28419
28446
|
searchTraces,
|
|
28420
|
-
|
|
28421
|
-
|
|
28422
|
-
|
|
28423
|
-
|
|
28424
|
-
|
|
28447
|
+
getTraces,
|
|
28448
|
+
getTraceLabels,
|
|
28449
|
+
getSpanField,
|
|
28450
|
+
saveAgentLabels,
|
|
28451
|
+
saveHumanLabels,
|
|
28425
28452
|
saveGrader,
|
|
28426
28453
|
listGraders,
|
|
28427
|
-
|
|
28454
|
+
saveDataset,
|
|
28428
28455
|
listDatasets,
|
|
28429
28456
|
addTracesToDataset,
|
|
28430
28457
|
removeTracesFromDataset,
|
|
@@ -28432,13 +28459,14 @@ var ALL_TOOL_CONTRACTS = [
|
|
|
28432
28459
|
removeGradersFromDataset,
|
|
28433
28460
|
addGradersToExperiment,
|
|
28434
28461
|
removeGradersFromExperiment,
|
|
28435
|
-
|
|
28462
|
+
addGradersToExperimentGroup,
|
|
28463
|
+
removeGradersFromExperimentGroup,
|
|
28436
28464
|
listExperiments,
|
|
28437
|
-
|
|
28465
|
+
listExperimentTraces,
|
|
28438
28466
|
getReplayStatus,
|
|
28439
28467
|
getTemplateReference,
|
|
28440
28468
|
getTemplate,
|
|
28441
|
-
|
|
28469
|
+
saveTemplate,
|
|
28442
28470
|
createTracePlan,
|
|
28443
28471
|
confirmTracePlan,
|
|
28444
28472
|
getTracePlan
|
|
@@ -28784,7 +28812,7 @@ async function runClaudeAnalyzeRepo(captureOverride, limit, prompt) {
|
|
|
28784
28812
|
}
|
|
28785
28813
|
};
|
|
28786
28814
|
try {
|
|
28787
|
-
const exitCode = await new Promise((
|
|
28815
|
+
const exitCode = await new Promise((resolve4, reject) => {
|
|
28788
28816
|
const child = spawn5(
|
|
28789
28817
|
CLI,
|
|
28790
28818
|
[
|
|
@@ -28823,7 +28851,7 @@ async function runClaudeAnalyzeRepo(captureOverride, limit, prompt) {
|
|
|
28823
28851
|
);
|
|
28824
28852
|
return;
|
|
28825
28853
|
}
|
|
28826
|
-
|
|
28854
|
+
resolve4(code);
|
|
28827
28855
|
});
|
|
28828
28856
|
});
|
|
28829
28857
|
flushRedactors();
|
|
@@ -29663,7 +29691,7 @@ async function runCodexAnalyzeRepo(captureOverride, limit, prompt) {
|
|
|
29663
29691
|
}
|
|
29664
29692
|
};
|
|
29665
29693
|
try {
|
|
29666
|
-
const exitCode = await new Promise((
|
|
29694
|
+
const exitCode = await new Promise((resolve4, reject) => {
|
|
29667
29695
|
const child = spawn6(
|
|
29668
29696
|
CLI2,
|
|
29669
29697
|
[
|
|
@@ -29705,7 +29733,7 @@ async function runCodexAnalyzeRepo(captureOverride, limit, prompt) {
|
|
|
29705
29733
|
);
|
|
29706
29734
|
return;
|
|
29707
29735
|
}
|
|
29708
|
-
|
|
29736
|
+
resolve4(code);
|
|
29709
29737
|
});
|
|
29710
29738
|
});
|
|
29711
29739
|
flushRedactors();
|
|
@@ -30040,7 +30068,7 @@ async function runCursorAnalyzeRepo(captureOverride, limit, prompt) {
|
|
|
30040
30068
|
}
|
|
30041
30069
|
};
|
|
30042
30070
|
try {
|
|
30043
|
-
const exitCode = await new Promise((
|
|
30071
|
+
const exitCode = await new Promise((resolve4, reject) => {
|
|
30044
30072
|
const child = spawn7(
|
|
30045
30073
|
"cursor",
|
|
30046
30074
|
[
|
|
@@ -30085,7 +30113,7 @@ async function runCursorAnalyzeRepo(captureOverride, limit, prompt) {
|
|
|
30085
30113
|
);
|
|
30086
30114
|
return;
|
|
30087
30115
|
}
|
|
30088
|
-
|
|
30116
|
+
resolve4(code);
|
|
30089
30117
|
});
|
|
30090
30118
|
});
|
|
30091
30119
|
flushRedactors();
|