@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
package/dist/acp/event-mapper.js
CHANGED
|
@@ -1,21 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
const INLINE_CONTROL_ESCAPE_MAP = {
|
|
2
|
+
"\0": "\\0",
|
|
3
|
+
"\r": "\\r",
|
|
4
|
+
"\n": "\\n",
|
|
5
|
+
"\t": "\\t",
|
|
6
|
+
"\v": "\\v",
|
|
7
|
+
"\f": "\\f",
|
|
8
|
+
"\u2028": "\\u2028",
|
|
9
|
+
"\u2029": "\\u2029",
|
|
10
|
+
};
|
|
11
|
+
function escapeInlineControlChars(value) {
|
|
12
|
+
let escaped = "";
|
|
13
|
+
for (const char of value) {
|
|
14
|
+
const codePoint = char.codePointAt(0);
|
|
15
|
+
if (codePoint === undefined) {
|
|
16
|
+
escaped += char;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const isInlineControl = codePoint <= 0x1f ||
|
|
20
|
+
(codePoint >= 0x7f && codePoint <= 0x9f) ||
|
|
21
|
+
codePoint === 0x2028 ||
|
|
22
|
+
codePoint === 0x2029;
|
|
23
|
+
if (!isInlineControl) {
|
|
24
|
+
escaped += char;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const mapped = INLINE_CONTROL_ESCAPE_MAP[char];
|
|
28
|
+
if (mapped) {
|
|
29
|
+
escaped += mapped;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
// Keep escaped control bytes readable and stable in logs/prompts.
|
|
33
|
+
escaped +=
|
|
34
|
+
codePoint <= 0xff
|
|
35
|
+
? `\\x${codePoint.toString(16).padStart(2, "0")}`
|
|
36
|
+
: `\\u${codePoint.toString(16).padStart(4, "0")}`;
|
|
37
|
+
}
|
|
38
|
+
return escaped;
|
|
39
|
+
}
|
|
40
|
+
function escapeResourceTitle(value) {
|
|
41
|
+
// Keep title content, but escape characters that can break the resource-link annotation shape.
|
|
42
|
+
return escapeInlineControlChars(value).replace(/[()[\]]/g, (char) => `\\${char}`);
|
|
43
|
+
}
|
|
44
|
+
export function extractTextFromPrompt(prompt, maxBytes) {
|
|
2
45
|
const parts = [];
|
|
46
|
+
// Track accumulated byte count per block to catch oversized prompts before full concatenation
|
|
47
|
+
let totalBytes = 0;
|
|
3
48
|
for (const block of prompt) {
|
|
49
|
+
let blockText;
|
|
4
50
|
if (block.type === "text") {
|
|
5
|
-
|
|
6
|
-
continue;
|
|
51
|
+
blockText = block.text;
|
|
7
52
|
}
|
|
8
|
-
if (block.type === "resource") {
|
|
53
|
+
else if (block.type === "resource") {
|
|
9
54
|
const resource = block.resource;
|
|
10
|
-
if (resource?.text)
|
|
11
|
-
|
|
12
|
-
|
|
55
|
+
if (resource?.text) {
|
|
56
|
+
blockText = resource.text;
|
|
57
|
+
}
|
|
13
58
|
}
|
|
14
|
-
if (block.type === "resource_link") {
|
|
15
|
-
const title = block.title ? ` (${block.title})` : "";
|
|
16
|
-
const uri = block.uri
|
|
17
|
-
|
|
18
|
-
|
|
59
|
+
else if (block.type === "resource_link") {
|
|
60
|
+
const title = block.title ? ` (${escapeResourceTitle(block.title)})` : "";
|
|
61
|
+
const uri = block.uri ? escapeInlineControlChars(block.uri) : "";
|
|
62
|
+
blockText = uri ? `[Resource link${title}] ${uri}` : `[Resource link${title}]`;
|
|
63
|
+
}
|
|
64
|
+
if (blockText !== undefined) {
|
|
65
|
+
// Guard: reject before allocating the full concatenated string
|
|
66
|
+
if (maxBytes !== undefined) {
|
|
67
|
+
const separatorBytes = parts.length > 0 ? 1 : 0; // "\n" added by join() between blocks
|
|
68
|
+
totalBytes += separatorBytes + Buffer.byteLength(blockText, "utf-8");
|
|
69
|
+
if (totalBytes > maxBytes) {
|
|
70
|
+
throw new Error(`Prompt exceeds maximum allowed size of ${maxBytes} bytes`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
parts.push(blockText);
|
|
19
74
|
}
|
|
20
75
|
}
|
|
21
76
|
return parts.join("\n");
|
|
@@ -23,11 +78,13 @@ export function extractTextFromPrompt(prompt) {
|
|
|
23
78
|
export function extractAttachmentsFromPrompt(prompt) {
|
|
24
79
|
const attachments = [];
|
|
25
80
|
for (const block of prompt) {
|
|
26
|
-
if (block.type !== "image")
|
|
81
|
+
if (block.type !== "image") {
|
|
27
82
|
continue;
|
|
83
|
+
}
|
|
28
84
|
const image = block;
|
|
29
|
-
if (!image.data || !image.mimeType)
|
|
85
|
+
if (!image.data || !image.mimeType) {
|
|
30
86
|
continue;
|
|
87
|
+
}
|
|
31
88
|
attachments.push({
|
|
32
89
|
type: "image",
|
|
33
90
|
mimeType: image.mimeType,
|
|
@@ -38,8 +95,9 @@ export function extractAttachmentsFromPrompt(prompt) {
|
|
|
38
95
|
}
|
|
39
96
|
export function formatToolTitle(name, args) {
|
|
40
97
|
const base = name ?? "tool";
|
|
41
|
-
if (!args || Object.keys(args).length === 0)
|
|
98
|
+
if (!args || Object.keys(args).length === 0) {
|
|
42
99
|
return base;
|
|
100
|
+
}
|
|
43
101
|
const parts = Object.entries(args).map(([key, value]) => {
|
|
44
102
|
const raw = typeof value === "string" ? value : JSON.stringify(value);
|
|
45
103
|
const safe = raw.length > 100 ? `${raw.slice(0, 100)}...` : raw;
|
|
@@ -48,23 +106,30 @@ export function formatToolTitle(name, args) {
|
|
|
48
106
|
return `${base}: ${parts.join(", ")}`;
|
|
49
107
|
}
|
|
50
108
|
export function inferToolKind(name) {
|
|
51
|
-
if (!name)
|
|
109
|
+
if (!name) {
|
|
52
110
|
return "other";
|
|
111
|
+
}
|
|
53
112
|
const normalized = name.toLowerCase();
|
|
54
|
-
if (normalized.includes("read"))
|
|
113
|
+
if (normalized.includes("read")) {
|
|
55
114
|
return "read";
|
|
56
|
-
|
|
115
|
+
}
|
|
116
|
+
if (normalized.includes("write") || normalized.includes("edit")) {
|
|
57
117
|
return "edit";
|
|
58
|
-
|
|
118
|
+
}
|
|
119
|
+
if (normalized.includes("delete") || normalized.includes("remove")) {
|
|
59
120
|
return "delete";
|
|
60
|
-
|
|
121
|
+
}
|
|
122
|
+
if (normalized.includes("move") || normalized.includes("rename")) {
|
|
61
123
|
return "move";
|
|
62
|
-
|
|
124
|
+
}
|
|
125
|
+
if (normalized.includes("search") || normalized.includes("find")) {
|
|
63
126
|
return "search";
|
|
127
|
+
}
|
|
64
128
|
if (normalized.includes("exec") || normalized.includes("run") || normalized.includes("bash")) {
|
|
65
129
|
return "execute";
|
|
66
130
|
}
|
|
67
|
-
if (normalized.includes("fetch") || normalized.includes("http"))
|
|
131
|
+
if (normalized.includes("fetch") || normalized.includes("http")) {
|
|
68
132
|
return "fetch";
|
|
133
|
+
}
|
|
69
134
|
return "other";
|
|
70
135
|
}
|
package/dist/acp/meta.js
CHANGED
|
@@ -1,30 +1,36 @@
|
|
|
1
1
|
export function readString(meta, keys) {
|
|
2
|
-
if (!meta)
|
|
2
|
+
if (!meta) {
|
|
3
3
|
return undefined;
|
|
4
|
+
}
|
|
4
5
|
for (const key of keys) {
|
|
5
6
|
const value = meta[key];
|
|
6
|
-
if (typeof value === "string" && value.trim())
|
|
7
|
+
if (typeof value === "string" && value.trim()) {
|
|
7
8
|
return value.trim();
|
|
9
|
+
}
|
|
8
10
|
}
|
|
9
11
|
return undefined;
|
|
10
12
|
}
|
|
11
13
|
export function readBool(meta, keys) {
|
|
12
|
-
if (!meta)
|
|
14
|
+
if (!meta) {
|
|
13
15
|
return undefined;
|
|
16
|
+
}
|
|
14
17
|
for (const key of keys) {
|
|
15
18
|
const value = meta[key];
|
|
16
|
-
if (typeof value === "boolean")
|
|
19
|
+
if (typeof value === "boolean") {
|
|
17
20
|
return value;
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
23
|
return undefined;
|
|
20
24
|
}
|
|
21
25
|
export function readNumber(meta, keys) {
|
|
22
|
-
if (!meta)
|
|
26
|
+
if (!meta) {
|
|
23
27
|
return undefined;
|
|
28
|
+
}
|
|
24
29
|
for (const key of keys) {
|
|
25
30
|
const value = meta[key];
|
|
26
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
31
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
27
32
|
return value;
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
return undefined;
|
|
30
36
|
}
|
|
@@ -3,21 +3,20 @@ import { resolveStateDir } from "../config/paths.js";
|
|
|
3
3
|
import { DEFAULT_AGENT_ID } from "../routing/session-key.js";
|
|
4
4
|
import { resolveUserPath } from "../utils.js";
|
|
5
5
|
export function resolvePoolbotAgentDir() {
|
|
6
|
-
const override = process.env.POOLBOT_AGENT_DIR?.trim() ||
|
|
7
|
-
|
|
8
|
-
process.env.PI_CODING_AGENT_DIR?.trim();
|
|
9
|
-
if (override)
|
|
6
|
+
const override = process.env.POOLBOT_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
|
|
7
|
+
if (override) {
|
|
10
8
|
return resolveUserPath(override);
|
|
9
|
+
}
|
|
11
10
|
const defaultAgentDir = path.join(resolveStateDir(), "agents", DEFAULT_AGENT_ID, "agent");
|
|
12
11
|
return resolveUserPath(defaultAgentDir);
|
|
13
12
|
}
|
|
14
|
-
export function
|
|
13
|
+
export function ensurePoolBotAgentEnv() {
|
|
15
14
|
const dir = resolvePoolbotAgentDir();
|
|
16
|
-
if (!process.env.POOLBOT_AGENT_DIR)
|
|
15
|
+
if (!process.env.POOLBOT_AGENT_DIR) {
|
|
17
16
|
process.env.POOLBOT_AGENT_DIR = dir;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!process.env.PI_CODING_AGENT_DIR)
|
|
17
|
+
}
|
|
18
|
+
if (!process.env.PI_CODING_AGENT_DIR) {
|
|
21
19
|
process.env.PI_CODING_AGENT_DIR = dir;
|
|
20
|
+
}
|
|
22
21
|
return dir;
|
|
23
22
|
}
|
|
@@ -4,17 +4,19 @@ import { resolveStateDir } from "../config/paths.js";
|
|
|
4
4
|
import { DEFAULT_AGENT_ID, normalizeAgentId, parseAgentSessionKey, } from "../routing/session-key.js";
|
|
5
5
|
import { normalizeSkillFilter } from "./skills/filter.js";
|
|
6
6
|
import { resolveUserPath } from "../utils.js";
|
|
7
|
+
import { createSubsystemLogger } from "../logging/subsystem.js";
|
|
7
8
|
import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
|
|
9
|
+
const log = createSubsystemLogger("agent-scope");
|
|
8
10
|
export { resolveAgentIdFromSessionKey } from "../routing/session-key.js";
|
|
9
11
|
let defaultAgentWarned = false;
|
|
10
|
-
function
|
|
12
|
+
export function listAgentEntries(cfg) {
|
|
11
13
|
const list = cfg.agents?.list;
|
|
12
14
|
if (!Array.isArray(list))
|
|
13
15
|
return [];
|
|
14
16
|
return list.filter((entry) => Boolean(entry && typeof entry === "object"));
|
|
15
17
|
}
|
|
16
18
|
export function listAgentIds(cfg) {
|
|
17
|
-
const agents =
|
|
19
|
+
const agents = listAgentEntries(cfg);
|
|
18
20
|
if (agents.length === 0)
|
|
19
21
|
return [DEFAULT_AGENT_ID];
|
|
20
22
|
const seen = new Set();
|
|
@@ -29,13 +31,13 @@ export function listAgentIds(cfg) {
|
|
|
29
31
|
return ids.length > 0 ? ids : [DEFAULT_AGENT_ID];
|
|
30
32
|
}
|
|
31
33
|
export function resolveDefaultAgentId(cfg) {
|
|
32
|
-
const agents =
|
|
34
|
+
const agents = listAgentEntries(cfg);
|
|
33
35
|
if (agents.length === 0)
|
|
34
36
|
return DEFAULT_AGENT_ID;
|
|
35
37
|
const defaults = agents.filter((agent) => agent?.default);
|
|
36
38
|
if (defaults.length > 1 && !defaultAgentWarned) {
|
|
37
39
|
defaultAgentWarned = true;
|
|
38
|
-
|
|
40
|
+
log.warn("Multiple agents marked default=true; using the first entry as default.");
|
|
39
41
|
}
|
|
40
42
|
const chosen = (defaults[0] ?? agents[0])?.id?.trim();
|
|
41
43
|
return normalizeAgentId(chosen || DEFAULT_AGENT_ID);
|
|
@@ -53,7 +55,7 @@ export function resolveSessionAgentId(params) {
|
|
|
53
55
|
}
|
|
54
56
|
function resolveAgentEntry(cfg, agentId) {
|
|
55
57
|
const id = normalizeAgentId(agentId);
|
|
56
|
-
return
|
|
58
|
+
return listAgentEntries(cfg).find((entry) => normalizeAgentId(entry.id) === id);
|
|
57
59
|
}
|
|
58
60
|
export function resolveAgentConfig(cfg, agentId) {
|
|
59
61
|
const id = normalizeAgentId(agentId);
|
|
@@ -1,12 +1,37 @@
|
|
|
1
|
-
import { getOAuthApiKey } from "@mariozechner/pi-ai";
|
|
2
|
-
import
|
|
3
|
-
import { refreshChutesTokens } from "../chutes-oauth.js";
|
|
1
|
+
import { getOAuthApiKey, getOAuthProviders, } from "@mariozechner/pi-ai";
|
|
2
|
+
import { withFileLock } from "../../infra/file-lock.js";
|
|
4
3
|
import { refreshQwenPortalCredentials } from "../../providers/qwen-portal-oauth.js";
|
|
4
|
+
import { refreshChutesTokens } from "../chutes-oauth.js";
|
|
5
5
|
import { AUTH_STORE_LOCK_OPTIONS, log } from "./constants.js";
|
|
6
6
|
import { formatAuthDoctorHint } from "./doctor.js";
|
|
7
7
|
import { ensureAuthStoreFile, resolveAuthStorePath } from "./paths.js";
|
|
8
8
|
import { suggestOAuthProfileIdForLegacyDefault } from "./repair.js";
|
|
9
9
|
import { ensureAuthProfileStore, saveAuthProfileStore } from "./store.js";
|
|
10
|
+
const OAUTH_PROVIDER_IDS = new Set(getOAuthProviders().map((provider) => provider.id));
|
|
11
|
+
const isOAuthProvider = (provider) => OAUTH_PROVIDER_IDS.has(provider);
|
|
12
|
+
const resolveOAuthProvider = (provider) => isOAuthProvider(provider) ? provider : null;
|
|
13
|
+
/** Bearer-token auth modes that are interchangeable (oauth tokens and raw tokens). */
|
|
14
|
+
const BEARER_AUTH_MODES = new Set(["oauth", "token"]);
|
|
15
|
+
const isCompatibleModeType = (mode, type) => {
|
|
16
|
+
if (!mode || !type) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (mode === type) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
// Both token and oauth represent bearer-token auth paths — allow bidirectional compat.
|
|
23
|
+
return BEARER_AUTH_MODES.has(mode) && BEARER_AUTH_MODES.has(type);
|
|
24
|
+
};
|
|
25
|
+
function isProfileConfigCompatible(params) {
|
|
26
|
+
const profileConfig = params.cfg?.auth?.profiles?.[params.profileId];
|
|
27
|
+
if (profileConfig && profileConfig.provider !== params.provider) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (profileConfig && !isCompatibleModeType(profileConfig.mode, params.mode)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
10
35
|
function buildOAuthApiKey(provider, credentials) {
|
|
11
36
|
const needsProjectId = provider === "google-gemini-cli" || provider === "google-antigravity";
|
|
12
37
|
return needsProjectId
|
|
@@ -16,18 +41,62 @@ function buildOAuthApiKey(provider, credentials) {
|
|
|
16
41
|
})
|
|
17
42
|
: credentials.access;
|
|
18
43
|
}
|
|
44
|
+
function buildApiKeyProfileResult(params) {
|
|
45
|
+
return {
|
|
46
|
+
apiKey: params.apiKey,
|
|
47
|
+
provider: params.provider,
|
|
48
|
+
email: params.email,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function buildOAuthProfileResult(params) {
|
|
52
|
+
return buildApiKeyProfileResult({
|
|
53
|
+
apiKey: buildOAuthApiKey(params.provider, params.credentials),
|
|
54
|
+
provider: params.provider,
|
|
55
|
+
email: params.email,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function isExpiredCredential(expires) {
|
|
59
|
+
return (typeof expires === "number" && Number.isFinite(expires) && expires > 0 && Date.now() >= expires);
|
|
60
|
+
}
|
|
61
|
+
function adoptNewerMainOAuthCredential(params) {
|
|
62
|
+
if (!params.agentDir) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const mainStore = ensureAuthProfileStore(undefined);
|
|
67
|
+
const mainCred = mainStore.profiles[params.profileId];
|
|
68
|
+
if (mainCred?.type === "oauth" &&
|
|
69
|
+
mainCred.provider === params.cred.provider &&
|
|
70
|
+
Number.isFinite(mainCred.expires) &&
|
|
71
|
+
(!Number.isFinite(params.cred.expires) || mainCred.expires > params.cred.expires)) {
|
|
72
|
+
params.store.profiles[params.profileId] = { ...mainCred };
|
|
73
|
+
saveAuthProfileStore(params.store, params.agentDir);
|
|
74
|
+
log.info("adopted newer OAuth credentials from main agent", {
|
|
75
|
+
profileId: params.profileId,
|
|
76
|
+
agentDir: params.agentDir,
|
|
77
|
+
expires: new Date(mainCred.expires).toISOString(),
|
|
78
|
+
});
|
|
79
|
+
return mainCred;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
// Best-effort: don't crash if main agent store is missing or unreadable.
|
|
84
|
+
log.debug("adoptNewerMainOAuthCredential failed", {
|
|
85
|
+
profileId: params.profileId,
|
|
86
|
+
error: err instanceof Error ? err.message : String(err),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
19
91
|
async function refreshOAuthTokenWithLock(params) {
|
|
20
92
|
const authPath = resolveAuthStorePath(params.agentDir);
|
|
21
93
|
ensureAuthStoreFile(authPath);
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
release = await lockfile.lock(authPath, {
|
|
25
|
-
...AUTH_STORE_LOCK_OPTIONS,
|
|
26
|
-
});
|
|
94
|
+
return await withFileLock(authPath, AUTH_STORE_LOCK_OPTIONS, async () => {
|
|
27
95
|
const store = ensureAuthProfileStore(params.agentDir);
|
|
28
96
|
const cred = store.profiles[params.profileId];
|
|
29
|
-
if (!cred || cred.type !== "oauth")
|
|
97
|
+
if (!cred || cred.type !== "oauth") {
|
|
30
98
|
return null;
|
|
99
|
+
}
|
|
31
100
|
if (Date.now() < cred.expires) {
|
|
32
101
|
return {
|
|
33
102
|
apiKey: buildOAuthApiKey(cred.provider, cred),
|
|
@@ -49,9 +118,16 @@ async function refreshOAuthTokenWithLock(params) {
|
|
|
49
118
|
const newCredentials = await refreshQwenPortalCredentials(cred);
|
|
50
119
|
return { apiKey: newCredentials.access, newCredentials };
|
|
51
120
|
})()
|
|
52
|
-
: await
|
|
53
|
-
|
|
121
|
+
: await (async () => {
|
|
122
|
+
const oauthProvider = resolveOAuthProvider(cred.provider);
|
|
123
|
+
if (!oauthProvider) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
return await getOAuthApiKey(oauthProvider, oauthCreds);
|
|
127
|
+
})();
|
|
128
|
+
if (!result) {
|
|
54
129
|
return null;
|
|
130
|
+
}
|
|
55
131
|
store.profiles[params.profileId] = {
|
|
56
132
|
...cred,
|
|
57
133
|
...result.newCredentials,
|
|
@@ -59,104 +135,111 @@ async function refreshOAuthTokenWithLock(params) {
|
|
|
59
135
|
};
|
|
60
136
|
saveAuthProfileStore(store, params.agentDir);
|
|
61
137
|
return result;
|
|
62
|
-
}
|
|
63
|
-
finally {
|
|
64
|
-
if (release) {
|
|
65
|
-
try {
|
|
66
|
-
await release();
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
// ignore unlock errors
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
138
|
+
});
|
|
73
139
|
}
|
|
74
140
|
async function tryResolveOAuthProfile(params) {
|
|
75
141
|
const { cfg, store, profileId } = params;
|
|
76
142
|
const cred = store.profiles[profileId];
|
|
77
|
-
if (!cred || cred.type !== "oauth")
|
|
78
|
-
return null;
|
|
79
|
-
const profileConfig = cfg?.auth?.profiles?.[profileId];
|
|
80
|
-
if (profileConfig && profileConfig.provider !== cred.provider)
|
|
143
|
+
if (!cred || cred.type !== "oauth") {
|
|
81
144
|
return null;
|
|
82
|
-
|
|
145
|
+
}
|
|
146
|
+
if (!isProfileConfigCompatible({
|
|
147
|
+
cfg,
|
|
148
|
+
profileId,
|
|
149
|
+
provider: cred.provider,
|
|
150
|
+
mode: cred.type,
|
|
151
|
+
})) {
|
|
83
152
|
return null;
|
|
153
|
+
}
|
|
84
154
|
if (Date.now() < cred.expires) {
|
|
85
|
-
return {
|
|
86
|
-
apiKey: buildOAuthApiKey(cred.provider, cred),
|
|
155
|
+
return buildOAuthProfileResult({
|
|
87
156
|
provider: cred.provider,
|
|
157
|
+
credentials: cred,
|
|
88
158
|
email: cred.email,
|
|
89
|
-
};
|
|
159
|
+
});
|
|
90
160
|
}
|
|
91
161
|
const refreshed = await refreshOAuthTokenWithLock({
|
|
92
162
|
profileId,
|
|
93
163
|
agentDir: params.agentDir,
|
|
94
164
|
});
|
|
95
|
-
if (!refreshed)
|
|
165
|
+
if (!refreshed) {
|
|
96
166
|
return null;
|
|
97
|
-
|
|
167
|
+
}
|
|
168
|
+
return buildApiKeyProfileResult({
|
|
98
169
|
apiKey: refreshed.apiKey,
|
|
99
170
|
provider: cred.provider,
|
|
100
171
|
email: cred.email,
|
|
101
|
-
};
|
|
172
|
+
});
|
|
102
173
|
}
|
|
103
174
|
export async function resolveApiKeyForProfile(params) {
|
|
104
175
|
const { cfg, store, profileId } = params;
|
|
105
176
|
const cred = store.profiles[profileId];
|
|
106
|
-
if (!cred)
|
|
107
|
-
return null;
|
|
108
|
-
const profileConfig = cfg?.auth?.profiles?.[profileId];
|
|
109
|
-
if (profileConfig && profileConfig.provider !== cred.provider)
|
|
177
|
+
if (!cred) {
|
|
110
178
|
return null;
|
|
111
|
-
|
|
179
|
+
}
|
|
180
|
+
if (!isProfileConfigCompatible({
|
|
181
|
+
cfg,
|
|
182
|
+
profileId,
|
|
183
|
+
provider: cred.provider,
|
|
184
|
+
mode: cred.type,
|
|
112
185
|
// Compatibility: treat "oauth" config as compatible with stored token profiles.
|
|
113
|
-
|
|
114
|
-
|
|
186
|
+
allowOAuthTokenCompatibility: true,
|
|
187
|
+
})) {
|
|
188
|
+
return null;
|
|
115
189
|
}
|
|
116
190
|
if (cred.type === "api_key") {
|
|
117
|
-
|
|
191
|
+
const key = cred.key?.trim();
|
|
192
|
+
if (!key) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return buildApiKeyProfileResult({ apiKey: key, provider: cred.provider, email: cred.email });
|
|
118
196
|
}
|
|
119
197
|
if (cred.type === "token") {
|
|
120
198
|
const token = cred.token?.trim();
|
|
121
|
-
if (!token)
|
|
199
|
+
if (!token) {
|
|
122
200
|
return null;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
cred.expires > 0 &&
|
|
126
|
-
Date.now() >= cred.expires) {
|
|
201
|
+
}
|
|
202
|
+
if (isExpiredCredential(cred.expires)) {
|
|
127
203
|
return null;
|
|
128
204
|
}
|
|
129
|
-
return { apiKey: token, provider: cred.provider, email: cred.email };
|
|
205
|
+
return buildApiKeyProfileResult({ apiKey: token, provider: cred.provider, email: cred.email });
|
|
130
206
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
207
|
+
const oauthCred = adoptNewerMainOAuthCredential({
|
|
208
|
+
store,
|
|
209
|
+
profileId,
|
|
210
|
+
agentDir: params.agentDir,
|
|
211
|
+
cred,
|
|
212
|
+
}) ?? cred;
|
|
213
|
+
if (Date.now() < oauthCred.expires) {
|
|
214
|
+
return buildOAuthProfileResult({
|
|
215
|
+
provider: oauthCred.provider,
|
|
216
|
+
credentials: oauthCred,
|
|
217
|
+
email: oauthCred.email,
|
|
218
|
+
});
|
|
137
219
|
}
|
|
138
220
|
try {
|
|
139
221
|
const result = await refreshOAuthTokenWithLock({
|
|
140
222
|
profileId,
|
|
141
223
|
agentDir: params.agentDir,
|
|
142
224
|
});
|
|
143
|
-
if (!result)
|
|
225
|
+
if (!result) {
|
|
144
226
|
return null;
|
|
145
|
-
|
|
227
|
+
}
|
|
228
|
+
return buildApiKeyProfileResult({
|
|
146
229
|
apiKey: result.apiKey,
|
|
147
230
|
provider: cred.provider,
|
|
148
231
|
email: cred.email,
|
|
149
|
-
};
|
|
232
|
+
});
|
|
150
233
|
}
|
|
151
234
|
catch (error) {
|
|
152
235
|
const refreshedStore = ensureAuthProfileStore(params.agentDir);
|
|
153
236
|
const refreshed = refreshedStore.profiles[profileId];
|
|
154
237
|
if (refreshed?.type === "oauth" && Date.now() < refreshed.expires) {
|
|
155
|
-
return {
|
|
156
|
-
apiKey: buildOAuthApiKey(refreshed.provider, refreshed),
|
|
238
|
+
return buildOAuthProfileResult({
|
|
157
239
|
provider: refreshed.provider,
|
|
240
|
+
credentials: refreshed,
|
|
158
241
|
email: refreshed.email ?? cred.email,
|
|
159
|
-
};
|
|
242
|
+
});
|
|
160
243
|
}
|
|
161
244
|
const fallbackProfileId = suggestOAuthProfileIdForLegacyDefault({
|
|
162
245
|
cfg,
|
|
@@ -172,8 +255,9 @@ export async function resolveApiKeyForProfile(params) {
|
|
|
172
255
|
profileId: fallbackProfileId,
|
|
173
256
|
agentDir: params.agentDir,
|
|
174
257
|
});
|
|
175
|
-
if (fallbackResolved)
|
|
258
|
+
if (fallbackResolved) {
|
|
176
259
|
return fallbackResolved;
|
|
260
|
+
}
|
|
177
261
|
}
|
|
178
262
|
catch {
|
|
179
263
|
// keep original error
|
|
@@ -193,11 +277,11 @@ export async function resolveApiKeyForProfile(params) {
|
|
|
193
277
|
agentDir: params.agentDir,
|
|
194
278
|
expires: new Date(mainCred.expires).toISOString(),
|
|
195
279
|
});
|
|
196
|
-
return {
|
|
197
|
-
apiKey: buildOAuthApiKey(mainCred.provider, mainCred),
|
|
280
|
+
return buildOAuthProfileResult({
|
|
198
281
|
provider: mainCred.provider,
|
|
282
|
+
credentials: mainCred,
|
|
199
283
|
email: mainCred.email,
|
|
200
|
-
};
|
|
284
|
+
});
|
|
201
285
|
}
|
|
202
286
|
}
|
|
203
287
|
catch {
|
|
@@ -213,6 +297,6 @@ export async function resolveApiKeyForProfile(params) {
|
|
|
213
297
|
});
|
|
214
298
|
throw new Error(`OAuth token refresh failed for ${cred.provider}: ${message}. ` +
|
|
215
299
|
"Please try again or re-authenticate." +
|
|
216
|
-
(hint ? `\n\n${hint}` : ""));
|
|
300
|
+
(hint ? `\n\n${hint}` : ""), { cause: error });
|
|
217
301
|
}
|
|
218
302
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { updateSessionStore } from "../../config/sessions.js";
|
|
2
|
-
import { normalizeProviderId } from "../model-selection.js";
|
|
3
2
|
import { ensureAuthProfileStore, isProfileInCooldown, resolveAuthProfileOrder, } from "../auth-profiles.js";
|
|
3
|
+
import { normalizeProviderId } from "../model-selection.js";
|
|
4
4
|
function isProfileForProvider(params) {
|
|
5
5
|
const entry = params.store.profiles[params.profileId];
|
|
6
|
-
if (!entry?.provider)
|
|
6
|
+
if (!entry?.provider) {
|
|
7
7
|
return false;
|
|
8
|
+
}
|
|
8
9
|
return normalizeProviderId(entry.provider) === normalizeProviderId(params.provider);
|
|
9
10
|
}
|
|
10
11
|
export async function clearSessionAuthProfileOverride(params) {
|
|
@@ -22,8 +23,9 @@ export async function clearSessionAuthProfileOverride(params) {
|
|
|
22
23
|
}
|
|
23
24
|
export async function resolveSessionAuthProfileOverride(params) {
|
|
24
25
|
const { cfg, provider, agentDir, sessionEntry, sessionStore, sessionKey, storePath, isNewSession, } = params;
|
|
25
|
-
if (!sessionEntry || !sessionStore || !sessionKey)
|
|
26
|
+
if (!sessionEntry || !sessionStore || !sessionKey) {
|
|
26
27
|
return sessionEntry?.authProfileOverride;
|
|
28
|
+
}
|
|
27
29
|
const store = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
|
|
28
30
|
const order = resolveAuthProfileOrder({ cfg, store, provider });
|
|
29
31
|
let current = sessionEntry.authProfileOverride?.trim();
|
|
@@ -39,17 +41,20 @@ export async function resolveSessionAuthProfileOverride(params) {
|
|
|
39
41
|
await clearSessionAuthProfileOverride({ sessionEntry, sessionStore, sessionKey, storePath });
|
|
40
42
|
current = undefined;
|
|
41
43
|
}
|
|
42
|
-
if (order.length === 0)
|
|
44
|
+
if (order.length === 0) {
|
|
43
45
|
return undefined;
|
|
46
|
+
}
|
|
44
47
|
const pickFirstAvailable = () => order.find((profileId) => !isProfileInCooldown(store, profileId)) ?? order[0];
|
|
45
48
|
const pickNextAvailable = (active) => {
|
|
46
49
|
const startIndex = order.indexOf(active);
|
|
47
|
-
if (startIndex < 0)
|
|
50
|
+
if (startIndex < 0) {
|
|
48
51
|
return pickFirstAvailable();
|
|
52
|
+
}
|
|
49
53
|
for (let offset = 1; offset <= order.length; offset += 1) {
|
|
50
54
|
const candidate = order[(startIndex + offset) % order.length];
|
|
51
|
-
if (!isProfileInCooldown(store, candidate))
|
|
55
|
+
if (!isProfileInCooldown(store, candidate)) {
|
|
52
56
|
return candidate;
|
|
57
|
+
}
|
|
53
58
|
}
|
|
54
59
|
return order[startIndex] ?? order[0];
|
|
55
60
|
};
|
|
@@ -76,8 +81,9 @@ export async function resolveSessionAuthProfileOverride(params) {
|
|
|
76
81
|
else if (!current || isProfileInCooldown(store, current)) {
|
|
77
82
|
next = pickFirstAvailable();
|
|
78
83
|
}
|
|
79
|
-
if (!next)
|
|
84
|
+
if (!next) {
|
|
80
85
|
return current;
|
|
86
|
+
}
|
|
81
87
|
const shouldPersist = next !== sessionEntry.authProfileOverride ||
|
|
82
88
|
sessionEntry.authProfileOverrideSource !== "auto" ||
|
|
83
89
|
sessionEntry.authProfileOverrideCompactionCount !== compactionCount;
|