zidane 5.4.1 → 5.4.3
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 +15 -0
- package/dist/{agent-DHQAsdj6.d.ts → agent-Yu8uhpy-.d.ts} +213 -3
- package/dist/agent-Yu8uhpy-.d.ts.map +1 -0
- package/dist/chat.d.ts +49 -6
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/{errors-Byb0F8B9.js → errors-CDwtPIMX.js} +4 -2
- package/dist/{errors-Byb0F8B9.js.map → errors-CDwtPIMX.js.map} +1 -1
- package/dist/{index-CHSaLab5.d.ts → index-DklfxeYy.d.ts} +8 -2
- package/dist/index-DklfxeYy.d.ts.map +1 -0
- package/dist/{index-CrqFoaQA.d.ts → index-j9tY28ah.d.ts} +474 -8
- package/dist/index-j9tY28ah.d.ts.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1528 -53
- package/dist/index.js.map +1 -1
- package/dist/{interpolate-ERgZUxgg.js → interpolate-CmtjEyRJ.js} +155 -18
- package/dist/interpolate-CmtjEyRJ.js.map +1 -0
- package/dist/{login-8c5C0FYq.js → login-DxyAERe1.js} +3 -3
- package/dist/{login-8c5C0FYq.js.map → login-DxyAERe1.js.map} +1 -1
- package/dist/{mcp-DhmmJfxK.js → mcp-CNUbvbsy.js} +2 -2
- package/dist/{mcp-DhmmJfxK.js.map → mcp-CNUbvbsy.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +1 -1
- package/dist/{messages-D0xT979U.js → messages-fTR19Ga6.js} +2 -2
- package/dist/{messages-D0xT979U.js.map → messages-fTR19Ga6.js.map} +1 -1
- package/dist/{presets-Ck4VusTo.js → presets-D9IbaI40.js} +2 -2
- package/dist/{presets-Ck4VusTo.js.map → presets-D9IbaI40.js.map} +1 -1
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +1 -1
- package/dist/{providers-x3LZByR5.js → providers-CEzRFYtS.js} +3 -3
- package/dist/{providers-x3LZByR5.js.map → providers-CEzRFYtS.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +2 -2
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session/sqlite.js +1 -1
- package/dist/{session-BHZwxmfr.js → session-kwsNnOmt.js} +2 -2
- package/dist/{session-BHZwxmfr.js.map → session-kwsNnOmt.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/{tools-PQH1Ge4M.js → tools-BK2vG9UX.js} +246 -44
- package/dist/tools-BK2vG9UX.js.map +1 -0
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-ByB2MSCB.d.ts → transcript-anchors-DnaBcJej.d.ts} +52 -8
- package/dist/transcript-anchors-DnaBcJej.d.ts.map +1 -0
- package/dist/tui.d.ts +4 -2
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +651 -42
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-Bqs4YbbH.js → turn-operations-OzKEOXul.js} +240 -52
- package/dist/turn-operations-OzKEOXul.js.map +1 -0
- package/dist/types-IcokUOyC.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/docs/ARCHITECTURE.md +16 -3
- package/docs/CHAT.md +1 -1
- package/docs/SKILL.md +24 -14
- package/docs/TUI.md +24 -0
- package/package.json +3 -3
- package/dist/agent-DHQAsdj6.d.ts.map +0 -1
- package/dist/index-CHSaLab5.d.ts.map +0 -1
- package/dist/index-CrqFoaQA.d.ts.map +0 -1
- package/dist/interpolate-ERgZUxgg.js.map +0 -1
- package/dist/tools-PQH1Ge4M.js.map +0 -1
- package/dist/transcript-anchors-ByB2MSCB.d.ts.map +0 -1
- package/dist/turn-operations-Bqs4YbbH.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as createProcessContext } from "./contexts-BwiHIr2w.js";
|
|
2
|
-
import { a as AgentToolPairingError, l as toTypedError, r as AgentProviderError, s as errorMessage, t as AgentAbortedError } from "./errors-
|
|
2
|
+
import { a as AgentToolPairingError, l as toTypedError, r as AgentProviderError, s as errorMessage, t as AgentAbortedError } from "./errors-CDwtPIMX.js";
|
|
3
3
|
import { t as toolOutputByteLength } from "./types-IcokUOyC.js";
|
|
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-
|
|
4
|
+
import { a as detectTurnInterruption, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureToolResultPairing, s as filterUnresolvedToolUses } from "./messages-fTR19Ga6.js";
|
|
5
|
+
import { t as connectMcpServers } from "./mcp-CNUbvbsy.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-CmtjEyRJ.js";
|
|
7
7
|
import { n as formatTokenUsage, t as flattenTurns } from "./stats-DgOvY7wd.js";
|
|
8
8
|
import { createHooks } from "hookable";
|
|
9
9
|
import { mkdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -812,6 +812,27 @@ const INTERRUPT_MESSAGE_FOR_TOOL_USE = "[Request interrupted by user for tool us
|
|
|
812
812
|
*/
|
|
813
813
|
const TOOL_USE_SKIPPED_MESSAGE = "[Tool use skipped — superseded by user message]";
|
|
814
814
|
/**
|
|
815
|
+
* Canonical tool_result text emitted when a single tool call is cancelled
|
|
816
|
+
* mid-flight via `agent.cancelTool(callId)` (typically the TUI's
|
|
817
|
+
* "cancel this tool" affordance). Distinguished from
|
|
818
|
+
* {@link INTERRUPT_MESSAGE_FOR_TOOL_USE} (run-wide user abort) and
|
|
819
|
+
* {@link TOOL_USE_SKIPPED_MESSAGE} (steered) so the model — and downstream
|
|
820
|
+
* consumers — can tell the three apart by string match.
|
|
821
|
+
*
|
|
822
|
+
* Always paired with `isError: true` on the wire so the model treats the
|
|
823
|
+
* call as failed rather than as a successful response. The remaining tool
|
|
824
|
+
* calls in the batch continue running, in contrast with a full-run abort.
|
|
825
|
+
*/
|
|
826
|
+
const TOOL_USE_CANCELLED_MESSAGE = "[Tool call cancelled by user]";
|
|
827
|
+
/**
|
|
828
|
+
* Sentinel message rejected from the per-call cancellation promise inside
|
|
829
|
+
* {@link executeSingleTool}'s race. Plain-string and module-private — only
|
|
830
|
+
* the surrounding code reads it (via the `perCallAbort.signal.aborted`
|
|
831
|
+
* guard, NOT the message itself), so it just needs to be a stable
|
|
832
|
+
* non-empty identifier the rejection can carry.
|
|
833
|
+
*/
|
|
834
|
+
const CANCELLED_BY_USER_SENTINEL = "zidane:tool:cancelled-by-user";
|
|
835
|
+
/**
|
|
815
836
|
* Compute the effective thinking budget for a given run-relative turn, given
|
|
816
837
|
* the configured decay schedule. Pure helper — exported for tests and so
|
|
817
838
|
* downstream tooling can preview decay curves without spinning up the loop.
|
|
@@ -1184,7 +1205,14 @@ async function runLoop(ctx) {
|
|
|
1184
1205
|
await ctx.hooks.callHook("agent:abort", {});
|
|
1185
1206
|
break;
|
|
1186
1207
|
}
|
|
1187
|
-
const result = await executeTurn(ctx, turn
|
|
1208
|
+
const result = await executeTurn(ctx, turn, {
|
|
1209
|
+
input: totalIn,
|
|
1210
|
+
output: totalOut,
|
|
1211
|
+
cacheRead: totalCacheRead,
|
|
1212
|
+
cacheCreation: totalCacheCreation,
|
|
1213
|
+
priorCost: turnUsages.reduce((s, t) => s + (t.cost ?? 0), 0),
|
|
1214
|
+
priorTurns: turnsCompleted
|
|
1215
|
+
});
|
|
1188
1216
|
turnsCompleted = turn + 1;
|
|
1189
1217
|
totalIn += result.usage.input;
|
|
1190
1218
|
totalOut += result.usage.output;
|
|
@@ -1295,7 +1323,49 @@ function buildStreamErrorPlaceholder(err) {
|
|
|
1295
1323
|
const oneLine = raw.replace(/\s+/g, " ");
|
|
1296
1324
|
return `[✗ Streaming failed before any output: ${oneLine.length > ERROR_PLACEHOLDER_MAX ? `${oneLine.slice(0, ERROR_PLACEHOLDER_MAX - 1).trimEnd()}…` : oneLine}]`;
|
|
1297
1325
|
}
|
|
1298
|
-
|
|
1326
|
+
function buildCumulativeUsage(prior, turnUsage) {
|
|
1327
|
+
const cost = prior.priorCost + (turnUsage.cost ?? 0);
|
|
1328
|
+
return Object.freeze({
|
|
1329
|
+
input: prior.input + turnUsage.input,
|
|
1330
|
+
output: prior.output + turnUsage.output,
|
|
1331
|
+
cacheRead: prior.cacheRead + (turnUsage.cacheRead ?? 0),
|
|
1332
|
+
cacheCreation: prior.cacheCreation + (turnUsage.cacheCreation ?? 0),
|
|
1333
|
+
...cost > 0 ? { cost } : {},
|
|
1334
|
+
turns: prior.priorTurns + 1
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Best-effort extraction of `statusCode` / `requestId` from native provider
|
|
1339
|
+
* SDK exceptions, attached to `stream:error` ctx so observability handlers
|
|
1340
|
+
* don't have to walk `cause` chains. Recognized shapes:
|
|
1341
|
+
*
|
|
1342
|
+
* - Anthropic SDK `APIError` (`status`, `headers['request-id']`)
|
|
1343
|
+
* - OpenAI SDK error (`status`, `headers['x-request-id']`)
|
|
1344
|
+
* - OpenRouter / OpenAI-compat HTTP errors (`status`)
|
|
1345
|
+
* - Cerebras (`status`)
|
|
1346
|
+
*
|
|
1347
|
+
* Silent no-op for arbitrary `Error`s and primitives — the fields stay
|
|
1348
|
+
* undefined and the raw `err` is still forwarded for handlers that need
|
|
1349
|
+
* full context.
|
|
1350
|
+
*/
|
|
1351
|
+
function extractStreamErrorMeta(err) {
|
|
1352
|
+
if (!err || typeof err !== "object") return {};
|
|
1353
|
+
const e = err;
|
|
1354
|
+
const out = {};
|
|
1355
|
+
const statusCandidate = typeof e.status === "number" ? e.status : typeof e.statusCode === "number" ? e.statusCode : void 0;
|
|
1356
|
+
if (typeof statusCandidate === "number" && Number.isFinite(statusCandidate)) out.statusCode = statusCandidate;
|
|
1357
|
+
if (typeof e.requestId === "string") out.requestId = e.requestId;
|
|
1358
|
+
else {
|
|
1359
|
+
const headers = e.headers;
|
|
1360
|
+
if (headers && typeof headers === "object") {
|
|
1361
|
+
const h = headers;
|
|
1362
|
+
const candidate = h["request-id"] ?? h["x-request-id"] ?? h.requestId;
|
|
1363
|
+
if (typeof candidate === "string") out.requestId = candidate;
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
return out;
|
|
1367
|
+
}
|
|
1368
|
+
async function executeTurn(ctx, turn, priorUsage) {
|
|
1299
1369
|
const turnId = await ctx.generateTurnId();
|
|
1300
1370
|
let canonicalMessages = turnsToMessages(applyCompactSummaryCutoff(ctx.turns));
|
|
1301
1371
|
if (ctx.elideStaleReads === true) {
|
|
@@ -1343,10 +1413,20 @@ async function executeTurn(ctx, turn) {
|
|
|
1343
1413
|
});
|
|
1344
1414
|
let currentText = "";
|
|
1345
1415
|
let currentThinking = "";
|
|
1416
|
+
const streamStartedAt = Date.now();
|
|
1417
|
+
let turnTtftMs;
|
|
1418
|
+
const markTurnTtft = () => {
|
|
1419
|
+
if (turnTtftMs === void 0) turnTtftMs = Date.now() - streamStartedAt;
|
|
1420
|
+
};
|
|
1421
|
+
await ctx.hooks.callHook("stream:start", {
|
|
1422
|
+
turnId,
|
|
1423
|
+
startedAt: streamStartedAt
|
|
1424
|
+
});
|
|
1346
1425
|
let result;
|
|
1347
1426
|
try {
|
|
1348
1427
|
result = await ctx.provider.stream(streamOptions, {
|
|
1349
1428
|
onText(delta) {
|
|
1429
|
+
markTurnTtft();
|
|
1350
1430
|
currentText += delta;
|
|
1351
1431
|
ctx.hooks.callHook("stream:text", {
|
|
1352
1432
|
delta,
|
|
@@ -1355,6 +1435,7 @@ async function executeTurn(ctx, turn) {
|
|
|
1355
1435
|
});
|
|
1356
1436
|
},
|
|
1357
1437
|
onThinking(delta) {
|
|
1438
|
+
markTurnTtft();
|
|
1358
1439
|
currentThinking += delta;
|
|
1359
1440
|
ctx.hooks.callHook("stream:thinking", {
|
|
1360
1441
|
delta,
|
|
@@ -1389,10 +1470,14 @@ async function executeTurn(ctx, turn) {
|
|
|
1389
1470
|
createdAt: Date.now()
|
|
1390
1471
|
};
|
|
1391
1472
|
ctx.turns.push(errorTurn);
|
|
1392
|
-
if (!wasAborted)
|
|
1393
|
-
err
|
|
1394
|
-
|
|
1395
|
-
|
|
1473
|
+
if (!wasAborted) {
|
|
1474
|
+
const meta = extractStreamErrorMeta(err);
|
|
1475
|
+
await ctx.hooks.callHook("stream:error", {
|
|
1476
|
+
err,
|
|
1477
|
+
turnId,
|
|
1478
|
+
...meta
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1396
1481
|
await ctx.hooks.callHook("turn:after", {
|
|
1397
1482
|
turn,
|
|
1398
1483
|
turnId,
|
|
@@ -1401,7 +1486,8 @@ async function executeTurn(ctx, turn) {
|
|
|
1401
1486
|
toolCounts: {
|
|
1402
1487
|
turn: Object.freeze({}),
|
|
1403
1488
|
run: Object.freeze({ ...ctx.runToolCounts })
|
|
1404
|
-
}
|
|
1489
|
+
},
|
|
1490
|
+
cumulativeUsage: buildCumulativeUsage(priorUsage, errorUsage)
|
|
1405
1491
|
});
|
|
1406
1492
|
throw wrapProviderError(err, ctx);
|
|
1407
1493
|
}
|
|
@@ -1409,11 +1495,13 @@ async function executeTurn(ctx, turn) {
|
|
|
1409
1495
|
text: currentText,
|
|
1410
1496
|
turnId
|
|
1411
1497
|
});
|
|
1498
|
+
if (turnTtftMs === void 0 && result.toolCalls.length > 0) turnTtftMs = Date.now() - streamStartedAt;
|
|
1412
1499
|
const canonicalToolCalls = result.toolCalls.map((tc) => ({
|
|
1413
1500
|
...tc,
|
|
1414
1501
|
name: toCanonicalName(tc.name, ctx.aliasMaps)
|
|
1415
1502
|
}));
|
|
1416
1503
|
const canonicalContent = rewriteContentToCanonical(result.assistantMessage?.content ?? [], ctx.aliasMaps);
|
|
1504
|
+
if (turnTtftMs !== void 0 && result.usage.timeToFirstTokenMs === void 0) result.usage.timeToFirstTokenMs = turnTtftMs;
|
|
1417
1505
|
const assistantTurn = {
|
|
1418
1506
|
id: turnId,
|
|
1419
1507
|
runId: ctx.runId,
|
|
@@ -1436,7 +1524,8 @@ async function executeTurn(ctx, turn) {
|
|
|
1436
1524
|
toolCounts: {
|
|
1437
1525
|
turn: Object.freeze(turnCounts),
|
|
1438
1526
|
run: Object.freeze({ ...ctx.runToolCounts })
|
|
1439
|
-
}
|
|
1527
|
+
},
|
|
1528
|
+
cumulativeUsage: buildCumulativeUsage(priorUsage, result.usage)
|
|
1440
1529
|
});
|
|
1441
1530
|
if (result.done) {
|
|
1442
1531
|
if (ctx.schema && !ctx.signal.aborted) {
|
|
@@ -1602,6 +1691,29 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1602
1691
|
const callId = call.id;
|
|
1603
1692
|
const displayName = toWireName(call.name, ctx.aliasMaps);
|
|
1604
1693
|
const runToolCounts = Object.freeze({ ...ctx.runToolCounts });
|
|
1694
|
+
const perCallAbort = new AbortController();
|
|
1695
|
+
ctx.pendingToolCancels?.set(callId, perCallAbort);
|
|
1696
|
+
try {
|
|
1697
|
+
return await runSingleToolDispatch(ctx, call, turnId, {
|
|
1698
|
+
toolDef,
|
|
1699
|
+
callId,
|
|
1700
|
+
displayName,
|
|
1701
|
+
runToolCounts,
|
|
1702
|
+
perCallAbort
|
|
1703
|
+
});
|
|
1704
|
+
} finally {
|
|
1705
|
+
ctx.pendingToolCancels?.delete(callId);
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
/**
|
|
1709
|
+
* Body of {@link executeSingleTool}. Hoisted into its own function purely so
|
|
1710
|
+
* the per-call cancel registration (which spans every exit path) can sit in
|
|
1711
|
+
* a tight `try / finally` at the call site. Behavior is unchanged from the
|
|
1712
|
+
* pre-cancel implementation aside from the user-cancel branch in the
|
|
1713
|
+
* execute body — see {@link TOOL_USE_CANCELLED_MESSAGE}.
|
|
1714
|
+
*/
|
|
1715
|
+
async function runSingleToolDispatch(ctx, call, turnId, fixed) {
|
|
1716
|
+
const { toolDef, callId, displayName, runToolCounts, perCallAbort } = fixed;
|
|
1605
1717
|
const gateCtx = {
|
|
1606
1718
|
...buildToolHookBase(ctx, turnId, callId, call.name, displayName, call.input),
|
|
1607
1719
|
block: false,
|
|
@@ -1727,12 +1839,14 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1727
1839
|
runToolCounts,
|
|
1728
1840
|
...coercions ? { coercions } : {}
|
|
1729
1841
|
});
|
|
1730
|
-
let output;
|
|
1842
|
+
let output = "";
|
|
1731
1843
|
let isError = false;
|
|
1844
|
+
let cancelledByUser = false;
|
|
1845
|
+
const childSignal = typeof AbortSignal.any === "function" ? AbortSignal.any([ctx.signal, perCallAbort.signal]) : ctx.signal;
|
|
1732
1846
|
try {
|
|
1733
1847
|
const toolCtx = {
|
|
1734
1848
|
provider: ctx.provider,
|
|
1735
|
-
signal:
|
|
1849
|
+
signal: childSignal,
|
|
1736
1850
|
execution: ctx.execution,
|
|
1737
1851
|
handle: ctx.handle,
|
|
1738
1852
|
hooks: ctx.hooks,
|
|
@@ -1751,16 +1865,48 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1751
1865
|
...ctx.readState ? { readState: ctx.readState } : {},
|
|
1752
1866
|
...typeof ctx.depth === "number" ? { depth: ctx.depth } : {}
|
|
1753
1867
|
};
|
|
1754
|
-
|
|
1868
|
+
const bodyPromise = toolDef.execute(effectiveInput, toolCtx);
|
|
1869
|
+
bodyPromise.catch(() => {});
|
|
1870
|
+
let removeAbortListener;
|
|
1871
|
+
const cancellationPromise = new Promise((_, reject) => {
|
|
1872
|
+
if (perCallAbort.signal.aborted) {
|
|
1873
|
+
reject(new Error(CANCELLED_BY_USER_SENTINEL));
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
const onAbort = () => reject(new Error(CANCELLED_BY_USER_SENTINEL));
|
|
1877
|
+
perCallAbort.signal.addEventListener("abort", onAbort, { once: true });
|
|
1878
|
+
removeAbortListener = () => perCallAbort.signal.removeEventListener("abort", onAbort);
|
|
1879
|
+
});
|
|
1880
|
+
try {
|
|
1881
|
+
output = await Promise.race([bodyPromise, cancellationPromise]);
|
|
1882
|
+
} finally {
|
|
1883
|
+
removeAbortListener?.();
|
|
1884
|
+
}
|
|
1755
1885
|
} catch (err) {
|
|
1756
|
-
|
|
1757
|
-
|
|
1886
|
+
if (perCallAbort.signal.aborted && !ctx.signal.aborted) cancelledByUser = true;
|
|
1887
|
+
else {
|
|
1888
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1889
|
+
const errorCtx = {
|
|
1890
|
+
...buildToolHookBase(ctx, turnId, callId, call.name, displayName, effectiveInput),
|
|
1891
|
+
error
|
|
1892
|
+
};
|
|
1893
|
+
await ctx.hooks.callHook("tool:error", errorCtx);
|
|
1894
|
+
output = errorCtx.result ?? `Tool error: ${error.message}`;
|
|
1895
|
+
isError = true;
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
if (cancelledByUser) {
|
|
1899
|
+
const reason = typeof perCallAbort.signal.reason === "string" ? perCallAbort.signal.reason : "cancelled-by-user";
|
|
1900
|
+
await ctx.hooks.callHook("tool:cancelled", {
|
|
1758
1901
|
...buildToolHookBase(ctx, turnId, callId, call.name, displayName, effectiveInput),
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1902
|
+
reason,
|
|
1903
|
+
runToolCounts
|
|
1904
|
+
});
|
|
1905
|
+
return { result: {
|
|
1906
|
+
id: callId,
|
|
1907
|
+
content: TOOL_USE_CANCELLED_MESSAGE,
|
|
1908
|
+
isError: true
|
|
1909
|
+
} };
|
|
1764
1910
|
}
|
|
1765
1911
|
const emitted = await emitToolResult(ctx, {
|
|
1766
1912
|
turnId,
|
|
@@ -2412,14 +2558,21 @@ function createSkillsUseTool(options) {
|
|
|
2412
2558
|
return {
|
|
2413
2559
|
spec: {
|
|
2414
2560
|
name: "skills_use",
|
|
2415
|
-
description: "Activate a specialized skill
|
|
2561
|
+
description: "Activate or deactivate a specialized skill. Call with `mode: \"activate\"` (default) to load a skill's full instructions when a task matches its catalog description. Call with `mode: \"deactivate\"` to release a skill whose allowed-tools restrictions are now in the way — e.g. when the skill's work is done or the active skill is blocking unrelated tool calls. After activating, follow the returned instructions; use skills_read to load referenced files and skills_run_script to execute bundled scripts.",
|
|
2416
2562
|
inputSchema: {
|
|
2417
2563
|
type: "object",
|
|
2418
|
-
properties: {
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2564
|
+
properties: {
|
|
2565
|
+
name: {
|
|
2566
|
+
type: "string",
|
|
2567
|
+
enum: options.catalog.map((s) => s.name),
|
|
2568
|
+
description: "The name of the skill to activate or deactivate (must be in the available skills catalog)."
|
|
2569
|
+
},
|
|
2570
|
+
mode: {
|
|
2571
|
+
type: "string",
|
|
2572
|
+
enum: ["activate", "deactivate"],
|
|
2573
|
+
description: "Whether to activate (load + apply the skill) or deactivate (release an active skill). Default: \"activate\"."
|
|
2574
|
+
}
|
|
2575
|
+
},
|
|
2423
2576
|
required: ["name"],
|
|
2424
2577
|
additionalProperties: false
|
|
2425
2578
|
}
|
|
@@ -2428,8 +2581,18 @@ function createSkillsUseTool(options) {
|
|
|
2428
2581
|
const skillName = input.name;
|
|
2429
2582
|
const skill = byName.get(skillName);
|
|
2430
2583
|
if (!skill) return `Error: unknown skill "${skillName}". Available skills: ${[...byName.keys()].join(", ") || "<none>"}.`;
|
|
2584
|
+
if ((input.mode ?? "activate") === "deactivate") {
|
|
2585
|
+
const removed = options.state.deactivate(skillName);
|
|
2586
|
+
if (!removed) return `Skill "${skillName}" was not active — nothing to deactivate.`;
|
|
2587
|
+
await options.hooks.callHook("skills:deactivate", {
|
|
2588
|
+
skill: removed.skill,
|
|
2589
|
+
reason: "model"
|
|
2590
|
+
});
|
|
2591
|
+
const remaining = options.state.active().map((a) => a.skill.name);
|
|
2592
|
+
return `Skill "${skillName}" deactivated — its allowed-tools restrictions no longer apply.${remaining.length > 0 ? ` Remaining active skills: ${remaining.join(", ")}.` : " No skills are currently active."}`;
|
|
2593
|
+
}
|
|
2431
2594
|
if (!options.state.isActive(skillName)) {
|
|
2432
|
-
if (options.state.activate(skill, "model") === "cap-reached") return `Error: cannot activate "${skillName}" — the maxActive skill cap has been reached. Currently active: ${options.state.active().map((a) => a.skill.name).join(", ")}.
|
|
2595
|
+
if (options.state.activate(skill, "model") === "cap-reached") return `Error: cannot activate "${skillName}" — the maxActive skill cap has been reached. Currently active: ${options.state.active().map((a) => a.skill.name).join(", ")}. Call \`skills_use\` with \`mode: "deactivate"\` and one of those names first.`;
|
|
2433
2596
|
await options.hooks.callHook("skills:activate", {
|
|
2434
2597
|
skill,
|
|
2435
2598
|
via: "model"
|
|
@@ -2590,9 +2753,11 @@ function createToolSearchTool(options) {
|
|
|
2590
2753
|
//#region src/agent.ts
|
|
2591
2754
|
const HOOK_EVENT_SET = new Set([
|
|
2592
2755
|
"system:before",
|
|
2756
|
+
"agent:start",
|
|
2593
2757
|
"turn:before",
|
|
2594
2758
|
"turn:after",
|
|
2595
2759
|
"tool-results:after",
|
|
2760
|
+
"stream:start",
|
|
2596
2761
|
"stream:text",
|
|
2597
2762
|
"stream:end",
|
|
2598
2763
|
"stream:thinking",
|
|
@@ -2603,6 +2768,7 @@ const HOOK_EVENT_SET = new Set([
|
|
|
2603
2768
|
"tool:before",
|
|
2604
2769
|
"tool:after",
|
|
2605
2770
|
"tool:error",
|
|
2771
|
+
"tool:cancelled",
|
|
2606
2772
|
"tool:transform",
|
|
2607
2773
|
"tool:unknown",
|
|
2608
2774
|
"validation:reject",
|
|
@@ -2624,6 +2790,7 @@ const HOOK_EVENT_SET = new Set([
|
|
|
2624
2790
|
"child:tool:after",
|
|
2625
2791
|
"child:tool:transform",
|
|
2626
2792
|
"child:tool:error",
|
|
2793
|
+
"child:tool:cancelled",
|
|
2627
2794
|
"child:turn:after",
|
|
2628
2795
|
"mcp:connect",
|
|
2629
2796
|
"mcp:error",
|
|
@@ -2649,6 +2816,7 @@ const HOOK_EVENT_SET = new Set([
|
|
|
2649
2816
|
"budget:exceeded",
|
|
2650
2817
|
"tool-budget:exceeded",
|
|
2651
2818
|
"pairing:repair",
|
|
2819
|
+
"tracing:redact",
|
|
2652
2820
|
"agent:abort",
|
|
2653
2821
|
"agent:done",
|
|
2654
2822
|
"session:start",
|
|
@@ -2902,6 +3070,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
2902
3070
|
let running = false;
|
|
2903
3071
|
let idleResolve;
|
|
2904
3072
|
let idlePromise;
|
|
3073
|
+
const pendingToolCancels = /* @__PURE__ */ new Map();
|
|
2905
3074
|
let executionHandle = null;
|
|
2906
3075
|
let mcpConnection = null;
|
|
2907
3076
|
let mcpWarmupPromise = null;
|
|
@@ -2983,6 +3152,16 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
2983
3152
|
prompt: promptLabel
|
|
2984
3153
|
});
|
|
2985
3154
|
}
|
|
3155
|
+
const runStartedAt = Date.now();
|
|
3156
|
+
await hooks.callHook("agent:start", {
|
|
3157
|
+
runId,
|
|
3158
|
+
...options.parentRunId ? { parentRunId: options.parentRunId } : {},
|
|
3159
|
+
depth: typeof options.depth === "number" ? options.depth : 0,
|
|
3160
|
+
...agentName ? { agentName } : {},
|
|
3161
|
+
...provider.name ? { providerName: provider.name } : {},
|
|
3162
|
+
startedAt: runStartedAt,
|
|
3163
|
+
...options.tracingContext ? { tracingContext: Object.freeze({ ...options.tracingContext }) } : {}
|
|
3164
|
+
});
|
|
2986
3165
|
if (externalSignal) if (externalSignal.aborted) abortController.abort();
|
|
2987
3166
|
else {
|
|
2988
3167
|
externalAbortListener = () => abortController?.abort();
|
|
@@ -3009,20 +3188,27 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3009
3188
|
await ensureSkillsResolved();
|
|
3010
3189
|
if (resolvedSkills && session && session.turns.length > 0 && skillActivationState.active().length === 0) {
|
|
3011
3190
|
const skillsByName = new Map(resolvedSkills.map((s) => [s.name, s]));
|
|
3191
|
+
const lastModeBySkill = /* @__PURE__ */ new Map();
|
|
3012
3192
|
for (const turn of session.turns) {
|
|
3013
3193
|
if (turn.role !== "assistant") continue;
|
|
3014
3194
|
for (const block of turn.content) {
|
|
3015
3195
|
if (block.type !== "tool_call" || block.name !== "skills_use") continue;
|
|
3016
|
-
const
|
|
3196
|
+
const input = block.input;
|
|
3197
|
+
const skillName = input?.name;
|
|
3017
3198
|
if (!skillName) continue;
|
|
3018
|
-
const
|
|
3019
|
-
|
|
3020
|
-
if (skillActivationState.activate(skill, "resume") === "ok") await hooks.callHook("skills:activate", {
|
|
3021
|
-
skill,
|
|
3022
|
-
via: "resume"
|
|
3023
|
-
});
|
|
3199
|
+
const mode = input?.mode === "deactivate" ? "deactivate" : "activate";
|
|
3200
|
+
lastModeBySkill.set(skillName, mode);
|
|
3024
3201
|
}
|
|
3025
3202
|
}
|
|
3203
|
+
for (const [skillName, mode] of lastModeBySkill) {
|
|
3204
|
+
if (mode !== "activate") continue;
|
|
3205
|
+
const skill = skillsByName.get(skillName);
|
|
3206
|
+
if (!skill) continue;
|
|
3207
|
+
if (skillActivationState.activate(skill, "resume") === "ok") await hooks.callHook("skills:activate", {
|
|
3208
|
+
skill,
|
|
3209
|
+
via: "resume"
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
3026
3212
|
}
|
|
3027
3213
|
const thinking = options.thinking ?? "off";
|
|
3028
3214
|
const model = options.model ?? provider.meta.defaultModel;
|
|
@@ -3220,7 +3406,8 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3220
3406
|
...strictToolPairing ? { strictToolPairing: true } : {},
|
|
3221
3407
|
providerName: provider.name,
|
|
3222
3408
|
runStartMs,
|
|
3223
|
-
runToolCounts: {}
|
|
3409
|
+
runToolCounts: {},
|
|
3410
|
+
pendingToolCancels
|
|
3224
3411
|
});
|
|
3225
3412
|
const parentTurnCost = stats.turnUsage?.reduce((sum, t) => sum + (t.cost ?? 0), 0) ?? 0;
|
|
3226
3413
|
let childrenIn = 0;
|
|
@@ -3317,6 +3504,12 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3317
3504
|
function abort() {
|
|
3318
3505
|
abortController?.abort();
|
|
3319
3506
|
}
|
|
3507
|
+
function cancelTool(callId, reason) {
|
|
3508
|
+
const controller = pendingToolCancels.get(callId);
|
|
3509
|
+
if (!controller || controller.signal.aborted) return false;
|
|
3510
|
+
controller.abort(reason ?? "user-cancelled-tool");
|
|
3511
|
+
return true;
|
|
3512
|
+
}
|
|
3320
3513
|
function steer(message) {
|
|
3321
3514
|
steeringQueue.push(message);
|
|
3322
3515
|
}
|
|
@@ -3410,6 +3603,8 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3410
3603
|
async function destroy() {
|
|
3411
3604
|
if (destroyed) return;
|
|
3412
3605
|
destroyed = true;
|
|
3606
|
+
for (const controller of pendingToolCancels.values()) if (!controller.signal.aborted) controller.abort("agent-destroyed");
|
|
3607
|
+
pendingToolCancels.clear();
|
|
3413
3608
|
if (mcpWarmupPromise) try {
|
|
3414
3609
|
await mcpWarmupPromise;
|
|
3415
3610
|
} catch {}
|
|
@@ -3430,6 +3625,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
3430
3625
|
hooks,
|
|
3431
3626
|
run,
|
|
3432
3627
|
abort,
|
|
3628
|
+
cancelTool,
|
|
3433
3629
|
steer,
|
|
3434
3630
|
followUp: followUpFn,
|
|
3435
3631
|
waitForIdle,
|
|
@@ -4821,6 +5017,7 @@ const BUBBLED_EVENTS = [
|
|
|
4821
5017
|
"tool:before",
|
|
4822
5018
|
"tool:after",
|
|
4823
5019
|
"tool:error",
|
|
5020
|
+
"tool:cancelled",
|
|
4824
5021
|
"turn:after"
|
|
4825
5022
|
];
|
|
4826
5023
|
const BUBBLED_MUTABLE_EVENTS = [
|
|
@@ -4837,6 +5034,7 @@ const CHILD_EVENT_NAME = {
|
|
|
4837
5034
|
"tool:before": "child:tool:before",
|
|
4838
5035
|
"tool:after": "child:tool:after",
|
|
4839
5036
|
"tool:error": "child:tool:error",
|
|
5037
|
+
"tool:cancelled": "child:tool:cancelled",
|
|
4840
5038
|
"turn:after": "child:turn:after"
|
|
4841
5039
|
};
|
|
4842
5040
|
const CHILD_MUTABLE_EVENT_NAME = {
|
|
@@ -5065,7 +5263,7 @@ function createSpawnTool(options = {}) {
|
|
|
5065
5263
|
});
|
|
5066
5264
|
if (forwardHooks) {
|
|
5067
5265
|
const unregisterEnricher = agent.hooks.hook("tool:before", async (toolCtx) => {
|
|
5068
|
-
if (toolCtx.name !== "write_file") return;
|
|
5266
|
+
if (toolCtx.name !== "write_file" && toolCtx.name !== "edit" && toolCtx.name !== "multi_edit") return;
|
|
5069
5267
|
if (!agent.handle) return;
|
|
5070
5268
|
const inputPath = toolCtx.input?.path;
|
|
5071
5269
|
if (typeof inputPath !== "string") return;
|
|
@@ -5080,11 +5278,14 @@ function createSpawnTool(options = {}) {
|
|
|
5080
5278
|
};
|
|
5081
5279
|
}
|
|
5082
5280
|
options.onSpawn?.(child);
|
|
5083
|
-
|
|
5281
|
+
const spawnHookCtx = {
|
|
5084
5282
|
id,
|
|
5085
5283
|
task,
|
|
5086
|
-
depth: childDepth
|
|
5087
|
-
|
|
5284
|
+
depth: childDepth,
|
|
5285
|
+
tracingContext: {}
|
|
5286
|
+
};
|
|
5287
|
+
await ctx.hooks.callHook("spawn:before", spawnHookCtx);
|
|
5288
|
+
const propagatedTracing = Object.keys(spawnHookCtx.tracingContext).length > 0 ? Object.freeze({ ...spawnHookCtx.tracingContext }) : void 0;
|
|
5088
5289
|
const runPromise = agent.run({
|
|
5089
5290
|
prompt: task,
|
|
5090
5291
|
model: options.model,
|
|
@@ -5092,7 +5293,8 @@ function createSpawnTool(options = {}) {
|
|
|
5092
5293
|
thinking: options.thinking,
|
|
5093
5294
|
signal: ctx.signal,
|
|
5094
5295
|
depth: childDepth,
|
|
5095
|
-
...options.persist && ctx.runId ? { parentRunId: ctx.runId } : {}
|
|
5296
|
+
...options.persist && ctx.runId ? { parentRunId: ctx.runId } : {},
|
|
5297
|
+
...propagatedTracing ? { tracingContext: propagatedTracing } : {}
|
|
5096
5298
|
});
|
|
5097
5299
|
try {
|
|
5098
5300
|
finalStats = await raceWithTimeout(runPromise, options.timeoutMs);
|
|
@@ -5236,6 +5438,6 @@ const writeFile$1 = {
|
|
|
5236
5438
|
}
|
|
5237
5439
|
};
|
|
5238
5440
|
//#endregion
|
|
5239
|
-
export {
|
|
5441
|
+
export { hashContent as A, PERSISTED_STUB_PREFIX as C, maybePersistToolResult as D, cleanupPersistedSession as E, resolveReadStateMap as M, resolvePersistDir as O, validateToolArgs as S, buildPersistedStub as T, createSkillsReadTool as _, multiEdit as a, TOOL_USE_CANCELLED_MESSAGE as b, grep as c, resolveOldString as d, styleReplacementForVia as f, createSkillsRunScriptTool as g, createSkillsUseTool as h, readFile$1 as i, readStateKey as j, getReadState as k, glob as l, createToolSearchTool as m, createSpawnTool as n, listFiles as o, createAgent as p, shell as r, createInteractionTool as s, writeFile$1 as t, edit as u, INTERRUPT_MESSAGE_FOR_TOOL_USE as v, PERSISTENCE_PREVIEW_BYTES as w, TOOL_USE_SKIPPED_MESSAGE as x, SHELL_CASCADE_CANCEL_MESSAGE as y };
|
|
5240
5442
|
|
|
5241
|
-
//# sourceMappingURL=tools-
|
|
5443
|
+
//# sourceMappingURL=tools-BK2vG9UX.js.map
|