@poolzin/pool-bot 2026.2.21 → 2026.2.22
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 +17 -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/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/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/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 +5 -0
- package/extensions/msteams/package.json +1 -1
- 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/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 +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- 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
- 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
|
@@ -1,58 +1,71 @@
|
|
|
1
1
|
import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js";
|
|
2
|
-
import { truncateUtf16Safe } from "../utils.js";
|
|
3
2
|
import { normalizeTargetForProvider } from "../infra/outbound/target-normalization.js";
|
|
3
|
+
import { MEDIA_TOKEN_RE } from "../media/parse.js";
|
|
4
|
+
import { truncateUtf16Safe } from "../utils.js";
|
|
4
5
|
const TOOL_RESULT_MAX_CHARS = 8000;
|
|
5
6
|
const TOOL_ERROR_MAX_CHARS = 400;
|
|
6
7
|
function truncateToolText(text) {
|
|
7
|
-
if (text.length <= TOOL_RESULT_MAX_CHARS)
|
|
8
|
+
if (text.length <= TOOL_RESULT_MAX_CHARS) {
|
|
8
9
|
return text;
|
|
10
|
+
}
|
|
9
11
|
return `${truncateUtf16Safe(text, TOOL_RESULT_MAX_CHARS)}\n…(truncated)…`;
|
|
10
12
|
}
|
|
11
13
|
function normalizeToolErrorText(text) {
|
|
12
14
|
const trimmed = text.trim();
|
|
13
|
-
if (!trimmed)
|
|
15
|
+
if (!trimmed) {
|
|
14
16
|
return undefined;
|
|
17
|
+
}
|
|
15
18
|
const firstLine = trimmed.split(/\r?\n/)[0]?.trim() ?? "";
|
|
16
|
-
if (!firstLine)
|
|
19
|
+
if (!firstLine) {
|
|
17
20
|
return undefined;
|
|
21
|
+
}
|
|
18
22
|
return firstLine.length > TOOL_ERROR_MAX_CHARS
|
|
19
23
|
? `${truncateUtf16Safe(firstLine, TOOL_ERROR_MAX_CHARS)}…`
|
|
20
24
|
: firstLine;
|
|
21
25
|
}
|
|
22
26
|
function readErrorCandidate(value) {
|
|
23
|
-
if (typeof value === "string")
|
|
27
|
+
if (typeof value === "string") {
|
|
24
28
|
return normalizeToolErrorText(value);
|
|
25
|
-
|
|
29
|
+
}
|
|
30
|
+
if (!value || typeof value !== "object") {
|
|
26
31
|
return undefined;
|
|
32
|
+
}
|
|
27
33
|
const record = value;
|
|
28
|
-
if (typeof record.message === "string")
|
|
34
|
+
if (typeof record.message === "string") {
|
|
29
35
|
return normalizeToolErrorText(record.message);
|
|
30
|
-
|
|
36
|
+
}
|
|
37
|
+
if (typeof record.error === "string") {
|
|
31
38
|
return normalizeToolErrorText(record.error);
|
|
39
|
+
}
|
|
32
40
|
return undefined;
|
|
33
41
|
}
|
|
34
42
|
function extractErrorField(value) {
|
|
35
|
-
if (!value || typeof value !== "object")
|
|
43
|
+
if (!value || typeof value !== "object") {
|
|
36
44
|
return undefined;
|
|
45
|
+
}
|
|
37
46
|
const record = value;
|
|
38
47
|
const direct = readErrorCandidate(record.error) ??
|
|
39
48
|
readErrorCandidate(record.message) ??
|
|
40
49
|
readErrorCandidate(record.reason);
|
|
41
|
-
if (direct)
|
|
50
|
+
if (direct) {
|
|
42
51
|
return direct;
|
|
52
|
+
}
|
|
43
53
|
const status = typeof record.status === "string" ? record.status.trim() : "";
|
|
44
54
|
return status ? normalizeToolErrorText(status) : undefined;
|
|
45
55
|
}
|
|
46
56
|
export function sanitizeToolResult(result) {
|
|
47
|
-
if (!result || typeof result !== "object")
|
|
57
|
+
if (!result || typeof result !== "object") {
|
|
48
58
|
return result;
|
|
59
|
+
}
|
|
49
60
|
const record = result;
|
|
50
61
|
const content = Array.isArray(record.content) ? record.content : null;
|
|
51
|
-
if (!content)
|
|
62
|
+
if (!content) {
|
|
52
63
|
return record;
|
|
64
|
+
}
|
|
53
65
|
const sanitized = content.map((item) => {
|
|
54
|
-
if (!item || typeof item !== "object")
|
|
66
|
+
if (!item || typeof item !== "object") {
|
|
55
67
|
return item;
|
|
68
|
+
}
|
|
56
69
|
const entry = item;
|
|
57
70
|
const type = typeof entry.type === "string" ? entry.type : undefined;
|
|
58
71
|
if (type === "text" && typeof entry.text === "string") {
|
|
@@ -70,58 +83,138 @@ export function sanitizeToolResult(result) {
|
|
|
70
83
|
return { ...record, content: sanitized };
|
|
71
84
|
}
|
|
72
85
|
export function extractToolResultText(result) {
|
|
73
|
-
if (!result || typeof result !== "object")
|
|
86
|
+
if (!result || typeof result !== "object") {
|
|
74
87
|
return undefined;
|
|
88
|
+
}
|
|
75
89
|
const record = result;
|
|
76
90
|
const content = Array.isArray(record.content) ? record.content : null;
|
|
77
|
-
if (!content)
|
|
91
|
+
if (!content) {
|
|
78
92
|
return undefined;
|
|
93
|
+
}
|
|
79
94
|
const texts = content
|
|
80
95
|
.map((item) => {
|
|
81
|
-
if (!item || typeof item !== "object")
|
|
96
|
+
if (!item || typeof item !== "object") {
|
|
82
97
|
return undefined;
|
|
98
|
+
}
|
|
83
99
|
const entry = item;
|
|
84
|
-
if (entry.type !== "text" || typeof entry.text !== "string")
|
|
100
|
+
if (entry.type !== "text" || typeof entry.text !== "string") {
|
|
85
101
|
return undefined;
|
|
102
|
+
}
|
|
86
103
|
const trimmed = entry.text.trim();
|
|
87
104
|
return trimmed ? trimmed : undefined;
|
|
88
105
|
})
|
|
89
106
|
.filter((value) => Boolean(value));
|
|
90
|
-
if (texts.length === 0)
|
|
107
|
+
if (texts.length === 0) {
|
|
91
108
|
return undefined;
|
|
109
|
+
}
|
|
92
110
|
return texts.join("\n");
|
|
93
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Extract media file paths from a tool result.
|
|
114
|
+
*
|
|
115
|
+
* Strategy (first match wins):
|
|
116
|
+
* 1. Parse `MEDIA:` tokens from text content blocks (all Pool Bot tools).
|
|
117
|
+
* 2. Fall back to `details.path` when image content exists (Pool Bot imageResult).
|
|
118
|
+
*
|
|
119
|
+
* Returns an empty array when no media is found (e.g. Pi SDK `read` tool
|
|
120
|
+
* returns base64 image data but no file path; those need a different delivery
|
|
121
|
+
* path like saving to a temp file).
|
|
122
|
+
*/
|
|
123
|
+
export function extractToolResultMediaPaths(result) {
|
|
124
|
+
if (!result || typeof result !== "object") {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
const record = result;
|
|
128
|
+
const content = Array.isArray(record.content) ? record.content : null;
|
|
129
|
+
if (!content) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
// Extract MEDIA: paths from text content blocks.
|
|
133
|
+
const paths = [];
|
|
134
|
+
let hasImageContent = false;
|
|
135
|
+
for (const item of content) {
|
|
136
|
+
if (!item || typeof item !== "object") {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const entry = item;
|
|
140
|
+
if (entry.type === "image") {
|
|
141
|
+
hasImageContent = true;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (entry.type === "text" && typeof entry.text === "string") {
|
|
145
|
+
// Only parse lines that start with MEDIA: (after trimming) to avoid
|
|
146
|
+
// false-matching placeholders like <media:audio> or mid-line mentions.
|
|
147
|
+
// Mirrors the line-start guard in splitMediaFromOutput (media/parse.ts).
|
|
148
|
+
for (const line of entry.text.split("\n")) {
|
|
149
|
+
if (!line.trimStart().startsWith("MEDIA:")) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
MEDIA_TOKEN_RE.lastIndex = 0;
|
|
153
|
+
let match;
|
|
154
|
+
while ((match = MEDIA_TOKEN_RE.exec(line)) !== null) {
|
|
155
|
+
const p = match[1]
|
|
156
|
+
?.replace(/^[`"'[{(]+/, "")
|
|
157
|
+
.replace(/[`"'\]})\\,]+$/, "")
|
|
158
|
+
.trim();
|
|
159
|
+
if (p && p.length <= 4096) {
|
|
160
|
+
paths.push(p);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (paths.length > 0) {
|
|
167
|
+
return paths;
|
|
168
|
+
}
|
|
169
|
+
// Fall back to details.path when image content exists but no MEDIA: text.
|
|
170
|
+
if (hasImageContent) {
|
|
171
|
+
const details = record.details;
|
|
172
|
+
const p = typeof details?.path === "string" ? details.path.trim() : "";
|
|
173
|
+
if (p) {
|
|
174
|
+
return [p];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
94
179
|
export function isToolResultError(result) {
|
|
95
|
-
if (!result || typeof result !== "object")
|
|
180
|
+
if (!result || typeof result !== "object") {
|
|
96
181
|
return false;
|
|
182
|
+
}
|
|
97
183
|
const record = result;
|
|
98
184
|
const details = record.details;
|
|
99
|
-
if (!details || typeof details !== "object")
|
|
185
|
+
if (!details || typeof details !== "object") {
|
|
100
186
|
return false;
|
|
187
|
+
}
|
|
101
188
|
const status = details.status;
|
|
102
|
-
if (typeof status !== "string")
|
|
189
|
+
if (typeof status !== "string") {
|
|
103
190
|
return false;
|
|
191
|
+
}
|
|
104
192
|
const normalized = status.trim().toLowerCase();
|
|
105
193
|
return normalized === "error" || normalized === "timeout";
|
|
106
194
|
}
|
|
107
195
|
export function extractToolErrorMessage(result) {
|
|
108
|
-
if (!result || typeof result !== "object")
|
|
196
|
+
if (!result || typeof result !== "object") {
|
|
109
197
|
return undefined;
|
|
198
|
+
}
|
|
110
199
|
const record = result;
|
|
111
200
|
const fromDetails = extractErrorField(record.details);
|
|
112
|
-
if (fromDetails)
|
|
201
|
+
if (fromDetails) {
|
|
113
202
|
return fromDetails;
|
|
203
|
+
}
|
|
114
204
|
const fromRoot = extractErrorField(record);
|
|
115
|
-
if (fromRoot)
|
|
205
|
+
if (fromRoot) {
|
|
116
206
|
return fromRoot;
|
|
207
|
+
}
|
|
117
208
|
const text = extractToolResultText(result);
|
|
118
|
-
if (!text)
|
|
209
|
+
if (!text) {
|
|
119
210
|
return undefined;
|
|
211
|
+
}
|
|
120
212
|
try {
|
|
121
213
|
const parsed = JSON.parse(text);
|
|
122
214
|
const fromJson = extractErrorField(parsed);
|
|
123
|
-
if (fromJson)
|
|
215
|
+
if (fromJson) {
|
|
124
216
|
return fromJson;
|
|
217
|
+
}
|
|
125
218
|
}
|
|
126
219
|
catch {
|
|
127
220
|
// Fall through to first-line text fallback.
|
|
@@ -134,11 +227,13 @@ export function extractMessagingToolSend(toolName, args) {
|
|
|
134
227
|
const accountIdRaw = typeof args.accountId === "string" ? args.accountId.trim() : undefined;
|
|
135
228
|
const accountId = accountIdRaw ? accountIdRaw : undefined;
|
|
136
229
|
if (toolName === "message") {
|
|
137
|
-
if (action !== "send" && action !== "thread-reply")
|
|
230
|
+
if (action !== "send" && action !== "thread-reply") {
|
|
138
231
|
return undefined;
|
|
232
|
+
}
|
|
139
233
|
const toRaw = typeof args.to === "string" ? args.to : undefined;
|
|
140
|
-
if (!toRaw)
|
|
234
|
+
if (!toRaw) {
|
|
141
235
|
return undefined;
|
|
236
|
+
}
|
|
142
237
|
const providerRaw = typeof args.provider === "string" ? args.provider.trim() : "";
|
|
143
238
|
const channelRaw = typeof args.channel === "string" ? args.channel.trim() : "";
|
|
144
239
|
const providerHint = providerRaw || channelRaw;
|
|
@@ -148,12 +243,14 @@ export function extractMessagingToolSend(toolName, args) {
|
|
|
148
243
|
return to ? { tool: toolName, provider, accountId, to } : undefined;
|
|
149
244
|
}
|
|
150
245
|
const providerId = normalizeChannelId(toolName);
|
|
151
|
-
if (!providerId)
|
|
246
|
+
if (!providerId) {
|
|
152
247
|
return undefined;
|
|
248
|
+
}
|
|
153
249
|
const plugin = getChannelPlugin(providerId);
|
|
154
250
|
const extracted = plugin?.actions?.extractToolSend?.({ args });
|
|
155
|
-
if (!extracted?.to)
|
|
251
|
+
if (!extracted?.to) {
|
|
156
252
|
return undefined;
|
|
253
|
+
}
|
|
157
254
|
const to = normalizeTargetForProvider(providerId, extracted.to);
|
|
158
255
|
return to
|
|
159
256
|
? {
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
2
1
|
import path from "node:path";
|
|
2
|
+
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
export { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
4
|
+
function createAuthStorage(AuthStorageLike, path) {
|
|
5
|
+
const withFactory = AuthStorageLike;
|
|
6
|
+
if (typeof withFactory.create === "function") {
|
|
7
|
+
return withFactory.create(path);
|
|
8
|
+
}
|
|
9
|
+
return new AuthStorageLike(path);
|
|
10
|
+
}
|
|
4
11
|
// Compatibility helpers for pi-coding-agent 0.50+ (discover* helpers removed).
|
|
5
12
|
export function discoverAuthStorage(agentDir) {
|
|
6
|
-
return
|
|
13
|
+
return createAuthStorage(AuthStorage, path.join(agentDir, "auth.json"));
|
|
7
14
|
}
|
|
8
15
|
export function discoverModels(authStorage, agentDir) {
|
|
9
16
|
return new ModelRegistry(authStorage, path.join(agentDir, "models.json"));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { logDebug, logError } from "../logger.js";
|
|
2
|
+
import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
|
|
2
3
|
import { isPlainObject } from "../utils.js";
|
|
3
|
-
import { runBeforeToolCallHook } from "./pi-tools.before-tool-call.js";
|
|
4
|
+
import { consumeAdjustedParamsForToolCall, isToolWrappedWithBeforeToolCallHook, runBeforeToolCallHook, } from "./pi-tools.before-tool-call.js";
|
|
4
5
|
import { normalizeToolName } from "./tool-policy.js";
|
|
5
6
|
import { jsonResult } from "./tools/common.js";
|
|
6
7
|
function isAbortSignal(value) {
|
|
@@ -8,8 +9,11 @@ function isAbortSignal(value) {
|
|
|
8
9
|
}
|
|
9
10
|
function isLegacyToolExecuteArgs(args) {
|
|
10
11
|
const third = args[2];
|
|
11
|
-
const
|
|
12
|
-
|
|
12
|
+
const fifth = args[4];
|
|
13
|
+
if (typeof third === "function") {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return isAbortSignal(fifth);
|
|
13
17
|
}
|
|
14
18
|
function describeToolExecutionError(err) {
|
|
15
19
|
if (err instanceof Error) {
|
|
@@ -20,7 +24,7 @@ function describeToolExecutionError(err) {
|
|
|
20
24
|
}
|
|
21
25
|
function splitToolExecuteArgs(args) {
|
|
22
26
|
if (isLegacyToolExecuteArgs(args)) {
|
|
23
|
-
const [toolCallId, params,
|
|
27
|
+
const [toolCallId, params, onUpdate, _ctx, signal] = args;
|
|
24
28
|
return {
|
|
25
29
|
toolCallId,
|
|
26
30
|
params,
|
|
@@ -28,7 +32,7 @@ function splitToolExecuteArgs(args) {
|
|
|
28
32
|
signal,
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
|
-
const [toolCallId, params,
|
|
35
|
+
const [toolCallId, params, signal, onUpdate] = args;
|
|
32
36
|
return {
|
|
33
37
|
toolCallId,
|
|
34
38
|
params,
|
|
@@ -40,6 +44,7 @@ export function toToolDefinitions(tools) {
|
|
|
40
44
|
return tools.map((tool) => {
|
|
41
45
|
const name = tool.name || "tool";
|
|
42
46
|
const normalizedName = normalizeToolName(name);
|
|
47
|
+
const beforeHookWrapped = isToolWrappedWithBeforeToolCallHook(tool);
|
|
43
48
|
return {
|
|
44
49
|
name,
|
|
45
50
|
label: tool.label ?? name,
|
|
@@ -47,8 +52,38 @@ export function toToolDefinitions(tools) {
|
|
|
47
52
|
parameters: tool.parameters,
|
|
48
53
|
execute: async (...args) => {
|
|
49
54
|
const { toolCallId, params, onUpdate, signal } = splitToolExecuteArgs(args);
|
|
55
|
+
let executeParams = params;
|
|
50
56
|
try {
|
|
51
|
-
|
|
57
|
+
if (!beforeHookWrapped) {
|
|
58
|
+
const hookOutcome = await runBeforeToolCallHook({
|
|
59
|
+
toolName: name,
|
|
60
|
+
params,
|
|
61
|
+
toolCallId,
|
|
62
|
+
});
|
|
63
|
+
if (hookOutcome.blocked) {
|
|
64
|
+
throw new Error(hookOutcome.reason);
|
|
65
|
+
}
|
|
66
|
+
executeParams = hookOutcome.params;
|
|
67
|
+
}
|
|
68
|
+
const result = await tool.execute(toolCallId, executeParams, signal, onUpdate);
|
|
69
|
+
const afterParams = beforeHookWrapped
|
|
70
|
+
? (consumeAdjustedParamsForToolCall(toolCallId) ?? executeParams)
|
|
71
|
+
: executeParams;
|
|
72
|
+
// Call after_tool_call hook
|
|
73
|
+
const hookRunner = getGlobalHookRunner();
|
|
74
|
+
if (hookRunner?.hasHooks("after_tool_call")) {
|
|
75
|
+
try {
|
|
76
|
+
await hookRunner.runAfterToolCall({
|
|
77
|
+
toolName: name,
|
|
78
|
+
params: isPlainObject(afterParams) ? afterParams : {},
|
|
79
|
+
result,
|
|
80
|
+
}, { toolName: name });
|
|
81
|
+
}
|
|
82
|
+
catch (hookErr) {
|
|
83
|
+
logDebug(`after_tool_call hook failed: tool=${normalizedName} error=${String(hookErr)}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
52
87
|
}
|
|
53
88
|
catch (err) {
|
|
54
89
|
if (signal?.aborted) {
|
|
@@ -60,16 +95,34 @@ export function toToolDefinitions(tools) {
|
|
|
60
95
|
if (name === "AbortError") {
|
|
61
96
|
throw err;
|
|
62
97
|
}
|
|
98
|
+
if (beforeHookWrapped) {
|
|
99
|
+
consumeAdjustedParamsForToolCall(toolCallId);
|
|
100
|
+
}
|
|
63
101
|
const described = describeToolExecutionError(err);
|
|
64
102
|
if (described.stack && described.stack !== described.message) {
|
|
65
103
|
logDebug(`tools: ${normalizedName} failed stack:\n${described.stack}`);
|
|
66
104
|
}
|
|
67
105
|
logError(`[tools] ${normalizedName} failed: ${described.message}`);
|
|
68
|
-
|
|
106
|
+
const errorResult = jsonResult({
|
|
69
107
|
status: "error",
|
|
70
108
|
tool: normalizedName,
|
|
71
109
|
error: described.message,
|
|
72
110
|
});
|
|
111
|
+
// Call after_tool_call hook for errors too
|
|
112
|
+
const hookRunner = getGlobalHookRunner();
|
|
113
|
+
if (hookRunner?.hasHooks("after_tool_call")) {
|
|
114
|
+
try {
|
|
115
|
+
await hookRunner.runAfterToolCall({
|
|
116
|
+
toolName: normalizedName,
|
|
117
|
+
params: isPlainObject(params) ? params : {},
|
|
118
|
+
error: described.message,
|
|
119
|
+
}, { toolName: normalizedName });
|
|
120
|
+
}
|
|
121
|
+
catch (hookErr) {
|
|
122
|
+
logDebug(`after_tool_call hook failed: tool=${normalizedName} error=${String(hookErr)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return errorResult;
|
|
73
126
|
}
|
|
74
127
|
},
|
|
75
128
|
};
|
|
@@ -84,7 +137,6 @@ export function toClientToolDefinitions(tools, onClientToolCall, hookContext) {
|
|
|
84
137
|
name: func.name,
|
|
85
138
|
label: func.name,
|
|
86
139
|
description: func.description ?? "",
|
|
87
|
-
// oxlint-disable-next-line typescript/no-explicit-any
|
|
88
140
|
parameters: func.parameters,
|
|
89
141
|
execute: async (...args) => {
|
|
90
142
|
const { toolCallId, params } = splitToolExecuteArgs(args);
|