zidane 5.5.0 → 5.5.4
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-CvImMxMQ.d.ts → agent-CMAklak7.d.ts} +98 -3
- package/dist/agent-CMAklak7.d.ts.map +1 -0
- package/dist/chat.d.ts +283 -5
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +203 -3
- package/dist/chat.js.map +1 -0
- package/dist/{contexts-DhmMlT2W.js → contexts-BOtMvzli.js} +1 -1
- package/dist/{contexts-DhmMlT2W.js.map → contexts-BOtMvzli.js.map} +1 -1
- package/dist/contexts.js +1 -1
- package/dist/{errors-CDwtPIMX.js → errors-C5VSakmT.js} +1 -1
- package/dist/{errors-CDwtPIMX.js.map → errors-C5VSakmT.js.map} +1 -1
- package/dist/{index-B0uc2C5x.d.ts → index-CF5QwBiz.d.ts} +2 -2
- package/dist/{index-B0uc2C5x.d.ts.map → index-CF5QwBiz.d.ts.map} +1 -1
- package/dist/{index-CtXksgqb.d.ts → index-kroGomhj.d.ts} +2 -2
- package/dist/index-kroGomhj.d.ts.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +12 -12
- package/dist/{interpolate-BaaKaKzN.js → interpolate-Cvjy8gpk.js} +2 -2
- package/dist/{interpolate-BaaKaKzN.js.map → interpolate-Cvjy8gpk.js.map} +1 -1
- package/dist/{login-iTy-0wYz.js → login-B_kfoGMP.js} +4 -4
- package/dist/{login-iTy-0wYz.js.map → login-B_kfoGMP.js.map} +1 -1
- package/dist/{mcp-CNUbvbsy.js → mcp-BE43Viwi.js} +3 -3
- package/dist/{mcp-CNUbvbsy.js.map → mcp-BE43Viwi.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +1 -1
- package/dist/{messages-fTR19Ga6.js → messages-BBWakTN6.js} +2 -2
- package/dist/{messages-fTR19Ga6.js.map → messages-BBWakTN6.js.map} +1 -1
- package/dist/{presets-h6UWhghO.js → presets-BDvBZuYI.js} +2 -2
- package/dist/{presets-h6UWhghO.js.map → presets-BDvBZuYI.js.map} +1 -1
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +1 -1
- package/dist/{providers-G0VBZK9j.js → providers-CsUyN_FJ.js} +3 -3
- package/dist/{providers-G0VBZK9j.js.map → providers-CsUyN_FJ.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +2 -2
- package/dist/restate.d.ts +148 -0
- package/dist/restate.d.ts.map +1 -0
- package/dist/restate.js +152 -0
- package/dist/restate.js.map +1 -0
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session/sqlite.js +1 -1
- package/dist/{session-CbkiJDlH.js → session-DzfRacU_.js} +2 -2
- package/dist/{session-CbkiJDlH.js.map → session-DzfRacU_.js.map} +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js +1 -1
- package/dist/{stats-DgOvY7wd.js → stats-Lc3zL3RM.js} +1 -1
- package/dist/{stats-DgOvY7wd.js.map → stats-Lc3zL3RM.js.map} +1 -1
- package/dist/{tools-D_icxa-V.js → tools-Bbd0Ivwn.js} +136 -73
- package/dist/tools-Bbd0Ivwn.js.map +1 -0
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-3FFw2xuk.d.ts → transcript-anchors-C79AszkC.d.ts} +155 -66
- package/dist/transcript-anchors-C79AszkC.d.ts.map +1 -0
- package/dist/tui.d.ts +2 -2
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +37 -16
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-CtgBlBHn.js → turn-operations-CGf7wWF0.js} +851 -16
- package/dist/turn-operations-CGf7wWF0.js.map +1 -0
- package/dist/{types-IcokUOyC.js → types-oKPBdCmL.js} +7 -2
- package/dist/types-oKPBdCmL.js.map +1 -0
- package/dist/types.d.ts +3 -3
- package/dist/types.js +4 -4
- package/docs/TUI.md +72 -1
- package/package.json +10 -1
- package/dist/agent-CvImMxMQ.d.ts.map +0 -1
- package/dist/index-CtXksgqb.d.ts.map +0 -1
- package/dist/tools-D_icxa-V.js.map +0 -1
- package/dist/transcript-anchors-3FFw2xuk.d.ts.map +0 -1
- package/dist/turn-operations-CtgBlBHn.js.map +0 -1
- package/dist/types-IcokUOyC.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats-
|
|
1
|
+
{"version":3,"file":"stats-Lc3zL3RM.js","names":[],"sources":["../src/stats.ts"],"sourcesContent":["/**\n * Pure derivations over `AgentStats`.\n *\n * Both helpers are tree-shakeable — import only what you need. They never\n * touch agent state, never do I/O, and always operate on the recursive\n * `AgentStats` tree returned by `agent.run()`.\n */\n\nimport type { AgentStats, TurnUsage } from './types'\n\n/**\n * Per-model usage rollup produced by {@link statsByModel}.\n *\n * `turns` counts the number of `TurnUsage` entries attributed to the model\n * across the whole tree (parent loop + every recursively-spawned child).\n * Cache and cost numbers are summed from the same set of turns.\n */\nexport interface ModelUsage {\n input: number\n output: number\n cost: number\n cacheRead: number\n cacheCreation: number\n turns: number\n}\n\n/**\n * Common shape for token-usage helpers. Mirrors `AgentStats`'s cumulative\n * fields. Callers working with `TurnUsage` / `SessionRun.totalUsage`\n * (`input` / `output` / `cacheRead` / `cacheCreation`) map their fields in\n * at the call site — we don't accept both shapes here because\n * `AgentStats.output` is a structured-output payload (`Record<string,\n * unknown>`), not a token count, so the field name `output` is ambiguous.\n */\nexport interface TokenUsageLike {\n totalIn?: number\n totalOut?: number\n totalCacheRead?: number\n totalCacheCreation?: number\n}\n\n/**\n * Clamp to a non-negative finite integer. Used to defend display logic\n * against providers that report `NaN`, `Infinity`, or negatives in their\n * usage payloads — the rendered string stays readable instead of leaking\n * `NaN`s into the footer / spawn-end markers.\n */\nfunction safeNumber(n: number | undefined): number {\n if (typeof n !== 'number' || !Number.isFinite(n) || n < 0)\n return 0\n return n\n}\n\nfunction normalize(stats: TokenUsageLike): {\n input: number\n output: number\n cacheRead: number\n cacheCreation: number\n} {\n return {\n input: safeNumber(stats.totalIn),\n output: safeNumber(stats.totalOut),\n cacheRead: safeNumber(stats.totalCacheRead),\n cacheCreation: safeNumber(stats.totalCacheCreation),\n }\n}\n\n/**\n * Sum of `input + cacheRead + cacheCreation` — i.e. the number of tokens the\n * model actually saw, regardless of how they were billed.\n *\n * With provider prompt caching (Anthropic, OpenRouter→Anthropic, Gemini),\n * `AgentStats.totalIn` only counts **new uncached** tokens per turn; the\n * bulk of an N-turn run's context lives in `totalCacheRead`, plus a smaller\n * `totalCacheCreation` chunk for whichever turns added new breakpoints.\n * Showing only `totalIn` in a per-run summary makes long subagent runs look\n * suspiciously cheap (e.g. \"13 in\" for 8 turns over a large repo).\n *\n * `TurnUsage` / `SessionRun.totalUsage` callers map their fields to the\n * `total*` names at the call site (see {@link TokenUsageLike}).\n */\nexport function effectiveInputTokens(stats: TokenUsageLike): number {\n const { input, cacheRead, cacheCreation } = normalize(stats)\n return input + cacheRead + cacheCreation\n}\n\n/**\n * Render a one-line token summary suitable for spawn-end markers, child\n * tool-result text, and any other per-run \"what did this cost?\" surface.\n *\n * `in 52413 (cache 50000) / 4075 out`\n *\n * The `in` total includes cached reads and cache-creation tokens (see\n * {@link effectiveInputTokens}); the `(cache N)` parenthetical breaks out\n * the cached portion so the user can tell at a glance how much was reused\n * vs new. The parenthetical is omitted when its value is zero, so\n * non-caching providers and brand-new runs read simply as `in N / M out`.\n *\n * Output-side caching is not a concept any current provider exposes —\n * Anthropic's `cacheRead` / `cacheCreation` are both input-billed. If a\n * future provider ships an output cache, extend `TokenUsageLike` with\n * output-cache fields and add a parallel `(cache N)` slot on the `out`\n * side here; today the right side is always plain `${N} out`.\n */\nexport function formatTokenUsage(stats: TokenUsageLike): string {\n const { input, output, cacheRead, cacheCreation } = normalize(stats)\n const inputTotal = input + cacheRead + cacheCreation\n const inputCache = cacheRead + cacheCreation\n const inPart = inputCache > 0\n ? `in ${inputTotal} (cache ${inputCache})`\n : `in ${inputTotal}`\n return `${inPart} / ${output} out`\n}\n\n/**\n * Depth-first walk over the stats tree, returning every `TurnUsage` entry\n * — parent loop first, then each child subtree in completion order.\n *\n * Closes the cache-token aggregation gap: `TurnUsage.cacheRead` /\n * `cacheCreation` live only on per-turn entries, and the top-level\n * `AgentStats` deliberately doesn't carry cumulative forms (one source of\n * truth, no risk of drift). Anything that needs a tree-wide sum walks\n * through this.\n */\nexport function flattenTurns(stats: AgentStats): TurnUsage[] {\n const out: TurnUsage[] = []\n collectTurns(stats, out)\n return out\n}\n\nfunction collectTurns(stats: AgentStats, out: TurnUsage[]): void {\n if (stats.turnUsage)\n out.push(...stats.turnUsage)\n if (stats.children) {\n for (const child of stats.children)\n collectTurns(child.stats, out)\n }\n}\n\n/**\n * Group cumulative usage by `TurnUsage.modelId`. Each entry sums the input,\n * output, cache, cost, and turn-count across every turn the tree attributed\n * to that model — naturally handling cross-model runs (vision-fallback,\n * model-shifted subagents, mixed-provider workflows).\n *\n * Turns missing `modelId` (mock providers, providers that don't echo a model\n * id) are bucketed under the literal string `'(unknown)'`.\n */\nexport function statsByModel(stats: AgentStats): Map<string, ModelUsage> {\n const out = new Map<string, ModelUsage>()\n for (const turn of flattenTurns(stats)) {\n const key = turn.modelId ?? '(unknown)'\n let entry = out.get(key)\n if (!entry) {\n entry = { input: 0, output: 0, cost: 0, cacheRead: 0, cacheCreation: 0, turns: 0 }\n out.set(key, entry)\n }\n entry.input += turn.input\n entry.output += turn.output\n entry.cost += turn.cost ?? 0\n entry.cacheRead += turn.cacheRead ?? 0\n entry.cacheCreation += turn.cacheCreation ?? 0\n entry.turns += 1\n }\n return out\n}\n"],"mappings":";;;;;;;AA+CA,SAAS,WAAW,GAA+B;CACjD,IAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,EAAE,IAAI,IAAI,GACtD,OAAO;CACT,OAAO;;AAGT,SAAS,UAAU,OAKjB;CACA,OAAO;EACL,OAAO,WAAW,MAAM,QAAQ;EAChC,QAAQ,WAAW,MAAM,SAAS;EAClC,WAAW,WAAW,MAAM,eAAe;EAC3C,eAAe,WAAW,MAAM,mBAAmB;EACpD;;;;;;;;;;;;;;;;;;;;AAwCH,SAAgB,iBAAiB,OAA+B;CAC9D,MAAM,EAAE,OAAO,QAAQ,WAAW,kBAAkB,UAAU,MAAM;CACpE,MAAM,aAAa,QAAQ,YAAY;CACvC,MAAM,aAAa,YAAY;CAI/B,OAAO,GAHQ,aAAa,IACxB,MAAM,WAAW,UAAU,WAAW,KACtC,MAAM,aACO,KAAK,OAAO;;;;;;;;;;;;AAa/B,SAAgB,aAAa,OAAgC;CAC3D,MAAM,MAAmB,EAAE;CAC3B,aAAa,OAAO,IAAI;CACxB,OAAO;;AAGT,SAAS,aAAa,OAAmB,KAAwB;CAC/D,IAAI,MAAM,WACR,IAAI,KAAK,GAAG,MAAM,UAAU;CAC9B,IAAI,MAAM,UACR,KAAK,MAAM,SAAS,MAAM,UACxB,aAAa,MAAM,OAAO,IAAI;;;;;;;;;;;AAapC,SAAgB,aAAa,OAA4C;CACvE,MAAM,sBAAM,IAAI,KAAyB;CACzC,KAAK,MAAM,QAAQ,aAAa,MAAM,EAAE;EACtC,MAAM,MAAM,KAAK,WAAW;EAC5B,IAAI,QAAQ,IAAI,IAAI,IAAI;EACxB,IAAI,CAAC,OAAO;GACV,QAAQ;IAAE,OAAO;IAAG,QAAQ;IAAG,MAAM;IAAG,WAAW;IAAG,eAAe;IAAG,OAAO;IAAG;GAClF,IAAI,IAAI,KAAK,MAAM;;EAErB,MAAM,SAAS,KAAK;EACpB,MAAM,UAAU,KAAK;EACrB,MAAM,QAAQ,KAAK,QAAQ;EAC3B,MAAM,aAAa,KAAK,aAAa;EACrC,MAAM,iBAAiB,KAAK,iBAAiB;EAC7C,MAAM,SAAS;;CAEjB,OAAO"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { n as createProcessContext } from "./contexts-
|
|
2
|
-
import { a as AgentToolPairingError, l as toTypedError, r as AgentProviderError, s as errorMessage, t as AgentAbortedError } from "./errors-
|
|
3
|
-
import {
|
|
4
|
-
import { a as detectTurnInterruption, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureToolResultPairing, s as filterUnresolvedToolUses } from "./messages-
|
|
5
|
-
import { t as connectMcpServers } from "./mcp-
|
|
6
|
-
import { _ as validateResourcePath, b as createSkillActivationState, d as escapeXml, n as resolveSkills, p as installAllowedToolsGate, t as interpolateShellCommands, u as buildCatalog } from "./interpolate-
|
|
7
|
-
import { n as formatTokenUsage, t as flattenTurns } from "./stats-
|
|
1
|
+
import { n as createProcessContext } from "./contexts-BOtMvzli.js";
|
|
2
|
+
import { a as AgentToolPairingError, l as toTypedError, r as AgentProviderError, s as errorMessage, t as AgentAbortedError } from "./errors-C5VSakmT.js";
|
|
3
|
+
import { n as toolOutputByteLength, t as DEFAULT_AGENT_CLOCK } from "./types-oKPBdCmL.js";
|
|
4
|
+
import { a as detectTurnInterruption, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureToolResultPairing, s as filterUnresolvedToolUses } from "./messages-BBWakTN6.js";
|
|
5
|
+
import { t as connectMcpServers } from "./mcp-BE43Viwi.js";
|
|
6
|
+
import { _ as validateResourcePath, b as createSkillActivationState, d as escapeXml, n as resolveSkills, p as installAllowedToolsGate, t as interpolateShellCommands, u as buildCatalog } from "./interpolate-Cvjy8gpk.js";
|
|
7
|
+
import { n as formatTokenUsage, t as flattenTurns } from "./stats-Lc3zL3RM.js";
|
|
8
8
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
9
9
|
import { createHooks } from "hookable";
|
|
10
10
|
import { homedir } from "node:os";
|
|
@@ -1376,7 +1376,7 @@ async function runLoop(ctx) {
|
|
|
1376
1376
|
runId: ctx.runId,
|
|
1377
1377
|
role: steerUserMsg.role,
|
|
1378
1378
|
content: steerUserMsg.content,
|
|
1379
|
-
createdAt:
|
|
1379
|
+
createdAt: await ctx.clock.now()
|
|
1380
1380
|
});
|
|
1381
1381
|
continue;
|
|
1382
1382
|
}
|
|
@@ -1390,7 +1390,7 @@ async function runLoop(ctx) {
|
|
|
1390
1390
|
runId: ctx.runId,
|
|
1391
1391
|
role: followUpMsg.role,
|
|
1392
1392
|
content: followUpMsg.content,
|
|
1393
|
-
createdAt:
|
|
1393
|
+
createdAt: await ctx.clock.now()
|
|
1394
1394
|
});
|
|
1395
1395
|
continue;
|
|
1396
1396
|
}
|
|
@@ -1604,7 +1604,7 @@ async function executeTurn(ctx, turn, priorUsage) {
|
|
|
1604
1604
|
role: "assistant",
|
|
1605
1605
|
content: errorContent,
|
|
1606
1606
|
usage: errorUsage,
|
|
1607
|
-
createdAt:
|
|
1607
|
+
createdAt: await ctx.clock.now()
|
|
1608
1608
|
};
|
|
1609
1609
|
ctx.turns.push(errorTurn);
|
|
1610
1610
|
if (!wasAborted) {
|
|
@@ -1648,7 +1648,7 @@ async function executeTurn(ctx, turn, priorUsage) {
|
|
|
1648
1648
|
text: currentText
|
|
1649
1649
|
}] : canonicalContent,
|
|
1650
1650
|
usage: result.usage,
|
|
1651
|
-
createdAt:
|
|
1651
|
+
createdAt: await ctx.clock.now()
|
|
1652
1652
|
};
|
|
1653
1653
|
ctx.turns.push(assistantTurn);
|
|
1654
1654
|
const turnCounts = {};
|
|
@@ -1705,7 +1705,7 @@ async function executeTurn(ctx, turn, priorUsage) {
|
|
|
1705
1705
|
role: "assistant",
|
|
1706
1706
|
content: schemaResult.assistantMessage.content,
|
|
1707
1707
|
usage: schemaResult.usage,
|
|
1708
|
-
createdAt:
|
|
1708
|
+
createdAt: await ctx.clock.now()
|
|
1709
1709
|
};
|
|
1710
1710
|
ctx.turns.push(schemaTurn);
|
|
1711
1711
|
return {
|
|
@@ -1731,7 +1731,7 @@ async function executeTurn(ctx, turn, priorUsage) {
|
|
|
1731
1731
|
runId: ctx.runId,
|
|
1732
1732
|
role: continueMsg.role,
|
|
1733
1733
|
content: continueMsg.content,
|
|
1734
|
-
createdAt:
|
|
1734
|
+
createdAt: await ctx.clock.now()
|
|
1735
1735
|
});
|
|
1736
1736
|
return {
|
|
1737
1737
|
ended: false,
|
|
@@ -1746,7 +1746,7 @@ async function executeTurn(ctx, turn, priorUsage) {
|
|
|
1746
1746
|
runId: ctx.runId,
|
|
1747
1747
|
role: toolResultMsg.role,
|
|
1748
1748
|
content: toolResultMsg.content,
|
|
1749
|
-
createdAt:
|
|
1749
|
+
createdAt: await ctx.clock.now()
|
|
1750
1750
|
};
|
|
1751
1751
|
ctx.turns.push(toolResultsTurn);
|
|
1752
1752
|
await ctx.hooks.callHook("tool-results:after", {
|
|
@@ -1756,7 +1756,15 @@ async function executeTurn(ctx, turn, priorUsage) {
|
|
|
1756
1756
|
results: toolResults
|
|
1757
1757
|
});
|
|
1758
1758
|
if (typeof ctx.toolOutputBudget === "number" && ctx.toolOutputBudget > 0) {
|
|
1759
|
-
const
|
|
1759
|
+
const excludeSet = ctx.toolOutputBudgetExcludeTools && ctx.toolOutputBudgetExcludeTools.length > 0 ? new Set(ctx.toolOutputBudgetExcludeTools) : void 0;
|
|
1760
|
+
const nameById = excludeSet ? new Map(canonicalToolCalls.map((c) => [c.id, c.name])) : void 0;
|
|
1761
|
+
const totalBytes = toolResults.reduce((sum, r) => {
|
|
1762
|
+
if (excludeSet && nameById) {
|
|
1763
|
+
const name = nameById.get(r.id);
|
|
1764
|
+
if (name !== void 0 && excludeSet.has(name)) return sum;
|
|
1765
|
+
}
|
|
1766
|
+
return sum + toolOutputByteLength(r.content);
|
|
1767
|
+
}, 0);
|
|
1760
1768
|
if (totalBytes > ctx.toolOutputBudget) {
|
|
1761
1769
|
const warning = `[Tool output budget exceeded: ${totalBytes} bytes returned in this turn (cap: ${ctx.toolOutputBudget}). Summarize the salient findings before calling more tools.]`;
|
|
1762
1770
|
const userMsg = ctx.provider.userMessage(warning);
|
|
@@ -1765,7 +1773,7 @@ async function executeTurn(ctx, turn, priorUsage) {
|
|
|
1765
1773
|
runId: ctx.runId,
|
|
1766
1774
|
role: userMsg.role,
|
|
1767
1775
|
content: userMsg.content,
|
|
1768
|
-
createdAt:
|
|
1776
|
+
createdAt: await ctx.clock.now()
|
|
1769
1777
|
});
|
|
1770
1778
|
await ctx.hooks.callHook("budget:exceeded", {
|
|
1771
1779
|
turn,
|
|
@@ -2000,7 +2008,8 @@ async function runSingleToolDispatch(ctx, call, turnId, fixed) {
|
|
|
2000
2008
|
...ctx.parentRunId !== void 0 ? { parentRunId: ctx.parentRunId } : {},
|
|
2001
2009
|
...ctx.session ? { session: ctx.session } : {},
|
|
2002
2010
|
...ctx.readState ? { readState: ctx.readState } : {},
|
|
2003
|
-
...typeof ctx.depth === "number" ? { depth: ctx.depth } : {}
|
|
2011
|
+
...typeof ctx.depth === "number" ? { depth: ctx.depth } : {},
|
|
2012
|
+
clock: ctx.clock
|
|
2004
2013
|
};
|
|
2005
2014
|
const bodyPromise = toolDef.execute(effectiveInput, toolCtx);
|
|
2006
2015
|
bodyPromise.catch(() => {});
|
|
@@ -3161,21 +3170,95 @@ function formatMatch(entry) {
|
|
|
3161
3170
|
].join("\n");
|
|
3162
3171
|
}
|
|
3163
3172
|
/**
|
|
3164
|
-
*
|
|
3165
|
-
*
|
|
3166
|
-
*
|
|
3173
|
+
* Pure resolver for a `tool_search` invocation. Mirrors the matching the
|
|
3174
|
+
* execute path performs (`names` → `server` → `query` → unconstrained fallback,
|
|
3175
|
+
* then cap by `limit`). Extracted so the unlock side-effect can be replayed
|
|
3176
|
+
* deterministically when a session is resumed — `run()` walks the persisted
|
|
3177
|
+
* `tool_search` tool_calls and feeds each historical input through here to
|
|
3178
|
+
* rebuild the `unlocked` set seeded by prior runs.
|
|
3179
|
+
*
|
|
3180
|
+
* Returns the entries the original call would have shown (post-limit), not the
|
|
3181
|
+
* full pre-cap match set — the cap is part of what the model actually saw.
|
|
3167
3182
|
*/
|
|
3168
|
-
function
|
|
3169
|
-
const
|
|
3170
|
-
const byName = new Map(options.catalog.map((e) => [e.name, e]));
|
|
3183
|
+
function selectToolSearchMatches(catalog, input, defaultLimit = DEFAULT_LIMIT$1) {
|
|
3184
|
+
const byName = new Map(catalog.map((e) => [e.name, e]));
|
|
3171
3185
|
const byServer = /* @__PURE__ */ new Map();
|
|
3172
|
-
for (const entry of
|
|
3186
|
+
for (const entry of catalog) {
|
|
3173
3187
|
if (!entry.server) continue;
|
|
3174
3188
|
const list = byServer.get(entry.server) ?? [];
|
|
3175
3189
|
list.push(entry);
|
|
3176
3190
|
byServer.set(entry.server, list);
|
|
3177
3191
|
}
|
|
3178
|
-
const maxLimit = Math.max(
|
|
3192
|
+
const maxLimit = Math.max(catalog.length, 1);
|
|
3193
|
+
const query = (typeof input.query === "string" ? input.query.trim() : void 0) || void 0;
|
|
3194
|
+
const namesIn = Array.isArray(input.names) ? input.names.filter((n) => typeof n === "string" && n.length > 0) : void 0;
|
|
3195
|
+
const server = typeof input.server === "string" && input.server.length > 0 ? input.server : void 0;
|
|
3196
|
+
const limitIn = typeof input.limit === "number" && Number.isFinite(input.limit) && input.limit > 0 ? Math.floor(input.limit) : defaultLimit;
|
|
3197
|
+
const limit = Math.min(limitIn, maxLimit);
|
|
3198
|
+
const matches = [];
|
|
3199
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3200
|
+
const misses = [];
|
|
3201
|
+
if (namesIn && namesIn.length > 0) for (const n of namesIn) {
|
|
3202
|
+
if (seen.has(n)) continue;
|
|
3203
|
+
const entry = byName.get(n);
|
|
3204
|
+
if (entry) {
|
|
3205
|
+
matches.push(entry);
|
|
3206
|
+
seen.add(n);
|
|
3207
|
+
} else misses.push(n);
|
|
3208
|
+
}
|
|
3209
|
+
if (server) {
|
|
3210
|
+
const list = byServer.get(server) ?? [];
|
|
3211
|
+
for (const entry of list) {
|
|
3212
|
+
if (seen.has(entry.name)) continue;
|
|
3213
|
+
matches.push(entry);
|
|
3214
|
+
seen.add(entry.name);
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
if (query !== void 0) for (const entry of rankByQuery(catalog, query)) {
|
|
3218
|
+
if (seen.has(entry.name)) continue;
|
|
3219
|
+
matches.push(entry);
|
|
3220
|
+
seen.add(entry.name);
|
|
3221
|
+
}
|
|
3222
|
+
if (!namesIn?.length && !server && query === void 0) for (const entry of catalog) {
|
|
3223
|
+
matches.push(entry);
|
|
3224
|
+
seen.add(entry.name);
|
|
3225
|
+
}
|
|
3226
|
+
const truncated = matches.length > limit;
|
|
3227
|
+
return {
|
|
3228
|
+
shown: truncated ? matches.slice(0, limit) : matches,
|
|
3229
|
+
total: matches.length,
|
|
3230
|
+
truncated,
|
|
3231
|
+
misses,
|
|
3232
|
+
query,
|
|
3233
|
+
server
|
|
3234
|
+
};
|
|
3235
|
+
}
|
|
3236
|
+
/**
|
|
3237
|
+
* Replay the unlock side-effect of a single historical `tool_search` call.
|
|
3238
|
+
*
|
|
3239
|
+
* Used on session resume: every run starts with a fresh `unlocked` set
|
|
3240
|
+
* (seeded with eager tools only), but the resumed conversation already
|
|
3241
|
+
* shows the model that some lazy tools are callable. Without this replay
|
|
3242
|
+
* the model emits a `tool_use` for a tool the gate then refuses with
|
|
3243
|
+
* "load via tool_search first" — the failure the bug report named.
|
|
3244
|
+
*
|
|
3245
|
+
* Safe to call repeatedly with the same input; the `Set` add is idempotent.
|
|
3246
|
+
* Lookups missing from the current catalog (host changed `mcpServers` or
|
|
3247
|
+
* `disclosure` between runs) are silently dropped — the model will get a
|
|
3248
|
+
* normal "tool not callable" error on its next attempt, which is the
|
|
3249
|
+
* correct response when a tool genuinely no longer exists.
|
|
3250
|
+
*/
|
|
3251
|
+
function applyToolSearchToUnlocked(catalog, input, unlocked, defaultLimit) {
|
|
3252
|
+
const { shown } = selectToolSearchMatches(catalog, input, defaultLimit ?? DEFAULT_LIMIT$1);
|
|
3253
|
+
for (const entry of shown) unlocked.add(entry.canonicalName);
|
|
3254
|
+
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Factory for `tool_search`. Auto-injected by the agent when
|
|
3257
|
+
* `behavior.toolDisclosure === 'lazy'` and at least one MCP tool is in the
|
|
3258
|
+
* registry. Opt out via `behavior.toolSearch.tool === false`.
|
|
3259
|
+
*/
|
|
3260
|
+
function createToolSearchTool(options) {
|
|
3261
|
+
const defaultLimit = options.defaultLimit ?? DEFAULT_LIMIT$1;
|
|
3179
3262
|
return {
|
|
3180
3263
|
isConcurrencySafe: true,
|
|
3181
3264
|
spec: {
|
|
@@ -3208,53 +3291,19 @@ function createToolSearchTool(options) {
|
|
|
3208
3291
|
},
|
|
3209
3292
|
async execute(input, ctx) {
|
|
3210
3293
|
if (ctx.signal?.aborted) return "<tool_search_results matches=\"0\" aborted=\"true\">Run aborted.</tool_search_results>";
|
|
3211
|
-
const query = (typeof input.query === "string" ? input.query.trim() : void 0) || void 0;
|
|
3212
|
-
const namesIn = Array.isArray(input.names) ? input.names.filter((n) => typeof n === "string" && n.length > 0) : void 0;
|
|
3213
|
-
const server = typeof input.server === "string" && input.server.length > 0 ? input.server : void 0;
|
|
3214
|
-
const limitIn = typeof input.limit === "number" && Number.isFinite(input.limit) && input.limit > 0 ? Math.floor(input.limit) : defaultLimit;
|
|
3215
|
-
const limit = Math.min(limitIn, maxLimit);
|
|
3216
3294
|
if (options.catalog.length === 0) return "<tool_search_results matches=\"0\">No lazy tools registered for this run.</tool_search_results>";
|
|
3217
|
-
const
|
|
3218
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3219
|
-
const misses = [];
|
|
3220
|
-
if (namesIn && namesIn.length > 0) for (const n of namesIn) {
|
|
3221
|
-
if (seen.has(n)) continue;
|
|
3222
|
-
const entry = byName.get(n);
|
|
3223
|
-
if (entry) {
|
|
3224
|
-
matches.push(entry);
|
|
3225
|
-
seen.add(n);
|
|
3226
|
-
} else misses.push(n);
|
|
3227
|
-
}
|
|
3228
|
-
if (server) {
|
|
3229
|
-
const list = byServer.get(server) ?? [];
|
|
3230
|
-
for (const entry of list) {
|
|
3231
|
-
if (seen.has(entry.name)) continue;
|
|
3232
|
-
matches.push(entry);
|
|
3233
|
-
seen.add(entry.name);
|
|
3234
|
-
}
|
|
3235
|
-
}
|
|
3236
|
-
if (query !== void 0) for (const entry of rankByQuery(options.catalog, query)) {
|
|
3237
|
-
if (seen.has(entry.name)) continue;
|
|
3238
|
-
matches.push(entry);
|
|
3239
|
-
seen.add(entry.name);
|
|
3240
|
-
}
|
|
3241
|
-
if (!namesIn?.length && !server && query === void 0) for (const entry of options.catalog) {
|
|
3242
|
-
matches.push(entry);
|
|
3243
|
-
seen.add(entry.name);
|
|
3244
|
-
}
|
|
3245
|
-
const truncated = matches.length > limit;
|
|
3246
|
-
const shown = truncated ? matches.slice(0, limit) : matches;
|
|
3295
|
+
const { shown, total, truncated, misses, query, server } = selectToolSearchMatches(options.catalog, input, defaultLimit);
|
|
3247
3296
|
for (const entry of shown) options.unlocked.add(entry.canonicalName);
|
|
3248
3297
|
const parts = [];
|
|
3249
3298
|
const queryAttr = query ? ` query="${escapeXml(query)}"` : "";
|
|
3250
3299
|
const serverAttr = server ? ` server="${escapeXml(server)}"` : "";
|
|
3251
|
-
parts.push(`<tool_search_results matches="${shown.length}" total="${
|
|
3300
|
+
parts.push(`<tool_search_results matches="${shown.length}" total="${total}"${queryAttr}${serverAttr}>`);
|
|
3252
3301
|
if (shown.length === 0) parts.push(" No matches. Try a broader query, or omit all parameters to list everything.");
|
|
3253
3302
|
else {
|
|
3254
3303
|
for (const entry of shown) parts.push(formatMatch(entry));
|
|
3255
3304
|
parts.push("");
|
|
3256
3305
|
parts.push(" These tools are now callable. Invoke them by name in subsequent turns.");
|
|
3257
|
-
if (truncated) parts.push(` ${
|
|
3306
|
+
if (truncated) parts.push(` ${total - shown.length} additional matches were truncated — refine the query or raise \`limit\`.`);
|
|
3258
3307
|
}
|
|
3259
3308
|
if (misses.length > 0) parts.push(` <misses>${misses.map(escapeXml).join(", ")}</misses>`);
|
|
3260
3309
|
parts.push("</tool_search_results>");
|
|
@@ -3405,7 +3454,7 @@ function isKnownHookEvent(event) {
|
|
|
3405
3454
|
* - All tool_use ids are already answered by a tool_result somewhere later
|
|
3406
3455
|
* in the conversation (defensive — shouldn't happen but cheap to check).
|
|
3407
3456
|
*/
|
|
3408
|
-
async function synthesizeMissingToolResults(turns, syntheticTurnId, runId, provider, hooks) {
|
|
3457
|
+
async function synthesizeMissingToolResults(turns, syntheticTurnId, runId, provider, hooks, clock) {
|
|
3409
3458
|
if (turns.length === 0) return;
|
|
3410
3459
|
const last = turns[turns.length - 1];
|
|
3411
3460
|
if (last.role !== "assistant") return;
|
|
@@ -3427,7 +3476,7 @@ async function synthesizeMissingToolResults(turns, syntheticTurnId, runId, provi
|
|
|
3427
3476
|
runId,
|
|
3428
3477
|
role: msg.role,
|
|
3429
3478
|
content: msg.content,
|
|
3430
|
-
createdAt:
|
|
3479
|
+
createdAt: await clock.now()
|
|
3431
3480
|
});
|
|
3432
3481
|
for (const callId of dangling) await hooks.callHook("pairing:repair", {
|
|
3433
3482
|
mode: "orphan-tool-use-append",
|
|
@@ -3444,6 +3493,7 @@ function resolveBehavior(agentBehavior, runBehavior) {
|
|
|
3444
3493
|
schema: runBehavior?.schema ?? agentBehavior?.schema,
|
|
3445
3494
|
cache: runBehavior?.cache ?? agentBehavior?.cache ?? true,
|
|
3446
3495
|
toolOutputBudget: runBehavior?.toolOutputBudget ?? agentBehavior?.toolOutputBudget,
|
|
3496
|
+
toolOutputBudgetExcludeTools: runBehavior?.toolOutputBudgetExcludeTools ?? agentBehavior?.toolOutputBudgetExcludeTools,
|
|
3447
3497
|
compactStrategy: runBehavior?.compactStrategy ?? agentBehavior?.compactStrategy ?? "off",
|
|
3448
3498
|
compactThreshold: runBehavior?.compactThreshold ?? agentBehavior?.compactThreshold,
|
|
3449
3499
|
compactKeepTurns: runBehavior?.compactKeepTurns ?? agentBehavior?.compactKeepTurns,
|
|
@@ -3608,7 +3658,7 @@ function initialRunCounter(session) {
|
|
|
3608
3658
|
for (const t of session.turns) consider(t.runId);
|
|
3609
3659
|
return max;
|
|
3610
3660
|
}
|
|
3611
|
-
function createAgent({ provider, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, mcpServers, session, readState: agentReadState, skills: agentSkills, mcpConnector, eager, hooks: initialHooks }) {
|
|
3661
|
+
function createAgent({ provider, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, mcpServers, session, readState: agentReadState, skills: agentSkills, mcpConnector, eager, hooks: initialHooks, clock: agentClock }) {
|
|
3612
3662
|
const hooks = createHooks();
|
|
3613
3663
|
const executionContext = execution ?? createProcessContext();
|
|
3614
3664
|
const sourceTools = agentTools ?? {};
|
|
@@ -3688,6 +3738,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3688
3738
|
throw new Error(`cannot resume without prompt: ${detail}. Pass a prompt to agent.run({ prompt: … }).`);
|
|
3689
3739
|
}
|
|
3690
3740
|
}
|
|
3741
|
+
const clock = options.clock ?? agentClock ?? DEFAULT_AGENT_CLOCK;
|
|
3691
3742
|
let externalAbortListener;
|
|
3692
3743
|
const externalSignal = options.signal;
|
|
3693
3744
|
running = true;
|
|
@@ -3708,7 +3759,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3708
3759
|
prompt: promptLabel
|
|
3709
3760
|
});
|
|
3710
3761
|
}
|
|
3711
|
-
const runStartedAt =
|
|
3762
|
+
const runStartedAt = await clock.now();
|
|
3712
3763
|
await hooks.callHook("agent:start", {
|
|
3713
3764
|
runId,
|
|
3714
3765
|
...options.parentRunId ? { parentRunId: options.parentRunId } : {},
|
|
@@ -3769,7 +3820,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3769
3820
|
const thinking = options.thinking ?? "off";
|
|
3770
3821
|
const model = options.model ?? provider.meta.defaultModel;
|
|
3771
3822
|
const resolvedBehavior = resolveBehavior(agentBehavior, options.behavior);
|
|
3772
|
-
const { maxConcurrentTools, maxTurns, maxTokens, thinkingBudget, schema, cache, toolOutputBudget, compactStrategy, compactThreshold, compactKeepTurns, thinkingDecay, dedupTools, toolBudgets, elideStaleReads, toolDisclosure, toolSearch, persistThreshold, persistExcludeTools, persistDir, strictToolPairing } = resolvedBehavior;
|
|
3823
|
+
const { maxConcurrentTools, maxTurns, maxTokens, thinkingBudget, schema, cache, toolOutputBudget, toolOutputBudgetExcludeTools, compactStrategy, compactThreshold, compactKeepTurns, thinkingDecay, dedupTools, toolBudgets, elideStaleReads, toolDisclosure, toolSearch, persistThreshold, persistExcludeTools, persistDir, strictToolPairing } = resolvedBehavior;
|
|
3773
3824
|
let system = options.system || agentSystem || "You are a helpful assistant.";
|
|
3774
3825
|
if (skillsCatalog) system = `${system}\n\n${skillsCatalog}`;
|
|
3775
3826
|
const runBaseTools = options.tools !== void 0 ? options.tools : mcpConnection ? {
|
|
@@ -3838,6 +3889,16 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3838
3889
|
const resumed = childRunIds.size === 0 ? session.turns : session.turns.filter((t) => !t.runId || !childRunIds.has(t.runId));
|
|
3839
3890
|
const filteredForRuntime = resumeFilteredTurns && resumed === session.turns ? resumeFilteredTurns : filterUnresolvedToolUses(resumed);
|
|
3840
3891
|
turns.push(...filteredForRuntime);
|
|
3892
|
+
if (shouldInjectToolSearch && disclosure.lazyEntries.length > 0) {
|
|
3893
|
+
const resolvedCallIds = /* @__PURE__ */ new Set();
|
|
3894
|
+
for (const turn of filteredForRuntime) for (const block of turn.content) if (block.type === "tool_result" && !block.isError) resolvedCallIds.add(block.callId);
|
|
3895
|
+
for (const turn of filteredForRuntime) for (const block of turn.content) {
|
|
3896
|
+
if (block.type !== "tool_call") continue;
|
|
3897
|
+
if (block.name !== "tool_search") continue;
|
|
3898
|
+
if (!resolvedCallIds.has(block.id)) continue;
|
|
3899
|
+
applyToolSearchToUnlocked(disclosure.lazyEntries, block.input, unlocked, toolSearch?.limit);
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3841
3902
|
}
|
|
3842
3903
|
const runTurnStart = turns.length;
|
|
3843
3904
|
if (options.system) await hooks.callHook("system:before", { system: options.system });
|
|
@@ -3855,11 +3916,11 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3855
3916
|
const promptMsg = promptParts ? buildPromptMessage(provider, promptParts) : null;
|
|
3856
3917
|
const content = [...drainedNotifications, ...promptMsg ? promptMsg.content : []];
|
|
3857
3918
|
turns.push({
|
|
3858
|
-
id:
|
|
3919
|
+
id: clock.randomUUID(),
|
|
3859
3920
|
runId,
|
|
3860
3921
|
role: promptMsg ? promptMsg.role : "user",
|
|
3861
3922
|
content,
|
|
3862
|
-
createdAt:
|
|
3923
|
+
createdAt: await clock.now()
|
|
3863
3924
|
});
|
|
3864
3925
|
}
|
|
3865
3926
|
conversationTurns = turns;
|
|
@@ -3889,7 +3950,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3889
3950
|
const unregisterToolResultsSync = session ? hooks.hook("tool-results:after", persistPendingTurns) : void 0;
|
|
3890
3951
|
async function flushTurns(opts = {}) {
|
|
3891
3952
|
if (!session) return;
|
|
3892
|
-
if (opts.failureFallback) await synthesizeMissingToolResults(turns, await session.generateTurnId?.() ??
|
|
3953
|
+
if (opts.failureFallback) await synthesizeMissingToolResults(turns, await session.generateTurnId?.() ?? clock.randomUUID(), runId, provider, hooks, clock);
|
|
3893
3954
|
const remaining = turns.slice(lastPersistedTurnCount);
|
|
3894
3955
|
if (remaining.length > 0) {
|
|
3895
3956
|
await session.appendTurns(remaining);
|
|
@@ -3923,7 +3984,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3923
3984
|
const uninstallToolBudgets = installToolBudgetsGate(hooks, () => toolBudgets, (msg) => steeringQueue.push(msg));
|
|
3924
3985
|
const uninstallDedupTools = installDedupToolsGate(hooks, () => dedupTools, () => session ?? void 0);
|
|
3925
3986
|
const uninstallLazyDisclosureGate = installLazyDisclosureGate(hooks, disclosure.lazyCanonicalNames, unlocked, discoveryToolName);
|
|
3926
|
-
const runStartMs =
|
|
3987
|
+
const runStartMs = await clock.now();
|
|
3927
3988
|
const runDepth = typeof options.depth === "number" ? options.depth : 0;
|
|
3928
3989
|
try {
|
|
3929
3990
|
const stats = await runLoop({
|
|
@@ -3951,7 +4012,8 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3951
4012
|
followUpQueue,
|
|
3952
4013
|
turns,
|
|
3953
4014
|
runId,
|
|
3954
|
-
generateTurnId: () => session?.generateTurnId() ??
|
|
4015
|
+
generateTurnId: () => session?.generateTurnId() ?? clock.randomUUID(),
|
|
4016
|
+
clock,
|
|
3955
4017
|
maxTurns,
|
|
3956
4018
|
maxTokens,
|
|
3957
4019
|
...session ? { session } : {},
|
|
@@ -3962,6 +4024,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3962
4024
|
schema,
|
|
3963
4025
|
cache,
|
|
3964
4026
|
toolOutputBudget,
|
|
4027
|
+
...toolOutputBudgetExcludeTools !== void 0 ? { toolOutputBudgetExcludeTools } : {},
|
|
3965
4028
|
compactStrategy,
|
|
3966
4029
|
compactThreshold,
|
|
3967
4030
|
compactKeepTurns,
|
|
@@ -5852,4 +5915,4 @@ const writeFile$1 = {
|
|
|
5852
5915
|
//#endregion
|
|
5853
5916
|
export { resolvePersistDir as A, formatTaskStatus as B, TOOL_USE_SKIPPED_MESSAGE as C, buildPersistedStub as D, PERSISTENCE_PREVIEW_BYTES as E, resolveReadStateMap as F, previewLine as H, ageString as I, compactPath as L, getReadState as M, hashContent as N, cleanupPersistedSession as O, readStateKey as P, fmtTokens as R, TOOL_USE_CANCELLED_MESSAGE as S, PERSISTED_STUB_PREFIX as T, shortId as U, formatTaskSummary as V, createSkillsReadTool as _, multiEdit as a, INTERRUPT_MESSAGE_FOR_TOOL_USE as b, grep as c, resolveOldString as d, styleReplacementForVia as f, createSkillsRunScriptTool as g, createSkillsUseTool as h, readFile$1 as i, resolveTasksDir as j, maybePersistToolResult as k, glob as l, createToolSearchTool as m, createSpawnTool as n, listFiles as o, createAgent as p, shellKill as r, createInteractionTool as s, writeFile$1 as t, edit as u, createShellTool as v, validateToolArgs as w, SHELL_CASCADE_CANCEL_MESSAGE as x, shell as y, formatDuration as z };
|
|
5854
5917
|
|
|
5855
|
-
//# sourceMappingURL=tools-
|
|
5918
|
+
//# sourceMappingURL=tools-Bbd0Ivwn.js.map
|