agent.libx.js 0.89.4 → 0.89.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +20 -0
- package/dist/cli.js +54 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
|
@@ -23,6 +23,25 @@ interface SessionMeta {
|
|
|
23
23
|
costUsd?: number;
|
|
24
24
|
/** Sticky: true if any turn's usage was estimated (streamed without provider usage) → cost is approximate. */
|
|
25
25
|
costEstimated?: boolean;
|
|
26
|
+
/** Per-turn forensic log: timing, outcome, usage, and provider error per turn — for investigating a reported issue. */
|
|
27
|
+
events?: TurnEvent[];
|
|
28
|
+
}
|
|
29
|
+
/** One turn's diagnostics, captured for offline forensics (mirrors what the footer prints, but persisted). */
|
|
30
|
+
interface TurnEvent {
|
|
31
|
+
ts: number;
|
|
32
|
+
durationMs: number;
|
|
33
|
+
model: string;
|
|
34
|
+
finishReason: string;
|
|
35
|
+
steps: number;
|
|
36
|
+
tools: number;
|
|
37
|
+
tokens?: number;
|
|
38
|
+
costUsd?: number;
|
|
39
|
+
estimated?: boolean;
|
|
40
|
+
error?: {
|
|
41
|
+
message: string;
|
|
42
|
+
statusCode?: number;
|
|
43
|
+
code?: string;
|
|
44
|
+
};
|
|
26
45
|
}
|
|
27
46
|
interface SessionData {
|
|
28
47
|
meta: SessionMeta;
|
|
@@ -145,6 +164,7 @@ declare function expandMentions(fs: IFilesystem, line: string): Promise<{
|
|
|
145
164
|
}>;
|
|
146
165
|
/** The headless `--output-format json` result object for a turn. */
|
|
147
166
|
declare function jsonResult(res: RunResult, session: SessionData): {
|
|
167
|
+
error?: any;
|
|
148
168
|
ok: boolean;
|
|
149
169
|
finishReason: "error" | "budget" | "stop" | "max_steps" | "timeout" | "loop" | "max_tool_calls" | "aborted";
|
|
150
170
|
text: string;
|
package/dist/cli.js
CHANGED
|
@@ -2805,7 +2805,7 @@ var Agent = class _Agent {
|
|
|
2805
2805
|
} catch (err2) {
|
|
2806
2806
|
if (err2?.code === "budget") return kill("budget");
|
|
2807
2807
|
if (o.signal?.aborted) return kill("aborted");
|
|
2808
|
-
log3.error(
|
|
2808
|
+
log3.error(`chat() failed: ${err2?.message ?? err2}`, err2);
|
|
2809
2809
|
return { text: "", steps, finishReason: "error", messages: this.transcript, usage, usageEstimated, error: err2 };
|
|
2810
2810
|
}
|
|
2811
2811
|
if (o.signal?.aborted) return kill("aborted");
|
|
@@ -2869,12 +2869,14 @@ var Agent = class _Agent {
|
|
|
2869
2869
|
}
|
|
2870
2870
|
async dispatch(tc) {
|
|
2871
2871
|
const tool = this.activeTools.find((t) => t.name === tc.function.name);
|
|
2872
|
-
if (!tool) return `Error: unknown tool '${tc.function.name}'`;
|
|
2873
2872
|
let args = {};
|
|
2873
|
+
let earlyError;
|
|
2874
|
+
if (!tool) earlyError = `Error: unknown tool '${tc.function.name}'`;
|
|
2874
2875
|
try {
|
|
2875
2876
|
args = tc.function.arguments ? JSON.parse(tc.function.arguments) : {};
|
|
2876
2877
|
} catch (e) {
|
|
2877
|
-
|
|
2878
|
+
args = tc.function.arguments;
|
|
2879
|
+
earlyError ??= `Error: invalid JSON arguments for ${tc.function.name}: ${String(e)}`;
|
|
2878
2880
|
}
|
|
2879
2881
|
const hooks = this.activeHooks;
|
|
2880
2882
|
const call = { name: tc.function.name, args };
|
|
@@ -2887,6 +2889,12 @@ var Agent = class _Agent {
|
|
|
2887
2889
|
return blocked;
|
|
2888
2890
|
}
|
|
2889
2891
|
this.options.host?.notify?.({ kind: "tool_use", id: tc.id ?? "", name: tc.function.name, input: args });
|
|
2892
|
+
if (earlyError) {
|
|
2893
|
+
log3.debug(`${tc.function.name} -> ${earlyError}`);
|
|
2894
|
+
await hooks?.postToolUse?.(call, earlyError, meta);
|
|
2895
|
+
this.options.host?.notify?.({ kind: "tool_result", id: tc.id ?? "", output: earlyError, isError: true });
|
|
2896
|
+
return earlyError;
|
|
2897
|
+
}
|
|
2890
2898
|
let result;
|
|
2891
2899
|
let threw = false;
|
|
2892
2900
|
try {
|
|
@@ -4641,7 +4649,7 @@ function completePath(listDir, ref) {
|
|
|
4641
4649
|
import { emitKeypressEvents } from "readline";
|
|
4642
4650
|
|
|
4643
4651
|
// cli/bidi.ts
|
|
4644
|
-
var RTL_RE = /[
|
|
4652
|
+
var RTL_RE = /[\u0590-\u05ff\u0600-\u06ff\u0750-\u077f\u08a0-\u08ff\ufb1d-\ufdff\ufe70-\ufeff]/;
|
|
4645
4653
|
var needsBidi = (s) => RTL_RE.test(s);
|
|
4646
4654
|
function classify(c) {
|
|
4647
4655
|
if (c >= 1425 && c <= 1469) return "NSM";
|
|
@@ -5927,6 +5935,22 @@ function resolveModelOrNewest(model) {
|
|
|
5927
5935
|
return fallback;
|
|
5928
5936
|
}
|
|
5929
5937
|
var ENV_KEY_ALIASES = { google: ["GEMINI_API_KEY"] };
|
|
5938
|
+
function loadInstallEnv() {
|
|
5939
|
+
let dir = dirname3(import.meta.path);
|
|
5940
|
+
for (let i = 0; i < 5 && !existsSync7(join8(dir, "package.json")); i++) dir = dirname3(dir);
|
|
5941
|
+
for (const name of [".env", ".env.local"]) {
|
|
5942
|
+
const file = join8(dir, name);
|
|
5943
|
+
if (!existsSync7(file)) continue;
|
|
5944
|
+
for (const line of readFileSync5(file, "utf8").split("\n")) {
|
|
5945
|
+
const m = line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
|
|
5946
|
+
if (!m || m[1] in process.env) continue;
|
|
5947
|
+
let val = m[2].trim();
|
|
5948
|
+
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) val = val.slice(1, -1);
|
|
5949
|
+
else val = val.replace(/\s+#.*$/, "").trim();
|
|
5950
|
+
process.env[m[1]] = val;
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
}
|
|
5930
5954
|
function apiKeysFromEnv() {
|
|
5931
5955
|
const e = process.env, keys = {};
|
|
5932
5956
|
for (const provider of listProviders()) {
|
|
@@ -6118,6 +6142,9 @@ function costOf(pricing, promptTokens = 0, completionTokens = 0) {
|
|
|
6118
6142
|
function turnCost(model, usage) {
|
|
6119
6143
|
return costOf(getModelInfo(model)?.pricing, usage?.promptTokens ?? 0, usage?.completionTokens ?? 0);
|
|
6120
6144
|
}
|
|
6145
|
+
function errInfo(e) {
|
|
6146
|
+
return { message: String(e?.message ?? e), statusCode: e?.statusCode, code: e?.code };
|
|
6147
|
+
}
|
|
6121
6148
|
function fmtUsd(n) {
|
|
6122
6149
|
return n >= 1 ? `$${n.toFixed(2)}` : `$${n.toFixed(4)}`;
|
|
6123
6150
|
}
|
|
@@ -6342,7 +6369,8 @@ function jsonResult(res, session) {
|
|
|
6342
6369
|
steps: res.steps,
|
|
6343
6370
|
tools: res.messages.slice(lastUser).filter((m) => m.role === "tool").length,
|
|
6344
6371
|
usage: res.usage,
|
|
6345
|
-
sessionId: session.meta.id
|
|
6372
|
+
sessionId: session.meta.id,
|
|
6373
|
+
...res.finishReason === "error" && res.error ? { error: res.error?.message ?? String(res.error) } : {}
|
|
6346
6374
|
};
|
|
6347
6375
|
}
|
|
6348
6376
|
async function readMultiline(readLine) {
|
|
@@ -6385,6 +6413,12 @@ async function runTurn(agent, store, session, task, cp, cwd = process.cwd()) {
|
|
|
6385
6413
|
spinner.stop();
|
|
6386
6414
|
err(red(` error: ${e?.message ?? e}
|
|
6387
6415
|
`));
|
|
6416
|
+
(session.meta.events ??= []).push({ ts: t0, durationMs: Date.now() - t0, model: agent.options.model, finishReason: "error", steps: 0, tools: 0, error: errInfo(e) });
|
|
6417
|
+
session.meta.updated = Date.now();
|
|
6418
|
+
try {
|
|
6419
|
+
store.save(session);
|
|
6420
|
+
} catch {
|
|
6421
|
+
}
|
|
6388
6422
|
return { ok: false };
|
|
6389
6423
|
} finally {
|
|
6390
6424
|
spinner.stop();
|
|
@@ -6399,8 +6433,13 @@ async function runTurn(agent, store, session, task, cp, cwd = process.cwd()) {
|
|
|
6399
6433
|
const lastUser = res.messages.map((m2) => m2.role).lastIndexOf("user");
|
|
6400
6434
|
const tools = res.messages.slice(lastUser).filter((m2) => m2.role === "tool").length;
|
|
6401
6435
|
const ok = res.finishReason === "stop";
|
|
6402
|
-
|
|
6436
|
+
const shortId = session.meta.id.slice(-10);
|
|
6437
|
+
err("\n" + (ok ? green(" \u2713 done") : red(` \u2717 ${res.finishReason}`)) + dim(` \xB7 ${res.steps} steps \xB7 ${tools} tools \xB7 ${tok}${secs}s \xB7 ${shortId}
|
|
6403
6438
|
`));
|
|
6439
|
+
if (res.finishReason === "error" && res.error) {
|
|
6440
|
+
const e = res.error;
|
|
6441
|
+
err(red(` ${e?.message ?? e}`) + (e?.statusCode ? dim(` (${e.statusCode}${e.code ? " " + e.code : ""})`) : "") + "\n");
|
|
6442
|
+
}
|
|
6404
6443
|
session.messages = agent.transcript;
|
|
6405
6444
|
session.meta.turns += 1;
|
|
6406
6445
|
session.meta.tokens = (session.meta.tokens ?? 0) + (res.usage?.totalTokens ?? 0);
|
|
@@ -6408,6 +6447,9 @@ async function runTurn(agent, store, session, task, cp, cwd = process.cwd()) {
|
|
|
6408
6447
|
if (res.usageEstimated) session.meta.costEstimated = true;
|
|
6409
6448
|
session.meta.updated = Date.now();
|
|
6410
6449
|
session.meta.model = agent.options.model;
|
|
6450
|
+
const ev = { ts: t0, durationMs: Date.now() - t0, model: agent.options.model, finishReason: res.finishReason, steps: res.steps, tools, tokens: res.usage?.totalTokens, costUsd: cost, estimated: res.usageEstimated };
|
|
6451
|
+
if (res.finishReason === "error" && res.error) ev.error = errInfo(res.error);
|
|
6452
|
+
(session.meta.events ??= []).push(ev);
|
|
6411
6453
|
if (!session.meta.title) session.meta.title = titleOf(agent.transcript);
|
|
6412
6454
|
try {
|
|
6413
6455
|
store.save(session);
|
|
@@ -6439,7 +6481,10 @@ function startSession(args, store, agent, cwd) {
|
|
|
6439
6481
|
`));
|
|
6440
6482
|
}
|
|
6441
6483
|
const now = Date.now();
|
|
6442
|
-
|
|
6484
|
+
const id = args.sessionId ?? store.newId(now);
|
|
6485
|
+
if (!args.task) err(dim(` session ${id}
|
|
6486
|
+
`));
|
|
6487
|
+
return { meta: { id, created: now, updated: now, cwd, model: agent.options.model, turns: 0, title: "" }, messages: [] };
|
|
6443
6488
|
}
|
|
6444
6489
|
var AGENTS_MD_TEMPLATE = `# ${"${name}"}
|
|
6445
6490
|
|
|
@@ -7214,7 +7259,7 @@ ${extra}` : body, checkpoints, cwd);
|
|
|
7214
7259
|
}
|
|
7215
7260
|
});
|
|
7216
7261
|
}
|
|
7217
|
-
const promptStr = bold(cyan("
|
|
7262
|
+
const promptStr = bold(cyan("agentx \u203A "));
|
|
7218
7263
|
const contPrompt = dim(" \u2026 \u203A ");
|
|
7219
7264
|
const classifyPaste = pastePathClassifier(cwd);
|
|
7220
7265
|
const releaseStdin = () => {
|
|
@@ -7376,6 +7421,7 @@ async function main() {
|
|
|
7376
7421
|
if (!id) process.exit(0);
|
|
7377
7422
|
args.resume = id;
|
|
7378
7423
|
}
|
|
7424
|
+
loadInstallEnv();
|
|
7379
7425
|
const apiKeys = { ...cfg.apiKeys, ...apiKeysFromEnv() };
|
|
7380
7426
|
if (!Object.keys(apiKeys).length) {
|
|
7381
7427
|
console.error(red("No provider key found. Set ANTHROPIC_API_KEY (or OPENAI_API_KEY / GOOGLE_API_KEY / GROQ_API_KEY), e.g. in .env."));
|