@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
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { resolveQueueSettings } from "../auto-reply/reply/queue.js";
|
|
2
2
|
import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
|
3
|
+
import { DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "../config/agent-limits.js";
|
|
3
4
|
import { loadConfig } from "../config/config.js";
|
|
4
5
|
import { loadSessionStore, resolveAgentIdFromSessionKey, resolveMainSessionKey, resolveStorePath, } from "../config/sessions.js";
|
|
5
6
|
import { callGateway } from "../gateway/call.js";
|
|
6
|
-
import {
|
|
7
|
+
import { createBoundDeliveryRouter } from "../infra/outbound/bound-delivery-router.js";
|
|
8
|
+
import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
|
|
9
|
+
import { normalizeAccountId, normalizeMainKey } from "../routing/session-key.js";
|
|
7
10
|
import { defaultRuntime } from "../runtime.js";
|
|
8
11
|
import { extractTextFromChatContent } from "../shared/chat-content.js";
|
|
9
12
|
import { deliveryContextFromSession, mergeDeliveryContext, normalizeDeliveryContext, } from "../utils/delivery-context.js";
|
|
@@ -12,11 +15,26 @@ import { buildAnnounceIdFromChildRun, buildAnnounceIdempotencyKey, resolveQueueA
|
|
|
12
15
|
import { isEmbeddedPiRunActive, queueEmbeddedPiMessage, waitForEmbeddedPiRunEnd, } from "./pi-embedded.js";
|
|
13
16
|
import { enqueueAnnounce } from "./subagent-announce-queue.js";
|
|
14
17
|
import { getSubagentDepthFromSessionStore } from "./subagent-depth.js";
|
|
18
|
+
import { readLatestAssistantReply } from "./tools/agent-step.js";
|
|
15
19
|
import { sanitizeTextContent, extractAssistantText } from "./tools/sessions-helpers.js";
|
|
16
20
|
function buildCompletionDeliveryMessage(params) {
|
|
17
21
|
const findingsText = params.findings.trim();
|
|
18
22
|
const hasFindings = findingsText.length > 0 && findingsText !== "(no output)";
|
|
19
|
-
const header =
|
|
23
|
+
const header = (() => {
|
|
24
|
+
if (params.outcome?.status === "error") {
|
|
25
|
+
return params.spawnMode === "session"
|
|
26
|
+
? `❌ Subagent ${params.subagentName} failed this task (session remains active)`
|
|
27
|
+
: `❌ Subagent ${params.subagentName} failed`;
|
|
28
|
+
}
|
|
29
|
+
if (params.outcome?.status === "timeout") {
|
|
30
|
+
return params.spawnMode === "session"
|
|
31
|
+
? `⏱️ Subagent ${params.subagentName} timed out on this task (session remains active)`
|
|
32
|
+
: `⏱️ Subagent ${params.subagentName} timed out`;
|
|
33
|
+
}
|
|
34
|
+
return params.spawnMode === "session"
|
|
35
|
+
? `✅ Subagent ${params.subagentName} completed this task (session remains active)`
|
|
36
|
+
: `✅ Subagent ${params.subagentName} finished`;
|
|
37
|
+
})();
|
|
20
38
|
if (!hasFindings) {
|
|
21
39
|
return header;
|
|
22
40
|
}
|
|
@@ -74,6 +92,16 @@ function extractToolResultText(content) {
|
|
|
74
92
|
});
|
|
75
93
|
return joined?.trim() ?? "";
|
|
76
94
|
}
|
|
95
|
+
function extractInlineTextContent(content) {
|
|
96
|
+
if (!Array.isArray(content)) {
|
|
97
|
+
return "";
|
|
98
|
+
}
|
|
99
|
+
return (extractTextFromChatContent(content, {
|
|
100
|
+
sanitizeText: sanitizeTextContent,
|
|
101
|
+
normalizeText: (text) => text.trim(),
|
|
102
|
+
joinWith: "",
|
|
103
|
+
}) ?? "");
|
|
104
|
+
}
|
|
77
105
|
function extractSubagentOutputText(message) {
|
|
78
106
|
if (!message || typeof message !== "object") {
|
|
79
107
|
return "";
|
|
@@ -89,30 +117,36 @@ function extractSubagentOutputText(message) {
|
|
|
89
117
|
return sanitizeTextContent(content);
|
|
90
118
|
}
|
|
91
119
|
if (Array.isArray(content)) {
|
|
92
|
-
return (
|
|
93
|
-
sanitizeText: sanitizeTextContent,
|
|
94
|
-
normalizeText: (text) => text.trim(),
|
|
95
|
-
joinWith: "",
|
|
96
|
-
}) ?? "");
|
|
120
|
+
return extractInlineTextContent(content);
|
|
97
121
|
}
|
|
98
122
|
return "";
|
|
99
123
|
}
|
|
100
124
|
if (role === "toolResult" || role === "tool") {
|
|
101
125
|
return extractToolResultText(message.content);
|
|
102
126
|
}
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
joinWith: "",
|
|
111
|
-
}) ?? "");
|
|
127
|
+
if (role == null) {
|
|
128
|
+
if (typeof content === "string") {
|
|
129
|
+
return sanitizeTextContent(content);
|
|
130
|
+
}
|
|
131
|
+
if (Array.isArray(content)) {
|
|
132
|
+
return extractInlineTextContent(content);
|
|
133
|
+
}
|
|
112
134
|
}
|
|
113
135
|
return "";
|
|
114
136
|
}
|
|
115
137
|
async function readLatestSubagentOutput(sessionKey) {
|
|
138
|
+
try {
|
|
139
|
+
const latestAssistant = await readLatestAssistantReply({
|
|
140
|
+
sessionKey,
|
|
141
|
+
limit: 50,
|
|
142
|
+
});
|
|
143
|
+
if (latestAssistant?.trim()) {
|
|
144
|
+
return latestAssistant;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Best-effort: fall back to richer history parsing below.
|
|
149
|
+
}
|
|
116
150
|
const history = await callGateway({
|
|
117
151
|
method: "chat.history",
|
|
118
152
|
params: { sessionKey, limit: 50 },
|
|
@@ -140,6 +174,26 @@ async function readLatestSubagentOutputWithRetry(params) {
|
|
|
140
174
|
}
|
|
141
175
|
return result;
|
|
142
176
|
}
|
|
177
|
+
async function waitForSubagentOutputChange(params) {
|
|
178
|
+
const baseline = params.baselineReply.trim();
|
|
179
|
+
if (!baseline) {
|
|
180
|
+
return params.baselineReply;
|
|
181
|
+
}
|
|
182
|
+
const RETRY_INTERVAL_MS = 100;
|
|
183
|
+
const deadline = Date.now() + Math.max(0, Math.min(params.maxWaitMs, 5_000));
|
|
184
|
+
let latest = params.baselineReply;
|
|
185
|
+
while (Date.now() < deadline) {
|
|
186
|
+
const next = await readLatestSubagentOutput(params.sessionKey);
|
|
187
|
+
if (next?.trim()) {
|
|
188
|
+
latest = next;
|
|
189
|
+
if (next.trim() !== baseline) {
|
|
190
|
+
return next;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL_MS));
|
|
194
|
+
}
|
|
195
|
+
return latest;
|
|
196
|
+
}
|
|
143
197
|
function formatDurationShort(valueMs) {
|
|
144
198
|
if (!valueMs || !Number.isFinite(valueMs) || valueMs <= 0) {
|
|
145
199
|
return "n/a";
|
|
@@ -197,7 +251,7 @@ async function buildCompactAnnounceStatsLine(params) {
|
|
|
197
251
|
if (typeof promptCache === "number" && promptCache > ioTotal) {
|
|
198
252
|
parts.push(`prompt/cache ${formatTokenCount(promptCache)}`);
|
|
199
253
|
}
|
|
200
|
-
return `Stats: ${parts.join("
|
|
254
|
+
return `Stats: ${parts.join(" \u00b7 ")}`;
|
|
201
255
|
}
|
|
202
256
|
function resolveAnnounceOrigin(entry, requesterOrigin) {
|
|
203
257
|
const normalizedRequester = normalizeDeliveryContext(requesterOrigin);
|
|
@@ -213,7 +267,100 @@ function resolveAnnounceOrigin(entry, requesterOrigin) {
|
|
|
213
267
|
// requesterOrigin (captured at spawn time) reflects the channel the user is
|
|
214
268
|
// actually on and must take priority over the session entry, which may carry
|
|
215
269
|
// stale lastChannel / lastTo values from a previous channel interaction.
|
|
216
|
-
|
|
270
|
+
const entryForMerge = normalizedRequester?.to &&
|
|
271
|
+
normalizedRequester.threadId == null &&
|
|
272
|
+
normalizedEntry?.threadId != null
|
|
273
|
+
? (() => {
|
|
274
|
+
const { threadId: _ignore, ...rest } = normalizedEntry;
|
|
275
|
+
return rest;
|
|
276
|
+
})()
|
|
277
|
+
: normalizedEntry;
|
|
278
|
+
return mergeDeliveryContext(normalizedRequester, entryForMerge);
|
|
279
|
+
}
|
|
280
|
+
async function resolveSubagentCompletionOrigin(params) {
|
|
281
|
+
const requesterOrigin = normalizeDeliveryContext(params.requesterOrigin);
|
|
282
|
+
const requesterConversation = (() => {
|
|
283
|
+
const channel = requesterOrigin?.channel?.trim().toLowerCase();
|
|
284
|
+
const to = requesterOrigin?.to?.trim();
|
|
285
|
+
const accountId = normalizeAccountId(requesterOrigin?.accountId);
|
|
286
|
+
const threadId = requesterOrigin?.threadId != null && requesterOrigin.threadId !== ""
|
|
287
|
+
? String(requesterOrigin.threadId).trim()
|
|
288
|
+
: undefined;
|
|
289
|
+
const conversationId = threadId || (to?.startsWith("channel:") ? to.slice("channel:".length) : "");
|
|
290
|
+
if (!channel || !conversationId) {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
const ref = {
|
|
294
|
+
channel,
|
|
295
|
+
accountId,
|
|
296
|
+
conversationId,
|
|
297
|
+
};
|
|
298
|
+
return ref;
|
|
299
|
+
})();
|
|
300
|
+
const route = createBoundDeliveryRouter().resolveDestination({
|
|
301
|
+
eventKind: "task_completion",
|
|
302
|
+
targetSessionKey: params.childSessionKey,
|
|
303
|
+
requester: requesterConversation,
|
|
304
|
+
failClosed: false,
|
|
305
|
+
});
|
|
306
|
+
if (route.mode === "bound" && route.binding) {
|
|
307
|
+
const boundOrigin = {
|
|
308
|
+
channel: route.binding.conversation.channel,
|
|
309
|
+
accountId: route.binding.conversation.accountId,
|
|
310
|
+
to: `channel:${route.binding.conversation.conversationId}`,
|
|
311
|
+
threadId: route.binding.conversation.conversationId,
|
|
312
|
+
};
|
|
313
|
+
return {
|
|
314
|
+
// Bound target is authoritative; requester hints fill only missing fields.
|
|
315
|
+
origin: mergeDeliveryContext(boundOrigin, requesterOrigin),
|
|
316
|
+
routeMode: "bound",
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
const hookRunner = getGlobalHookRunner();
|
|
320
|
+
if (!hookRunner?.hasHooks("subagent_delivery_target")) {
|
|
321
|
+
return {
|
|
322
|
+
origin: requesterOrigin,
|
|
323
|
+
routeMode: "fallback",
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
try {
|
|
327
|
+
const result = await hookRunner.runSubagentDeliveryTarget({
|
|
328
|
+
childSessionKey: params.childSessionKey,
|
|
329
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
330
|
+
requesterOrigin,
|
|
331
|
+
childRunId: params.childRunId,
|
|
332
|
+
spawnMode: params.spawnMode,
|
|
333
|
+
expectsCompletionMessage: params.expectsCompletionMessage,
|
|
334
|
+
}, {
|
|
335
|
+
runId: params.childRunId,
|
|
336
|
+
childSessionKey: params.childSessionKey,
|
|
337
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
338
|
+
});
|
|
339
|
+
const hookOrigin = normalizeDeliveryContext(result?.origin);
|
|
340
|
+
if (!hookOrigin) {
|
|
341
|
+
return {
|
|
342
|
+
origin: requesterOrigin,
|
|
343
|
+
routeMode: "fallback",
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
if (hookOrigin.channel && !isDeliverableMessageChannel(hookOrigin.channel)) {
|
|
347
|
+
return {
|
|
348
|
+
origin: requesterOrigin,
|
|
349
|
+
routeMode: "fallback",
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
// Hook-provided origin should override requester defaults when present.
|
|
353
|
+
return {
|
|
354
|
+
origin: mergeDeliveryContext(hookOrigin, requesterOrigin),
|
|
355
|
+
routeMode: "hook",
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return {
|
|
360
|
+
origin: requesterOrigin,
|
|
361
|
+
routeMode: "fallback",
|
|
362
|
+
};
|
|
363
|
+
}
|
|
217
364
|
}
|
|
218
365
|
async function sendAnnounce(item) {
|
|
219
366
|
const requesterDepth = getSubagentDepthFromSessionStore(item.sessionKey);
|
|
@@ -346,26 +493,46 @@ async function sendSubagentAnnounceDirectly(params) {
|
|
|
346
493
|
if (params.expectsCompletionMessage &&
|
|
347
494
|
hasCompletionDirectTarget &&
|
|
348
495
|
params.completionMessage?.trim()) {
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
496
|
+
const forceBoundSessionDirectDelivery = params.spawnMode === "session" &&
|
|
497
|
+
(params.completionRouteMode === "bound" || params.completionRouteMode === "hook");
|
|
498
|
+
let shouldSendCompletionDirectly = true;
|
|
499
|
+
if (!forceBoundSessionDirectDelivery) {
|
|
500
|
+
let activeDescendantRuns = 0;
|
|
501
|
+
try {
|
|
502
|
+
const { countActiveDescendantRuns } = await import("./subagent-registry.js");
|
|
503
|
+
activeDescendantRuns = Math.max(0, countActiveDescendantRuns(canonicalRequesterSessionKey));
|
|
504
|
+
}
|
|
505
|
+
catch {
|
|
506
|
+
// Best-effort only; when unavailable keep historical direct-send behavior.
|
|
507
|
+
}
|
|
508
|
+
// Keep non-bound completion announcements coordinated via requester
|
|
509
|
+
// session routing while sibling/descendant runs are still active.
|
|
510
|
+
if (activeDescendantRuns > 0) {
|
|
511
|
+
shouldSendCompletionDirectly = false;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (shouldSendCompletionDirectly) {
|
|
515
|
+
const completionThreadId = completionDirectOrigin?.threadId != null && completionDirectOrigin.threadId !== ""
|
|
516
|
+
? String(completionDirectOrigin.threadId)
|
|
517
|
+
: undefined;
|
|
518
|
+
await callGateway({
|
|
519
|
+
method: "send",
|
|
520
|
+
params: {
|
|
521
|
+
channel: completionChannel,
|
|
522
|
+
to: completionTo,
|
|
523
|
+
accountId: completionDirectOrigin?.accountId,
|
|
524
|
+
threadId: completionThreadId,
|
|
525
|
+
sessionKey: canonicalRequesterSessionKey,
|
|
526
|
+
message: params.completionMessage,
|
|
527
|
+
idempotencyKey: params.directIdempotencyKey,
|
|
528
|
+
},
|
|
529
|
+
timeoutMs: 15_000,
|
|
530
|
+
});
|
|
531
|
+
return {
|
|
532
|
+
delivered: true,
|
|
533
|
+
path: "direct",
|
|
534
|
+
};
|
|
535
|
+
}
|
|
369
536
|
}
|
|
370
537
|
const directOrigin = normalizeDeliveryContext(params.directOrigin);
|
|
371
538
|
const threadId = directOrigin?.threadId != null && directOrigin.threadId !== ""
|
|
@@ -423,6 +590,8 @@ async function deliverSubagentAnnouncement(params) {
|
|
|
423
590
|
completionMessage: params.completionMessage,
|
|
424
591
|
directIdempotencyKey: params.directIdempotencyKey,
|
|
425
592
|
completionDirectOrigin: params.completionDirectOrigin,
|
|
593
|
+
completionRouteMode: params.completionRouteMode,
|
|
594
|
+
spawnMode: params.spawnMode,
|
|
426
595
|
directOrigin: params.directOrigin,
|
|
427
596
|
requesterIsSubagent: params.requesterIsSubagent,
|
|
428
597
|
expectsCompletionMessage: params.expectsCompletionMessage,
|
|
@@ -456,7 +625,9 @@ export function buildSubagentSystemPrompt(params) {
|
|
|
456
625
|
? params.task.replace(/\s+/g, " ").trim()
|
|
457
626
|
: "{{TASK_DESCRIPTION}}";
|
|
458
627
|
const childDepth = typeof params.childDepth === "number" ? params.childDepth : 1;
|
|
459
|
-
const maxSpawnDepth = typeof params.maxSpawnDepth === "number"
|
|
628
|
+
const maxSpawnDepth = typeof params.maxSpawnDepth === "number"
|
|
629
|
+
? params.maxSpawnDepth
|
|
630
|
+
: DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH;
|
|
460
631
|
const canSpawn = childDepth < maxSpawnDepth;
|
|
461
632
|
const parentLabel = childDepth >= 2 ? "parent orchestrator" : "main agent";
|
|
462
633
|
const lines = [
|
|
@@ -510,9 +681,6 @@ export function buildSubagentSystemPrompt(params) {
|
|
|
510
681
|
return lines.join("\n");
|
|
511
682
|
}
|
|
512
683
|
function buildAnnounceReplyInstruction(params) {
|
|
513
|
-
if (params.expectsCompletionMessage) {
|
|
514
|
-
return `A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type).`;
|
|
515
|
-
}
|
|
516
684
|
if (params.remainingActiveSubagentRuns > 0) {
|
|
517
685
|
const activeRunsLabel = params.remainingActiveSubagentRuns === 1 ? "run" : "runs";
|
|
518
686
|
return `There are still ${params.remainingActiveSubagentRuns} active subagent ${activeRunsLabel} for this session. If they are part of the same workflow, wait for the remaining results before sending a user update. If they are unrelated, respond normally using only the result above.`;
|
|
@@ -520,6 +688,9 @@ function buildAnnounceReplyInstruction(params) {
|
|
|
520
688
|
if (params.requesterIsSubagent) {
|
|
521
689
|
return `Convert this completion into a concise internal orchestration update for your parent agent in your own words. Keep this internal context private (don't mention system/log/stats/session details or announce type). If this result is duplicate or no update is needed, reply ONLY: ${SILENT_REPLY_TOKEN}.`;
|
|
522
690
|
}
|
|
691
|
+
if (params.expectsCompletionMessage) {
|
|
692
|
+
return `A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type).`;
|
|
693
|
+
}
|
|
523
694
|
return `A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type), and do not copy the system message verbatim. Reply ONLY: ${SILENT_REPLY_TOKEN} if this exact result was already delivered to the user in this same turn.`;
|
|
524
695
|
}
|
|
525
696
|
export async function runSubagentAnnounceFlow(params) {
|
|
@@ -540,7 +711,7 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
540
711
|
let outcome = params.outcome;
|
|
541
712
|
// Lifecycle "end" can arrive before auto-compaction retries finish. If the
|
|
542
713
|
// subagent is still active, wait for the embedded run to fully settle.
|
|
543
|
-
if (
|
|
714
|
+
if (childSessionId && isEmbeddedPiRunActive(childSessionId)) {
|
|
544
715
|
const settled = await waitForEmbeddedPiRunEnd(childSessionId, settleTimeoutMs);
|
|
545
716
|
if (!settled && isEmbeddedPiRunActive(childSessionId)) {
|
|
546
717
|
// The child run is still active (e.g., compaction retry still in progress).
|
|
@@ -603,6 +774,7 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
603
774
|
if (!outcome) {
|
|
604
775
|
outcome = { status: "unknown" };
|
|
605
776
|
}
|
|
777
|
+
let requesterDepth = getSubagentDepthFromSessionStore(targetRequesterSessionKey);
|
|
606
778
|
let activeChildDescendantRuns = 0;
|
|
607
779
|
try {
|
|
608
780
|
const { countActiveDescendantRuns } = await import("./subagent-registry.js");
|
|
@@ -611,12 +783,19 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
611
783
|
catch {
|
|
612
784
|
// Best-effort only; fall back to direct announce behavior when unavailable.
|
|
613
785
|
}
|
|
614
|
-
if (
|
|
786
|
+
if (activeChildDescendantRuns > 0) {
|
|
615
787
|
// The finished run still has active descendant subagents. Defer announcing
|
|
616
788
|
// this run until descendants settle so we avoid posting in-progress updates.
|
|
617
789
|
shouldDeleteChildSession = false;
|
|
618
790
|
return false;
|
|
619
791
|
}
|
|
792
|
+
if (requesterDepth >= 1 && reply?.trim()) {
|
|
793
|
+
reply = await waitForSubagentOutputChange({
|
|
794
|
+
sessionKey: params.childSessionKey,
|
|
795
|
+
baselineReply: reply,
|
|
796
|
+
maxWaitMs: Math.max(250, Math.min(params.timeoutMs, 2_000)),
|
|
797
|
+
});
|
|
798
|
+
}
|
|
620
799
|
// Build status label
|
|
621
800
|
const statusLabel = outcome.status === "ok"
|
|
622
801
|
? "completed successfully"
|
|
@@ -633,8 +812,7 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
633
812
|
const findings = reply || "(no output)";
|
|
634
813
|
let completionMessage = "";
|
|
635
814
|
let triggerMessage = "";
|
|
636
|
-
let
|
|
637
|
-
let requesterIsSubagent = !expectsCompletionMessage && requesterDepth >= 1;
|
|
815
|
+
let requesterIsSubagent = requesterDepth >= 1;
|
|
638
816
|
// If the requester subagent has already finished, bubble the announce to its
|
|
639
817
|
// requester (typically main) so descendant completion is not silently lost.
|
|
640
818
|
// BUT: only fallback if the parent SESSION is deleted, not just if the current
|
|
@@ -691,6 +869,8 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
691
869
|
completionMessage = buildCompletionDeliveryMessage({
|
|
692
870
|
findings,
|
|
693
871
|
subagentName,
|
|
872
|
+
spawnMode: params.spawnMode,
|
|
873
|
+
outcome,
|
|
694
874
|
});
|
|
695
875
|
const internalSummaryMessage = [
|
|
696
876
|
`[System Message] [sessionId: ${announceSessionId}] A ${announceType} "${taskLabel}" just ${statusLabel}.`,
|
|
@@ -712,6 +892,20 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
712
892
|
const { entry } = loadRequesterSessionEntry(targetRequesterSessionKey);
|
|
713
893
|
directOrigin = resolveAnnounceOrigin(entry, targetRequesterOrigin);
|
|
714
894
|
}
|
|
895
|
+
const completionResolution = expectsCompletionMessage && !requesterIsSubagent
|
|
896
|
+
? await resolveSubagentCompletionOrigin({
|
|
897
|
+
childSessionKey: params.childSessionKey,
|
|
898
|
+
requesterSessionKey: targetRequesterSessionKey,
|
|
899
|
+
requesterOrigin: directOrigin,
|
|
900
|
+
childRunId: params.childRunId,
|
|
901
|
+
spawnMode: params.spawnMode,
|
|
902
|
+
expectsCompletionMessage,
|
|
903
|
+
})
|
|
904
|
+
: {
|
|
905
|
+
origin: targetRequesterOrigin,
|
|
906
|
+
routeMode: "fallback",
|
|
907
|
+
};
|
|
908
|
+
const completionDirectOrigin = completionResolution.origin;
|
|
715
909
|
// Use a deterministic idempotency key so the gateway dedup cache
|
|
716
910
|
// catches duplicates if this announce is also queued by the gateway-
|
|
717
911
|
// level message queue while the main session is busy (#17122).
|
|
@@ -722,12 +916,16 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
722
916
|
triggerMessage,
|
|
723
917
|
completionMessage,
|
|
724
918
|
summaryLine: taskLabel,
|
|
725
|
-
requesterOrigin:
|
|
726
|
-
|
|
919
|
+
requesterOrigin: expectsCompletionMessage && !requesterIsSubagent
|
|
920
|
+
? completionDirectOrigin
|
|
921
|
+
: targetRequesterOrigin,
|
|
922
|
+
completionDirectOrigin,
|
|
727
923
|
directOrigin,
|
|
728
924
|
targetRequesterSessionKey,
|
|
729
925
|
requesterIsSubagent,
|
|
730
926
|
expectsCompletionMessage: expectsCompletionMessage,
|
|
927
|
+
completionRouteMode: completionResolution.routeMode,
|
|
928
|
+
spawnMode: params.spawnMode,
|
|
731
929
|
directIdempotencyKey,
|
|
732
930
|
});
|
|
733
931
|
didAnnounce = delivery.delivered;
|
|
@@ -757,7 +955,11 @@ export async function runSubagentAnnounceFlow(params) {
|
|
|
757
955
|
try {
|
|
758
956
|
await callGateway({
|
|
759
957
|
method: "sessions.delete",
|
|
760
|
-
params: {
|
|
958
|
+
params: {
|
|
959
|
+
key: params.childSessionKey,
|
|
960
|
+
deleteTranscript: true,
|
|
961
|
+
emitLifecycleHooks: false,
|
|
962
|
+
},
|
|
761
963
|
timeoutMs: 10_000,
|
|
762
964
|
});
|
|
763
965
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const SUBAGENT_TARGET_KIND_SUBAGENT = "subagent";
|
|
2
|
+
export const SUBAGENT_TARGET_KIND_ACP = "acp";
|
|
3
|
+
export const SUBAGENT_ENDED_REASON_COMPLETE = "subagent-complete";
|
|
4
|
+
export const SUBAGENT_ENDED_REASON_ERROR = "subagent-error";
|
|
5
|
+
export const SUBAGENT_ENDED_REASON_KILLED = "subagent-killed";
|
|
6
|
+
export const SUBAGENT_ENDED_REASON_SESSION_RESET = "session-reset";
|
|
7
|
+
export const SUBAGENT_ENDED_REASON_SESSION_DELETE = "session-delete";
|
|
8
|
+
export const SUBAGENT_ENDED_OUTCOME_OK = "ok";
|
|
9
|
+
export const SUBAGENT_ENDED_OUTCOME_ERROR = "error";
|
|
10
|
+
export const SUBAGENT_ENDED_OUTCOME_TIMEOUT = "timeout";
|
|
11
|
+
export const SUBAGENT_ENDED_OUTCOME_KILLED = "killed";
|
|
12
|
+
export const SUBAGENT_ENDED_OUTCOME_RESET = "reset";
|
|
13
|
+
export const SUBAGENT_ENDED_OUTCOME_DELETED = "deleted";
|
|
14
|
+
export function resolveSubagentSessionEndedOutcome(reason) {
|
|
15
|
+
if (reason === SUBAGENT_ENDED_REASON_SESSION_RESET) {
|
|
16
|
+
return SUBAGENT_ENDED_OUTCOME_RESET;
|
|
17
|
+
}
|
|
18
|
+
return SUBAGENT_ENDED_OUTCOME_DELETED;
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SUBAGENT_ENDED_REASON_COMPLETE, } from "./subagent-lifecycle-events.js";
|
|
2
|
+
export function resolveCleanupCompletionReason(entry) {
|
|
3
|
+
return entry.endedReason ?? SUBAGENT_ENDED_REASON_COMPLETE;
|
|
4
|
+
}
|
|
5
|
+
function resolveEndedAgoMs(entry, now) {
|
|
6
|
+
return typeof entry.endedAt === "number" ? now - entry.endedAt : 0;
|
|
7
|
+
}
|
|
8
|
+
export function resolveDeferredCleanupDecision(params) {
|
|
9
|
+
const endedAgo = resolveEndedAgoMs(params.entry, params.now);
|
|
10
|
+
if (params.entry.expectsCompletionMessage === true && params.activeDescendantRuns > 0) {
|
|
11
|
+
if (endedAgo > params.announceExpiryMs) {
|
|
12
|
+
return { kind: "give-up", reason: "expiry" };
|
|
13
|
+
}
|
|
14
|
+
return { kind: "defer-descendants", delayMs: params.deferDescendantDelayMs };
|
|
15
|
+
}
|
|
16
|
+
const retryCount = (params.entry.announceRetryCount ?? 0) + 1;
|
|
17
|
+
if (retryCount >= params.maxAnnounceRetryCount || endedAgo > params.announceExpiryMs) {
|
|
18
|
+
return {
|
|
19
|
+
kind: "give-up",
|
|
20
|
+
reason: retryCount >= params.maxAnnounceRetryCount ? "retry-limit" : "expiry",
|
|
21
|
+
retryCount,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
kind: "retry",
|
|
26
|
+
retryCount,
|
|
27
|
+
resumeDelayMs: params.entry.expectsCompletionMessage === true
|
|
28
|
+
? params.resolveAnnounceRetryDelayMs(retryCount)
|
|
29
|
+
: undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
|
|
2
|
+
import { SUBAGENT_ENDED_OUTCOME_ERROR, SUBAGENT_ENDED_OUTCOME_OK, SUBAGENT_ENDED_OUTCOME_TIMEOUT, SUBAGENT_TARGET_KIND_SUBAGENT, } from "./subagent-lifecycle-events.js";
|
|
3
|
+
export function runOutcomesEqual(a, b) {
|
|
4
|
+
if (!a && !b) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
if (!a || !b) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if (a.status !== b.status) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
if (a.status === "error" && b.status === "error") {
|
|
14
|
+
return (a.error ?? "") === (b.error ?? "");
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
export function resolveLifecycleOutcomeFromRunOutcome(outcome) {
|
|
19
|
+
if (outcome?.status === "error") {
|
|
20
|
+
return SUBAGENT_ENDED_OUTCOME_ERROR;
|
|
21
|
+
}
|
|
22
|
+
if (outcome?.status === "timeout") {
|
|
23
|
+
return SUBAGENT_ENDED_OUTCOME_TIMEOUT;
|
|
24
|
+
}
|
|
25
|
+
return SUBAGENT_ENDED_OUTCOME_OK;
|
|
26
|
+
}
|
|
27
|
+
export async function emitSubagentEndedHookOnce(params) {
|
|
28
|
+
const runId = params.entry.runId.trim();
|
|
29
|
+
if (!runId) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (params.entry.endedHookEmittedAt) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (params.inFlightRunIds.has(runId)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
params.inFlightRunIds.add(runId);
|
|
39
|
+
try {
|
|
40
|
+
const hookRunner = getGlobalHookRunner();
|
|
41
|
+
if (hookRunner?.hasHooks("subagent_ended")) {
|
|
42
|
+
await hookRunner.runSubagentEnded({
|
|
43
|
+
targetSessionKey: params.entry.childSessionKey,
|
|
44
|
+
targetKind: SUBAGENT_TARGET_KIND_SUBAGENT,
|
|
45
|
+
reason: params.reason,
|
|
46
|
+
sendFarewell: params.sendFarewell,
|
|
47
|
+
accountId: params.accountId,
|
|
48
|
+
runId: params.entry.runId,
|
|
49
|
+
endedAt: params.entry.endedAt,
|
|
50
|
+
outcome: params.outcome,
|
|
51
|
+
error: params.error,
|
|
52
|
+
}, {
|
|
53
|
+
runId: params.entry.runId,
|
|
54
|
+
childSessionKey: params.entry.childSessionKey,
|
|
55
|
+
requesterSessionKey: params.entry.requesterSessionKey,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
params.entry.endedHookEmittedAt = Date.now();
|
|
59
|
+
params.persist();
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
params.inFlightRunIds.delete(runId);
|
|
67
|
+
}
|
|
68
|
+
}
|