@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/index.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { a as AgentOptions, H as Hooks, i as RunResult, A as Agent } from './Agent-qoEmC4ic.js';
2
- export { C as ChatFragment, b as CompactResult, D as DEFAULT_MUTATING, c as Decision, P as PermissionOptions, d as PermissionPolicy, e as PermissionRule, f as PreToolUseDecision, R as ReasoningEffort, g as RecordingHooks, h as RecordingLifecycle, T as ToolUse, j as ToolUseMeta, k as composeHooks, l as estimateTokens, p as planMode, r as reasoningToChatFragment } from './Agent-qoEmC4ic.js';
1
+ import { a as AgentOptions, H as Hooks, i as RunResult, A as Agent } from './Agent-USp7SIao.js';
2
+ export { C as ChatFragment, b as CompactResult, D as DEFAULT_MUTATING, c as Decision, P as PermissionOptions, d as PermissionPolicy, e as PermissionRule, f as PreToolUseDecision, R as ReasoningEffort, g as RecordingHooks, h as RecordingLifecycle, T as ToolUse, j as ToolUseMeta, k as composeHooks, l as estimateTokens, p as planMode, r as reasoningToChatFragment } from './Agent-USp7SIao.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, j as ToolCall, H as HostBridge, U as UserQuestion, g as MessageContent } from './tools-BZVppx-6.js';
8
- export { c as ContentPart, d as HostEvent, I as IMAGE_ELIDE_STUB, e as IMAGE_REF_SCHEME, f as ImageRef, M as Message, R as Role, S as SandboxJobRegistry, h as StreamChunk, T as TodoItem, i as Tool, k as ToolContext, l as bashTool, m as clearImageRefs, n as contentBytes, o as contentText, p as defaultTools, q as editTool, r as elideImages, s as elideInlineImages, t as elideStaleImages, u as exitSessionTool, v as expandImagesForSend, w as imagePart, x as imageRefPart, y as imageRefResult, z as makeContext, B as makeJobTools, D as messageHasImage, E as messageHasImageRef, F as messageHasInlineImage, G as mintImageRef, J as parseImageRef, K as readTool, L as remintImageRefs, N as sendBytes, O as sendBytesPer, P as toWireTools, Q as todoWriteTool, V as toolImageRef, W as toolRegistry, X as toolsByName } from './tools-BZVppx-6.js';
7
+ import { A as AgentTool, C as ChatLike, a as ChatOptions, b as ChatResponse, j as ToolCall, H as HostBridge, U as UserQuestion, g as MessageContent } from './tools-Byyh_bae.js';
8
+ export { c as ContentPart, d as HostEvent, I as IMAGE_ELIDE_STUB, e as IMAGE_REF_SCHEME, f as ImageRef, M as Message, R as Role, S as SandboxJobRegistry, h as StreamChunk, T as TodoItem, i as Tool, k as ToolContext, l as bashTool, m as clearImageRefs, n as contentBytes, o as contentText, p as defaultTools, q as editTool, r as elideImages, s as elideInlineImages, t as elideStaleImages, u as exitSessionTool, v as expandImagesForSend, w as imagePart, x as imageRefPart, y as imageRefResult, z as makeContext, B as makeJobTools, D as messageHasImage, E as messageHasImageRef, F as messageHasInlineImage, G as mintImageRef, J as parseImageRef, K as readTool, L as remintImageRefs, N as sendBytes, O as sendBytesPer, P as toWireTools, Q as todoWriteTool, V as toolImageRef, W as toolRegistry, X as toolsByName } from './tools-Byyh_bae.js';
9
9
  import { SpokenSplitter } from '@bod.ee/voice';
10
10
  export { AudioSink, AudioSource, AuthProvider, CartesiaTTS, CartesiaTTSOptions, STT_SAMPLE_RATE, SonioxSTT, SonioxSTTOptions, SttLike, TTS_SAMPLE_RATE, TtsLike, VoiceEngine, VoiceEngineOptions, VoiceState, resolveAuth } from '@bod.ee/voice';
11
- 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-Cnq0pS95.js';
11
+ 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-Bd19NiCL.js';
12
12
  import * as libx_js_src_modules_log from 'libx.js/src/modules/log';
13
13
  export { log } from 'libx.js/src/modules/log';
14
14
 
package/dist/index.js CHANGED
@@ -260,7 +260,13 @@ function stripContent(content, stub) {
260
260
  });
261
261
  return changed ? out : content;
262
262
  }
