@letta-ai/letta-code 0.34.18 → 0.34.19
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/gateway-core.js +2 -2
- package/dist/gateway-core.js.map +3 -3
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/mcp-oauth.js +2 -2
- package/dist/mcp-oauth.js.map +1 -1
- package/dist/types/agent/approval-execution.d.ts +33 -1
- package/dist/types/agent/approval-execution.d.ts.map +1 -1
- package/dist/types/agent/parent-memory-note.d.ts +3 -0
- package/dist/types/agent/parent-memory-note.d.ts.map +1 -0
- package/dist/types/agent/skills.d.ts.map +1 -1
- package/dist/types/agent/subagent-state.d.ts +53 -2
- package/dist/types/agent/subagent-state.d.ts.map +1 -1
- package/dist/types/channels/message-channel-executor.d.ts.map +1 -1
- package/dist/types/cli/helpers/agent-info.d.ts +1 -0
- package/dist/types/cli/helpers/agent-info.d.ts.map +1 -1
- package/dist/types/cli/subcommands/mcp.d.ts +3 -1
- package/dist/types/cli/subcommands/mcp.d.ts.map +1 -1
- package/dist/types/reminders/engine.d.ts.map +1 -1
- package/dist/types/telemetry/channel.d.ts.map +1 -1
- package/dist/types/tools/external-tool-background-eligibility.d.ts +2 -1
- package/dist/types/tools/external-tool-background-eligibility.d.ts.map +1 -1
- package/dist/types/tools/external-tool-background.d.ts +14 -1
- package/dist/types/tools/external-tool-background.d.ts.map +1 -1
- package/dist/types/tools/external-tool-types.d.ts +1 -0
- package/dist/types/tools/external-tool-types.d.ts.map +1 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/monitor.d.ts +2 -0
- package/dist/types/tools/impl/monitor.d.ts.map +1 -1
- package/dist/types/tools/impl/task-abort-hook.d.ts +2 -0
- package/dist/types/tools/impl/task-abort-hook.d.ts.map +1 -0
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/tools/impl/watch-pr.d.ts +1 -1
- package/dist/types/tools/impl/watch-pr.d.ts.map +1 -1
- package/dist/types/tools/impl/workflow.d.ts +2 -0
- package/dist/types/tools/impl/workflow.d.ts.map +1 -1
- package/dist/types/tools/manager.d.ts +1 -1
- package/dist/types/tools/manager.d.ts.map +1 -1
- package/dist/types/tools/script-tool-scope.d.ts.map +1 -1
- package/dist/types/utils/subagent-scope.d.ts +13 -0
- package/dist/types/utils/subagent-scope.d.ts.map +1 -0
- package/dist/types/utils/task-notifications.d.ts +43 -0
- package/dist/types/utils/task-notifications.d.ts.map +1 -1
- package/letta.js +835 -288
- package/npm-shrinkwrap.json +14 -14
- package/package.json +2 -2
- package/scripts/claude-watch/docs-snapshot.test.ts +65 -0
- package/scripts/claude-watch/docs-snapshot.ts +10 -4
- package/scripts/isolated-unit-tests.json +5 -0
- package/scripts/source-file-size-baseline.json +8 -8
- package/skills/finding-agents/SKILL.md +0 -4
- package/skills/curating-memory-palace/SKILL.md +0 -147
- package/skills/migrating-memory/SKILL.md +0 -98
package/letta.js
CHANGED
|
@@ -5941,7 +5941,7 @@ var package_default;
|
|
|
5941
5941
|
var init_package = __esm(() => {
|
|
5942
5942
|
package_default = {
|
|
5943
5943
|
name: "@letta-ai/letta-code",
|
|
5944
|
-
version: "0.34.
|
|
5944
|
+
version: "0.34.19",
|
|
5945
5945
|
lettaStartupLogProtocol: 1,
|
|
5946
5946
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5947
5947
|
type: "module",
|
|
@@ -6216,7 +6216,7 @@ var init_package = __esm(() => {
|
|
|
6216
6216
|
},
|
|
6217
6217
|
lettaLifecycleProtocol: 1,
|
|
6218
6218
|
lettaRuntimeGraphProtocol: 1,
|
|
6219
|
-
lettaRuntimeGraphSha512: "sha512-
|
|
6219
|
+
lettaRuntimeGraphSha512: "sha512-RWgzMK/RLJluHmJEAXwWV7NZe1gpOgg3BYpp8+G8QfqsXUUmzZgQpQz5E9CHogeIwfcGzCaHAUIdboH6Ir7KyA=="
|
|
6220
6220
|
};
|
|
6221
6221
|
});
|
|
6222
6222
|
|
|
@@ -6488,6 +6488,7 @@ function telemetryChannel(value) {
|
|
|
6488
6488
|
return;
|
|
6489
6489
|
return [
|
|
6490
6490
|
"slack",
|
|
6491
|
+
"microsoftteams",
|
|
6491
6492
|
"microsoftTeams",
|
|
6492
6493
|
"telegram",
|
|
6493
6494
|
"discord",
|
|
@@ -172634,6 +172635,16 @@ var init_message_queue_bridge = __esm(() => {
|
|
|
172634
172635
|
pendingMessages = [];
|
|
172635
172636
|
});
|
|
172636
172637
|
|
|
172638
|
+
// src/utils/subagent-scope.ts
|
|
172639
|
+
function subagentScopeMatches(parentAgentId, parentConversationId, scope) {
|
|
172640
|
+
if (scope.agentId !== undefined && parentAgentId !== scope.agentId) {
|
|
172641
|
+
return false;
|
|
172642
|
+
}
|
|
172643
|
+
if (scope.conversationId === undefined)
|
|
172644
|
+
return true;
|
|
172645
|
+
return parentConversationId === undefined || parentConversationId === scope.conversationId;
|
|
172646
|
+
}
|
|
172647
|
+
|
|
172637
172648
|
// src/utils/task-notifications.ts
|
|
172638
172649
|
function escapeXml(str) {
|
|
172639
172650
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
@@ -172742,6 +172753,47 @@ function appendTaskNotificationEventsToBuffer(summaries, buffer, generateId, flu
|
|
|
172742
172753
|
flush?.();
|
|
172743
172754
|
return true;
|
|
172744
172755
|
}
|
|
172756
|
+
function selectStopFailedNotifications(rows, seenIds, scope) {
|
|
172757
|
+
const failures = [];
|
|
172758
|
+
const stops = [];
|
|
172759
|
+
for (const row of rows) {
|
|
172760
|
+
if (!subagentScopeMatches(row.parentAgentId, row.parentConversationId, scope)) {
|
|
172761
|
+
continue;
|
|
172762
|
+
}
|
|
172763
|
+
if (row.stopFailed && (row.status === "pending" || row.status === "running")) {
|
|
172764
|
+
const key2 = `${row.id}:${row.stopOutcome?.attempt ?? 0}`;
|
|
172765
|
+
if (!seenIds.has(key2)) {
|
|
172766
|
+
seenIds.add(key2);
|
|
172767
|
+
failures.push(`Background task "${row.description}" could not be stopped — still running remotely. Press Esc to retry.`);
|
|
172768
|
+
}
|
|
172769
|
+
continue;
|
|
172770
|
+
}
|
|
172771
|
+
if (row.stopOutcome?.kind === "stopped" && row.status === "error") {
|
|
172772
|
+
const key2 = `${row.id}:${row.stopOutcome.attempt}`;
|
|
172773
|
+
if (!seenIds.has(key2)) {
|
|
172774
|
+
let surfacedEarlierFailure = false;
|
|
172775
|
+
for (let attempt2 = 0;attempt2 < row.stopOutcome.attempt; attempt2 += 1) {
|
|
172776
|
+
if (seenIds.has(`${row.id}:${attempt2}`)) {
|
|
172777
|
+
surfacedEarlierFailure = true;
|
|
172778
|
+
break;
|
|
172779
|
+
}
|
|
172780
|
+
}
|
|
172781
|
+
if (surfacedEarlierFailure) {
|
|
172782
|
+
seenIds.add(key2);
|
|
172783
|
+
stops.push(`Background task "${row.description}" stopped.`);
|
|
172784
|
+
}
|
|
172785
|
+
}
|
|
172786
|
+
}
|
|
172787
|
+
}
|
|
172788
|
+
const present = new Set(rows.map((row) => row.id));
|
|
172789
|
+
for (const key2 of seenIds) {
|
|
172790
|
+
const rowId = key2.slice(0, key2.lastIndexOf(":"));
|
|
172791
|
+
if (!present.has(rowId)) {
|
|
172792
|
+
seenIds.delete(key2);
|
|
172793
|
+
}
|
|
172794
|
+
}
|
|
172795
|
+
return { failures, stops };
|
|
172796
|
+
}
|
|
172745
172797
|
var init_task_notifications = __esm(() => {
|
|
172746
172798
|
init_context();
|
|
172747
172799
|
init_constants2();
|
|
@@ -210828,7 +210880,7 @@ var init_mcp_client = __esm(() => {
|
|
|
210828
210880
|
init_streamableHttp();
|
|
210829
210881
|
DEFAULT_CLIENT_INFO = {
|
|
210830
210882
|
name: "letta-code",
|
|
210831
|
-
version: "0.34.
|
|
210883
|
+
version: "0.34.19"
|
|
210832
210884
|
};
|
|
210833
210885
|
});
|
|
210834
210886
|
|
|
@@ -214963,7 +215015,7 @@ Do not use this tool for root memory files (already loaded) or skills/ (use Skil
|
|
|
214963
215015
|
var init_Memory = () => {};
|
|
214964
215016
|
|
|
214965
215017
|
// src/tools/descriptions/Monitor.md
|
|
214966
|
-
var Monitor_default = 'Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you\'re waiting for the user to answer a question.\n\nPick by how many notifications you need:\n- **One** ("tell me when the server is ready / the build finishes") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q "Ready in" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.\n- **One per occurrence, indefinitely** ("tell me every time an ERROR line appears") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).\n- **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") → Monitor with a command that emits lines and then exits.\n\nYour script\'s stdout is the event stream. Each line becomes a notification. Exit ends the watch.\n # Each matching log line is an event\n tail -f /var/log/app.log | grep --line-buffered "ERROR"\n # Each file change is an event\n inotifywait -m --format \'%e %f\' /watched/dir\n # Node script that emits events as they arrive (e.g. WebSocket listener)\n node watch-for-events.js\n\nFor open github.com pull requests, use WatchPR instead. It covers the whole PR surface and keeps watching after CI finishes. Use Monitor only when WatchPR does not apply.\n\n**Don\'t use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.\n\n- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.\n- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn\'t kill the monitor.\n- Poll intervals: 30s+ for remote APIs (rate limits), 0.5–1s for local checks.\n- Write a specific `description` — it appears in every notification ("errors in deploy.log" not "watching logs").\n- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)\n\n**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.\n # Wrong — silent on crash, hang, or any non-success exit\n tail -f run.log | grep --line-buffered "elapsed_steps="\n # Right — one alternation covering progress + the failure signatures you\'d act on\n tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"\n\nFor poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.\n\n**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means "the lines you\'d act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.\n\nStdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.\n\nThe script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Timeout → killed. Set `persistent: true` for session-length watches (log tails, long-lived event streams)
|
|
215018
|
+
var Monitor_default = 'Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you\'re waiting for the user to answer a question.\n\nPick by how many notifications you need:\n- **One** ("tell me when the server is ready / the build finishes") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q "Ready in" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.\n- **One per occurrence, indefinitely** ("tell me every time an ERROR line appears") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).\n- **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") → Monitor with a command that emits lines and then exits.\n\nYour script\'s stdout is the event stream. Each line becomes a notification. Exit ends the watch.\n # Each matching log line is an event\n tail -f /var/log/app.log | grep --line-buffered "ERROR"\n # Each file change is an event\n inotifywait -m --format \'%e %f\' /watched/dir\n # Node script that emits events as they arrive (e.g. WebSocket listener)\n node watch-for-events.js\n\nFor open github.com pull requests, use WatchPR instead. It covers the whole PR surface and keeps watching after CI finishes. Use Monitor only when WatchPR does not apply.\n\n**Don\'t use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.\n\n- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.\n- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn\'t kill the monitor.\n- Poll intervals: 30s+ for remote APIs (rate limits), 0.5–1s for local checks.\n- Write a specific `description` — it appears in every notification ("errors in deploy.log" not "watching logs").\n- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)\n\n**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.\n # Wrong — silent on crash, hang, or any non-success exit\n tail -f run.log | grep --line-buffered "elapsed_steps="\n # Right — one alternation covering progress + the failure signatures you\'d act on\n tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"\n\nFor poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.\n\n**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means "the lines you\'d act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.\n\nStdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.\n\nThe script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Timeout → killed. Set `persistent: true` for session-length watches (log tails, long-lived event streams). In managed Cloud sandboxes, every monitor stops after at most 1 hour, including persistent monitors; elsewhere persistent monitors run until TaskStop or session end. For longer Cloud waits, schedule a Wake or cron (which does not keep the sandbox running between turns) and combine it with shorter monitors. Use TaskStop to cancel early.\n\nWhen someone is waiting on the result, set `backup_after_seconds` (e.g. 900). If the monitor goes that long without an event, a durable Wake brings you back to check the real state, so a queued, hung, or dead watch can\'t leave them waiting in silence.\n\n**ws source** — open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.\n ws: {url: \'wss://events.example.com/stream\', protocols: [\'v1\']},\n description: \'deploy events\',\n\nEach text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as `[binary frame, N bytes]` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash — a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.\n\nPrefer this over `command: \'websocat wss://…\'` — it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.\n';
|
|
214967
215019
|
var init_Monitor = () => {};
|
|
214968
215020
|
|
|
214969
215021
|
// src/tools/descriptions/Read.md
|
|
@@ -215486,6 +215538,8 @@ var init_Wake = () => {};
|
|
|
215486
215538
|
// src/tools/descriptions/WatchPR.md
|
|
215487
215539
|
var WatchPR_default = `Watch one open github.com pull request until it merges, closes, is stopped with TaskStop, or the session ends.
|
|
215488
215540
|
|
|
215541
|
+
In managed Cloud sandboxes, WatchPR also stops after a hard 1-hour limit and sends a timeout notification. For checks beyond that window, use Wake or cron (which does not keep the sandbox running between turns) and combine it with shorter watches. Local watches have no duration limit.
|
|
215542
|
+
|
|
215489
215543
|
Use WatchPR instead of writing a Monitor or shell polling loop when you need ongoing notifications about a PR. Start at most one watch per PR. It reports:
|
|
215490
215544
|
|
|
215491
215545
|
- current-head check failures, recoveries, retries, and completion;
|
|
@@ -221142,12 +221196,55 @@ var init_disk_space = __esm(() => {
|
|
|
221142
221196
|
var exports_approval_execution = {};
|
|
221143
221197
|
__export(exports_approval_execution, {
|
|
221144
221198
|
settleApprovalExecutionTasks: () => settleApprovalExecutionTasks,
|
|
221199
|
+
overlayPartialResults: () => overlayPartialResults,
|
|
221200
|
+
isUserAbortError: () => isUserAbortError,
|
|
221145
221201
|
getResourceKey: () => getResourceKey,
|
|
221146
221202
|
getDisplayableToolReturn: () => getDisplayableToolReturn,
|
|
221147
221203
|
executeAutoAllowedTools: () => executeAutoAllowedTools,
|
|
221148
|
-
executeApprovalBatch: () => executeApprovalBatch
|
|
221204
|
+
executeApprovalBatch: () => executeApprovalBatch,
|
|
221205
|
+
buildDeniedResults: () => buildDeniedResults,
|
|
221206
|
+
buildCompanionResults: () => buildCompanionResults,
|
|
221207
|
+
appendAbortPartials: () => appendAbortPartials,
|
|
221208
|
+
ABORT_GRACE_MS: () => ABORT_GRACE_MS
|
|
221149
221209
|
});
|
|
221150
221210
|
import * as path16 from "node:path";
|
|
221211
|
+
function isUserAbortError(error5) {
|
|
221212
|
+
return error5 instanceof APIUserAbortError || error5 instanceof Error && (error5.name === "AbortError" || error5.message === INTERRUPTED_BY_USER || error5.message === "The operation was aborted");
|
|
221213
|
+
}
|
|
221214
|
+
function overlayPartialResults(queued, partials) {
|
|
221215
|
+
const realById = new Map((partials ?? []).map((r5) => [r5.tool_call_id, r5]));
|
|
221216
|
+
const overlaid = (queued ?? []).map((r5) => realById.get(r5.tool_call_id) ?? r5);
|
|
221217
|
+
const queuedIds = new Set((queued ?? []).map((r5) => r5.tool_call_id));
|
|
221218
|
+
const extras = (partials ?? []).filter((r5) => !queuedIds.has(r5.tool_call_id));
|
|
221219
|
+
return [...overlaid, ...extras];
|
|
221220
|
+
}
|
|
221221
|
+
function buildDeniedResults(autoDenied) {
|
|
221222
|
+
return autoDenied.map((ad) => ({
|
|
221223
|
+
type: "approval",
|
|
221224
|
+
tool_call_id: ad.approval.toolCallId,
|
|
221225
|
+
approve: false,
|
|
221226
|
+
reason: ad.reason
|
|
221227
|
+
}));
|
|
221228
|
+
}
|
|
221229
|
+
function buildCompanionResults(autoHandled, autoDenied) {
|
|
221230
|
+
return [
|
|
221231
|
+
...autoHandled.map((ar) => ({
|
|
221232
|
+
type: "tool",
|
|
221233
|
+
tool_call_id: ar.toolCallId,
|
|
221234
|
+
tool_return: ar.result.toolReturn,
|
|
221235
|
+
status: ar.result.status,
|
|
221236
|
+
stdout: ar.result.stdout,
|
|
221237
|
+
stderr: ar.result.stderr
|
|
221238
|
+
})),
|
|
221239
|
+
...buildDeniedResults(autoDenied)
|
|
221240
|
+
];
|
|
221241
|
+
}
|
|
221242
|
+
function appendAbortPartials(error5, extras) {
|
|
221243
|
+
if (extras.length === 0 || !isUserAbortError(error5))
|
|
221244
|
+
return;
|
|
221245
|
+
const abortError = error5;
|
|
221246
|
+
abortError.partialResults = [...abortError.partialResults ?? [], ...extras];
|
|
221247
|
+
}
|
|
221151
221248
|
function getDisplayableToolReturn(content) {
|
|
221152
221249
|
if (typeof content === "string") {
|
|
221153
221250
|
return content;
|
|
@@ -221284,8 +221381,61 @@ async function executeSingleDecision(decision, onChunk, options) {
|
|
|
221284
221381
|
async function executeApprovalBatch(decisions, onChunk, options) {
|
|
221285
221382
|
return watchDiskSpaceDuring(options?.workingDirectory ?? getCurrentWorkingDirectory(), (text2) => deliverDiskSpaceReminder(text2, options?.parentScope), () => executeApprovalBatchUnwatched(decisions, onChunk, options));
|
|
221286
221383
|
}
|
|
221287
|
-
async function settleApprovalExecutionTasks(tasks, partialResults = () => []) {
|
|
221288
|
-
const
|
|
221384
|
+
async function settleApprovalExecutionTasks(tasks, partialResults = () => [], options) {
|
|
221385
|
+
const signal = options?.abortSignal;
|
|
221386
|
+
if (!signal || signal.aborted) {
|
|
221387
|
+
throwFirstSettledRejection(await Promise.allSettled(tasks), partialResults);
|
|
221388
|
+
return;
|
|
221389
|
+
}
|
|
221390
|
+
const settled = new Array(tasks.length);
|
|
221391
|
+
let remaining = tasks.length;
|
|
221392
|
+
const tracked = tasks.map((task, index) => task.then(() => {
|
|
221393
|
+
settled[index] = { status: "fulfilled", value: undefined };
|
|
221394
|
+
}, (reason) => {
|
|
221395
|
+
settled[index] = { status: "rejected", reason };
|
|
221396
|
+
}).finally(() => {
|
|
221397
|
+
remaining -= 1;
|
|
221398
|
+
}));
|
|
221399
|
+
let onAbort = () => {};
|
|
221400
|
+
const aborted2 = new Promise((resolve20) => {
|
|
221401
|
+
onAbort = resolve20;
|
|
221402
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
221403
|
+
});
|
|
221404
|
+
try {
|
|
221405
|
+
await Promise.race([Promise.all(tracked).then(() => {
|
|
221406
|
+
return;
|
|
221407
|
+
}), aborted2]);
|
|
221408
|
+
} finally {
|
|
221409
|
+
signal.removeEventListener("abort", onAbort);
|
|
221410
|
+
}
|
|
221411
|
+
if (remaining === 0) {
|
|
221412
|
+
throwFirstSettledRejection(settled, partialResults);
|
|
221413
|
+
return;
|
|
221414
|
+
}
|
|
221415
|
+
let graceTimer;
|
|
221416
|
+
const graceExpired = new Promise((resolve20) => {
|
|
221417
|
+
graceTimer = setTimeout(resolve20, ABORT_GRACE_MS);
|
|
221418
|
+
});
|
|
221419
|
+
try {
|
|
221420
|
+
await Promise.race([
|
|
221421
|
+
Promise.all(tracked).then(() => {
|
|
221422
|
+
return;
|
|
221423
|
+
}),
|
|
221424
|
+
graceExpired
|
|
221425
|
+
]);
|
|
221426
|
+
} finally {
|
|
221427
|
+
clearTimeout(graceTimer);
|
|
221428
|
+
}
|
|
221429
|
+
if (remaining === 0) {
|
|
221430
|
+
throwFirstSettledRejection(settled, partialResults);
|
|
221431
|
+
return;
|
|
221432
|
+
}
|
|
221433
|
+
throwFirstSettledRejection(settled.filter((result2) => result2 !== undefined), partialResults);
|
|
221434
|
+
const error5 = signal.reason instanceof Error ? signal.reason : new Error(INTERRUPTED_BY_USER);
|
|
221435
|
+
Object.assign(error5, { partialResults: partialResults() });
|
|
221436
|
+
throw error5;
|
|
221437
|
+
}
|
|
221438
|
+
function throwFirstSettledRejection(settled, partialResults) {
|
|
221289
221439
|
for (const result2 of settled) {
|
|
221290
221440
|
if (result2.status !== "rejected")
|
|
221291
221441
|
continue;
|
|
@@ -221299,6 +221449,19 @@ async function executeApprovalBatchUnwatched(decisions, onChunk, options) {
|
|
|
221299
221449
|
workingDirectory: options.workingDirectory
|
|
221300
221450
|
})).contextId : undefined);
|
|
221301
221451
|
const results = new Array(decisions.length).fill(null);
|
|
221452
|
+
let batchDiscarded = false;
|
|
221453
|
+
const guardedOnChunk = onChunk ? (chunk2) => {
|
|
221454
|
+
if (!batchDiscarded)
|
|
221455
|
+
onChunk(chunk2);
|
|
221456
|
+
} : undefined;
|
|
221457
|
+
const guardedOptions = options?.onStreamingOutput ? {
|
|
221458
|
+
...options,
|
|
221459
|
+
onStreamingOutput: (toolCallId, chunk2, isStderr) => {
|
|
221460
|
+
if (!batchDiscarded) {
|
|
221461
|
+
options.onStreamingOutput?.(toolCallId, chunk2, isStderr);
|
|
221462
|
+
}
|
|
221463
|
+
}
|
|
221464
|
+
} : options;
|
|
221302
221465
|
const parallelIndices = [];
|
|
221303
221466
|
const writeToolsByResource = new Map;
|
|
221304
221467
|
const denyIndices = [];
|
|
@@ -221334,11 +221497,11 @@ async function executeApprovalBatchUnwatched(decisions, onChunk, options) {
|
|
|
221334
221497
|
const decision = decisions[i4];
|
|
221335
221498
|
if (decision) {
|
|
221336
221499
|
let crossedEffectBoundary = false;
|
|
221337
|
-
const result2 = await executeSingleDecision(decision,
|
|
221338
|
-
...
|
|
221500
|
+
const result2 = await executeSingleDecision(decision, guardedOnChunk, {
|
|
221501
|
+
...guardedOptions,
|
|
221339
221502
|
toolContextId,
|
|
221340
221503
|
beforeToolExecution: async (toolCallId) => {
|
|
221341
|
-
await
|
|
221504
|
+
await guardedOptions?.beforeToolExecution?.(toolCallId);
|
|
221342
221505
|
crossedEffectBoundary = true;
|
|
221343
221506
|
}
|
|
221344
221507
|
});
|
|
@@ -221348,15 +221511,20 @@ async function executeApprovalBatchUnwatched(decisions, onChunk, options) {
|
|
|
221348
221511
|
}
|
|
221349
221512
|
}
|
|
221350
221513
|
};
|
|
221351
|
-
|
|
221352
|
-
|
|
221353
|
-
|
|
221354
|
-
|
|
221355
|
-
|
|
221356
|
-
|
|
221357
|
-
|
|
221358
|
-
|
|
221359
|
-
|
|
221514
|
+
try {
|
|
221515
|
+
await settleApprovalExecutionTasks([
|
|
221516
|
+
...parallelIndices.map(execute),
|
|
221517
|
+
...denyIndices.map(execute),
|
|
221518
|
+
...Array.from(writeToolsByResource.values()).map(async (indices) => {
|
|
221519
|
+
for (const i4 of indices) {
|
|
221520
|
+
await execute(i4);
|
|
221521
|
+
}
|
|
221522
|
+
})
|
|
221523
|
+
], () => results.filter((result2) => result2 !== null), { abortSignal: options?.abortSignal });
|
|
221524
|
+
} catch (error5) {
|
|
221525
|
+
batchDiscarded = true;
|
|
221526
|
+
throw error5;
|
|
221527
|
+
}
|
|
221360
221528
|
return results.filter((r5) => r5 !== null);
|
|
221361
221529
|
}
|
|
221362
221530
|
async function executeAutoAllowedTools(autoAllowed, onChunk, options) {
|
|
@@ -221375,8 +221543,9 @@ async function executeAutoAllowedTools(autoAllowed, onChunk, options) {
|
|
|
221375
221543
|
}
|
|
221376
221544
|
}));
|
|
221377
221545
|
}
|
|
221378
|
-
var PARALLEL_SAFE_TOOLS, FILE_PATH_TOOLS, GLOBAL_LOCK_TOOLS;
|
|
221546
|
+
var ABORT_GRACE_MS = 500, PARALLEL_SAFE_TOOLS, FILE_PATH_TOOLS, GLOBAL_LOCK_TOOLS;
|
|
221379
221547
|
var init_approval_execution = __esm(async () => {
|
|
221548
|
+
init_error();
|
|
221380
221549
|
init_constants2();
|
|
221381
221550
|
init_disk_space();
|
|
221382
221551
|
init_runtime_context();
|
|
@@ -222374,14 +222543,23 @@ function scheduleCompletedSubagentCleanup(id2) {
|
|
|
222374
222543
|
return;
|
|
222375
222544
|
}
|
|
222376
222545
|
clearCompletedSubagentCleanup(id2);
|
|
222546
|
+
armCompletedSubagentCleanup(id2);
|
|
222547
|
+
}
|
|
222548
|
+
function armCompletedSubagentCleanup(id2) {
|
|
222549
|
+
const agent = store2.agents.get(id2);
|
|
222550
|
+
if (!agent)
|
|
222551
|
+
return;
|
|
222377
222552
|
const timer = setTimeout(() => {
|
|
222553
|
+
completedSubagentCleanupTimers.delete(id2);
|
|
222378
222554
|
const current = store2.agents.get(id2);
|
|
222379
222555
|
if (!current || current.status !== "completed" && current.status !== "error") {
|
|
222380
|
-
|
|
222556
|
+
return;
|
|
222557
|
+
}
|
|
222558
|
+
if (current.cancelPending) {
|
|
222559
|
+
armCompletedSubagentCleanup(id2);
|
|
222381
222560
|
return;
|
|
222382
222561
|
}
|
|
222383
222562
|
store2.agents.delete(id2);
|
|
222384
|
-
completedSubagentCleanupTimers.delete(id2);
|
|
222385
222563
|
notifyListeners();
|
|
222386
222564
|
}, agent.result !== undefined ? publishedResultRetentionMs : completedSubagentRetentionMs);
|
|
222387
222565
|
unrefTimer2(timer);
|
|
@@ -222471,6 +222649,7 @@ function completeSubagent(id2, result2) {
|
|
|
222471
222649
|
...agent,
|
|
222472
222650
|
status: result2.success ? "completed" : "error",
|
|
222473
222651
|
error: result2.error,
|
|
222652
|
+
stopFailed: undefined,
|
|
222474
222653
|
...result2.result !== undefined ? { result: result2.result } : {},
|
|
222475
222654
|
durationMs: Date.now() - agent.startTime,
|
|
222476
222655
|
totalTokens: result2.totalTokens ?? agent.totalTokens,
|
|
@@ -222527,6 +222706,8 @@ function clearCompletedSubagents() {
|
|
|
222527
222706
|
for (const [id2, agent] of store2.agents.entries()) {
|
|
222528
222707
|
if (agent.result !== undefined)
|
|
222529
222708
|
continue;
|
|
222709
|
+
if (agent.cancelPending)
|
|
222710
|
+
continue;
|
|
222530
222711
|
if (agent.status === "completed" || agent.status === "error") {
|
|
222531
222712
|
clearCompletedSubagentCleanup(id2);
|
|
222532
222713
|
store2.agents.delete(id2);
|
|
@@ -222540,6 +222721,11 @@ function clearCompletedSubagents() {
|
|
|
222540
222721
|
function clearSubagentsByIds(ids) {
|
|
222541
222722
|
let removedAny = false;
|
|
222542
222723
|
for (const id2 of ids) {
|
|
222724
|
+
const agent = store2.agents.get(id2);
|
|
222725
|
+
if (agent?.cancelPending) {
|
|
222726
|
+
updateSubagent(id2, { silent: true });
|
|
222727
|
+
continue;
|
|
222728
|
+
}
|
|
222543
222729
|
clearCompletedSubagentCleanup(id2);
|
|
222544
222730
|
removedAny = store2.agents.delete(id2) || removedAny;
|
|
222545
222731
|
}
|
|
@@ -222555,15 +222741,28 @@ function hasActiveSubagents() {
|
|
|
222555
222741
|
}
|
|
222556
222742
|
return false;
|
|
222557
222743
|
}
|
|
222558
|
-
function
|
|
222744
|
+
function registerSubagentAbortHook(id2, hook) {
|
|
222745
|
+
subagentAbortHooks.set(id2, hook);
|
|
222746
|
+
}
|
|
222747
|
+
function clearSubagentAbortHook(id2) {
|
|
222748
|
+
subagentAbortHooks.delete(id2);
|
|
222749
|
+
}
|
|
222750
|
+
function interruptActiveSubagents(errorMessage, scope) {
|
|
222559
222751
|
let anyInterrupted = false;
|
|
222560
222752
|
for (const [id2, agent] of store2.agents.entries()) {
|
|
222561
222753
|
if (agent.status === "pending" || agent.status === "running") {
|
|
222754
|
+
if (scope && !subagentMatchesScope(agent, scope))
|
|
222755
|
+
continue;
|
|
222756
|
+
const hook = subagentAbortHooks.get(id2);
|
|
222757
|
+
hook?.();
|
|
222758
|
+
subagentAbortHooks.delete(id2);
|
|
222562
222759
|
const updatedAgent = {
|
|
222563
222760
|
...agent,
|
|
222564
222761
|
status: "error",
|
|
222565
222762
|
error: errorMessage,
|
|
222566
|
-
durationMs: Date.now() - agent.startTime
|
|
222763
|
+
durationMs: Date.now() - agent.startTime,
|
|
222764
|
+
...hook ? { cancelPending: true, stopAttempts: (agent.stopAttempts ?? 0) + 1 } : {},
|
|
222765
|
+
stopFailed: undefined
|
|
222567
222766
|
};
|
|
222568
222767
|
store2.agents.set(id2, updatedAgent);
|
|
222569
222768
|
scheduleCompletedSubagentCleanup(id2);
|
|
@@ -222574,6 +222773,50 @@ function interruptActiveSubagents(errorMessage) {
|
|
|
222574
222773
|
notifyListeners();
|
|
222575
222774
|
}
|
|
222576
222775
|
}
|
|
222776
|
+
function interruptStopFailedSubagents(errorMessage, scope) {
|
|
222777
|
+
const interrupted = [];
|
|
222778
|
+
for (const [id2, agent] of store2.agents.entries()) {
|
|
222779
|
+
if (!agent.stopFailed)
|
|
222780
|
+
continue;
|
|
222781
|
+
if (agent.status !== "pending" && agent.status !== "running")
|
|
222782
|
+
continue;
|
|
222783
|
+
if (scope && !subagentMatchesScope(agent, scope))
|
|
222784
|
+
continue;
|
|
222785
|
+
const hook = subagentAbortHooks.get(id2);
|
|
222786
|
+
hook?.();
|
|
222787
|
+
subagentAbortHooks.delete(id2);
|
|
222788
|
+
const updatedAgent = {
|
|
222789
|
+
...agent,
|
|
222790
|
+
status: "error",
|
|
222791
|
+
error: errorMessage,
|
|
222792
|
+
durationMs: Date.now() - agent.startTime,
|
|
222793
|
+
...hook ? { cancelPending: true, stopAttempts: (agent.stopAttempts ?? 0) + 1 } : {},
|
|
222794
|
+
stopFailed: undefined
|
|
222795
|
+
};
|
|
222796
|
+
store2.agents.set(id2, updatedAgent);
|
|
222797
|
+
scheduleCompletedSubagentCleanup(id2);
|
|
222798
|
+
interrupted.push(id2);
|
|
222799
|
+
}
|
|
222800
|
+
if (interrupted.length > 0) {
|
|
222801
|
+
notifyListeners();
|
|
222802
|
+
}
|
|
222803
|
+
return interrupted;
|
|
222804
|
+
}
|
|
222805
|
+
function subagentMatchesScope(agent, scope) {
|
|
222806
|
+
return subagentScopeMatches(agent.parentAgentId, agent.parentConversationId, scope);
|
|
222807
|
+
}
|
|
222808
|
+
function hasStopFailedSubagents(scope) {
|
|
222809
|
+
for (const agent of store2.agents.values()) {
|
|
222810
|
+
if (!agent.stopFailed)
|
|
222811
|
+
continue;
|
|
222812
|
+
if (agent.status !== "pending" && agent.status !== "running")
|
|
222813
|
+
continue;
|
|
222814
|
+
if (scope && !subagentMatchesScope(agent, scope))
|
|
222815
|
+
continue;
|
|
222816
|
+
return true;
|
|
222817
|
+
}
|
|
222818
|
+
return false;
|
|
222819
|
+
}
|
|
222577
222820
|
function subscribe2(listener) {
|
|
222578
222821
|
store2.listeners.add(listener);
|
|
222579
222822
|
return () => {
|
|
@@ -222594,7 +222837,7 @@ function emitStreamEvent(subagentId, event) {
|
|
|
222594
222837
|
listener(subagentId, event);
|
|
222595
222838
|
}
|
|
222596
222839
|
}
|
|
222597
|
-
var store2, cachedSnapshot, cachedLifecycleItems, DEFAULT_COMPLETED_SUBAGENT_RETENTION_MS = 30000, completedSubagentRetentionMs, DEFAULT_PUBLISHED_RESULT_RETENTION_MS, publishedResultRetentionMs, completedSubagentCleanupTimers, subagentCounter = 0, streamEventListeners;
|
|
222840
|
+
var store2, cachedSnapshot, cachedLifecycleItems, DEFAULT_COMPLETED_SUBAGENT_RETENTION_MS = 30000, completedSubagentRetentionMs, DEFAULT_PUBLISHED_RESULT_RETENTION_MS, publishedResultRetentionMs, completedSubagentCleanupTimers, subagentCounter = 0, subagentAbortHooks, streamEventListeners;
|
|
222598
222841
|
var init_subagent_state = __esm(() => {
|
|
222599
222842
|
store2 = {
|
|
222600
222843
|
agents: new Map,
|
|
@@ -222610,6 +222853,7 @@ var init_subagent_state = __esm(() => {
|
|
|
222610
222853
|
DEFAULT_PUBLISHED_RESULT_RETENTION_MS = 30 * 60000;
|
|
222611
222854
|
publishedResultRetentionMs = DEFAULT_PUBLISHED_RESULT_RETENTION_MS;
|
|
222612
222855
|
completedSubagentCleanupTimers = new Map;
|
|
222856
|
+
subagentAbortHooks = new Map;
|
|
222613
222857
|
streamEventListeners = new Set;
|
|
222614
222858
|
});
|
|
222615
222859
|
|
|
@@ -223128,10 +223372,37 @@ var init_tool_registry = __esm(() => {
|
|
|
223128
223372
|
});
|
|
223129
223373
|
|
|
223130
223374
|
// src/tools/external-tool-background.ts
|
|
223375
|
+
function interruptedExternalToolResult(toolName2) {
|
|
223376
|
+
return {
|
|
223377
|
+
status: "error",
|
|
223378
|
+
toolReturn: `External tool call interrupted by user: ${toolName2}. The remote tool may still finish; its outcome is unknown. Check the destination before retrying a write.`
|
|
223379
|
+
};
|
|
223380
|
+
}
|
|
223381
|
+
function raceExternalOperationAbort(operation, signal, toolName2) {
|
|
223382
|
+
if (signal.aborted) {
|
|
223383
|
+
return Promise.resolve(interruptedExternalToolResult(toolName2));
|
|
223384
|
+
}
|
|
223385
|
+
return new Promise((resolve21, reject2) => {
|
|
223386
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
223387
|
+
const onAbort = () => {
|
|
223388
|
+
cleanup();
|
|
223389
|
+
resolve21(interruptedExternalToolResult(toolName2));
|
|
223390
|
+
};
|
|
223391
|
+
signal.addEventListener("abort", onAbort);
|
|
223392
|
+
operation.then((result2) => {
|
|
223393
|
+
cleanup();
|
|
223394
|
+
resolve21(result2);
|
|
223395
|
+
}, (error5) => {
|
|
223396
|
+
cleanup();
|
|
223397
|
+
reject2(error5);
|
|
223398
|
+
});
|
|
223399
|
+
});
|
|
223400
|
+
}
|
|
223131
223401
|
function notificationText(toolReturn) {
|
|
223132
223402
|
return scrubAmbientSecrets(String(toolReturn));
|
|
223133
223403
|
}
|
|
223134
223404
|
async function autoBackgroundExternalTool(toolName2, tool, operation, options) {
|
|
223405
|
+
const signal = options?.signal;
|
|
223135
223406
|
const runtime = options?.runtimeScope;
|
|
223136
223407
|
const scope = options?.scope ?? (runtime?.agentId && runtime.conversationId ? {
|
|
223137
223408
|
agentId: runtime.agentId,
|
|
@@ -223140,24 +223411,36 @@ async function autoBackgroundExternalTool(toolName2, tool, operation, options) {
|
|
|
223140
223411
|
} : undefined);
|
|
223141
223412
|
const canBackground = () => typeof options?.canBackground === "function" ? options.canBackground() : options?.canBackground !== false;
|
|
223142
223413
|
if (tool?.autoBackground !== true || !canBackground() || !scope || !options?.enqueue && !isQueueBridgeConnected())
|
|
223143
|
-
return operation;
|
|
223414
|
+
return signal ? raceExternalOperationAbort(operation, signal, toolName2) : operation;
|
|
223144
223415
|
const startedAt = Date.now();
|
|
223145
223416
|
const settled = operation.then((result2) => ({ kind: "result", result: result2 }), (error5) => ({ kind: "error", error: error5 }));
|
|
223146
223417
|
let timer;
|
|
223418
|
+
let onAbort;
|
|
223419
|
+
const abortSettled = signal ? new Promise((resolve21) => {
|
|
223420
|
+
onAbort = () => resolve21({ kind: "aborted" });
|
|
223421
|
+
signal?.addEventListener("abort", onAbort);
|
|
223422
|
+
}) : undefined;
|
|
223147
223423
|
const first = await Promise.race([
|
|
223148
223424
|
settled,
|
|
223149
223425
|
new Promise((resolve21) => {
|
|
223150
223426
|
timer = setTimeout(() => resolve21({ kind: "yield" }), options?.yieldMs ?? DEFAULT_EXTERNAL_TOOL_YIELD_MS);
|
|
223151
|
-
})
|
|
223427
|
+
}),
|
|
223428
|
+
...abortSettled ? [abortSettled] : []
|
|
223152
223429
|
]);
|
|
223153
223430
|
if (timer !== undefined)
|
|
223154
223431
|
clearTimeout(timer);
|
|
223432
|
+
if (onAbort !== undefined && signal) {
|
|
223433
|
+
signal.removeEventListener("abort", onAbort);
|
|
223434
|
+
}
|
|
223435
|
+
if (first.kind === "aborted")
|
|
223436
|
+
return interruptedExternalToolResult(toolName2);
|
|
223155
223437
|
if (first.kind === "result")
|
|
223156
223438
|
return first.result;
|
|
223157
223439
|
if (first.kind === "error")
|
|
223158
223440
|
throw first.error;
|
|
223159
|
-
if (!canBackground())
|
|
223160
|
-
return operation;
|
|
223441
|
+
if (!canBackground()) {
|
|
223442
|
+
return signal ? raceExternalOperationAbort(operation, signal, toolName2) : operation;
|
|
223443
|
+
}
|
|
223161
223444
|
const taskId = `external_${crypto.randomUUID()}`;
|
|
223162
223445
|
const enqueue = options?.enqueue ?? addToMessageQueue;
|
|
223163
223446
|
settled.then(async (outcome) => {
|
|
@@ -223207,14 +223490,15 @@ function hasActiveToolEndHandlers(events) {
|
|
|
223207
223490
|
return false;
|
|
223208
223491
|
return events.hasHandlers?.("tool_end") ?? true;
|
|
223209
223492
|
}
|
|
223210
|
-
function listenerExternalToolBackgroundOptions(tool, events, runtimeScope) {
|
|
223493
|
+
function listenerExternalToolBackgroundOptions(tool, events, runtimeScope, signal) {
|
|
223211
223494
|
const registration = tool ? listenerRegistrations.get(tool) : undefined;
|
|
223212
223495
|
const notificationGuard = registration?.createNotificationGuard();
|
|
223213
223496
|
return {
|
|
223214
223497
|
canBackground: () => notificationGuard?.isCurrent() === true && !hasActiveToolEndHandlers(events),
|
|
223215
223498
|
...registration?.yieldMs !== undefined ? { yieldMs: registration.yieldMs } : {},
|
|
223216
223499
|
...notificationGuard ? { shouldEnqueue: notificationGuard.waitUntilCurrent } : {},
|
|
223217
|
-
runtimeScope
|
|
223500
|
+
runtimeScope,
|
|
223501
|
+
...signal ? { signal } : {}
|
|
223218
223502
|
};
|
|
223219
223503
|
}
|
|
223220
223504
|
var listenerRegistrations;
|
|
@@ -228992,7 +229276,6 @@ var LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS, PROJECT_SKILLS_DIR, SKILLS_DIR = ".skil
|
|
|
228992
229276
|
var init_skills5 = __esm(() => {
|
|
228993
229277
|
init_skill_sources();
|
|
228994
229278
|
LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS = new Set([
|
|
228995
|
-
"curating-memory-palace",
|
|
228996
229279
|
"image-generation",
|
|
228997
229280
|
"managing-agent-webhooks",
|
|
228998
229281
|
"managing-shared-memory",
|
|
@@ -230142,7 +230425,7 @@ function getExternalToolsAsClientTools() {
|
|
|
230142
230425
|
parameters: tool.parameters
|
|
230143
230426
|
}));
|
|
230144
230427
|
}
|
|
230145
|
-
async function executeExternalTool(toolCallId, toolName2, input, executorOverride, toolDefinition) {
|
|
230428
|
+
async function executeExternalTool(toolCallId, toolName2, input, executorOverride, toolDefinition, signal) {
|
|
230146
230429
|
const executor = executorOverride ?? getExternalToolExecutor();
|
|
230147
230430
|
if (!executor) {
|
|
230148
230431
|
return {
|
|
@@ -230154,7 +230437,7 @@ async function executeExternalTool(toolCallId, toolName2, input, executorOverrid
|
|
|
230154
230437
|
let success = false;
|
|
230155
230438
|
try {
|
|
230156
230439
|
const tool = toolDefinition ?? getExternalToolDefinition(toolName2);
|
|
230157
|
-
const result2 = await executor(toolCallId, toolName2, input, tool ? { tool } : undefined);
|
|
230440
|
+
const result2 = await executor(toolCallId, toolName2, input, tool ? { tool, signal } : undefined);
|
|
230158
230441
|
success = !result2.isError;
|
|
230159
230442
|
return {
|
|
230160
230443
|
toolReturn: clampToolReturnContent(normalizeExternalToolResultContent(result2.content), toolName2),
|
|
@@ -230921,7 +231204,7 @@ async function executeToolInner(name, args, options) {
|
|
|
230921
231204
|
if (permissionDecision2?.decision !== undefined && permissionDecision2.decision !== "allow") {
|
|
230922
231205
|
return createModPermissionToolResult(permissionDecision2);
|
|
230923
231206
|
}
|
|
230924
|
-
return runWithRuntimeContext(executionScope, () => autoBackgroundExternalTool(name, externalTool, executeExternalTool(options?.toolCallId ?? `ext-${Date.now()}`, name, eventArgs2, externalTool?.executor ?? activeExternalExecutor, externalTool), listenerExternalToolBackgroundOptions(externalTool, modEvents, executionScope)));
|
|
231207
|
+
return runWithRuntimeContext(executionScope, () => autoBackgroundExternalTool(name, externalTool, executeExternalTool(options?.toolCallId ?? `ext-${Date.now()}`, name, eventArgs2, externalTool?.executor ?? activeExternalExecutor, externalTool, options?.signal), listenerExternalToolBackgroundOptions(externalTool, modEvents, executionScope, options?.signal)));
|
|
230925
231208
|
}
|
|
230926
231209
|
const internalName = resolveInternalToolName(name, activeRegistry);
|
|
230927
231210
|
const tool = internalName ? activeRegistry.get(internalName) : undefined;
|
|
@@ -232383,12 +232666,12 @@ async function runCall(parsed, deps, agentId, stdout) {
|
|
|
232383
232666
|
await printJson(stdout, result2);
|
|
232384
232667
|
return result2.isError === true ? 2 : 0;
|
|
232385
232668
|
}
|
|
232386
|
-
async function callCatalogTool(catalog, deps, agentId, toolName2, args) {
|
|
232669
|
+
async function callCatalogTool(catalog, deps, agentId, toolName2, args, options) {
|
|
232387
232670
|
const tool = catalog.tools.find((candidate) => candidate.schema.name === toolName2);
|
|
232388
232671
|
if (!tool) {
|
|
232389
232672
|
throw new McpCliError("tool_not_found", `MCP tool '${toolName2}' is not available`);
|
|
232390
232673
|
}
|
|
232391
|
-
return tool.target.kind === "client" ? await tool.target.connection.callTool(tool.target.rawName, args) : mcpToolResultFromServer(await runUnifiedMcpTool({
|
|
232674
|
+
return tool.target.kind === "client" ? await tool.target.connection.callTool(tool.target.rawName, args, options) : mcpToolResultFromServer(await runUnifiedMcpTool({
|
|
232392
232675
|
client: await getServerClient(deps),
|
|
232393
232676
|
agentId,
|
|
232394
232677
|
mcpServerId: tool.target.serverId,
|
|
@@ -232417,7 +232700,7 @@ function createAgentMcpSession(agentId, deps = {}) {
|
|
|
232417
232700
|
return catalog;
|
|
232418
232701
|
};
|
|
232419
232702
|
return {
|
|
232420
|
-
callTool: async (toolName2, args) => callCatalogTool(await load(), deps, agentId, toolName2, args),
|
|
232703
|
+
callTool: async (toolName2, args, options) => callCatalogTool(await load(), deps, agentId, toolName2, args, options),
|
|
232421
232704
|
listTools: async () => (await load()).tools.map((tool) => tool.schema),
|
|
232422
232705
|
close: async () => {
|
|
232423
232706
|
closed = true;
|
|
@@ -232574,7 +232857,7 @@ async function createScriptToolScope(parentAgentId, signal) {
|
|
|
232574
232857
|
isError: result2.status === "error"
|
|
232575
232858
|
};
|
|
232576
232859
|
}
|
|
232577
|
-
return (await mcp()).callTool(toolName2, toolArgs);
|
|
232860
|
+
return (await mcp()).callTool(toolName2, toolArgs, signal ? { signal } : {});
|
|
232578
232861
|
},
|
|
232579
232862
|
cleanup: async () => {
|
|
232580
232863
|
await mcpSession?.then((session3) => session3.close()).catch(() => {
|
|
@@ -239866,6 +240149,9 @@ var init_monitor_event_stream = __esm(() => {
|
|
|
239866
240149
|
// src/tools/impl/monitor.ts
|
|
239867
240150
|
import { appendFileSync as appendFileSync7, readFileSync as readFileSync35, writeFileSync as writeFileSync27 } from "node:fs";
|
|
239868
240151
|
import { WebSocket as WebSocket4 } from "ws";
|
|
240152
|
+
function getMonitorTimeoutEvent(timeoutMs) {
|
|
240153
|
+
return isManagedCloudRuntime() && timeoutMs === MONITOR_MAX_TIMEOUT_MS ? "Monitor stopped at the 1-hour Cloud sandbox limit. Cloud monitors have a hard 1-hour limit to avoid keeping sandbox resources unnecessarily running. For later checks, schedule a Wake or cron, which does not keep the sandbox running between turns, and combine it with shorter monitors when needed." : "[Monitor timed out — re-arm if needed.]";
|
|
240154
|
+
}
|
|
239869
240155
|
function buildMonitorResult(taskId, timeoutMs, persistent, outputFile) {
|
|
239870
240156
|
const lifetime = persistent ? "persistent — runs until TaskStop or session end" : `timeout ${timeoutMs}ms`;
|
|
239871
240157
|
return {
|
|
@@ -239975,8 +240261,8 @@ function normalizeMonitorArgs(args) {
|
|
|
239975
240261
|
if (typeof normalized.description !== "string") {
|
|
239976
240262
|
throw new Error("Monitor description is required");
|
|
239977
240263
|
}
|
|
239978
|
-
if (typeof normalized.timeout_ms !== "number" || !Number.isFinite(normalized.timeout_ms) || normalized.timeout_ms < MIN_TIMEOUT_MS || !normalized.persistent && normalized.timeout_ms >
|
|
239979
|
-
throw new Error(`Monitor timeout_ms must be between ${MIN_TIMEOUT_MS} and ${
|
|
240264
|
+
if (typeof normalized.timeout_ms !== "number" || !Number.isFinite(normalized.timeout_ms) || normalized.timeout_ms < MIN_TIMEOUT_MS || !normalized.persistent && normalized.timeout_ms > MONITOR_MAX_TIMEOUT_MS) {
|
|
240265
|
+
throw new Error(`Monitor timeout_ms must be between ${MIN_TIMEOUT_MS} and ${MONITOR_MAX_TIMEOUT_MS}`);
|
|
239980
240266
|
}
|
|
239981
240267
|
if (typeof normalized.persistent !== "boolean") {
|
|
239982
240268
|
throw new Error("Monitor persistent must be a boolean");
|
|
@@ -240008,6 +240294,10 @@ function normalizeMonitorArgs(args) {
|
|
|
240008
240294
|
}
|
|
240009
240295
|
validateWebSocketSource(normalized.ws);
|
|
240010
240296
|
}
|
|
240297
|
+
if (isManagedCloudRuntime() && normalized.persistent) {
|
|
240298
|
+
normalized.persistent = false;
|
|
240299
|
+
normalized.timeout_ms = MONITOR_MAX_TIMEOUT_MS;
|
|
240300
|
+
}
|
|
240011
240301
|
return normalized;
|
|
240012
240302
|
}
|
|
240013
240303
|
function webSocketDisplayUrl(sourceUrl) {
|
|
@@ -240240,7 +240530,7 @@ function startCommandMonitor(args) {
|
|
|
240240
240530
|
`);
|
|
240241
240531
|
queueMonitorEvent({
|
|
240242
240532
|
taskId,
|
|
240243
|
-
event:
|
|
240533
|
+
event: getMonitorTimeoutEvent(args.timeout_ms),
|
|
240244
240534
|
scope,
|
|
240245
240535
|
actingUserId,
|
|
240246
240536
|
secrets: secrets2
|
|
@@ -240422,7 +240712,7 @@ function startWebSocketMonitor(args) {
|
|
|
240422
240712
|
return;
|
|
240423
240713
|
queueMonitorEvent({
|
|
240424
240714
|
taskId,
|
|
240425
|
-
event:
|
|
240715
|
+
event: getMonitorTimeoutEvent(args.timeout_ms),
|
|
240426
240716
|
scope,
|
|
240427
240717
|
actingUserId,
|
|
240428
240718
|
secrets: secrets2
|
|
@@ -240485,7 +240775,7 @@ function installMonitorProcessExitCleanup() {
|
|
|
240485
240775
|
monitorProcessExitCleanupInstalled = true;
|
|
240486
240776
|
process.once("exit", stopMonitorsForProcessExit);
|
|
240487
240777
|
}
|
|
240488
|
-
var MIN_TIMEOUT_MS = 1000,
|
|
240778
|
+
var MIN_TIMEOUT_MS = 1000, MONITOR_MAX_TIMEOUT_MS = 3600000, DEFAULT_TIMEOUT_MS4 = 300000, MONITOR_OUTPUT_FILE_BYTES, WEBSOCKET_MAX_PAYLOAD_BYTES, WEBSOCKET_PROTOCOL_PATTERN, monitorProcessExitCleanupInstalled = false;
|
|
240489
240779
|
var init_monitor = __esm(async () => {
|
|
240490
240780
|
init_strip_ansi();
|
|
240491
240781
|
init_runtime_context();
|
|
@@ -242270,7 +242560,7 @@ class CodexAppServerClient {
|
|
|
242270
242560
|
await this.request("initialize", {
|
|
242271
242561
|
clientInfo: {
|
|
242272
242562
|
name: "letta-code",
|
|
242273
|
-
version: "0.34.
|
|
242563
|
+
version: "0.34.19"
|
|
242274
242564
|
},
|
|
242275
242565
|
capabilities: null
|
|
242276
242566
|
});
|
|
@@ -242689,6 +242979,22 @@ var init_codex_app_server = __esm(() => {
|
|
|
242689
242979
|
DEFAULT_IDLE_TIMEOUT_MS = 5 * 60000;
|
|
242690
242980
|
});
|
|
242691
242981
|
|
|
242982
|
+
// src/agent/parent-memory-note.ts
|
|
242983
|
+
import { statSync as statSync18 } from "node:fs";
|
|
242984
|
+
function buildParentMemoryNote(parentAgentId) {
|
|
242985
|
+
const directory = getScopedMemoryFilesystemRoot(parentAgentId);
|
|
242986
|
+
try {
|
|
242987
|
+
if (!statSync18(directory).isDirectory())
|
|
242988
|
+
return;
|
|
242989
|
+
} catch {
|
|
242990
|
+
return;
|
|
242991
|
+
}
|
|
242992
|
+
return `Your parent agent (${parentAgentId}) keeps its memory as Markdown files at \`${directory}\`; attached shared-memory repos sit next to it. If the task depends on context about the user, project, people or conventions, check there first: start with \`MEMORY.md\` and the directory indexes, then open only the files that look relevant. Don't edit or commit there unless asked.`;
|
|
242993
|
+
}
|
|
242994
|
+
var init_parent_memory_note = __esm(() => {
|
|
242995
|
+
init_memory_filesystem2();
|
|
242996
|
+
});
|
|
242997
|
+
|
|
242692
242998
|
// src/cli/helpers/agent-info.ts
|
|
242693
242999
|
function getRelativeTime(dateStr) {
|
|
242694
243000
|
const date5 = new Date(dateStr);
|
|
@@ -242732,10 +243038,13 @@ function buildAgentInfo(options) {
|
|
|
242732
243038
|
})();
|
|
242733
243039
|
const memoryDirLine = showMemoryDir ? `
|
|
242734
243040
|
- **Memory directory (also stored in \`MEMORY_DIR\` env var)**: \`${getScopedMemoryFilesystemRoot(agentInfo.id)}\`` : "";
|
|
243041
|
+
const parentMemoryNote = options.parentAgentId && options.parentAgentId !== agentInfo.id ? buildParentMemoryNote(options.parentAgentId) : undefined;
|
|
243042
|
+
const parentMemoryLine = parentMemoryNote ? `
|
|
243043
|
+
- ${parentMemoryNote}` : "";
|
|
242735
243044
|
const convLine = conversationId ? `
|
|
242736
243045
|
- **Conversation ID (also stored in \`CONVERSATION_ID\` env var)**: ${conversationId}` : "";
|
|
242737
243046
|
return `${SYSTEM_REMINDER_OPEN} This is an automated message providing information about you.
|
|
242738
|
-
- **Agent ID (also stored in \`AGENT_ID\` env var)**: ${agentInfo.id}${convLine}${memoryDirLine}
|
|
243047
|
+
- **Agent ID (also stored in \`AGENT_ID\` env var)**: ${agentInfo.id}${convLine}${memoryDirLine}${parentMemoryLine}
|
|
242739
243048
|
- **Agent name**: ${agentInfo.name || "(unnamed)"} (the user can change this with /rename)
|
|
242740
243049
|
- **Agent description**: ${agentInfo.description || "(no description)"} (the user can change this with /description)
|
|
242741
243050
|
- **Last message**: ${lastRunInfo}
|
|
@@ -242746,6 +243055,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
242746
243055
|
}
|
|
242747
243056
|
var init_agent_info = __esm(() => {
|
|
242748
243057
|
init_memory_filesystem2();
|
|
243058
|
+
init_parent_memory_note();
|
|
242749
243059
|
init_paths();
|
|
242750
243060
|
init_constants2();
|
|
242751
243061
|
init_settings_manager();
|
|
@@ -243215,7 +243525,14 @@ async function buildAgentInfoReminder(context3) {
|
|
|
243215
243525
|
if (!context3.systemInfoReminderEnabled || context3.state.hasSentAgentInfo) {
|
|
243216
243526
|
return null;
|
|
243217
243527
|
}
|
|
243528
|
+
let parentAgentId;
|
|
243529
|
+
try {
|
|
243530
|
+
const scopeAgentId = await getMcpScopeAgentId(context3.agent.id);
|
|
243531
|
+
if (scopeAgentId !== context3.agent.id)
|
|
243532
|
+
parentAgentId = scopeAgentId;
|
|
243533
|
+
} catch {}
|
|
243218
243534
|
const reminder = buildAgentInfo({
|
|
243535
|
+
parentAgentId,
|
|
243219
243536
|
agentInfo: {
|
|
243220
243537
|
id: context3.agent.id,
|
|
243221
243538
|
name: context3.agent.name,
|
|
@@ -244822,6 +245139,18 @@ async function resolveExternalCodingAgentSecretEnv(parentAgentId, lookupParent)
|
|
|
244822
245139
|
return { ...inherited, ...loadSecrets2(parentAgentId) };
|
|
244823
245140
|
}
|
|
244824
245141
|
async function runExternalCodingAgent(options, deps = {}) {
|
|
245142
|
+
const parentMemoryNote = buildParentMemoryNote(options.parentAgentId);
|
|
245143
|
+
options = {
|
|
245144
|
+
...options,
|
|
245145
|
+
mcpReminder: [
|
|
245146
|
+
parentMemoryNote ? `${SYSTEM_REMINDER_OPEN}
|
|
245147
|
+
${parentMemoryNote}
|
|
245148
|
+
${SYSTEM_REMINDER_CLOSE}` : undefined,
|
|
245149
|
+
options.mcpReminder
|
|
245150
|
+
].filter(Boolean).join(`
|
|
245151
|
+
|
|
245152
|
+
`) || undefined
|
|
245153
|
+
};
|
|
244825
245154
|
const startedAt = Date.now();
|
|
244826
245155
|
const secretEnv = await (deps.resolveSecretEnv ?? resolveExternalCodingAgentSecretEnv)(options.parentAgentId);
|
|
244827
245156
|
const env6 = {
|
|
@@ -244988,8 +245317,10 @@ async function runExternalCodingAgent(options, deps = {}) {
|
|
|
244988
245317
|
}
|
|
244989
245318
|
var EXTERNAL_CODING_AGENT_TYPES, EXTERNAL_AGENT_ID_PREFIXES, NATIVE_SESSION_ID_PATTERN, MISSING_EXECUTABLE_PREFIX = "Required executable '", CODEX_NOT_READY_PREFIX = "Codex executable is not ready", CLAUDE_NOT_SIGNED_IN_PREFIX = "claude-code authentication is not ready";
|
|
244990
245319
|
var init_external_coding_agent = __esm(() => {
|
|
245320
|
+
init_parent_memory_note();
|
|
244991
245321
|
init_subagent_depth();
|
|
244992
245322
|
init_subagent_process();
|
|
245323
|
+
init_constants2();
|
|
244993
245324
|
init_mcp_scope();
|
|
244994
245325
|
init_engine3();
|
|
244995
245326
|
init_runtime_context();
|
|
@@ -248836,6 +249167,184 @@ var init_subagent_computer = __esm(() => {
|
|
|
248836
249167
|
LOCAL_COMPUTER_SELECTORS = new Set(["local", "self"]);
|
|
248837
249168
|
});
|
|
248838
249169
|
|
|
249170
|
+
// src/tools/impl/kill-bash.ts
|
|
249171
|
+
function killBackgroundProcess(shell_id) {
|
|
249172
|
+
const proc = backgroundProcesses.get(shell_id);
|
|
249173
|
+
const retainsEntry = proc?.kind === "monitor" || proc?.kind === "workflow";
|
|
249174
|
+
if (!proc || retainsEntry && proc.status !== "running") {
|
|
249175
|
+
return false;
|
|
249176
|
+
}
|
|
249177
|
+
const previousStatus = proc.status;
|
|
249178
|
+
const previousNotificationSuppression = proc.completionNotificationSuppressed;
|
|
249179
|
+
try {
|
|
249180
|
+
proc.completionNotificationSuppressed = true;
|
|
249181
|
+
if (retainsEntry) {
|
|
249182
|
+
proc.status = "failed";
|
|
249183
|
+
}
|
|
249184
|
+
proc.process.kill("SIGTERM");
|
|
249185
|
+
if (proc.kind === "monitor")
|
|
249186
|
+
cancelMonitorBackup(shell_id);
|
|
249187
|
+
clearBackgroundProcessCleanup(shell_id);
|
|
249188
|
+
if (retainsEntry) {
|
|
249189
|
+
scheduleBackgroundProcessCleanup(shell_id);
|
|
249190
|
+
notifyBackgroundProcessStateChanged(proc.runtimeScope);
|
|
249191
|
+
} else {
|
|
249192
|
+
backgroundProcesses.delete(shell_id);
|
|
249193
|
+
}
|
|
249194
|
+
return true;
|
|
249195
|
+
} catch {
|
|
249196
|
+
proc.status = previousStatus;
|
|
249197
|
+
proc.completionNotificationSuppressed = previousNotificationSuppression;
|
|
249198
|
+
return false;
|
|
249199
|
+
}
|
|
249200
|
+
}
|
|
249201
|
+
var init_kill_bash = __esm(async () => {
|
|
249202
|
+
init_process_manager();
|
|
249203
|
+
await init_monitor_backup();
|
|
249204
|
+
});
|
|
249205
|
+
|
|
249206
|
+
// src/tools/impl/task-stop.ts
|
|
249207
|
+
var exports_task_stop = {};
|
|
249208
|
+
__export(exports_task_stop, {
|
|
249209
|
+
task_stop: () => task_stop
|
|
249210
|
+
});
|
|
249211
|
+
async function cancelRemoteRun(subagentId) {
|
|
249212
|
+
const child = getSubagents().find((agent) => agent.id === subagentId);
|
|
249213
|
+
const target2 = child?.conversationId === "default" ? child.agentId : child?.conversationId;
|
|
249214
|
+
try {
|
|
249215
|
+
if (!target2)
|
|
249216
|
+
throw new Error("its conversation is not known yet");
|
|
249217
|
+
const results = await getBackend().cancelConversation(target2);
|
|
249218
|
+
const outcomes = Object.values(results);
|
|
249219
|
+
if (outcomes.length === 0 || outcomes.some((status) => status !== "cancelled")) {
|
|
249220
|
+
throw new Error("Cloud did not cancel every run");
|
|
249221
|
+
}
|
|
249222
|
+
return { killed: true, output: "Cancelled the remote run" };
|
|
249223
|
+
} catch (error5) {
|
|
249224
|
+
return {
|
|
249225
|
+
killed: false,
|
|
249226
|
+
output: `Couldn't cancel the remote run: ${getErrorMessage2(error5)}`
|
|
249227
|
+
};
|
|
249228
|
+
}
|
|
249229
|
+
}
|
|
249230
|
+
async function task_stop(args, deps = {}) {
|
|
249231
|
+
validateRequiredParams(args, ["task_id"], "TaskStop");
|
|
249232
|
+
const { task_id } = args;
|
|
249233
|
+
const task = backgroundTasks.get(task_id);
|
|
249234
|
+
if (task) {
|
|
249235
|
+
if (task.status === "running" && task.abortController) {
|
|
249236
|
+
const child = getSubagents().find((agent) => agent.id === task.subagentId);
|
|
249237
|
+
const external3 = parseExternalCodingAgentId(child?.agentId ?? undefined);
|
|
249238
|
+
let remote;
|
|
249239
|
+
let remoteExternalStopped = false;
|
|
249240
|
+
if (external3?.computer) {
|
|
249241
|
+
try {
|
|
249242
|
+
if (!task.runtimeScope)
|
|
249243
|
+
throw new Error("its parent conversation is not known");
|
|
249244
|
+
const result3 = await (deps.stopRemoteExternal ?? stopRemoteExternalCodingAgent)({
|
|
249245
|
+
agentId: child?.agentId,
|
|
249246
|
+
parentScope: {
|
|
249247
|
+
agentId: task.runtimeScope.agentId,
|
|
249248
|
+
conversationId: task.runtimeScope.conversationId,
|
|
249249
|
+
actingUserId: task.actingUserId
|
|
249250
|
+
}
|
|
249251
|
+
});
|
|
249252
|
+
remote = {
|
|
249253
|
+
killed: result3.stopped,
|
|
249254
|
+
output: result3.stopped ? "Stopped the remote external subagent" : "The remote external subagent was not running"
|
|
249255
|
+
};
|
|
249256
|
+
remoteExternalStopped = result3.stopped;
|
|
249257
|
+
} catch (error5) {
|
|
249258
|
+
remote = {
|
|
249259
|
+
killed: false,
|
|
249260
|
+
output: `Couldn't stop the remote external subagent: ${getErrorMessage2(error5)}`
|
|
249261
|
+
};
|
|
249262
|
+
}
|
|
249263
|
+
} else if (task.remote) {
|
|
249264
|
+
remote = await cancelRemoteRun(task.subagentId);
|
|
249265
|
+
}
|
|
249266
|
+
if (remote && !remote.killed)
|
|
249267
|
+
return remote;
|
|
249268
|
+
task.abortController.abort(remoteExternalStopped ? REMOTE_EXTERNAL_WORKER_STOPPED : undefined);
|
|
249269
|
+
task.error = "Aborted by user";
|
|
249270
|
+
await task.completion;
|
|
249271
|
+
task.status = "failed";
|
|
249272
|
+
scheduleBackgroundTaskCleanup(task_id);
|
|
249273
|
+
return remote ?? { killed: true };
|
|
249274
|
+
}
|
|
249275
|
+
return { killed: false };
|
|
249276
|
+
}
|
|
249277
|
+
return { killed: killBackgroundProcess(task_id) };
|
|
249278
|
+
}
|
|
249279
|
+
var init_task_stop = __esm(async () => {
|
|
249280
|
+
init_subagent_state();
|
|
249281
|
+
init_backend2();
|
|
249282
|
+
init_external_coding_agent();
|
|
249283
|
+
init_process_manager();
|
|
249284
|
+
init_remote_external_coding_agent();
|
|
249285
|
+
await init_kill_bash();
|
|
249286
|
+
});
|
|
249287
|
+
|
|
249288
|
+
// src/tools/impl/task-abort-hook.ts
|
|
249289
|
+
function buildBackgroundTaskAbortHook(taskId, abortController) {
|
|
249290
|
+
const bgTask = backgroundTasks.get(taskId);
|
|
249291
|
+
const remote = bgTask?.remote ?? false;
|
|
249292
|
+
const failSafeAbort = () => !remote && abortController.abort();
|
|
249293
|
+
const hook = () => {
|
|
249294
|
+
init_task_stop().then(() => exports_task_stop).then((m4) => m4.task_stop({ task_id: taskId })).then((result3) => {
|
|
249295
|
+
if (!result3.killed)
|
|
249296
|
+
failSafeAbort();
|
|
249297
|
+
settleInterruptedCancel(bgTask, remote, result3.killed, hook);
|
|
249298
|
+
}).catch(() => {
|
|
249299
|
+
failSafeAbort();
|
|
249300
|
+
settleInterruptedCancel(bgTask, remote, false, hook);
|
|
249301
|
+
});
|
|
249302
|
+
};
|
|
249303
|
+
return hook;
|
|
249304
|
+
}
|
|
249305
|
+
function settleInterruptedCancel(bgTask, remote, killed, hook) {
|
|
249306
|
+
if (!bgTask)
|
|
249307
|
+
return;
|
|
249308
|
+
const taskLive = bgTask.status === "running";
|
|
249309
|
+
if (remote && !killed && taskLive) {
|
|
249310
|
+
restoreInterruptedSubagentRow(bgTask.subagentId, hook);
|
|
249311
|
+
return;
|
|
249312
|
+
}
|
|
249313
|
+
const row = getSubagents().find((agent) => agent.id === bgTask.subagentId);
|
|
249314
|
+
updateSubagent(bgTask.subagentId, {
|
|
249315
|
+
cancelPending: undefined,
|
|
249316
|
+
stopFailed: undefined,
|
|
249317
|
+
stopOutcome: {
|
|
249318
|
+
attempt: row?.stopAttempts ?? 0,
|
|
249319
|
+
kind: killed ? "stopped" : "natural"
|
|
249320
|
+
}
|
|
249321
|
+
});
|
|
249322
|
+
}
|
|
249323
|
+
function restoreInterruptedSubagentRow(subagentId, hook) {
|
|
249324
|
+
const row = getSubagents().find((agent) => agent.id === subagentId);
|
|
249325
|
+
if (!row || row.status !== "error" || row.result !== undefined) {
|
|
249326
|
+
if (row) {
|
|
249327
|
+
updateSubagent(subagentId, {
|
|
249328
|
+
cancelPending: undefined,
|
|
249329
|
+
stopOutcome: { attempt: row.stopAttempts ?? 0, kind: "natural" }
|
|
249330
|
+
});
|
|
249331
|
+
}
|
|
249332
|
+
return;
|
|
249333
|
+
}
|
|
249334
|
+
updateSubagent(subagentId, {
|
|
249335
|
+
status: "running",
|
|
249336
|
+
error: undefined,
|
|
249337
|
+
cancelPending: undefined,
|
|
249338
|
+
stopFailed: true,
|
|
249339
|
+
stopOutcome: { attempt: row.stopAttempts ?? 0, kind: "failed" }
|
|
249340
|
+
});
|
|
249341
|
+
registerSubagentAbortHook(subagentId, hook);
|
|
249342
|
+
}
|
|
249343
|
+
var init_task_abort_hook = __esm(() => {
|
|
249344
|
+
init_subagent_state();
|
|
249345
|
+
init_process_manager();
|
|
249346
|
+
});
|
|
249347
|
+
|
|
248839
249348
|
// src/tools/impl/task-transcript.ts
|
|
248840
249349
|
function buildTaskResultHeader(subagentType, subagentId, result3, status) {
|
|
248841
249350
|
return [
|
|
@@ -248954,6 +249463,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
248954
249463
|
actingUserId
|
|
248955
249464
|
};
|
|
248956
249465
|
backgroundTasks.set(taskId, bgTask);
|
|
249466
|
+
registerSubagentAbortHook(subagentId, buildBackgroundTaskAbortHook(taskId, abortController));
|
|
248957
249467
|
writeTaskTranscriptStart(outputFile, description, subagentType);
|
|
248958
249468
|
const parentAgentIdForSpawn = resolvedParentScope?.agentId;
|
|
248959
249469
|
const workerMemoryDir = subagentType === "memory" && resolvedParentScope ? memoryScope?.primaryRoot ?? getScopedMemoryFilesystemRoot(resolvedParentScope.agentId) : undefined;
|
|
@@ -248985,6 +249495,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
248985
249495
|
const header = buildTaskResultHeader(subagentType, subagentId, result3, result3.success ? "success" : "error");
|
|
248986
249496
|
writeTaskTranscriptResult(outputFile, result3, header, !!memoryTask);
|
|
248987
249497
|
scheduleBackgroundTaskCleanup(taskId);
|
|
249498
|
+
clearSubagentAbortHook(subagentId);
|
|
248988
249499
|
completeSubagentFn(subagentId, {
|
|
248989
249500
|
success: result3.success,
|
|
248990
249501
|
error: result3.error,
|
|
@@ -249052,6 +249563,7 @@ Error: ${result3.error || "Subagent execution failed"}`;
|
|
|
249052
249563
|
[Task failed]
|
|
249053
249564
|
`);
|
|
249054
249565
|
scheduleBackgroundTaskCleanup(taskId);
|
|
249566
|
+
clearSubagentAbortHook(subagentId);
|
|
249055
249567
|
completeSubagentFn(subagentId, { success: false, error: errorMessage4 });
|
|
249056
249568
|
try {
|
|
249057
249569
|
await onComplete?.({
|
|
@@ -249410,6 +249922,7 @@ var init_task = __esm(async () => {
|
|
|
249410
249922
|
init_process_manager();
|
|
249411
249923
|
init_remote_external_coding_agent();
|
|
249412
249924
|
init_subagent_computer();
|
|
249925
|
+
init_task_abort_hook();
|
|
249413
249926
|
init_task_transcript();
|
|
249414
249927
|
init_truncation();
|
|
249415
249928
|
init_background_link();
|
|
@@ -250302,120 +250815,6 @@ var init_task_list = __esm(() => {
|
|
|
250302
250815
|
init_store();
|
|
250303
250816
|
});
|
|
250304
250817
|
|
|
250305
|
-
// src/tools/impl/kill-bash.ts
|
|
250306
|
-
function killBackgroundProcess(shell_id) {
|
|
250307
|
-
const proc = backgroundProcesses.get(shell_id);
|
|
250308
|
-
const retainsEntry = proc?.kind === "monitor" || proc?.kind === "workflow";
|
|
250309
|
-
if (!proc || retainsEntry && proc.status !== "running") {
|
|
250310
|
-
return false;
|
|
250311
|
-
}
|
|
250312
|
-
const previousStatus = proc.status;
|
|
250313
|
-
const previousNotificationSuppression = proc.completionNotificationSuppressed;
|
|
250314
|
-
try {
|
|
250315
|
-
proc.completionNotificationSuppressed = true;
|
|
250316
|
-
if (retainsEntry) {
|
|
250317
|
-
proc.status = "failed";
|
|
250318
|
-
}
|
|
250319
|
-
proc.process.kill("SIGTERM");
|
|
250320
|
-
if (proc.kind === "monitor")
|
|
250321
|
-
cancelMonitorBackup(shell_id);
|
|
250322
|
-
clearBackgroundProcessCleanup(shell_id);
|
|
250323
|
-
if (retainsEntry) {
|
|
250324
|
-
scheduleBackgroundProcessCleanup(shell_id);
|
|
250325
|
-
notifyBackgroundProcessStateChanged(proc.runtimeScope);
|
|
250326
|
-
} else {
|
|
250327
|
-
backgroundProcesses.delete(shell_id);
|
|
250328
|
-
}
|
|
250329
|
-
return true;
|
|
250330
|
-
} catch {
|
|
250331
|
-
proc.status = previousStatus;
|
|
250332
|
-
proc.completionNotificationSuppressed = previousNotificationSuppression;
|
|
250333
|
-
return false;
|
|
250334
|
-
}
|
|
250335
|
-
}
|
|
250336
|
-
var init_kill_bash = __esm(async () => {
|
|
250337
|
-
init_process_manager();
|
|
250338
|
-
await init_monitor_backup();
|
|
250339
|
-
});
|
|
250340
|
-
|
|
250341
|
-
// src/tools/impl/task-stop.ts
|
|
250342
|
-
async function cancelRemoteRun(subagentId) {
|
|
250343
|
-
const child = getSubagents().find((agent) => agent.id === subagentId);
|
|
250344
|
-
const target2 = child?.conversationId === "default" ? child.agentId : child?.conversationId;
|
|
250345
|
-
try {
|
|
250346
|
-
if (!target2)
|
|
250347
|
-
throw new Error("its conversation is not known yet");
|
|
250348
|
-
const results = await getBackend().cancelConversation(target2);
|
|
250349
|
-
const outcomes = Object.values(results);
|
|
250350
|
-
if (outcomes.length === 0 || outcomes.some((status) => status !== "cancelled")) {
|
|
250351
|
-
throw new Error("Cloud did not cancel every run");
|
|
250352
|
-
}
|
|
250353
|
-
return { killed: true, output: "Cancelled the remote run" };
|
|
250354
|
-
} catch (error5) {
|
|
250355
|
-
return {
|
|
250356
|
-
killed: false,
|
|
250357
|
-
output: `Couldn't cancel the remote run: ${getErrorMessage2(error5)}`
|
|
250358
|
-
};
|
|
250359
|
-
}
|
|
250360
|
-
}
|
|
250361
|
-
async function task_stop(args, deps = {}) {
|
|
250362
|
-
validateRequiredParams(args, ["task_id"], "TaskStop");
|
|
250363
|
-
const { task_id } = args;
|
|
250364
|
-
const task2 = backgroundTasks.get(task_id);
|
|
250365
|
-
if (task2) {
|
|
250366
|
-
if (task2.status === "running" && task2.abortController) {
|
|
250367
|
-
const child = getSubagents().find((agent) => agent.id === task2.subagentId);
|
|
250368
|
-
const external3 = parseExternalCodingAgentId(child?.agentId ?? undefined);
|
|
250369
|
-
let remote;
|
|
250370
|
-
let remoteExternalStopped = false;
|
|
250371
|
-
if (external3?.computer) {
|
|
250372
|
-
try {
|
|
250373
|
-
if (!task2.runtimeScope)
|
|
250374
|
-
throw new Error("its parent conversation is not known");
|
|
250375
|
-
const result3 = await (deps.stopRemoteExternal ?? stopRemoteExternalCodingAgent)({
|
|
250376
|
-
agentId: child?.agentId,
|
|
250377
|
-
parentScope: {
|
|
250378
|
-
agentId: task2.runtimeScope.agentId,
|
|
250379
|
-
conversationId: task2.runtimeScope.conversationId,
|
|
250380
|
-
actingUserId: task2.actingUserId
|
|
250381
|
-
}
|
|
250382
|
-
});
|
|
250383
|
-
remote = {
|
|
250384
|
-
killed: result3.stopped,
|
|
250385
|
-
output: result3.stopped ? "Stopped the remote external subagent" : "The remote external subagent was not running"
|
|
250386
|
-
};
|
|
250387
|
-
remoteExternalStopped = result3.stopped;
|
|
250388
|
-
} catch (error5) {
|
|
250389
|
-
remote = {
|
|
250390
|
-
killed: false,
|
|
250391
|
-
output: `Couldn't stop the remote external subagent: ${getErrorMessage2(error5)}`
|
|
250392
|
-
};
|
|
250393
|
-
}
|
|
250394
|
-
} else if (task2.remote) {
|
|
250395
|
-
remote = await cancelRemoteRun(task2.subagentId);
|
|
250396
|
-
}
|
|
250397
|
-
if (remote && !remote.killed)
|
|
250398
|
-
return remote;
|
|
250399
|
-
task2.abortController.abort(remoteExternalStopped ? REMOTE_EXTERNAL_WORKER_STOPPED : undefined);
|
|
250400
|
-
task2.error = "Aborted by user";
|
|
250401
|
-
await task2.completion;
|
|
250402
|
-
task2.status = "failed";
|
|
250403
|
-
scheduleBackgroundTaskCleanup(task_id);
|
|
250404
|
-
return remote ?? { killed: true };
|
|
250405
|
-
}
|
|
250406
|
-
return { killed: false };
|
|
250407
|
-
}
|
|
250408
|
-
return { killed: killBackgroundProcess(task_id) };
|
|
250409
|
-
}
|
|
250410
|
-
var init_task_stop = __esm(async () => {
|
|
250411
|
-
init_subagent_state();
|
|
250412
|
-
init_backend2();
|
|
250413
|
-
init_external_coding_agent();
|
|
250414
|
-
init_process_manager();
|
|
250415
|
-
init_remote_external_coding_agent();
|
|
250416
|
-
await init_kill_bash();
|
|
250417
|
-
});
|
|
250418
|
-
|
|
250419
250818
|
// src/tools/impl/task-update.ts
|
|
250420
250819
|
function validateStringArray(value, paramName) {
|
|
250421
250820
|
if (value === undefined)
|
|
@@ -251470,6 +251869,8 @@ ${describeGitHubPullRequestSnapshot(initial2)}
|
|
|
251470
251869
|
const controller = new AbortController;
|
|
251471
251870
|
const secrets2 = {};
|
|
251472
251871
|
let processState;
|
|
251872
|
+
const persistent = !isManagedCloudRuntime();
|
|
251873
|
+
let timeout;
|
|
251473
251874
|
const events = createMonitorEventStream({
|
|
251474
251875
|
emit(event) {
|
|
251475
251876
|
queueMonitorEvent({
|
|
@@ -251508,6 +251909,7 @@ ${describeGitHubPullRequestSnapshot(initial2)}
|
|
|
251508
251909
|
processState = {
|
|
251509
251910
|
process: {
|
|
251510
251911
|
kill() {
|
|
251912
|
+
clearTimeout(timeout);
|
|
251511
251913
|
events.cancel();
|
|
251512
251914
|
controller.abort();
|
|
251513
251915
|
}
|
|
@@ -251522,11 +251924,29 @@ ${describeGitHubPullRequestSnapshot(initial2)}
|
|
|
251522
251924
|
kind: "monitor",
|
|
251523
251925
|
description,
|
|
251524
251926
|
monitorSource: "github_pull_request",
|
|
251525
|
-
persistent
|
|
251927
|
+
persistent,
|
|
251526
251928
|
secrets: secrets2
|
|
251527
251929
|
};
|
|
251528
251930
|
backgroundProcesses.set(taskId, processState);
|
|
251529
251931
|
notifyBackgroundProcessStateChanged(scope);
|
|
251932
|
+
if (!persistent) {
|
|
251933
|
+
timeout = setTimeout(() => {
|
|
251934
|
+
if (processState.status !== "running")
|
|
251935
|
+
return;
|
|
251936
|
+
events.finish();
|
|
251937
|
+
if (processState.status !== "running")
|
|
251938
|
+
return;
|
|
251939
|
+
const event = getMonitorTimeoutEvent(MONITOR_MAX_TIMEOUT_MS);
|
|
251940
|
+
output.append(`
|
|
251941
|
+
${event}
|
|
251942
|
+
`);
|
|
251943
|
+
queueMonitorEvent({ taskId, event, scope, actingUserId, secrets: secrets2 });
|
|
251944
|
+
processState.completionNotificationSuppressed = true;
|
|
251945
|
+
markMonitorFinished(taskId, processState, "failed", null);
|
|
251946
|
+
processState.process.kill();
|
|
251947
|
+
}, MONITOR_MAX_TIMEOUT_MS);
|
|
251948
|
+
unrefTimer(timeout);
|
|
251949
|
+
}
|
|
251530
251950
|
const wait = deps.wait ?? defaultWait;
|
|
251531
251951
|
(async () => {
|
|
251532
251952
|
let previous = initial2;
|
|
@@ -251590,12 +252010,12 @@ ${describeGitHubPullRequestSnapshot(initial2)}
|
|
|
251590
252010
|
if (processState.status === "running") {
|
|
251591
252011
|
markMonitorFinished(taskId, processState, "failed", null);
|
|
251592
252012
|
}
|
|
251593
|
-
});
|
|
252013
|
+
}).finally(() => clearTimeout(timeout));
|
|
251594
252014
|
return {
|
|
251595
252015
|
content: [
|
|
251596
252016
|
{
|
|
251597
252017
|
type: "text",
|
|
251598
|
-
text: `WatchPR started (task ${taskId}). It will keep watching after CI finishes and report new failures, reviews, comments, conflicts, head changes, merge-state changes, and watcher errors. It stops when the PR merges/closes, on TaskStop, or when this session ends.
|
|
252018
|
+
text: `WatchPR started (task ${taskId}). It will keep watching after CI finishes and report new failures, reviews, comments, conflicts, head changes, merge-state changes, and watcher errors. It stops when the PR merges/closes, on TaskStop, or when this session ends.${persistent ? "" : " A hard 1-hour limit applies in this Cloud sandbox; use Wake or cron for later checks."}
|
|
251599
252019
|
|
|
251600
252020
|
Current state:
|
|
251601
252021
|
${describeGitHubPullRequestSnapshot(initial2)}
|
|
@@ -251606,7 +252026,7 @@ Output file: ${outputFile}`
|
|
|
251606
252026
|
taskId,
|
|
251607
252027
|
url: ref5.url,
|
|
251608
252028
|
headSha: initial2.headSha,
|
|
251609
|
-
persistent
|
|
252029
|
+
persistent
|
|
251610
252030
|
};
|
|
251611
252031
|
}
|
|
251612
252032
|
var WATCH_POLL_MS = 30000, WATCH_MAX_POLL_MS;
|
|
@@ -252272,10 +252692,12 @@ async function createSdkSpawnerHandle(args, setStage = () => {}) {
|
|
|
252272
252692
|
});
|
|
252273
252693
|
throw error5;
|
|
252274
252694
|
}
|
|
252275
|
-
const
|
|
252695
|
+
const backgroundStopController = args.wait ? undefined : new AbortController;
|
|
252696
|
+
const toolScope = await createScriptToolScope(parentAgentId, args.wait ? args.signal : backgroundStopController?.signal);
|
|
252276
252697
|
return {
|
|
252277
252698
|
spawner,
|
|
252278
252699
|
...toolScope,
|
|
252700
|
+
backgroundStopController,
|
|
252279
252701
|
cleanup: async () => {
|
|
252280
252702
|
await toolScope.cleanup();
|
|
252281
252703
|
await client[Symbol.asyncDispose]?.().catch(() => {
|
|
@@ -252488,7 +252910,7 @@ async function workflow(args) {
|
|
|
252488
252910
|
const taskId = getNextWorkflowId();
|
|
252489
252911
|
const outputFile = createBackgroundOutputFile(taskId);
|
|
252490
252912
|
const scope = resolveNotificationScope(args.parentScope);
|
|
252491
|
-
const abortController = new AbortController;
|
|
252913
|
+
const abortController = handle2.backgroundStopController ?? new AbortController;
|
|
252492
252914
|
const processState = {
|
|
252493
252915
|
process: {
|
|
252494
252916
|
kill() {
|
|
@@ -253097,7 +253519,7 @@ var init_Monitor2 = __esm(() => {
|
|
|
253097
253519
|
persistent: {
|
|
253098
253520
|
type: "boolean",
|
|
253099
253521
|
default: false,
|
|
253100
|
-
description: "Run
|
|
253522
|
+
description: "Run until TaskStop or session end. In managed Cloud sandboxes, a hard 1-hour limit still applies; elsewhere there is no timeout. For longer waits in Cloud, use Wake/cron rather than keeping a monitor running."
|
|
253101
253523
|
},
|
|
253102
253524
|
backup_after_seconds: {
|
|
253103
253525
|
type: "integer",
|
|
@@ -254260,7 +254682,7 @@ import {
|
|
|
254260
254682
|
readFileSync as readFileSync38,
|
|
254261
254683
|
renameSync as renameSync10,
|
|
254262
254684
|
rmSync as rmSync18,
|
|
254263
|
-
statSync as
|
|
254685
|
+
statSync as statSync19,
|
|
254264
254686
|
writeFileSync as writeFileSync29
|
|
254265
254687
|
} from "node:fs";
|
|
254266
254688
|
import { join as join71 } from "node:path";
|
|
@@ -254579,11 +255001,11 @@ function createRecoveryLineageSidecarAccess(params) {
|
|
|
254579
255001
|
ownerIsAlive = error5.code !== "ESRCH";
|
|
254580
255002
|
}
|
|
254581
255003
|
}
|
|
254582
|
-
const ageMs = Date.now() -
|
|
255004
|
+
const ageMs = Date.now() - statSync19(join71(params.directory, file)).mtimeMs;
|
|
254583
255005
|
if (!ownerIsCurrentWriter && (!ownerIsAlive && ageMs >= staleTemporaryAgeMs || ageMs >= maximumTemporaryAgeMs)) {
|
|
254584
255006
|
const release = acquireDurableFileLock(join71(params.directory, mainFile), { waitMs: params.lockWaitMs });
|
|
254585
255007
|
try {
|
|
254586
|
-
const currentAgeMs = Date.now() -
|
|
255008
|
+
const currentAgeMs = Date.now() - statSync19(join71(params.directory, file)).mtimeMs;
|
|
254587
255009
|
if (!ownerIsCurrentWriter && (!ownerIsAlive && currentAgeMs >= staleTemporaryAgeMs || currentAgeMs >= maximumTemporaryAgeMs)) {
|
|
254588
255010
|
rmSync18(join71(params.directory, file), { force: true });
|
|
254589
255011
|
params.syncDirectory(params.directory);
|
|
@@ -257075,7 +257497,7 @@ import {
|
|
|
257075
257497
|
openSync as openSync7,
|
|
257076
257498
|
readFileSync as readFileSync40,
|
|
257077
257499
|
renameSync as renameSync11,
|
|
257078
|
-
statSync as
|
|
257500
|
+
statSync as statSync20,
|
|
257079
257501
|
unlinkSync as unlinkSync10,
|
|
257080
257502
|
writeFileSync as writeFileSync31
|
|
257081
257503
|
} from "node:fs";
|
|
@@ -257215,7 +257637,7 @@ function validateDurableStore(value) {
|
|
|
257215
257637
|
function readDurableStore(path32) {
|
|
257216
257638
|
if (!existsSync50(path32))
|
|
257217
257639
|
return emptyDurableStore();
|
|
257218
|
-
const size2 =
|
|
257640
|
+
const size2 = statSync20(path32).size;
|
|
257219
257641
|
if (size2 > MAX_INPUT_DISPOSITION_STORE_BYTES) {
|
|
257220
257642
|
throw new Error("Accepted-input disposition store exceeds its size limit");
|
|
257221
257643
|
}
|
|
@@ -264811,7 +265233,7 @@ function isBrowserDeviceMcpOAuthProtocolCommand(value) {
|
|
|
264811
265233
|
return false;
|
|
264812
265234
|
const record6 = value;
|
|
264813
265235
|
if (record6.type === "browser_device_mcp_oauth") {
|
|
264814
|
-
return Object.keys(record6).length === 6 && typeof record6.request_id === "string" && REQUEST_ID_PATTERN.test(record6.request_id) && typeof record6.handoff_key === "string" && HANDOFF_KEY_PATTERN2.test(record6.handoff_key) && typeof record6.service === "string" && SERVICE_PATTERN.test(record6.service) && typeof record6.server_url === "string" && record6.server_url.length > 0 && record6.server_url.length <= MAX_SERVER_URL_LENGTH && !hasControlCharacters(record6.server_url) && typeof record6.timeout_ms === "number" && Number.isSafeInteger(record6.timeout_ms) && record6.timeout_ms > 0 && record6.timeout_ms <=
|
|
265236
|
+
return Object.keys(record6).length === 6 && typeof record6.request_id === "string" && REQUEST_ID_PATTERN.test(record6.request_id) && typeof record6.handoff_key === "string" && HANDOFF_KEY_PATTERN2.test(record6.handoff_key) && typeof record6.service === "string" && SERVICE_PATTERN.test(record6.service) && typeof record6.server_url === "string" && record6.server_url.length > 0 && record6.server_url.length <= MAX_SERVER_URL_LENGTH && !hasControlCharacters(record6.server_url) && typeof record6.timeout_ms === "number" && Number.isSafeInteger(record6.timeout_ms) && record6.timeout_ms > 0 && record6.timeout_ms <= MAX_TIMEOUT_MS;
|
|
264815
265237
|
}
|
|
264816
265238
|
return record6.type === "browser_device_mcp_oauth_cancel" && Object.keys(record6).length === 2 && typeof record6.operation_id === "string" && REQUEST_ID_PATTERN.test(record6.operation_id);
|
|
264817
265239
|
}
|
|
@@ -264823,7 +265245,7 @@ function hasControlCharacters(value) {
|
|
|
264823
265245
|
}
|
|
264824
265246
|
return false;
|
|
264825
265247
|
}
|
|
264826
|
-
var REQUEST_ID_PATTERN, HANDOFF_KEY_PATTERN2, SERVICE_PATTERN, MAX_SERVER_URL_LENGTH = 2048,
|
|
265248
|
+
var REQUEST_ID_PATTERN, HANDOFF_KEY_PATTERN2, SERVICE_PATTERN, MAX_SERVER_URL_LENGTH = 2048, MAX_TIMEOUT_MS = 285000;
|
|
264827
265249
|
var init_browser_device_mcp_oauth_protocol_inbound = __esm(() => {
|
|
264828
265250
|
REQUEST_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
264829
265251
|
HANDOFF_KEY_PATTERN2 = /^[A-Za-z0-9_-]{43,128}$/;
|
|
@@ -266238,7 +266660,7 @@ __export(exports_memory_scanner, {
|
|
|
266238
266660
|
readFileContent: () => readFileContent,
|
|
266239
266661
|
getFileNodes: () => getFileNodes
|
|
266240
266662
|
});
|
|
266241
|
-
import { readdirSync as readdirSync21, readFileSync as readFileSync42, statSync as
|
|
266663
|
+
import { readdirSync as readdirSync21, readFileSync as readFileSync42, statSync as statSync21 } from "node:fs";
|
|
266242
266664
|
import { join as join76, relative as relative7 } from "node:path";
|
|
266243
266665
|
function scanMemoryFilesystem(memoryRoot) {
|
|
266244
266666
|
const nodes = [];
|
|
@@ -266256,10 +266678,10 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
266256
266678
|
let aIsDir = false;
|
|
266257
266679
|
let bIsDir = false;
|
|
266258
266680
|
try {
|
|
266259
|
-
aIsDir =
|
|
266681
|
+
aIsDir = statSync21(aPath).isDirectory();
|
|
266260
266682
|
} catch {}
|
|
266261
266683
|
try {
|
|
266262
|
-
bIsDir =
|
|
266684
|
+
bIsDir = statSync21(bPath).isDirectory();
|
|
266263
266685
|
} catch {}
|
|
266264
266686
|
if (aIsDir !== bIsDir)
|
|
266265
266687
|
return aIsDir ? -1 : 1;
|
|
@@ -266275,7 +266697,7 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
266275
266697
|
const fullPath = join76(dir, name);
|
|
266276
266698
|
let isDir = false;
|
|
266277
266699
|
try {
|
|
266278
|
-
isDir =
|
|
266700
|
+
isDir = statSync21(fullPath).isDirectory();
|
|
266279
266701
|
} catch {
|
|
266280
266702
|
return;
|
|
266281
266703
|
}
|
|
@@ -266374,7 +266796,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
266374
266796
|
const isMemfsEnabledOnServer2 = overrides.isMemfsEnabledOnServer ?? actualIsMemfsEnabledOnServer;
|
|
266375
266797
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memory_scanner(), exports_memory_scanner));
|
|
266376
266798
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
266377
|
-
const { existsSync: existsSync52, statSync:
|
|
266799
|
+
const { existsSync: existsSync52, statSync: statSync22 } = await import("node:fs");
|
|
266378
266800
|
const { join: join77, posix: posix3 } = await import("node:path");
|
|
266379
266801
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
266380
266802
|
let memfsInitialized = existsSync52(join77(memoryRoot, ".git"));
|
|
@@ -266471,7 +266893,7 @@ async function handleListMemoryCommand(parsed, socket, safeSocketSend, overrides
|
|
|
266471
266893
|
if (imageMimeType) {
|
|
266472
266894
|
let size2 = 0;
|
|
266473
266895
|
try {
|
|
266474
|
-
size2 =
|
|
266896
|
+
size2 = statSync22(node.fullPath).size;
|
|
266475
266897
|
} catch {}
|
|
266476
266898
|
return {
|
|
266477
266899
|
relative_path: node.relativePath,
|
|
@@ -276020,7 +276442,7 @@ ${lanes.join(`
|
|
|
276020
276442
|
return process.memoryUsage().heapUsed;
|
|
276021
276443
|
},
|
|
276022
276444
|
getFileSize(path35) {
|
|
276023
|
-
const stat12 =
|
|
276445
|
+
const stat12 = statSync22(path35);
|
|
276024
276446
|
if (stat12 == null ? undefined : stat12.isFile()) {
|
|
276025
276447
|
return stat12.size;
|
|
276026
276448
|
}
|
|
@@ -276063,7 +276485,7 @@ ${lanes.join(`
|
|
|
276063
276485
|
}
|
|
276064
276486
|
};
|
|
276065
276487
|
return nodeSystem;
|
|
276066
|
-
function
|
|
276488
|
+
function statSync22(path35) {
|
|
276067
276489
|
try {
|
|
276068
276490
|
return _fs.statSync(path35, statSyncOptions);
|
|
276069
276491
|
} catch {
|
|
@@ -276115,7 +276537,7 @@ ${lanes.join(`
|
|
|
276115
276537
|
activeSession.post("Profiler.stop", (err, { profile }) => {
|
|
276116
276538
|
var _a10;
|
|
276117
276539
|
if (!err) {
|
|
276118
|
-
if ((_a10 =
|
|
276540
|
+
if ((_a10 = statSync22(profilePath)) == null ? undefined : _a10.isDirectory()) {
|
|
276119
276541
|
profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
|
|
276120
276542
|
}
|
|
276121
276543
|
try {
|
|
@@ -276224,7 +276646,7 @@ ${lanes.join(`
|
|
|
276224
276646
|
let stat12;
|
|
276225
276647
|
if (typeof dirent === "string" || dirent.isSymbolicLink()) {
|
|
276226
276648
|
const name = combinePaths(path35, entry);
|
|
276227
|
-
stat12 =
|
|
276649
|
+
stat12 = statSync22(name);
|
|
276228
276650
|
if (!stat12) {
|
|
276229
276651
|
continue;
|
|
276230
276652
|
}
|
|
@@ -276248,7 +276670,7 @@ ${lanes.join(`
|
|
|
276248
276670
|
return matchFiles(path35, extensions, excludes, includes2, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath6);
|
|
276249
276671
|
}
|
|
276250
276672
|
function fileSystemEntryExists(path35, entryKind) {
|
|
276251
|
-
const stat12 =
|
|
276673
|
+
const stat12 = statSync22(path35);
|
|
276252
276674
|
if (!stat12) {
|
|
276253
276675
|
return false;
|
|
276254
276676
|
}
|
|
@@ -276282,7 +276704,7 @@ ${lanes.join(`
|
|
|
276282
276704
|
}
|
|
276283
276705
|
function getModifiedTime3(path35) {
|
|
276284
276706
|
var _a10;
|
|
276285
|
-
return (_a10 =
|
|
276707
|
+
return (_a10 = statSync22(path35)) == null ? undefined : _a10.mtime;
|
|
276286
276708
|
}
|
|
276287
276709
|
function setModifiedTime(path35, time3) {
|
|
276288
276710
|
try {
|
|
@@ -437757,7 +438179,7 @@ import {
|
|
|
437757
438179
|
mkdirSync as mkdirSync42,
|
|
437758
438180
|
readdirSync as readdirSync23,
|
|
437759
438181
|
readFileSync as readFileSync46,
|
|
437760
|
-
statSync as
|
|
438182
|
+
statSync as statSync22,
|
|
437761
438183
|
unlinkSync as unlinkSync13,
|
|
437762
438184
|
writeFileSync as writeFileSync36
|
|
437763
438185
|
} from "node:fs";
|
|
@@ -438586,7 +439008,7 @@ async function loadLocalMods(options) {
|
|
|
438586
439008
|
recordLegacyExtensionLoadedDiagnostic(registry4, owner, source, options.onDiagnostic);
|
|
438587
439009
|
}
|
|
438588
439010
|
try {
|
|
438589
|
-
const mtimeMs =
|
|
439011
|
+
const mtimeMs = statSync22(modPath).mtimeMs;
|
|
438590
439012
|
const sourceText = readFileSync46(modPath, "utf8");
|
|
438591
439013
|
recordDeprecatedContextApiSourceDiagnostics(sourceText, (diagnostic) => {
|
|
438592
439014
|
recordModDiagnostic(registry4, {
|
|
@@ -453387,7 +453809,7 @@ var init_deepagents = __esm(() => {
|
|
|
453387
453809
|
});
|
|
453388
453810
|
|
|
453389
453811
|
// node_modules/@letta-ai/trajectory/dist/adapters/listing-shared.js
|
|
453390
|
-
import { readdirSync as readdirSync25, statSync as
|
|
453812
|
+
import { readdirSync as readdirSync25, statSync as statSync23 } from "node:fs";
|
|
453391
453813
|
import { join as join83 } from "node:path";
|
|
453392
453814
|
function sortListings(items3) {
|
|
453393
453815
|
return items3.sort((left, right) => {
|
|
@@ -453411,7 +453833,7 @@ function safeReadDir(path42) {
|
|
|
453411
453833
|
}
|
|
453412
453834
|
function safeStat(path42) {
|
|
453413
453835
|
try {
|
|
453414
|
-
const stats =
|
|
453836
|
+
const stats = statSync23(path42);
|
|
453415
453837
|
return { mtimeMs: stats.mtimeMs, sizeBytes: stats.size };
|
|
453416
453838
|
} catch {
|
|
453417
453839
|
return;
|
|
@@ -468690,7 +469112,7 @@ var init_memory_tokens = __esm(() => {
|
|
|
468690
469112
|
});
|
|
468691
469113
|
|
|
468692
469114
|
// src/cli/subcommands/memory.ts
|
|
468693
|
-
import { cpSync, existsSync as existsSync64, mkdirSync as mkdirSync46, rmSync as rmSync22, statSync as
|
|
469115
|
+
import { cpSync, existsSync as existsSync64, mkdirSync as mkdirSync46, rmSync as rmSync22, statSync as statSync24 } from "node:fs";
|
|
468694
469116
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
468695
469117
|
import { dirname as dirname35, join as join94 } from "node:path";
|
|
468696
469118
|
import { parseArgs as parseArgs11 } from "node:util";
|
|
@@ -468765,7 +469187,7 @@ async function listBackups(agentId) {
|
|
|
468765
469187
|
const path46 = join94(agentRoot, entry.name);
|
|
468766
469188
|
let createdAt = null;
|
|
468767
469189
|
try {
|
|
468768
|
-
const stat15 =
|
|
469190
|
+
const stat15 = statSync24(path46);
|
|
468769
469191
|
createdAt = stat15.mtime.toISOString();
|
|
468770
469192
|
} catch {
|
|
468771
469193
|
createdAt = null;
|
|
@@ -468892,7 +469314,7 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
468892
469314
|
console.error(`Backup not found: ${backupPath}`);
|
|
468893
469315
|
return 1;
|
|
468894
469316
|
}
|
|
468895
|
-
const stat15 =
|
|
469317
|
+
const stat15 = statSync24(backupPath);
|
|
468896
469318
|
if (!stat15.isDirectory()) {
|
|
468897
469319
|
console.error(`Backup path is not a directory: ${backupPath}`);
|
|
468898
469320
|
return 1;
|
|
@@ -468915,7 +469337,7 @@ async function runMemorySubcommand(argv, deps = {}) {
|
|
|
468915
469337
|
return 1;
|
|
468916
469338
|
}
|
|
468917
469339
|
if (existsSync64(out)) {
|
|
468918
|
-
const stat15 =
|
|
469340
|
+
const stat15 = statSync24(out);
|
|
468919
469341
|
if (stat15.isDirectory()) {
|
|
468920
469342
|
const contents = await readdir12(out);
|
|
468921
469343
|
if (contents.length > 0) {
|
|
@@ -468963,7 +469385,7 @@ var init_memory7 = __esm(() => {
|
|
|
468963
469385
|
});
|
|
468964
469386
|
|
|
468965
469387
|
// src/backend/local/transcript-search.ts
|
|
468966
|
-
import { existsSync as existsSync65, readdirSync as readdirSync27, readFileSync as readFileSync48, statSync as
|
|
469388
|
+
import { existsSync as existsSync65, readdirSync as readdirSync27, readFileSync as readFileSync48, statSync as statSync25 } from "node:fs";
|
|
468967
469389
|
import { join as join95 } from "node:path";
|
|
468968
469390
|
function readJsonFile3(path46) {
|
|
468969
469391
|
if (!existsSync65(path46))
|
|
@@ -469251,7 +469673,7 @@ function conversationDirectories(storageDir) {
|
|
|
469251
469673
|
if (!existsSync65(conversationsDir))
|
|
469252
469674
|
return [];
|
|
469253
469675
|
try {
|
|
469254
|
-
return readdirSync27(conversationsDir).map((entry) => join95(conversationsDir, entry)).filter((entryPath) =>
|
|
469676
|
+
return readdirSync27(conversationsDir).map((entry) => join95(conversationsDir, entry)).filter((entryPath) => statSync25(entryPath).isDirectory());
|
|
469255
469677
|
} catch {
|
|
469256
469678
|
return [];
|
|
469257
469679
|
}
|
|
@@ -474465,7 +474887,7 @@ import {
|
|
|
474465
474887
|
mkdtempSync as mkdtempSync6,
|
|
474466
474888
|
readFileSync as readFileSync50,
|
|
474467
474889
|
rmSync as rmSync25,
|
|
474468
|
-
statSync as
|
|
474890
|
+
statSync as statSync26,
|
|
474469
474891
|
writeFileSync as writeFileSync41
|
|
474470
474892
|
} from "node:fs";
|
|
474471
474893
|
import { mkdir as mkdir16, readdir as readdir13 } from "node:fs/promises";
|
|
@@ -474923,7 +475345,7 @@ async function installSkillDirectory(params) {
|
|
|
474923
475345
|
if (!existsSync69(skillMdPath)) {
|
|
474924
475346
|
throw new Error("No SKILL.md found in the skill directory.");
|
|
474925
475347
|
}
|
|
474926
|
-
if (!
|
|
475348
|
+
if (!statSync26(sourceDir).isDirectory()) {
|
|
474927
475349
|
throw new Error(`Skill source is not a directory: ${sourceDir}`);
|
|
474928
475350
|
}
|
|
474929
475351
|
const name = getSkillName(sourceDir);
|
|
@@ -474982,7 +475404,7 @@ async function deleteSkillDirectory(params) {
|
|
|
474982
475404
|
if (!existsSync69(targetPath)) {
|
|
474983
475405
|
throw new Error(`Skill "${name}" is not installed at ${targetPath}.`);
|
|
474984
475406
|
}
|
|
474985
|
-
if (!
|
|
475407
|
+
if (!statSync26(targetPath).isDirectory()) {
|
|
474986
475408
|
throw new Error(`Skill path is not a directory: ${targetPath}`);
|
|
474987
475409
|
}
|
|
474988
475410
|
rmSync25(targetPath, { recursive: true, force: true });
|
|
@@ -476880,7 +477302,7 @@ function firstDefinedBoolean(...values4) {
|
|
|
476880
477302
|
}
|
|
476881
477303
|
function normalizeChatTarget(channel, value) {
|
|
476882
477304
|
const trimmed = value.trim();
|
|
476883
|
-
if (channel === "signal")
|
|
477305
|
+
if (channel === "signal" || channel === "microsoftteams")
|
|
476884
477306
|
return trimmed;
|
|
476885
477307
|
const parts = trimmed.split(":").map((part) => part.trim()).filter(Boolean);
|
|
476886
477308
|
if (parts.length === 2 && /^[a-z_-]+$/i.test(parts[0] ?? "")) {
|
|
@@ -484346,6 +484768,9 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
484346
484768
|
await exitHeadless(1, "headless_stop_reason_error");
|
|
484347
484769
|
}
|
|
484348
484770
|
} catch (error5) {
|
|
484771
|
+
if (sigintSignal.aborted) {
|
|
484772
|
+
await exitInterrupted();
|
|
484773
|
+
}
|
|
484349
484774
|
markIncompleteToolsAsCancelled(buffers, true, "stream_error");
|
|
484350
484775
|
const errorDetails = formatErrorDetails2(error5, agent.id);
|
|
484351
484776
|
trackHeadlessBoundaryError("headless_runtime_exception", error5, "headless_turn_execution");
|
|
@@ -484760,6 +485185,30 @@ async function runBidirectionalMode(agent, conversationId, effectiveModel, _outp
|
|
|
484760
485185
|
lineResolver = resolve42;
|
|
484761
485186
|
});
|
|
484762
485187
|
}
|
|
485188
|
+
const EXTERNAL_TOOL_WAIT_ABORTED = Symbol("externalToolWaitAborted");
|
|
485189
|
+
async function getNextLineOrAbort(signal) {
|
|
485190
|
+
if (signal?.aborted)
|
|
485191
|
+
return EXTERNAL_TOOL_WAIT_ABORTED;
|
|
485192
|
+
if (lineQueue.length > 0)
|
|
485193
|
+
return lineQueue.shift() ?? null;
|
|
485194
|
+
if (!signal)
|
|
485195
|
+
return getNextLine();
|
|
485196
|
+
return new Promise((resolve42) => {
|
|
485197
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
485198
|
+
const onAbort = () => {
|
|
485199
|
+
cleanup();
|
|
485200
|
+
if (lineResolver === settle3)
|
|
485201
|
+
lineResolver = null;
|
|
485202
|
+
resolve42(EXTERNAL_TOOL_WAIT_ABORTED);
|
|
485203
|
+
};
|
|
485204
|
+
const settle3 = (line) => {
|
|
485205
|
+
cleanup();
|
|
485206
|
+
resolve42(line);
|
|
485207
|
+
};
|
|
485208
|
+
signal.addEventListener("abort", onAbort);
|
|
485209
|
+
lineResolver = settle3;
|
|
485210
|
+
});
|
|
485211
|
+
}
|
|
484763
485212
|
async function requestPermission(toolCallId, toolName2, toolInput) {
|
|
484764
485213
|
const requestId = `perm-${toolCallId}`;
|
|
484765
485214
|
const diffs = await computeDiffPreviews(toolName2, toolInput);
|
|
@@ -484920,7 +485369,14 @@ async function runBidirectionalMode(agent, conversationId, effectiveModel, _outp
|
|
|
484920
485369
|
const toolsRequest = message2.request;
|
|
484921
485370
|
const tools = toolsRequest.tools ?? [];
|
|
484922
485371
|
registerExternalTools(tools);
|
|
484923
|
-
setExternalToolExecutor(async (toolCallId, toolName2, input) => {
|
|
485372
|
+
setExternalToolExecutor(async (toolCallId, toolName2, input, context3) => {
|
|
485373
|
+
const signal = context3?.signal;
|
|
485374
|
+
if (signal?.aborted) {
|
|
485375
|
+
return {
|
|
485376
|
+
content: [{ type: "text", text: INTERRUPTED_BY_USER }],
|
|
485377
|
+
isError: true
|
|
485378
|
+
};
|
|
485379
|
+
}
|
|
484924
485380
|
const execRequest = {
|
|
484925
485381
|
type: "control_request",
|
|
484926
485382
|
request_id: `ext-${toolCallId}`,
|
|
@@ -484932,25 +485388,48 @@ async function runBidirectionalMode(agent, conversationId, effectiveModel, _outp
|
|
|
484932
485388
|
}
|
|
484933
485389
|
};
|
|
484934
485390
|
writeWireMessage(execRequest);
|
|
484935
|
-
|
|
484936
|
-
|
|
484937
|
-
|
|
484938
|
-
|
|
484939
|
-
|
|
484940
|
-
isError: true
|
|
484941
|
-
};
|
|
484942
|
-
}
|
|
484943
|
-
if (!line2.trim())
|
|
484944
|
-
continue;
|
|
484945
|
-
try {
|
|
484946
|
-
const msg = JSON.parse(line2);
|
|
484947
|
-
if (msg.type === "control_response" && msg.response?.subtype === "external_tool_result" && msg.response?.tool_call_id === toolCallId) {
|
|
485391
|
+
const deferredLines = [];
|
|
485392
|
+
try {
|
|
485393
|
+
while (true) {
|
|
485394
|
+
const line2 = await getNextLineOrAbort(signal);
|
|
485395
|
+
if (line2 === EXTERNAL_TOOL_WAIT_ABORTED) {
|
|
484948
485396
|
return {
|
|
484949
|
-
content:
|
|
484950
|
-
isError:
|
|
485397
|
+
content: [{ type: "text", text: INTERRUPTED_BY_USER }],
|
|
485398
|
+
isError: true
|
|
484951
485399
|
};
|
|
484952
485400
|
}
|
|
484953
|
-
|
|
485401
|
+
if (line2 === null) {
|
|
485402
|
+
return {
|
|
485403
|
+
content: [
|
|
485404
|
+
{
|
|
485405
|
+
type: "text",
|
|
485406
|
+
text: currentAbortController?.signal.aborted ? INTERRUPTED_BY_USER : "stdin closed"
|
|
485407
|
+
}
|
|
485408
|
+
],
|
|
485409
|
+
isError: true
|
|
485410
|
+
};
|
|
485411
|
+
}
|
|
485412
|
+
if (!line2.trim())
|
|
485413
|
+
continue;
|
|
485414
|
+
try {
|
|
485415
|
+
const msg = JSON.parse(line2);
|
|
485416
|
+
if (msg.type === "control_response" && msg.response?.subtype === "external_tool_result") {
|
|
485417
|
+
if (msg.response.tool_call_id === toolCallId) {
|
|
485418
|
+
return {
|
|
485419
|
+
content: msg.response.content ?? [
|
|
485420
|
+
{ type: "text", text: "" }
|
|
485421
|
+
],
|
|
485422
|
+
isError: msg.response.is_error ?? false
|
|
485423
|
+
};
|
|
485424
|
+
}
|
|
485425
|
+
continue;
|
|
485426
|
+
}
|
|
485427
|
+
} catch {}
|
|
485428
|
+
deferredLines.push(line2);
|
|
485429
|
+
}
|
|
485430
|
+
} finally {
|
|
485431
|
+
if (deferredLines.length > 0)
|
|
485432
|
+
lineQueue.unshift(...deferredLines);
|
|
484954
485433
|
}
|
|
484955
485434
|
});
|
|
484956
485435
|
const registerResponse = {
|
|
@@ -485370,10 +485849,18 @@ async function runBidirectionalMode(agent, conversationId, effectiveModel, _outp
|
|
|
485370
485849
|
}
|
|
485371
485850
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
485372
485851
|
emitLocalToolCalls(decisions, sessionId);
|
|
485373
|
-
|
|
485374
|
-
|
|
485375
|
-
|
|
485376
|
-
|
|
485852
|
+
let executedResults;
|
|
485853
|
+
try {
|
|
485854
|
+
executedResults = await executeApprovalBatch2(decisions, undefined, {
|
|
485855
|
+
toolContextId: turnToolContextId ?? undefined,
|
|
485856
|
+
abortSignal: currentAbortController.signal
|
|
485857
|
+
});
|
|
485858
|
+
} catch (error5) {
|
|
485859
|
+
if (currentAbortController?.signal.aborted) {
|
|
485860
|
+
break;
|
|
485861
|
+
}
|
|
485862
|
+
throw error5;
|
|
485863
|
+
}
|
|
485377
485864
|
emitLocalToolReturns(executedResults, sessionId);
|
|
485378
485865
|
currentInput = responseState.prepare(executedResults, needsUserInput.length === 0);
|
|
485379
485866
|
continue;
|
|
@@ -485491,6 +485978,7 @@ var LLM_API_ERROR_MAX_RETRIES2 = 3, EMPTY_RESPONSE_MAX_RETRIES2 = 2, HEADLESS_ST
|
|
|
485491
485978
|
var init_headless = __esm(async () => {
|
|
485492
485979
|
init_error();
|
|
485493
485980
|
init_preloaded_skills();
|
|
485981
|
+
init_constants2();
|
|
485494
485982
|
init_headless_message_sender();
|
|
485495
485983
|
init_headless_response_state();
|
|
485496
485984
|
init_headless_startup_backend();
|
|
@@ -497448,7 +497936,6 @@ var init_SlashCommandAutocomplete = __esm(async () => {
|
|
|
497448
497936
|
"creating-skills",
|
|
497449
497937
|
"customizing-statusline",
|
|
497450
497938
|
"initializing-memory",
|
|
497451
|
-
"migrating-memory",
|
|
497452
497939
|
"syncing-memory-filesystem"
|
|
497453
497940
|
]);
|
|
497454
497941
|
_allCommands = Object.entries(commands).filter(([, { hidden }]) => !hidden).map(([cmd, { desc, order }]) => ({
|
|
@@ -498445,6 +498932,7 @@ function Input({
|
|
|
498445
498932
|
queueMode = "immediate",
|
|
498446
498933
|
deferModeSupported = false,
|
|
498447
498934
|
interruptRequested = false,
|
|
498935
|
+
hasStopFailedTasks = false,
|
|
498448
498936
|
agentId,
|
|
498449
498937
|
agentName,
|
|
498450
498938
|
currentModel,
|
|
@@ -498744,7 +499232,7 @@ function Input({
|
|
|
498744
499232
|
onBashInterrupt();
|
|
498745
499233
|
return;
|
|
498746
499234
|
}
|
|
498747
|
-
if ((streaming3 || interruptRequested) && onInterrupt) {
|
|
499235
|
+
if ((streaming3 || interruptRequested || hasStopFailedTasks) && onInterrupt) {
|
|
498748
499236
|
onInterrupt();
|
|
498749
499237
|
return;
|
|
498750
499238
|
}
|
|
@@ -514750,6 +515238,7 @@ function AppView(props) {
|
|
|
514750
515238
|
inputEnabled,
|
|
514751
515239
|
inputVisible,
|
|
514752
515240
|
interruptRequested,
|
|
515241
|
+
hasStopFailedTasks,
|
|
514753
515242
|
isAgentBusy,
|
|
514754
515243
|
liveItems,
|
|
514755
515244
|
liveTrajectoryElapsedBaseMs,
|
|
@@ -514978,6 +515467,7 @@ function AppView(props) {
|
|
|
514978
515467
|
queueMode,
|
|
514979
515468
|
deferModeSupported,
|
|
514980
515469
|
interruptRequested,
|
|
515470
|
+
hasStopFailedTasks,
|
|
514981
515471
|
agentId,
|
|
514982
515472
|
agentName,
|
|
514983
515473
|
currentModel: currentModelDisplay,
|
|
@@ -516136,6 +516626,12 @@ function useApprovalFlow(ctx) {
|
|
|
516136
516626
|
startupApprovals
|
|
516137
516627
|
]);
|
|
516138
516628
|
const sendAllResults = import_react113.useCallback(async (additionalDecision) => {
|
|
516629
|
+
const approvalAbortController = new AbortController;
|
|
516630
|
+
const approvalResultsSnapshot = [...approvalResults];
|
|
516631
|
+
const autoHandledSnapshot = [...autoHandledResults];
|
|
516632
|
+
const autoDeniedSnapshot = [...autoDeniedApprovals];
|
|
516633
|
+
const pendingSnapshot = [...pendingApprovals];
|
|
516634
|
+
const companionResults = buildCompanionResults(autoHandledSnapshot, autoDeniedSnapshot);
|
|
516139
516635
|
try {
|
|
516140
516636
|
if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
|
|
516141
516637
|
setStreaming(false);
|
|
@@ -516145,12 +516641,13 @@ function useApprovalFlow(ctx) {
|
|
|
516145
516641
|
setApprovalResults([]);
|
|
516146
516642
|
setAutoHandledResults([]);
|
|
516147
516643
|
setAutoDeniedApprovals([]);
|
|
516644
|
+
clearApprovalToolContext();
|
|
516645
|
+
toolAbortControllerRef.current = null;
|
|
516646
|
+
executingToolCallIdsRef.current = [];
|
|
516647
|
+
interruptQueuedRef.current = false;
|
|
516648
|
+
toolResultsInFlightRef.current = false;
|
|
516148
516649
|
return;
|
|
516149
516650
|
}
|
|
516150
|
-
const approvalResultsSnapshot = [...approvalResults];
|
|
516151
|
-
const autoHandledSnapshot = [...autoHandledResults];
|
|
516152
|
-
const autoDeniedSnapshot = [...autoDeniedApprovals];
|
|
516153
|
-
const pendingSnapshot = [...pendingApprovals];
|
|
516154
516651
|
setPendingApprovals([]);
|
|
516155
516652
|
setApprovalContexts([]);
|
|
516156
516653
|
setApprovalResults([]);
|
|
@@ -516159,7 +516656,6 @@ function useApprovalFlow(ctx) {
|
|
|
516159
516656
|
setStreaming(true);
|
|
516160
516657
|
openTrajectorySegment();
|
|
516161
516658
|
buffersRef.current.interrupted = false;
|
|
516162
|
-
const approvalAbortController = new AbortController;
|
|
516163
516659
|
toolAbortControllerRef.current = approvalAbortController;
|
|
516164
516660
|
const allDecisions = [
|
|
516165
516661
|
...approvalResultsSnapshot,
|
|
@@ -516201,23 +516697,10 @@ function useApprovalFlow(ctx) {
|
|
|
516201
516697
|
localToolMs: toolRunMs
|
|
516202
516698
|
});
|
|
516203
516699
|
}
|
|
516204
|
-
|
|
516205
|
-
|
|
516206
|
-
|
|
516207
|
-
|
|
516208
|
-
tool_return: ar.result.toolReturn,
|
|
516209
|
-
status: ar.result.status,
|
|
516210
|
-
stdout: ar.result.stdout,
|
|
516211
|
-
stderr: ar.result.stderr
|
|
516212
|
-
})),
|
|
516213
|
-
...autoDeniedSnapshot.map((ad) => ({
|
|
516214
|
-
type: "approval",
|
|
516215
|
-
tool_call_id: ad.approval.toolCallId,
|
|
516216
|
-
approve: false,
|
|
516217
|
-
reason: ad.reason
|
|
516218
|
-
})),
|
|
516219
|
-
...executedResults
|
|
516220
|
-
];
|
|
516700
|
+
if (toolAbortControllerRef.current !== approvalAbortController) {
|
|
516701
|
+
return;
|
|
516702
|
+
}
|
|
516703
|
+
const allResults = [...companionResults, ...executedResults];
|
|
516221
516704
|
if (true) {
|
|
516222
516705
|
const expectedIds = new Set([
|
|
516223
516706
|
...autoHandledSnapshot.map((ar) => ar.toolCallId),
|
|
@@ -516236,9 +516719,7 @@ function useApprovalFlow(ctx) {
|
|
|
516236
516719
|
const wasAborted = approvalAbortController.signal.aborted;
|
|
516237
516720
|
const userCancelled = userCancelledRef.current;
|
|
516238
516721
|
if (wasAborted || userCancelled) {
|
|
516239
|
-
|
|
516240
|
-
queueApprovalResults(allResults);
|
|
516241
|
-
}
|
|
516722
|
+
queueApprovalResults(allResults);
|
|
516242
516723
|
setStreaming(false);
|
|
516243
516724
|
closeTrajectorySegment();
|
|
516244
516725
|
syncTrajectoryElapsedBase();
|
|
@@ -516259,6 +516740,24 @@ function useApprovalFlow(ctx) {
|
|
|
516259
516740
|
queueApprovalResults(null);
|
|
516260
516741
|
}
|
|
516261
516742
|
} catch (error5) {
|
|
516743
|
+
if (toolAbortControllerRef.current !== approvalAbortController) {
|
|
516744
|
+
return;
|
|
516745
|
+
}
|
|
516746
|
+
if (isUserAbortError(error5)) {
|
|
516747
|
+
markIncompleteToolsAsCancelled(buffersRef.current, true, "user_interrupt");
|
|
516748
|
+
const merged = overlayPartialResults(queuedApprovalResultsRef.current, [
|
|
516749
|
+
...error5.partialResults ?? [],
|
|
516750
|
+
...companionResults
|
|
516751
|
+
]);
|
|
516752
|
+
if (merged.length > 0) {
|
|
516753
|
+
queueApprovalResults(merged);
|
|
516754
|
+
}
|
|
516755
|
+
setStreaming(false);
|
|
516756
|
+
closeTrajectorySegment();
|
|
516757
|
+
syncTrajectoryElapsedBase();
|
|
516758
|
+
refreshDerived();
|
|
516759
|
+
return;
|
|
516760
|
+
}
|
|
516262
516761
|
markIncompleteToolsAsCancelled(buffersRef.current, true, "stream_error");
|
|
516263
516762
|
const errorDetails = formatErrorDetails2(error5, agentId);
|
|
516264
516763
|
appendError(errorDetails, {
|
|
@@ -516270,12 +516769,14 @@ function useApprovalFlow(ctx) {
|
|
|
516270
516769
|
syncTrajectoryElapsedBase();
|
|
516271
516770
|
refreshDerived();
|
|
516272
516771
|
} finally {
|
|
516273
|
-
|
|
516274
|
-
|
|
516275
|
-
|
|
516276
|
-
|
|
516277
|
-
|
|
516278
|
-
|
|
516772
|
+
if (toolAbortControllerRef.current === approvalAbortController) {
|
|
516773
|
+
clearApprovalToolContext();
|
|
516774
|
+
setIsExecutingTool(false);
|
|
516775
|
+
toolAbortControllerRef.current = null;
|
|
516776
|
+
executingToolCallIdsRef.current = [];
|
|
516777
|
+
interruptQueuedRef.current = false;
|
|
516778
|
+
toolResultsInFlightRef.current = false;
|
|
516779
|
+
}
|
|
516279
516780
|
}
|
|
516280
516781
|
}, [
|
|
516281
516782
|
agentId,
|
|
@@ -516603,7 +517104,10 @@ var init_use_approval_flow = __esm(async () => {
|
|
|
516603
517104
|
init_debug();
|
|
516604
517105
|
init_notifications();
|
|
516605
517106
|
init_turn_input();
|
|
516606
|
-
await
|
|
517107
|
+
await __promiseAll([
|
|
517108
|
+
init_approval_execution(),
|
|
517109
|
+
init_manager2()
|
|
517110
|
+
]);
|
|
516607
517111
|
import_react113 = __toESM(require_react(), 1);
|
|
516608
517112
|
});
|
|
516609
517113
|
|
|
@@ -517902,6 +518406,7 @@ function useConversationLoop(ctx) {
|
|
|
517902
518406
|
precomputedDiffsRef,
|
|
517903
518407
|
prepareScopedToolExecutionContext,
|
|
517904
518408
|
processingConversationRef,
|
|
518409
|
+
queuedApprovalResultsRef,
|
|
517905
518410
|
queueApprovalResults,
|
|
517906
518411
|
queueSnapshotRef,
|
|
517907
518412
|
quotaAutoSwapAttemptedRef,
|
|
@@ -518799,7 +519304,11 @@ ${feedback}
|
|
|
518799
519304
|
const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
|
|
518800
519305
|
const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
|
|
518801
519306
|
let autoAllowedResults = [];
|
|
518802
|
-
|
|
519307
|
+
const autoDeniedResults = autoDenied.map((ac) => ({
|
|
519308
|
+
approval: ac.approval,
|
|
519309
|
+
reason: formatPermissionDenial(ac.permission)
|
|
519310
|
+
}));
|
|
519311
|
+
const prebuiltDeniedApprovalResults = buildDeniedResults(autoDeniedResults);
|
|
518803
519312
|
if (shouldTrackAutoAllowed) {
|
|
518804
519313
|
setIsExecutingTool(true);
|
|
518805
519314
|
executingToolCallIdsRef.current = autoAllowedToolCallIds;
|
|
@@ -518816,29 +519325,35 @@ ${feedback}
|
|
|
518816
519325
|
setToolCallsRunning(buffersRef.current, autoAllowedToolCallIds);
|
|
518817
519326
|
refreshDerived();
|
|
518818
519327
|
}
|
|
518819
|
-
|
|
518820
|
-
|
|
518821
|
-
|
|
518822
|
-
|
|
518823
|
-
|
|
518824
|
-
|
|
518825
|
-
|
|
518826
|
-
|
|
519328
|
+
try {
|
|
519329
|
+
const approvalToolContextId = approvalToolContextIdRef.current ?? (await prepareScopedToolExecutionContext(tempModelOverrideRef.current ?? undefined)).preparedToolContext.contextId;
|
|
519330
|
+
autoAllowedResults = autoAllowed.length > 0 ? await executeAutoAllowedTools(autoAllowed, (chunk2) => onChunk(buffersRef.current, chunk2), {
|
|
519331
|
+
abortSignal: autoAllowedAbortController.signal,
|
|
519332
|
+
onStreamingOutput: updateStreamingOutput,
|
|
519333
|
+
toolContextId: approvalToolContextId
|
|
519334
|
+
}) : [];
|
|
519335
|
+
} catch (error5) {
|
|
519336
|
+
if (shouldTrackAutoAllowed && toolAbortControllerRef.current !== autoAllowedAbortController) {
|
|
519337
|
+
return;
|
|
519338
|
+
}
|
|
519339
|
+
appendAbortPartials(error5, prebuiltDeniedApprovalResults);
|
|
519340
|
+
throw error5;
|
|
519341
|
+
}
|
|
519342
|
+
if (shouldTrackAutoAllowed && toolAbortControllerRef.current !== autoAllowedAbortController) {
|
|
519343
|
+
return;
|
|
519344
|
+
}
|
|
519345
|
+
for (const ad of autoDeniedResults) {
|
|
518827
519346
|
onChunk(buffersRef.current, {
|
|
518828
519347
|
message_type: "tool_return_message",
|
|
518829
519348
|
id: "dummy",
|
|
518830
519349
|
date: new Date().toISOString(),
|
|
518831
|
-
tool_call_id:
|
|
518832
|
-
tool_return: `Error: request to call tool denied. User reason: ${reason}`,
|
|
519350
|
+
tool_call_id: ad.approval.toolCallId,
|
|
519351
|
+
tool_return: `Error: request to call tool denied. User reason: ${ad.reason}`,
|
|
518833
519352
|
status: "error",
|
|
518834
519353
|
stdout: null,
|
|
518835
519354
|
stderr: null
|
|
518836
519355
|
});
|
|
518837
|
-
|
|
518838
|
-
approval: ac.approval,
|
|
518839
|
-
reason
|
|
518840
|
-
};
|
|
518841
|
-
});
|
|
519356
|
+
}
|
|
518842
519357
|
const allResults = [
|
|
518843
519358
|
...autoAllowedResults.map((ar) => ({
|
|
518844
519359
|
type: "tool",
|
|
@@ -518848,12 +519363,7 @@ ${feedback}
|
|
|
518848
519363
|
stdout: ar.result.stdout,
|
|
518849
519364
|
stderr: ar.result.stderr
|
|
518850
519365
|
})),
|
|
518851
|
-
...
|
|
518852
|
-
type: "approval",
|
|
518853
|
-
tool_call_id: ad.approval.toolCallId,
|
|
518854
|
-
approve: false,
|
|
518855
|
-
reason: ad.reason
|
|
518856
|
-
}))
|
|
519366
|
+
...prebuiltDeniedApprovalResults
|
|
518857
519367
|
];
|
|
518858
519368
|
if (autoAllowedExecutionRef.current) {
|
|
518859
519369
|
autoAllowedExecutionRef.current.results = allResults;
|
|
@@ -518951,7 +519461,7 @@ ${feedback}
|
|
|
518951
519461
|
return;
|
|
518952
519462
|
}
|
|
518953
519463
|
} finally {
|
|
518954
|
-
if (shouldTrackAutoAllowed) {
|
|
519464
|
+
if (shouldTrackAutoAllowed && toolAbortControllerRef.current === autoAllowedAbortController) {
|
|
518955
519465
|
setIsExecutingTool(false);
|
|
518956
519466
|
toolAbortControllerRef.current = null;
|
|
518957
519467
|
executingToolCallIdsRef.current = [];
|
|
@@ -519285,8 +519795,16 @@ ${feedback}
|
|
|
519285
519795
|
}
|
|
519286
519796
|
} catch (e2) {
|
|
519287
519797
|
debugWarn("message_stream", "Unhandled conversation error: %s", e2 instanceof Error ? e2.stack ?? e2.message : String(e2));
|
|
519288
|
-
|
|
519289
|
-
|
|
519798
|
+
if (abortControllerRef.current !== turnAbortController) {
|
|
519799
|
+
return;
|
|
519800
|
+
}
|
|
519801
|
+
markIncompleteToolsAsCancelled(buffersRef.current, true, isUserAbortError(e2) ? "user_interrupt" : "stream_error");
|
|
519802
|
+
if (EAGER_CANCEL && isUserAbortError(e2)) {
|
|
519803
|
+
const partials = e2.partialResults;
|
|
519804
|
+
const overlaid = partials ? overlayPartialResults(queuedApprovalResultsRef.current, partials) : [];
|
|
519805
|
+
if (overlaid.length > 0) {
|
|
519806
|
+
queueApprovalResults(overlaid);
|
|
519807
|
+
}
|
|
519290
519808
|
setStreaming(false);
|
|
519291
519809
|
refreshDerived();
|
|
519292
519810
|
return;
|
|
@@ -520045,18 +520563,23 @@ var init_use_feedback_handler = __esm(() => {
|
|
|
520045
520563
|
});
|
|
520046
520564
|
|
|
520047
520565
|
// src/cli/app/use-interrupt-handler.ts
|
|
520048
|
-
function hasActiveReflectionSubagentForAgent(agentId) {
|
|
520566
|
+
function hasActiveReflectionSubagentForAgent(agentId, conversationId) {
|
|
520049
520567
|
return getSubagents().some((agent) => {
|
|
520050
520568
|
if (agent.type.toLowerCase() !== "reflection")
|
|
520051
520569
|
return false;
|
|
520052
520570
|
if (agent.status !== "pending" && agent.status !== "running")
|
|
520053
520571
|
return false;
|
|
520054
|
-
|
|
520572
|
+
if (agent.parentAgentId !== agentId)
|
|
520573
|
+
return false;
|
|
520574
|
+
return conversationId === undefined || agent.parentConversationId === undefined || agent.parentConversationId === conversationId;
|
|
520055
520575
|
});
|
|
520056
520576
|
}
|
|
520057
|
-
function interruptSubagentsAndReleaseReflection(agentId) {
|
|
520058
|
-
const interruptedReflection = hasActiveReflectionSubagentForAgent(agentId);
|
|
520059
|
-
interruptActiveSubagents(INTERRUPTED_BY_USER
|
|
520577
|
+
function interruptSubagentsAndReleaseReflection(agentId, conversationId) {
|
|
520578
|
+
const interruptedReflection = hasActiveReflectionSubagentForAgent(agentId, conversationId);
|
|
520579
|
+
interruptActiveSubagents(INTERRUPTED_BY_USER, {
|
|
520580
|
+
agentId,
|
|
520581
|
+
conversationId
|
|
520582
|
+
});
|
|
520060
520583
|
if (interruptedReflection) {
|
|
520061
520584
|
releaseReflectionLaunch(agentId);
|
|
520062
520585
|
}
|
|
@@ -520158,7 +520681,7 @@ function useInterruptHandler(ctx) {
|
|
|
520158
520681
|
autoAllowedExecutionRef.current = null;
|
|
520159
520682
|
buffersRef.current.abortGeneration = (buffersRef.current.abortGeneration || 0) + 1;
|
|
520160
520683
|
const toolsCancelled = markIncompleteToolsAsCancelled(buffersRef.current, true, "user_interrupt");
|
|
520161
|
-
interruptSubagentsAndReleaseReflection(agentId);
|
|
520684
|
+
interruptSubagentsAndReleaseReflection(agentId, conversationIdRef.current);
|
|
520162
520685
|
if (!toolsCancelled) {
|
|
520163
520686
|
appendError(INTERRUPT_MESSAGE, true);
|
|
520164
520687
|
}
|
|
@@ -520188,6 +520711,16 @@ function useInterruptHandler(ctx) {
|
|
|
520188
520711
|
bumpDequeueEpoch: () => setDequeueEpoch((e2) => e2 + 1)
|
|
520189
520712
|
});
|
|
520190
520713
|
}
|
|
520714
|
+
const retried = interruptStopFailedSubagents(INTERRUPTED_BY_USER, {
|
|
520715
|
+
agentId,
|
|
520716
|
+
conversationId: conversationIdRef.current
|
|
520717
|
+
});
|
|
520718
|
+
if (retried.length > 0) {
|
|
520719
|
+
if (retried.some((id2) => getSubagents().find((agent) => agent.id === id2)?.type.toLowerCase() === "reflection")) {
|
|
520720
|
+
releaseReflectionLaunch(agentId);
|
|
520721
|
+
}
|
|
520722
|
+
appendError("Retrying stop of background task...", true);
|
|
520723
|
+
}
|
|
520191
520724
|
return;
|
|
520192
520725
|
}
|
|
520193
520726
|
if (waitingForQueueCancelRef.current) {
|
|
@@ -520198,7 +520731,7 @@ function useInterruptHandler(ctx) {
|
|
|
520198
520731
|
setInterruptRequested(true);
|
|
520199
520732
|
buffersRef.current.abortGeneration = (buffersRef.current.abortGeneration || 0) + 1;
|
|
520200
520733
|
const toolsCancelled = markIncompleteToolsAsCancelled(buffersRef.current, true, "user_interrupt");
|
|
520201
|
-
interruptSubagentsAndReleaseReflection(agentId);
|
|
520734
|
+
interruptSubagentsAndReleaseReflection(agentId, conversationIdRef.current);
|
|
520202
520735
|
abortControllerRef.current?.abort();
|
|
520203
520736
|
pendingInterruptRecoveryConversationIdRef.current = conversationIdRef.current;
|
|
520204
520737
|
userCancelledRef.current = true;
|
|
@@ -529463,6 +529996,7 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
529463
529996
|
precomputedDiffsRef,
|
|
529464
529997
|
prepareScopedToolExecutionContext,
|
|
529465
529998
|
processingConversationRef,
|
|
529999
|
+
queuedApprovalResultsRef,
|
|
529466
530000
|
queueApprovalResults,
|
|
529467
530001
|
queueSnapshotRef,
|
|
529468
530002
|
quotaAutoSwapAttemptedRef,
|
|
@@ -530219,6 +530753,18 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
530219
530753
|
deferredCommitAt
|
|
530220
530754
|
]);
|
|
530221
530755
|
const { agents: subagents } = import_react123.useSyncExternalStore(subscribe2, getSnapshot2);
|
|
530756
|
+
const hasStopFailedTasks = hasStopFailedSubagents({
|
|
530757
|
+
agentId,
|
|
530758
|
+
conversationId
|
|
530759
|
+
});
|
|
530760
|
+
const stopFailedNotifiedRef = import_react123.useRef(new Set);
|
|
530761
|
+
import_react123.useEffect(() => {
|
|
530762
|
+
const { failures, stops } = selectStopFailedNotifications(subagents, stopFailedNotifiedRef.current, { agentId, conversationId });
|
|
530763
|
+
const messages = [...failures, ...stops];
|
|
530764
|
+
if (messages.length > 0) {
|
|
530765
|
+
appendTaskNotificationEvents(messages);
|
|
530766
|
+
}
|
|
530767
|
+
}, [subagents, conversationId, appendTaskNotificationEvents, agentId]);
|
|
530222
530768
|
const estimatedLiveHeight = import_react123.useMemo(() => {
|
|
530223
530769
|
const countLines4 = (text3) => {
|
|
530224
530770
|
if (!text3)
|
|
@@ -530466,6 +531012,7 @@ Memory may be stale. Try running: git -C ${getScopedMemoryFilesystemRoot(agentId
|
|
|
530466
531012
|
inputEnabled,
|
|
530467
531013
|
inputVisible,
|
|
530468
531014
|
interruptRequested: interruptRequested || !!abortControllerRef.current?.signal.aborted,
|
|
531015
|
+
hasStopFailedTasks,
|
|
530469
531016
|
isAgentBusy,
|
|
530470
531017
|
liveItems,
|
|
530471
531018
|
liveTrajectoryElapsedBaseMs,
|
|
@@ -534743,4 +535290,4 @@ function registerBunOAuthFlows() {
|
|
|
534743
535290
|
registerBunOAuthFlows();
|
|
534744
535291
|
await init_src5().then(() => exports_src2);
|
|
534745
535292
|
|
|
534746
|
-
//# debugId=
|
|
535293
|
+
//# debugId=9CD2133B459655FB64756E2164756E21
|