@agentsky/sky 2.19.0 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-MOYCAI4S.js → chunk-BHW2NAXP.js} +1 -1
- package/dist/{chunk-UJ3D24IG.js → chunk-DC3R6BV2.js} +3059 -2759
- package/dist/{chunk-4MVWXHZY.js → chunk-ICSGMEG5.js} +2 -2
- package/dist/index.js +216 -27
- package/dist/products.js +1 -1
- package/dist/{src-5HKXRXLU.js → src-3HXHE2S6.js} +1 -1
- package/dist/{trace-VZX6UIOF.js → trace-DI2SQI7M.js} +2 -2
- package/dist/{trace-library-EBH2GYDA.js → trace-library-4WWKCSVU.js} +3 -3
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
apiBase,
|
|
4
4
|
apiToken,
|
|
5
5
|
currentUniverse
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BHW2NAXP.js";
|
|
7
7
|
|
|
8
8
|
// src/api.ts
|
|
9
9
|
import { createWriteStream, writeFileSync } from "fs";
|
|
@@ -144,7 +144,7 @@ async function resolveSessionRef(ref) {
|
|
|
144
144
|
return agent.defaultSessionId;
|
|
145
145
|
}
|
|
146
146
|
async function* streamEvents(sessionId, signal) {
|
|
147
|
-
const { parseSseStream } = await import("./src-
|
|
147
|
+
const { parseSseStream } = await import("./src-3HXHE2S6.js");
|
|
148
148
|
const res = await fetch(
|
|
149
149
|
`${apiBase()}/sessions/${encodeURIComponent(sessionId)}/stream`,
|
|
150
150
|
{
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
resolveSessionRef,
|
|
10
10
|
streamEvents,
|
|
11
11
|
uploadFile
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ICSGMEG5.js";
|
|
13
13
|
import {
|
|
14
14
|
CLI_VERSION,
|
|
15
15
|
USER_AGENT,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
currentUniverse,
|
|
21
21
|
loadConfig,
|
|
22
22
|
saveConfig
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-BHW2NAXP.js";
|
|
24
24
|
import {
|
|
25
25
|
AGENT_TYPES,
|
|
26
26
|
MODEL_SUBSCRIPTION_PLAN_PHRASE,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
skillRefSchema,
|
|
43
43
|
splitMcpServers,
|
|
44
44
|
supersededBy
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-DC3R6BV2.js";
|
|
46
46
|
import "./chunk-MLKGABMK.js";
|
|
47
47
|
|
|
48
48
|
// src/index.ts
|
|
@@ -4130,7 +4130,7 @@ function textOf2(event) {
|
|
|
4130
4130
|
return "";
|
|
4131
4131
|
}
|
|
4132
4132
|
function firstAsk(record) {
|
|
4133
|
-
const root = record.threads.find((
|
|
4133
|
+
const root = record.threads.find((thread2) => thread2.relation === "primary") ?? record.threads[0];
|
|
4134
4134
|
if (!root) return null;
|
|
4135
4135
|
for (const event of record.events[root.id] ?? []) {
|
|
4136
4136
|
if (event.type === "user.message") {
|
|
@@ -4142,9 +4142,9 @@ function firstAsk(record) {
|
|
|
4142
4142
|
}
|
|
4143
4143
|
function decisionsOf(record) {
|
|
4144
4144
|
const out = [];
|
|
4145
|
-
for (const
|
|
4146
|
-
for (const event of record.events[
|
|
4147
|
-
if (event.type === "human.decision" || event.type === "outcome.observed") out.push({ ...event, thread_id:
|
|
4145
|
+
for (const thread2 of record.threads) {
|
|
4146
|
+
for (const event of record.events[thread2.id] ?? []) {
|
|
4147
|
+
if (event.type === "human.decision" || event.type === "outcome.observed") out.push({ ...event, thread_id: thread2.id });
|
|
4148
4148
|
}
|
|
4149
4149
|
}
|
|
4150
4150
|
return out.sort((a, b) => (a.at ?? "").localeCompare(b.at ?? ""));
|
|
@@ -4158,7 +4158,7 @@ function adoptedSession(record) {
|
|
|
4158
4158
|
return null;
|
|
4159
4159
|
}
|
|
4160
4160
|
function stepsOf(record, names2) {
|
|
4161
|
-
const root = record.threads.find((
|
|
4161
|
+
const root = record.threads.find((thread2) => thread2.relation === "primary") ?? record.threads[0];
|
|
4162
4162
|
if (!root) return [];
|
|
4163
4163
|
const events = record.events[root.id] ?? [];
|
|
4164
4164
|
const steps = [];
|
|
@@ -4277,8 +4277,8 @@ function buildHarborTask(record, opts) {
|
|
|
4277
4277
|
const out = /* @__PURE__ */ new Map();
|
|
4278
4278
|
const ask2 = record.goal?.objective ?? firstAsk(record) ?? record.title ?? "Complete the task described by the workspace.";
|
|
4279
4279
|
const instruction = scrub(ask2, names2);
|
|
4280
|
-
const root = record.threads.find((
|
|
4281
|
-
const harnesses = [...new Set(record.threads.map((
|
|
4280
|
+
const root = record.threads.find((thread2) => thread2.relation === "primary") ?? record.threads[0];
|
|
4281
|
+
const harnesses = [...new Set(record.threads.map((thread2) => thread2.agent.harness))];
|
|
4282
4282
|
const decisions = decisionsOf(record);
|
|
4283
4283
|
const adopted = adoptedSession(record);
|
|
4284
4284
|
const steps = stepsOf(record, names2);
|
|
@@ -4370,7 +4370,7 @@ async function fetchTaskRecord(taskRef) {
|
|
|
4370
4370
|
const { task: task2 } = await api("GET", `/tasks/${encodeURIComponent(taskRef)}`);
|
|
4371
4371
|
const { threads } = await api("GET", `/sessions/${encodeURIComponent(task2.id)}/threads`);
|
|
4372
4372
|
const events = {};
|
|
4373
|
-
for (const
|
|
4373
|
+
for (const thread2 of threads) events[thread2.id] = await pagedEvents(thread2.id);
|
|
4374
4374
|
let goal2 = null;
|
|
4375
4375
|
try {
|
|
4376
4376
|
goal2 = (await api("GET", `/sessions/${encodeURIComponent(task2.id)}/goal`)).goal;
|
|
@@ -4383,7 +4383,7 @@ async function fetchTaskRecord(taskRef) {
|
|
|
4383
4383
|
} catch (error) {
|
|
4384
4384
|
if (!(error instanceof ApiError && (error.status === 404 || error.status === 503))) throw error;
|
|
4385
4385
|
}
|
|
4386
|
-
const root = threads.find((
|
|
4386
|
+
const root = threads.find((thread2) => thread2.relation === "primary") ?? threads[0];
|
|
4387
4387
|
return { task_id: task2.id, exported_at: (/* @__PURE__ */ new Date()).toISOString(), title: task2.title ?? null, threads, events, goal: goal2, files: files2, completion_answer: task2.completion_answer ?? null, environment: root?.environment ?? null };
|
|
4388
4388
|
}
|
|
4389
4389
|
var FILE_BYTES_MAX = 50 * 1024 * 1024;
|
|
@@ -4421,10 +4421,10 @@ var DECISION_KINDS = ["adopt", "rerun", "revise", "discard", "vote", "did_the_jo
|
|
|
4421
4421
|
async function listThreads(taskRef) {
|
|
4422
4422
|
return (await api("GET", `/sessions/${encodeURIComponent(taskRef)}/threads`)).threads;
|
|
4423
4423
|
}
|
|
4424
|
-
function renderThread(
|
|
4425
|
-
const spend = (Number(
|
|
4426
|
-
const env =
|
|
4427
|
-
return `${
|
|
4424
|
+
function renderThread(thread2) {
|
|
4425
|
+
const spend = (Number(thread2.usage.spent_usd_micros) / 1e6).toFixed(4);
|
|
4426
|
+
const env = thread2.environment?.repo ? ` ${thread2.environment.repo}${thread2.environment.commit ? `@${thread2.environment.commit.slice(0, 7)}` : ""}` : "";
|
|
4427
|
+
return `${thread2.id} ${thread2.relation.padEnd(7)} ${thread2.source.padEnd(12)} ${thread2.agent.harness}/${thread2.agent.model} ${thread2.status} $${spend}${env}`;
|
|
4428
4428
|
}
|
|
4429
4429
|
async function recordDecision(sessionRef, kind, opts = {}) {
|
|
4430
4430
|
if (!DECISION_KINDS.includes(kind)) throw new Error(`kind must be one of ${DECISION_KINDS.join(", ")}`);
|
|
@@ -4704,6 +4704,38 @@ function renderBrowserProfile(profile) {
|
|
|
4704
4704
|
return lines.join("\n");
|
|
4705
4705
|
}
|
|
4706
4706
|
|
|
4707
|
+
// src/compare.ts
|
|
4708
|
+
async function listComparisons(opts = {}) {
|
|
4709
|
+
const qs = opts.archived ? "?archived=true" : "";
|
|
4710
|
+
const { comparisons } = await api("GET", `/comparisons${qs}`);
|
|
4711
|
+
return comparisons;
|
|
4712
|
+
}
|
|
4713
|
+
async function createComparison(body) {
|
|
4714
|
+
return api("POST", "/comparisons", body);
|
|
4715
|
+
}
|
|
4716
|
+
async function getComparison(id) {
|
|
4717
|
+
return api("GET", `/comparisons/${encodeURIComponent(id)}`);
|
|
4718
|
+
}
|
|
4719
|
+
async function pickWinner(id, opts) {
|
|
4720
|
+
return api("POST", `/comparisons/${encodeURIComponent(id)}/pick`, opts);
|
|
4721
|
+
}
|
|
4722
|
+
async function listThreads2(opts = {}) {
|
|
4723
|
+
const qs = opts.filter ? `?filter=${opts.filter}` : "";
|
|
4724
|
+
const { threads } = await api("GET", `/threads${qs}`);
|
|
4725
|
+
return threads;
|
|
4726
|
+
}
|
|
4727
|
+
function renderComparisonSummary(c) {
|
|
4728
|
+
const agents = c.agents.map((a) => `${a.agentType}/${a.llm}`).join(" vs ");
|
|
4729
|
+
const status = c.statusLine ?? c.attention ?? (c.archived ? "archived" : "active");
|
|
4730
|
+
return `${c.id.slice(0, 12)} ${c.title.slice(0, 40).padEnd(42)} [${agents}] ${status}`;
|
|
4731
|
+
}
|
|
4732
|
+
function renderThreadSummary(t) {
|
|
4733
|
+
const agents = t.agents.map((a) => `${a.agentType}/${a.llm}`).join(", ");
|
|
4734
|
+
const flag = t.pinned ? "\u{1F4CC} " : "";
|
|
4735
|
+
const status = t.working ? "working" : t.attention ?? (t.archived ? "archived" : "idle");
|
|
4736
|
+
return `${t.id.slice(0, 12)} ${flag}${t.title.slice(0, 40).padEnd(44)} [${agents}] ${status}`;
|
|
4737
|
+
}
|
|
4738
|
+
|
|
4707
4739
|
// src/harness.ts
|
|
4708
4740
|
import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
|
|
4709
4741
|
import { dirname as dirname8, join as join16, resolve as resolve8 } from "path";
|
|
@@ -6029,7 +6061,7 @@ task.command("threads <task>").description("the task's threads from the session
|
|
|
6029
6061
|
console.log(JSON.stringify({ threads }));
|
|
6030
6062
|
return;
|
|
6031
6063
|
}
|
|
6032
|
-
for (const
|
|
6064
|
+
for (const thread2 of threads) console.log(renderThread(thread2));
|
|
6033
6065
|
})
|
|
6034
6066
|
);
|
|
6035
6067
|
task.command("decide <session> <kind>").description("record what you did with a session's result: adopt | rerun | revise | discard | vote | did_the_job | approve").option("--target <session>", "the session the decision names (a vote's winner, the option you adopted)").option("--yes", "the value for did_the_job and approve").option("--no", "the value for did_the_job and approve").option("--reason <text>", "your own words, kept with the decision").option("--key <key>", "an idempotency key, so a repeat records nothing new").action(
|
|
@@ -6733,7 +6765,7 @@ vendor.command("usage <id>").description("the agents and tasks that used this ve
|
|
|
6733
6765
|
})
|
|
6734
6766
|
);
|
|
6735
6767
|
var browserProfile = program.command("browser-profile").description("saved-login profiles: the sites your agents stay signed in to");
|
|
6736
|
-
browserProfile.command("list").description("your workspace's browser profiles
|
|
6768
|
+
browserProfile.command("list").description("your workspace's browser profiles: the sites your agents stay signed in to").option("--json", "print as JSON").action(
|
|
6737
6769
|
run(async (opts) => {
|
|
6738
6770
|
const profiles = await listBrowserProfiles();
|
|
6739
6771
|
if (opts.json) {
|
|
@@ -6956,7 +6988,7 @@ harness.command("connect").description("run an ACP agent (the command after --)
|
|
|
6956
6988
|
}));
|
|
6957
6989
|
var traceCmd = program.command("trace").description("correlate this machine's agent work with the cloud sessions it starts (metadata only unless you choose content)");
|
|
6958
6990
|
traceCmd.command("start").description("start a trace: a grant for this machine, a root span, and the spool the hooks write to").option("--name <name>", "a name for the task").option("--source <source>", "how this machine reports itself", "claude-code").option("--hooks [settings]", "also install the Claude Code hooks (default: ./.claude/settings.local.json)").option("--capture <scopes>", "also send content, redacted on this machine first: any of prompts,tool_output,files").option("--file <path>", "a file the files scope may send (repeatable)", collect).option("--dir <path>", "a folder whose files the files scope may send when a file tool touches them (repeatable)", collect).action(run(async (opts) => {
|
|
6959
|
-
const { readState, writeState, record, installClaudeHooks, parseContentScopes, chosenPaths, fileEvent } = await import("./trace-
|
|
6991
|
+
const { readState, writeState, record, installClaudeHooks, parseContentScopes, chosenPaths, fileEvent } = await import("./trace-DI2SQI7M.js");
|
|
6960
6992
|
if (readState()) throw new Error("a trace is already running here \u2014 `sky trace stop` it first");
|
|
6961
6993
|
const scopes = parseContentScopes(opts.capture);
|
|
6962
6994
|
const chosen = chosenPaths(opts.file ?? [], opts.dir ?? []);
|
|
@@ -6991,7 +7023,7 @@ traceCmd.command("start").description("start a trace: a grant for this machine,
|
|
|
6991
7023
|
}));
|
|
6992
7024
|
traceCmd.command("hook").description("record one Claude Code hook event read from stdin (run by the installed hooks; never fails, prints nothing)").action(async () => {
|
|
6993
7025
|
try {
|
|
6994
|
-
const { readState, record, flush, grantSender, eventsForClaudeHook, contentForClaudeHook, clearState } = await import("./trace-
|
|
7026
|
+
const { readState, record, flush, grantSender, eventsForClaudeHook, contentForClaudeHook, clearState } = await import("./trace-DI2SQI7M.js");
|
|
6995
7027
|
const chunks = [];
|
|
6996
7028
|
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
6997
7029
|
const input = JSON.parse(Buffer.concat(chunks).toString("utf8") || "{}");
|
|
@@ -7004,14 +7036,14 @@ traceCmd.command("hook").description("record one Claude Code hook event read fro
|
|
|
7004
7036
|
}
|
|
7005
7037
|
});
|
|
7006
7038
|
traceCmd.command("flush").description("send what the spool holds, retrying with backoff").action(run(async () => {
|
|
7007
|
-
const { readState, flush, grantSender } = await import("./trace-
|
|
7039
|
+
const { readState, flush, grantSender } = await import("./trace-DI2SQI7M.js");
|
|
7008
7040
|
const state = readState();
|
|
7009
7041
|
if (!state) throw new Error("no trace is running here");
|
|
7010
7042
|
const outcome = await flush(grantSender(state), { attempts: 4 });
|
|
7011
7043
|
console.log(`sent ${outcome.sent}, refused ${outcome.refused}, given up ${outcome.expired}, still pending ${outcome.pending}${outcome.stopped ? ` (stopped: ${outcome.stopped})` : ""}`);
|
|
7012
7044
|
}));
|
|
7013
7045
|
traceCmd.command("status").description("the running trace and its spool").action(run(async () => {
|
|
7014
|
-
const { readState, spoolStatus } = await import("./trace-
|
|
7046
|
+
const { readState, spoolStatus } = await import("./trace-DI2SQI7M.js");
|
|
7015
7047
|
const state = readState();
|
|
7016
7048
|
if (!state) {
|
|
7017
7049
|
console.log("No trace is running here.");
|
|
@@ -7021,7 +7053,7 @@ traceCmd.command("status").description("the running trace and its spool").action
|
|
|
7021
7053
|
console.log(`${state.trace_id} as ${state.source}: ${spool.pending} pending, ${spool.dropped_full} dropped (spool full), ${spool.dropped_expired} given up, ${spool.refused} refused`);
|
|
7022
7054
|
}));
|
|
7023
7055
|
traceCmd.command("show [id]").description("the trace bundle: spans, the sessions they reach, cost counted once per session").option("--json", "print the bundle as JSON").action(run(async (id, opts) => {
|
|
7024
|
-
const { readState } = await import("./trace-
|
|
7056
|
+
const { readState } = await import("./trace-DI2SQI7M.js");
|
|
7025
7057
|
const ref = id ?? readState()?.trace_id;
|
|
7026
7058
|
if (!ref) throw new Error("name a trace, or start one here");
|
|
7027
7059
|
const bundle = await api("GET", `/traces/${ref}`);
|
|
@@ -7048,7 +7080,7 @@ traceCmd.command("show [id]").description("the trace bundle: spans, the sessions
|
|
|
7048
7080
|
for (const gap of bundle.gaps) console.log(` gap: ${gap.span_id} ${gap.reason}`);
|
|
7049
7081
|
}));
|
|
7050
7082
|
traceCmd.command("stop").description("end the root span, send what is left, and revoke this machine's grant").action(run(async () => {
|
|
7051
|
-
const { readState, record, flush, grantSender, clearState } = await import("./trace-
|
|
7083
|
+
const { readState, record, flush, grantSender, clearState } = await import("./trace-DI2SQI7M.js");
|
|
7052
7084
|
const state = readState();
|
|
7053
7085
|
if (!state) throw new Error("no trace is running here");
|
|
7054
7086
|
if (state.root_span) record(() => [{ span_id: state.root_span, kind: "end", outcome: "completed" }]);
|
|
@@ -7058,7 +7090,7 @@ traceCmd.command("stop").description("end the root span, send what is left, and
|
|
|
7058
7090
|
console.log(`Stopped ${state.trace_id}${outcome.pending ? ` (${outcome.pending} events could not be sent)` : ""}`);
|
|
7059
7091
|
}));
|
|
7060
7092
|
traceCmd.command("sync [payload]").description("upload this machine's Claude Code and Codex sessions to the matching workspace's trace library, redacted here first").option("--enable", "turn sync on for this machine").option("--disable", "turn sync off; nothing more is uploaded").option("--route <match=workspace>", "send sessions whose folder path contains <match> to <workspace> (repeatable; replaces the saved rules)", collect).option("--default <workspace>", "where a session no rule matches goes").option("--keep-local", "keep sessions no rule matches on this machine (the default)").option("--session <ref>", "only this session: its id or transcript path (repeatable)", collect).option("--full", "re-read every session, not only files that changed").option("--limit <n>", "at most this many changed sessions this run", (v) => Number.parseInt(v, 10)).option("--dry-run", "show what would be uploaded without uploading").option("--hook", "run from a Claude Code SessionEnd hook or Codex notify: upload that session in the background and return at once").option("--install-schedule", "also sweep every 15 minutes (macOS launchd)").option("--status", "what sync has done on this machine").option("--quiet", "print only failures").action(async (payload, opts) => {
|
|
7061
|
-
const lib = await import("./trace-library-
|
|
7093
|
+
const lib = await import("./trace-library-4WWKCSVU.js");
|
|
7062
7094
|
if (opts.hook) {
|
|
7063
7095
|
try {
|
|
7064
7096
|
let raw = payload ?? "";
|
|
@@ -7156,7 +7188,7 @@ traceCmd.command("sync [payload]").description("upload this machine's Claude Cod
|
|
|
7156
7188
|
})();
|
|
7157
7189
|
});
|
|
7158
7190
|
traceCmd.command("search <query...>").description("search every session in a workspace's trace library (literal substring)").option("--workspace <slug>", "the workspace to search (default: the current one)").option("--limit <n>", "hits per page", (v) => Number.parseInt(v, 10), 20).option("--cursor <cursor>", "the next page of an earlier search").option("--json", "print the page as JSON").action(run(async (words, opts) => {
|
|
7159
|
-
const { libraryRequest } = await import("./trace-library-
|
|
7191
|
+
const { libraryRequest } = await import("./trace-library-4WWKCSVU.js");
|
|
7160
7192
|
const workspace2 = opts.workspace ?? currentUniverse();
|
|
7161
7193
|
if (!workspace2) throw new Error("name a workspace with --workspace");
|
|
7162
7194
|
const params = new URLSearchParams({ q: words.join(" "), scope: "traces", limit: String(opts.limit), ...opts.cursor ? { cursor: opts.cursor } : {} });
|
|
@@ -7173,7 +7205,7 @@ traceCmd.command("search <query...>").description("search every session in a wor
|
|
|
7173
7205
|
if (page.nextCursor) console.log(`More: sky trace search ${JSON.stringify(words.join(" "))} --workspace ${workspace2} --cursor ${page.nextCursor}`);
|
|
7174
7206
|
}));
|
|
7175
7207
|
traceCmd.command("library").description("list the sessions in a workspace's trace library, most recently updated first").option("--workspace <slug>", "the workspace (default: the current one)").option("--limit <n>", "how many", (v) => Number.parseInt(v, 10), 20).option("--json", "print the page as JSON").action(run(async (opts) => {
|
|
7176
|
-
const { libraryRequest } = await import("./trace-library-
|
|
7208
|
+
const { libraryRequest } = await import("./trace-library-4WWKCSVU.js");
|
|
7177
7209
|
const workspace2 = opts.workspace ?? currentUniverse();
|
|
7178
7210
|
if (!workspace2) throw new Error("name a workspace with --workspace");
|
|
7179
7211
|
const page = await libraryRequest("GET", `/trace-library?limit=${opts.limit}`, workspace2);
|
|
@@ -7203,5 +7235,162 @@ workerCmd.command("start <pool>").description("start a worker connected to the g
|
|
|
7203
7235
|
process.on("SIGTERM", () => ac.abort());
|
|
7204
7236
|
await startWorker({ poolId, token, label: options.label, apiBase: base, signal: ac.signal });
|
|
7205
7237
|
});
|
|
7238
|
+
var compare = program.command("compare").description("side-by-side agent comparisons: create, list, read, pick a winner");
|
|
7239
|
+
compare.command("create").description("run one task on two or more agents simultaneously and start a comparison").requiredOption("--task <text>", "the task to send to every agent").requiredOption("--agent <type>", "the main agent's harness type (e.g. claude_code, hermes)").requiredOption("--llm <model>", "the main agent's model").option("--vs <type:model...>", "one or more competing agents in type:model form (e.g. codex:gpt-6)", (val, acc) => [...acc, val], []).option("--effort <level>", "reasoning effort for every agent (low|medium|high)").option("--json", "print the created comparison as JSON").action(
|
|
7240
|
+
run(async (opts) => {
|
|
7241
|
+
const competitors = (opts.vs ?? []).map((v) => {
|
|
7242
|
+
const [agentType, llm] = v.split(":");
|
|
7243
|
+
if (!agentType || !llm) throw new ApiError(400, "invalid_request", `--vs must be type:model, got "${v}"`);
|
|
7244
|
+
return { agentType, llm, ...opts.effort ? { reasoningEffort: opts.effort } : {} };
|
|
7245
|
+
});
|
|
7246
|
+
if (!competitors.length) throw new ApiError(400, "invalid_request", "Provide at least one --vs type:model competitor.");
|
|
7247
|
+
const requestId = `sky-compare-${Date.now()}`;
|
|
7248
|
+
const result = await createComparison({
|
|
7249
|
+
requestId,
|
|
7250
|
+
agentType: opts.agent,
|
|
7251
|
+
llm: opts.llm,
|
|
7252
|
+
task: opts.task,
|
|
7253
|
+
compare: competitors,
|
|
7254
|
+
...opts.effort ? { reasoningEffort: opts.effort } : {}
|
|
7255
|
+
});
|
|
7256
|
+
if (opts.json) {
|
|
7257
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7258
|
+
return;
|
|
7259
|
+
}
|
|
7260
|
+
console.log(`created ${result.comparisonId}`);
|
|
7261
|
+
for (const col of result.columns) console.log(` column ${col.columnId} session ${col.sessionId}`);
|
|
7262
|
+
})
|
|
7263
|
+
);
|
|
7264
|
+
compare.command("list").description("your workspace comparisons, most recently updated first").option("--archived", "list archived comparisons instead").option("--json", "print as JSON").action(
|
|
7265
|
+
run(async (opts) => {
|
|
7266
|
+
const comparisons = await listComparisons({ archived: opts.archived });
|
|
7267
|
+
if (opts.json) {
|
|
7268
|
+
console.log(JSON.stringify(comparisons, null, 2));
|
|
7269
|
+
return;
|
|
7270
|
+
}
|
|
7271
|
+
if (!comparisons.length) console.log("no comparisons");
|
|
7272
|
+
for (const c of comparisons) console.log(renderComparisonSummary(c));
|
|
7273
|
+
})
|
|
7274
|
+
);
|
|
7275
|
+
compare.command("show <id>").description("one comparison: task, agents, status, and the vote verdict").option("--json", "print as JSON").action(
|
|
7276
|
+
run(async (id, opts) => {
|
|
7277
|
+
const detail = await getComparison(id);
|
|
7278
|
+
if (opts.json) {
|
|
7279
|
+
console.log(JSON.stringify(detail, null, 2));
|
|
7280
|
+
return;
|
|
7281
|
+
}
|
|
7282
|
+
console.log(`comparison ${detail.id}`);
|
|
7283
|
+
if (detail.title) console.log(` title: ${detail.title}`);
|
|
7284
|
+
if (detail.openerText) console.log(` task: ${detail.openerText}`);
|
|
7285
|
+
console.log(` created ${detail.createdAt}`);
|
|
7286
|
+
for (const col of detail.columns) {
|
|
7287
|
+
const masked = !col.agentType;
|
|
7288
|
+
const identity = masked ? "(hidden \u2014 Arena match pending)" : `${col.agentType ?? "?"}/${col.llm ?? "?"}`;
|
|
7289
|
+
console.log(` column ${col.columnId} session ${col.sessionId ?? "-"} ${identity} ${col.podStatus ?? ""}`);
|
|
7290
|
+
}
|
|
7291
|
+
if (detail.arena) console.log(` arena kind=${detail.arena.kind} status=${detail.arena.status} hidden=${detail.arena.hidden}`);
|
|
7292
|
+
if (detail.vote) console.log(` vote outcome=${detail.vote.outcome} winner=${detail.vote.winnerSessionId ?? "none"} sealed=${detail.vote.sealed}`);
|
|
7293
|
+
})
|
|
7294
|
+
);
|
|
7295
|
+
compare.command("pick <id>").description('record the winning column \u2014 or a tie or "both_bad" \u2014 for this comparison').option("--winner <columnId>", "the columnId of the winning column").option("--tie", "record a tie instead of a winner").option("--both-bad", "record that neither agent did the job").option("--json", "print the verdict as JSON").action(
|
|
7296
|
+
run(async (id, opts) => {
|
|
7297
|
+
const choices = [opts.winner, opts.tie, opts.bothBad].filter(Boolean).length;
|
|
7298
|
+
if (choices !== 1) throw new ApiError(400, "invalid_request", "Provide exactly one of --winner, --tie or --both-bad.");
|
|
7299
|
+
const outcome = opts.tie ? "tie" : opts.bothBad ? "both_bad" : void 0;
|
|
7300
|
+
const result = await pickWinner(id, { winnerColumnId: opts.winner, outcome });
|
|
7301
|
+
if (opts.json) {
|
|
7302
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7303
|
+
return;
|
|
7304
|
+
}
|
|
7305
|
+
if (result.winnerSessionId) console.log(`winner: session ${result.winnerSessionId}`);
|
|
7306
|
+
else console.log("recorded: " + (outcome ?? "pick"));
|
|
7307
|
+
if (result.revealed) console.log("identities revealed:");
|
|
7308
|
+
for (const s of result.seats) console.log(` ${s.sessionId} ${s.agentType}/${s.llm}`);
|
|
7309
|
+
})
|
|
7310
|
+
);
|
|
7311
|
+
var thread = program.command("thread").description("workspace threads: the conversation history across all agents");
|
|
7312
|
+
thread.command("list").description("your workspace threads, most recently updated first (includes comparisons)").option("--archived", "list archived threads only").option("--all", "include both active and archived").option("--json", "print as JSON").action(
|
|
7313
|
+
run(async (opts) => {
|
|
7314
|
+
const filter = opts.all ? "all" : opts.archived ? "archived" : "active";
|
|
7315
|
+
const threads = await listThreads2({ filter });
|
|
7316
|
+
if (opts.json) {
|
|
7317
|
+
console.log(JSON.stringify(threads, null, 2));
|
|
7318
|
+
return;
|
|
7319
|
+
}
|
|
7320
|
+
if (!threads.length) console.log("no threads");
|
|
7321
|
+
for (const t of threads) console.log(renderThreadSummary(t));
|
|
7322
|
+
})
|
|
7323
|
+
);
|
|
7324
|
+
session.command("feedback <id>").description("read the thumbs-up/down feedback on this session's messages").option("--json", "print as JSON").action(
|
|
7325
|
+
run(async (id, opts) => {
|
|
7326
|
+
const result = await api(
|
|
7327
|
+
"GET",
|
|
7328
|
+
`/sessions/${encodeURIComponent(id)}/feedback`
|
|
7329
|
+
);
|
|
7330
|
+
if (opts.json) {
|
|
7331
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7332
|
+
return;
|
|
7333
|
+
}
|
|
7334
|
+
const entries = Object.entries(result.reports);
|
|
7335
|
+
if (!entries.length) {
|
|
7336
|
+
console.log("no feedback recorded");
|
|
7337
|
+
return;
|
|
7338
|
+
}
|
|
7339
|
+
for (const [msgId, r] of entries) console.log(`${msgId.slice(0, 12)} ${r.vote} ${(r.reasons ?? []).join(", ")}`);
|
|
7340
|
+
})
|
|
7341
|
+
);
|
|
7342
|
+
session.command("side-chat <id>").description("ask a question about this session's transcript (answered beside it, never sent to the agent)").requiredOption("--question <text>", "the question to ask").requiredOption("--transcript <text>", "the session transcript or relevant excerpt").option("--quote <text>", "a specific passage the question targets").option("--json", "print as JSON").action(
|
|
7343
|
+
run(async (id, opts) => {
|
|
7344
|
+
const result = await api("POST", `/sessions/${encodeURIComponent(id)}/side-chat`, {
|
|
7345
|
+
transcript: opts.transcript,
|
|
7346
|
+
history: [],
|
|
7347
|
+
question: opts.question,
|
|
7348
|
+
...opts.quote ? { quote: opts.quote } : {}
|
|
7349
|
+
});
|
|
7350
|
+
if (opts.json) {
|
|
7351
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7352
|
+
return;
|
|
7353
|
+
}
|
|
7354
|
+
console.log(result.answer);
|
|
7355
|
+
if (result.looked?.length) console.log(`
|
|
7356
|
+
(sources: ${result.looked.join(", ")})`);
|
|
7357
|
+
})
|
|
7358
|
+
);
|
|
7359
|
+
session.command("code-review <id>").description("run the code-review assistant on this session's diff or file").requiredOption("--diff <text>", "the diff or file content to review").option("--filename <name>", "the filename for language-aware review").option("--json", "print as JSON").action(
|
|
7360
|
+
run(async (id, opts) => {
|
|
7361
|
+
const result = await api(
|
|
7362
|
+
"POST",
|
|
7363
|
+
`/sessions/${encodeURIComponent(id)}/code-review`,
|
|
7364
|
+
{ diff: opts.diff, ...opts.filename ? { filename: opts.filename } : {} }
|
|
7365
|
+
);
|
|
7366
|
+
if (opts.json) {
|
|
7367
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7368
|
+
return;
|
|
7369
|
+
}
|
|
7370
|
+
console.log(result.review);
|
|
7371
|
+
if (result.issues?.length) {
|
|
7372
|
+
console.log("\nIssues:");
|
|
7373
|
+
for (const issue of result.issues) {
|
|
7374
|
+
const loc = issue.line ? ` line ${issue.line}` : "";
|
|
7375
|
+
console.log(` [${issue.severity}]${loc} ${issue.message}`);
|
|
7376
|
+
}
|
|
7377
|
+
}
|
|
7378
|
+
})
|
|
7379
|
+
);
|
|
7380
|
+
session.command("snapshot <id>").description("read or revoke the public share link for a session").requiredOption("--thread <threadId>", "the thread/comparison that owns this session").option("--revoke", "revoke the snapshot link instead of reading it").option("--json", "print as JSON").action(
|
|
7381
|
+
run(async (id, opts) => {
|
|
7382
|
+
const path = `/sessions/${encodeURIComponent(id)}/snapshot?thread=${encodeURIComponent(opts.thread)}`;
|
|
7383
|
+
const result = await api(opts.revoke ? "DELETE" : "GET", path);
|
|
7384
|
+
if (opts.json) {
|
|
7385
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7386
|
+
return;
|
|
7387
|
+
}
|
|
7388
|
+
if (opts.revoke) {
|
|
7389
|
+
console.log(result.url === null ? "snapshot link revoked" : `still set: ${result.url}`);
|
|
7390
|
+
return;
|
|
7391
|
+
}
|
|
7392
|
+
console.log(result.url ?? "no snapshot link set");
|
|
7393
|
+
})
|
|
7394
|
+
);
|
|
7206
7395
|
var ARGUMENTS_FOLLOW_THE_SCRIPT_PATH_ON_EVERY_RUNTIME = { from: "node" };
|
|
7207
7396
|
program.parseAsync(process.argv, ARGUMENTS_FOLLOW_THE_SCRIPT_PATH_ON_EVERY_RUNTIME).catch(fail);
|
package/dist/products.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
USER_AGENT,
|
|
3
3
|
configPath
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BHW2NAXP.js";
|
|
5
5
|
import {
|
|
6
6
|
TRACE_CONTENT_SCOPES,
|
|
7
7
|
redactTraceText
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DC3R6BV2.js";
|
|
9
9
|
import "./chunk-MLKGABMK.js";
|
|
10
10
|
|
|
11
11
|
// src/trace.ts
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ApiError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ICSGMEG5.js";
|
|
4
4
|
import {
|
|
5
5
|
USER_AGENT,
|
|
6
6
|
apiBase,
|
|
7
7
|
apiToken
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BHW2NAXP.js";
|
|
9
9
|
import {
|
|
10
10
|
SessionSourceCollector,
|
|
11
11
|
publicRemote,
|
|
12
12
|
redactTraceText
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DC3R6BV2.js";
|
|
14
14
|
import "./chunk-MLKGABMK.js";
|
|
15
15
|
|
|
16
16
|
// src/trace-library.ts
|