@poolzin/pool-bot 2026.2.11 → 2026.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/dist/agents/agent-scope.js +4 -0
- package/dist/agents/announce-idempotency.js +14 -0
- package/dist/agents/auth-profiles/usage.js +22 -0
- package/dist/agents/auth-profiles.js +1 -1
- package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +23 -0
- package/dist/agents/bash-tools.exec-runtime.js +438 -0
- package/dist/agents/bash-tools.shared.js +6 -0
- package/dist/agents/cli-runner/reliability.js +61 -0
- package/dist/agents/cli-watchdog-defaults.js +11 -0
- package/dist/agents/command-poll-backoff.js +63 -0
- package/dist/agents/current-time.js +16 -0
- package/dist/agents/glob-pattern.js +42 -0
- package/dist/agents/memory-search.js +33 -0
- package/dist/agents/model-alias-lines.js +18 -0
- package/dist/agents/model-auth-label.js +61 -0
- package/dist/agents/model-fallback.js +59 -8
- package/dist/agents/models-config.e2e-harness.js +115 -0
- package/dist/agents/ollama-stream.js +11 -3
- package/dist/agents/openclaw-tools.js +135 -0
- package/dist/agents/pi-auth-json.js +118 -0
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +147 -0
- package/dist/agents/pi-embedded-subscribe.e2e-harness.js +90 -0
- package/dist/agents/pi-embedded-subscribe.handlers.compaction.js +63 -0
- package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +30 -0
- package/dist/agents/pi-extensions/session-manager-runtime-registry.js +23 -0
- package/dist/agents/pi-tools.before-tool-call.js +145 -4
- package/dist/agents/pi-tools.js +29 -9
- package/dist/agents/pi-tools.policy.js +85 -92
- package/dist/agents/pi-tools.schema.js +54 -27
- package/dist/agents/queued-file-writer.js +22 -0
- package/dist/agents/sandbox/docker.js +133 -40
- package/dist/agents/sandbox/fs-bridge.js +146 -0
- package/dist/agents/sandbox/fs-paths.js +205 -0
- package/dist/agents/sandbox/hash.js +4 -0
- package/dist/agents/sandbox/validate-sandbox-security.js +157 -0
- package/dist/agents/sandbox-paths.js +3 -0
- package/dist/agents/sandbox-tool-policy.js +26 -0
- package/dist/agents/sanitize-for-prompt.js +18 -0
- package/dist/agents/session-dirs.js +20 -0
- package/dist/agents/session-write-lock.js +203 -39
- package/dist/agents/skills/filter.js +24 -0
- package/dist/agents/skills/tools-dir.js +9 -0
- package/dist/agents/skills-install-download.js +290 -0
- package/dist/agents/skills-install-output.js +30 -0
- package/dist/agents/skills-install.download-test-utils.js +36 -0
- package/dist/agents/skills.e2e-test-helpers.js +13 -0
- package/dist/agents/subagent-announce-queue.js +59 -15
- package/dist/agents/subagent-depth.js +137 -0
- package/dist/agents/subagent-registry.js +448 -96
- package/dist/agents/subagent-spawn.js +262 -0
- package/dist/agents/system-prompt.js +52 -10
- package/dist/agents/test-helpers/fast-tool-stubs.js +18 -0
- package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +74 -0
- package/dist/agents/tool-display-common.js +782 -0
- package/dist/agents/tool-loop-detection.js +466 -0
- package/dist/agents/tool-policy.js +6 -0
- package/dist/agents/tools/image-tool.js +1 -1
- package/dist/agents/tools/sessions-access.js +178 -0
- package/dist/agents/tools/sessions-resolution.js +206 -0
- package/dist/agents/tools/subagents-tool.js +616 -0
- package/dist/agents/workspace-dir.js +18 -0
- package/dist/agents/workspace-dirs.js +14 -0
- package/dist/agents/workspace.js +70 -0
- package/dist/auto-reply/heartbeat-reply-payload.js +18 -0
- package/dist/auto-reply/reply/commands-export-session.js +163 -0
- package/dist/auto-reply/reply/commands-mesh.js +245 -0
- package/dist/auto-reply/reply/commands-setunset.js +28 -0
- package/dist/auto-reply/reply/commands-slash-parse.js +31 -0
- package/dist/auto-reply/reply/commands-system-prompt.js +117 -0
- package/dist/auto-reply/reply/directive-handling.levels.js +17 -0
- package/dist/auto-reply/reply/directive-handling.params.js +1 -0
- package/dist/auto-reply/reply/directive-parsing.js +36 -0
- package/dist/auto-reply/reply/dispatcher-registry.js +43 -0
- package/dist/auto-reply/reply/elevated-unavailable.js +20 -0
- package/dist/auto-reply/reply/post-compaction-audit.js +96 -0
- package/dist/auto-reply/reply/post-compaction-context.js +98 -0
- package/dist/auto-reply/reply/reply-delivery.js +92 -0
- package/dist/auto-reply/reply/session-reset-prompt.js +1 -0
- package/dist/auto-reply/reply/session-run-accounting.js +33 -0
- package/dist/auto-reply/reply.directive.directive-behavior.e2e-harness.js +115 -0
- package/dist/auto-reply/reply.directive.directive-behavior.e2e-mocks.js +12 -0
- package/dist/browser/bridge-auth-registry.js +26 -0
- package/dist/browser/client-actions-url.js +10 -0
- package/dist/browser/control-auth.js +73 -0
- package/dist/browser/csrf.js +64 -0
- package/dist/browser/http-auth.js +52 -0
- package/dist/browser/paths.js +37 -0
- package/dist/browser/proxy-files.js +32 -0
- package/dist/browser/pw-ai-state.js +7 -0
- package/dist/browser/resolved-config-refresh.js +42 -0
- package/dist/browser/routes/path-output.js +1 -0
- package/dist/browser/server-context.chrome-test-harness.js +20 -0
- package/dist/browser/server-middleware.js +31 -0
- package/dist/browser/test-port.js +16 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/file-resolver.js +43 -0
- package/dist/channels/account-summary.js +19 -0
- package/dist/channels/draft-stream-loop.js +77 -0
- package/dist/channels/plugins/account-helpers.js +26 -0
- package/dist/channels/telegram/allow-from.js +10 -0
- package/dist/cli/browser-cli-resize.js +22 -0
- package/dist/cli/browser-cli-shared.js +8 -0
- package/dist/cli/clawbot-cli.js +5 -0
- package/dist/cli/completion-cli.js +566 -0
- package/dist/cli/config-cli.js +63 -5
- package/dist/cli/daemon-cli/lifecycle-core.js +256 -0
- package/dist/cli/daemon-cli/register-service-commands.js +60 -0
- package/dist/cli/daemon-cli-compat.js +80 -0
- package/dist/cli/nodes-cli/pairing-render.js +26 -0
- package/dist/cli/program/action-reparse.js +17 -0
- package/dist/cli/program/command-registry.js +17 -0
- package/dist/cli/program/program-context.js +8 -0
- package/dist/cli/program/register.subclis.js +7 -0
- package/dist/cli/program/routes.js +233 -0
- package/dist/cli/qr-cli.js +132 -0
- package/dist/cli/requirements-test-fixtures.js +17 -0
- package/dist/cli/respawn-policy.js +4 -0
- package/dist/cli/shared/parse-port.js +18 -0
- package/dist/cli/skills-cli.format.js +241 -0
- package/dist/cli/update-cli/progress.js +121 -0
- package/dist/cli/update-cli/restart-helper.js +108 -0
- package/dist/cli/update-cli/shared.js +196 -0
- package/dist/cli/update-cli/status.js +97 -0
- package/dist/cli/update-cli/suppress-deprecations.js +17 -0
- package/dist/cli/update-cli/update-command.js +506 -0
- package/dist/cli/update-cli/wizard.js +130 -0
- package/dist/cli/update-cli.js +3 -9
- package/dist/cli/windows-argv.js +69 -0
- package/dist/commands/auth-choice-legacy.js +20 -0
- package/dist/commands/auth-choice.apply-helpers.js +8 -0
- package/dist/commands/channel-test-helpers.js +19 -0
- package/dist/commands/cleanup-plan.js +10 -0
- package/dist/commands/cleanup-utils.js +7 -0
- package/dist/commands/config-validation.js +15 -0
- package/dist/commands/doctor-completion.js +112 -0
- package/dist/commands/doctor-memory-search.js +119 -0
- package/dist/commands/doctor-session-locks.js +73 -0
- package/dist/commands/doctor.e2e-harness.js +364 -0
- package/dist/commands/gateway-presence.js +19 -0
- package/dist/commands/model-default.js +35 -0
- package/dist/commands/models/fallbacks-shared.js +102 -0
- package/dist/commands/models/shared.js +24 -0
- package/dist/commands/onboard-auth.config-gateways.js +64 -0
- package/dist/commands/onboard-auth.config-litellm.js +45 -0
- package/dist/commands/onboard-auth.config-shared.js +116 -0
- package/dist/commands/onboard-config.js +16 -0
- package/dist/commands/onboard-non-interactive.test-helpers.js +31 -0
- package/dist/commands/onboard-provider-auth-flags.js +136 -0
- package/dist/commands/openai-codex-oauth.js +40 -0
- package/dist/commands/test-runtime-config-helpers.js +21 -0
- package/dist/commands/test-wizard-helpers.js +68 -0
- package/dist/commands/vllm-setup.js +66 -0
- package/dist/compat/legacy-names.js +2 -0
- package/dist/config/backup-rotation.js +19 -0
- package/dist/config/env-preserve.js +122 -0
- package/dist/config/includes-scan.js +78 -0
- package/dist/config/plugins-allowlist.js +13 -0
- package/dist/config/schema.help.js +256 -0
- package/dist/config/schema.hints.js +189 -0
- package/dist/config/schema.irc.js +20 -0
- package/dist/config/schema.labels.js +317 -0
- package/dist/config/sessions/delivery-info.js +40 -0
- package/dist/config/types.irc.js +1 -0
- package/dist/config/zod-schema.agent-defaults.js +14 -0
- package/dist/config/zod-schema.agent-model.js +10 -0
- package/dist/config/zod-schema.agent-runtime.js +14 -0
- package/dist/config/zod-schema.allowdeny.js +35 -0
- package/dist/config/zod-schema.sensitive.js +4 -0
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/skills-snapshot.js +26 -0
- package/dist/cron/isolated-agent/subagent-followup.js +127 -0
- package/dist/cron/isolated-agent.mocks.js +12 -0
- package/dist/cron/isolated-agent.test-setup.js +22 -0
- package/dist/cron/legacy-delivery.js +43 -0
- package/dist/cron/webhook-url.js +22 -0
- package/dist/daemon/arg-split.js +40 -0
- package/dist/daemon/exec-file.js +23 -0
- package/dist/daemon/output.js +6 -0
- package/dist/daemon/runtime-format.js +31 -0
- package/dist/daemon/schtasks-exec.js +4 -0
- package/dist/daemon/service-audit.js +22 -0
- package/dist/discord/client.js +41 -0
- package/dist/discord/components-registry.js +57 -0
- package/dist/discord/components.js +816 -0
- package/dist/discord/guilds.js +12 -0
- package/dist/discord/monitor/gateway-plugin.js +48 -0
- package/dist/discord/monitor/presence.js +30 -0
- package/dist/discord/send.components.js +115 -0
- package/dist/discord/send.shared.js +4 -0
- package/dist/discord/ui.js +26 -0
- package/dist/discord/voice-message.js +254 -0
- package/dist/gateway/agent-event-assistant-text.js +5 -0
- package/dist/gateway/agent-prompt.js +33 -0
- package/dist/gateway/auth-rate-limit.js +136 -0
- package/dist/gateway/channel-health-monitor.js +114 -0
- package/dist/gateway/control-ui-contract.js +1 -0
- package/dist/gateway/control-ui-csp.js +15 -0
- package/dist/gateway/gateway-config-prompts.shared.js +25 -0
- package/dist/gateway/http-auth-helpers.js +18 -0
- package/dist/gateway/http-common.js +18 -0
- package/dist/gateway/http-endpoint-helpers.js +27 -0
- package/dist/gateway/node-invoke-sanitize.js +11 -0
- package/dist/gateway/node-invoke-system-run-approval.js +205 -0
- package/dist/gateway/probe-auth.js +21 -0
- package/dist/gateway/protocol/index.js +7 -2
- package/dist/gateway/protocol/schema/mesh.js +54 -0
- package/dist/gateway/protocol/schema/protocol-schemas.js +7 -0
- package/dist/gateway/protocol/schema.js +1 -0
- package/dist/gateway/server/ws-connection/auth-messages.js +54 -0
- package/dist/gateway/server-channels.js +11 -0
- package/dist/gateway/server-methods/attachment-normalize.js +16 -0
- package/dist/gateway/server-methods/base-hash.js +8 -0
- package/dist/gateway/server-methods/mesh.js +700 -0
- package/dist/gateway/server-methods/nodes.handlers.invoke-result.js +55 -0
- package/dist/gateway/server-methods/restart-request.js +13 -0
- package/dist/gateway/server-methods/validation.js +8 -0
- package/dist/gateway/server.agent.gateway-server-agent.mocks.js +35 -0
- package/dist/gateway/server.e2e-registry-helpers.js +1 -0
- package/dist/gateway/server.e2e-ws-harness.js +20 -0
- package/dist/gateway/test-helpers.js +2 -0
- package/dist/gateway/test-helpers.server.js +3 -1
- package/dist/gateway/test-http-response.js +12 -0
- package/dist/gateway/test-openai-responses-model.js +20 -0
- package/dist/gateway/test-temp-config.js +30 -0
- package/dist/gateway/test-with-server.js +32 -0
- package/dist/hooks/bundled/bootstrap-extra-files/handler.js +46 -0
- package/dist/imessage/monitor/abort-handler.js +23 -0
- package/dist/imessage/monitor/inbound-processing.js +346 -0
- package/dist/imessage/monitor/parse-notification.js +64 -0
- package/dist/imessage/target-parsing-helpers.js +92 -0
- package/dist/infra/archive.js +244 -20
- package/dist/infra/detect-package-manager.js +26 -0
- package/dist/infra/exec-approvals-allowlist.js +257 -0
- package/dist/infra/exec-approvals-analysis.js +770 -0
- package/dist/infra/exec-approvals.js +13 -0
- package/dist/infra/file-lock.js +1 -0
- package/dist/infra/gemini-auth.js +39 -0
- package/dist/infra/heartbeat-active-hours.js +85 -0
- package/dist/infra/heartbeat-events-filter.js +50 -0
- package/dist/infra/heartbeat-runner.test-utils.js +39 -0
- package/dist/infra/http-body.js +265 -0
- package/dist/infra/install-package-dir.js +50 -0
- package/dist/infra/install-safe-path.js +49 -0
- package/dist/infra/json-files.js +49 -0
- package/dist/infra/jsonl-socket.js +52 -0
- package/dist/infra/map-size.js +14 -0
- package/dist/infra/net/hostname.js +7 -0
- package/dist/infra/npm-registry-spec.js +39 -0
- package/dist/infra/openclaw-root.js +109 -0
- package/dist/infra/outbound/delivery-queue.js +214 -0
- package/dist/infra/outbound/identity.js +23 -0
- package/dist/infra/outbound/message-action-params.js +307 -0
- package/dist/infra/outbound/tool-payload.js +21 -0
- package/dist/infra/package-json.js +23 -0
- package/dist/infra/pairing-files.js +19 -0
- package/dist/infra/pairing-token.js +9 -0
- package/dist/infra/path-prepend.js +51 -0
- package/dist/infra/path-safety.js +16 -0
- package/dist/infra/process-respawn.js +49 -0
- package/dist/infra/runtime-status.js +16 -0
- package/dist/infra/session-cost-usage.types.js +1 -0
- package/dist/infra/session-maintenance-warning.js +89 -0
- package/dist/infra/system-run-command.js +78 -0
- package/dist/infra/tmp-openclaw-dir.js +81 -0
- package/dist/infra/tmp-poolbot-dir.js +2 -0
- package/dist/infra/update-channels.js +19 -0
- package/dist/line/actions.js +45 -0
- package/dist/line/channel-access-token.js +9 -0
- package/dist/line/flex-templates/basic-cards.js +332 -0
- package/dist/line/flex-templates/common.js +18 -0
- package/dist/line/flex-templates/media-control-cards.js +453 -0
- package/dist/line/flex-templates/message.js +10 -0
- package/dist/line/flex-templates/schedule-cards.js +399 -0
- package/dist/line/flex-templates/types.js +1 -0
- package/dist/line/webhook-node.js +100 -0
- package/dist/line/webhook-utils.js +11 -0
- package/dist/logging/diagnostic-session-state.js +73 -0
- package/dist/logging/diagnostic.js +22 -0
- package/dist/logging/timestamps.js +14 -0
- package/dist/markdown/whatsapp.js +62 -0
- package/dist/media/base64.js +34 -0
- package/dist/media/local-roots.js +32 -0
- package/dist/media/outbound-attachment.js +10 -0
- package/dist/media/read-response-with-limit.js +41 -0
- package/dist/media/sniff-mime-from-base64.js +19 -0
- package/dist/media-understanding/audio-preflight.js +67 -0
- package/dist/media-understanding/fs.js +13 -0
- package/dist/media-understanding/output-extract.js +26 -0
- package/dist/media-understanding/providers/audio.test-helpers.js +34 -0
- package/dist/media-understanding/providers/google/inline-data.js +64 -0
- package/dist/media-understanding/providers/shared.js +7 -0
- package/dist/media-understanding/runner.entries.js +459 -0
- package/dist/memory/batch-error-utils.js +11 -0
- package/dist/memory/batch-http.js +27 -0
- package/dist/memory/batch-output.js +29 -0
- package/dist/memory/batch-runner.js +22 -0
- package/dist/memory/batch-upload.js +23 -0
- package/dist/memory/batch-utils.js +26 -0
- package/dist/memory/embeddings-debug.js +11 -0
- package/dist/memory/embeddings-remote-client.js +22 -0
- package/dist/memory/embeddings-remote-fetch.js +14 -0
- package/dist/memory/embeddings.js +36 -9
- package/dist/memory/hybrid.js +24 -5
- package/dist/memory/manager-embedding-ops.js +616 -0
- package/dist/memory/manager-sync-ops.js +953 -0
- package/dist/memory/manager.js +76 -28
- package/dist/memory/mmr.js +164 -0
- package/dist/memory/qmd-manager.js +1061 -0
- package/dist/memory/qmd-query-parser.js +107 -0
- package/dist/memory/qmd-scope.js +93 -0
- package/dist/memory/query-expansion.js +331 -0
- package/dist/memory/search-manager.js +0 -1
- package/dist/memory/sync-index.js +21 -0
- package/dist/memory/sync-progress.js +22 -0
- package/dist/memory/sync-stale.js +30 -0
- package/dist/memory/temporal-decay.js +119 -0
- package/dist/memory/test-embeddings-mock.js +16 -0
- package/dist/memory/test-manager-helpers.js +14 -0
- package/dist/memory/test-runtime-mocks.js +11 -0
- package/dist/node-host/invoke-browser.js +177 -0
- package/dist/node-host/invoke.js +685 -0
- package/dist/pairing/setup-code.js +285 -0
- package/dist/plugin-sdk/account-id.js +1 -0
- package/dist/plugin-sdk/agent-media-payload.js +13 -0
- package/dist/plugin-sdk/allow-from.js +47 -0
- package/dist/plugin-sdk/command-auth.js +23 -0
- package/dist/plugin-sdk/config-paths.js +9 -0
- package/dist/plugin-sdk/file-lock.js +116 -0
- package/dist/plugin-sdk/json-store.js +31 -0
- package/dist/plugin-sdk/onboarding.js +28 -0
- package/dist/plugin-sdk/provider-auth-result.js +29 -0
- package/dist/plugin-sdk/slack-message-actions.js +133 -0
- package/dist/plugin-sdk/status-helpers.js +35 -0
- package/dist/plugin-sdk/text-chunking.js +31 -0
- package/dist/plugin-sdk/tool-send.js +12 -0
- package/dist/plugin-sdk/webhook-path.js +27 -0
- package/dist/plugin-sdk/webhook-targets.js +34 -0
- package/dist/plugins/hooks.test-helpers.js +21 -0
- package/dist/plugins/uninstall.js +171 -0
- package/dist/process/kill-tree.js +98 -0
- package/dist/process/supervisor/adapters/child.js +143 -0
- package/dist/process/supervisor/adapters/env.js +13 -0
- package/dist/process/supervisor/adapters/pty.js +148 -0
- package/dist/process/supervisor/index.js +10 -0
- package/dist/process/supervisor/registry.js +117 -0
- package/dist/process/supervisor/supervisor.js +244 -0
- package/dist/process/supervisor/types.js +1 -0
- package/dist/providers/google-shared.test-helpers.js +75 -0
- package/dist/security/audit-channel.js +419 -0
- package/dist/security/audit-tool-policy.js +1 -0
- package/dist/security/scan-paths.js +12 -0
- package/dist/sessions/input-provenance.js +55 -0
- package/dist/sessions/session-key-utils.js +7 -0
- package/dist/shared/chat-content.js +31 -0
- package/dist/shared/chat-envelope.js +45 -0
- package/dist/shared/config-eval.js +117 -0
- package/dist/shared/device-auth.js +16 -0
- package/dist/shared/entry-metadata.js +9 -0
- package/dist/shared/entry-status.js +25 -0
- package/dist/shared/frontmatter.js +98 -0
- package/dist/shared/model-param-b.js +19 -0
- package/dist/shared/net/ipv4.js +17 -0
- package/dist/shared/node-match.js +53 -0
- package/dist/shared/pid-alive.js +12 -0
- package/dist/shared/process-scoped-map.js +10 -0
- package/dist/shared/requirements.js +128 -0
- package/dist/shared/subagents-format.js +84 -0
- package/dist/shared/usage-aggregates.js +28 -0
- package/dist/signal/monitor/mentions.js +45 -0
- package/dist/signal/rpc-context.js +19 -0
- package/dist/slack/blocks-fallback.js +76 -0
- package/dist/slack/blocks-input.js +40 -0
- package/dist/slack/draft-stream.js +106 -0
- package/dist/slack/message-actions.js +51 -0
- package/dist/slack/modal-metadata.js +32 -0
- package/dist/slack/monitor/events/interactions.js +462 -0
- package/dist/slack/monitor/room-context.js +17 -0
- package/dist/slack/stream-mode.js +41 -0
- package/dist/telegram/bot-native-command-menu.js +64 -0
- package/dist/telegram/bot.media.e2e-harness.js +81 -0
- package/dist/telegram/button-types.js +1 -0
- package/dist/telegram/group-access.js +65 -0
- package/dist/telegram/outbound-params.js +21 -0
- package/dist/telegram/poll-vote-cache.js +21 -0
- package/dist/terminal/health-style.js +36 -0
- package/dist/test-utils/chunk-test-helpers.js +21 -0
- package/dist/test-utils/env.js +72 -0
- package/dist/test-utils/exec-assertions.js +12 -0
- package/dist/test-utils/imessage-test-plugin.js +54 -0
- package/dist/test-utils/mock-http-response.js +17 -0
- package/dist/test-utils/vitest-mock-fn.js +1 -0
- package/dist/tts/tts-core.js +550 -0
- package/dist/utils/chunk-items.js +10 -0
- package/dist/utils/reaction-level.js +52 -0
- package/dist/utils/safe-json.js +22 -0
- package/dist/utils/with-timeout.js +14 -0
- package/dist/web/media.js +17 -5
- package/dist/whatsapp/resolve-outbound-target.js +42 -0
- package/dist/wizard/onboarding.completion.js +74 -0
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/bluebubbles/src/account-resolve.ts +29 -0
- package/extensions/bluebubbles/src/monitor-normalize.ts +796 -0
- package/extensions/bluebubbles/src/monitor-processing.ts +1007 -0
- package/extensions/bluebubbles/src/monitor-reply-cache.ts +185 -0
- package/extensions/bluebubbles/src/monitor-shared.ts +51 -0
- package/extensions/bluebubbles/src/multipart.ts +32 -0
- package/extensions/bluebubbles/src/send-helpers.ts +53 -0
- package/extensions/bluebubbles/src/test-harness.ts +50 -0
- package/extensions/bluebubbles/src/test-mocks.ts +11 -0
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/device-pair/index.ts +554 -0
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/discord/src/channel.js +366 -0
- package/extensions/discord/src/runtime.js +10 -0
- package/extensions/feishu/index.ts +63 -0
- package/extensions/feishu/src/accounts.ts +114 -0
- package/extensions/feishu/src/bitable.ts +739 -0
- package/extensions/feishu/src/bot.ts +965 -0
- package/extensions/feishu/src/channel.ts +351 -0
- package/extensions/feishu/src/client.ts +118 -0
- package/extensions/feishu/src/config-schema.ts +206 -0
- package/extensions/feishu/src/dedup.ts +33 -0
- package/extensions/feishu/src/directory.ts +177 -0
- package/extensions/feishu/src/doc-schema.ts +47 -0
- package/extensions/feishu/src/docx.ts +536 -0
- package/extensions/feishu/src/drive-schema.ts +46 -0
- package/extensions/feishu/src/drive.ts +227 -0
- package/extensions/feishu/src/dynamic-agent.ts +131 -0
- package/extensions/feishu/src/media.ts +449 -0
- package/extensions/feishu/src/mention.ts +126 -0
- package/extensions/feishu/src/monitor.ts +330 -0
- package/extensions/feishu/src/onboarding.ts +359 -0
- package/extensions/feishu/src/outbound.ts +55 -0
- package/extensions/feishu/src/perm-schema.ts +52 -0
- package/extensions/feishu/src/perm.ts +173 -0
- package/extensions/feishu/src/policy.ts +84 -0
- package/extensions/feishu/src/probe.ts +44 -0
- package/extensions/feishu/src/reactions.ts +160 -0
- package/extensions/feishu/src/reply-dispatcher.ts +239 -0
- package/extensions/feishu/src/runtime.ts +14 -0
- package/extensions/feishu/src/send-result.ts +29 -0
- package/extensions/feishu/src/send.ts +335 -0
- package/extensions/feishu/src/streaming-card.ts +223 -0
- package/extensions/feishu/src/targets.ts +78 -0
- package/extensions/feishu/src/tools-config.ts +21 -0
- package/extensions/feishu/src/types.ts +81 -0
- package/extensions/feishu/src/typing.ts +80 -0
- package/extensions/feishu/src/wiki-schema.ts +55 -0
- package/extensions/feishu/src/wiki.ts +232 -0
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/imessage/src/channel.js +253 -0
- package/extensions/imessage/src/runtime.js +10 -0
- package/extensions/irc/index.ts +17 -0
- package/extensions/irc/src/accounts.ts +268 -0
- package/extensions/irc/src/channel.ts +367 -0
- package/extensions/irc/src/client.ts +439 -0
- package/extensions/irc/src/config-schema.ts +97 -0
- package/extensions/irc/src/connect-options.ts +30 -0
- package/extensions/irc/src/control-chars.ts +22 -0
- package/extensions/irc/src/inbound.ts +334 -0
- package/extensions/irc/src/monitor.ts +147 -0
- package/extensions/irc/src/normalize.ts +117 -0
- package/extensions/irc/src/onboarding.ts +479 -0
- package/extensions/irc/src/policy.ts +157 -0
- package/extensions/irc/src/probe.ts +53 -0
- package/extensions/irc/src/protocol.ts +169 -0
- package/extensions/irc/src/runtime.ts +14 -0
- package/extensions/irc/src/send.ts +88 -0
- package/extensions/irc/src/types.ts +93 -0
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/matrix/src/matrix/client-bootstrap.ts +39 -0
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mattermost/src/mattermost/monitor-onchar.ts +25 -0
- package/extensions/mattermost/src/mattermost/monitor-websocket.ts +221 -0
- package/extensions/mattermost/src/mattermost/reactions.ts +130 -0
- package/extensions/mattermost/src/mattermost/reconnect.ts +103 -0
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/index.ts +161 -0
- package/extensions/minimax-portal-auth/oauth.ts +247 -0
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/msteams/src/file-lock.ts +1 -0
- package/extensions/msteams/src/graph.ts +92 -0
- package/extensions/msteams/src/mentions.ts +114 -0
- package/extensions/msteams/src/test-runtime.ts +16 -0
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/index.ts +177 -0
- package/extensions/phone-control/index.ts +421 -0
- package/extensions/shared/resolve-target-test-helpers.ts +66 -0
- package/extensions/signal/package.json +1 -1
- package/extensions/signal/src/channel.js +273 -0
- package/extensions/signal/src/runtime.js +10 -0
- package/extensions/slack/package.json +1 -1
- package/extensions/slack/src/channel.js +489 -0
- package/extensions/slack/src/runtime.js +10 -0
- package/extensions/talk-voice/index.ts +150 -0
- package/extensions/telegram/package.json +1 -1
- package/extensions/telegram/src/channel.js +424 -0
- package/extensions/telegram/src/runtime.js +10 -0
- package/extensions/thread-ownership/index.ts +133 -0
- package/extensions/tlon/package.json +1 -1
- package/extensions/tlon/src/account-fields.ts +25 -0
- package/extensions/tlon/src/urbit/base-url.ts +57 -0
- package/extensions/tlon/src/urbit/channel-client.ts +157 -0
- package/extensions/tlon/src/urbit/channel-ops.ts +164 -0
- package/extensions/tlon/src/urbit/context.ts +47 -0
- package/extensions/tlon/src/urbit/errors.ts +51 -0
- package/extensions/tlon/src/urbit/fetch.ts +39 -0
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/twitch/src/test-fixtures.ts +30 -0
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/voice-call/src/allowlist.ts +19 -0
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/whatsapp/src/channel.js +429 -0
- package/extensions/whatsapp/src/runtime.js +10 -0
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Exponential backoff schedule for command polling
|
|
2
|
+
const BACKOFF_SCHEDULE_MS = [5000, 10000, 30000, 60000];
|
|
3
|
+
/**
|
|
4
|
+
* Calculate suggested retry delay based on consecutive no-output poll count.
|
|
5
|
+
* Implements exponential backoff schedule: 5s → 10s → 30s → 60s (capped).
|
|
6
|
+
*/
|
|
7
|
+
export function calculateBackoffMs(consecutiveNoOutputPolls) {
|
|
8
|
+
const index = Math.min(consecutiveNoOutputPolls, BACKOFF_SCHEDULE_MS.length - 1);
|
|
9
|
+
return BACKOFF_SCHEDULE_MS[index] ?? 60000;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Record a command poll and return suggested retry delay.
|
|
13
|
+
* @param state Session state to track polling in
|
|
14
|
+
* @param commandId Unique identifier for the command being polled
|
|
15
|
+
* @param hasNewOutput Whether this poll returned new output
|
|
16
|
+
* @returns Suggested delay in milliseconds before next poll
|
|
17
|
+
*/
|
|
18
|
+
export function recordCommandPoll(state, commandId, hasNewOutput) {
|
|
19
|
+
if (!state.commandPollCounts) {
|
|
20
|
+
state.commandPollCounts = new Map();
|
|
21
|
+
}
|
|
22
|
+
const existing = state.commandPollCounts.get(commandId);
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
if (hasNewOutput) {
|
|
25
|
+
state.commandPollCounts.set(commandId, { count: 0, lastPollAt: now });
|
|
26
|
+
return BACKOFF_SCHEDULE_MS[0] ?? 5000;
|
|
27
|
+
}
|
|
28
|
+
const newCount = (existing?.count ?? -1) + 1;
|
|
29
|
+
state.commandPollCounts.set(commandId, { count: newCount, lastPollAt: now });
|
|
30
|
+
return calculateBackoffMs(newCount);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get current suggested backoff for a command without modifying state.
|
|
34
|
+
* Useful for checking current backoff level.
|
|
35
|
+
*/
|
|
36
|
+
export function getCommandPollSuggestion(state, commandId) {
|
|
37
|
+
const pollData = state.commandPollCounts?.get(commandId);
|
|
38
|
+
if (!pollData) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
return calculateBackoffMs(pollData.count);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Reset poll count for a command (e.g., when command completes).
|
|
45
|
+
*/
|
|
46
|
+
export function resetCommandPollCount(state, commandId) {
|
|
47
|
+
state.commandPollCounts?.delete(commandId);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Prune stale command poll records (older than 1 hour).
|
|
51
|
+
* Call periodically to prevent memory bloat.
|
|
52
|
+
*/
|
|
53
|
+
export function pruneStaleCommandPolls(state, maxAgeMs = 3600000) {
|
|
54
|
+
if (!state.commandPollCounts) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
for (const [commandId, data] of state.commandPollCounts.entries()) {
|
|
59
|
+
if (now - data.lastPollAt > maxAgeMs) {
|
|
60
|
+
state.commandPollCounts.delete(commandId);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone, } from "./date-time.js";
|
|
2
|
+
export function resolveCronStyleNow(cfg, nowMs) {
|
|
3
|
+
const userTimezone = resolveUserTimezone(cfg.agents?.defaults?.userTimezone);
|
|
4
|
+
const userTimeFormat = resolveUserTimeFormat(cfg.agents?.defaults?.timeFormat);
|
|
5
|
+
const formattedTime = formatUserTime(new Date(nowMs), userTimezone, userTimeFormat) ?? new Date(nowMs).toISOString();
|
|
6
|
+
const timeLine = `Current time: ${formattedTime} (${userTimezone})`;
|
|
7
|
+
return { userTimezone, formattedTime, timeLine };
|
|
8
|
+
}
|
|
9
|
+
export function appendCronStyleCurrentTimeLine(text, cfg, nowMs) {
|
|
10
|
+
const base = text.trimEnd();
|
|
11
|
+
if (!base || base.includes("Current time:")) {
|
|
12
|
+
return base;
|
|
13
|
+
}
|
|
14
|
+
const { timeLine } = resolveCronStyleNow(cfg, nowMs);
|
|
15
|
+
return `${base}\n${timeLine}`;
|
|
16
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function escapeRegex(value) {
|
|
2
|
+
// Standard "escape string for regex literal" pattern.
|
|
3
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4
|
+
}
|
|
5
|
+
export function compileGlobPattern(params) {
|
|
6
|
+
const normalized = params.normalize(params.raw);
|
|
7
|
+
if (!normalized) {
|
|
8
|
+
return { kind: "exact", value: "" };
|
|
9
|
+
}
|
|
10
|
+
if (normalized === "*") {
|
|
11
|
+
return { kind: "all" };
|
|
12
|
+
}
|
|
13
|
+
if (!normalized.includes("*")) {
|
|
14
|
+
return { kind: "exact", value: normalized };
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
kind: "regex",
|
|
18
|
+
value: new RegExp(`^${escapeRegex(normalized).replaceAll("\\*", ".*")}$`),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function compileGlobPatterns(params) {
|
|
22
|
+
if (!Array.isArray(params.raw)) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
return params.raw
|
|
26
|
+
.map((raw) => compileGlobPattern({ raw, normalize: params.normalize }))
|
|
27
|
+
.filter((pattern) => pattern.kind !== "exact" || pattern.value);
|
|
28
|
+
}
|
|
29
|
+
export function matchesAnyGlobPattern(value, patterns) {
|
|
30
|
+
for (const pattern of patterns) {
|
|
31
|
+
if (pattern.kind === "all") {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (pattern.kind === "exact" && value === pattern.value) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (pattern.kind === "regex" && pattern.value.test(value)) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
@@ -17,6 +17,10 @@ const DEFAULT_HYBRID_ENABLED = true;
|
|
|
17
17
|
const DEFAULT_HYBRID_VECTOR_WEIGHT = 0.7;
|
|
18
18
|
const DEFAULT_HYBRID_TEXT_WEIGHT = 0.3;
|
|
19
19
|
const DEFAULT_HYBRID_CANDIDATE_MULTIPLIER = 4;
|
|
20
|
+
const DEFAULT_MMR_ENABLED = false;
|
|
21
|
+
const DEFAULT_MMR_LAMBDA = 0.7;
|
|
22
|
+
const DEFAULT_TEMPORAL_DECAY_ENABLED = false;
|
|
23
|
+
const DEFAULT_TEMPORAL_DECAY_HALF_LIFE_DAYS = 30;
|
|
20
24
|
const DEFAULT_CACHE_ENABLED = true;
|
|
21
25
|
const DEFAULT_SOURCES = ["memory"];
|
|
22
26
|
function normalizeSources(sources, sessionMemoryEnabled) {
|
|
@@ -141,6 +145,22 @@ function mergeConfig(defaults, overrides, agentId) {
|
|
|
141
145
|
candidateMultiplier: overrides?.query?.hybrid?.candidateMultiplier ??
|
|
142
146
|
defaults?.query?.hybrid?.candidateMultiplier ??
|
|
143
147
|
DEFAULT_HYBRID_CANDIDATE_MULTIPLIER,
|
|
148
|
+
mmr: {
|
|
149
|
+
enabled: overrides?.query?.hybrid?.mmr?.enabled ??
|
|
150
|
+
defaults?.query?.hybrid?.mmr?.enabled ??
|
|
151
|
+
DEFAULT_MMR_ENABLED,
|
|
152
|
+
lambda: overrides?.query?.hybrid?.mmr?.lambda ??
|
|
153
|
+
defaults?.query?.hybrid?.mmr?.lambda ??
|
|
154
|
+
DEFAULT_MMR_LAMBDA,
|
|
155
|
+
},
|
|
156
|
+
temporalDecay: {
|
|
157
|
+
enabled: overrides?.query?.hybrid?.temporalDecay?.enabled ??
|
|
158
|
+
defaults?.query?.hybrid?.temporalDecay?.enabled ??
|
|
159
|
+
DEFAULT_TEMPORAL_DECAY_ENABLED,
|
|
160
|
+
halfLifeDays: overrides?.query?.hybrid?.temporalDecay?.halfLifeDays ??
|
|
161
|
+
defaults?.query?.hybrid?.temporalDecay?.halfLifeDays ??
|
|
162
|
+
DEFAULT_TEMPORAL_DECAY_HALF_LIFE_DAYS,
|
|
163
|
+
},
|
|
144
164
|
};
|
|
145
165
|
const cache = {
|
|
146
166
|
enabled: overrides?.cache?.enabled ?? defaults?.cache?.enabled ?? DEFAULT_CACHE_ENABLED,
|
|
@@ -154,6 +174,9 @@ function mergeConfig(defaults, overrides, agentId) {
|
|
|
154
174
|
const normalizedVectorWeight = sum > 0 ? vectorWeight / sum : DEFAULT_HYBRID_VECTOR_WEIGHT;
|
|
155
175
|
const normalizedTextWeight = sum > 0 ? textWeight / sum : DEFAULT_HYBRID_TEXT_WEIGHT;
|
|
156
176
|
const candidateMultiplier = clampInt(hybrid.candidateMultiplier, 1, 20);
|
|
177
|
+
const temporalDecayHalfLifeDays = Math.max(1, Math.floor(Number.isFinite(hybrid.temporalDecay.halfLifeDays)
|
|
178
|
+
? hybrid.temporalDecay.halfLifeDays
|
|
179
|
+
: DEFAULT_TEMPORAL_DECAY_HALF_LIFE_DAYS));
|
|
157
180
|
const deltaBytes = clampInt(sync.sessions.deltaBytes, 0, Number.MAX_SAFE_INTEGER);
|
|
158
181
|
const deltaMessages = clampInt(sync.sessions.deltaMessages, 0, Number.MAX_SAFE_INTEGER);
|
|
159
182
|
return {
|
|
@@ -185,6 +208,16 @@ function mergeConfig(defaults, overrides, agentId) {
|
|
|
185
208
|
vectorWeight: normalizedVectorWeight,
|
|
186
209
|
textWeight: normalizedTextWeight,
|
|
187
210
|
candidateMultiplier,
|
|
211
|
+
mmr: {
|
|
212
|
+
enabled: Boolean(hybrid.mmr.enabled),
|
|
213
|
+
lambda: Number.isFinite(hybrid.mmr.lambda)
|
|
214
|
+
? Math.max(0, Math.min(1, hybrid.mmr.lambda))
|
|
215
|
+
: DEFAULT_MMR_LAMBDA,
|
|
216
|
+
},
|
|
217
|
+
temporalDecay: {
|
|
218
|
+
enabled: Boolean(hybrid.temporalDecay.enabled),
|
|
219
|
+
halfLifeDays: temporalDecayHalfLifeDays,
|
|
220
|
+
},
|
|
188
221
|
},
|
|
189
222
|
},
|
|
190
223
|
cache: {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function buildModelAliasLines(cfg) {
|
|
2
|
+
const models = cfg?.agents?.defaults?.models ?? {};
|
|
3
|
+
const entries = [];
|
|
4
|
+
for (const [keyRaw, entryRaw] of Object.entries(models)) {
|
|
5
|
+
const model = String(keyRaw ?? "").trim();
|
|
6
|
+
if (!model) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
const alias = String(entryRaw?.alias ?? "").trim();
|
|
10
|
+
if (!alias) {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
entries.push({ alias, model });
|
|
14
|
+
}
|
|
15
|
+
return entries
|
|
16
|
+
.toSorted((a, b) => a.alias.localeCompare(b.alias))
|
|
17
|
+
.map((entry) => `- ${entry.alias}: ${entry.model}`);
|
|
18
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ensureAuthProfileStore, resolveAuthProfileDisplayLabel, resolveAuthProfileOrder, } from "./auth-profiles.js";
|
|
2
|
+
import { getCustomProviderApiKey, resolveEnvApiKey } from "./model-auth.js";
|
|
3
|
+
import { normalizeProviderId } from "./model-selection.js";
|
|
4
|
+
function formatApiKeySnippet(apiKey) {
|
|
5
|
+
const compact = apiKey.replace(/\s+/g, "");
|
|
6
|
+
if (!compact) {
|
|
7
|
+
return "unknown";
|
|
8
|
+
}
|
|
9
|
+
const edge = compact.length >= 12 ? 6 : 4;
|
|
10
|
+
const head = compact.slice(0, edge);
|
|
11
|
+
const tail = compact.slice(-edge);
|
|
12
|
+
return `${head}…${tail}`;
|
|
13
|
+
}
|
|
14
|
+
export function resolveModelAuthLabel(params) {
|
|
15
|
+
const resolvedProvider = params.provider?.trim();
|
|
16
|
+
if (!resolvedProvider) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
const providerKey = normalizeProviderId(resolvedProvider);
|
|
20
|
+
const store = ensureAuthProfileStore(params.agentDir, {
|
|
21
|
+
allowKeychainPrompt: false,
|
|
22
|
+
});
|
|
23
|
+
const profileOverride = params.sessionEntry?.authProfileOverride?.trim();
|
|
24
|
+
const order = resolveAuthProfileOrder({
|
|
25
|
+
cfg: params.cfg,
|
|
26
|
+
store,
|
|
27
|
+
provider: providerKey,
|
|
28
|
+
preferredProfile: profileOverride,
|
|
29
|
+
});
|
|
30
|
+
const candidates = [profileOverride, ...order].filter(Boolean);
|
|
31
|
+
for (const profileId of candidates) {
|
|
32
|
+
const profile = store.profiles[profileId];
|
|
33
|
+
if (!profile || normalizeProviderId(profile.provider) !== providerKey) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const label = resolveAuthProfileDisplayLabel({
|
|
37
|
+
cfg: params.cfg,
|
|
38
|
+
store,
|
|
39
|
+
profileId,
|
|
40
|
+
});
|
|
41
|
+
if (profile.type === "oauth") {
|
|
42
|
+
return `oauth${label ? ` (${label})` : ""}`;
|
|
43
|
+
}
|
|
44
|
+
if (profile.type === "token") {
|
|
45
|
+
return `token ${formatApiKeySnippet(profile.token)}${label ? ` (${label})` : ""}`;
|
|
46
|
+
}
|
|
47
|
+
return `api-key ${formatApiKeySnippet(profile.key ?? "")}${label ? ` (${label})` : ""}`;
|
|
48
|
+
}
|
|
49
|
+
const envKey = resolveEnvApiKey(providerKey);
|
|
50
|
+
if (envKey?.apiKey) {
|
|
51
|
+
if (envKey.source.includes("OAUTH_TOKEN")) {
|
|
52
|
+
return `oauth (${envKey.source})`;
|
|
53
|
+
}
|
|
54
|
+
return `api-key ${formatApiKeySnippet(envKey.apiKey)} (${envKey.source})`;
|
|
55
|
+
}
|
|
56
|
+
const customKey = getCustomProviderApiKey(params.cfg, providerKey);
|
|
57
|
+
if (customKey) {
|
|
58
|
+
return `api-key ${formatApiKeySnippet(customKey)} (models.json)`;
|
|
59
|
+
}
|
|
60
|
+
return "unknown";
|
|
61
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js";
|
|
2
2
|
import { coerceToFailoverError, describeFailoverError, isFailoverError, isTimeoutError, } from "./failover-error.js";
|
|
3
3
|
import { buildModelAliasIndex, modelKey, parseModelRef, resolveConfiguredModelRef, resolveModelRefFromString, } from "./model-selection.js";
|
|
4
|
-
import { ensureAuthProfileStore, isProfileInCooldown, resolveAuthProfileOrder, } from "./auth-profiles.js";
|
|
4
|
+
import { ensureAuthProfileStore, getSoonestCooldownExpiry, isProfileInCooldown, resolveAuthProfileOrder, } from "./auth-profiles.js";
|
|
5
5
|
function isAbortError(err) {
|
|
6
6
|
if (!err || typeof err !== "object")
|
|
7
7
|
return false;
|
|
@@ -135,6 +135,36 @@ function resolveFallbackCandidates(params) {
|
|
|
135
135
|
}
|
|
136
136
|
return candidates;
|
|
137
137
|
}
|
|
138
|
+
const lastProbeAttempt = new Map();
|
|
139
|
+
const MIN_PROBE_INTERVAL_MS = 30_000; // 30 seconds between probes per key
|
|
140
|
+
const PROBE_MARGIN_MS = 2 * 60 * 1000;
|
|
141
|
+
const PROBE_SCOPE_DELIMITER = "::";
|
|
142
|
+
function resolveProbeThrottleKey(provider, agentDir) {
|
|
143
|
+
const scope = String(agentDir ?? "").trim();
|
|
144
|
+
return scope ? `${scope}${PROBE_SCOPE_DELIMITER}${provider}` : provider;
|
|
145
|
+
}
|
|
146
|
+
function shouldProbePrimaryDuringCooldown(params) {
|
|
147
|
+
if (!params.isPrimary || !params.hasFallbackCandidates) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
const lastProbe = lastProbeAttempt.get(params.throttleKey) ?? 0;
|
|
151
|
+
if (params.now - lastProbe < MIN_PROBE_INTERVAL_MS) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
const soonest = getSoonestCooldownExpiry(params.authStore, params.profileIds);
|
|
155
|
+
if (soonest === null || !Number.isFinite(soonest)) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
// Probe when cooldown already expired or within the configured margin.
|
|
159
|
+
return params.now >= soonest - PROBE_MARGIN_MS;
|
|
160
|
+
}
|
|
161
|
+
/** @internal – exposed for unit tests only */
|
|
162
|
+
export const _probeThrottleInternals = {
|
|
163
|
+
lastProbeAttempt,
|
|
164
|
+
MIN_PROBE_INTERVAL_MS,
|
|
165
|
+
PROBE_MARGIN_MS,
|
|
166
|
+
resolveProbeThrottleKey,
|
|
167
|
+
};
|
|
138
168
|
export async function runWithModelFallback(params) {
|
|
139
169
|
const candidates = resolveFallbackCandidates({
|
|
140
170
|
cfg: params.cfg,
|
|
@@ -146,6 +176,7 @@ export async function runWithModelFallback(params) {
|
|
|
146
176
|
? ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false })
|
|
147
177
|
: null;
|
|
148
178
|
const attempts = [];
|
|
179
|
+
const hasFallbackCandidates = candidates.length > 1;
|
|
149
180
|
let lastError;
|
|
150
181
|
for (let i = 0; i < candidates.length; i += 1) {
|
|
151
182
|
const candidate = candidates[i];
|
|
@@ -157,14 +188,34 @@ export async function runWithModelFallback(params) {
|
|
|
157
188
|
});
|
|
158
189
|
const isAnyProfileAvailable = profileIds.some((id) => !isProfileInCooldown(authStore, id));
|
|
159
190
|
if (profileIds.length > 0 && !isAnyProfileAvailable) {
|
|
160
|
-
// All profiles for this provider are in cooldown
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
191
|
+
// All profiles for this provider are in cooldown.
|
|
192
|
+
// For the primary model (i === 0), probe it if the soonest cooldown
|
|
193
|
+
// expiry is close or already past. This avoids staying on a fallback
|
|
194
|
+
// model long after the real rate-limit window clears.
|
|
195
|
+
const now = Date.now();
|
|
196
|
+
const probeThrottleKey = resolveProbeThrottleKey(candidate.provider, params.agentDir);
|
|
197
|
+
const shouldProbe = shouldProbePrimaryDuringCooldown({
|
|
198
|
+
isPrimary: i === 0,
|
|
199
|
+
hasFallbackCandidates,
|
|
200
|
+
now,
|
|
201
|
+
throttleKey: probeThrottleKey,
|
|
202
|
+
authStore,
|
|
203
|
+
profileIds,
|
|
166
204
|
});
|
|
167
|
-
|
|
205
|
+
if (!shouldProbe) {
|
|
206
|
+
// Skip without attempting
|
|
207
|
+
attempts.push({
|
|
208
|
+
provider: candidate.provider,
|
|
209
|
+
model: candidate.model,
|
|
210
|
+
error: `Provider ${candidate.provider} is in cooldown (all profiles unavailable)`,
|
|
211
|
+
reason: "rate_limit",
|
|
212
|
+
});
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
// Primary model probe: attempt it despite cooldown to detect recovery.
|
|
216
|
+
// If it fails, the error is caught below and we fall through to the
|
|
217
|
+
// next candidate as usual.
|
|
218
|
+
lastProbeAttempt.set(probeThrottleKey, now);
|
|
168
219
|
}
|
|
169
220
|
}
|
|
170
221
|
try {
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
|
|
2
|
+
import { afterEach, beforeEach, vi } from "vitest";
|
|
3
|
+
export async function withModelsTempHome(fn) {
|
|
4
|
+
return withTempHomeBase(fn, { prefix: "openclaw-models-" });
|
|
5
|
+
}
|
|
6
|
+
export function installModelsConfigTestHooks(opts) {
|
|
7
|
+
let previousHome;
|
|
8
|
+
const originalFetch = globalThis.fetch;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
previousHome = process.env.HOME;
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
process.env.HOME = previousHome;
|
|
14
|
+
if (opts?.restoreFetch && originalFetch) {
|
|
15
|
+
globalThis.fetch = originalFetch;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export async function withTempEnv(vars, fn) {
|
|
20
|
+
const previous = {};
|
|
21
|
+
for (const envVar of vars) {
|
|
22
|
+
previous[envVar] = process.env[envVar];
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
return await fn();
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
for (const envVar of vars) {
|
|
29
|
+
const value = previous[envVar];
|
|
30
|
+
if (value === undefined) {
|
|
31
|
+
delete process.env[envVar];
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
process.env[envVar] = value;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function unsetEnv(vars) {
|
|
40
|
+
for (const envVar of vars) {
|
|
41
|
+
delete process.env[envVar];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export const COPILOT_TOKEN_ENV_VARS = ["COPILOT_GITHUB_TOKEN", "GH_TOKEN", "GITHUB_TOKEN"];
|
|
45
|
+
export async function withUnsetCopilotTokenEnv(fn) {
|
|
46
|
+
return withTempEnv(COPILOT_TOKEN_ENV_VARS, async () => {
|
|
47
|
+
unsetEnv(COPILOT_TOKEN_ENV_VARS);
|
|
48
|
+
return fn();
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export function mockCopilotTokenExchangeSuccess() {
|
|
52
|
+
const fetchMock = vi.fn().mockResolvedValue({
|
|
53
|
+
ok: true,
|
|
54
|
+
status: 200,
|
|
55
|
+
json: async () => ({
|
|
56
|
+
token: "copilot-token;proxy-ep=proxy.copilot.example",
|
|
57
|
+
expires_at: Math.floor(Date.now() / 1000) + 3600,
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
globalThis.fetch = fetchMock;
|
|
61
|
+
return fetchMock;
|
|
62
|
+
}
|
|
63
|
+
export const MODELS_CONFIG_IMPLICIT_ENV_VARS = [
|
|
64
|
+
"CLOUDFLARE_AI_GATEWAY_API_KEY",
|
|
65
|
+
"COPILOT_GITHUB_TOKEN",
|
|
66
|
+
"GH_TOKEN",
|
|
67
|
+
"GITHUB_TOKEN",
|
|
68
|
+
"HF_TOKEN",
|
|
69
|
+
"HUGGINGFACE_HUB_TOKEN",
|
|
70
|
+
"MINIMAX_API_KEY",
|
|
71
|
+
"MOONSHOT_API_KEY",
|
|
72
|
+
"NVIDIA_API_KEY",
|
|
73
|
+
"OLLAMA_API_KEY",
|
|
74
|
+
"POOLBOT_AGENT_DIR",
|
|
75
|
+
"PI_CODING_AGENT_DIR",
|
|
76
|
+
"QIANFAN_API_KEY",
|
|
77
|
+
"SYNTHETIC_API_KEY",
|
|
78
|
+
"TOGETHER_API_KEY",
|
|
79
|
+
"VENICE_API_KEY",
|
|
80
|
+
"VLLM_API_KEY",
|
|
81
|
+
"XIAOMI_API_KEY",
|
|
82
|
+
// Avoid ambient AWS creds unintentionally enabling Bedrock discovery.
|
|
83
|
+
"AWS_ACCESS_KEY_ID",
|
|
84
|
+
"AWS_CONFIG_FILE",
|
|
85
|
+
"AWS_BEARER_TOKEN_BEDROCK",
|
|
86
|
+
"AWS_DEFAULT_REGION",
|
|
87
|
+
"AWS_PROFILE",
|
|
88
|
+
"AWS_REGION",
|
|
89
|
+
"AWS_SESSION_TOKEN",
|
|
90
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
91
|
+
"AWS_SHARED_CREDENTIALS_FILE",
|
|
92
|
+
];
|
|
93
|
+
export const CUSTOM_PROXY_MODELS_CONFIG = {
|
|
94
|
+
models: {
|
|
95
|
+
providers: {
|
|
96
|
+
"custom-proxy": {
|
|
97
|
+
baseUrl: "http://localhost:4000/v1",
|
|
98
|
+
apiKey: "TEST_KEY",
|
|
99
|
+
api: "openai-completions",
|
|
100
|
+
models: [
|
|
101
|
+
{
|
|
102
|
+
id: "llama-3.1-8b",
|
|
103
|
+
name: "Llama 3.1 8B (Proxy)",
|
|
104
|
+
api: "openai-completions",
|
|
105
|
+
reasoning: false,
|
|
106
|
+
input: ["text"],
|
|
107
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
108
|
+
contextWindow: 128000,
|
|
109
|
+
maxTokens: 32000,
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createAssistantMessageEventStream } from "@mariozechner/pi-ai";
|
|
2
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createAssistantMessageEventStream } from "@mariozechner/pi-ai";
|
|
3
3
|
export const OLLAMA_NATIVE_BASE_URL = "http://127.0.0.1:11434";
|
|
4
4
|
function extractTextContent(content) {
|
|
5
5
|
if (typeof content === "string") {
|
|
@@ -102,8 +102,12 @@ function extractOllamaTools(tools) {
|
|
|
102
102
|
// ── Response conversion ─────────────────────────────────────────────────────
|
|
103
103
|
export function buildAssistantMessage(response, modelInfo) {
|
|
104
104
|
const content = [];
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
// Qwen 3 (and potentially other reasoning models) may return their final
|
|
106
|
+
// answer in a `reasoning` field with an empty `content`. Fall back to
|
|
107
|
+
// `reasoning` so the response isn't silently dropped.
|
|
108
|
+
const text = response.message.content || response.message.reasoning || "";
|
|
109
|
+
if (text) {
|
|
110
|
+
content.push({ type: "text", text });
|
|
107
111
|
}
|
|
108
112
|
const toolCalls = response.message.tool_calls;
|
|
109
113
|
if (toolCalls && toolCalls.length > 0) {
|
|
@@ -230,6 +234,10 @@ export function createOllamaStreamFn(baseUrl) {
|
|
|
230
234
|
if (chunk.message?.content) {
|
|
231
235
|
accumulatedContent += chunk.message.content;
|
|
232
236
|
}
|
|
237
|
+
else if (chunk.message?.reasoning) {
|
|
238
|
+
// Qwen 3 reasoning mode: content may be empty, output in reasoning
|
|
239
|
+
accumulatedContent += chunk.message.reasoning;
|
|
240
|
+
}
|
|
233
241
|
// Ollama sends tool_calls in intermediate (done:false) chunks,
|
|
234
242
|
// NOT in the final done:true chunk. Collect from all chunks.
|
|
235
243
|
if (chunk.message?.tool_calls) {
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { resolvePluginTools } from "../plugins/tools.js";
|
|
2
|
+
import { resolveSessionAgentId } from "./agent-scope.js";
|
|
3
|
+
import { createAgentsListTool } from "./tools/agents-list-tool.js";
|
|
4
|
+
import { createBrowserTool } from "./tools/browser-tool.js";
|
|
5
|
+
import { createCanvasTool } from "./tools/canvas-tool.js";
|
|
6
|
+
import { createCronTool } from "./tools/cron-tool.js";
|
|
7
|
+
import { createGatewayTool } from "./tools/gateway-tool.js";
|
|
8
|
+
import { createImageTool } from "./tools/image-tool.js";
|
|
9
|
+
import { createMessageTool } from "./tools/message-tool.js";
|
|
10
|
+
import { createNodesTool } from "./tools/nodes-tool.js";
|
|
11
|
+
import { createSessionStatusTool } from "./tools/session-status-tool.js";
|
|
12
|
+
import { createSessionsHistoryTool } from "./tools/sessions-history-tool.js";
|
|
13
|
+
import { createSessionsListTool } from "./tools/sessions-list-tool.js";
|
|
14
|
+
import { createSessionsSendTool } from "./tools/sessions-send-tool.js";
|
|
15
|
+
import { createSessionsSpawnTool } from "./tools/sessions-spawn-tool.js";
|
|
16
|
+
import { createSubagentsTool } from "./tools/subagents-tool.js";
|
|
17
|
+
import { createTtsTool } from "./tools/tts-tool.js";
|
|
18
|
+
import { createWebFetchTool, createWebSearchTool } from "./tools/web-tools.js";
|
|
19
|
+
import { resolveWorkspaceRoot } from "./workspace-dir.js";
|
|
20
|
+
export function createOpenClawTools(options) {
|
|
21
|
+
const workspaceDir = resolveWorkspaceRoot(options?.workspaceDir);
|
|
22
|
+
const imageTool = options?.agentDir?.trim()
|
|
23
|
+
? createImageTool({
|
|
24
|
+
config: options?.config,
|
|
25
|
+
agentDir: options.agentDir,
|
|
26
|
+
workspaceDir,
|
|
27
|
+
sandbox: options?.sandboxRoot && options?.sandboxFsBridge
|
|
28
|
+
? { root: options.sandboxRoot, bridge: options.sandboxFsBridge }
|
|
29
|
+
: undefined,
|
|
30
|
+
modelHasVision: options?.modelHasVision,
|
|
31
|
+
})
|
|
32
|
+
: null;
|
|
33
|
+
const webSearchTool = createWebSearchTool({
|
|
34
|
+
config: options?.config,
|
|
35
|
+
sandboxed: options?.sandboxed,
|
|
36
|
+
});
|
|
37
|
+
const webFetchTool = createWebFetchTool({
|
|
38
|
+
config: options?.config,
|
|
39
|
+
sandboxed: options?.sandboxed,
|
|
40
|
+
});
|
|
41
|
+
const messageTool = options?.disableMessageTool
|
|
42
|
+
? null
|
|
43
|
+
: createMessageTool({
|
|
44
|
+
agentAccountId: options?.agentAccountId,
|
|
45
|
+
agentSessionKey: options?.agentSessionKey,
|
|
46
|
+
config: options?.config,
|
|
47
|
+
currentChannelId: options?.currentChannelId,
|
|
48
|
+
currentChannelProvider: options?.agentChannel,
|
|
49
|
+
currentThreadTs: options?.currentThreadTs,
|
|
50
|
+
replyToMode: options?.replyToMode,
|
|
51
|
+
hasRepliedRef: options?.hasRepliedRef,
|
|
52
|
+
sandboxRoot: options?.sandboxRoot,
|
|
53
|
+
requireExplicitTarget: options?.requireExplicitMessageTarget,
|
|
54
|
+
});
|
|
55
|
+
const tools = [
|
|
56
|
+
createBrowserTool({
|
|
57
|
+
sandboxBridgeUrl: options?.sandboxBrowserBridgeUrl,
|
|
58
|
+
allowHostControl: options?.allowHostBrowserControl,
|
|
59
|
+
}),
|
|
60
|
+
createCanvasTool(),
|
|
61
|
+
createNodesTool({
|
|
62
|
+
agentSessionKey: options?.agentSessionKey,
|
|
63
|
+
config: options?.config,
|
|
64
|
+
}),
|
|
65
|
+
createCronTool({
|
|
66
|
+
agentSessionKey: options?.agentSessionKey,
|
|
67
|
+
}),
|
|
68
|
+
...(messageTool ? [messageTool] : []),
|
|
69
|
+
createTtsTool({
|
|
70
|
+
agentChannel: options?.agentChannel,
|
|
71
|
+
config: options?.config,
|
|
72
|
+
}),
|
|
73
|
+
createGatewayTool({
|
|
74
|
+
agentSessionKey: options?.agentSessionKey,
|
|
75
|
+
config: options?.config,
|
|
76
|
+
}),
|
|
77
|
+
createAgentsListTool({
|
|
78
|
+
agentSessionKey: options?.agentSessionKey,
|
|
79
|
+
requesterAgentIdOverride: options?.requesterAgentIdOverride,
|
|
80
|
+
}),
|
|
81
|
+
createSessionsListTool({
|
|
82
|
+
agentSessionKey: options?.agentSessionKey,
|
|
83
|
+
sandboxed: options?.sandboxed,
|
|
84
|
+
}),
|
|
85
|
+
createSessionsHistoryTool({
|
|
86
|
+
agentSessionKey: options?.agentSessionKey,
|
|
87
|
+
sandboxed: options?.sandboxed,
|
|
88
|
+
}),
|
|
89
|
+
createSessionsSendTool({
|
|
90
|
+
agentSessionKey: options?.agentSessionKey,
|
|
91
|
+
agentChannel: options?.agentChannel,
|
|
92
|
+
sandboxed: options?.sandboxed,
|
|
93
|
+
}),
|
|
94
|
+
createSessionsSpawnTool({
|
|
95
|
+
agentSessionKey: options?.agentSessionKey,
|
|
96
|
+
agentChannel: options?.agentChannel,
|
|
97
|
+
agentAccountId: options?.agentAccountId,
|
|
98
|
+
agentTo: options?.agentTo,
|
|
99
|
+
agentThreadId: options?.agentThreadId,
|
|
100
|
+
agentGroupId: options?.agentGroupId,
|
|
101
|
+
agentGroupChannel: options?.agentGroupChannel,
|
|
102
|
+
agentGroupSpace: options?.agentGroupSpace,
|
|
103
|
+
sandboxed: options?.sandboxed,
|
|
104
|
+
requesterAgentIdOverride: options?.requesterAgentIdOverride,
|
|
105
|
+
}),
|
|
106
|
+
createSubagentsTool({
|
|
107
|
+
agentSessionKey: options?.agentSessionKey,
|
|
108
|
+
}),
|
|
109
|
+
createSessionStatusTool({
|
|
110
|
+
agentSessionKey: options?.agentSessionKey,
|
|
111
|
+
config: options?.config,
|
|
112
|
+
}),
|
|
113
|
+
...(webSearchTool ? [webSearchTool] : []),
|
|
114
|
+
...(webFetchTool ? [webFetchTool] : []),
|
|
115
|
+
...(imageTool ? [imageTool] : []),
|
|
116
|
+
];
|
|
117
|
+
const pluginTools = resolvePluginTools({
|
|
118
|
+
context: {
|
|
119
|
+
config: options?.config,
|
|
120
|
+
workspaceDir,
|
|
121
|
+
agentDir: options?.agentDir,
|
|
122
|
+
agentId: resolveSessionAgentId({
|
|
123
|
+
sessionKey: options?.agentSessionKey,
|
|
124
|
+
config: options?.config,
|
|
125
|
+
}),
|
|
126
|
+
sessionKey: options?.agentSessionKey,
|
|
127
|
+
messageChannel: options?.agentChannel,
|
|
128
|
+
agentAccountId: options?.agentAccountId,
|
|
129
|
+
sandboxed: options?.sandboxed,
|
|
130
|
+
},
|
|
131
|
+
existingToolNames: new Set(tools.map((tool) => tool.name)),
|
|
132
|
+
toolAllowlist: options?.pluginToolAllowlist,
|
|
133
|
+
});
|
|
134
|
+
return [...tools, ...pluginTools];
|
|
135
|
+
}
|