@livx.cc/agentx 0.99.29 → 0.99.31
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-qoEmC4ic.d.ts → Agent-USp7SIao.d.ts} +7 -4
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +31 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +28 -11
- package/dist/index.js.map +1 -1
- package/dist/{mcp-Cnq0pS95.d.ts → mcp-Bd19NiCL.d.ts} +1 -1
- package/dist/mcp.client.d.ts +2 -2
- package/dist/{tools-BZVppx-6.d.ts → tools-Byyh_bae.d.ts} +4 -3
- package/dist/tools.shell.d.ts +1 -1
- package/dist/tools.shell.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IFilesystem } from '@livx.cc/wcli/core';
|
|
2
|
-
import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, g as MessageContent, U as UserQuestion } from './tools-
|
|
2
|
+
import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, g as MessageContent, U as UserQuestion } from './tools-Byyh_bae.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Hooks — deterministic interception points around tool execution, run by the
|
|
@@ -325,9 +325,12 @@ declare class AgentOptions {
|
|
|
325
325
|
traceDir?: string;
|
|
326
326
|
/** Stream tokens from the model. Takes effect only with a `host.notify`; off => current (non-stream) behavior. */
|
|
327
327
|
stream: boolean;
|
|
328
|
-
/** Closure reflex for delegated runtimes (cursor/claude-code): when such a turn
|
|
329
|
-
* no assistant text after
|
|
330
|
-
*
|
|
328
|
+
/** Closure reflex for delegated runtimes (cursor/claude-code): when such a turn runs tools but never
|
|
329
|
+
* closes — no assistant text after the last tool, or text that trails off on an action it announced
|
|
330
|
+
* and never took ("Also checking for X.") — nudge ONE more step to ANSWER the user
|
|
331
|
+
* from the tool results already in the transcript — so the turn delivers a reply instead of trailing off
|
|
332
|
+
* mid-narration. Deliberately not a "summarize what you did" nudge: that produced process reports and
|
|
333
|
+
* permission-asking instead of answers (see the nudge text in runLoop).
|
|
331
334
|
* Fires at most once per run and only for delegated runtimes (native turns never emit the trigger). */
|
|
332
335
|
closeDelegatedTurns: boolean;
|
|
333
336
|
/** Fold the dropped middle of an over-long transcript into a synthetic summary (edge-safe, no LLM). Off => drop-oldest. */
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { H as Hooks, i as RunResult, R as ReasoningEffort, A as Agent } from './Agent-
|
|
2
|
+
import { H as Hooks, i as RunResult, R as ReasoningEffort, A as Agent } from './Agent-USp7SIao.js';
|
|
3
3
|
import { IFilesystem } from '@livx.cc/wcli/core';
|
|
4
|
-
import { M as Message, U as UserQuestion, H as HostBridge, c as ContentPart, g as MessageContent } from './tools-
|
|
4
|
+
import { M as Message, U as UserQuestion, H as HostBridge, c as ContentPart, g as MessageContent } from './tools-Byyh_bae.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* On-disk session store for the CLI: each conversation is one JSON file at
|
package/dist/cli.js
CHANGED
|
@@ -258,7 +258,13 @@ function stripContent(content, stub) {
|
|
|
258
258
|
});
|
|
259
259
|
return changed ? out : content;
|
|
260
260
|
}
|
|
261
|
-
|
|
261
|
+
function endsOnAnnouncedAction(text) {
|
|
262
|
+
const sentences = text.split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter(Boolean);
|
|
263
|
+
const last = sentences[sentences.length - 1];
|
|
264
|
+
if (!last || NEXT_STEP.test(last)) return false;
|
|
265
|
+
return ANNOUNCED_ACTION.test(last);
|
|
266
|
+
}
|
|
267
|
+
var log2, p_sep, IMAGE_ELIDE_STUB, IMAGE_REF_SCHEME, REF_REGISTRY_MAX, refRegistry, isImageRefUrl, bearsImage, ANNOUNCED_ACTION, NEXT_STEP;
|
|
262
268
|
var init_llm = __esm({
|
|
263
269
|
"src/llm.ts"() {
|
|
264
270
|
"use strict";
|
|
@@ -271,6 +277,8 @@ var init_llm = __esm({
|
|
|
271
277
|
refRegistry = /* @__PURE__ */ new Map();
|
|
272
278
|
isImageRefUrl = (url) => !!url && url.startsWith(IMAGE_REF_SCHEME);
|
|
273
279
|
bearsImage = (m) => messageHasImage(m.content) || toolImageRef(m.content) != null;
|
|
280
|
+
ANNOUNCED_ACTION = /^(?:also\s+|now\s+|then\s+)*(?:let me\b|i'?ll\b|i will\b|i'?m going to\b|(?:re-?)?(?:check|search|scan|read|verify|run|inspect|expand|look|examin|continu|proceed|try|fetch|load|open|test|build|grep|find|review|trac|dig|explor)\w*ing\b)/i;
|
|
281
|
+
NEXT_STEP = /^next (?:step|run|up)\b/i;
|
|
274
282
|
}
|
|
275
283
|
});
|
|
276
284
|
|
|
@@ -3614,9 +3622,12 @@ var AgentOptions = class {
|
|
|
3614
3622
|
traceDir;
|
|
3615
3623
|
/** Stream tokens from the model. Takes effect only with a `host.notify`; off => current (non-stream) behavior. */
|
|
3616
3624
|
stream = false;
|
|
3617
|
-
/** Closure reflex for delegated runtimes (cursor/claude-code): when such a turn
|
|
3618
|
-
* no assistant text after
|
|
3619
|
-
*
|
|
3625
|
+
/** Closure reflex for delegated runtimes (cursor/claude-code): when such a turn runs tools but never
|
|
3626
|
+
* closes — no assistant text after the last tool, or text that trails off on an action it announced
|
|
3627
|
+
* and never took ("Also checking for X.") — nudge ONE more step to ANSWER the user
|
|
3628
|
+
* from the tool results already in the transcript — so the turn delivers a reply instead of trailing off
|
|
3629
|
+
* mid-narration. Deliberately not a "summarize what you did" nudge: that produced process reports and
|
|
3630
|
+
* permission-asking instead of answers (see the nudge text in runLoop).
|
|
3620
3631
|
* Fires at most once per run and only for delegated runtimes (native turns never emit the trigger). */
|
|
3621
3632
|
closeDelegatedTurns = true;
|
|
3622
3633
|
/** Fold the dropped middle of an over-long transcript into a synthetic summary (edge-safe, no LLM). Off => drop-oldest. */
|
|
@@ -4116,10 +4127,13 @@ var Agent = class _Agent {
|
|
|
4116
4127
|
}
|
|
4117
4128
|
if (toolCalls.length === 0) {
|
|
4118
4129
|
if (this.drainInjections()) continue;
|
|
4119
|
-
if (o.closeDelegatedTurns && res.
|
|
4130
|
+
if (o.closeDelegatedTurns && res.endedWithoutClosing && !closureNudged && steps < o.maxSteps) {
|
|
4120
4131
|
closureNudged = true;
|
|
4121
|
-
log6.verbose("delegated turn went silent after a tool \u2014 nudging a closing
|
|
4122
|
-
this.transcript.push({
|
|
4132
|
+
log6.verbose("delegated turn went silent after a tool \u2014 nudging a closing answer");
|
|
4133
|
+
this.transcript.push({
|
|
4134
|
+
role: "user",
|
|
4135
|
+
content: "You ran tools but did not reply. Answer the user now using the tool results above; if a tool failed, say so plainly. Do NOT re-run those tools, do NOT narrate what you did, and do NOT ask for permission to continue."
|
|
4136
|
+
});
|
|
4123
4137
|
continue;
|
|
4124
4138
|
}
|
|
4125
4139
|
log6.verbose(`completed in ${steps} step(s)`);
|
|
@@ -4220,7 +4234,8 @@ var Agent = class _Agent {
|
|
|
4220
4234
|
let usage;
|
|
4221
4235
|
const delegated = /* @__PURE__ */ new Map();
|
|
4222
4236
|
const delegatedOrder = [];
|
|
4223
|
-
let
|
|
4237
|
+
let sawTool = false;
|
|
4238
|
+
let trailing = "";
|
|
4224
4239
|
for await (const chunk of stream) {
|
|
4225
4240
|
poke?.();
|
|
4226
4241
|
if (this.options.signal?.aborted) break;
|
|
@@ -4240,11 +4255,12 @@ var Agent = class _Agent {
|
|
|
4240
4255
|
if (a.output !== void 0) prev.output = a.output;
|
|
4241
4256
|
prev.status = a.status;
|
|
4242
4257
|
}
|
|
4243
|
-
|
|
4258
|
+
sawTool = true;
|
|
4259
|
+
trailing = "";
|
|
4244
4260
|
}
|
|
4245
4261
|
if (chunk.content) {
|
|
4246
4262
|
content += chunk.content;
|
|
4247
|
-
|
|
4263
|
+
trailing += chunk.content;
|
|
4248
4264
|
this.options.host.notify({ kind: "text_delta", message: chunk.content });
|
|
4249
4265
|
}
|
|
4250
4266
|
if (chunk.finishReason) finishReason = chunk.finishReason;
|
|
@@ -4252,7 +4268,8 @@ var Agent = class _Agent {
|
|
|
4252
4268
|
if (chunk.usage) usage = chunk.usage;
|
|
4253
4269
|
}
|
|
4254
4270
|
const delegatedTools = delegatedOrder.map((k) => delegated.get(k));
|
|
4255
|
-
|
|
4271
|
+
const endedWithoutClosing = sawTool && (!trailing.trim() || endsOnAnnouncedAction(trailing));
|
|
4272
|
+
return { content, ...finishReason ? { finishReason } : {}, ...toolCalls ? { toolCalls } : {}, ...usage ? { usage } : {}, ...delegatedTools.length ? { delegatedTools } : {}, ...endedWithoutClosing ? { endedWithoutClosing: true } : {} };
|
|
4256
4273
|
}
|
|
4257
4274
|
async dispatch(tc) {
|
|
4258
4275
|
const tool = this.activeTools.find((t) => t.name === tc.function.name);
|
|
@@ -9033,7 +9050,8 @@ The filesystem root '/' is the real machine root \u2014 you have full filesystem
|
|
|
9033
9050
|
const list = [...names];
|
|
9034
9051
|
return `You are agentx (an agent runtime) \u2014 NOT Claude Code or Claude Desktop, which are separate agents with their own config. Your MCP servers are configured in .agent/settings.json or .agent/config.* (this project's .agent/ or ~/.agent/), and their tools are already in your tool list as \`mcp__<server>__<tool>\`.${list.length ? ` Configured MCP servers: ${list.join(", ")}.` : " No MCP servers are currently configured."} When asked which MCPs/tools you have, answer from your own tool list \u2014 never read Claude Code/Desktop config (e.g. ~/.claude.json, claude_desktop_config.json) to answer; those belong to a different agent.`;
|
|
9035
9052
|
})();
|
|
9036
|
-
const
|
|
9053
|
+
const closureNote = isDelegated ? "Never end your turn on an action you only announced. If you say you are about to search, read, check or run something, DO it in the same turn before you stop. Your last message must be the ANSWER \u2014 the result and what it means \u2014 or an explicit statement that you are blocked and why. Narration of what you are about to do is not an ending." : "";
|
|
9054
|
+
const extra = [o.appendSystemPrompt, envNote, cwdNote, shellNote, toneNote, mountNote, mcpNote, closureNote].filter(Boolean).join("\n\n");
|
|
9037
9055
|
const basePrompt = (() => {
|
|
9038
9056
|
let p = new AgentOptions().systemPrompt;
|
|
9039
9057
|
if (!virtual) p = p.replace("operating on a virtual filesystem", "operating on the host filesystem");
|
|
@@ -13611,9 +13629,8 @@ async function runTurn(agent, store, session, task, cp, cwd = process.cwd(), sen
|
|
|
13611
13629
|
const cost = turnCost(agent.options.model, res.usage);
|
|
13612
13630
|
const m = res.usageEstimated ? "~" : "";
|
|
13613
13631
|
const tok = res.usage?.totalTokens ? `${m}${(res.usage.totalTokens / 1e3).toFixed(1)}k tok \xB7 ${cost > 0 ? m + fmtUsd(cost) + " \xB7 " : ""}` : "";
|
|
13614
|
-
const lastUser = res.messages.map((m2) => m2.role).lastIndexOf("user");
|
|
13615
13632
|
agent.options.host?.takeToolCount?.();
|
|
13616
|
-
const tools = res.messages.slice(
|
|
13633
|
+
const tools = res.messages.slice(msgsBefore).filter((m2) => m2.role === "tool").length;
|
|
13617
13634
|
const ok = res.finishReason === "stop";
|
|
13618
13635
|
const shortId = session.meta.id.replace(/^\d{8}-/, "");
|
|
13619
13636
|
const didWork = agent.transcript.slice(msgsBefore).some((m2) => m2.role === "assistant" || m2.role === "tool");
|