claudish 9.1.0 → 9.2.1
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 +79 -52
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -715,7 +715,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
715
715
|
});
|
|
716
716
|
|
|
717
717
|
// src/version.ts
|
|
718
|
-
var VERSION = "9.1
|
|
718
|
+
var VERSION = "9.2.1";
|
|
719
719
|
|
|
720
720
|
// src/logger.ts
|
|
721
721
|
import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -33599,6 +33599,26 @@ data: ${JSON.stringify(data)}
|
|
|
33599
33599
|
}
|
|
33600
33600
|
openToolBlocks.clear();
|
|
33601
33601
|
};
|
|
33602
|
+
const endTurnWithText = (text) => {
|
|
33603
|
+
const idx = curIdx++;
|
|
33604
|
+
send("content_block_start", {
|
|
33605
|
+
type: "content_block_start",
|
|
33606
|
+
index: idx,
|
|
33607
|
+
content_block: { type: "text", text: "" }
|
|
33608
|
+
});
|
|
33609
|
+
send("content_block_delta", {
|
|
33610
|
+
type: "content_block_delta",
|
|
33611
|
+
index: idx,
|
|
33612
|
+
delta: { type: "text_delta", text }
|
|
33613
|
+
});
|
|
33614
|
+
send("content_block_stop", { type: "content_block_stop", index: idx });
|
|
33615
|
+
send("message_delta", {
|
|
33616
|
+
type: "message_delta",
|
|
33617
|
+
delta: { stop_reason: "end_turn", stop_sequence: null },
|
|
33618
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens }
|
|
33619
|
+
});
|
|
33620
|
+
send("message_stop", { type: "message_stop" });
|
|
33621
|
+
};
|
|
33602
33622
|
send("message_start", {
|
|
33603
33623
|
type: "message_start",
|
|
33604
33624
|
message: {
|
|
@@ -33809,24 +33829,7 @@ data: ${JSON.stringify(data)}
|
|
|
33809
33829
|
|
|
33810
33830
|
[Context limit reached] This model's backend enforces a smaller context window${cap} than its API spec. ` + "Run /clear to start fresh (/compact will also fail \u2014 it re-sends the full conversation), " + `or route the model via \`oai@${opts.modelName}\` to use the full-size window.`;
|
|
33811
33831
|
}
|
|
33812
|
-
|
|
33813
|
-
send("content_block_start", {
|
|
33814
|
-
type: "content_block_start",
|
|
33815
|
-
index: errorIdx,
|
|
33816
|
-
content_block: { type: "text", text: "" }
|
|
33817
|
-
});
|
|
33818
|
-
send("content_block_delta", {
|
|
33819
|
-
type: "content_block_delta",
|
|
33820
|
-
index: errorIdx,
|
|
33821
|
-
delta: { type: "text_delta", text: errorText }
|
|
33822
|
-
});
|
|
33823
|
-
send("content_block_stop", { type: "content_block_stop", index: errorIdx });
|
|
33824
|
-
send("message_delta", {
|
|
33825
|
-
type: "message_delta",
|
|
33826
|
-
delta: { stop_reason: "end_turn", stop_sequence: null },
|
|
33827
|
-
usage: { input_tokens: inputTokens, output_tokens: outputTokens }
|
|
33828
|
-
});
|
|
33829
|
-
send("message_stop", { type: "message_stop" });
|
|
33832
|
+
endTurnWithText(errorText);
|
|
33830
33833
|
isClosed = true;
|
|
33831
33834
|
if (pingInterval) {
|
|
33832
33835
|
clearInterval(pingInterval);
|
|
@@ -33877,27 +33880,19 @@ data: ${JSON.stringify(data)}
|
|
|
33877
33880
|
try {
|
|
33878
33881
|
closeReasoning();
|
|
33879
33882
|
closeText();
|
|
33883
|
+
const toolCallCutOff = openToolBlocks.size > 0;
|
|
33880
33884
|
closeTools();
|
|
33881
|
-
|
|
33882
|
-
|
|
33883
|
-
|
|
33884
|
-
|
|
33885
|
-
|
|
33886
|
-
|
|
33887
|
-
|
|
33888
|
-
|
|
33889
|
-
index: errorIdx,
|
|
33890
|
-
delta: { type: "text_delta", text: `
|
|
33885
|
+
if (toolCallCutOff) {
|
|
33886
|
+
log("[ResponsesSSE] tool arguments cut off mid-stream \u2192 error event");
|
|
33887
|
+
send("error", {
|
|
33888
|
+
type: "error",
|
|
33889
|
+
error: { type: "api_error", message: `Stream error: ${error}` }
|
|
33890
|
+
});
|
|
33891
|
+
} else {
|
|
33892
|
+
endTurnWithText(`
|
|
33891
33893
|
|
|
33892
|
-
[Stream error: ${error}]`
|
|
33893
|
-
}
|
|
33894
|
-
send("content_block_stop", { type: "content_block_stop", index: errorIdx });
|
|
33895
|
-
send("message_delta", {
|
|
33896
|
-
type: "message_delta",
|
|
33897
|
-
delta: { stop_reason: "end_turn", stop_sequence: null },
|
|
33898
|
-
usage: { input_tokens: inputTokens, output_tokens: outputTokens }
|
|
33899
|
-
});
|
|
33900
|
-
send("message_stop", { type: "message_stop" });
|
|
33894
|
+
[Stream error: ${error}]`);
|
|
33895
|
+
}
|
|
33901
33896
|
} catch {}
|
|
33902
33897
|
isClosed = true;
|
|
33903
33898
|
if (opts.onTokenUpdate)
|
|
@@ -40410,6 +40405,18 @@ function teamSlotActivity(teamSessionId) {
|
|
|
40410
40405
|
}
|
|
40411
40406
|
return out;
|
|
40412
40407
|
}
|
|
40408
|
+
function teamSlotLiveBytes(teamSessionId) {
|
|
40409
|
+
const run = liveTeamRuns.get(teamSessionId);
|
|
40410
|
+
if (!run)
|
|
40411
|
+
return null;
|
|
40412
|
+
const out = {};
|
|
40413
|
+
for (const slotId of run.processes.keys()) {
|
|
40414
|
+
const bytes = run.liveBytesFor(slotId);
|
|
40415
|
+
if (bytes !== null)
|
|
40416
|
+
out[slotId] = bytes;
|
|
40417
|
+
}
|
|
40418
|
+
return out;
|
|
40419
|
+
}
|
|
40413
40420
|
async function cancelTeamRun(teamSessionId, slotId) {
|
|
40414
40421
|
const run = liveTeamRuns.get(teamSessionId);
|
|
40415
40422
|
if (!run)
|
|
@@ -40862,6 +40869,7 @@ async function startModels(sessionPath, opts = {}) {
|
|
|
40862
40869
|
processes,
|
|
40863
40870
|
idleMsFor: (slotId) => runtimes.get(slotId)?.getIdleMs() ?? null,
|
|
40864
40871
|
activityFor: (slotId) => runtimes.get(slotId)?.getActivity() ?? null,
|
|
40872
|
+
liveBytesFor: (slotId) => runtimes.get(slotId)?.getByteCount() ?? null,
|
|
40865
40873
|
cancelledSlots
|
|
40866
40874
|
});
|
|
40867
40875
|
const done = (async () => {
|
|
@@ -47107,6 +47115,28 @@ function buildChildClaudeFlags(agent, claudeFlags) {
|
|
|
47107
47115
|
const flags = [...named ? ["--agent", named] : [], ...cleaned];
|
|
47108
47116
|
return flags.length > 0 ? flags : undefined;
|
|
47109
47117
|
}
|
|
47118
|
+
function teamStatusNote(opts) {
|
|
47119
|
+
if (!opts.anyRunning)
|
|
47120
|
+
return;
|
|
47121
|
+
const trap = "outputSize is the size of the FINAL answer and is written once, when a slot " + "finishes. Every RUNNING slot therefore reports 0 however much work it has done: " + "it is NOT a progress signal, and 0 there does not mean the slot produced nothing.";
|
|
47122
|
+
if (!opts.live) {
|
|
47123
|
+
return `${trap} This run is not live in this process \u2014 it was started elsewhere, or this ` + "server restarted \u2014 so there are no liveness fields for it and the states above are " + "whatever was last written to status.json.";
|
|
47124
|
+
}
|
|
47125
|
+
return `${trap} Judge a running slot on three fields read TOGETHER: ` + "live_output_bytes_by_slot (answer bytes so far, the number outputSize will become), " + "idle_seconds_by_slot (seconds of silence) and activity_by_slot (what it is doing). " + "Silence in tool_executing is a build or test suite running, and is not a failure " + 'signal. Nothing cancels on your behalf \u2014 use mode:"cancel" if you decide to.';
|
|
47126
|
+
}
|
|
47127
|
+
function buildTeamStatusPayload(opts) {
|
|
47128
|
+
const { status, sessionPath, idle, activity, liveBytes } = opts;
|
|
47129
|
+
const anyRunning = Object.values(status.models).some((m) => m.state === "RUNNING");
|
|
47130
|
+
const note = teamStatusNote({ anyRunning, live: idle !== null });
|
|
47131
|
+
return {
|
|
47132
|
+
...status,
|
|
47133
|
+
live_output_bytes_by_slot: liveBytes,
|
|
47134
|
+
idle_seconds_by_slot: idle,
|
|
47135
|
+
activity_by_slot: activity,
|
|
47136
|
+
...note ? { note } : {},
|
|
47137
|
+
...anyRunning ? {} : { summary: formatTeamResult(status, sessionPath) }
|
|
47138
|
+
};
|
|
47139
|
+
}
|
|
47110
47140
|
function formatTeamResult(status, sessionPath) {
|
|
47111
47141
|
const entries = Object.entries(status.models).sort(([a], [b]) => a.localeCompare(b));
|
|
47112
47142
|
const failed = entries.filter(([, m]) => m.state === "FAILED" || m.state === "TIMEOUT" || m.state === "EMPTY");
|
|
@@ -47592,14 +47622,14 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
47592
47622
|
});
|
|
47593
47623
|
tools.push({
|
|
47594
47624
|
name: "team",
|
|
47595
|
-
description: "Run AI models on a task with anonymized outputs and optional blind judging. " + "Modes: 'run' (START the models and return a slot map immediately \u2014 it does NOT " + "wait), 'status' (per-slot state, plus
|
|
47625
|
+
description: "Run AI models on a task with anonymized outputs and optional blind judging. " + "Modes: 'run' (START the models and return a slot map immediately \u2014 it does NOT " + "wait), 'status' (per-slot state, plus live answer bytes, seconds of silence and " + "current activity per slot), " + "'cancel' (stop one slot or the whole run), 'judge' (blind-vote on existing " + "outputs), 'run-and-judge' (the blocking pipeline). " + "NO SLOT IS EVER KILLED ON A TIMER. A team slot is a full Claude Code session and " + "may work for a long time; a slot inside a build or test suite emits nothing for " + "minutes and is working, not stuck. Poll 'status', judge the silence against the " + "task you set, and use 'cancel' if you decide a slot is wedged. " + "JUDGING A RUNNING SLOT: read live_output_bytes_by_slot, idle_seconds_by_slot and " + "activity_by_slot. Do NOT use 'outputSize' \u2014 it is the size of the final answer, " + "written only when a slot finishes, so it is 0 for every running slot no matter how " + "much that slot has produced.",
|
|
47596
47626
|
inputSchema: {
|
|
47597
47627
|
type: "object",
|
|
47598
47628
|
properties: {
|
|
47599
47629
|
mode: {
|
|
47600
47630
|
type: "string",
|
|
47601
47631
|
enum: ["run", "judge", "run-and-judge", "status", "cancel"],
|
|
47602
|
-
description: "Operation mode. 'run' STARTS the models and returns immediately with a " + "slot map \u2014 it does not wait. Poll 'status' for progress, then 'judge' once
|
|
47632
|
+
description: "Operation mode. 'run' STARTS the models and returns immediately with a " + "slot map \u2014 it does not wait. Poll 'status' for progress (read it from " + "live_output_bytes_by_slot and activity_by_slot, never from outputSize, " + "which stays 0 until a slot finishes), then 'judge' once the slots have " + "finished. 'run-and-judge' is the blocking pipeline and holds the call open " + "for the whole run. 'cancel' stops one slot or the whole run."
|
|
47603
47633
|
},
|
|
47604
47634
|
slot: {
|
|
47605
47635
|
type: "string",
|
|
@@ -47750,21 +47780,17 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
47750
47780
|
case "status": {
|
|
47751
47781
|
const status = getStatus(resolved);
|
|
47752
47782
|
const teamSessionId = resolved.split("/").filter(Boolean).pop() ?? "team";
|
|
47753
|
-
const idle = teamSlotIdleSeconds(teamSessionId);
|
|
47754
|
-
const settled = !Object.values(status.models).some((m) => m.state === "RUNNING");
|
|
47755
47783
|
return {
|
|
47756
47784
|
content: [
|
|
47757
47785
|
{
|
|
47758
47786
|
type: "text",
|
|
47759
|
-
text: JSON.stringify({
|
|
47760
|
-
|
|
47761
|
-
|
|
47762
|
-
|
|
47763
|
-
|
|
47764
|
-
|
|
47765
|
-
|
|
47766
|
-
...settled ? { summary: formatTeamResult(status, resolved) } : {}
|
|
47767
|
-
}, null, 2)
|
|
47787
|
+
text: JSON.stringify(buildTeamStatusPayload({
|
|
47788
|
+
status,
|
|
47789
|
+
sessionPath: resolved,
|
|
47790
|
+
idle: teamSlotIdleSeconds(teamSessionId),
|
|
47791
|
+
activity: teamSlotActivity(teamSessionId),
|
|
47792
|
+
liveBytes: teamSlotLiveBytes(teamSessionId)
|
|
47793
|
+
}), null, 2)
|
|
47768
47794
|
}
|
|
47769
47795
|
]
|
|
47770
47796
|
};
|
|
@@ -69386,7 +69412,8 @@ Team Status`);
|
|
|
69386
69412
|
}
|
|
69387
69413
|
const rawArgs = process.argv.slice(2);
|
|
69388
69414
|
const explicitNoAutoApprove = rawArgs.includes("--no-auto-approve");
|
|
69389
|
-
|
|
69415
|
+
const explicitAutoApprove = rawArgs.includes("-y") || rawArgs.includes("--auto-approve");
|
|
69416
|
+
if (cliConfig.autoApprove && !explicitNoAutoApprove && !explicitAutoApprove && !cliConfig.stdin && cliConfig.interactive) {
|
|
69390
69417
|
await Promise.resolve().then(() => init_profile_config());
|
|
69391
69418
|
try {
|
|
69392
69419
|
const cfg = loadConfig();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "9.1
|
|
3
|
+
"version": "9.2.1",
|
|
4
4
|
"description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"ai"
|
|
61
61
|
],
|
|
62
62
|
"optionalDependencies": {
|
|
63
|
-
"@claudish/magmux-darwin-arm64": "9.1
|
|
64
|
-
"@claudish/magmux-darwin-x64": "9.1
|
|
65
|
-
"@claudish/magmux-linux-arm64": "9.1
|
|
66
|
-
"@claudish/magmux-linux-x64": "9.1
|
|
63
|
+
"@claudish/magmux-darwin-arm64": "9.2.1",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "9.2.1",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "9.2.1",
|
|
66
|
+
"@claudish/magmux-linux-x64": "9.2.1"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|