263
- var log2, p_sep, IMAGE_ELIDE_STUB, IMAGE_REF_SCHEME, REF_REGISTRY_MAX, refRegistry, isImageRefUrl, bearsImage;
263
+ function endsOnAnnouncedAction(text) {
264
+ const sentences = text.split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter(Boolean);
265
+ const last = sentences[sentences.length - 1];
266
+ if (!last || NEXT_STEP.test(last)) return false;
267
+ return ANNOUNCED_ACTION.test(last);
268
+ }
269
+ var log2, p_sep, IMAGE_ELIDE_STUB, IMAGE_REF_SCHEME, REF_REGISTRY_MAX, refRegistry, isImageRefUrl, bearsImage, ANNOUNCED_ACTION, NEXT_STEP;
264
270
  var init_llm = __esm({
265
271
  "src/llm.ts"() {
266
272
  "use strict";
@@ -273,6 +279,8 @@ var init_llm = __esm({
273
279
  refRegistry = /* @__PURE__ */ new Map();
274
280
  isImageRefUrl = (url) => !!url && url.startsWith(IMAGE_REF_SCHEME);
275
281
  bearsImage = (m) => messageHasImage(m.content) || toolImageRef(m.content) != null;
282
+ 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;
283
+ NEXT_STEP = /^next (?:step|run|up)\b/i;
276
284
  }
277
285
  });
278
286
 
@@ -3579,9 +3587,12 @@ var AgentOptions = class {
3579
3587
  traceDir;
3580
3588
  /** Stream tokens from the model. Takes effect only with a `host.notify`; off => current (non-stream) behavior. */
3581
3589
  stream = false;
3582
- /** Closure reflex for delegated runtimes (cursor/claude-code): when such a turn ends on a tool call with
3583
- * no assistant text after it (the runtime went silent post-work), nudge ONE more step for a brief summary
3584
- * of what changed + what's pending — so the turn delivers a wrap-up instead of trailing off mid-narration.
3590
+ /** Closure reflex for delegated runtimes (cursor/claude-code): when such a turn runs tools but never
3591
+ * closes — no assistant text after the last tool, or text that trails off on an action it announced
3592
+ * and never took ("Also checking for X.") — nudge ONE more step to ANSWER the user
3593
+ * from the tool results already in the transcript — so the turn delivers a reply instead of trailing off
3594
+ * mid-narration. Deliberately not a "summarize what you did" nudge: that produced process reports and
3595
+ * permission-asking instead of answers (see the nudge text in runLoop).
3585
3596
  * Fires at most once per run and only for delegated runtimes (native turns never emit the trigger). */
3586
3597
  closeDelegatedTurns = true;
3587
3598
  /** Fold the dropped middle of an over-long transcript into a synthetic summary (edge-safe, no LLM). Off => drop-oldest. */
@@ -4081,10 +4092,13 @@ var Agent = class _Agent {
4081
4092
  }
4082
4093
  if (toolCalls.length === 0) {
4083
4094
  if (this.drainInjections()) continue;
4084
- if (o.closeDelegatedTurns && res.endedOnToolNoText && !closureNudged && steps < o.maxSteps) {
4095
+ if (o.closeDelegatedTurns && res.endedWithoutClosing && !closureNudged && steps < o.maxSteps) {
4085
4096
  closureNudged = true;
4086
- log6.verbose("delegated turn went silent after a tool \u2014 nudging a closing summary");
4087
- this.transcript.push({ role: "user", content: "Summarize what you did this turn and what (if anything) still needs doing. Be concise." });
4097
+ log6.verbose("delegated turn went silent after a tool \u2014 nudging a closing answer");
4098
+ this.transcript.push({
4099
+ role: "user",
4100
+ 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."
4101
+ });
4088
4102
  continue;
4089
4103
  }
4090
4104
  log6.verbose(`completed in ${steps} step(s)`);
@@ -4185,7 +4199,8 @@ var Agent = class _Agent {
4185
4199
  let usage;
4186
4200
  const delegated = /* @__PURE__ */ new Map();
4187
4201
  const delegatedOrder = [];
4188
- let endedOnToolNoText = false;
4202
+ let sawTool = false;
4203
+ let trailing = "";
4189
4204
  for await (const chunk of stream) {
4190
4205
  poke?.();
4191
4206
  if (this.options.signal?.aborted) break;
@@ -4205,11 +4220,12 @@ var Agent = class _Agent {
4205
4220
  if (a.output !== void 0) prev.output = a.output;
4206
4221
  prev.status = a.status;
4207
4222
  }
4208
- endedOnToolNoText = true;
4223
+ sawTool = true;
4224
+ trailing = "";
4209
4225
  }
4210
4226
  if (chunk.content) {
4211
4227
  content += chunk.content;
4212
- if (chunk.content.trim()) endedOnToolNoText = false;
4228
+ trailing += chunk.content;
4213
4229
  this.options.host.notify({ kind: "text_delta", message: chunk.content });
4214
4230
  }
4215
4231
  if (chunk.finishReason) finishReason = chunk.finishReason;
@@ -4217,7 +4233,8 @@ var Agent = class _Agent {
4217
4233
  if (chunk.usage) usage = chunk.usage;
4218
4234
  }
4219
4235
  const delegatedTools = delegatedOrder.map((k) => delegated.get(k));
4220
- return { content, ...finishReason ? { finishReason } : {}, ...toolCalls ? { toolCalls } : {}, ...usage ? { usage } : {}, ...delegatedTools.length ? { delegatedTools } : {}, ...endedOnToolNoText ? { endedOnToolNoText: true } : {} };
4236
+ const endedWithoutClosing = sawTool && (!trailing.trim() || endsOnAnnouncedAction(trailing));
4237
+ return { content, ...finishReason ? { finishReason } : {}, ...toolCalls ? { toolCalls } : {}, ...usage ? { usage } : {}, ...delegatedTools.length ? { delegatedTools } : {}, ...endedWithoutClosing ? { endedWithoutClosing: true } : {} };
4221
4238
  }
4222
4239
  async dispatch(tc) {
4223
4240
  const tool = this.activeTools.find((t) => t.name === tc.function.name);