@poolzin/pool-bot 2026.2.21 → 2026.2.22
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/CHANGELOG.md +17 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
|
@@ -14,8 +14,9 @@ export function normalizeCacheKey(value) {
|
|
|
14
14
|
}
|
|
15
15
|
export function readCache(cache, key) {
|
|
16
16
|
const entry = cache.get(key);
|
|
17
|
-
if (!entry)
|
|
17
|
+
if (!entry) {
|
|
18
18
|
return null;
|
|
19
|
+
}
|
|
19
20
|
if (Date.now() > entry.expiresAt) {
|
|
20
21
|
cache.delete(key);
|
|
21
22
|
return null;
|
|
@@ -23,12 +24,14 @@ export function readCache(cache, key) {
|
|
|
23
24
|
return { value: entry.value, cached: true };
|
|
24
25
|
}
|
|
25
26
|
export function writeCache(cache, key, value, ttlMs) {
|
|
26
|
-
if (ttlMs <= 0)
|
|
27
|
+
if (ttlMs <= 0) {
|
|
27
28
|
return;
|
|
29
|
+
}
|
|
28
30
|
if (cache.size >= DEFAULT_CACHE_MAX_ENTRIES) {
|
|
29
31
|
const oldest = cache.keys().next();
|
|
30
|
-
if (!oldest.done)
|
|
32
|
+
if (!oldest.done) {
|
|
31
33
|
cache.delete(oldest.value);
|
|
34
|
+
}
|
|
32
35
|
}
|
|
33
36
|
cache.set(key, {
|
|
34
37
|
value,
|
|
@@ -37,10 +40,11 @@ export function writeCache(cache, key, value, ttlMs) {
|
|
|
37
40
|
});
|
|
38
41
|
}
|
|
39
42
|
export function withTimeout(signal, timeoutMs) {
|
|
40
|
-
if (timeoutMs <= 0)
|
|
43
|
+
if (timeoutMs <= 0) {
|
|
41
44
|
return signal ?? new AbortController().signal;
|
|
45
|
+
}
|
|
42
46
|
const controller = new AbortController();
|
|
43
|
-
const timer = setTimeout(
|
|
47
|
+
const timer = setTimeout(controller.abort.bind(controller), timeoutMs);
|
|
44
48
|
if (signal) {
|
|
45
49
|
signal.addEventListener("abort", () => {
|
|
46
50
|
clearTimeout(timer);
|
|
@@ -52,11 +56,70 @@ export function withTimeout(signal, timeoutMs) {
|
|
|
52
56
|
}, { once: true });
|
|
53
57
|
return controller.signal;
|
|
54
58
|
}
|
|
55
|
-
export async function readResponseText(res) {
|
|
59
|
+
export async function readResponseText(res, options) {
|
|
60
|
+
const maxBytesRaw = options?.maxBytes;
|
|
61
|
+
const maxBytes = typeof maxBytesRaw === "number" && Number.isFinite(maxBytesRaw) && maxBytesRaw > 0
|
|
62
|
+
? Math.floor(maxBytesRaw)
|
|
63
|
+
: undefined;
|
|
64
|
+
const body = res.body;
|
|
65
|
+
if (maxBytes &&
|
|
66
|
+
body &&
|
|
67
|
+
typeof body === "object" &&
|
|
68
|
+
"getReader" in body &&
|
|
69
|
+
typeof body.getReader === "function") {
|
|
70
|
+
const reader = body.getReader();
|
|
71
|
+
const decoder = new TextDecoder();
|
|
72
|
+
let bytesRead = 0;
|
|
73
|
+
let truncated = false;
|
|
74
|
+
const parts = [];
|
|
75
|
+
try {
|
|
76
|
+
while (true) {
|
|
77
|
+
const { value, done } = await reader.read();
|
|
78
|
+
if (done) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (!value || value.byteLength === 0) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
let chunk = value;
|
|
85
|
+
if (bytesRead + chunk.byteLength > maxBytes) {
|
|
86
|
+
const remaining = Math.max(0, maxBytes - bytesRead);
|
|
87
|
+
if (remaining <= 0) {
|
|
88
|
+
truncated = true;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
chunk = chunk.subarray(0, remaining);
|
|
92
|
+
truncated = true;
|
|
93
|
+
}
|
|
94
|
+
bytesRead += chunk.byteLength;
|
|
95
|
+
parts.push(decoder.decode(chunk, { stream: true }));
|
|
96
|
+
if (truncated || bytesRead >= maxBytes) {
|
|
97
|
+
truncated = true;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Best-effort: return whatever we decoded so far.
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
if (truncated) {
|
|
107
|
+
try {
|
|
108
|
+
await reader.cancel();
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// ignore
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
parts.push(decoder.decode());
|
|
116
|
+
return { text: parts.join(""), truncated, bytesRead };
|
|
117
|
+
}
|
|
56
118
|
try {
|
|
57
|
-
|
|
119
|
+
const text = await res.text();
|
|
120
|
+
return { text, truncated: false, bytesRead: text.length };
|
|
58
121
|
}
|
|
59
122
|
catch {
|
|
60
|
-
return "";
|
|
123
|
+
return { text: "", truncated: false, bytesRead: 0 };
|
|
61
124
|
}
|
|
62
125
|
}
|
package/dist/agents/usage.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
const asFiniteNumber = (value) => {
|
|
2
|
-
if (typeof value !== "number")
|
|
2
|
+
if (typeof value !== "number") {
|
|
3
3
|
return undefined;
|
|
4
|
-
|
|
4
|
+
}
|
|
5
|
+
if (!Number.isFinite(value)) {
|
|
5
6
|
return undefined;
|
|
7
|
+
}
|
|
6
8
|
return value;
|
|
7
9
|
};
|
|
8
10
|
export function hasNonzeroUsage(usage) {
|
|
9
|
-
if (!usage)
|
|
11
|
+
if (!usage) {
|
|
10
12
|
return false;
|
|
13
|
+
}
|
|
11
14
|
return [usage.input, usage.output, usage.cacheRead, usage.cacheWrite, usage.total].some((v) => typeof v === "number" && Number.isFinite(v) && v > 0);
|
|
12
15
|
}
|
|
13
16
|
export function normalizeUsage(raw) {
|
|
14
|
-
if (!raw)
|
|
17
|
+
if (!raw) {
|
|
15
18
|
return undefined;
|
|
19
|
+
}
|
|
16
20
|
const input = asFiniteNumber(raw.input ?? raw.inputTokens ?? raw.input_tokens ?? raw.promptTokens ?? raw.prompt_tokens);
|
|
17
21
|
const output = asFiniteNumber(raw.output ??
|
|
18
22
|
raw.outputTokens ??
|
|
@@ -48,23 +52,28 @@ export function derivePromptTokens(usage) {
|
|
|
48
52
|
return sum > 0 ? sum : undefined;
|
|
49
53
|
}
|
|
50
54
|
export function deriveSessionTotalTokens(params) {
|
|
55
|
+
const promptOverride = params.promptTokens;
|
|
56
|
+
const hasPromptOverride = typeof promptOverride === "number" && Number.isFinite(promptOverride) && promptOverride > 0;
|
|
51
57
|
const usage = params.usage;
|
|
52
|
-
if (!usage) {
|
|
58
|
+
if (!usage && !hasPromptOverride) {
|
|
53
59
|
return undefined;
|
|
54
60
|
}
|
|
55
|
-
const input = usage
|
|
56
|
-
const promptTokens =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
const input = usage?.input ?? 0;
|
|
62
|
+
const promptTokens = hasPromptOverride
|
|
63
|
+
? promptOverride
|
|
64
|
+
: derivePromptTokens({
|
|
65
|
+
input: usage?.input,
|
|
66
|
+
cacheRead: usage?.cacheRead,
|
|
67
|
+
cacheWrite: usage?.cacheWrite,
|
|
68
|
+
});
|
|
69
|
+
let total = promptTokens ?? usage?.total ?? input;
|
|
62
70
|
if (!(total > 0)) {
|
|
63
71
|
return undefined;
|
|
64
72
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
// NOTE: Do NOT clamp total to contextTokens here. The stored totalTokens
|
|
74
|
+
// should reflect the actual token count (or best estimate). Clamping causes
|
|
75
|
+
// /status to display contextTokens/contextTokens (100%) when the accumulated
|
|
76
|
+
// input exceeds the context window, hiding the real usage. The display layer
|
|
77
|
+
// (formatTokens in status.ts) already caps the percentage at 999%.
|
|
69
78
|
return total;
|
|
70
79
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { listChannelDocks } from "../channels/dock.js";
|
|
2
2
|
import { getActivePluginRegistry } from "../plugins/runtime.js";
|
|
3
|
-
import { listThinkingLevels } from "./thinking.js";
|
|
4
3
|
import { COMMAND_ARG_FORMATTERS } from "./commands-args.js";
|
|
4
|
+
import { listThinkingLevels } from "./thinking.js";
|
|
5
5
|
function defineChatCommand(command) {
|
|
6
6
|
const aliases = (command.textAliases ?? (command.textAlias ? [command.textAlias] : []))
|
|
7
7
|
.map((alias) => alias.trim())
|
|
@@ -40,11 +40,13 @@ function registerAlias(commands, key, ...aliases) {
|
|
|
40
40
|
const existing = new Set(command.textAliases.map((alias) => alias.trim().toLowerCase()));
|
|
41
41
|
for (const alias of aliases) {
|
|
42
42
|
const trimmed = alias.trim();
|
|
43
|
-
if (!trimmed)
|
|
43
|
+
if (!trimmed) {
|
|
44
44
|
continue;
|
|
45
|
+
}
|
|
45
46
|
const lowered = trimmed.toLowerCase();
|
|
46
|
-
if (existing.has(lowered))
|
|
47
|
+
if (existing.has(lowered)) {
|
|
47
48
|
continue;
|
|
49
|
+
}
|
|
48
50
|
existing.add(lowered);
|
|
49
51
|
command.textAliases.push(trimmed);
|
|
50
52
|
}
|
|
@@ -164,6 +166,22 @@ function buildChatCommands() {
|
|
|
164
166
|
acceptsArgs: true,
|
|
165
167
|
category: "status",
|
|
166
168
|
}),
|
|
169
|
+
defineChatCommand({
|
|
170
|
+
key: "export-session",
|
|
171
|
+
nativeName: "export-session",
|
|
172
|
+
description: "Export current session to HTML file with full system prompt.",
|
|
173
|
+
textAliases: ["/export-session", "/export"],
|
|
174
|
+
acceptsArgs: true,
|
|
175
|
+
category: "status",
|
|
176
|
+
args: [
|
|
177
|
+
{
|
|
178
|
+
name: "path",
|
|
179
|
+
description: "Output path (default: workspace)",
|
|
180
|
+
type: "string",
|
|
181
|
+
required: false,
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
}),
|
|
167
185
|
defineChatCommand({
|
|
168
186
|
key: "tts",
|
|
169
187
|
nativeName: "tts",
|
|
@@ -216,15 +234,15 @@ function buildChatCommands() {
|
|
|
216
234
|
defineChatCommand({
|
|
217
235
|
key: "subagents",
|
|
218
236
|
nativeName: "subagents",
|
|
219
|
-
description: "List
|
|
237
|
+
description: "List, kill, log, spawn, or steer subagent runs for this session.",
|
|
220
238
|
textAlias: "/subagents",
|
|
221
239
|
category: "management",
|
|
222
240
|
args: [
|
|
223
241
|
{
|
|
224
242
|
name: "action",
|
|
225
|
-
description: "list |
|
|
243
|
+
description: "list | kill | log | info | send | steer | spawn",
|
|
226
244
|
type: "string",
|
|
227
|
-
choices: ["list", "
|
|
245
|
+
choices: ["list", "kill", "log", "info", "send", "steer", "spawn"],
|
|
228
246
|
},
|
|
229
247
|
{
|
|
230
248
|
name: "target",
|
|
@@ -240,6 +258,41 @@ function buildChatCommands() {
|
|
|
240
258
|
],
|
|
241
259
|
argsMenu: "auto",
|
|
242
260
|
}),
|
|
261
|
+
defineChatCommand({
|
|
262
|
+
key: "kill",
|
|
263
|
+
nativeName: "kill",
|
|
264
|
+
description: "Kill a running subagent (or all).",
|
|
265
|
+
textAlias: "/kill",
|
|
266
|
+
category: "management",
|
|
267
|
+
args: [
|
|
268
|
+
{
|
|
269
|
+
name: "target",
|
|
270
|
+
description: "Label, run id, index, or all",
|
|
271
|
+
type: "string",
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
argsMenu: "auto",
|
|
275
|
+
}),
|
|
276
|
+
defineChatCommand({
|
|
277
|
+
key: "steer",
|
|
278
|
+
nativeName: "steer",
|
|
279
|
+
description: "Send guidance to a running subagent.",
|
|
280
|
+
textAlias: "/steer",
|
|
281
|
+
category: "management",
|
|
282
|
+
args: [
|
|
283
|
+
{
|
|
284
|
+
name: "target",
|
|
285
|
+
description: "Label, run id, or index",
|
|
286
|
+
type: "string",
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "message",
|
|
290
|
+
description: "Steering message",
|
|
291
|
+
type: "string",
|
|
292
|
+
captureRemaining: true,
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
}),
|
|
243
296
|
defineChatCommand({
|
|
244
297
|
key: "config",
|
|
245
298
|
nativeName: "config",
|
|
@@ -322,7 +375,7 @@ function buildChatCommands() {
|
|
|
322
375
|
defineChatCommand({
|
|
323
376
|
key: "restart",
|
|
324
377
|
nativeName: "restart",
|
|
325
|
-
description: "Restart
|
|
378
|
+
description: "Restart Pool Bot.",
|
|
326
379
|
textAlias: "/restart",
|
|
327
380
|
category: "tools",
|
|
328
381
|
}),
|
|
@@ -376,9 +429,9 @@ function buildChatCommands() {
|
|
|
376
429
|
}),
|
|
377
430
|
defineChatCommand({
|
|
378
431
|
key: "compact",
|
|
432
|
+
nativeName: "compact",
|
|
379
433
|
description: "Compact the session context.",
|
|
380
434
|
textAlias: "/compact",
|
|
381
|
-
scope: "text",
|
|
382
435
|
category: "session",
|
|
383
436
|
args: [
|
|
384
437
|
{
|
|
@@ -461,12 +514,31 @@ function buildChatCommands() {
|
|
|
461
514
|
category: "options",
|
|
462
515
|
args: [
|
|
463
516
|
{
|
|
464
|
-
name: "
|
|
465
|
-
description: "
|
|
517
|
+
name: "host",
|
|
518
|
+
description: "sandbox, gateway, or node",
|
|
519
|
+
type: "string",
|
|
520
|
+
choices: ["sandbox", "gateway", "node"],
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: "security",
|
|
524
|
+
description: "deny, allowlist, or full",
|
|
525
|
+
type: "string",
|
|
526
|
+
choices: ["deny", "allowlist", "full"],
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
name: "ask",
|
|
530
|
+
description: "off, on-miss, or always",
|
|
531
|
+
type: "string",
|
|
532
|
+
choices: ["off", "on-miss", "always"],
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
name: "node",
|
|
536
|
+
description: "Node id or name",
|
|
466
537
|
type: "string",
|
|
467
538
|
},
|
|
468
539
|
],
|
|
469
540
|
argsParsing: "none",
|
|
541
|
+
formatArgs: COMMAND_ARG_FORMATTERS.exec,
|
|
470
542
|
}),
|
|
471
543
|
defineChatCommand({
|
|
472
544
|
key: "model",
|
|
@@ -548,13 +620,15 @@ function buildChatCommands() {
|
|
|
548
620
|
registerAlias(commands, "verbose", "/v");
|
|
549
621
|
registerAlias(commands, "reasoning", "/reason");
|
|
550
622
|
registerAlias(commands, "elevated", "/elev");
|
|
623
|
+
registerAlias(commands, "steer", "/tell");
|
|
551
624
|
assertCommandRegistry(commands);
|
|
552
625
|
return commands;
|
|
553
626
|
}
|
|
554
627
|
export function getChatCommands() {
|
|
555
628
|
const registry = getActivePluginRegistry();
|
|
556
|
-
if (cachedCommands && registry === cachedRegistry)
|
|
629
|
+
if (cachedCommands && registry === cachedRegistry) {
|
|
557
630
|
return cachedCommands;
|
|
631
|
+
}
|
|
558
632
|
const commands = buildChatCommands();
|
|
559
633
|
cachedCommands = commands;
|
|
560
634
|
cachedRegistry = registry;
|
|
@@ -1,40 +1,59 @@
|
|
|
1
|
-
import { finalizeInboundContext } from "./reply/inbound-context.js";
|
|
2
1
|
import { dispatchReplyFromConfig } from "./reply/dispatch-from-config.js";
|
|
2
|
+
import { finalizeInboundContext } from "./reply/inbound-context.js";
|
|
3
3
|
import { createReplyDispatcher, createReplyDispatcherWithTyping, } from "./reply/reply-dispatcher.js";
|
|
4
|
+
export async function withReplyDispatcher(params) {
|
|
5
|
+
try {
|
|
6
|
+
return await params.run();
|
|
7
|
+
}
|
|
8
|
+
finally {
|
|
9
|
+
// Ensure dispatcher reservations are always released on every exit path.
|
|
10
|
+
params.dispatcher.markComplete();
|
|
11
|
+
try {
|
|
12
|
+
await params.dispatcher.waitForIdle();
|
|
13
|
+
}
|
|
14
|
+
finally {
|
|
15
|
+
await params.onSettled?.();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
4
19
|
export async function dispatchInboundMessage(params) {
|
|
5
20
|
const finalized = finalizeInboundContext(params.ctx);
|
|
6
|
-
return await
|
|
7
|
-
ctx: finalized,
|
|
8
|
-
cfg: params.cfg,
|
|
21
|
+
return await withReplyDispatcher({
|
|
9
22
|
dispatcher: params.dispatcher,
|
|
10
|
-
|
|
11
|
-
|
|
23
|
+
run: () => dispatchReplyFromConfig({
|
|
24
|
+
ctx: finalized,
|
|
25
|
+
cfg: params.cfg,
|
|
26
|
+
dispatcher: params.dispatcher,
|
|
27
|
+
replyOptions: params.replyOptions,
|
|
28
|
+
replyResolver: params.replyResolver,
|
|
29
|
+
}),
|
|
12
30
|
});
|
|
13
31
|
}
|
|
14
32
|
export async function dispatchInboundMessageWithBufferedDispatcher(params) {
|
|
15
33
|
const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping(params.dispatcherOptions);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
try {
|
|
35
|
+
return await dispatchInboundMessage({
|
|
36
|
+
ctx: params.ctx,
|
|
37
|
+
cfg: params.cfg,
|
|
38
|
+
dispatcher,
|
|
39
|
+
replyResolver: params.replyResolver,
|
|
40
|
+
replyOptions: {
|
|
41
|
+
...params.replyOptions,
|
|
42
|
+
...replyOptions,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
markDispatchIdle();
|
|
48
|
+
}
|
|
28
49
|
}
|
|
29
50
|
export async function dispatchInboundMessageWithDispatcher(params) {
|
|
30
51
|
const dispatcher = createReplyDispatcher(params.dispatcherOptions);
|
|
31
|
-
|
|
52
|
+
return await dispatchInboundMessage({
|
|
32
53
|
ctx: params.ctx,
|
|
33
54
|
cfg: params.cfg,
|
|
34
55
|
dispatcher,
|
|
35
56
|
replyResolver: params.replyResolver,
|
|
36
57
|
replyOptions: params.replyOptions,
|
|
37
58
|
});
|
|
38
|
-
await dispatcher.waitForIdle();
|
|
39
|
-
return result;
|
|
40
59
|
}
|
|
@@ -1,27 +1,76 @@
|
|
|
1
1
|
import { resolveSessionAgentId } from "../../agents/agent-scope.js";
|
|
2
2
|
import { abortEmbeddedPiRun } from "../../agents/pi-embedded.js";
|
|
3
|
-
import { listSubagentRunsForRequester } from "../../agents/subagent-registry.js";
|
|
3
|
+
import { listSubagentRunsForRequester, markSubagentRunTerminated, } from "../../agents/subagent-registry.js";
|
|
4
|
+
import { resolveInternalSessionKey, resolveMainSessionAlias, } from "../../agents/tools/sessions-helpers.js";
|
|
4
5
|
import { loadSessionStore, resolveStorePath, updateSessionStore, } from "../../config/sessions.js";
|
|
6
|
+
import { logVerbose } from "../../globals.js";
|
|
5
7
|
import { parseAgentSessionKey } from "../../routing/session-key.js";
|
|
6
8
|
import { resolveCommandAuthorization } from "../command-auth.js";
|
|
7
9
|
import { normalizeCommandBody } from "../commands-registry.js";
|
|
8
|
-
import { logVerbose } from "../../globals.js";
|
|
9
10
|
import { stripMentions, stripStructuralPrefixes } from "./mentions.js";
|
|
10
11
|
import { clearSessionQueues } from "./queue.js";
|
|
11
|
-
import { resolveInternalSessionKey, resolveMainSessionAlias, } from "../../agents/tools/sessions-helpers.js";
|
|
12
12
|
const ABORT_TRIGGERS = new Set(["stop", "esc", "abort", "wait", "exit", "interrupt"]);
|
|
13
13
|
const ABORT_MEMORY = new Map();
|
|
14
|
+
const ABORT_MEMORY_MAX = 2000;
|
|
14
15
|
export function isAbortTrigger(text) {
|
|
15
|
-
if (!text)
|
|
16
|
+
if (!text) {
|
|
16
17
|
return false;
|
|
18
|
+
}
|
|
17
19
|
const normalized = text.trim().toLowerCase();
|
|
18
20
|
return ABORT_TRIGGERS.has(normalized);
|
|
19
21
|
}
|
|
22
|
+
export function isAbortRequestText(text, options) {
|
|
23
|
+
if (!text) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const normalized = normalizeCommandBody(text, options).trim();
|
|
27
|
+
if (!normalized) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return normalized.toLowerCase() === "/stop" || isAbortTrigger(normalized);
|
|
31
|
+
}
|
|
20
32
|
export function getAbortMemory(key) {
|
|
21
|
-
|
|
33
|
+
const normalized = key.trim();
|
|
34
|
+
if (!normalized) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return ABORT_MEMORY.get(normalized);
|
|
38
|
+
}
|
|
39
|
+
function pruneAbortMemory() {
|
|
40
|
+
if (ABORT_MEMORY.size <= ABORT_MEMORY_MAX) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const excess = ABORT_MEMORY.size - ABORT_MEMORY_MAX;
|
|
44
|
+
let removed = 0;
|
|
45
|
+
for (const entryKey of ABORT_MEMORY.keys()) {
|
|
46
|
+
ABORT_MEMORY.delete(entryKey);
|
|
47
|
+
removed += 1;
|
|
48
|
+
if (removed >= excess) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
22
52
|
}
|
|
23
53
|
export function setAbortMemory(key, value) {
|
|
24
|
-
|
|
54
|
+
const normalized = key.trim();
|
|
55
|
+
if (!normalized) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (!value) {
|
|
59
|
+
ABORT_MEMORY.delete(normalized);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Refresh insertion order so active keys are less likely to be evicted.
|
|
63
|
+
if (ABORT_MEMORY.has(normalized)) {
|
|
64
|
+
ABORT_MEMORY.delete(normalized);
|
|
65
|
+
}
|
|
66
|
+
ABORT_MEMORY.set(normalized, true);
|
|
67
|
+
pruneAbortMemory();
|
|
68
|
+
}
|
|
69
|
+
export function getAbortMemorySizeForTest() {
|
|
70
|
+
return ABORT_MEMORY.size;
|
|
71
|
+
}
|
|
72
|
+
export function resetAbortMemoryForTest() {
|
|
73
|
+
ABORT_MEMORY.clear();
|
|
25
74
|
}
|
|
26
75
|
export function formatAbortReplyText(stoppedSubagents) {
|
|
27
76
|
if (typeof stoppedSubagents !== "number" || stoppedSubagents <= 0) {
|
|
@@ -31,58 +80,76 @@ export function formatAbortReplyText(stoppedSubagents) {
|
|
|
31
80
|
return `⚙️ Agent was aborted. Stopped ${stoppedSubagents} ${label}.`;
|
|
32
81
|
}
|
|
33
82
|
function resolveSessionEntryForKey(store, sessionKey) {
|
|
34
|
-
if (!store || !sessionKey)
|
|
83
|
+
if (!store || !sessionKey) {
|
|
35
84
|
return {};
|
|
85
|
+
}
|
|
36
86
|
const direct = store[sessionKey];
|
|
37
|
-
if (direct)
|
|
87
|
+
if (direct) {
|
|
38
88
|
return { entry: direct, key: sessionKey };
|
|
89
|
+
}
|
|
39
90
|
return {};
|
|
40
91
|
}
|
|
41
92
|
function resolveAbortTargetKey(ctx) {
|
|
42
93
|
const target = ctx.CommandTargetSessionKey?.trim();
|
|
43
|
-
if (target)
|
|
94
|
+
if (target) {
|
|
44
95
|
return target;
|
|
96
|
+
}
|
|
45
97
|
const sessionKey = ctx.SessionKey?.trim();
|
|
46
98
|
return sessionKey || undefined;
|
|
47
99
|
}
|
|
48
100
|
function normalizeRequesterSessionKey(cfg, key) {
|
|
49
101
|
const cleaned = key?.trim();
|
|
50
|
-
if (!cleaned)
|
|
102
|
+
if (!cleaned) {
|
|
51
103
|
return undefined;
|
|
104
|
+
}
|
|
52
105
|
const { mainKey, alias } = resolveMainSessionAlias(cfg);
|
|
53
106
|
return resolveInternalSessionKey({ key: cleaned, alias, mainKey });
|
|
54
107
|
}
|
|
55
108
|
export function stopSubagentsForRequester(params) {
|
|
56
109
|
const requesterKey = normalizeRequesterSessionKey(params.cfg, params.requesterSessionKey);
|
|
57
|
-
if (!requesterKey)
|
|
110
|
+
if (!requesterKey) {
|
|
58
111
|
return { stopped: 0 };
|
|
112
|
+
}
|
|
59
113
|
const runs = listSubagentRunsForRequester(requesterKey);
|
|
60
|
-
if (runs.length === 0)
|
|
114
|
+
if (runs.length === 0) {
|
|
61
115
|
return { stopped: 0 };
|
|
116
|
+
}
|
|
62
117
|
const storeCache = new Map();
|
|
63
118
|
const seenChildKeys = new Set();
|
|
64
119
|
let stopped = 0;
|
|
65
120
|
for (const run of runs) {
|
|
66
|
-
if (run.endedAt)
|
|
67
|
-
continue;
|
|
68
121
|
const childKey = run.childSessionKey?.trim();
|
|
69
|
-
if (!childKey || seenChildKeys.has(childKey))
|
|
122
|
+
if (!childKey || seenChildKeys.has(childKey)) {
|
|
70
123
|
continue;
|
|
71
|
-
seenChildKeys.add(childKey);
|
|
72
|
-
const cleared = clearSessionQueues([childKey]);
|
|
73
|
-
const parsed = parseAgentSessionKey(childKey);
|
|
74
|
-
const storePath = resolveStorePath(params.cfg.session?.store, { agentId: parsed?.agentId });
|
|
75
|
-
let store = storeCache.get(storePath);
|
|
76
|
-
if (!store) {
|
|
77
|
-
store = loadSessionStore(storePath);
|
|
78
|
-
storeCache.set(storePath, store);
|
|
79
124
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
125
|
+
seenChildKeys.add(childKey);
|
|
126
|
+
if (!run.endedAt) {
|
|
127
|
+
const cleared = clearSessionQueues([childKey]);
|
|
128
|
+
const parsed = parseAgentSessionKey(childKey);
|
|
129
|
+
const storePath = resolveStorePath(params.cfg.session?.store, { agentId: parsed?.agentId });
|
|
130
|
+
let store = storeCache.get(storePath);
|
|
131
|
+
if (!store) {
|
|
132
|
+
store = loadSessionStore(storePath);
|
|
133
|
+
storeCache.set(storePath, store);
|
|
134
|
+
}
|
|
135
|
+
const entry = store[childKey];
|
|
136
|
+
const sessionId = entry?.sessionId;
|
|
137
|
+
const aborted = sessionId ? abortEmbeddedPiRun(sessionId) : false;
|
|
138
|
+
const markedTerminated = markSubagentRunTerminated({
|
|
139
|
+
runId: run.runId,
|
|
140
|
+
childSessionKey: childKey,
|
|
141
|
+
reason: "killed",
|
|
142
|
+
}) > 0;
|
|
143
|
+
if (markedTerminated || aborted || cleared.followupCleared > 0 || cleared.laneCleared > 0) {
|
|
144
|
+
stopped += 1;
|
|
145
|
+
}
|
|
85
146
|
}
|
|
147
|
+
// Cascade: also stop any sub-sub-agents spawned by this child.
|
|
148
|
+
const cascadeResult = stopSubagentsForRequester({
|
|
149
|
+
cfg: params.cfg,
|
|
150
|
+
requesterSessionKey: childKey,
|
|
151
|
+
});
|
|
152
|
+
stopped += cascadeResult.stopped;
|
|
86
153
|
}
|
|
87
154
|
if (stopped > 0) {
|
|
88
155
|
logVerbose(`abort: stopped ${stopped} subagent run(s) for ${requesterKey}`);
|
|
@@ -100,18 +167,19 @@ export async function tryFastAbortFromMessage(params) {
|
|
|
100
167
|
const raw = stripStructuralPrefixes(ctx.CommandBody ?? ctx.RawBody ?? ctx.Body ?? "");
|
|
101
168
|
const isGroup = ctx.ChatType?.trim().toLowerCase() === "group";
|
|
102
169
|
const stripped = isGroup ? stripMentions(raw, ctx, cfg, agentId) : raw;
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
if (!abortRequested)
|
|
170
|
+
const abortRequested = isAbortRequestText(stripped);
|
|
171
|
+
if (!abortRequested) {
|
|
106
172
|
return { handled: false, aborted: false };
|
|
173
|
+
}
|
|
107
174
|
const commandAuthorized = ctx.CommandAuthorized;
|
|
108
175
|
const auth = resolveCommandAuthorization({
|
|
109
176
|
ctx,
|
|
110
177
|
cfg,
|
|
111
178
|
commandAuthorized,
|
|
112
179
|
});
|
|
113
|
-
if (!auth.isAuthorizedSender)
|
|
180
|
+
if (!auth.isAuthorizedSender) {
|
|
114
181
|
return { handled: false, aborted: false };
|
|
182
|
+
}
|
|
115
183
|
const abortKey = targetKey ?? auth.from ?? auth.to;
|
|
116
184
|
const requesterSessionKey = targetKey ?? ctx.SessionKey ?? abortKey;
|
|
117
185
|
if (targetKey) {
|
|
@@ -130,8 +198,9 @@ export async function tryFastAbortFromMessage(params) {
|
|
|
130
198
|
store[key] = entry;
|
|
131
199
|
await updateSessionStore(storePath, (nextStore) => {
|
|
132
200
|
const nextEntry = nextStore[key] ?? entry;
|
|
133
|
-
if (!nextEntry)
|
|
201
|
+
if (!nextEntry) {
|
|
134
202
|
return;
|
|
203
|
+
}
|
|
135
204
|
nextEntry.abortedLastRun = true;
|
|
136
205
|
nextEntry.updatedAt = Date.now();
|
|
137
206
|
nextStore[key] = nextEntry;
|