@poolzin/pool-bot 2026.1.39 → 2026.2.1
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/assets/chrome-extension/README.md +3 -3
- package/assets/chrome-extension/background.js +5 -5
- package/assets/chrome-extension/manifest.json +3 -3
- package/assets/chrome-extension/options.html +4 -4
- package/assets/chrome-extension/options.js +1 -1
- package/dist/acp/client.js +3 -3
- package/dist/acp/types.js +1 -1
- package/dist/agents/agent-paths.js +3 -3
- package/dist/agents/auth-profiles/paths.js +3 -3
- package/dist/agents/bash-tools.exec.js +76 -25
- package/dist/agents/cli-runner/helpers.js +10 -12
- package/dist/agents/cli-runner.js +2 -2
- package/dist/agents/cloudflare-ai-gateway.js +31 -0
- package/dist/agents/compaction.js +16 -2
- package/dist/agents/context-window-guard.js +13 -10
- package/dist/agents/context.js +4 -4
- package/dist/agents/docs-path.js +1 -1
- package/dist/agents/identity.js +47 -7
- package/dist/agents/memory-search.js +25 -8
- package/dist/agents/minimax-vlm.js +1 -1
- package/dist/agents/model-auth.js +12 -1
- package/dist/agents/model-catalog.js +4 -4
- package/dist/agents/model-selection.js +31 -4
- package/dist/agents/models-config.js +3 -3
- package/dist/agents/models-config.providers.js +147 -39
- package/dist/agents/pi-embedded-block-chunker.js +117 -42
- package/dist/agents/pi-embedded-helpers/errors.js +183 -78
- package/dist/agents/pi-embedded-helpers/openai.js +1 -1
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +9 -8
- package/dist/agents/pi-embedded-runner/model.js +63 -4
- package/dist/agents/pi-embedded-runner/run/attempt.js +27 -17
- package/dist/agents/pi-embedded-runner/run.js +203 -50
- package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
- package/dist/agents/pi-embedded-runner/tool-result-truncation.js +275 -0
- package/dist/agents/pi-embedded-runner/utils.js +1 -1
- package/dist/agents/pi-embedded-subscribe.js +118 -29
- package/dist/agents/pi-model-discovery.js +10 -0
- package/dist/agents/pi-tool-definition-adapter.js +50 -9
- package/dist/agents/pi-tools.before-tool-call.js +67 -0
- package/dist/agents/pi-tools.js +20 -10
- package/dist/agents/pi-tools.read.js +2 -2
- package/dist/agents/poolbot-tools.js +15 -10
- package/dist/agents/sandbox-paths.js +31 -0
- package/dist/agents/session-file-repair.js +83 -0
- package/dist/agents/session-tool-result-guard.js +94 -15
- package/dist/agents/session-transcript-repair.js +68 -0
- package/dist/agents/shell-utils.js +51 -0
- package/dist/agents/skills/bundled-context.js +23 -0
- package/dist/agents/skills/bundled-dir.js +41 -7
- package/dist/agents/skills/frontmatter.js +1 -1
- package/dist/agents/skills/workspace.js +2 -2
- package/dist/agents/skills-install.js +60 -23
- package/dist/agents/subagent-announce.js +79 -34
- package/dist/agents/system-prompt.js +28 -4
- package/dist/agents/together-models.js +127 -0
- package/dist/agents/tool-images.js +1 -1
- package/dist/agents/tool-policy.conformance.js +14 -0
- package/dist/agents/tool-policy.js +25 -1
- package/dist/agents/tools/browser-tool.js +3 -3
- package/dist/agents/tools/cron-tool.js +166 -19
- package/dist/agents/tools/discord-actions-presence.js +78 -0
- package/dist/agents/tools/image-tool.js +2 -2
- package/dist/agents/tools/memory-tool.js +93 -5
- package/dist/agents/tools/message-tool.js +56 -2
- package/dist/agents/tools/sessions-history-tool.js +69 -1
- package/dist/agents/tools/web-search.js +211 -42
- package/dist/agents/usage.js +23 -1
- package/dist/agents/workspace-run.js +67 -0
- package/dist/agents/workspace-templates.js +44 -0
- package/dist/auto-reply/command-auth.js +121 -6
- package/dist/auto-reply/commands-registry.data.js +1 -1
- package/dist/auto-reply/envelope.js +50 -72
- package/dist/auto-reply/reply/commands-compact.js +1 -0
- package/dist/auto-reply/reply/commands-context-report.js +3 -2
- package/dist/auto-reply/reply/commands-context.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +107 -60
- package/dist/auto-reply/reply/commands-ptt.js +171 -0
- package/dist/auto-reply/reply/commands-session.js +2 -2
- package/dist/auto-reply/reply/get-reply-run.js +16 -5
- package/dist/auto-reply/reply/groups.js +1 -1
- package/dist/auto-reply/reply/inbound-context.js +9 -1
- package/dist/auto-reply/reply/inbound-meta.js +130 -0
- package/dist/auto-reply/reply/model-selection.js +3 -3
- package/dist/auto-reply/reply/untrusted-context.js +15 -0
- package/dist/auto-reply/status.js +1 -1
- package/dist/auto-reply/thinking.js +88 -43
- package/dist/browser/bridge-server.js +13 -0
- package/dist/browser/cdp.helpers.js +38 -24
- package/dist/browser/client-fetch.js +51 -8
- package/dist/browser/config.js +2 -11
- package/dist/browser/extension-relay.js +104 -43
- package/dist/browser/pw-ai.js +1 -1
- package/dist/browser/pw-session.js +143 -8
- package/dist/browser/pw-tools-core.interactions.js +125 -27
- package/dist/browser/pw-tools-core.responses.js +1 -1
- package/dist/browser/pw-tools-core.state.js +1 -1
- package/dist/browser/routes/agent.act.js +86 -41
- package/dist/browser/routes/dispatcher.js +4 -4
- package/dist/browser/screenshot.js +1 -1
- package/dist/browser/server-context.js +2 -2
- package/dist/browser/server.js +13 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui.js +3 -3
- package/dist/channels/plugins/catalog.js +2 -2
- package/dist/channels/plugins/onboarding/imessage.js +1 -1
- package/dist/channels/plugins/onboarding/signal.js +1 -1
- package/dist/channels/plugins/onboarding/slack.js +4 -4
- package/dist/channels/plugins/onboarding/whatsapp.js +3 -3
- package/dist/channels/plugins/pairing-message.js +1 -1
- package/dist/channels/reply-prefix.js +8 -1
- package/dist/cli/browser-cli-extension.js +2 -2
- package/dist/cli/cron-cli/register.cron-add.js +61 -40
- package/dist/cli/cron-cli/register.cron-edit.js +60 -34
- package/dist/cli/cron-cli/shared.js +56 -41
- package/dist/cli/dns-cli.js +26 -14
- package/dist/cli/docs-cli.js +1 -1
- package/dist/cli/gateway-cli/dev.js +1 -1
- package/dist/cli/gateway-cli/register.js +37 -19
- package/dist/cli/memory-cli.js +30 -20
- package/dist/cli/nodes-cli/register.canvas.js +1 -1
- package/dist/cli/parse-bytes.js +37 -0
- package/dist/cli/plugins-cli.js +1 -1
- package/dist/cli/run-main.js +2 -2
- package/dist/cli/security-cli.js +1 -1
- package/dist/cli/tagline.js +1 -1
- package/dist/cli/update-cli.js +173 -52
- package/dist/cli/webhooks-cli.js +5 -5
- package/dist/commands/agent.js +1 -0
- package/dist/commands/agents.commands.add.js +1 -1
- package/dist/commands/auth-choice.apply.api-providers.js +305 -17
- package/dist/commands/auth-choice.apply.js +4 -1
- package/dist/commands/auth-choice.apply.plugin-provider.js +2 -2
- package/dist/commands/auth-choice.apply.xai.js +63 -0
- package/dist/commands/auth-choice.preferred-provider.js +7 -1
- package/dist/commands/configure.wizard.js +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/doctor-config-flow.js +61 -5
- package/dist/commands/doctor-gateway-services.js +3 -3
- package/dist/commands/doctor-state-migrations.js +1 -1
- package/dist/commands/doctor-update.js +3 -3
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/health.js +1 -1
- package/dist/commands/model-allowlist.js +29 -0
- package/dist/commands/model-picker.js +2 -1
- package/dist/commands/models/list.probe.js +2 -2
- package/dist/commands/models/list.registry.js +4 -4
- package/dist/commands/models/list.status-command.js +44 -24
- package/dist/commands/models/shared.js +15 -0
- package/dist/commands/onboard-auth.config-core.js +366 -28
- package/dist/commands/onboard-auth.credentials.js +71 -9
- package/dist/commands/onboard-auth.js +3 -3
- package/dist/commands/onboard-auth.models.js +26 -24
- package/dist/commands/onboard-custom.js +384 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +146 -9
- package/dist/commands/onboard-skills.js +63 -38
- package/dist/commands/openai-model-default.js +41 -0
- package/dist/commands/status-all/report-lines.js +1 -1
- package/dist/commands/status.command.js +1 -1
- package/dist/commands/uninstall.js +3 -3
- package/dist/compat/legacy-names.js +1 -1
- package/dist/config/defaults.js +3 -2
- package/dist/config/io.js +3 -3
- package/dist/config/paths.js +136 -35
- package/dist/config/plugin-auto-enable.js +21 -5
- package/dist/config/redact-snapshot.js +153 -0
- package/dist/config/schema.field-metadata.js +590 -0
- package/dist/config/schema.js +3 -3
- package/dist/config/sessions/store.js +291 -23
- package/dist/config/types.memory.js +1 -0
- package/dist/config/version.js +4 -4
- package/dist/config/zod-schema.agent-defaults.js +3 -0
- package/dist/config/zod-schema.agent-runtime.js +13 -2
- package/dist/config/zod-schema.providers-core.js +142 -0
- package/dist/config/zod-schema.session.js +3 -0
- package/dist/cron/delivery.js +57 -0
- package/dist/cron/isolated-agent/delivery-target.js +18 -3
- package/dist/cron/isolated-agent/helpers.js +22 -5
- package/dist/cron/isolated-agent/run.js +171 -63
- package/dist/cron/isolated-agent/session.js +2 -0
- package/dist/cron/normalize.js +356 -28
- package/dist/cron/parse.js +10 -5
- package/dist/cron/run-log.js +35 -10
- package/dist/cron/schedule.js +41 -6
- package/dist/cron/service/jobs.js +208 -35
- package/dist/cron/service/ops.js +72 -16
- package/dist/cron/service/state.js +2 -0
- package/dist/cron/service/store.js +386 -14
- package/dist/cron/service/timer.js +390 -147
- package/dist/cron/session-reaper.js +86 -0
- package/dist/cron/store.js +23 -8
- package/dist/cron/validate-timestamp.js +43 -0
- package/dist/daemon/constants.js +7 -7
- package/dist/daemon/inspect.js +6 -6
- package/dist/daemon/systemd-unit.js +1 -1
- package/dist/discord/monitor/agent-components.js +438 -0
- package/dist/discord/monitor/allow-list.js +28 -5
- package/dist/discord/monitor/gateway-registry.js +29 -0
- package/dist/discord/monitor/native-command.js +44 -23
- package/dist/discord/monitor/sender-identity.js +45 -0
- package/dist/discord/pluralkit.js +27 -0
- package/dist/discord/send.outbound.js +92 -5
- package/dist/discord/send.shared.js +60 -23
- package/dist/discord/targets.js +84 -1
- package/dist/entry.js +15 -9
- package/dist/extensionAPI.js +8 -0
- package/dist/gateway/control-ui.js +8 -1
- package/dist/gateway/hooks-mapping.js +3 -0
- package/dist/gateway/hooks.js +65 -0
- package/dist/gateway/live-image-probe.js +1 -66
- package/dist/gateway/net.js +96 -31
- package/dist/gateway/node-command-policy.js +50 -15
- package/dist/gateway/openai-http.js +2 -2
- package/dist/gateway/openresponses-http.js +4 -4
- package/dist/gateway/origin-check.js +56 -0
- package/dist/gateway/protocol/client-info.js +9 -0
- package/dist/gateway/protocol/index.js +9 -2
- package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
- package/dist/gateway/protocol/schema/cron.js +22 -10
- package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
- package/dist/gateway/protocol/schema/sessions.js +12 -0
- package/dist/gateway/server/hooks.js +1 -1
- package/dist/gateway/server-broadcast.js +26 -9
- package/dist/gateway/server-chat.js +112 -23
- package/dist/gateway/server-discovery-runtime.js +10 -2
- package/dist/gateway/server-discovery.js +2 -2
- package/dist/gateway/server-http.js +110 -12
- package/dist/gateway/server-methods/agent-timestamp.js +60 -0
- package/dist/gateway/server-methods/agents.js +321 -2
- package/dist/gateway/server-methods/usage.js +559 -16
- package/dist/gateway/server-runtime-state.js +22 -8
- package/dist/gateway/server-startup-memory.js +16 -0
- package/dist/gateway/server.impl.js +7 -3
- package/dist/gateway/session-utils.fs.js +23 -25
- package/dist/gateway/session-utils.js +20 -10
- package/dist/gateway/sessions-patch.js +7 -22
- package/dist/gateway/test-helpers.server.js +35 -2
- package/dist/hooks/frontmatter.js +1 -1
- package/dist/hooks/hooks-status.js +1 -1
- package/dist/hooks/install.js +2 -2
- package/dist/hooks/loader.js +1 -1
- package/dist/hooks/workspace.js +3 -3
- package/dist/imessage/constants.js +2 -0
- package/dist/imessage/monitor/deliver.js +4 -1
- package/dist/imessage/monitor/monitor-provider.js +51 -1
- package/dist/index.js +2 -2
- package/dist/infra/bonjour-discovery.js +131 -70
- package/dist/infra/bonjour.js +3 -3
- package/dist/infra/control-ui-assets.js +134 -12
- package/dist/infra/errors.js +12 -0
- package/dist/infra/exec-approvals.js +266 -57
- package/dist/infra/format-time/format-datetime.js +79 -0
- package/dist/infra/format-time/format-duration.js +81 -0
- package/dist/infra/format-time/format-relative.js +80 -0
- package/dist/infra/heartbeat-runner.js +140 -49
- package/dist/infra/home-dir.js +54 -0
- package/dist/infra/net/fetch-guard.js +122 -0
- package/dist/infra/net/ssrf.js +65 -29
- package/dist/infra/outbound/abort.js +14 -0
- package/dist/infra/outbound/message-action-runner.js +77 -13
- package/dist/infra/outbound/outbound-session.js +143 -37
- package/dist/infra/path-env.js +3 -3
- package/dist/infra/poolbot-root.js +43 -1
- package/dist/infra/provider-usage.fetch.minimax.js +1 -1
- package/dist/infra/restart.js +1 -1
- package/dist/infra/session-cost-usage.js +631 -41
- package/dist/infra/state-migrations.js +317 -47
- package/dist/infra/tailscale.js +1 -1
- package/dist/infra/update-global.js +35 -0
- package/dist/infra/update-runner.js +149 -43
- package/dist/infra/warning-filter.js +65 -0
- package/dist/infra/widearea-dns.js +30 -9
- package/dist/logging/redact-identifier.js +12 -0
- package/dist/macos/relay.js +2 -2
- package/dist/media/fetch.js +81 -58
- package/dist/media/input-files.js +1 -1
- package/dist/media/mime.js +4 -0
- package/dist/media/png-encode.js +74 -0
- package/dist/media-understanding/apply.js +403 -3
- package/dist/media-understanding/attachments.js +38 -27
- package/dist/media-understanding/defaults.js +16 -0
- package/dist/media-understanding/providers/deepgram/audio.js +22 -14
- package/dist/media-understanding/providers/google/audio.js +24 -17
- package/dist/media-understanding/providers/google/video.js +24 -17
- package/dist/media-understanding/providers/image.js +4 -4
- package/dist/media-understanding/providers/index.js +4 -1
- package/dist/media-understanding/providers/openai/audio.js +22 -14
- package/dist/media-understanding/providers/shared.js +16 -11
- package/dist/media-understanding/providers/zai/index.js +6 -0
- package/dist/media-understanding/runner.js +158 -90
- package/dist/memory/backend-config.js +207 -0
- package/dist/memory/batch-voyage.js +277 -0
- package/dist/memory/embeddings-voyage.js +75 -0
- package/dist/memory/embeddings.js +29 -17
- package/dist/memory/internal.js +101 -18
- package/dist/memory/manager.js +155 -48
- package/dist/memory/search-manager.js +173 -0
- package/dist/memory/session-files.js +9 -3
- package/dist/memory/types.js +1 -0
- package/dist/node-host/runner.js +36 -26
- package/dist/node-host/with-timeout.js +27 -0
- package/dist/pairing/pairing-messages.js +1 -1
- package/dist/plugins/commands.js +5 -1
- package/dist/plugins/config-state.js +86 -7
- package/dist/plugins/discovery.js +1 -1
- package/dist/plugins/install.js +2 -2
- package/dist/plugins/source-display.js +51 -0
- package/dist/plugins/update.js +1 -1
- package/dist/process/exec.js +20 -2
- package/dist/routing/resolve-route.js +12 -0
- package/dist/routing/session-key.js +15 -0
- package/dist/runtime.js +2 -0
- package/dist/security/audit-extra.async.js +601 -0
- package/dist/security/audit-extra.js +2 -830
- package/dist/security/audit-extra.sync.js +505 -0
- package/dist/security/audit.js +2 -2
- package/dist/security/channel-metadata.js +34 -0
- package/dist/security/external-content.js +88 -6
- package/dist/security/skill-scanner.js +330 -0
- package/dist/sessions/session-key-utils.js +7 -0
- package/dist/shared/text/reasoning-tags.js +52 -7
- package/dist/signal/monitor/event-handler.js +80 -1
- package/dist/slack/monitor/media.js +85 -15
- package/dist/tailscale/detect.js +145 -0
- package/dist/telegram/bot/helpers.js +109 -28
- package/dist/telegram/bot-handlers.js +144 -3
- package/dist/telegram/bot-message-context.js +38 -11
- package/dist/telegram/bot-message-dispatch.js +48 -15
- package/dist/telegram/bot-native-commands.js +86 -29
- package/dist/telegram/bot.js +30 -29
- package/dist/telegram/model-buttons.js +163 -0
- package/dist/telegram/monitor.js +110 -85
- package/dist/telegram/send.js +129 -47
- package/dist/terminal/restore.js +45 -0
- package/dist/test-helpers/state-dir-env.js +16 -0
- package/dist/test-helpers/workspace.js +11 -0
- package/dist/test-utils/channel-plugins.js +82 -0
- package/dist/test-utils/ports.js +73 -0
- package/dist/tts/tts.js +12 -6
- package/dist/tui/tui-session-actions.js +166 -54
- package/dist/utils/fetch-timeout.js +20 -0
- package/dist/utils/normalize-secret-input.js +19 -0
- package/dist/utils/shell-argv.js +61 -0
- package/dist/utils/transcript-tools.js +58 -0
- package/dist/utils.js +55 -14
- package/dist/version.js +42 -5
- package/dist/web/qr-image.js +1 -61
- package/dist/wizard/onboarding.finalize.js +7 -7
- package/dist/wizard/onboarding.js +3 -3
- package/docs/RELEASE_WORKFOTS_COMPARISON.md +3 -3
- package/docs/_config.yml +2 -2
- package/docs/_layouts/default.html +9 -9
- package/docs/concepts/typebox.md +1 -1
- package/docs/docs.json +1 -1
- package/docs/northflank.mdx +7 -7
- package/docs/railway.mdx +3 -3
- package/docs/render.mdx +5 -5
- package/docs/start/lore.md +2 -2
- package/extensions/bluebubbles/index.ts +2 -2
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/bluebubbles/src/accounts.ts +8 -8
- package/extensions/bluebubbles/src/actions.test.ts +22 -22
- package/extensions/bluebubbles/src/actions.ts +5 -5
- package/extensions/bluebubbles/src/attachments.ts +2 -2
- package/extensions/bluebubbles/src/channel.ts +16 -16
- package/extensions/bluebubbles/src/chat.ts +2 -2
- package/extensions/bluebubbles/src/media-send.ts +2 -2
- package/extensions/bluebubbles/src/monitor.test.ts +46 -46
- package/extensions/bluebubbles/src/monitor.ts +5 -5
- package/extensions/bluebubbles/src/onboarding.ts +7 -7
- package/extensions/bluebubbles/src/reactions.ts +2 -2
- package/extensions/bluebubbles/src/send.ts +2 -2
- package/extensions/copilot-proxy/README.md +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/diagnostics-otel/src/service.ts +3 -3
- package/extensions/discord/index.ts +2 -2
- package/extensions/discord/package.json +1 -1
- package/extensions/google-antigravity-auth/README.md +1 -1
- package/extensions/google-antigravity-auth/index.ts +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/README.md +1 -1
- package/extensions/google-gemini-cli-auth/oauth.ts +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/index.ts +3 -3
- package/extensions/googlechat/package.json +1 -1
- package/extensions/googlechat/src/accounts.ts +8 -8
- package/extensions/googlechat/src/actions.ts +6 -6
- package/extensions/googlechat/src/channel.ts +21 -21
- package/extensions/googlechat/src/monitor.ts +8 -8
- package/extensions/googlechat/src/onboarding.ts +10 -10
- package/extensions/imessage/index.ts +2 -2
- package/extensions/imessage/package.json +1 -1
- package/extensions/line/index.ts +2 -2
- package/extensions/line/package.json +1 -1
- package/extensions/line/src/card-command.ts +2 -2
- package/extensions/line/src/channel.logout.test.ts +4 -4
- package/extensions/line/src/channel.sendPayload.test.ts +8 -8
- package/extensions/line/src/channel.ts +3 -3
- package/extensions/llm-task/README.md +3 -3
- package/extensions/llm-task/index.ts +2 -2
- package/extensions/llm-task/package.json +1 -1
- package/extensions/llm-task/src/llm-task-tool.ts +4 -4
- package/extensions/lobster/README.md +6 -6
- package/extensions/lobster/index.ts +2 -2
- package/extensions/lobster/src/lobster-tool.test.ts +4 -4
- package/extensions/lobster/src/lobster-tool.ts +2 -2
- package/extensions/matrix/index.ts +2 -2
- package/extensions/matrix/package.json +1 -1
- package/extensions/matrix/src/matrix/client/config.ts +1 -1
- package/extensions/matrix/src/matrix/monitor/handler.ts +1 -1
- package/extensions/matrix/src/onboarding.ts +1 -1
- package/extensions/mattermost/index.ts +2 -2
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mattermost/src/mattermost/accounts.ts +8 -8
- package/extensions/mattermost/src/mattermost/monitor-helpers.ts +5 -5
- package/extensions/mattermost/src/mattermost/monitor.ts +2 -2
- package/extensions/mattermost/src/onboarding-helpers.ts +3 -3
- package/extensions/mattermost/src/onboarding.ts +2 -2
- package/extensions/memory-core/index.ts +2 -2
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/index.ts +3 -3
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/msteams/index.ts +2 -2
- package/extensions/msteams/package.json +1 -1
- package/extensions/msteams/src/channel.directory.test.ts +2 -2
- package/extensions/msteams/src/channel.ts +2 -2
- package/extensions/msteams/src/graph-upload.ts +4 -4
- package/extensions/msteams/src/monitor-handler.ts +2 -2
- package/extensions/msteams/src/monitor.ts +2 -2
- package/extensions/msteams/src/onboarding.ts +9 -9
- package/extensions/msteams/src/reply-dispatcher.ts +2 -2
- package/extensions/msteams/src/send-context.ts +2 -2
- package/extensions/msteams/src/send.ts +4 -4
- package/extensions/nextcloud-talk/index.ts +2 -2
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nextcloud-talk/src/channel.ts +7 -7
- package/extensions/nextcloud-talk/src/inbound.ts +7 -7
- package/extensions/nextcloud-talk/src/onboarding.ts +1 -1
- package/extensions/nostr/README.md +2 -2
- package/extensions/nostr/index.ts +5 -5
- package/extensions/nostr/package.json +1 -1
- package/extensions/nostr/src/types.ts +4 -4
- package/extensions/open-prose/index.ts +2 -2
- package/extensions/qwen-portal-auth/README.md +1 -1
- package/extensions/signal/index.ts +2 -2
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/index.ts +2 -2
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/index.ts +2 -2
- package/extensions/telegram/package.json +1 -1
- package/extensions/telegram/src/channel.ts +2 -2
- package/extensions/tlon/README.md +2 -2
- package/extensions/tlon/index.ts +2 -2
- package/extensions/tlon/package.json +1 -1
- package/extensions/tlon/src/channel.ts +13 -13
- package/extensions/tlon/src/monitor/index.ts +3 -3
- package/extensions/tlon/src/onboarding.ts +3 -3
- package/extensions/tlon/src/types.ts +3 -3
- package/extensions/twitch/README.md +1 -1
- package/extensions/twitch/index.ts +2 -2
- package/extensions/twitch/package.json +1 -1
- package/extensions/twitch/src/config.ts +3 -3
- package/extensions/twitch/src/monitor.ts +3 -3
- package/extensions/twitch/src/onboarding.ts +9 -9
- package/extensions/twitch/src/outbound.test.ts +2 -2
- package/extensions/twitch/src/plugin.test.ts +2 -2
- package/extensions/twitch/src/plugin.ts +8 -8
- package/extensions/twitch/src/send.test.ts +2 -2
- package/extensions/twitch/src/send.ts +4 -4
- package/extensions/twitch/src/token.test.ts +8 -8
- package/extensions/twitch/src/token.ts +3 -3
- package/extensions/twitch/src/twitch-client.ts +3 -3
- package/extensions/twitch/src/types.ts +3 -3
- package/extensions/twitch/src/utils/markdown.ts +1 -1
- package/extensions/voice-call/README.md +3 -3
- package/extensions/voice-call/package.json +1 -1
- package/extensions/voice-call/src/core-bridge.ts +2 -2
- package/extensions/voice-call/src/response-generator.ts +1 -1
- package/extensions/whatsapp/index.ts +2 -2
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/README.md +1 -1
- package/extensions/zalo/index.ts +2 -2
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalo/src/accounts.ts +8 -8
- package/extensions/zalo/src/actions.ts +4 -4
- package/extensions/zalo/src/channel.directory.test.ts +2 -2
- package/extensions/zalo/src/channel.ts +18 -18
- package/extensions/zalo/src/monitor.ts +9 -9
- package/extensions/zalo/src/monitor.webhook.test.ts +2 -2
- package/extensions/zalo/src/onboarding.ts +24 -24
- package/extensions/zalo/src/send.ts +2 -2
- package/extensions/zalouser/README.md +2 -2
- package/extensions/zalouser/index.ts +2 -2
- package/extensions/zalouser/package.json +1 -1
- package/extensions/zalouser/src/accounts.ts +9 -9
- package/extensions/zalouser/src/channel.ts +24 -24
- package/extensions/zalouser/src/monitor.ts +4 -4
- package/extensions/zalouser/src/onboarding.ts +28 -28
- package/package.json +13 -251
- package/skills/nano-banana-pro/scripts/generate_image.py +1 -1
- package/skills/tmux/scripts/find-sessions.sh +1 -1
- package/CHANGELOG.md +0 -102
- package/README-header.png +0 -0
- package/git-hooks/pre-commit +0 -4
- package/scripts/format-staged.js +0 -148
- package/scripts/postinstall.js +0 -300
- package/scripts/setup-git-hooks.js +0 -96
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { clearActiveProgressLine } from "./progress-line.js";
|
|
2
|
+
const RESET_SEQUENCE = "\x1b[0m\x1b[?25h\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?2004l";
|
|
3
|
+
function reportRestoreFailure(scope, err, reason) {
|
|
4
|
+
const suffix = reason ? ` (${reason})` : "";
|
|
5
|
+
const message = `[terminal] restore ${scope} failed${suffix}: ${String(err)}`;
|
|
6
|
+
try {
|
|
7
|
+
process.stderr.write(`${message}\n`);
|
|
8
|
+
}
|
|
9
|
+
catch (writeErr) {
|
|
10
|
+
console.error(`[terminal] restore reporting failed${suffix}: ${String(writeErr)}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function restoreTerminalState(reason) {
|
|
14
|
+
try {
|
|
15
|
+
clearActiveProgressLine();
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
reportRestoreFailure("progress line", err, reason);
|
|
19
|
+
}
|
|
20
|
+
const stdin = process.stdin;
|
|
21
|
+
if (stdin.isTTY && typeof stdin.setRawMode === "function") {
|
|
22
|
+
try {
|
|
23
|
+
stdin.setRawMode(false);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
reportRestoreFailure("raw mode", err, reason);
|
|
27
|
+
}
|
|
28
|
+
if (typeof stdin.isPaused === "function" && stdin.isPaused()) {
|
|
29
|
+
try {
|
|
30
|
+
stdin.resume();
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
reportRestoreFailure("stdin resume", err, reason);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (process.stdout.isTTY) {
|
|
38
|
+
try {
|
|
39
|
+
process.stdout.write(RESET_SEQUENCE);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
reportRestoreFailure("stdout reset", err, reason);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function snapshotStateDirEnv() {
|
|
2
|
+
return {
|
|
3
|
+
clawdbotStateDir: process.env.CLAWDBOT_STATE_DIR,
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
export function restoreStateDirEnv(snapshot) {
|
|
7
|
+
if (snapshot.clawdbotStateDir === undefined) {
|
|
8
|
+
delete process.env.CLAWDBOT_STATE_DIR;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
process.env.CLAWDBOT_STATE_DIR = snapshot.clawdbotStateDir;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function setStateDirEnv(stateDir) {
|
|
15
|
+
process.env.CLAWDBOT_STATE_DIR = stateDir;
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
export async function makeTempWorkspace(prefix = "poolbot-workspace-") {
|
|
5
|
+
return fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
|
6
|
+
}
|
|
7
|
+
export async function writeWorkspaceFile(params) {
|
|
8
|
+
const filePath = path.join(params.dir, params.name);
|
|
9
|
+
await fs.writeFile(filePath, params.content, "utf-8");
|
|
10
|
+
return filePath;
|
|
11
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { imessageOutbound } from "../channels/plugins/outbound/imessage.js";
|
|
2
|
+
import { normalizeIMessageHandle } from "../imessage/targets.js";
|
|
3
|
+
export const createTestRegistry = (channels = []) => ({
|
|
4
|
+
plugins: [],
|
|
5
|
+
tools: [],
|
|
6
|
+
hooks: [],
|
|
7
|
+
typedHooks: [],
|
|
8
|
+
channels,
|
|
9
|
+
providers: [],
|
|
10
|
+
gatewayHandlers: {},
|
|
11
|
+
httpHandlers: [],
|
|
12
|
+
httpRoutes: [],
|
|
13
|
+
cliRegistrars: [],
|
|
14
|
+
services: [],
|
|
15
|
+
commands: [],
|
|
16
|
+
diagnostics: [],
|
|
17
|
+
});
|
|
18
|
+
export const createIMessageTestPlugin = (params) => ({
|
|
19
|
+
id: "imessage",
|
|
20
|
+
meta: {
|
|
21
|
+
id: "imessage",
|
|
22
|
+
label: "iMessage",
|
|
23
|
+
selectionLabel: "iMessage (imsg)",
|
|
24
|
+
docsPath: "/channels/imessage",
|
|
25
|
+
blurb: "iMessage test stub.",
|
|
26
|
+
aliases: ["imsg"],
|
|
27
|
+
},
|
|
28
|
+
capabilities: { chatTypes: ["direct", "group"], media: true },
|
|
29
|
+
config: {
|
|
30
|
+
listAccountIds: () => [],
|
|
31
|
+
resolveAccount: () => ({}),
|
|
32
|
+
},
|
|
33
|
+
status: {
|
|
34
|
+
collectStatusIssues: (accounts) => accounts.flatMap((account) => {
|
|
35
|
+
const lastError = typeof account.lastError === "string" ? account.lastError.trim() : "";
|
|
36
|
+
if (!lastError)
|
|
37
|
+
return [];
|
|
38
|
+
return [
|
|
39
|
+
{
|
|
40
|
+
channel: "imessage",
|
|
41
|
+
accountId: account.accountId,
|
|
42
|
+
kind: "runtime",
|
|
43
|
+
message: `Channel error: ${lastError}`,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}),
|
|
47
|
+
},
|
|
48
|
+
outbound: params?.outbound ?? imessageOutbound,
|
|
49
|
+
messaging: {
|
|
50
|
+
targetResolver: {
|
|
51
|
+
looksLikeId: (raw) => {
|
|
52
|
+
const trimmed = raw.trim();
|
|
53
|
+
if (!trimmed)
|
|
54
|
+
return false;
|
|
55
|
+
if (/^(imessage:|sms:|auto:|chat_id:|chat_guid:|chat_identifier:)/i.test(trimmed)) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
if (trimmed.includes("@"))
|
|
59
|
+
return true;
|
|
60
|
+
return /^\+?\d{3,}$/.test(trimmed);
|
|
61
|
+
},
|
|
62
|
+
hint: "<handle|chat_id:ID>",
|
|
63
|
+
},
|
|
64
|
+
normalizeTarget: (raw) => normalizeIMessageHandle(raw),
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
export const createOutboundTestPlugin = (params) => ({
|
|
68
|
+
id: params.id,
|
|
69
|
+
meta: {
|
|
70
|
+
id: params.id,
|
|
71
|
+
label: params.label ?? String(params.id),
|
|
72
|
+
selectionLabel: params.label ?? String(params.id),
|
|
73
|
+
docsPath: params.docsPath ?? `/channels/${params.id}`,
|
|
74
|
+
blurb: "test stub.",
|
|
75
|
+
},
|
|
76
|
+
capabilities: params.capabilities ?? { chatTypes: ["direct"] },
|
|
77
|
+
config: {
|
|
78
|
+
listAccountIds: () => [],
|
|
79
|
+
resolveAccount: () => ({}),
|
|
80
|
+
},
|
|
81
|
+
outbound: params.outbound,
|
|
82
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createServer } from "node:net";
|
|
2
|
+
import { isMainThread, threadId } from "node:worker_threads";
|
|
3
|
+
async function isPortFree(port) {
|
|
4
|
+
if (!Number.isFinite(port) || port <= 0 || port > 65535)
|
|
5
|
+
return false;
|
|
6
|
+
return await new Promise((resolve) => {
|
|
7
|
+
const server = createServer();
|
|
8
|
+
server.once("error", () => resolve(false));
|
|
9
|
+
server.listen(port, "127.0.0.1", () => {
|
|
10
|
+
server.close(() => resolve(true));
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
async function getOsFreePort() {
|
|
15
|
+
return await new Promise((resolve, reject) => {
|
|
16
|
+
const server = createServer();
|
|
17
|
+
server.once("error", reject);
|
|
18
|
+
server.listen(0, "127.0.0.1", () => {
|
|
19
|
+
const addr = server.address();
|
|
20
|
+
if (!addr || typeof addr === "string") {
|
|
21
|
+
server.close();
|
|
22
|
+
reject(new Error("failed to acquire free port"));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const port = addr.port;
|
|
26
|
+
server.close((err) => (err ? reject(err) : resolve(port)));
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
let nextTestPortOffset = 0;
|
|
31
|
+
/**
|
|
32
|
+
* Allocate a deterministic per-worker port block.
|
|
33
|
+
*
|
|
34
|
+
* Motivation: many tests spin up gateway + related services that use derived ports
|
|
35
|
+
* (e.g. +1/+2/+3/+4). If each test just grabs an OS free port, parallel test runs
|
|
36
|
+
* can collide on derived ports and get flaky EADDRINUSE.
|
|
37
|
+
*/
|
|
38
|
+
export async function getDeterministicFreePortBlock(params) {
|
|
39
|
+
const offsets = params?.offsets ?? [0, 1, 2, 3, 4];
|
|
40
|
+
const maxOffset = Math.max(...offsets);
|
|
41
|
+
const workerIdRaw = process.env.VITEST_WORKER_ID ?? process.env.VITEST_POOL_ID ?? "";
|
|
42
|
+
const workerId = Number.parseInt(workerIdRaw, 10);
|
|
43
|
+
const shard = Number.isFinite(workerId)
|
|
44
|
+
? Math.max(0, workerId)
|
|
45
|
+
: isMainThread
|
|
46
|
+
? Math.abs(process.pid)
|
|
47
|
+
: Math.abs(threadId);
|
|
48
|
+
const rangeSize = 1000;
|
|
49
|
+
const shardCount = 30;
|
|
50
|
+
const base = 30_000 + (Math.abs(shard) % shardCount) * rangeSize; // <= 59_999
|
|
51
|
+
const usable = rangeSize - maxOffset;
|
|
52
|
+
// Allocate in blocks to avoid derived-port overlaps (e.g. port+3).
|
|
53
|
+
const blockSize = Math.max(maxOffset + 1, 8);
|
|
54
|
+
for (let attempt = 0; attempt < usable; attempt += 1) {
|
|
55
|
+
const start = base + ((nextTestPortOffset + attempt) % usable);
|
|
56
|
+
// eslint-disable-next-line no-await-in-loop
|
|
57
|
+
const ok = (await Promise.all(offsets.map((offset) => isPortFree(start + offset)))).every(Boolean);
|
|
58
|
+
if (!ok)
|
|
59
|
+
continue;
|
|
60
|
+
nextTestPortOffset = (nextTestPortOffset + attempt + blockSize) % usable;
|
|
61
|
+
return start;
|
|
62
|
+
}
|
|
63
|
+
// Fallback: let the OS pick a port block (best effort).
|
|
64
|
+
for (let attempt = 0; attempt < 25; attempt += 1) {
|
|
65
|
+
// eslint-disable-next-line no-await-in-loop
|
|
66
|
+
const port = await getOsFreePort();
|
|
67
|
+
// eslint-disable-next-line no-await-in-loop
|
|
68
|
+
const ok = (await Promise.all(offsets.map((offset) => isPortFree(port + offset)))).every(Boolean);
|
|
69
|
+
if (ok)
|
|
70
|
+
return port;
|
|
71
|
+
}
|
|
72
|
+
throw new Error("failed to acquire a free port block");
|
|
73
|
+
}
|
package/dist/tts/tts.js
CHANGED
|
@@ -579,9 +579,15 @@ export const OPENAI_TTS_MODELS = ["gpt-4o-mini-tts", "tts-1", "tts-1-hd"];
|
|
|
579
579
|
* Custom OpenAI-compatible TTS endpoint.
|
|
580
580
|
* When set, model/voice validation is relaxed to allow non-OpenAI models.
|
|
581
581
|
* Example: OPENAI_TTS_BASE_URL=http://localhost:8880/v1
|
|
582
|
+
*
|
|
583
|
+
* Note: Read at runtime (not module load) to support config.env loading.
|
|
582
584
|
*/
|
|
583
|
-
|
|
584
|
-
|
|
585
|
+
function getOpenAITtsBaseUrl() {
|
|
586
|
+
return (process.env.OPENAI_TTS_BASE_URL?.trim() || "https://api.openai.com/v1").replace(/\/+$/, "");
|
|
587
|
+
}
|
|
588
|
+
function isCustomOpenAIEndpoint() {
|
|
589
|
+
return getOpenAITtsBaseUrl() !== "https://api.openai.com/v1";
|
|
590
|
+
}
|
|
585
591
|
export const OPENAI_TTS_VOICES = [
|
|
586
592
|
"alloy",
|
|
587
593
|
"ash",
|
|
@@ -595,13 +601,13 @@ export const OPENAI_TTS_VOICES = [
|
|
|
595
601
|
];
|
|
596
602
|
function isValidOpenAIModel(model) {
|
|
597
603
|
// Allow any model when using custom endpoint (e.g., Kokoro, LocalAI)
|
|
598
|
-
if (isCustomOpenAIEndpoint)
|
|
604
|
+
if (isCustomOpenAIEndpoint())
|
|
599
605
|
return true;
|
|
600
606
|
return OPENAI_TTS_MODELS.includes(model);
|
|
601
607
|
}
|
|
602
608
|
function isValidOpenAIVoice(voice) {
|
|
603
609
|
// Allow any voice when using custom endpoint (e.g., Kokoro Chinese voices)
|
|
604
|
-
if (isCustomOpenAIEndpoint)
|
|
610
|
+
if (isCustomOpenAIEndpoint())
|
|
605
611
|
return true;
|
|
606
612
|
return OPENAI_TTS_VOICES.includes(voice);
|
|
607
613
|
}
|
|
@@ -679,7 +685,7 @@ async function summarizeText(params) {
|
|
|
679
685
|
catch (err) {
|
|
680
686
|
const error = err;
|
|
681
687
|
if (error.name === "AbortError") {
|
|
682
|
-
throw new Error("Summarization timed out");
|
|
688
|
+
throw new Error("Summarization timed out", { cause: err });
|
|
683
689
|
}
|
|
684
690
|
throw err;
|
|
685
691
|
}
|
|
@@ -754,7 +760,7 @@ async function openaiTTS(params) {
|
|
|
754
760
|
const controller = new AbortController();
|
|
755
761
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
756
762
|
try {
|
|
757
|
-
const response = await fetch(`${
|
|
763
|
+
const response = await fetch(`${getOpenAITtsBaseUrl()}/audio/speech`, {
|
|
758
764
|
method: "POST",
|
|
759
765
|
headers: {
|
|
760
766
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { normalizeAgentId, normalizeMainKey, parseAgentSessionKey, } from "../routing/session-key.js";
|
|
2
2
|
import { asString, extractTextFromMessage, isCommandMessage } from "./tui-formatters.js";
|
|
3
3
|
export function createSessionActions(context) {
|
|
4
|
-
const { client, chatLog, tui, opts, state, agentNames, initialSessionInput, initialSessionAgentId, resolveSessionKey, updateHeader, updateFooter, updateAutocompleteProvider, setActivityStatus, } = context;
|
|
5
|
-
let refreshSessionInfoPromise =
|
|
4
|
+
const { client, chatLog, tui, opts, state, agentNames, initialSessionInput, initialSessionAgentId, resolveSessionKey, updateHeader, updateFooter, updateAutocompleteProvider, setActivityStatus, clearLocalRunIds, } = context;
|
|
5
|
+
let refreshSessionInfoPromise = Promise.resolve();
|
|
6
|
+
let lastSessionDefaults = null;
|
|
6
7
|
const applyAgentsResult = (result) => {
|
|
7
8
|
state.agentDefaultId = normalizeAgentId(result.defaultId);
|
|
8
9
|
state.sessionMainKey = normalizeMainKey(result.mainKey);
|
|
@@ -13,8 +14,9 @@ export function createSessionActions(context) {
|
|
|
13
14
|
}));
|
|
14
15
|
agentNames.clear();
|
|
15
16
|
for (const agent of state.agents) {
|
|
16
|
-
if (agent.name)
|
|
17
|
+
if (agent.name) {
|
|
17
18
|
agentNames.set(agent.id, agent.name);
|
|
19
|
+
}
|
|
18
20
|
}
|
|
19
21
|
if (!state.initialSessionApplied) {
|
|
20
22
|
if (initialSessionAgentId) {
|
|
@@ -50,62 +52,161 @@ export function createSessionActions(context) {
|
|
|
50
52
|
};
|
|
51
53
|
const updateAgentFromSessionKey = (key) => {
|
|
52
54
|
const parsed = parseAgentSessionKey(key);
|
|
53
|
-
if (!parsed)
|
|
55
|
+
if (!parsed) {
|
|
54
56
|
return;
|
|
57
|
+
}
|
|
55
58
|
const next = normalizeAgentId(parsed.agentId);
|
|
56
59
|
if (next !== state.currentAgentId) {
|
|
57
60
|
state.currentAgentId = next;
|
|
58
61
|
}
|
|
59
62
|
};
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
63
|
+
const resolveModelSelection = (entry) => {
|
|
64
|
+
if (entry?.modelProvider || entry?.model) {
|
|
65
|
+
return {
|
|
66
|
+
modelProvider: entry.modelProvider ?? state.sessionInfo.modelProvider,
|
|
67
|
+
model: entry.model ?? state.sessionInfo.model,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const overrideModel = entry?.modelOverride?.trim();
|
|
71
|
+
if (overrideModel) {
|
|
72
|
+
const overrideProvider = entry?.providerOverride?.trim() || state.sessionInfo.modelProvider;
|
|
73
|
+
return { modelProvider: overrideProvider, model: overrideModel };
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
modelProvider: state.sessionInfo.modelProvider,
|
|
77
|
+
model: state.sessionInfo.model,
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const applySessionInfo = (params) => {
|
|
81
|
+
const entry = params.entry ?? undefined;
|
|
82
|
+
const defaults = params.defaults ?? lastSessionDefaults ?? undefined;
|
|
83
|
+
const previousDefaults = lastSessionDefaults;
|
|
84
|
+
const defaultsChanged = params.defaults
|
|
85
|
+
? previousDefaults?.model !== params.defaults.model ||
|
|
86
|
+
previousDefaults?.modelProvider !== params.defaults.modelProvider ||
|
|
87
|
+
previousDefaults?.contextTokens !== params.defaults.contextTokens
|
|
88
|
+
: false;
|
|
89
|
+
if (params.defaults) {
|
|
90
|
+
lastSessionDefaults = params.defaults;
|
|
91
|
+
}
|
|
92
|
+
const entryUpdatedAt = entry?.updatedAt ?? null;
|
|
93
|
+
const currentUpdatedAt = state.sessionInfo.updatedAt ?? null;
|
|
94
|
+
const modelChanged = (entry?.modelProvider !== undefined &&
|
|
95
|
+
entry.modelProvider !== state.sessionInfo.modelProvider) ||
|
|
96
|
+
(entry?.model !== undefined && entry.model !== state.sessionInfo.model);
|
|
97
|
+
if (!params.force &&
|
|
98
|
+
entryUpdatedAt !== null &&
|
|
99
|
+
currentUpdatedAt !== null &&
|
|
100
|
+
entryUpdatedAt < currentUpdatedAt &&
|
|
101
|
+
!defaultsChanged &&
|
|
102
|
+
!modelChanged) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const next = { ...state.sessionInfo };
|
|
106
|
+
if (entry?.thinkingLevel !== undefined) {
|
|
107
|
+
next.thinkingLevel = entry.thinkingLevel;
|
|
108
|
+
}
|
|
109
|
+
if (entry?.verboseLevel !== undefined) {
|
|
110
|
+
next.verboseLevel = entry.verboseLevel;
|
|
111
|
+
}
|
|
112
|
+
if (entry?.reasoningLevel !== undefined) {
|
|
113
|
+
next.reasoningLevel = entry.reasoningLevel;
|
|
114
|
+
}
|
|
115
|
+
if (entry?.responseUsage !== undefined) {
|
|
116
|
+
next.responseUsage = entry.responseUsage;
|
|
117
|
+
}
|
|
118
|
+
if (entry?.inputTokens !== undefined) {
|
|
119
|
+
next.inputTokens = entry.inputTokens;
|
|
120
|
+
}
|
|
121
|
+
if (entry?.outputTokens !== undefined) {
|
|
122
|
+
next.outputTokens = entry.outputTokens;
|
|
123
|
+
}
|
|
124
|
+
if (entry?.totalTokens !== undefined) {
|
|
125
|
+
next.totalTokens = entry.totalTokens;
|
|
126
|
+
}
|
|
127
|
+
if (entry?.contextTokens !== undefined || defaults?.contextTokens !== undefined) {
|
|
128
|
+
next.contextTokens =
|
|
129
|
+
entry?.contextTokens ?? defaults?.contextTokens ?? state.sessionInfo.contextTokens;
|
|
130
|
+
}
|
|
131
|
+
if (entry?.displayName !== undefined) {
|
|
132
|
+
next.displayName = entry.displayName;
|
|
133
|
+
}
|
|
134
|
+
if (entry?.updatedAt !== undefined) {
|
|
135
|
+
next.updatedAt = entry.updatedAt;
|
|
136
|
+
}
|
|
137
|
+
const selection = resolveModelSelection(entry);
|
|
138
|
+
if (selection.modelProvider !== undefined) {
|
|
139
|
+
next.modelProvider = selection.modelProvider;
|
|
140
|
+
}
|
|
141
|
+
if (selection.model !== undefined) {
|
|
142
|
+
next.model = selection.model;
|
|
143
|
+
}
|
|
144
|
+
state.sessionInfo = next;
|
|
145
|
+
updateAutocompleteProvider();
|
|
146
|
+
updateFooter();
|
|
147
|
+
tui.requestRender();
|
|
148
|
+
};
|
|
149
|
+
const runRefreshSessionInfo = async () => {
|
|
103
150
|
try {
|
|
104
|
-
|
|
151
|
+
const resolveListAgentId = () => {
|
|
152
|
+
if (state.currentSessionKey === "global" || state.currentSessionKey === "unknown") {
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
const parsed = parseAgentSessionKey(state.currentSessionKey);
|
|
156
|
+
return parsed?.agentId ? normalizeAgentId(parsed.agentId) : state.currentAgentId;
|
|
157
|
+
};
|
|
158
|
+
const listAgentId = resolveListAgentId();
|
|
159
|
+
const result = await client.listSessions({
|
|
160
|
+
includeGlobal: false,
|
|
161
|
+
includeUnknown: false,
|
|
162
|
+
agentId: listAgentId,
|
|
163
|
+
});
|
|
164
|
+
const normalizeMatchKey = (key) => parseAgentSessionKey(key)?.rest ?? key;
|
|
165
|
+
const currentMatchKey = normalizeMatchKey(state.currentSessionKey);
|
|
166
|
+
const entry = result.sessions.find((row) => {
|
|
167
|
+
// Exact match
|
|
168
|
+
if (row.key === state.currentSessionKey) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
// Also match canonical keys like "agent:default:main" against "main"
|
|
172
|
+
return normalizeMatchKey(row.key) === currentMatchKey;
|
|
173
|
+
});
|
|
174
|
+
if (entry?.key && entry.key !== state.currentSessionKey) {
|
|
175
|
+
updateAgentFromSessionKey(entry.key);
|
|
176
|
+
state.currentSessionKey = entry.key;
|
|
177
|
+
updateHeader();
|
|
178
|
+
}
|
|
179
|
+
applySessionInfo({
|
|
180
|
+
entry,
|
|
181
|
+
defaults: result.defaults,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
chatLog.addSystem(`sessions list failed: ${String(err)}`);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const refreshSessionInfo = async () => {
|
|
189
|
+
refreshSessionInfoPromise = refreshSessionInfoPromise.then(runRefreshSessionInfo, runRefreshSessionInfo);
|
|
190
|
+
await refreshSessionInfoPromise;
|
|
191
|
+
};
|
|
192
|
+
const applySessionInfoFromPatch = (result) => {
|
|
193
|
+
if (!result?.entry) {
|
|
194
|
+
return;
|
|
105
195
|
}
|
|
106
|
-
|
|
107
|
-
|
|
196
|
+
if (result.key && result.key !== state.currentSessionKey) {
|
|
197
|
+
updateAgentFromSessionKey(result.key);
|
|
198
|
+
state.currentSessionKey = result.key;
|
|
199
|
+
updateHeader();
|
|
108
200
|
}
|
|
201
|
+
const resolved = result.resolved;
|
|
202
|
+
const entry = resolved && (resolved.modelProvider || resolved.model)
|
|
203
|
+
? {
|
|
204
|
+
...result.entry,
|
|
205
|
+
modelProvider: resolved.modelProvider ?? result.entry.modelProvider,
|
|
206
|
+
model: resolved.model ?? result.entry.model,
|
|
207
|
+
}
|
|
208
|
+
: result.entry;
|
|
209
|
+
applySessionInfo({ entry, force: true });
|
|
109
210
|
};
|
|
110
211
|
const loadHistory = async () => {
|
|
111
212
|
try {
|
|
@@ -116,33 +217,42 @@ export function createSessionActions(context) {
|
|
|
116
217
|
const record = history;
|
|
117
218
|
state.currentSessionId = typeof record.sessionId === "string" ? record.sessionId : null;
|
|
118
219
|
state.sessionInfo.thinkingLevel = record.thinkingLevel ?? state.sessionInfo.thinkingLevel;
|
|
220
|
+
state.sessionInfo.verboseLevel = record.verboseLevel ?? state.sessionInfo.verboseLevel;
|
|
221
|
+
const showTools = (state.sessionInfo.verboseLevel ?? "off") !== "off";
|
|
119
222
|
chatLog.clearAll();
|
|
120
223
|
chatLog.addSystem(`session ${state.currentSessionKey}`);
|
|
121
224
|
for (const entry of record.messages ?? []) {
|
|
122
|
-
if (!entry || typeof entry !== "object")
|
|
225
|
+
if (!entry || typeof entry !== "object") {
|
|
123
226
|
continue;
|
|
227
|
+
}
|
|
124
228
|
const message = entry;
|
|
125
229
|
if (isCommandMessage(message)) {
|
|
126
230
|
const text = extractTextFromMessage(message);
|
|
127
|
-
if (text)
|
|
231
|
+
if (text) {
|
|
128
232
|
chatLog.addSystem(text);
|
|
233
|
+
}
|
|
129
234
|
continue;
|
|
130
235
|
}
|
|
131
236
|
if (message.role === "user") {
|
|
132
237
|
const text = extractTextFromMessage(message);
|
|
133
|
-
if (text)
|
|
238
|
+
if (text) {
|
|
134
239
|
chatLog.addUser(text);
|
|
240
|
+
}
|
|
135
241
|
continue;
|
|
136
242
|
}
|
|
137
243
|
if (message.role === "assistant") {
|
|
138
244
|
const text = extractTextFromMessage(message, {
|
|
139
245
|
includeThinking: state.showThinking,
|
|
140
246
|
});
|
|
141
|
-
if (text)
|
|
247
|
+
if (text) {
|
|
142
248
|
chatLog.finalizeAssistant(text);
|
|
249
|
+
}
|
|
143
250
|
continue;
|
|
144
251
|
}
|
|
145
252
|
if (message.role === "toolResult") {
|
|
253
|
+
if (!showTools) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
146
256
|
const toolCallId = asString(message.toolCallId, "");
|
|
147
257
|
const toolName = asString(message.toolName, "tool");
|
|
148
258
|
const component = chatLog.startTool(toolCallId, toolName, {});
|
|
@@ -171,6 +281,7 @@ export function createSessionActions(context) {
|
|
|
171
281
|
state.activeChatRunId = null;
|
|
172
282
|
state.currentSessionId = null;
|
|
173
283
|
state.historyLoaded = false;
|
|
284
|
+
clearLocalRunIds?.();
|
|
174
285
|
updateHeader();
|
|
175
286
|
updateFooter();
|
|
176
287
|
await loadHistory();
|
|
@@ -198,6 +309,7 @@ export function createSessionActions(context) {
|
|
|
198
309
|
applyAgentsResult,
|
|
199
310
|
refreshAgents,
|
|
200
311
|
refreshSessionInfo,
|
|
312
|
+
applySessionInfoFromPatch,
|
|
201
313
|
loadHistory,
|
|
202
314
|
setSession,
|
|
203
315
|
abortActive,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch wrapper that adds timeout support via AbortController.
|
|
3
|
+
*
|
|
4
|
+
* @param url - The URL to fetch
|
|
5
|
+
* @param init - RequestInit options (headers, method, body, etc.)
|
|
6
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
7
|
+
* @param fetchFn - The fetch implementation to use (defaults to global fetch)
|
|
8
|
+
* @returns The fetch Response
|
|
9
|
+
* @throws AbortError if the request times out
|
|
10
|
+
*/
|
|
11
|
+
export async function fetchWithTimeout(url, init, timeoutMs, fetchFn = fetch) {
|
|
12
|
+
const controller = new AbortController();
|
|
13
|
+
const timer = setTimeout(() => controller.abort(), Math.max(1, timeoutMs));
|
|
14
|
+
try {
|
|
15
|
+
return await fetchFn(url, { ...init, signal: controller.signal });
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
clearTimeout(timer);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret normalization for copy/pasted credentials.
|
|
3
|
+
*
|
|
4
|
+
* Common footgun: line breaks (especially `\r`) embedded in API keys/tokens.
|
|
5
|
+
* We strip line breaks anywhere, then trim whitespace at the ends.
|
|
6
|
+
*
|
|
7
|
+
* Intentionally does NOT remove ordinary spaces inside the string to avoid
|
|
8
|
+
* silently altering "Bearer <token>" style values.
|
|
9
|
+
*/
|
|
10
|
+
export function normalizeSecretInput(value) {
|
|
11
|
+
if (typeof value !== "string") {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
return value.replace(/[\r\n\u2028\u2029]+/g, "").trim();
|
|
15
|
+
}
|
|
16
|
+
export function normalizeOptionalSecretInput(value) {
|
|
17
|
+
const normalized = normalizeSecretInput(value);
|
|
18
|
+
return normalized ? normalized : undefined;
|
|
19
|
+
}
|