agent.libx.js 0.94.18 → 0.94.20
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/README.md +1 -1
- package/dist/{Agent-COa80xYy.d.ts → Agent-DmsB5hzp.d.ts} +7 -2
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +98 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.js +50 -12
- package/dist/index.js.map +1 -1
- package/dist/{mcp-C5GuDinb.d.ts → mcp-D00OuccC.d.ts} +1 -1
- package/dist/mcp.client.d.ts +2 -2
- package/dist/{tools-GPWp7oXq.d.ts → tools-9AUK6SG2.d.ts} +4 -0
- package/dist/tools.shell.d.ts +1 -1
- package/dist/tools.shell.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { a as AgentOptions, H as Hooks, h as RunResult, A as Agent } from './Agent-
|
|
2
|
-
export { C as ChatFragment, D as DEFAULT_MUTATING, b as Decision, P as PermissionOptions, c as PermissionPolicy, d as PermissionRule, e as PreToolUseDecision, R as ReasoningEffort, f as RecordingHooks, g as RecordingLifecycle, T as ToolUse, i as ToolUseMeta, j as composeHooks, p as planMode, r as reasoningToChatFragment } from './Agent-
|
|
1
|
+
import { a as AgentOptions, H as Hooks, h as RunResult, A as Agent } from './Agent-DmsB5hzp.js';
|
|
2
|
+
export { C as ChatFragment, D as DEFAULT_MUTATING, b as Decision, P as PermissionOptions, c as PermissionPolicy, d as PermissionRule, e as PreToolUseDecision, R as ReasoningEffort, f as RecordingHooks, g as RecordingLifecycle, T as ToolUse, i as ToolUseMeta, j as composeHooks, p as planMode, r as reasoningToChatFragment } from './Agent-DmsB5hzp.js';
|
|
3
3
|
import { IFilesystem, FileMetadata } from '@livx.cc/wcli/core';
|
|
4
4
|
export { CommandExecutor, FileMetadata, IFilesystem, IndexedDbFilesystem, MemFilesystem, registerHeadlessCommands } from '@livx.cc/wcli/core';
|
|
5
5
|
import { BodDB } from '@bod.ee/db';
|
|
6
|
-
import { A as AgentTool, C as ChatLike, a as ChatOptions, b as ChatResponse, h as ToolCall, H as HostBridge, U as UserQuestion, e as MessageContent } from './tools-
|
|
7
|
-
export { c as ContentPart, d as HostEvent, M as Message, R as Role, S as SandboxJobRegistry, f as StreamChunk, T as TodoItem, g as Tool, i as ToolContext, j as bashTool, k as contentText, l as defaultTools, m as editTool, n as exitSessionTool, o as imagePart, p as makeContext, q as makeJobTools, r as readTool, t as toWireTools, s as todoWriteTool, u as toolRegistry, v as toolsByName } from './tools-
|
|
8
|
-
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-
|
|
6
|
+
import { A as AgentTool, C as ChatLike, a as ChatOptions, b as ChatResponse, h as ToolCall, H as HostBridge, U as UserQuestion, e as MessageContent } from './tools-9AUK6SG2.js';
|
|
7
|
+
export { c as ContentPart, d as HostEvent, M as Message, R as Role, S as SandboxJobRegistry, f as StreamChunk, T as TodoItem, g as Tool, i as ToolContext, j as bashTool, k as contentText, l as defaultTools, m as editTool, n as exitSessionTool, o as imagePart, p as makeContext, q as makeJobTools, r as readTool, t as toWireTools, s as todoWriteTool, u as toolRegistry, v as toolsByName } from './tools-9AUK6SG2.js';
|
|
8
|
+
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-D00OuccC.js';
|
|
9
9
|
import * as libx_js_src_modules_log from 'libx.js/src/modules/log';
|
|
10
10
|
export { log } from 'libx.js/src/modules/log';
|
|
11
11
|
|
|
@@ -590,6 +590,8 @@ interface SkillInfo {
|
|
|
590
590
|
* adds the catalog + a convenience tool. (Executable skills can be `bash`-exec'd: wcli
|
|
591
591
|
* runs JS files from the VFS as commands.)
|
|
592
592
|
*/
|
|
593
|
+
/** Scan `dir`(s) for `<dir>/<id>/SKILL.md` entries (first dir wins on duplicate ids). */
|
|
594
|
+
declare function scanSkills(fs: IFilesystem, dir: string | string[]): Promise<SkillInfo[]>;
|
|
593
595
|
declare function loadSkills(fs: IFilesystem, dir: string | string[], opts?: {
|
|
594
596
|
relevanceHint?: string;
|
|
595
597
|
max?: number;
|
|
@@ -644,6 +646,8 @@ declare function expandCommand(fs: IFilesystem, cmd: CommandInfo, args: string):
|
|
|
644
646
|
* VFS files. The template body is returned (user args appended, and `$ARGUMENTS`
|
|
645
647
|
* substituted if present) so the model can act on it. Mirrors loadSkills.
|
|
646
648
|
*/
|
|
649
|
+
/** Scan `dir`(s) for `<dir>/<name>.md` command templates (first dir wins on duplicate names). */
|
|
650
|
+
declare function scanCommands(fs: IFilesystem, dir: string | string[]): Promise<CommandInfo[]>;
|
|
647
651
|
declare function loadCommands(fs: IFilesystem, dir: string | string[], opts?: {
|
|
648
652
|
relevanceHint?: string;
|
|
649
653
|
max?: number;
|
|
@@ -1261,4 +1265,4 @@ declare class CartesiaTTS {
|
|
|
1261
1265
|
close(): void;
|
|
1262
1266
|
}
|
|
1263
1267
|
|
|
1264
|
-
export { Agent, type AgentDef, AgentOptions, AgentTool, type AskOptions, type Attempt, type AudioSink, type AudioSource, type AuthProvider, BodDbFilesystem, CartesiaTTS, CartesiaTTSOptions, ChatLike, ChatOptions, ChatResponse, type CommandInfo, ConsoleHostBridge, DEFAULT_DENY, DuplexAgent, DuplexAgentOptions, type DuplexTaskStatus, FakeAIClient, Hooks, HostBridge, JailOptions, JailedFilesystem, type LessonOptions, LessonOptionsDefaults, type LoadMemoryOpts, MEMORY_PROMPT, MessageContent, type Mount, MountFilesystem, NodeDiskFilesystem, OverlayFilesystem, type ReflectOptions, RunResult, SCRATCH_DIR, STT_SAMPLE_RATE, type ScheduledJob, type ScheduledJobSnapshot, Scheduler, type SchedulerOptions, Scratch, type ScratchOptions, ScriptedHostBridge, type SkillInfo, SonioxSTT, SonioxSTTOptions, type SttLike, TTS_SAMPLE_RATE, type TaskRecord, type TaskToolOptions, ToolCall, type ToolSpec, type Trigger, type TriggerCron, type TriggerInterval, type TriggerOneOff, type TtsLike, UserQuestion, VOICE_MEMORY_PROMPT, VOICE_SYSTEM_PROMPT, VoiceEngine, VoiceEngineOptions, type VoiceState, type WebFetchOptions, type WebSearchOptions, type WorkerTier, applyEditsTool, askUserQuestionTool, checkpointTool, checkpointTools, compileSynthesizedTool, cronMatches, decodeDdgUrl, diskAgentOptions, expandCommand, expandTemplate, forComponent, fullAgentOptions, globTool, grepTool, htmlToText, idfWeights, lessonCapture, loadAgents, loadCommands, loadInstructions, loadMemory, loadSkills, makeAskTool, makeScheduleTools, makeTaskBatchTool, makeTaskTool, makeWebFetchTool, makeWebSearchTool, mkdirp, multiEditTool, nextCronAfter, parseCron, parseDdgHtml, raceAttempts, reflectOnRun, relevanceScore, repoIndex, repoMapTool, resolveAuth, rollbackTool, sandboxAgentOptions, slugify, tokenize, toolCall, topByRelevance, validateToolCode, webFetchTool, webSearchTool, writeFact, writeTool };
|
|
1268
|
+
export { Agent, type AgentDef, AgentOptions, AgentTool, type AskOptions, type Attempt, type AudioSink, type AudioSource, type AuthProvider, BodDbFilesystem, CartesiaTTS, CartesiaTTSOptions, ChatLike, ChatOptions, ChatResponse, type CommandInfo, ConsoleHostBridge, DEFAULT_DENY, DuplexAgent, DuplexAgentOptions, type DuplexTaskStatus, FakeAIClient, Hooks, HostBridge, JailOptions, JailedFilesystem, type LessonOptions, LessonOptionsDefaults, type LoadMemoryOpts, MEMORY_PROMPT, MessageContent, type Mount, MountFilesystem, NodeDiskFilesystem, OverlayFilesystem, type ReflectOptions, RunResult, SCRATCH_DIR, STT_SAMPLE_RATE, type ScheduledJob, type ScheduledJobSnapshot, Scheduler, type SchedulerOptions, Scratch, type ScratchOptions, ScriptedHostBridge, type SkillInfo, SonioxSTT, SonioxSTTOptions, type SttLike, TTS_SAMPLE_RATE, type TaskRecord, type TaskToolOptions, ToolCall, type ToolSpec, type Trigger, type TriggerCron, type TriggerInterval, type TriggerOneOff, type TtsLike, UserQuestion, VOICE_MEMORY_PROMPT, VOICE_SYSTEM_PROMPT, VoiceEngine, VoiceEngineOptions, type VoiceState, type WebFetchOptions, type WebSearchOptions, type WorkerTier, applyEditsTool, askUserQuestionTool, checkpointTool, checkpointTools, compileSynthesizedTool, cronMatches, decodeDdgUrl, diskAgentOptions, expandCommand, expandTemplate, forComponent, fullAgentOptions, globTool, grepTool, htmlToText, idfWeights, lessonCapture, loadAgents, loadCommands, loadInstructions, loadMemory, loadSkills, makeAskTool, makeScheduleTools, makeTaskBatchTool, makeTaskTool, makeWebFetchTool, makeWebSearchTool, mkdirp, multiEditTool, nextCronAfter, parseCron, parseDdgHtml, raceAttempts, reflectOnRun, relevanceScore, repoIndex, repoMapTool, resolveAuth, rollbackTool, sandboxAgentOptions, scanCommands, scanSkills, slugify, tokenize, toolCall, topByRelevance, validateToolCode, webFetchTool, webSearchTool, writeFact, writeTool };
|
package/dist/index.js
CHANGED
|
@@ -1980,7 +1980,7 @@ function parseFrontmatter(md) {
|
|
|
1980
1980
|
const b = block || md.slice(0, 600);
|
|
1981
1981
|
return { name: grabField(b, "name"), description: grabField(b, "description") };
|
|
1982
1982
|
}
|
|
1983
|
-
async function
|
|
1983
|
+
async function scanSkills(fs, dir) {
|
|
1984
1984
|
const skills = [];
|
|
1985
1985
|
const seen = /* @__PURE__ */ new Set();
|
|
1986
1986
|
for (const d of Array.isArray(dir) ? dir : [dir]) {
|
|
@@ -1995,6 +1995,10 @@ async function loadSkills(fs, dir, opts = {}) {
|
|
|
1995
1995
|
}
|
|
1996
1996
|
}
|
|
1997
1997
|
}
|
|
1998
|
+
return skills;
|
|
1999
|
+
}
|
|
2000
|
+
async function loadSkills(fs, dir, opts = {}) {
|
|
2001
|
+
const skills = await scanSkills(fs, dir);
|
|
1998
2002
|
if (skills.length === 0) return { skills, catalog: "" };
|
|
1999
2003
|
const { kept, rest } = topByRelevance(skills, opts.relevanceHint ?? "", (s) => `${s.name} ${s.description}`, opts.max ?? MAX_CATALOG);
|
|
2000
2004
|
const catalog = "## Skills (load one before acting on a matching task)\n" + kept.map((s) => `- **${s.name}** \u2014 ${s.description} (\`${s.path}\`)`).join("\n") + (rest.length ? `
|
|
@@ -2004,8 +2008,13 @@ async function loadSkills(fs, dir, opts = {}) {
|
|
|
2004
2008
|
description: "Load a skill by name \u2014 returns its full instructions (SKILL.md). Use when a task matches a listed skill.",
|
|
2005
2009
|
parameters: { type: "object", required: ["name"], properties: { name: { type: "string" } } },
|
|
2006
2010
|
async run({ name }, ctx) {
|
|
2007
|
-
|
|
2008
|
-
if (!s)
|
|
2011
|
+
let s = skills.find((x) => x.name === name);
|
|
2012
|
+
if (!s) {
|
|
2013
|
+
const fresh = await scanSkills(ctx.fs, dir);
|
|
2014
|
+
s = fresh.find((x) => x.name === name);
|
|
2015
|
+
if (!s) return `Error: no skill named '${name}'. Available: ${fresh.map((x) => x.name).join(", ")}`;
|
|
2016
|
+
skills.push(s);
|
|
2017
|
+
}
|
|
2009
2018
|
return ctx.fs.readFile(s.path);
|
|
2010
2019
|
}
|
|
2011
2020
|
};
|
|
@@ -2046,7 +2055,7 @@ async function expandCommand(fs, cmd, args) {
|
|
|
2046
2055
|
const { body } = parseFrontmatter2(await fs.readFile(cmd.path));
|
|
2047
2056
|
return embedFiles(expandTemplate(body, args), fs);
|
|
2048
2057
|
}
|
|
2049
|
-
async function
|
|
2058
|
+
async function scanCommands(fs, dir) {
|
|
2050
2059
|
const commands = [];
|
|
2051
2060
|
const seen = /* @__PURE__ */ new Set();
|
|
2052
2061
|
for (const d of Array.isArray(dir) ? dir : [dir]) {
|
|
@@ -2061,6 +2070,10 @@ async function loadCommands(fs, dir, opts = {}) {
|
|
|
2061
2070
|
commands.push({ name, description: fm.description || "", path });
|
|
2062
2071
|
}
|
|
2063
2072
|
}
|
|
2073
|
+
return commands;
|
|
2074
|
+
}
|
|
2075
|
+
async function loadCommands(fs, dir, opts = {}) {
|
|
2076
|
+
const commands = await scanCommands(fs, dir);
|
|
2064
2077
|
if (commands.length === 0) return { commands, catalog: "" };
|
|
2065
2078
|
const { kept, rest } = topByRelevance(commands, opts.relevanceHint ?? "", (c) => `${c.name} ${c.description}`, opts.max ?? MAX_CATALOG2);
|
|
2066
2079
|
const catalog = "## Slash commands (reusable prompt templates)\n" + kept.map((c) => `- **/${c.name}** \u2014 ${c.description} (\`${c.path}\`)`).join("\n") + (rest.length ? `
|
|
@@ -2075,8 +2088,13 @@ async function loadCommands(fs, dir, opts = {}) {
|
|
|
2075
2088
|
},
|
|
2076
2089
|
async run({ name, args }, ctx) {
|
|
2077
2090
|
const slug2 = String(name ?? "").replace(/^\//, "");
|
|
2078
|
-
|
|
2079
|
-
if (!c)
|
|
2091
|
+
let c = commands.find((x) => x.name === slug2);
|
|
2092
|
+
if (!c) {
|
|
2093
|
+
const fresh = await scanCommands(ctx.fs, dir);
|
|
2094
|
+
c = fresh.find((x) => x.name === slug2);
|
|
2095
|
+
if (!c) return `Error: no command named '${slug2}'. Available: ${fresh.map((x) => x.name).join(", ")}`;
|
|
2096
|
+
commands.push(c);
|
|
2097
|
+
}
|
|
2080
2098
|
return expandCommand(ctx.fs, c, String(args ?? ""));
|
|
2081
2099
|
}
|
|
2082
2100
|
};
|
|
@@ -2586,9 +2604,10 @@ function planMode(opts) {
|
|
|
2586
2604
|
parameters: { type: "object", required: ["plan"], properties: { plan: { type: "string", description: "the concrete steps you will take" } } },
|
|
2587
2605
|
async run({ plan }, _ctx) {
|
|
2588
2606
|
if (opts?.host?.confirm) {
|
|
2589
|
-
const
|
|
2607
|
+
const confirm = opts.host.confirm(`Approve this plan?
|
|
2590
2608
|
|
|
2591
2609
|
${String(plan ?? "")}`);
|
|
2610
|
+
const ok = await (_ctx?.parkHuman ? _ctx.parkHuman(confirm) : confirm);
|
|
2592
2611
|
if (!ok) return "Plan not approved. Revise it and call ExitPlanMode again.";
|
|
2593
2612
|
}
|
|
2594
2613
|
approved = true;
|
|
@@ -2744,7 +2763,8 @@ var AgentOptions = class {
|
|
|
2744
2763
|
tools = defaultTools();
|
|
2745
2764
|
maxSteps = 25;
|
|
2746
2765
|
// --- automatic kill-switches (always on; protect the API budget against runaway loops/abuse) ---
|
|
2747
|
-
/** Hard ceiling on accumulated tokens (prompt+completion) across the run
|
|
2766
|
+
/** Hard ceiling on accumulated tokens (prompt+completion) across the run; cache READS count at 0.1×
|
|
2767
|
+
* (their real price) so a fat cached context doesn't trip the guard on healthy turns. 0 = unbounded. */
|
|
2748
2768
|
maxTokens = 2e5;
|
|
2749
2769
|
/** Wall-clock ceiling in ms for the whole run. 0 = unbounded. */
|
|
2750
2770
|
timeoutMs = 12e4;
|
|
@@ -2846,6 +2866,18 @@ var Agent = class _Agent {
|
|
|
2846
2866
|
// the assembled system prompt from the last prepare()
|
|
2847
2867
|
started = false;
|
|
2848
2868
|
// session-start lifecycle hook fires once per conversation
|
|
2869
|
+
parkedMs = 0;
|
|
2870
|
+
// cumulative time blocked on the HUMAN (permission/plan prompts) — excluded from the timeout
|
|
2871
|
+
/** Time a human-blocking await (a permission/plan prompt) and bank it in `parkedMs` so idle prompt
|
|
2872
|
+
* time never trips the wall-clock kill-switch. The agent did no work while parked on the user. */
|
|
2873
|
+
async park(p) {
|
|
2874
|
+
const t = Date.now();
|
|
2875
|
+
try {
|
|
2876
|
+
return await p;
|
|
2877
|
+
} finally {
|
|
2878
|
+
this.parkedMs += Date.now() - t;
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2849
2881
|
/** Force the next `send()`/`run()` to rebuild the system prompt, tools, plan-mode and permission hooks
|
|
2850
2882
|
* from `options` — apply mid-conversation changes to `planMode`/`permissions`/`model` etc. (prepare()
|
|
2851
2883
|
* is otherwise memoized per conversation). */
|
|
@@ -2874,6 +2906,7 @@ var Agent = class _Agent {
|
|
|
2874
2906
|
if (this.options.lintOnWrite) this.ctx.lint = checkSyntax;
|
|
2875
2907
|
this.ctx.ai = this.options.ai;
|
|
2876
2908
|
this.ctx.model = this.options.model;
|
|
2909
|
+
this.ctx.parkHuman = (p) => this.park(p);
|
|
2877
2910
|
if (this.options.backgroundJobs) this.ctx.jobs = new SandboxJobRegistry();
|
|
2878
2911
|
}
|
|
2879
2912
|
/**
|
|
@@ -3019,19 +3052,21 @@ var Agent = class _Agent {
|
|
|
3019
3052
|
const usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0 };
|
|
3020
3053
|
let usageEstimated = false;
|
|
3021
3054
|
const start = Date.now();
|
|
3055
|
+
this.parkedMs = 0;
|
|
3022
3056
|
let toolCallsTotal = 0;
|
|
3023
3057
|
let lastFp = "";
|
|
3024
3058
|
let repeats = 0;
|
|
3025
3059
|
const kill = (finishReason) => {
|
|
3026
|
-
log3.warn(`kill-switch: ${finishReason} (steps=${steps}, tokens=${usage.totalTokens}, ms=${Date.now() - start})`);
|
|
3060
|
+
log3.warn(`kill-switch: ${finishReason} (steps=${steps}, tokens=${usage.totalTokens}, budgetTokens=${Math.round(usage.totalTokens - 0.9 * usage.cacheReadTokens)}, ms=${Date.now() - start - this.parkedMs}${this.parkedMs ? ` +${this.parkedMs} parked` : ""})`);
|
|
3027
3061
|
this.ctx.jobs?.killAll();
|
|
3028
3062
|
return { text: lastAssistantText(this.transcript), steps, finishReason, messages: this.transcript, usage, usageEstimated };
|
|
3029
3063
|
};
|
|
3030
3064
|
while (true) {
|
|
3031
3065
|
if (o.signal?.aborted) return kill("aborted");
|
|
3032
3066
|
if (steps >= o.maxSteps) return kill("max_steps");
|
|
3033
|
-
if (o.timeoutMs && Date.now() - start >= o.timeoutMs) return kill("timeout");
|
|
3034
|
-
|
|
3067
|
+
if (o.timeoutMs && Date.now() - start - this.parkedMs >= o.timeoutMs) return kill("timeout");
|
|
3068
|
+
const budgetTokens = usage.totalTokens - 0.9 * usage.cacheReadTokens;
|
|
3069
|
+
if (o.maxTokens && budgetTokens >= o.maxTokens) return kill("budget");
|
|
3035
3070
|
steps++;
|
|
3036
3071
|
this.options.host?.notify?.({ kind: "turn_start", message: `step ${steps}` });
|
|
3037
3072
|
let res;
|
|
@@ -3166,7 +3201,7 @@ var Agent = class _Agent {
|
|
|
3166
3201
|
const hooks = this.activeHooks;
|
|
3167
3202
|
const call = { name: tc.function.name, args };
|
|
3168
3203
|
const meta = { id: tc.id };
|
|
3169
|
-
const decision = await hooks?.preToolUse?.(call, meta);
|
|
3204
|
+
const decision = await this.park(Promise.resolve(hooks?.preToolUse?.(call, meta)));
|
|
3170
3205
|
if (decision?.block) {
|
|
3171
3206
|
const blocked = `Blocked by hook: ${decision.reason ?? "no reason given"}`;
|
|
3172
3207
|
log3.debug(`${tc.function.name} -> ${blocked}`);
|
|
@@ -3208,6 +3243,7 @@ var Agent = class _Agent {
|
|
|
3208
3243
|
this.ctx.emit = void 0;
|
|
3209
3244
|
}
|
|
3210
3245
|
if (!threw) result = await this.maybeAutoTest(tc.function.name, result);
|
|
3246
|
+
if (images?.length && !result) result = `[${images.length} image${images.length > 1 ? "s" : ""} attached]`;
|
|
3211
3247
|
const cap = this.options.maxToolResultBytes ?? 0;
|
|
3212
3248
|
if (!threw && cap > 0 && result.length > cap) {
|
|
3213
3249
|
const info = { tool: tc.function.name, args };
|
|
@@ -5822,6 +5858,8 @@ export {
|
|
|
5822
5858
|
resolveAuth,
|
|
5823
5859
|
rollbackTool,
|
|
5824
5860
|
sandboxAgentOptions,
|
|
5861
|
+
scanCommands,
|
|
5862
|
+
scanSkills,
|
|
5825
5863
|
slugify,
|
|
5826
5864
|
toWireTools,
|
|
5827
5865
|
todoWriteTool,
|