@livx.cc/agentx 0.99.73 → 0.99.75
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/{Agent-CSFGRC-I.d.ts → Agent-BBlKI8uD.d.ts} +8 -1
- package/dist/cli.d.ts +7 -2
- package/dist/cli.js +168 -296
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +44 -173
- package/dist/index.js.map +1 -1
- package/dist/{mcp-8_lBApgs.d.ts → mcp-BhTxN2I7.d.ts} +1 -1
- package/dist/mcp.client.d.ts +2 -2
- package/dist/{tools-wVQBhYwm.d.ts → tools-lC3jn60o.d.ts} +2 -2
- package/dist/tools.shell.d.ts +1 -1
- package/dist/tools.shell.js +2 -7
- package/dist/tools.shell.js.map +1 -1
- package/package.json +3 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { a as AgentOptions, H as Hooks, n as RunResult, A as Agent, g as PermissionPolicy } from './Agent-
|
|
2
|
-
export { C as ChatFragment, b as Classification, c as Classifier, d as CompactResult, D as DEFAULT_MUTATING, e as Decision, M as ModelRouter, f as ModelRouterOptions, P as PermissionOptions, h as PermissionRule, i as PreToolUseDecision, R as ReasoningEffort, j as RecordingHooks, k as RecordingLifecycle, l as RouteDecision, m as RouterState, T as Tier, o as ToolUse, p as ToolUseMeta, q as claudeCodeDisallowedTools, r as composeHooks, s as estimateTokens, t as jevAvailable, u as jevClassifier, v as pickTier, w as planMode, x as reasoningToChatFragment } from './Agent-
|
|
1
|
+
import { a as AgentOptions, H as Hooks, n as RunResult, A as Agent, g as PermissionPolicy } from './Agent-BBlKI8uD.js';
|
|
2
|
+
export { C as ChatFragment, b as Classification, c as Classifier, d as CompactResult, D as DEFAULT_MUTATING, e as Decision, M as ModelRouter, f as ModelRouterOptions, P as PermissionOptions, h as PermissionRule, i as PreToolUseDecision, R as ReasoningEffort, j as RecordingHooks, k as RecordingLifecycle, l as RouteDecision, m as RouterState, T as Tier, o as ToolUse, p as ToolUseMeta, q as claudeCodeDisallowedTools, r as composeHooks, s as estimateTokens, t as jevAvailable, u as jevClassifier, v as pickTier, w as planMode, x as reasoningToChatFragment } from './Agent-BBlKI8uD.js';
|
|
3
3
|
export { MODEL_ALIASES, ModelSwitch, ResolveModelSwitchOpts, modelShortLabel, resolveModelAlias, resolveModelSwitch } from './models.js';
|
|
4
4
|
import { IFilesystem, FileMetadata } from '@livx.cc/wcli/core';
|
|
5
5
|
export { CommandExecutor, FileMetadata, IFilesystem, IndexedDbFilesystem, MemFilesystem, registerHeadlessCommands } from '@livx.cc/wcli/core';
|
|
6
6
|
import { BodDB } from '@bod.ee/db';
|
|
7
|
-
import { A as AgentTool, C as ChatLike, a as ChatOptions, b as ChatResponse, r as ToolCall, H as HostBridge, U as UserQuestion, o as MessageContent } from './tools-
|
|
8
|
-
export { c as ContentPart, d as HostEvent, I as IMAGE_ELIDE_STUB, e as IMAGE_REF_SCHEME, f as ImageRef, J as JobCtx, g as JobHandle, h as JobInfo, i as JobKind, j as JobNotice, k as JobRegistry, l as JobRegistryOptions, n as JobTrackOptions, M as Message, m as RegistryJobStatus, R as Role, S as SandboxJobRegistry, p as StreamChunk, T as TodoItem, q as Tool, s as ToolContext, t as bashTool, u as clearImageRefs, v as contentBytes, w as contentText, x as defaultTools, y as editTool, z as elideImages, B as elideInlineImages, D as elideStaleImages, E as exitSessionTool, F as expandImagesForSend, G as formatJobNotice, K as imagePart, L as imageRefPart, N as imageRefResult, O as makeContext, P as makeJobTools, Q as messageHasImage, V as messageHasImageRef, W as messageHasInlineImage, X as mintImageRef, Y as parseImageRef, Z as readTool, _ as remintImageRefs, $ as sendBytes, a0 as sendBytesPer, a1 as toWireTools, a2 as todoWriteTool, a3 as toolImageRef, a4 as toolRegistry, a5 as toolsByName } from './tools-
|
|
7
|
+
import { A as AgentTool, C as ChatLike, a as ChatOptions, b as ChatResponse, r as ToolCall, H as HostBridge, U as UserQuestion, o as MessageContent } from './tools-lC3jn60o.js';
|
|
8
|
+
export { c as ContentPart, d as HostEvent, I as IMAGE_ELIDE_STUB, e as IMAGE_REF_SCHEME, f as ImageRef, J as JobCtx, g as JobHandle, h as JobInfo, i as JobKind, j as JobNotice, k as JobRegistry, l as JobRegistryOptions, n as JobTrackOptions, M as Message, m as RegistryJobStatus, R as Role, S as SandboxJobRegistry, p as StreamChunk, T as TodoItem, q as Tool, s as ToolContext, t as bashTool, u as clearImageRefs, v as contentBytes, w as contentText, x as defaultTools, y as editTool, z as elideImages, B as elideInlineImages, D as elideStaleImages, E as exitSessionTool, F as expandImagesForSend, G as formatJobNotice, K as imagePart, L as imageRefPart, N as imageRefResult, O as makeContext, P as makeJobTools, Q as messageHasImage, V as messageHasImageRef, W as messageHasInlineImage, X as mintImageRef, Y as parseImageRef, Z as readTool, _ as remintImageRefs, $ as sendBytes, a0 as sendBytesPer, a1 as toWireTools, a2 as todoWriteTool, a3 as toolImageRef, a4 as toolRegistry, a5 as toolsByName } from './tools-lC3jn60o.js';
|
|
9
9
|
import { ShellJobRegistry } from './tools.shell.js';
|
|
10
10
|
import { SpokenSplitter } from '@bod.ee/voice';
|
|
11
11
|
export { AudioSink, AudioSource, AuthProvider, CartesiaTTS, CartesiaTTSOptions, STT_SAMPLE_RATE, SonioxSTT, SonioxSTTOptions, SttLike, TTS_SAMPLE_RATE, TtsLike, VoiceEngine, VoiceEngineOptions, VoiceState, resolveAuth } from '@bod.ee/voice';
|
|
12
|
-
export { M as McpCall, a as McpImage, b as McpRoute, c as McpRouteResolver, d as McpToolResult, e as McpToolSearchOptions, f as McpToolSpec, g as MountedMcpLike, h as buildMcpCatalog, m as makeLazyMcpToolSearch, i as makeMcpToolSearch, j as makeMcpToolSearchFromMounted, k as mcpToolToAgentTool, l as mcpToolsToAgentTools } from './mcp-
|
|
12
|
+
export { M as McpCall, a as McpImage, b as McpRoute, c as McpRouteResolver, d as McpToolResult, e as McpToolSearchOptions, f as McpToolSpec, g as MountedMcpLike, h as buildMcpCatalog, m as makeLazyMcpToolSearch, i as makeMcpToolSearch, j as makeMcpToolSearchFromMounted, k as mcpToolToAgentTool, l as mcpToolsToAgentTools } from './mcp-BhTxN2I7.js';
|
|
13
13
|
import * as libx_js_src_modules_log from 'libx.js/src/modules/log';
|
|
14
14
|
export { log } from 'libx.js/src/modules/log';
|
|
15
15
|
|
package/dist/index.js
CHANGED
|
@@ -19,134 +19,14 @@ var init_logging = __esm({
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
// src/imageWire.ts
|
|
22
|
-
import { readFileSync,
|
|
23
|
-
import {
|
|
24
|
-
import { createHash } from "crypto";
|
|
25
|
-
import { tmpdir } from "os";
|
|
26
|
-
import { join } from "path";
|
|
27
|
-
import { PNG } from "pngjs";
|
|
28
|
-
import jpeg from "jpeg-js";
|
|
29
|
-
function imageSize(b) {
|
|
30
|
-
const u16 = (i) => b[i] << 8 | b[i + 1];
|
|
31
|
-
const le16 = (i) => b[i] | b[i + 1] << 8;
|
|
32
|
-
const u32 = (i) => (b[i] << 24 >>> 0) + (b[i + 1] << 16) + (b[i + 2] << 8) + b[i + 3];
|
|
33
|
-
if (b[0] === 137 && b[1] === 80 && b.length >= 24) return { w: u32(16), h: u32(20) };
|
|
34
|
-
if (b[0] === 71 && b[1] === 73 && b.length >= 10) return { w: le16(6), h: le16(8) };
|
|
35
|
-
if (b[0] === 255 && b[1] === 216) {
|
|
36
|
-
for (let i = 2; i + 9 < b.length; ) {
|
|
37
|
-
if (b[i] !== 255) return null;
|
|
38
|
-
const m = b[i + 1];
|
|
39
|
-
if (m >= 192 && m <= 207 && m !== 196 && m !== 200 && m !== 204) return { w: u16(i + 7), h: u16(i + 5) };
|
|
40
|
-
i += 2 + u16(i + 2);
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
if (b.length >= 30 && String.fromCharCode(...b.subarray(8, 12)) === "WEBP") {
|
|
45
|
-
const kind = String.fromCharCode(...b.subarray(12, 16));
|
|
46
|
-
if (kind === "VP8X") return { w: 1 + (b[24] | b[25] << 8 | b[26] << 16), h: 1 + (b[27] | b[28] << 8 | b[29] << 16) };
|
|
47
|
-
if (kind === "VP8 ") return { w: le16(26) & 16383, h: le16(28) & 16383 };
|
|
48
|
-
if (kind === "VP8L") {
|
|
49
|
-
const v = b[21] | b[22] << 8 | b[23] << 16 | b[24] << 24;
|
|
50
|
-
return { w: (v & 16383) + 1, h: (v >> 14 & 16383) + 1 };
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
function imageNote(what, bytes, dims, why) {
|
|
56
|
-
return `[image ${what}${dims ? `, ${dims.w}x${dims.h}` : ""}, ${fmtBytes(bytes)} \u2014 not sent: ${why}]`;
|
|
57
|
-
}
|
|
58
|
-
function downscaleJs(buf, maxSide) {
|
|
59
|
-
let src;
|
|
60
|
-
try {
|
|
61
|
-
if (buf[0] === 137 && buf[1] === 80) src = PNG.sync.read(buf);
|
|
62
|
-
else if (buf[0] === 255 && buf[1] === 216) src = jpeg.decode(buf, { useTArray: true, maxMemoryUsageInMB: 1024 });
|
|
63
|
-
else return null;
|
|
64
|
-
} catch (e) {
|
|
65
|
-
log2.warn("pure-JS image decode failed", e);
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
const { width: sw, height: sh, data: s } = src;
|
|
69
|
-
const k = Math.min(1, maxSide / Math.max(sw, sh));
|
|
70
|
-
const w = Math.max(1, Math.round(sw * k)), h = Math.max(1, Math.round(sh * k));
|
|
71
|
-
const d = new Uint8Array(w * h * 4);
|
|
72
|
-
for (let y = 0; y < h; y++) {
|
|
73
|
-
const y0 = Math.floor(y * sh / h), y1 = Math.max(y0 + 1, Math.floor((y + 1) * sh / h));
|
|
74
|
-
for (let x = 0; x < w; x++) {
|
|
75
|
-
const x0 = Math.floor(x * sw / w), x1 = Math.max(x0 + 1, Math.floor((x + 1) * sw / w));
|
|
76
|
-
let r = 0, g = 0, b = 0, a = 0;
|
|
77
|
-
for (let yy = y0; yy < y1; yy++) for (let xx = x0; xx < x1; xx++) {
|
|
78
|
-
const i = (yy * sw + xx) * 4, al = s[i + 3];
|
|
79
|
-
r += s[i] * al;
|
|
80
|
-
g += s[i + 1] * al;
|
|
81
|
-
b += s[i + 2] * al;
|
|
82
|
-
a += al;
|
|
83
|
-
}
|
|
84
|
-
const o = (y * w + x) * 4, n = (y1 - y0) * (x1 - x0), bg = 255 * (n - a / 255);
|
|
85
|
-
d[o] = (r / 255 + bg) / n;
|
|
86
|
-
d[o + 1] = (g / 255 + bg) / n;
|
|
87
|
-
d[o + 2] = (b / 255 + bg) / n;
|
|
88
|
-
d[o + 3] = 255;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
let out = Buffer.alloc(0);
|
|
92
|
-
for (const q of [80, 60, 40]) {
|
|
93
|
-
out = Buffer.from(jpeg.encode({ width: w, height: h, data: d }, q).data);
|
|
94
|
-
if (out.length <= IMAGE_MAX_BYTES) break;
|
|
95
|
-
}
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
98
|
-
function downscale(path, maxSide) {
|
|
99
|
-
const dir = mkdtempSync(join(tmpdir(), "agentx-img-"));
|
|
100
|
-
const out = join(dir, "x.jpg");
|
|
101
|
-
try {
|
|
102
|
-
const tries = [
|
|
103
|
-
["sips", ["-Z", String(maxSide), "-s", "format", "jpeg", "-s", "formatOptions", "80", path, "--out", out]],
|
|
104
|
-
["magick", [path, "-resize", `${maxSide}x${maxSide}>`, "-quality", "80", out]],
|
|
105
|
-
["convert", [path, "-resize", `${maxSide}x${maxSide}>`, "-quality", "80", out]]
|
|
106
|
-
];
|
|
107
|
-
for (const [cmd, args] of tries) {
|
|
108
|
-
const r = spawnSync(cmd, args, { stdio: "ignore", timeout: 15e3 });
|
|
109
|
-
if (r.status !== 0) continue;
|
|
110
|
-
try {
|
|
111
|
-
const o = readFileSync(out);
|
|
112
|
-
if (o.length <= IMAGE_MAX_BYTES) return o;
|
|
113
|
-
break;
|
|
114
|
-
} catch {
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
const js = downscaleJs(readFileSync(path), maxSide);
|
|
118
|
-
if (!js) log2.warn(`could not downscale ${path} (tried sips/magick/convert/pure JS)`);
|
|
119
|
-
return js;
|
|
120
|
-
} finally {
|
|
121
|
-
rmSync(dir, { recursive: true, force: true });
|
|
122
|
-
}
|
|
123
|
-
}
|
|
22
|
+
import { readFileSync, statSync } from "fs";
|
|
23
|
+
import { imageWireOf, inlineImageForWire, scrubBase64Text, imageSize, imageNote, IMAGE_MAX_SIDE, IMAGE_MAX_BYTES } from "ai.libx.js";
|
|
124
24
|
function remember(id, w) {
|
|
125
25
|
cache.delete(id);
|
|
126
26
|
cache.set(id, w);
|
|
127
27
|
if (cache.size > CACHE_MAX) cache.delete(cache.keys().next().value);
|
|
128
28
|
return w;
|
|
129
29
|
}
|
|
130
|
-
function wireOf(key, buf, mime, label, file) {
|
|
131
|
-
const dims = imageSize(buf);
|
|
132
|
-
const fits = buf.length <= IMAGE_MAX_BYTES && (!dims || Math.max(dims.w, dims.h) <= IMAGE_MAX_SIDE);
|
|
133
|
-
let small = null;
|
|
134
|
-
if (!fits) {
|
|
135
|
-
if (file) small = downscale(file, IMAGE_MAX_SIDE);
|
|
136
|
-
else {
|
|
137
|
-
const dir = mkdtempSync(join(tmpdir(), "agentx-img-in-"));
|
|
138
|
-
try {
|
|
139
|
-
const f = join(dir, `in.${mime.split("/")[1] || "img"}`);
|
|
140
|
-
writeFileSync(f, buf);
|
|
141
|
-
small = downscale(f, IMAGE_MAX_SIDE);
|
|
142
|
-
} finally {
|
|
143
|
-
rmSync(dir, { recursive: true, force: true });
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
const url = fits ? `data:${mime};base64,${buf.toString("base64")}` : small && small.length <= IMAGE_MAX_BYTES ? `data:image/jpeg;base64,${small.toString("base64")}` : null;
|
|
148
|
-
return { key, url, note: imageNote(label, buf.length, dims, url ? "this model can't see images" : "too large and it couldn't be downscaled") };
|
|
149
|
-
}
|
|
150
30
|
function imageForWire(path, mime, vision) {
|
|
151
31
|
let st;
|
|
152
32
|
try {
|
|
@@ -157,48 +37,30 @@ function imageForWire(path, mime, vision) {
|
|
|
157
37
|
}
|
|
158
38
|
const key = `${st.mtimeMs}:${st.size}`;
|
|
159
39
|
let hit = cache.get(path);
|
|
160
|
-
if (!hit || hit.key !== key) hit = remember(path,
|
|
40
|
+
if (!hit || hit.key !== key) hit = remember(path, { key, ...imageWireOf(readFileSync(path), mime, path, path) });
|
|
161
41
|
return vision && hit.url ? { url: hit.url } : { note: hit.note };
|
|
162
42
|
}
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
const mime = url.slice(5, url.indexOf(";"));
|
|
166
|
-
if (vision && url.length < 3e5) {
|
|
167
|
-
const b64 = url.slice(comma + 1);
|
|
168
|
-
const dims = imageSize(Buffer.from(b64.slice(0, 4096), "base64")) ?? imageSize(Buffer.from(b64, "base64"));
|
|
169
|
-
if (!dims || Math.max(dims.w, dims.h) <= IMAGE_MAX_SIDE) return { url };
|
|
170
|
-
}
|
|
171
|
-
const id = `inline:${createHash("sha1").update(url).digest("base64")}`;
|
|
172
|
-
let hit = cache.get(id);
|
|
173
|
-
if (!hit) {
|
|
174
|
-
const buf = Buffer.from(url.slice(comma + 1), "base64");
|
|
175
|
-
hit = remember(id, wireOf(id, buf, mime, `(${mime})`));
|
|
176
|
-
}
|
|
177
|
-
return vision && hit.url ? { url: hit.url } : { note: hit.note };
|
|
43
|
+
function imageTokens(dims) {
|
|
44
|
+
return dims ? Math.min(IMAGE_TOKENS_MAX, Math.max(1, Math.ceil(dims.w * dims.h / 750))) : IMAGE_TOKENS_MAX;
|
|
178
45
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
|
|
46
|
+
function wiredImageWeight(r) {
|
|
47
|
+
if ("note" in r) return r.note.length;
|
|
48
|
+
const b64 = r.url.slice(r.url.indexOf(",") + 1);
|
|
49
|
+
return 4 * imageTokens(imageSize(Buffer.from(b64.slice(0, 4096), "base64")));
|
|
182
50
|
}
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (out !== s) log2.warn(`scrubbed base64 from request text (${s.length} \u2192 ${out.length} chars)`);
|
|
187
|
-
return out;
|
|
51
|
+
function imageWireWeight(path, mime, vision) {
|
|
52
|
+
const r = imageForWire(path, mime, vision);
|
|
53
|
+
return r ? wiredImageWeight(r) : 0;
|
|
188
54
|
}
|
|
189
|
-
var log2,
|
|
55
|
+
var log2, cache, CACHE_MAX, IMAGE_TOKENS_MAX;
|
|
190
56
|
var init_imageWire = __esm({
|
|
191
57
|
"src/imageWire.ts"() {
|
|
192
58
|
"use strict";
|
|
193
59
|
init_logging();
|
|
194
60
|
log2 = forComponent("imageWire");
|
|
195
|
-
IMAGE_MAX_SIDE = 1568;
|
|
196
|
-
IMAGE_MAX_BYTES = 1e6;
|
|
197
|
-
fmtBytes = (n) => n >= 1e6 ? `${(n / 1e6).toFixed(1)} MB` : n >= 1e3 ? `${Math.round(n / 1e3)} KB` : `${n} B`;
|
|
198
61
|
cache = /* @__PURE__ */ new Map();
|
|
199
62
|
CACHE_MAX = 8;
|
|
200
|
-
|
|
201
|
-
B64_RUN = /[A-Za-z0-9+/=]{2000,}/g;
|
|
63
|
+
IMAGE_TOKENS_MAX = 1600;
|
|
202
64
|
}
|
|
203
65
|
});
|
|
204
66
|
|
|
@@ -396,7 +258,7 @@ function sendBytesPer(messages, keepRecent = 1, vision = true, stub = IMAGE_ELID
|
|
|
396
258
|
}
|
|
397
259
|
function wireBytes(content, kept, vision, stub) {
|
|
398
260
|
const tool = toolImageRef(content);
|
|
399
|
-
if (tool) return kept ?
|
|
261
|
+
if (tool) return kept ? imageWireWeight(tool.path, tool.mime, vision) || stub.length : stub.length;
|
|
400
262
|
if (content == null || typeof content === "string") return contentBytes(content);
|
|
401
263
|
if (kept) {
|
|
402
264
|
let n2 = 0;
|
|
@@ -404,7 +266,7 @@ function wireBytes(content, kept, vision, stub) {
|
|
|
404
266
|
const url = p.type === "image_url" ? p.image_url?.url ?? "" : "";
|
|
405
267
|
const ref = url ? parseImageRef(url) : null;
|
|
406
268
|
const inline = url.startsWith("data:") ? inlineImageForWire(url, vision) : null;
|
|
407
|
-
n2 += ref ?
|
|
269
|
+
n2 += ref ? imageWireWeight(ref.path, ref.mime, vision) : inline ? wiredImageWeight(inline) : contentBytes([p]);
|
|
408
270
|
}
|
|
409
271
|
return n2;
|
|
410
272
|
}
|
|
@@ -3642,8 +3504,8 @@ ${sections.join("\n\n---\n\n")}`;
|
|
|
3642
3504
|
|
|
3643
3505
|
// src/subagent.ts
|
|
3644
3506
|
init_tools();
|
|
3645
|
-
import { mkdirSync as mkdirSync2, writeFileSync
|
|
3646
|
-
import { join as
|
|
3507
|
+
import { mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
3508
|
+
import { join as join3 } from "path";
|
|
3647
3509
|
|
|
3648
3510
|
// src/models.ts
|
|
3649
3511
|
var MODEL_ALIASES = {
|
|
@@ -3840,9 +3702,9 @@ function composeHooks(...list) {
|
|
|
3840
3702
|
init_OverlayFilesystem();
|
|
3841
3703
|
|
|
3842
3704
|
// src/worktree.ts
|
|
3843
|
-
import { spawnSync
|
|
3844
|
-
import { symlinkSync, mkdirSync, statSync as statSync3, readFileSync as readFileSync3, rmSync
|
|
3845
|
-
import { join
|
|
3705
|
+
import { spawnSync } from "child_process";
|
|
3706
|
+
import { symlinkSync, mkdirSync, statSync as statSync3, readFileSync as readFileSync3, rmSync } from "fs";
|
|
3707
|
+
import { join } from "path";
|
|
3846
3708
|
var VALID_SEGMENT = /^[a-zA-Z0-9._-]+$/;
|
|
3847
3709
|
var MAX_SLUG_LENGTH = 64;
|
|
3848
3710
|
var GIT_NO_PROMPT_ENV = { GIT_TERMINAL_PROMPT: "0", GIT_ASKPASS: "" };
|
|
@@ -3861,13 +3723,13 @@ function worktreeBranchName(slug2) {
|
|
|
3861
3723
|
return `worktree-${flattenSlug(slug2)}`;
|
|
3862
3724
|
}
|
|
3863
3725
|
function worktreesDir(repoRoot) {
|
|
3864
|
-
return
|
|
3726
|
+
return join(repoRoot, ".claude", "worktrees");
|
|
3865
3727
|
}
|
|
3866
3728
|
function worktreePathFor(repoRoot, slug2) {
|
|
3867
|
-
return
|
|
3729
|
+
return join(worktreesDir(repoRoot), flattenSlug(slug2));
|
|
3868
3730
|
}
|
|
3869
3731
|
function git(args, cwd) {
|
|
3870
|
-
const r =
|
|
3732
|
+
const r = spawnSync("git", args, {
|
|
3871
3733
|
cwd,
|
|
3872
3734
|
stdio: ["ignore", "pipe", "pipe"],
|
|
3873
3735
|
env: { ...process.env, ...GIT_NO_PROMPT_ENV }
|
|
@@ -3880,14 +3742,14 @@ function findGitRoot(from) {
|
|
|
3880
3742
|
}
|
|
3881
3743
|
function readWorktreeHead(worktreePath) {
|
|
3882
3744
|
try {
|
|
3883
|
-
const gitFile = readFileSync3(
|
|
3745
|
+
const gitFile = readFileSync3(join(worktreePath, ".git"), "utf-8").trim();
|
|
3884
3746
|
const m = gitFile.match(/^gitdir:\s*(.+)$/);
|
|
3885
3747
|
if (!m) return null;
|
|
3886
|
-
const headPath =
|
|
3748
|
+
const headPath = join(m[1], "HEAD");
|
|
3887
3749
|
const head = readFileSync3(headPath, "utf-8").trim();
|
|
3888
3750
|
const refMatch = head.match(/^ref:\s*(.+)$/);
|
|
3889
3751
|
if (!refMatch) return head.length === 40 ? head : null;
|
|
3890
|
-
const refPath =
|
|
3752
|
+
const refPath = join(m[1], "..", refMatch[1]);
|
|
3891
3753
|
try {
|
|
3892
3754
|
return readFileSync3(refPath, "utf-8").trim();
|
|
3893
3755
|
} catch {
|
|
@@ -3922,8 +3784,8 @@ function getOrCreateWorktree(repoRoot, slug2) {
|
|
|
3922
3784
|
}
|
|
3923
3785
|
function symlinkDirs(repoRoot, worktreePath, dirs) {
|
|
3924
3786
|
for (const dir of dirs) {
|
|
3925
|
-
const src =
|
|
3926
|
-
const dst =
|
|
3787
|
+
const src = join(repoRoot, dir);
|
|
3788
|
+
const dst = join(worktreePath, dir);
|
|
3927
3789
|
try {
|
|
3928
3790
|
statSync3(src);
|
|
3929
3791
|
} catch {
|
|
@@ -3951,7 +3813,7 @@ function cleanupWorktree(repoRoot, slug2, opts) {
|
|
|
3951
3813
|
}
|
|
3952
3814
|
for (const dir of ["node_modules", ".bun"]) {
|
|
3953
3815
|
try {
|
|
3954
|
-
|
|
3816
|
+
rmSync(join(worktreePath, dir));
|
|
3955
3817
|
} catch {
|
|
3956
3818
|
}
|
|
3957
3819
|
}
|
|
@@ -4063,7 +3925,7 @@ function traceFileFor(dir, label, depth) {
|
|
|
4063
3925
|
try {
|
|
4064
3926
|
mkdirSync2(dir, { recursive: true });
|
|
4065
3927
|
const id = `${Date.now().toString(36)}-${(traceSeq++).toString(36)}`;
|
|
4066
|
-
return
|
|
3928
|
+
return join3(dir, `${id}-d${depth}-${sanitizeSlug(label) || "sub"}.json`);
|
|
4067
3929
|
} catch (e) {
|
|
4068
3930
|
log7.warn(`subagent trace dir unavailable (${dir}) \u2014 running without a trace: ${e instanceof Error ? e.message : String(e)}`);
|
|
4069
3931
|
return void 0;
|
|
@@ -4071,7 +3933,7 @@ function traceFileFor(dir, label, depth) {
|
|
|
4071
3933
|
}
|
|
4072
3934
|
function flushTrace(file, meta, messages, status) {
|
|
4073
3935
|
try {
|
|
4074
|
-
|
|
3936
|
+
writeFileSync(file, JSON.stringify({ ...meta, status, updated: Date.now(), messages }, null, 2));
|
|
4075
3937
|
} catch (e) {
|
|
4076
3938
|
log7.warn(`subagent trace flush failed (${file}): ${e instanceof Error ? e.message : String(e)}`);
|
|
4077
3939
|
}
|
|
@@ -5005,6 +4867,7 @@ var Agent = class _Agent {
|
|
|
5005
4867
|
let steps = 0;
|
|
5006
4868
|
const usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0 };
|
|
5007
4869
|
let usageEstimated = false;
|
|
4870
|
+
let spent = 0, prevPrompt = -1, stepPrompt = 0;
|
|
5008
4871
|
const start = Date.now();
|
|
5009
4872
|
this.parkedMs = 0;
|
|
5010
4873
|
this.ctx.needsInput = void 0;
|
|
@@ -5015,12 +4878,12 @@ var Agent = class _Agent {
|
|
|
5015
4878
|
let closureNudged = false;
|
|
5016
4879
|
let lastProgressAt = start;
|
|
5017
4880
|
const kill = (finishReason) => {
|
|
5018
|
-
log8.warn(`kill-switch: ${finishReason} (steps=${steps}, tokens=${usage.totalTokens}, budgetTokens=${Math.round(
|
|
4881
|
+
log8.warn(`kill-switch: ${finishReason} (steps=${steps}, tokens=${usage.totalTokens}, budgetTokens=${Math.round(spent)}, ms=${Date.now() - start - this.parkedMs}${finishReason === "timeout" ? `, idle=${Date.now() - lastProgressAt - this.parkedMs}ms` : ""}${this.parkedMs ? ` +${this.parkedMs} parked` : ""})`);
|
|
5019
4882
|
this.jobs.killAll(`run ended: ${finishReason}`, true);
|
|
5020
4883
|
const claims = this.survivingClaims();
|
|
5021
|
-
return { text: lastAssistantText(this.transcript), steps, finishReason, messages: this.transcript, usage, usageEstimated, ...claims.length ? { fabricatedToolClaims: claims } : {} };
|
|
4884
|
+
return { text: lastAssistantText(this.transcript), steps, finishReason, messages: this.transcript, usage, usageEstimated, ...finishReason === "budget" ? { budget: { spent: Math.round(spent), limit: o.maxTokens, stepPrompt } } : {}, ...claims.length ? { fabricatedToolClaims: claims } : {} };
|
|
5022
4885
|
};
|
|
5023
|
-
const overBudget = () => !!o.maxTokens &&
|
|
4886
|
+
const overBudget = () => !!o.maxTokens && spent >= o.maxTokens;
|
|
5024
4887
|
const canNudge = () => steps < o.maxSteps && !overBudget();
|
|
5025
4888
|
while (true) {
|
|
5026
4889
|
if (o.signal?.aborted) return kill("aborted");
|
|
@@ -5174,6 +5037,14 @@ var Agent = class _Agent {
|
|
|
5174
5037
|
usage.totalTokens += res.usage.totalTokens ?? 0;
|
|
5175
5038
|
usage.cacheCreationTokens += res.usage.cacheCreationTokens ?? 0;
|
|
5176
5039
|
usage.cacheReadTokens += res.usage.cacheReadTokens ?? 0;
|
|
5040
|
+
const prompt = res.usage.promptTokens ?? 0, cacheRead = res.usage.cacheReadTokens ?? 0;
|
|
5041
|
+
if (prevPrompt < 0) {
|
|
5042
|
+
const u = sent.map((m) => m.role).lastIndexOf("user");
|
|
5043
|
+
prevPrompt = u > 0 ? estimateTokens(sent.slice(0, u)) : 0;
|
|
5044
|
+
}
|
|
5045
|
+
const reused = Math.min(prompt, Math.max(cacheRead, prevPrompt));
|
|
5046
|
+
spent += (res.usage.totalTokens ?? 0) - 0.9 * reused;
|
|
5047
|
+
prevPrompt = stepPrompt = prompt;
|
|
5177
5048
|
}
|
|
5178
5049
|
const delegatedTools = res.delegatedTools ?? [];
|
|
5179
5050
|
if (delegatedTools.length) {
|