@poolzin/pool-bot 2026.2.25 → 2026.2.26
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/acp/event-mapper.js +87 -22
- package/dist/acp/meta.js +12 -6
- package/dist/agents/agent-paths.js +8 -9
- package/dist/agents/agent-scope.js +7 -5
- package/dist/agents/auth-profiles/oauth.js +148 -64
- package/dist/agents/auth-profiles/session-override.js +13 -7
- package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
- package/dist/agents/bash-tools.exec-runtime.js +2 -25
- package/dist/agents/bedrock-discovery.js +3 -1
- package/dist/agents/byteplus-models.js +97 -0
- package/dist/agents/chutes-oauth.js +1 -0
- package/dist/agents/cli-runner/helpers.js +4 -0
- package/dist/agents/compaction.js +41 -14
- package/dist/agents/doubao-models.js +121 -0
- package/dist/agents/failover-error.js +2 -0
- package/dist/agents/huggingface-models.js +5 -3
- package/dist/agents/live-model-filter.js +5 -0
- package/dist/agents/minimax-vlm.js +10 -8
- package/dist/agents/model-auth.js +6 -0
- package/dist/agents/model-catalog.js +3 -1
- package/dist/agents/model-selection.js +7 -1
- package/dist/agents/models-config.providers.js +93 -11
- package/dist/agents/ollama-stream.js +117 -4
- package/dist/agents/opencode-zen-models.js +22 -11
- package/dist/agents/pi-embedded-helpers/errors.js +55 -33
- package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
- package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +29 -7
- package/dist/agents/pi-embedded-runner/extensions.js +28 -26
- package/dist/agents/pi-embedded-runner/google.js +20 -8
- package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
- package/dist/agents/pi-embedded-runner/run.js +71 -12
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
- package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
- package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
- package/dist/agents/pi-embedded-runner/thinking.js +42 -0
- package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
- package/dist/agents/pi-embedded-runner/utils.js +7 -10
- package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
- package/dist/agents/pi-embedded-subscribe.js +9 -4
- package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
- package/dist/agents/pi-embedded-utils.js +3 -0
- package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
- package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
- package/dist/agents/pi-settings.js +40 -0
- package/dist/agents/pi-tools.policy.js +2 -1
- package/dist/agents/provider/config-loader.js +1 -1
- package/dist/agents/sandbox/browser.js +170 -33
- package/dist/agents/sandbox/config-hash.js +14 -27
- package/dist/agents/sandbox/config.js +21 -2
- package/dist/agents/sandbox/constants.js +2 -0
- package/dist/agents/sandbox/docker.js +16 -2
- package/dist/agents/sandbox/novnc-auth.js +62 -0
- package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
- package/dist/agents/sandbox/shared.js +10 -6
- package/dist/agents/sandbox-paths.js +24 -11
- package/dist/agents/schema/clean-for-gemini.js +132 -85
- package/dist/agents/session-slug.js +10 -5
- package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
- package/dist/agents/session-tool-result-guard.js +3 -1
- package/dist/agents/session-transcript-repair.js +40 -6
- package/dist/agents/skills/bundled-dir.js +19 -5
- package/dist/agents/skills/env-overrides.js +124 -43
- package/dist/agents/skills/frontmatter.js +6 -6
- package/dist/agents/skills/plugin-skills.js +14 -7
- package/dist/agents/skills/workspace.js +1 -0
- package/dist/agents/subagent-announce.js +251 -49
- package/dist/agents/subagent-lifecycle-events.js +19 -0
- package/dist/agents/subagent-registry-cleanup.js +31 -0
- package/dist/agents/subagent-registry-completion.js +68 -0
- package/dist/agents/subagent-registry-queries.js +117 -0
- package/dist/agents/subagent-registry-state.js +46 -0
- package/dist/agents/subagent-registry.js +252 -221
- package/dist/agents/subagent-registry.store.js +1 -0
- package/dist/agents/subagent-registry.types.js +1 -0
- package/dist/agents/subagent-spawn.js +195 -7
- package/dist/agents/system-prompt.js +22 -6
- package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
- package/dist/agents/test-helpers/fast-core-tools.js +1 -17
- package/dist/agents/timeout.js +18 -6
- package/dist/agents/tool-call-id.js +1 -1
- package/dist/agents/tool-display-common.js +162 -29
- package/dist/agents/tool-images.js +82 -9
- package/dist/agents/tool-policy.js +51 -26
- package/dist/agents/tools/browser-tool.js +2 -2
- package/dist/agents/tools/canvas-tool.js +27 -1
- package/dist/agents/tools/common.js +45 -0
- package/dist/agents/tools/discord-actions-guild.js +4 -1
- package/dist/agents/tools/gateway-tool.js +3 -1
- package/dist/agents/tools/nodes-utils.js +1 -10
- package/dist/agents/tools/sessions-send-helpers.js +12 -6
- package/dist/agents/tools/sessions-spawn-tool.js +8 -2
- package/dist/agents/tools/subagents-tool.js +2 -1
- package/dist/agents/tools/whatsapp-actions.js +10 -2
- package/dist/agents/tools/whatsapp-target-auth.js +18 -0
- package/dist/agents/transcript-policy.js +22 -8
- package/dist/agents/venice-models.js +11 -3
- package/dist/auto-reply/commands-registry.data.js +51 -0
- package/dist/auto-reply/commands-registry.js +4 -3
- package/dist/auto-reply/group-activation.js +10 -5
- package/dist/auto-reply/inbound-debounce.js +10 -5
- package/dist/auto-reply/reply/abort.js +1 -1
- package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
- package/dist/auto-reply/reply/bash-command.js +41 -39
- package/dist/auto-reply/reply/command-gates.js +25 -0
- package/dist/auto-reply/reply/commands-allowlist.js +111 -72
- package/dist/auto-reply/reply/commands-bash.js +6 -5
- package/dist/auto-reply/reply/commands-config.js +30 -28
- package/dist/auto-reply/reply/commands-core.js +2 -1
- package/dist/auto-reply/reply/commands-info.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +65 -14
- package/dist/auto-reply/reply/commands-session.js +237 -82
- package/dist/auto-reply/reply/commands-setunset.js +45 -0
- package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
- package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
- package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
- package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
- package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
- package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
- package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
- package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
- package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
- package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
- package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
- package/dist/auto-reply/reply/commands-subagents.js +51 -587
- package/dist/auto-reply/reply/commands-tts.js +10 -5
- package/dist/auto-reply/reply/config-value.js +10 -5
- package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
- package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
- package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
- package/dist/auto-reply/reply/followup-runner.js +1 -0
- package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
- package/dist/auto-reply/reply/get-reply-directives.js +17 -28
- package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
- package/dist/auto-reply/reply/get-reply.js +71 -12
- package/dist/auto-reply/reply/model-selection.js +80 -39
- package/dist/auto-reply/reply/queue/enqueue.js +10 -5
- package/dist/auto-reply/reply/queue/state.js +13 -12
- package/dist/auto-reply/reply/reply-payloads.js +67 -36
- package/dist/auto-reply/reply/reply-reference.js +9 -8
- package/dist/auto-reply/reply/route-reply.js +15 -8
- package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
- package/dist/auto-reply/reply/session.js +22 -6
- package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
- package/dist/auto-reply/reply/subagents-utils.js +56 -30
- package/dist/auto-reply/reply/typing.js +46 -21
- package/dist/auto-reply/send-policy.js +14 -7
- package/dist/auto-reply/status.js +140 -16
- package/dist/auto-reply/templating.js +10 -5
- package/dist/auto-reply/thinking.js +7 -16
- package/dist/auto-reply/tokens.js +21 -5
- package/dist/browser/bridge-server.js +36 -20
- package/dist/browser/cdp.helpers.js +7 -14
- package/dist/browser/cdp.js +35 -15
- package/dist/browser/chrome.profile-decoration.js +7 -4
- package/dist/browser/config.js +4 -0
- package/dist/browser/extension-relay-auth.js +55 -0
- package/dist/browser/extension-relay.js +74 -29
- package/dist/browser/navigation-guard.js +9 -1
- package/dist/browser/paths.js +77 -0
- package/dist/browser/profiles.js +13 -8
- package/dist/browser/pw-ai-module.js +10 -5
- package/dist/browser/pw-session.js +76 -39
- package/dist/browser/pw-tools-core.interactions.js +14 -7
- package/dist/browser/pw-tools-core.state.js +12 -6
- package/dist/browser/routes/agent.act.js +2 -2
- package/dist/browser/server-context.js +7 -0
- package/dist/build-info.json +3 -3
- package/dist/channels/allow-from.js +2 -1
- package/dist/channels/allowlists/resolve-utils.js +43 -19
- package/dist/channels/channel-config.js +14 -7
- package/dist/channels/draft-stream-loop.js +7 -0
- package/dist/channels/model-overrides.js +82 -0
- package/dist/channels/plugins/normalize/imessage.js +14 -7
- package/dist/channels/plugins/normalize/slack.js +10 -5
- package/dist/channels/plugins/normalize/telegram.js +14 -7
- package/dist/channels/plugins/outbound/discord.js +80 -8
- package/dist/channels/plugins/outbound/signal.js +11 -11
- package/dist/channels/plugins/setup-helpers.js +10 -5
- package/dist/channels/sender-label.js +14 -7
- package/dist/channels/session.js +4 -2
- package/dist/channels/status-reactions.js +297 -0
- package/dist/cli/banner.js +1 -1
- package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
- package/dist/cli/cli-name.js +11 -11
- package/dist/cli/cli-utils.js +13 -3
- package/dist/cli/command-format.js +1 -1
- package/dist/cli/config-cli.js +1 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
- package/dist/cli/daemon-cli/lifecycle.js +64 -2
- package/dist/cli/daemon-cli/restart-health.js +126 -0
- package/dist/cli/daemon-cli/status.gather.js +9 -13
- package/dist/cli/daemon-cli/status.print.js +2 -10
- package/dist/cli/deps.js +27 -22
- package/dist/cli/gateway-cli/run-loop.js +23 -5
- package/dist/cli/node-cli/register.js +14 -5
- package/dist/cli/nodes-media-utils.js +7 -2
- package/dist/cli/outbound-send-deps.js +2 -9
- package/dist/cli/outbound-send-mapping.js +11 -0
- package/dist/cli/pairing-cli.js +40 -14
- package/dist/cli/plugins-cli.js +34 -41
- package/dist/cli/ports.js +11 -10
- package/dist/cli/program/command-registry.js +2 -11
- package/dist/cli/program/command-tree.js +16 -0
- package/dist/cli/program/preaction.js +13 -9
- package/dist/cli/program/register.configure.js +3 -18
- package/dist/cli/program/register.maintenance.js +2 -2
- package/dist/cli/program/register.onboard.js +2 -0
- package/dist/cli/program/register.status-health-sessions.js +16 -17
- package/dist/cli/program/register.subclis.js +93 -52
- package/dist/cli/route.js +11 -7
- package/dist/cli/system-cli.js +36 -46
- package/dist/cli/update-cli/shared.js +22 -9
- package/dist/cli/update-cli/update-command.js +89 -14
- package/dist/cli/update-cli/wizard.js +6 -12
- package/dist/commands/agent/run-context.js +18 -5
- package/dist/commands/agent/session-store.js +17 -4
- package/dist/commands/agent.js +22 -2
- package/dist/commands/agents.bindings.js +14 -7
- package/dist/commands/agents.commands.add.js +13 -9
- package/dist/commands/agents.commands.identity.js +12 -6
- package/dist/commands/agents.commands.list.js +11 -6
- package/dist/commands/agents.config.js +8 -10
- package/dist/commands/agents.providers.js +12 -6
- package/dist/commands/auth-choice-options.js +103 -75
- package/dist/commands/auth-choice.apply.byteplus.js +55 -0
- package/dist/commands/auth-choice.apply.js +4 -0
- package/dist/commands/auth-choice.apply.minimax.js +61 -13
- package/dist/commands/auth-choice.apply.openai.js +3 -1
- package/dist/commands/auth-choice.apply.volcengine.js +55 -0
- package/dist/commands/auth-choice.preferred-provider.js +2 -0
- package/dist/commands/channels/remove.js +13 -6
- package/dist/commands/channels/shared.js +4 -14
- package/dist/commands/configure.commands.js +14 -0
- package/dist/commands/configure.gateway.js +2 -4
- package/dist/commands/configure.js +1 -1
- package/dist/commands/configure.shared.js +11 -0
- package/dist/commands/daemon-install-helpers.js +2 -2
- package/dist/commands/dashboard.js +12 -10
- package/dist/commands/docs.js +14 -8
- package/dist/commands/doctor-config-flow.js +11 -9
- package/dist/commands/doctor-legacy-config.js +281 -0
- package/dist/commands/doctor-state-integrity.js +99 -23
- package/dist/commands/doctor-update.js +12 -9
- package/dist/commands/models/list.list-command.js +7 -5
- package/dist/commands/models/set-image.js +2 -21
- package/dist/commands/node-daemon-install-helpers.js +10 -8
- package/dist/commands/onboard-auth.config-minimax.js +54 -80
- package/dist/commands/onboard-auth.config-opencode.js +2 -18
- package/dist/commands/onboard-auth.credentials.js +90 -13
- package/dist/commands/onboard-auth.js +1 -1
- package/dist/commands/onboard-auth.models.js +6 -5
- package/dist/commands/onboard-hooks.js +1 -1
- package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
- package/dist/commands/onboard-provider-auth-flags.js +14 -0
- package/dist/commands/onboard-remote.js +14 -7
- package/dist/commands/onboard.js +11 -13
- package/dist/commands/sandbox-display.js +6 -5
- package/dist/commands/status-all/diagnosis.js +14 -10
- package/dist/commands/status-all/format.js +1 -0
- package/dist/commands/status.gateway-probe.js +1 -16
- package/dist/commands/systemd-linger.js +12 -6
- package/dist/config/agent-limits.js +2 -0
- package/dist/config/commands.js +30 -16
- package/dist/config/config-paths.js +9 -11
- package/dist/config/defaults.js +22 -2
- package/dist/config/discord-preview-streaming.js +104 -0
- package/dist/config/env-vars.js +37 -8
- package/dist/config/includes.js +4 -0
- package/dist/config/io.js +97 -12
- package/dist/config/legacy.migrations.part-1.js +189 -78
- package/dist/config/legacy.shared.js +3 -1
- package/dist/config/merge-patch.js +4 -0
- package/dist/config/prototype-keys.js +4 -0
- package/dist/config/schema.help.js +44 -7
- package/dist/config/schema.labels.js +38 -6
- package/dist/config/sessions/delivery-info.js +10 -3
- package/dist/config/sessions/main-session.js +10 -5
- package/dist/config/sessions/session-file.js +33 -0
- package/dist/config/sessions/session-key.js +10 -5
- package/dist/config/sessions/store.js +1 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/zod-schema.agent-runtime.js +11 -0
- package/dist/config/zod-schema.js +148 -13
- package/dist/config/zod-schema.providers-core.js +78 -4
- package/dist/config/zod-schema.providers.js +6 -1
- package/dist/config/zod-schema.session.js +41 -2
- package/dist/cron/run-log.js +3 -0
- package/dist/cron/schedule.js +21 -10
- package/dist/cron/service/ops.js +35 -21
- package/dist/cron/service/timer.js +116 -16
- package/dist/cron/stagger.js +3 -1
- package/dist/discord/api.js +12 -6
- package/dist/discord/draft-chunking.js +22 -0
- package/dist/discord/draft-stream.js +124 -0
- package/dist/discord/monitor/agent-components.js +1 -1
- package/dist/discord/monitor/commands.js +5 -0
- package/dist/discord/monitor/gateway-plugin.js +2 -1
- package/dist/discord/monitor/listeners.js +37 -27
- package/dist/discord/monitor/message-handler.js +4 -1
- package/dist/discord/monitor/message-handler.preflight.js +65 -8
- package/dist/discord/monitor/message-handler.process.js +246 -217
- package/dist/discord/monitor/message-utils.js +143 -6
- package/dist/discord/monitor/model-picker-preferences.js +143 -0
- package/dist/discord/monitor/model-picker.js +651 -0
- package/dist/discord/monitor/native-command.js +573 -16
- package/dist/discord/monitor/provider.allowlist.js +223 -0
- package/dist/discord/monitor/provider.js +275 -347
- package/dist/discord/monitor/provider.lifecycle.js +100 -0
- package/dist/discord/monitor/reply-delivery.js +123 -16
- package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
- package/dist/discord/monitor/thread-bindings.js +4 -0
- package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
- package/dist/discord/monitor/thread-bindings.manager.js +423 -0
- package/dist/discord/monitor/thread-bindings.messages.js +55 -0
- package/dist/discord/monitor/thread-bindings.state.js +358 -0
- package/dist/discord/monitor/thread-bindings.types.js +6 -0
- package/dist/discord/resolve-users.js +33 -21
- package/dist/discord/send.channels.js +15 -0
- package/dist/discord/send.js +3 -2
- package/dist/discord/send.outbound.js +82 -26
- package/dist/discord/send.permissions.js +83 -30
- package/dist/discord/send.reactions.js +8 -4
- package/dist/discord/token.js +10 -5
- package/dist/discord/voice/command.js +263 -0
- package/dist/discord/voice/manager.js +531 -0
- package/dist/gateway/auth.js +34 -10
- package/dist/gateway/call.js +4 -16
- package/dist/gateway/client.js +28 -4
- package/dist/gateway/config-reload.js +3 -4
- package/dist/gateway/control-ui.js +219 -96
- package/dist/gateway/hooks-mapping.js +88 -38
- package/dist/gateway/http-auth-helpers.js +3 -2
- package/dist/gateway/http-endpoint-helpers.js +1 -0
- package/dist/gateway/net.js +54 -12
- package/dist/gateway/node-invoke-system-run-approval.js +14 -35
- package/dist/gateway/node-registry.js +10 -5
- package/dist/gateway/openai-http.js +1 -0
- package/dist/gateway/openresponses-http.js +1 -0
- package/dist/gateway/origin-check.js +1 -18
- package/dist/gateway/protocol/index.js +4 -3
- package/dist/gateway/protocol/schema/cron.js +1 -0
- package/dist/gateway/protocol/schema/devices.js +1 -0
- package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
- package/dist/gateway/protocol/schema/sessions.js +6 -0
- package/dist/gateway/role-policy.js +17 -0
- package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
- package/dist/gateway/server/ws-connection/message-handler.js +175 -148
- package/dist/gateway/server-chat.js +83 -25
- package/dist/gateway/server-constants.js +10 -9
- package/dist/gateway/server-cron.js +1 -0
- package/dist/gateway/server-http.js +16 -7
- package/dist/gateway/server-maintenance.js +20 -5
- package/dist/gateway/server-methods/chat.js +10 -6
- package/dist/gateway/server-methods/config.js +12 -14
- package/dist/gateway/server-methods/devices.js +17 -3
- package/dist/gateway/server-methods/models.js +11 -1
- package/dist/gateway/server-methods/sessions.js +64 -8
- package/dist/gateway/server-methods/usage.js +162 -75
- package/dist/gateway/server-node-events.js +29 -0
- package/dist/gateway/server-runtime-config.js +34 -13
- package/dist/gateway/server-startup-memory.js +17 -11
- package/dist/gateway/session-utils.fs.js +32 -34
- package/dist/gateway/sessions-resolve.js +17 -5
- package/dist/gateway/test-helpers.openai-mock.js +14 -7
- package/dist/gateway/tools-invoke-http.js +21 -10
- package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
- package/dist/hooks/bundled/command-logger/handler.js +7 -2
- package/dist/hooks/bundled/session-memory/handler.js +6 -5
- package/dist/hooks/frontmatter.js +6 -6
- package/dist/hooks/gmail-watcher.js +11 -6
- package/dist/hooks/internal-hooks.js +11 -1
- package/dist/hooks/llm-slug-generator.js +4 -1
- package/dist/hooks/workspace.js +47 -17
- package/dist/imessage/accounts.js +9 -20
- package/dist/imessage/monitor/inbound-processing.js +2 -1
- package/dist/infra/archive.js +174 -73
- package/dist/infra/control-ui-assets.js +14 -6
- package/dist/infra/device-pairing.js +108 -29
- package/dist/infra/env.js +10 -5
- package/dist/infra/exec-approvals-allowlist.js +122 -0
- package/dist/infra/exec-approvals-analysis.js +34 -3
- package/dist/infra/exec-approvals.js +5 -17
- package/dist/infra/exec-safe-bin-policy.js +53 -45
- package/dist/infra/fs-safe.js +71 -39
- package/dist/infra/gateway-lock.js +6 -2
- package/dist/infra/heartbeat-wake.js +6 -12
- package/dist/infra/host-env-security-policy.json +19 -0
- package/dist/infra/host-env-security.js +66 -0
- package/dist/infra/net/ssrf.js +131 -38
- package/dist/infra/outbound/bound-delivery-router.js +88 -0
- package/dist/infra/outbound/channel-selection.js +12 -6
- package/dist/infra/outbound/envelope.js +1 -1
- package/dist/infra/outbound/format.js +12 -6
- package/dist/infra/outbound/payloads.js +14 -7
- package/dist/infra/outbound/session-binding-service.js +123 -0
- package/dist/infra/path-guards.js +25 -0
- package/dist/infra/provider-usage.fetch.codex.js +7 -15
- package/dist/infra/provider-usage.fetch.gemini.js +14 -11
- package/dist/infra/provider-usage.fetch.shared.js +30 -1
- package/dist/infra/provider-usage.fetch.zai.js +10 -9
- package/dist/infra/retry-policy.js +4 -2
- package/dist/infra/retry.js +9 -5
- package/dist/infra/session-cost-usage.js +107 -59
- package/dist/infra/session-maintenance-warning.js +3 -1
- package/dist/infra/shell-env.js +98 -34
- package/dist/infra/ssh-config.js +12 -6
- package/dist/infra/system-run-command.js +49 -4
- package/dist/infra/update-channels.js +10 -5
- package/dist/line/accounts.js +5 -7
- package/dist/line/bot-access.js +8 -20
- package/dist/line/bot-handlers.js +3 -1
- package/dist/link-understanding/detect.js +15 -7
- package/dist/media/constants.js +15 -6
- package/dist/media/image-ops.js +7 -0
- package/dist/media/local-roots.js +3 -2
- package/dist/media-understanding/apply.js +4 -1
- package/dist/media-understanding/concurrency.js +8 -20
- package/dist/memory/backend-config.js +45 -6
- package/dist/memory/embeddings.js +10 -4
- package/dist/memory/fs-utils.js +23 -0
- package/dist/memory/manager-search.js +12 -6
- package/dist/memory/manager-sync-ops.js +12 -2
- package/dist/memory/qmd-manager.js +466 -53
- package/dist/memory/query-expansion.js +167 -3
- package/dist/memory/status-format.js +10 -5
- package/dist/memory/sync-memory-files.js +1 -1
- package/dist/node-host/invoke-system-run.js +281 -0
- package/dist/node-host/invoke.js +55 -337
- package/dist/pairing/pairing-store.js +22 -0
- package/dist/plugin-sdk/allow-from.js +1 -1
- package/dist/plugin-sdk/command-auth.js +3 -1
- package/dist/plugin-sdk/index.js +6 -3
- package/dist/plugin-sdk/webhook-targets.js +32 -0
- package/dist/plugins/bundled-dir.js +9 -6
- package/dist/plugins/hooks.js +50 -0
- package/dist/plugins/install.js +28 -16
- package/dist/plugins/runtime.js +3 -17
- package/dist/plugins/update.js +78 -12
- package/dist/process/spawn-utils.js +14 -7
- package/dist/providers/github-copilot-token.js +11 -6
- package/dist/providers/qwen-portal-oauth.js +14 -6
- package/dist/routing/account-id.js +30 -0
- package/dist/routing/resolve-route.js +3 -7
- package/dist/routing/session-key.js +2 -16
- package/dist/security/audit-channel.js +93 -2
- package/dist/security/audit-extra.async.js +159 -5
- package/dist/security/audit-extra.js +1 -1
- package/dist/security/audit-extra.sync.js +85 -6
- package/dist/security/audit.js +40 -4
- package/dist/security/dm-policy-shared.js +44 -0
- package/dist/security/external-content.js +26 -6
- package/dist/shared/entry-status.js +6 -0
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-match.js +11 -4
- package/dist/shared/operator-scope-compat.js +8 -3
- package/dist/signal/accounts.js +7 -20
- package/dist/signal/monitor/event-handler.js +3 -1
- package/dist/slack/accounts.js +6 -19
- package/dist/slack/actions.js +11 -3
- package/dist/slack/monitor/auth.js +1 -1
- package/dist/slack/monitor/message-handler/dispatch.js +50 -29
- package/dist/slack/monitor/replies.js +15 -7
- package/dist/slack/monitor/slash.js +22 -13
- package/dist/slack/resolve-channels.js +10 -5
- package/dist/slack/send.js +102 -12
- package/dist/slack/stream-mode.js +10 -0
- package/dist/slack/streaming.js +4 -2
- package/dist/telegram/accounts.js +19 -14
- package/dist/telegram/bot/helpers.js +3 -5
- package/dist/telegram/bot-access.js +35 -36
- package/dist/telegram/bot-handlers.js +120 -148
- package/dist/telegram/bot-message-context.js +68 -9
- package/dist/telegram/bot-message-dispatch.js +155 -90
- package/dist/telegram/bot-native-commands.js +16 -0
- package/dist/telegram/draft-stream.js +14 -1
- package/dist/telegram/inline-buttons.js +5 -15
- package/dist/telegram/monitor.js +11 -7
- package/dist/telegram/network-config.js +19 -7
- package/dist/telegram/send.js +3 -2
- package/dist/telegram/sent-message-cache.js +5 -6
- package/dist/telegram/status-reaction-variants.js +208 -0
- package/dist/telegram/sticker-cache.js +11 -9
- package/dist/terminal/theme.js +12 -12
- package/dist/tts/tts.js +80 -567
- package/dist/tui/components/chat-log.js +41 -8
- package/dist/tui/theme/theme.js +10 -12
- package/dist/tui/tui-local-shell.js +16 -6
- package/dist/tui/tui.js +58 -6
- package/dist/utils/account-id.js +2 -4
- package/dist/utils/boolean.js +10 -5
- package/dist/utils/directive-tags.js +11 -0
- package/dist/utils/queue-helpers.js +67 -12
- package/dist/web/auto-reply/deliver-reply.js +8 -4
- package/dist/web/auto-reply/mentions.js +10 -5
- package/dist/web/auto-reply/monitor/group-members.js +14 -7
- package/dist/web/auto-reply/monitor/process-message.js +45 -24
- package/dist/web/inbound/access-control.js +5 -2
- package/dist/web/login-qr.js +12 -6
- package/dist/web/media.js +123 -16
- package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
- package/extensions/bluebubbles/src/monitor.ts +208 -1950
- package/package.json +1 -1
|
@@ -5,7 +5,11 @@ import { defaultRuntime } from "../runtime.js";
|
|
|
5
5
|
import { normalizeDeliveryContext } from "../utils/delivery-context.js";
|
|
6
6
|
import { resetAnnounceQueuesForTests } from "./subagent-announce-queue.js";
|
|
7
7
|
import { runSubagentAnnounceFlow } from "./subagent-announce.js";
|
|
8
|
-
import {
|
|
8
|
+
import { SUBAGENT_ENDED_OUTCOME_KILLED, SUBAGENT_ENDED_REASON_COMPLETE, SUBAGENT_ENDED_REASON_ERROR, SUBAGENT_ENDED_REASON_KILLED, } from "./subagent-lifecycle-events.js";
|
|
9
|
+
import { resolveCleanupCompletionReason, resolveDeferredCleanupDecision, } from "./subagent-registry-cleanup.js";
|
|
10
|
+
import { emitSubagentEndedHookOnce, resolveLifecycleOutcomeFromRunOutcome, runOutcomesEqual, } from "./subagent-registry-completion.js";
|
|
11
|
+
import { countActiveDescendantRunsFromRuns, countActiveRunsForSessionFromRuns, findRunIdsByChildSessionKeyFromRuns, listDescendantRunsForRequesterFromRuns, listRunsForRequesterFromRuns, resolveRequesterForChildSessionFromRuns, } from "./subagent-registry-queries.js";
|
|
12
|
+
import { getSubagentRunsSnapshotForRead, persistSubagentRunsToDisk, restoreSubagentRunsFromDisk, } from "./subagent-registry-state.js";
|
|
9
13
|
import { resolveAgentTimeoutMs } from "./timeout.js";
|
|
10
14
|
const subagentRuns = new Map();
|
|
11
15
|
let sweeper = null;
|
|
@@ -41,17 +45,85 @@ function logAnnounceGiveUp(entry, reason) {
|
|
|
41
45
|
defaultRuntime.log(`[warn] Subagent announce give up (${reason}) run=${entry.runId} child=${entry.childSessionKey} requester=${entry.requesterSessionKey} retries=${retryCount} endedAgo=${endedAgoLabel}`);
|
|
42
46
|
}
|
|
43
47
|
function persistSubagentRuns() {
|
|
44
|
-
|
|
45
|
-
saveSubagentRegistryToDisk(subagentRuns);
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
// ignore persistence failures
|
|
49
|
-
}
|
|
48
|
+
persistSubagentRunsToDisk(subagentRuns);
|
|
50
49
|
}
|
|
51
50
|
const resumedRuns = new Set();
|
|
51
|
+
const endedHookInFlightRunIds = new Set();
|
|
52
52
|
function suppressAnnounceForSteerRestart(entry) {
|
|
53
53
|
return entry?.suppressAnnounceReason === "steer-restart";
|
|
54
54
|
}
|
|
55
|
+
function shouldKeepThreadBindingAfterRun(params) {
|
|
56
|
+
if (params.reason === SUBAGENT_ENDED_REASON_KILLED) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return params.entry.spawnMode === "session";
|
|
60
|
+
}
|
|
61
|
+
function shouldEmitEndedHookForRun(params) {
|
|
62
|
+
return !shouldKeepThreadBindingAfterRun(params);
|
|
63
|
+
}
|
|
64
|
+
async function emitSubagentEndedHookForRun(params) {
|
|
65
|
+
const reason = params.reason ?? params.entry.endedReason ?? SUBAGENT_ENDED_REASON_COMPLETE;
|
|
66
|
+
const outcome = resolveLifecycleOutcomeFromRunOutcome(params.entry.outcome);
|
|
67
|
+
const error = params.entry.outcome?.status === "error" ? params.entry.outcome.error : undefined;
|
|
68
|
+
await emitSubagentEndedHookOnce({
|
|
69
|
+
entry: params.entry,
|
|
70
|
+
reason,
|
|
71
|
+
sendFarewell: params.sendFarewell,
|
|
72
|
+
accountId: params.accountId ?? params.entry.requesterOrigin?.accountId,
|
|
73
|
+
outcome,
|
|
74
|
+
error,
|
|
75
|
+
inFlightRunIds: endedHookInFlightRunIds,
|
|
76
|
+
persist: persistSubagentRuns,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async function completeSubagentRun(params) {
|
|
80
|
+
const entry = subagentRuns.get(params.runId);
|
|
81
|
+
if (!entry) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
let mutated = false;
|
|
85
|
+
const endedAt = typeof params.endedAt === "number" ? params.endedAt : Date.now();
|
|
86
|
+
if (entry.endedAt !== endedAt) {
|
|
87
|
+
entry.endedAt = endedAt;
|
|
88
|
+
mutated = true;
|
|
89
|
+
}
|
|
90
|
+
if (!runOutcomesEqual(entry.outcome, params.outcome)) {
|
|
91
|
+
entry.outcome = params.outcome;
|
|
92
|
+
mutated = true;
|
|
93
|
+
}
|
|
94
|
+
if (entry.endedReason !== params.reason) {
|
|
95
|
+
entry.endedReason = params.reason;
|
|
96
|
+
mutated = true;
|
|
97
|
+
}
|
|
98
|
+
if (mutated) {
|
|
99
|
+
persistSubagentRuns();
|
|
100
|
+
}
|
|
101
|
+
const suppressedForSteerRestart = suppressAnnounceForSteerRestart(entry);
|
|
102
|
+
const shouldEmitEndedHook = !suppressedForSteerRestart &&
|
|
103
|
+
shouldEmitEndedHookForRun({
|
|
104
|
+
entry,
|
|
105
|
+
reason: params.reason,
|
|
106
|
+
});
|
|
107
|
+
const shouldDeferEndedHook = shouldEmitEndedHook &&
|
|
108
|
+
params.triggerCleanup &&
|
|
109
|
+
entry.expectsCompletionMessage === true &&
|
|
110
|
+
!suppressedForSteerRestart;
|
|
111
|
+
if (!shouldDeferEndedHook && shouldEmitEndedHook) {
|
|
112
|
+
await emitSubagentEndedHookForRun({
|
|
113
|
+
entry,
|
|
114
|
+
reason: params.reason,
|
|
115
|
+
sendFarewell: params.sendFarewell,
|
|
116
|
+
accountId: params.accountId,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (!params.triggerCleanup) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (suppressedForSteerRestart) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
startSubagentAnnounceCleanupFlow(params.runId, entry);
|
|
126
|
+
}
|
|
55
127
|
function startSubagentAnnounceCleanupFlow(runId, entry) {
|
|
56
128
|
if (!beginSubagentCleanup(runId)) {
|
|
57
129
|
return false;
|
|
@@ -64,7 +136,6 @@ function startSubagentAnnounceCleanupFlow(runId, entry) {
|
|
|
64
136
|
requesterOrigin,
|
|
65
137
|
requesterDisplayKey: entry.requesterDisplayKey,
|
|
66
138
|
task: entry.task,
|
|
67
|
-
expectsCompletionMessage: entry.expectsCompletionMessage,
|
|
68
139
|
timeoutMs: SUBAGENT_ANNOUNCE_TIMEOUT_MS,
|
|
69
140
|
cleanup: entry.cleanup,
|
|
70
141
|
waitForCompletion: false,
|
|
@@ -72,8 +143,10 @@ function startSubagentAnnounceCleanupFlow(runId, entry) {
|
|
|
72
143
|
endedAt: entry.endedAt,
|
|
73
144
|
label: entry.label,
|
|
74
145
|
outcome: entry.outcome,
|
|
146
|
+
spawnMode: entry.spawnMode,
|
|
147
|
+
expectsCompletionMessage: entry.expectsCompletionMessage,
|
|
75
148
|
}).then((didAnnounce) => {
|
|
76
|
-
finalizeSubagentCleanup(runId, entry.cleanup, didAnnounce);
|
|
149
|
+
void finalizeSubagentCleanup(runId, entry.cleanup, didAnnounce);
|
|
77
150
|
});
|
|
78
151
|
return true;
|
|
79
152
|
}
|
|
@@ -137,19 +210,13 @@ function restoreSubagentRunsOnce() {
|
|
|
137
210
|
}
|
|
138
211
|
restoreAttempted = true;
|
|
139
212
|
try {
|
|
140
|
-
const
|
|
141
|
-
|
|
213
|
+
const restoredCount = restoreSubagentRunsFromDisk({
|
|
214
|
+
runs: subagentRuns,
|
|
215
|
+
mergeOnly: true,
|
|
216
|
+
});
|
|
217
|
+
if (restoredCount === 0) {
|
|
142
218
|
return;
|
|
143
219
|
}
|
|
144
|
-
for (const [runId, entry] of restored.entries()) {
|
|
145
|
-
if (!runId || !entry) {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
// Keep any newer in-memory entries.
|
|
149
|
-
if (!subagentRuns.has(runId)) {
|
|
150
|
-
subagentRuns.set(runId, entry);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
220
|
// Resume pending work.
|
|
154
221
|
ensureListener();
|
|
155
222
|
if ([...subagentRuns.values()].some((entry) => entry.archiveAtMs)) {
|
|
@@ -202,7 +269,11 @@ async function sweepSubagentRuns() {
|
|
|
202
269
|
try {
|
|
203
270
|
await callGateway({
|
|
204
271
|
method: "sessions.delete",
|
|
205
|
-
params: {
|
|
272
|
+
params: {
|
|
273
|
+
key: entry.childSessionKey,
|
|
274
|
+
deleteTranscript: true,
|
|
275
|
+
emitLifecycleHooks: false,
|
|
276
|
+
},
|
|
206
277
|
timeoutMs: 10_000,
|
|
207
278
|
});
|
|
208
279
|
}
|
|
@@ -223,87 +294,131 @@ function ensureListener() {
|
|
|
223
294
|
}
|
|
224
295
|
listenerStarted = true;
|
|
225
296
|
listenerStop = onAgentEvent((evt) => {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const entry = subagentRuns.get(evt.runId);
|
|
230
|
-
if (!entry) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
const phase = evt.data?.phase;
|
|
234
|
-
if (phase === "start") {
|
|
235
|
-
const startedAt = typeof evt.data?.startedAt === "number" ? evt.data.startedAt : undefined;
|
|
236
|
-
if (startedAt) {
|
|
237
|
-
entry.startedAt = startedAt;
|
|
238
|
-
persistSubagentRuns();
|
|
297
|
+
void (async () => {
|
|
298
|
+
if (!evt || evt.stream !== "lifecycle") {
|
|
299
|
+
return;
|
|
239
300
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
301
|
+
const entry = subagentRuns.get(evt.runId);
|
|
302
|
+
if (!entry) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const phase = evt.data?.phase;
|
|
306
|
+
if (phase === "start") {
|
|
307
|
+
const startedAt = typeof evt.data?.startedAt === "number" ? evt.data.startedAt : undefined;
|
|
308
|
+
if (startedAt) {
|
|
309
|
+
entry.startedAt = startedAt;
|
|
310
|
+
persistSubagentRuns();
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (phase !== "end" && phase !== "error") {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const endedAt = typeof evt.data?.endedAt === "number" ? evt.data.endedAt : Date.now();
|
|
248
318
|
const error = typeof evt.data?.error === "string" ? evt.data.error : undefined;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
319
|
+
const outcome = phase === "error"
|
|
320
|
+
? { status: "error", error }
|
|
321
|
+
: evt.data?.aborted
|
|
322
|
+
? { status: "timeout" }
|
|
323
|
+
: { status: "ok" };
|
|
324
|
+
await completeSubagentRun({
|
|
325
|
+
runId: evt.runId,
|
|
326
|
+
endedAt,
|
|
327
|
+
outcome,
|
|
328
|
+
reason: phase === "error" ? SUBAGENT_ENDED_REASON_ERROR : SUBAGENT_ENDED_REASON_COMPLETE,
|
|
329
|
+
sendFarewell: true,
|
|
330
|
+
accountId: entry.requesterOrigin?.accountId,
|
|
331
|
+
triggerCleanup: true,
|
|
332
|
+
});
|
|
333
|
+
})();
|
|
264
334
|
});
|
|
265
335
|
}
|
|
266
|
-
function finalizeSubagentCleanup(runId, cleanup, didAnnounce) {
|
|
336
|
+
async function finalizeSubagentCleanup(runId, cleanup, didAnnounce) {
|
|
267
337
|
const entry = subagentRuns.get(runId);
|
|
268
338
|
if (!entry) {
|
|
269
339
|
return;
|
|
270
340
|
}
|
|
271
|
-
if (
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
341
|
+
if (didAnnounce) {
|
|
342
|
+
const completionReason = resolveCleanupCompletionReason(entry);
|
|
343
|
+
await emitCompletionEndedHookIfNeeded(entry, completionReason);
|
|
344
|
+
completeCleanupBookkeeping({
|
|
345
|
+
runId,
|
|
346
|
+
entry,
|
|
347
|
+
cleanup,
|
|
348
|
+
completedAt: Date.now(),
|
|
349
|
+
});
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const now = Date.now();
|
|
353
|
+
const deferredDecision = resolveDeferredCleanupDecision({
|
|
354
|
+
entry,
|
|
355
|
+
now,
|
|
356
|
+
activeDescendantRuns: Math.max(0, countActiveDescendantRuns(entry.childSessionKey)),
|
|
357
|
+
announceExpiryMs: ANNOUNCE_EXPIRY_MS,
|
|
358
|
+
maxAnnounceRetryCount: MAX_ANNOUNCE_RETRY_COUNT,
|
|
359
|
+
deferDescendantDelayMs: MIN_ANNOUNCE_RETRY_DELAY_MS,
|
|
360
|
+
resolveAnnounceRetryDelayMs,
|
|
361
|
+
});
|
|
362
|
+
if (deferredDecision.kind === "defer-descendants") {
|
|
275
363
|
entry.lastAnnounceRetryAt = now;
|
|
276
|
-
// Check if the announce has exceeded retry limits or expired (#18264).
|
|
277
|
-
const endedAgo = typeof entry.endedAt === "number" ? now - entry.endedAt : 0;
|
|
278
|
-
if (retryCount >= MAX_ANNOUNCE_RETRY_COUNT || endedAgo > ANNOUNCE_EXPIRY_MS) {
|
|
279
|
-
// Give up: mark as completed to break the infinite retry loop.
|
|
280
|
-
logAnnounceGiveUp(entry, retryCount >= MAX_ANNOUNCE_RETRY_COUNT ? "retry-limit" : "expiry");
|
|
281
|
-
entry.cleanupCompletedAt = now;
|
|
282
|
-
persistSubagentRuns();
|
|
283
|
-
retryDeferredCompletedAnnounces(runId);
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
// Allow retry on the next wake if announce was deferred or failed.
|
|
287
364
|
entry.cleanupHandled = false;
|
|
288
365
|
resumedRuns.delete(runId);
|
|
289
366
|
persistSubagentRuns();
|
|
290
|
-
if (entry.expectsCompletionMessage !== true) {
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
367
|
setTimeout(() => {
|
|
294
368
|
resumeSubagentRun(runId);
|
|
295
|
-
},
|
|
369
|
+
}, deferredDecision.delayMs).unref?.();
|
|
296
370
|
return;
|
|
297
371
|
}
|
|
298
|
-
if (
|
|
299
|
-
|
|
372
|
+
if (deferredDecision.retryCount != null) {
|
|
373
|
+
entry.announceRetryCount = deferredDecision.retryCount;
|
|
374
|
+
entry.lastAnnounceRetryAt = now;
|
|
375
|
+
}
|
|
376
|
+
if (deferredDecision.kind === "give-up") {
|
|
377
|
+
const completionReason = resolveCleanupCompletionReason(entry);
|
|
378
|
+
await emitCompletionEndedHookIfNeeded(entry, completionReason);
|
|
379
|
+
logAnnounceGiveUp(entry, deferredDecision.reason);
|
|
380
|
+
completeCleanupBookkeeping({
|
|
381
|
+
runId,
|
|
382
|
+
entry,
|
|
383
|
+
cleanup: "keep",
|
|
384
|
+
completedAt: now,
|
|
385
|
+
});
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
// Allow retry on the next wake if announce was deferred or failed.
|
|
389
|
+
entry.cleanupHandled = false;
|
|
390
|
+
resumedRuns.delete(runId);
|
|
391
|
+
persistSubagentRuns();
|
|
392
|
+
if (deferredDecision.resumeDelayMs == null) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
setTimeout(() => {
|
|
396
|
+
resumeSubagentRun(runId);
|
|
397
|
+
}, deferredDecision.resumeDelayMs).unref?.();
|
|
398
|
+
}
|
|
399
|
+
async function emitCompletionEndedHookIfNeeded(entry, reason) {
|
|
400
|
+
if (entry.expectsCompletionMessage === true &&
|
|
401
|
+
shouldEmitEndedHookForRun({
|
|
402
|
+
entry,
|
|
403
|
+
reason,
|
|
404
|
+
})) {
|
|
405
|
+
await emitSubagentEndedHookForRun({
|
|
406
|
+
entry,
|
|
407
|
+
reason,
|
|
408
|
+
sendFarewell: true,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function completeCleanupBookkeeping(params) {
|
|
413
|
+
if (params.cleanup === "delete") {
|
|
414
|
+
subagentRuns.delete(params.runId);
|
|
300
415
|
persistSubagentRuns();
|
|
301
|
-
retryDeferredCompletedAnnounces(runId);
|
|
416
|
+
retryDeferredCompletedAnnounces(params.runId);
|
|
302
417
|
return;
|
|
303
418
|
}
|
|
304
|
-
entry.cleanupCompletedAt =
|
|
419
|
+
params.entry.cleanupCompletedAt = params.completedAt;
|
|
305
420
|
persistSubagentRuns();
|
|
306
|
-
retryDeferredCompletedAnnounces(runId);
|
|
421
|
+
retryDeferredCompletedAnnounces(params.runId);
|
|
307
422
|
}
|
|
308
423
|
function retryDeferredCompletedAnnounces(excludeRunId) {
|
|
309
424
|
const now = Date.now();
|
|
@@ -403,7 +518,8 @@ export function replaceSubagentRunAfterSteer(params) {
|
|
|
403
518
|
const now = Date.now();
|
|
404
519
|
const cfg = loadConfig();
|
|
405
520
|
const archiveAfterMs = resolveArchiveAfterMs(cfg);
|
|
406
|
-
const
|
|
521
|
+
const spawnMode = source.spawnMode === "session" ? "session" : "run";
|
|
522
|
+
const archiveAtMs = spawnMode === "session" ? undefined : archiveAfterMs ? now + archiveAfterMs : undefined;
|
|
407
523
|
const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0;
|
|
408
524
|
const waitTimeoutMs = resolveSubagentWaitTimeoutMs(cfg, runTimeoutSeconds);
|
|
409
525
|
const next = {
|
|
@@ -411,12 +527,15 @@ export function replaceSubagentRunAfterSteer(params) {
|
|
|
411
527
|
runId: nextRunId,
|
|
412
528
|
startedAt: now,
|
|
413
529
|
endedAt: undefined,
|
|
530
|
+
endedReason: undefined,
|
|
531
|
+
endedHookEmittedAt: undefined,
|
|
414
532
|
outcome: undefined,
|
|
415
533
|
cleanupCompletedAt: undefined,
|
|
416
534
|
cleanupHandled: false,
|
|
417
535
|
suppressAnnounceReason: undefined,
|
|
418
536
|
announceRetryCount: undefined,
|
|
419
537
|
lastAnnounceRetryAt: undefined,
|
|
538
|
+
spawnMode,
|
|
420
539
|
archiveAtMs,
|
|
421
540
|
runTimeoutSeconds,
|
|
422
541
|
};
|
|
@@ -433,7 +552,8 @@ export function registerSubagentRun(params) {
|
|
|
433
552
|
const now = Date.now();
|
|
434
553
|
const cfg = loadConfig();
|
|
435
554
|
const archiveAfterMs = resolveArchiveAfterMs(cfg);
|
|
436
|
-
const
|
|
555
|
+
const spawnMode = params.spawnMode === "session" ? "session" : "run";
|
|
556
|
+
const archiveAtMs = spawnMode === "session" ? undefined : archiveAfterMs ? now + archiveAfterMs : undefined;
|
|
437
557
|
const runTimeoutSeconds = params.runTimeoutSeconds ?? 0;
|
|
438
558
|
const waitTimeoutMs = resolveSubagentWaitTimeoutMs(cfg, runTimeoutSeconds);
|
|
439
559
|
const requesterOrigin = normalizeDeliveryContext(params.requesterOrigin);
|
|
@@ -446,6 +566,7 @@ export function registerSubagentRun(params) {
|
|
|
446
566
|
task: params.task,
|
|
447
567
|
cleanup: params.cleanup,
|
|
448
568
|
expectsCompletionMessage: params.expectsCompletionMessage,
|
|
569
|
+
spawnMode,
|
|
449
570
|
label: params.label,
|
|
450
571
|
model: params.model,
|
|
451
572
|
runTimeoutSeconds,
|
|
@@ -456,7 +577,7 @@ export function registerSubagentRun(params) {
|
|
|
456
577
|
});
|
|
457
578
|
ensureListener();
|
|
458
579
|
persistSubagentRuns();
|
|
459
|
-
if (
|
|
580
|
+
if (archiveAtMs) {
|
|
460
581
|
startSweeper();
|
|
461
582
|
}
|
|
462
583
|
// Wait for subagent completion via gateway RPC (cross-process).
|
|
@@ -495,22 +616,27 @@ async function waitForSubagentCompletion(runId, waitTimeoutMs) {
|
|
|
495
616
|
mutated = true;
|
|
496
617
|
}
|
|
497
618
|
const waitError = typeof wait.error === "string" ? wait.error : undefined;
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
619
|
+
const outcome = wait.status === "error"
|
|
620
|
+
? { status: "error", error: waitError }
|
|
621
|
+
: wait.status === "timeout"
|
|
622
|
+
? { status: "timeout" }
|
|
623
|
+
: { status: "ok" };
|
|
624
|
+
if (!runOutcomesEqual(entry.outcome, outcome)) {
|
|
625
|
+
entry.outcome = outcome;
|
|
626
|
+
mutated = true;
|
|
627
|
+
}
|
|
505
628
|
if (mutated) {
|
|
506
629
|
persistSubagentRuns();
|
|
507
630
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
631
|
+
await completeSubagentRun({
|
|
632
|
+
runId,
|
|
633
|
+
endedAt: entry.endedAt,
|
|
634
|
+
outcome,
|
|
635
|
+
reason: wait.status === "error" ? SUBAGENT_ENDED_REASON_ERROR : SUBAGENT_ENDED_REASON_COMPLETE,
|
|
636
|
+
sendFarewell: true,
|
|
637
|
+
accountId: entry.requesterOrigin?.accountId,
|
|
638
|
+
triggerCleanup: true,
|
|
639
|
+
});
|
|
514
640
|
}
|
|
515
641
|
catch {
|
|
516
642
|
// ignore
|
|
@@ -519,6 +645,7 @@ async function waitForSubagentCompletion(runId, waitTimeoutMs) {
|
|
|
519
645
|
export function resetSubagentRegistryForTests(opts) {
|
|
520
646
|
subagentRuns.clear();
|
|
521
647
|
resumedRuns.clear();
|
|
648
|
+
endedHookInFlightRunIds.clear();
|
|
522
649
|
resetAnnounceQueuesForTests();
|
|
523
650
|
stopSweeper();
|
|
524
651
|
restoreAttempted = false;
|
|
@@ -544,58 +671,16 @@ export function releaseSubagentRun(runId) {
|
|
|
544
671
|
}
|
|
545
672
|
}
|
|
546
673
|
function findRunIdsByChildSessionKey(childSessionKey) {
|
|
547
|
-
|
|
548
|
-
if (!key) {
|
|
549
|
-
return [];
|
|
550
|
-
}
|
|
551
|
-
const runIds = [];
|
|
552
|
-
for (const [runId, entry] of subagentRuns.entries()) {
|
|
553
|
-
if (entry.childSessionKey === key) {
|
|
554
|
-
runIds.push(runId);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
return runIds;
|
|
558
|
-
}
|
|
559
|
-
function getRunsSnapshotForRead() {
|
|
560
|
-
const merged = new Map();
|
|
561
|
-
const shouldReadDisk = !(process.env.VITEST || process.env.NODE_ENV === "test");
|
|
562
|
-
if (shouldReadDisk) {
|
|
563
|
-
try {
|
|
564
|
-
// Registry state is persisted to disk so other worker processes (for
|
|
565
|
-
// example cron runners) can observe active children spawned elsewhere.
|
|
566
|
-
for (const [runId, entry] of loadSubagentRegistryFromDisk().entries()) {
|
|
567
|
-
merged.set(runId, entry);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
catch {
|
|
571
|
-
// Ignore disk read failures and fall back to local memory state.
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
for (const [runId, entry] of subagentRuns.entries()) {
|
|
575
|
-
merged.set(runId, entry);
|
|
576
|
-
}
|
|
577
|
-
return merged;
|
|
674
|
+
return findRunIdsByChildSessionKeyFromRuns(subagentRuns, childSessionKey);
|
|
578
675
|
}
|
|
579
676
|
export function resolveRequesterForChildSession(childSessionKey) {
|
|
580
|
-
const
|
|
581
|
-
if (!
|
|
582
|
-
return null;
|
|
583
|
-
}
|
|
584
|
-
let best;
|
|
585
|
-
for (const entry of getRunsSnapshotForRead().values()) {
|
|
586
|
-
if (entry.childSessionKey !== key) {
|
|
587
|
-
continue;
|
|
588
|
-
}
|
|
589
|
-
if (!best || entry.createdAt > best.createdAt) {
|
|
590
|
-
best = entry;
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
if (!best) {
|
|
677
|
+
const resolved = resolveRequesterForChildSessionFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), childSessionKey);
|
|
678
|
+
if (!resolved) {
|
|
594
679
|
return null;
|
|
595
680
|
}
|
|
596
681
|
return {
|
|
597
|
-
requesterSessionKey:
|
|
598
|
-
requesterOrigin: normalizeDeliveryContext(
|
|
682
|
+
requesterSessionKey: resolved.requesterSessionKey,
|
|
683
|
+
requesterOrigin: normalizeDeliveryContext(resolved.requesterOrigin),
|
|
599
684
|
};
|
|
600
685
|
}
|
|
601
686
|
export function isSubagentSessionRunActive(childSessionKey) {
|
|
@@ -627,6 +712,7 @@ export function markSubagentRunTerminated(params) {
|
|
|
627
712
|
const now = Date.now();
|
|
628
713
|
const reason = params.reason?.trim() || "killed";
|
|
629
714
|
let updated = 0;
|
|
715
|
+
const entriesByChildSessionKey = new Map();
|
|
630
716
|
for (const runId of runIds) {
|
|
631
717
|
const entry = subagentRuns.get(runId);
|
|
632
718
|
if (!entry) {
|
|
@@ -637,99 +723,44 @@ export function markSubagentRunTerminated(params) {
|
|
|
637
723
|
}
|
|
638
724
|
entry.endedAt = now;
|
|
639
725
|
entry.outcome = { status: "error", error: reason };
|
|
726
|
+
entry.endedReason = SUBAGENT_ENDED_REASON_KILLED;
|
|
640
727
|
entry.cleanupHandled = true;
|
|
641
728
|
entry.cleanupCompletedAt = now;
|
|
642
729
|
entry.suppressAnnounceReason = "killed";
|
|
730
|
+
if (!entriesByChildSessionKey.has(entry.childSessionKey)) {
|
|
731
|
+
entriesByChildSessionKey.set(entry.childSessionKey, entry);
|
|
732
|
+
}
|
|
643
733
|
updated += 1;
|
|
644
734
|
}
|
|
645
735
|
if (updated > 0) {
|
|
646
736
|
persistSubagentRuns();
|
|
737
|
+
for (const entry of entriesByChildSessionKey.values()) {
|
|
738
|
+
void emitSubagentEndedHookOnce({
|
|
739
|
+
entry,
|
|
740
|
+
reason: SUBAGENT_ENDED_REASON_KILLED,
|
|
741
|
+
sendFarewell: true,
|
|
742
|
+
outcome: SUBAGENT_ENDED_OUTCOME_KILLED,
|
|
743
|
+
error: reason,
|
|
744
|
+
inFlightRunIds: endedHookInFlightRunIds,
|
|
745
|
+
persist: persistSubagentRuns,
|
|
746
|
+
}).catch(() => {
|
|
747
|
+
// Hook failures should not break termination flow.
|
|
748
|
+
});
|
|
749
|
+
}
|
|
647
750
|
}
|
|
648
751
|
return updated;
|
|
649
752
|
}
|
|
650
753
|
export function listSubagentRunsForRequester(requesterSessionKey) {
|
|
651
|
-
|
|
652
|
-
if (!key) {
|
|
653
|
-
return [];
|
|
654
|
-
}
|
|
655
|
-
return [...subagentRuns.values()].filter((entry) => entry.requesterSessionKey === key);
|
|
754
|
+
return listRunsForRequesterFromRuns(subagentRuns, requesterSessionKey);
|
|
656
755
|
}
|
|
657
756
|
export function countActiveRunsForSession(requesterSessionKey) {
|
|
658
|
-
|
|
659
|
-
if (!key) {
|
|
660
|
-
return 0;
|
|
661
|
-
}
|
|
662
|
-
let count = 0;
|
|
663
|
-
for (const entry of getRunsSnapshotForRead().values()) {
|
|
664
|
-
if (entry.requesterSessionKey !== key) {
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
if (typeof entry.endedAt === "number") {
|
|
668
|
-
continue;
|
|
669
|
-
}
|
|
670
|
-
count += 1;
|
|
671
|
-
}
|
|
672
|
-
return count;
|
|
757
|
+
return countActiveRunsForSessionFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), requesterSessionKey);
|
|
673
758
|
}
|
|
674
759
|
export function countActiveDescendantRuns(rootSessionKey) {
|
|
675
|
-
|
|
676
|
-
if (!root) {
|
|
677
|
-
return 0;
|
|
678
|
-
}
|
|
679
|
-
const runs = getRunsSnapshotForRead();
|
|
680
|
-
const pending = [root];
|
|
681
|
-
const visited = new Set([root]);
|
|
682
|
-
let count = 0;
|
|
683
|
-
while (pending.length > 0) {
|
|
684
|
-
const requester = pending.shift();
|
|
685
|
-
if (!requester) {
|
|
686
|
-
continue;
|
|
687
|
-
}
|
|
688
|
-
for (const entry of runs.values()) {
|
|
689
|
-
if (entry.requesterSessionKey !== requester) {
|
|
690
|
-
continue;
|
|
691
|
-
}
|
|
692
|
-
if (typeof entry.endedAt !== "number") {
|
|
693
|
-
count += 1;
|
|
694
|
-
}
|
|
695
|
-
const childKey = entry.childSessionKey.trim();
|
|
696
|
-
if (!childKey || visited.has(childKey)) {
|
|
697
|
-
continue;
|
|
698
|
-
}
|
|
699
|
-
visited.add(childKey);
|
|
700
|
-
pending.push(childKey);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
return count;
|
|
760
|
+
return countActiveDescendantRunsFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), rootSessionKey);
|
|
704
761
|
}
|
|
705
762
|
export function listDescendantRunsForRequester(rootSessionKey) {
|
|
706
|
-
|
|
707
|
-
if (!root) {
|
|
708
|
-
return [];
|
|
709
|
-
}
|
|
710
|
-
const runs = getRunsSnapshotForRead();
|
|
711
|
-
const pending = [root];
|
|
712
|
-
const visited = new Set([root]);
|
|
713
|
-
const descendants = [];
|
|
714
|
-
while (pending.length > 0) {
|
|
715
|
-
const requester = pending.shift();
|
|
716
|
-
if (!requester) {
|
|
717
|
-
continue;
|
|
718
|
-
}
|
|
719
|
-
for (const entry of runs.values()) {
|
|
720
|
-
if (entry.requesterSessionKey !== requester) {
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
descendants.push(entry);
|
|
724
|
-
const childKey = entry.childSessionKey.trim();
|
|
725
|
-
if (!childKey || visited.has(childKey)) {
|
|
726
|
-
continue;
|
|
727
|
-
}
|
|
728
|
-
visited.add(childKey);
|
|
729
|
-
pending.push(childKey);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
return descendants;
|
|
763
|
+
return listDescendantRunsForRequesterFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), rootSessionKey);
|
|
733
764
|
}
|
|
734
765
|
export function initSubagentRegistry() {
|
|
735
766
|
restoreSubagentRunsOnce();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|