@poolzin/pool-bot 2026.2.21 → 2026.2.23
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 +25 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/device-pair/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- 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/irc/package.json +1 -1
- package/extensions/irc/src/accounts.ts +1 -1
- package/extensions/irc/src/onboarding.ts +4 -4
- 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 +10 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +10 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +10 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +10 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +10 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +10 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +10 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
- package/dist/agents/openclaw-tools.js +0 -151
- package/dist/agents/tool-security.js +0 -96
- package/dist/gateway/url-validation.js +0 -94
- package/dist/infra/openclaw-root.js +0 -109
- package/dist/infra/tmp-openclaw-dir.js +0 -81
- package/dist/media/path-sanitization.js +0 -78
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { resolveAllowedModelRef, resolveDefaultModelForAgent } from "../agents/model-selection.js";
|
|
3
2
|
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
|
|
3
|
+
import { resolveAllowedModelRef, resolveDefaultModelForAgent, resolveSubagentConfiguredModelSelection, } from "../agents/model-selection.js";
|
|
4
4
|
import { normalizeGroupActivation } from "../auto-reply/group-activation.js";
|
|
5
5
|
import { formatThinkingLevels, formatXHighModelHint, normalizeElevatedLevel, normalizeReasoningLevel, normalizeThinkLevel, normalizeUsageDisplay, supportsXHighThinking, } from "../auto-reply/thinking.js";
|
|
6
6
|
import { isSubagentSessionKey, normalizeAgentId, parseAgentSessionKey, } from "../routing/session-key.js";
|
|
7
7
|
import { applyVerboseOverride, parseVerboseOverride } from "../sessions/level-overrides.js";
|
|
8
|
+
import { applyModelOverrideToSessionEntry } from "../sessions/model-overrides.js";
|
|
8
9
|
import { normalizeSendPolicy } from "../sessions/send-policy.js";
|
|
9
10
|
import { parseSessionLabel } from "../sessions/session-label.js";
|
|
10
|
-
import { applyModelOverrideToSessionEntry } from "../sessions/model-overrides.js";
|
|
11
11
|
import { ErrorCodes, errorShape, } from "./protocol/index.js";
|
|
12
12
|
function invalid(message) {
|
|
13
13
|
return { ok: false, error: errorShape(ErrorCodes.INVALID_REQUEST, message) };
|
|
@@ -39,6 +39,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
39
39
|
const parsedAgent = parseAgentSessionKey(storeKey);
|
|
40
40
|
const sessionAgentId = normalizeAgentId(parsedAgent?.agentId ?? resolveDefaultAgentId(cfg));
|
|
41
41
|
const resolvedDefault = resolveDefaultModelForAgent({ cfg, agentId: sessionAgentId });
|
|
42
|
+
const subagentModelHint = isSubagentSessionKey(storeKey)
|
|
43
|
+
? resolveSubagentConfiguredModelSelection({ cfg, agentId: sessionAgentId })
|
|
44
|
+
: undefined;
|
|
42
45
|
const existing = store[storeKey];
|
|
43
46
|
const next = existing
|
|
44
47
|
? {
|
|
@@ -49,13 +52,15 @@ export async function applySessionsPatchToStore(params) {
|
|
|
49
52
|
if ("spawnedBy" in patch) {
|
|
50
53
|
const raw = patch.spawnedBy;
|
|
51
54
|
if (raw === null) {
|
|
52
|
-
if (existing?.spawnedBy)
|
|
55
|
+
if (existing?.spawnedBy) {
|
|
53
56
|
return invalid("spawnedBy cannot be cleared once set");
|
|
57
|
+
}
|
|
54
58
|
}
|
|
55
59
|
else if (raw !== undefined) {
|
|
56
60
|
const trimmed = String(raw).trim();
|
|
57
|
-
if (!trimmed)
|
|
61
|
+
if (!trimmed) {
|
|
58
62
|
return invalid("invalid spawnedBy: empty");
|
|
63
|
+
}
|
|
59
64
|
if (!isSubagentSessionKey(storeKey)) {
|
|
60
65
|
return invalid("spawnedBy is only supported for subagent:* sessions");
|
|
61
66
|
}
|
|
@@ -65,6 +70,28 @@ export async function applySessionsPatchToStore(params) {
|
|
|
65
70
|
next.spawnedBy = trimmed;
|
|
66
71
|
}
|
|
67
72
|
}
|
|
73
|
+
if ("spawnDepth" in patch) {
|
|
74
|
+
const raw = patch.spawnDepth;
|
|
75
|
+
if (raw === null) {
|
|
76
|
+
if (typeof existing?.spawnDepth === "number") {
|
|
77
|
+
return invalid("spawnDepth cannot be cleared once set");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (raw !== undefined) {
|
|
81
|
+
if (!isSubagentSessionKey(storeKey)) {
|
|
82
|
+
return invalid("spawnDepth is only supported for subagent:* sessions");
|
|
83
|
+
}
|
|
84
|
+
const numeric = Number(raw);
|
|
85
|
+
if (!Number.isInteger(numeric) || numeric < 0) {
|
|
86
|
+
return invalid("invalid spawnDepth (use an integer >= 0)");
|
|
87
|
+
}
|
|
88
|
+
const normalized = numeric;
|
|
89
|
+
if (typeof existing?.spawnDepth === "number" && existing.spawnDepth !== normalized) {
|
|
90
|
+
return invalid("spawnDepth cannot be changed once set");
|
|
91
|
+
}
|
|
92
|
+
next.spawnDepth = normalized;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
68
95
|
if ("label" in patch) {
|
|
69
96
|
const raw = patch.label;
|
|
70
97
|
if (raw === null) {
|
|
@@ -72,11 +99,13 @@ export async function applySessionsPatchToStore(params) {
|
|
|
72
99
|
}
|
|
73
100
|
else if (raw !== undefined) {
|
|
74
101
|
const parsed = parseSessionLabel(raw);
|
|
75
|
-
if (!parsed.ok)
|
|
102
|
+
if (!parsed.ok) {
|
|
76
103
|
return invalid(parsed.error);
|
|
104
|
+
}
|
|
77
105
|
for (const [key, entry] of Object.entries(store)) {
|
|
78
|
-
if (key === storeKey)
|
|
106
|
+
if (key === storeKey) {
|
|
79
107
|
continue;
|
|
108
|
+
}
|
|
80
109
|
if (entry?.label === parsed.label) {
|
|
81
110
|
return invalid(`label already in use: ${parsed.label}`);
|
|
82
111
|
}
|
|
@@ -87,6 +116,7 @@ export async function applySessionsPatchToStore(params) {
|
|
|
87
116
|
if ("thinkingLevel" in patch) {
|
|
88
117
|
const raw = patch.thinkingLevel;
|
|
89
118
|
if (raw === null) {
|
|
119
|
+
// Clear the override and fall back to model default
|
|
90
120
|
delete next.thinkingLevel;
|
|
91
121
|
}
|
|
92
122
|
else if (raw !== undefined) {
|
|
@@ -102,8 +132,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
102
132
|
if ("verboseLevel" in patch) {
|
|
103
133
|
const raw = patch.verboseLevel;
|
|
104
134
|
const parsed = parseVerboseOverride(raw);
|
|
105
|
-
if (!parsed.ok)
|
|
135
|
+
if (!parsed.ok) {
|
|
106
136
|
return invalid(parsed.error);
|
|
137
|
+
}
|
|
107
138
|
applyVerboseOverride(next, parsed.value);
|
|
108
139
|
}
|
|
109
140
|
if ("reasoningLevel" in patch) {
|
|
@@ -116,10 +147,12 @@ export async function applySessionsPatchToStore(params) {
|
|
|
116
147
|
if (!normalized) {
|
|
117
148
|
return invalid('invalid reasoningLevel (use "on"|"off"|"stream")');
|
|
118
149
|
}
|
|
119
|
-
if (normalized === "off")
|
|
150
|
+
if (normalized === "off") {
|
|
120
151
|
delete next.reasoningLevel;
|
|
121
|
-
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
122
154
|
next.reasoningLevel = normalized;
|
|
155
|
+
}
|
|
123
156
|
}
|
|
124
157
|
}
|
|
125
158
|
if ("responseUsage" in patch) {
|
|
@@ -129,12 +162,15 @@ export async function applySessionsPatchToStore(params) {
|
|
|
129
162
|
}
|
|
130
163
|
else if (raw !== undefined) {
|
|
131
164
|
const normalized = normalizeUsageDisplay(String(raw));
|
|
132
|
-
if (!normalized)
|
|
165
|
+
if (!normalized) {
|
|
133
166
|
return invalid('invalid responseUsage (use "off"|"tokens"|"full")');
|
|
134
|
-
|
|
167
|
+
}
|
|
168
|
+
if (normalized === "off") {
|
|
135
169
|
delete next.responseUsage;
|
|
136
|
-
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
137
172
|
next.responseUsage = normalized;
|
|
173
|
+
}
|
|
138
174
|
}
|
|
139
175
|
}
|
|
140
176
|
if ("elevatedLevel" in patch) {
|
|
@@ -144,8 +180,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
144
180
|
}
|
|
145
181
|
else if (raw !== undefined) {
|
|
146
182
|
const normalized = normalizeElevatedLevel(String(raw));
|
|
147
|
-
if (!normalized)
|
|
183
|
+
if (!normalized) {
|
|
148
184
|
return invalid('invalid elevatedLevel (use "on"|"off"|"ask"|"full")');
|
|
185
|
+
}
|
|
149
186
|
// Persist "off" explicitly so patches can override defaults.
|
|
150
187
|
next.elevatedLevel = normalized;
|
|
151
188
|
}
|
|
@@ -157,8 +194,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
157
194
|
}
|
|
158
195
|
else if (raw !== undefined) {
|
|
159
196
|
const normalized = normalizeExecHost(String(raw));
|
|
160
|
-
if (!normalized)
|
|
197
|
+
if (!normalized) {
|
|
161
198
|
return invalid('invalid execHost (use "sandbox"|"gateway"|"node")');
|
|
199
|
+
}
|
|
162
200
|
next.execHost = normalized;
|
|
163
201
|
}
|
|
164
202
|
}
|
|
@@ -169,8 +207,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
169
207
|
}
|
|
170
208
|
else if (raw !== undefined) {
|
|
171
209
|
const normalized = normalizeExecSecurity(String(raw));
|
|
172
|
-
if (!normalized)
|
|
210
|
+
if (!normalized) {
|
|
173
211
|
return invalid('invalid execSecurity (use "deny"|"allowlist"|"full")');
|
|
212
|
+
}
|
|
174
213
|
next.execSecurity = normalized;
|
|
175
214
|
}
|
|
176
215
|
}
|
|
@@ -181,8 +220,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
181
220
|
}
|
|
182
221
|
else if (raw !== undefined) {
|
|
183
222
|
const normalized = normalizeExecAsk(String(raw));
|
|
184
|
-
if (!normalized)
|
|
223
|
+
if (!normalized) {
|
|
185
224
|
return invalid('invalid execAsk (use "off"|"on-miss"|"always")');
|
|
225
|
+
}
|
|
186
226
|
next.execAsk = normalized;
|
|
187
227
|
}
|
|
188
228
|
}
|
|
@@ -193,8 +233,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
193
233
|
}
|
|
194
234
|
else if (raw !== undefined) {
|
|
195
235
|
const trimmed = String(raw).trim();
|
|
196
|
-
if (!trimmed)
|
|
236
|
+
if (!trimmed) {
|
|
197
237
|
return invalid("invalid execNode: empty");
|
|
238
|
+
}
|
|
198
239
|
next.execNode = trimmed;
|
|
199
240
|
}
|
|
200
241
|
}
|
|
@@ -212,8 +253,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
212
253
|
}
|
|
213
254
|
else if (raw !== undefined) {
|
|
214
255
|
const trimmed = String(raw).trim();
|
|
215
|
-
if (!trimmed)
|
|
256
|
+
if (!trimmed) {
|
|
216
257
|
return invalid("invalid model: empty");
|
|
258
|
+
}
|
|
217
259
|
if (!params.loadGatewayModelCatalog) {
|
|
218
260
|
return {
|
|
219
261
|
ok: false,
|
|
@@ -226,7 +268,7 @@ export async function applySessionsPatchToStore(params) {
|
|
|
226
268
|
catalog,
|
|
227
269
|
raw: trimmed,
|
|
228
270
|
defaultProvider: resolvedDefault.provider,
|
|
229
|
-
defaultModel: resolvedDefault.model,
|
|
271
|
+
defaultModel: subagentModelHint ?? resolvedDefault.model,
|
|
230
272
|
});
|
|
231
273
|
if ("error" in resolved) {
|
|
232
274
|
return invalid(resolved.error);
|
|
@@ -260,8 +302,9 @@ export async function applySessionsPatchToStore(params) {
|
|
|
260
302
|
}
|
|
261
303
|
else if (raw !== undefined) {
|
|
262
304
|
const normalized = normalizeSendPolicy(String(raw));
|
|
263
|
-
if (!normalized)
|
|
305
|
+
if (!normalized) {
|
|
264
306
|
return invalid('invalid sendPolicy (use "allow"|"deny")');
|
|
307
|
+
}
|
|
265
308
|
next.sendPolicy = normalized;
|
|
266
309
|
}
|
|
267
310
|
}
|
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
export async function withTempConfig(params) {
|
|
5
5
|
const prevConfigPath = process.env.POOLBOT_CONFIG_PATH;
|
|
6
6
|
const prevDisableCache = process.env.POOLBOT_DISABLE_CONFIG_CACHE;
|
|
7
|
-
const dir = await mkdtemp(path.join(os.tmpdir(), params.prefix ?? "
|
|
7
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), params.prefix ?? "poolbot-test-config-"));
|
|
8
8
|
const configPath = path.join(dir, "poolbot.json");
|
|
9
9
|
process.env.POOLBOT_CONFIG_PATH = configPath;
|
|
10
10
|
process.env.POOLBOT_DISABLE_CONFIG_CACHE = "1";
|
|
@@ -1,41 +1,90 @@
|
|
|
1
1
|
import { createPoolBotTools } from "../agents/poolbot-tools.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { resolveEffectiveToolPolicy, resolveGroupToolPolicy, resolveSubagentToolPolicy, } from "../agents/pi-tools.policy.js";
|
|
3
|
+
import { applyToolPolicyPipeline, buildDefaultToolPolicyPipelineSteps, } from "../agents/tool-policy-pipeline.js";
|
|
4
|
+
import { collectExplicitAllowlist, mergeAlsoAllowPolicy, resolveToolProfilePolicy, } from "../agents/tool-policy.js";
|
|
5
|
+
import { ToolInputError } from "../agents/tools/common.js";
|
|
4
6
|
import { loadConfig } from "../config/config.js";
|
|
5
7
|
import { resolveMainSessionKey } from "../config/sessions.js";
|
|
6
8
|
import { logWarn } from "../logger.js";
|
|
9
|
+
import { isTestDefaultMemorySlotDisabled } from "../plugins/config-state.js";
|
|
7
10
|
import { getPluginToolMeta } from "../plugins/tools.js";
|
|
8
11
|
import { isSubagentSessionKey } from "../routing/session-key.js";
|
|
12
|
+
import { DEFAULT_GATEWAY_HTTP_TOOL_DENY } from "../security/dangerous-tools.js";
|
|
9
13
|
import { normalizeMessageChannel } from "../utils/message-channel.js";
|
|
10
14
|
import { authorizeGatewayConnect } from "./auth.js";
|
|
15
|
+
import { readJsonBodyOrError, sendGatewayAuthFailure, sendInvalidRequest, sendJson, sendMethodNotAllowed, } from "./http-common.js";
|
|
11
16
|
import { getBearerToken, getHeader } from "./http-utils.js";
|
|
12
|
-
import { readJsonBodyOrError, sendInvalidRequest, sendJson, sendMethodNotAllowed, sendUnauthorized, } from "./http-common.js";
|
|
13
17
|
const DEFAULT_BODY_BYTES = 2 * 1024 * 1024;
|
|
18
|
+
const MEMORY_TOOL_NAMES = new Set(["memory_search", "memory_get"]);
|
|
14
19
|
function resolveSessionKeyFromBody(body) {
|
|
15
|
-
if (typeof body.sessionKey === "string" && body.sessionKey.trim())
|
|
20
|
+
if (typeof body.sessionKey === "string" && body.sessionKey.trim()) {
|
|
16
21
|
return body.sessionKey.trim();
|
|
22
|
+
}
|
|
17
23
|
return undefined;
|
|
18
24
|
}
|
|
25
|
+
function resolveMemoryToolDisableReasons(cfg) {
|
|
26
|
+
if (!process.env.VITEST) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const reasons = [];
|
|
30
|
+
const plugins = cfg.plugins;
|
|
31
|
+
const slotRaw = plugins?.slots?.memory;
|
|
32
|
+
const slotDisabled = slotRaw === null || (typeof slotRaw === "string" && slotRaw.trim().toLowerCase() === "none");
|
|
33
|
+
const pluginsDisabled = plugins?.enabled === false;
|
|
34
|
+
const defaultDisabled = isTestDefaultMemorySlotDisabled(cfg);
|
|
35
|
+
if (pluginsDisabled) {
|
|
36
|
+
reasons.push("plugins.enabled=false");
|
|
37
|
+
}
|
|
38
|
+
if (slotDisabled) {
|
|
39
|
+
reasons.push(slotRaw === null ? "plugins.slots.memory=null" : 'plugins.slots.memory="none"');
|
|
40
|
+
}
|
|
41
|
+
if (!pluginsDisabled && !slotDisabled && defaultDisabled) {
|
|
42
|
+
reasons.push("memory plugin disabled by test default");
|
|
43
|
+
}
|
|
44
|
+
return reasons;
|
|
45
|
+
}
|
|
19
46
|
function mergeActionIntoArgsIfSupported(params) {
|
|
20
47
|
const { toolSchema, action, args } = params;
|
|
21
|
-
if (!action)
|
|
48
|
+
if (!action) {
|
|
22
49
|
return args;
|
|
23
|
-
|
|
50
|
+
}
|
|
51
|
+
if (args.action !== undefined) {
|
|
24
52
|
return args;
|
|
53
|
+
}
|
|
25
54
|
// TypeBox schemas are plain objects; many tools define an `action` property.
|
|
26
55
|
const schemaObj = toolSchema;
|
|
27
56
|
const hasAction = Boolean(schemaObj &&
|
|
28
57
|
typeof schemaObj === "object" &&
|
|
29
58
|
schemaObj.properties &&
|
|
30
59
|
"action" in schemaObj.properties);
|
|
31
|
-
if (!hasAction)
|
|
60
|
+
if (!hasAction) {
|
|
32
61
|
return args;
|
|
62
|
+
}
|
|
33
63
|
return { ...args, action };
|
|
34
64
|
}
|
|
65
|
+
function getErrorMessage(err) {
|
|
66
|
+
if (err instanceof Error) {
|
|
67
|
+
return err.message || String(err);
|
|
68
|
+
}
|
|
69
|
+
if (typeof err === "string") {
|
|
70
|
+
return err;
|
|
71
|
+
}
|
|
72
|
+
return String(err);
|
|
73
|
+
}
|
|
74
|
+
function isToolInputError(err) {
|
|
75
|
+
if (err instanceof ToolInputError) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return (typeof err === "object" &&
|
|
79
|
+
err !== null &&
|
|
80
|
+
"name" in err &&
|
|
81
|
+
err.name === "ToolInputError");
|
|
82
|
+
}
|
|
35
83
|
export async function handleToolsInvokeHttpRequest(req, res, opts) {
|
|
36
84
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
37
|
-
if (url.pathname !== "/tools/invoke")
|
|
85
|
+
if (url.pathname !== "/tools/invoke") {
|
|
38
86
|
return false;
|
|
87
|
+
}
|
|
39
88
|
if (req.method !== "POST") {
|
|
40
89
|
sendMethodNotAllowed(res, "POST");
|
|
41
90
|
return true;
|
|
@@ -47,25 +96,42 @@ export async function handleToolsInvokeHttpRequest(req, res, opts) {
|
|
|
47
96
|
connectAuth: token ? { token, password: token } : null,
|
|
48
97
|
req,
|
|
49
98
|
trustedProxies: opts.trustedProxies ?? cfg.gateway?.trustedProxies,
|
|
99
|
+
rateLimiter: opts.rateLimiter,
|
|
50
100
|
});
|
|
51
101
|
if (!authResult.ok) {
|
|
52
|
-
|
|
102
|
+
sendGatewayAuthFailure(res, authResult);
|
|
53
103
|
return true;
|
|
54
104
|
}
|
|
55
105
|
const bodyUnknown = await readJsonBodyOrError(req, res, opts.maxBodyBytes ?? DEFAULT_BODY_BYTES);
|
|
56
|
-
if (bodyUnknown === undefined)
|
|
106
|
+
if (bodyUnknown === undefined) {
|
|
57
107
|
return true;
|
|
108
|
+
}
|
|
58
109
|
const body = (bodyUnknown ?? {});
|
|
59
110
|
const toolName = typeof body.tool === "string" ? body.tool.trim() : "";
|
|
60
111
|
if (!toolName) {
|
|
61
112
|
sendInvalidRequest(res, "tools.invoke requires body.tool");
|
|
62
113
|
return true;
|
|
63
114
|
}
|
|
115
|
+
if (process.env.VITEST && MEMORY_TOOL_NAMES.has(toolName)) {
|
|
116
|
+
const reasons = resolveMemoryToolDisableReasons(cfg);
|
|
117
|
+
if (reasons.length > 0) {
|
|
118
|
+
const suffix = reasons.length > 0 ? ` (${reasons.join(", ")})` : "";
|
|
119
|
+
sendJson(res, 400, {
|
|
120
|
+
ok: false,
|
|
121
|
+
error: {
|
|
122
|
+
type: "invalid_request",
|
|
123
|
+
message: `memory tools are disabled in tests${suffix}. ` +
|
|
124
|
+
'Enable by setting plugins.slots.memory="memory-core" (and ensure plugins.enabled is not false).',
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
64
130
|
const action = typeof body.action === "string" ? body.action.trim() : undefined;
|
|
65
131
|
const argsRaw = body.args;
|
|
66
|
-
const args =
|
|
132
|
+
const args = argsRaw && typeof argsRaw === "object" && !Array.isArray(argsRaw)
|
|
67
133
|
? argsRaw
|
|
68
|
-
: {}
|
|
134
|
+
: {};
|
|
69
135
|
const rawSessionKey = resolveSessionKeyFromBody(body);
|
|
70
136
|
const sessionKey = !rawSessionKey || rawSessionKey === "main" ? resolveMainSessionKey(cfg) : rawSessionKey;
|
|
71
137
|
// Resolve message channel/account hints (optional headers) for policy inheritance.
|
|
@@ -74,13 +140,8 @@ export async function handleToolsInvokeHttpRequest(req, res, opts) {
|
|
|
74
140
|
const { agentId, globalPolicy, globalProviderPolicy, agentPolicy, agentProviderPolicy, profile, providerProfile, profileAlsoAllow, providerProfileAlsoAllow, } = resolveEffectiveToolPolicy({ config: cfg, sessionKey });
|
|
75
141
|
const profilePolicy = resolveToolProfilePolicy(profile);
|
|
76
142
|
const providerProfilePolicy = resolveToolProfilePolicy(providerProfile);
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
return policy;
|
|
80
|
-
return { ...policy, allow: Array.from(new Set([...policy.allow, ...alsoAllow])) };
|
|
81
|
-
};
|
|
82
|
-
const profilePolicyWithAlsoAllow = mergeAlsoAllow(profilePolicy, profileAlsoAllow);
|
|
83
|
-
const providerProfilePolicyWithAlsoAllow = mergeAlsoAllow(providerProfilePolicy, providerProfileAlsoAllow);
|
|
143
|
+
const profilePolicyWithAlsoAllow = mergeAlsoAllowPolicy(profilePolicy, profileAlsoAllow);
|
|
144
|
+
const providerProfilePolicyWithAlsoAllow = mergeAlsoAllowPolicy(providerProfilePolicy, providerProfileAlsoAllow);
|
|
84
145
|
const groupPolicy = resolveGroupToolPolicy({
|
|
85
146
|
config: cfg,
|
|
86
147
|
sessionKey,
|
|
@@ -107,58 +168,35 @@ export async function handleToolsInvokeHttpRequest(req, res, opts) {
|
|
|
107
168
|
subagentPolicy,
|
|
108
169
|
]),
|
|
109
170
|
});
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
.map((tool) => normalizeToolName(tool.name))
|
|
113
|
-
.filter(Boolean));
|
|
114
|
-
const pluginGroups = buildPluginToolGroups({
|
|
171
|
+
const subagentFiltered = applyToolPolicyPipeline({
|
|
172
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
115
173
|
tools: allTools,
|
|
174
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
116
175
|
toolMeta: (tool) => getPluginToolMeta(tool),
|
|
176
|
+
warn: logWarn,
|
|
177
|
+
steps: [
|
|
178
|
+
...buildDefaultToolPolicyPipelineSteps({
|
|
179
|
+
profilePolicy: profilePolicyWithAlsoAllow,
|
|
180
|
+
profile,
|
|
181
|
+
providerProfilePolicy: providerProfilePolicyWithAlsoAllow,
|
|
182
|
+
providerProfile,
|
|
183
|
+
globalPolicy,
|
|
184
|
+
globalProviderPolicy,
|
|
185
|
+
agentPolicy,
|
|
186
|
+
agentProviderPolicy,
|
|
187
|
+
groupPolicy,
|
|
188
|
+
agentId,
|
|
189
|
+
}),
|
|
190
|
+
{ policy: subagentPolicy, label: "subagent tools.allow" },
|
|
191
|
+
],
|
|
117
192
|
});
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
logWarn(`tools: ${label} allowlist contains unknown entries (${entries}). ${suffix}`);
|
|
126
|
-
}
|
|
127
|
-
return expandPolicyWithPluginGroups(resolved.policy, pluginGroups);
|
|
128
|
-
};
|
|
129
|
-
const profilePolicyExpanded = resolvePolicy(profilePolicyWithAlsoAllow, profile ? `tools.profile (${profile})` : "tools.profile");
|
|
130
|
-
const providerProfileExpanded = resolvePolicy(providerProfilePolicyWithAlsoAllow, providerProfile ? `tools.byProvider.profile (${providerProfile})` : "tools.byProvider.profile");
|
|
131
|
-
const globalPolicyExpanded = resolvePolicy(globalPolicy, "tools.allow");
|
|
132
|
-
const globalProviderExpanded = resolvePolicy(globalProviderPolicy, "tools.byProvider.allow");
|
|
133
|
-
const agentPolicyExpanded = resolvePolicy(agentPolicy, agentId ? `agents.${agentId}.tools.allow` : "agent tools.allow");
|
|
134
|
-
const agentProviderExpanded = resolvePolicy(agentProviderPolicy, agentId ? `agents.${agentId}.tools.byProvider.allow` : "agent tools.byProvider.allow");
|
|
135
|
-
const groupPolicyExpanded = resolvePolicy(groupPolicy, "group tools.allow");
|
|
136
|
-
const subagentPolicyExpanded = expandPolicyWithPluginGroups(subagentPolicy, pluginGroups);
|
|
137
|
-
const toolsFiltered = profilePolicyExpanded
|
|
138
|
-
? filterToolsByPolicy(allTools, profilePolicyExpanded)
|
|
139
|
-
: allTools;
|
|
140
|
-
const providerProfileFiltered = providerProfileExpanded
|
|
141
|
-
? filterToolsByPolicy(toolsFiltered, providerProfileExpanded)
|
|
142
|
-
: toolsFiltered;
|
|
143
|
-
const globalFiltered = globalPolicyExpanded
|
|
144
|
-
? filterToolsByPolicy(providerProfileFiltered, globalPolicyExpanded)
|
|
145
|
-
: providerProfileFiltered;
|
|
146
|
-
const globalProviderFiltered = globalProviderExpanded
|
|
147
|
-
? filterToolsByPolicy(globalFiltered, globalProviderExpanded)
|
|
148
|
-
: globalFiltered;
|
|
149
|
-
const agentFiltered = agentPolicyExpanded
|
|
150
|
-
? filterToolsByPolicy(globalProviderFiltered, agentPolicyExpanded)
|
|
151
|
-
: globalProviderFiltered;
|
|
152
|
-
const agentProviderFiltered = agentProviderExpanded
|
|
153
|
-
? filterToolsByPolicy(agentFiltered, agentProviderExpanded)
|
|
154
|
-
: agentFiltered;
|
|
155
|
-
const groupFiltered = groupPolicyExpanded
|
|
156
|
-
? filterToolsByPolicy(agentProviderFiltered, groupPolicyExpanded)
|
|
157
|
-
: agentProviderFiltered;
|
|
158
|
-
const subagentFiltered = subagentPolicyExpanded
|
|
159
|
-
? filterToolsByPolicy(groupFiltered, subagentPolicyExpanded)
|
|
160
|
-
: groupFiltered;
|
|
161
|
-
const tool = subagentFiltered.find((t) => t.name === toolName);
|
|
193
|
+
// Gateway HTTP-specific deny list — applies to ALL sessions via HTTP.
|
|
194
|
+
const gatewayToolsCfg = cfg.gateway?.tools;
|
|
195
|
+
const defaultGatewayDeny = DEFAULT_GATEWAY_HTTP_TOOL_DENY.filter((name) => !gatewayToolsCfg?.allow?.includes(name));
|
|
196
|
+
const gatewayDenyNames = defaultGatewayDeny.concat(Array.isArray(gatewayToolsCfg?.deny) ? gatewayToolsCfg.deny : []);
|
|
197
|
+
const gatewayDenySet = new Set(gatewayDenyNames);
|
|
198
|
+
const gatewayFiltered = subagentFiltered.filter((t) => !gatewayDenySet.has(t.name));
|
|
199
|
+
const tool = gatewayFiltered.find((t) => t.name === toolName);
|
|
162
200
|
if (!tool) {
|
|
163
201
|
sendJson(res, 404, {
|
|
164
202
|
ok: false,
|
|
@@ -168,17 +206,27 @@ export async function handleToolsInvokeHttpRequest(req, res, opts) {
|
|
|
168
206
|
}
|
|
169
207
|
try {
|
|
170
208
|
const toolArgs = mergeActionIntoArgsIfSupported({
|
|
209
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
171
210
|
toolSchema: tool.parameters,
|
|
172
211
|
action,
|
|
173
212
|
args,
|
|
174
213
|
});
|
|
214
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
175
215
|
const result = await tool.execute?.(`http-${Date.now()}`, toolArgs);
|
|
176
216
|
sendJson(res, 200, { ok: true, result });
|
|
177
217
|
}
|
|
178
218
|
catch (err) {
|
|
179
|
-
|
|
219
|
+
if (isToolInputError(err)) {
|
|
220
|
+
sendJson(res, 400, {
|
|
221
|
+
ok: false,
|
|
222
|
+
error: { type: "tool_error", message: getErrorMessage(err) || "invalid tool arguments" },
|
|
223
|
+
});
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
logWarn(`tools-invoke: tool execution failed: ${String(err)}`);
|
|
227
|
+
sendJson(res, 500, {
|
|
180
228
|
ok: false,
|
|
181
|
-
error: { type: "tool_error", message:
|
|
229
|
+
error: { type: "tool_error", message: "tool execution failed" },
|
|
182
230
|
});
|
|
183
231
|
}
|
|
184
232
|
return true;
|