@poolzin/pool-bot 2026.3.25 → 2026.3.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/model-fallback.js +5 -4
- package/dist/agents/tools/common.js +16 -201
- package/dist/auto-reply/auto-reply/reply/agent-runner-execution.js +502 -0
- package/dist/auto-reply/auto-reply/reply/agent-runner-helpers.js +65 -0
- package/dist/auto-reply/auto-reply/reply/agent-runner-memory.js +160 -0
- package/dist/auto-reply/auto-reply/reply/agent-runner-payloads.js +85 -0
- package/dist/auto-reply/auto-reply/reply/agent-runner-utils.js +101 -0
- package/dist/auto-reply/auto-reply/reply/bash-command.js +338 -0
- package/dist/auto-reply/auto-reply/reply/block-streaming.js +91 -0
- package/dist/auto-reply/auto-reply/reply/commands-approve.js +88 -0
- package/dist/auto-reply/auto-reply/reply/commands-bash.js +26 -0
- package/dist/auto-reply/auto-reply/reply/commands-compact.js +107 -0
- package/dist/auto-reply/auto-reply/reply/commands-config.js +241 -0
- package/dist/auto-reply/auto-reply/reply/commands-context-report.js +295 -0
- package/dist/auto-reply/auto-reply/reply/commands-context.js +30 -0
- package/dist/auto-reply/auto-reply/reply/commands-core.js +151 -0
- package/dist/auto-reply/auto-reply/reply/commands-export-session.js +163 -0
- package/dist/auto-reply/auto-reply/reply/commands-info.js +184 -0
- package/dist/auto-reply/auto-reply/reply/commands-models.js +299 -0
- package/dist/auto-reply/auto-reply/reply/commands-plugin.js +35 -0
- package/dist/auto-reply/auto-reply/reply/commands-ptt.js +171 -0
- package/dist/auto-reply/auto-reply/reply/commands-setunset-standard.js +13 -0
- package/dist/auto-reply/auto-reply/reply/commands-setunset.js +73 -0
- package/dist/auto-reply/auto-reply/reply/commands-slash-parse.js +31 -0
- package/dist/auto-reply/auto-reply/reply/commands-status.js +178 -0
- package/dist/auto-reply/auto-reply/reply/commands-subagents.js +73 -0
- package/dist/auto-reply/auto-reply/reply/commands-system-prompt.js +117 -0
- package/dist/auto-reply/auto-reply/reply/commands-tts.js +231 -0
- package/dist/auto-reply/auto-reply/reply/directive-handling.impl.js +380 -0
- package/dist/auto-reply/auto-reply/reply/followup-runner.js +227 -0
- package/dist/auto-reply/auto-reply/reply/get-reply-directives-apply.js +201 -0
- package/dist/auto-reply/auto-reply/reply/get-reply-directives-utils.js +54 -0
- package/dist/auto-reply/auto-reply/reply/get-reply-directives.js +332 -0
- package/dist/auto-reply/auto-reply/reply/get-reply-inline-actions.js +258 -0
- package/dist/auto-reply/auto-reply/reply/get-reply-run.js +297 -0
- package/dist/auto-reply/auto-reply/reply/groups.js +102 -0
- package/dist/auto-reply/auto-reply/reply/mentions.js +129 -0
- package/dist/auto-reply/auto-reply/reply/reply-delivery.js +92 -0
- package/dist/auto-reply/auto-reply/reply/reply-directives.js +30 -0
- package/dist/auto-reply/auto-reply/reply/reply-dispatcher.js +152 -0
- package/dist/auto-reply/auto-reply/reply/reply-elevated.js +166 -0
- package/dist/auto-reply/auto-reply/reply/reply-inline.js +28 -0
- package/dist/auto-reply/auto-reply/reply/reply-payloads.js +114 -0
- package/dist/auto-reply/auto-reply/reply/reply-reference.js +36 -0
- package/dist/auto-reply/auto-reply/reply/reply-tags.js +13 -0
- package/dist/auto-reply/auto-reply/reply/reply-threading.js +41 -0
- package/dist/auto-reply/auto-reply/reply/session-updates.js +233 -0
- package/dist/auto-reply/auto-reply/reply/stage-sandbox-media.js +146 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/canvas-host/a2ui/a2ui.bundle.js +2 -17772
- package/dist/canvas-host/a2ui/index.html +1 -307
- package/dist/channels/channels/directory-config.js +185 -0
- package/dist/channels/channels/discord/handle-action.guild-admin.js +332 -0
- package/dist/channels/channels/discord/handle-action.js +165 -0
- package/dist/channels/channels/discord.js +413 -0
- package/dist/channels/channels/dock.js +436 -0
- package/dist/channels/channels/index.js +51 -0
- package/dist/channels/channels/plugins/outbound/discord.js +101 -0
- package/dist/channels/channels/whatsapp.js +17 -0
- package/dist/channels/plugins/types.js +1 -1
- package/dist/channels/run-state-machine.js +7 -0
- package/dist/commands/models/auth.js +47 -1
- package/dist/commands-subagents/action-agents.js +44 -0
- package/dist/commands-subagents/action-focus.js +64 -0
- package/dist/commands-subagents/action-help.js +4 -0
- package/dist/commands-subagents/action-info.js +45 -0
- package/dist/commands-subagents/action-kill.js +60 -0
- package/dist/commands-subagents/action-list.js +44 -0
- package/dist/commands-subagents/action-log.js +29 -0
- package/dist/commands-subagents/action-send.js +119 -0
- package/dist/commands-subagents/action-spawn.js +52 -0
- package/dist/commands-subagents/action-unfocus.js +30 -0
- package/dist/commands-subagents/shared.js +303 -0
- package/dist/config/config.js +1 -8
- package/dist/config/types.secrets.js +61 -0
- package/dist/control-ui/assets/{index-D7shnQwQ.js → index-umCsvrWy.js} +884 -741
- package/dist/control-ui/assets/index-umCsvrWy.js.map +1 -0
- package/dist/control-ui/assets/pt-BR-DedEVAvY.js +2 -0
- package/dist/control-ui/assets/pt-BR-DedEVAvY.js.map +1 -0
- package/dist/control-ui/assets/zh-CN-CDzeklK-.js +2 -0
- package/dist/control-ui/assets/zh-CN-CDzeklK-.js.map +1 -0
- package/dist/control-ui/assets/zh-TW-BJCRYNWH.js +2 -0
- package/dist/control-ui/assets/zh-TW-BJCRYNWH.js.map +1 -0
- package/dist/control-ui/index.html +1 -1
- package/dist/gateway/method-scopes.js +9 -1
- package/dist/gateway/node-pending-work.js +142 -0
- package/dist/gateway/protocol/index.js +5 -1
- package/dist/gateway/protocol/schema/nodes.js +18 -0
- package/dist/gateway/server-methods/nodes-pending.js +96 -0
- package/dist/gateway/server-methods-list.js +4 -0
- package/dist/gateway/server-methods.js +2 -0
- package/dist/imessage/channel.js +253 -0
- package/dist/imessage/monitor/echo-cache.js +70 -0
- package/dist/imessage/monitor/loop-rate-limiter.js +51 -0
- package/dist/imessage/monitor/reflection-guard.js +50 -0
- package/dist/imessage/monitor/sanitize-outbound.js +25 -0
- package/dist/imessage/monitor/self-chat-cache.js +75 -0
- package/dist/imessage/runtime.js +3 -0
- package/dist/infra/exec-approval-reply.js +7 -0
- package/dist/infra/tmp-openclaw-dir.js +84 -0
- package/dist/pairing/pairing-challenge.js +15 -0
- package/dist/plugin-sdk/account-id.d.ts +1 -0
- package/dist/plugin-sdk/agent-media-payload.d.ts +12 -0
- package/dist/plugin-sdk/allow-from.d.ts +27 -0
- package/dist/plugin-sdk/command-auth.d.ts +25 -0
- package/dist/plugin-sdk/command-auth.js +3 -1
- package/dist/plugin-sdk/config-paths.d.ts +6 -0
- package/dist/plugin-sdk/file-lock.d.ts +16 -0
- package/dist/plugin-sdk/index.d.ts +428 -0
- package/dist/plugin-sdk/index.js +237 -103
- package/dist/plugin-sdk/json-store.d.ts +5 -0
- package/dist/plugin-sdk/keyed-async-queue.d.ts +12 -0
- package/dist/plugin-sdk/onboarding.d.ts +11 -0
- package/dist/plugin-sdk/provider-auth-result.d.ts +14 -0
- package/dist/plugin-sdk/slack-message-actions.d.ts +11 -0
- package/dist/plugin-sdk/status-helpers.d.ts +25 -0
- package/dist/plugin-sdk/temp-path.d.ts +12 -0
- package/dist/plugin-sdk/text-chunking.d.ts +1 -0
- package/dist/plugin-sdk/tool-send.d.ts +4 -0
- package/dist/plugin-sdk/webhook-path.d.ts +6 -0
- package/dist/plugin-sdk/webhook-targets.d.ts +23 -0
- package/dist/plugin-sdk/windows-spawn.d.ts +39 -0
- package/dist/plugin-sdk-internal/accounts.js +6 -0
- package/dist/plugin-sdk-internal/discord.js +23 -0
- package/dist/plugin-sdk-internal/imessage.js +13 -0
- package/dist/plugin-sdk-internal/setup.js +9 -0
- package/dist/plugin-sdk-internal/signal.js +13 -0
- package/dist/plugin-sdk-internal/slack.js +22 -0
- package/dist/plugin-sdk-internal/telegram.js +32 -0
- package/dist/plugin-sdk-internal/whatsapp.js +29 -0
- package/dist/routing/session-key.js +4 -185
- package/dist/shared/pid-alive.js +2 -61
- package/dist/shared/process-scoped-map.js +5 -7
- package/dist/signal/channel.js +264 -0
- package/dist/signal/monitor/access-policy.js +60 -0
- package/dist/signal/runtime.js +3 -0
- package/dist/slack/account-inspect.js +135 -0
- package/dist/slack/blocks-input.js +7 -38
- package/dist/slack/channel.js +394 -0
- package/dist/slack/interactive-replies.js +28 -0
- package/dist/slack/monitor/channel-type.js +31 -0
- package/dist/slack/monitor/dm-auth.js +49 -0
- package/dist/slack/monitor/events/interactions.modal.js +137 -0
- package/dist/slack/monitor/events/message-subtype-handlers.js +68 -0
- package/dist/slack/monitor/events/system-event-context.js +29 -0
- package/dist/slack/monitor/events/system-event-test-harness.js +41 -0
- package/dist/slack/monitor/external-arg-menu-store.js +46 -0
- package/dist/slack/monitor/message-handler/prepare-content.js +69 -0
- package/dist/slack/monitor/message-handler/prepare-thread-context.js +91 -0
- package/dist/slack/monitor/message-handler/prepare.test-helpers.js +55 -0
- package/dist/slack/monitor/reconnect-policy.js +78 -0
- package/dist/slack/monitor/slash-commands.runtime.js +1 -0
- package/dist/slack/monitor/slash-dispatch.runtime.js +9 -0
- package/dist/slack/monitor/slash-skill-commands.runtime.js +1 -0
- package/dist/slack/resolve-allowlist-common.js +36 -0
- package/dist/slack/runtime.js +3 -0
- package/dist/slack/sent-thread-cache.js +61 -0
- package/dist/slack/truncate.js +10 -0
- package/dist/telegram/account-inspect.js +175 -0
- package/dist/telegram/allow-from.js +10 -0
- package/dist/telegram/api-fetch.js +18 -0
- package/dist/telegram/approval-buttons.js +30 -0
- package/dist/telegram/audit-membership-runtime.js +61 -0
- package/dist/telegram/bot/delivery.replies.js +508 -0
- package/dist/telegram/bot/delivery.resolve-media.js +227 -0
- package/dist/telegram/bot/delivery.send.js +132 -0
- package/dist/telegram/bot/reply-threading.js +46 -0
- package/dist/telegram/bot-message-context.body.js +186 -0
- package/dist/telegram/bot-message-context.session.js +207 -0
- package/dist/telegram/bot-message-context.types.js +1 -0
- package/dist/telegram/bot-native-commands.test-helpers.js +117 -0
- package/dist/telegram/bot.media.e2e-harness.js +81 -0
- package/dist/telegram/bot.media.test-utils.js +81 -0
- package/dist/telegram/channel-actions.js +225 -0
- package/dist/telegram/channel.js +515 -0
- package/dist/telegram/conversation-route.js +107 -0
- package/dist/telegram/delivery.js +2 -0
- package/dist/telegram/delivery.replies.js +508 -0
- package/dist/telegram/dm-access.js +86 -0
- package/dist/telegram/draft-stream.test-helpers.js +62 -0
- package/dist/telegram/exec-approvals-handler.js +281 -0
- package/dist/telegram/exec-approvals.js +62 -0
- package/dist/telegram/forum-service-message.js +22 -0
- package/dist/telegram/group-config-helpers.js +10 -0
- package/dist/telegram/lane-delivery-state.js +19 -0
- package/dist/telegram/lane-delivery-text-deliverer.js +357 -0
- package/dist/telegram/lane-delivery.js +2 -0
- package/dist/telegram/normalize.js +37 -0
- package/dist/telegram/onboarding.js +192 -0
- package/dist/telegram/outbound-adapter.js +100 -0
- package/dist/telegram/polling-session.js +275 -0
- package/dist/telegram/runtime.js +3 -0
- package/dist/telegram/sendchataction-401-backoff.js +71 -0
- package/dist/telegram/sequential-key.js +46 -0
- package/dist/telegram/status-issues.js +105 -0
- package/dist/telegram/target-writeback.js +165 -0
- package/dist/telegram/thread-bindings.js +560 -0
- package/dist/utils.js +10 -276
- package/dist/wizard/prompts.js +5 -5
- package/extensions/feishu/src/policy.ts +1 -1
- package/extensions/firecrawl/index.test.ts +82 -0
- package/extensions/firecrawl/index.ts +20 -0
- package/extensions/firecrawl/openclaw.plugin.json +8 -0
- package/extensions/firecrawl/package.json +12 -0
- package/extensions/firecrawl/src/config.ts +159 -0
- package/extensions/firecrawl/src/firecrawl-client.ts +446 -0
- package/extensions/firecrawl/src/firecrawl-scrape-tool.ts +89 -0
- package/extensions/firecrawl/src/firecrawl-search-provider.ts +63 -0
- package/extensions/firecrawl/src/firecrawl-search-tool.ts +76 -0
- package/package.json +1 -1
- package/dist/.buildstamp +0 -1
- package/dist/acp/bindings-store.js +0 -209
- package/dist/acp/control-plane/runtime-cache.js +0 -54
- package/dist/acp/control-plane/runtime-options.js +0 -215
- package/dist/acp/control-plane/session-actor-queue.js +0 -36
- package/dist/acp/index.js +0 -2
- package/dist/acp/runtime/errors.js +0 -47
- package/dist/acp/runtime/registry.js +0 -86
- package/dist/acp/secret-file.js +0 -22
- package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +0 -23
- package/dist/agents/bash-process-registry.test-helpers.js +0 -29
- package/dist/agents/bash-tools.exec-approval-request.js +0 -20
- package/dist/agents/bash-tools.exec-host-gateway.js +0 -240
- package/dist/agents/bash-tools.exec-host-node.js +0 -235
- package/dist/agents/checkpoint-manager.js +0 -290
- package/dist/agents/claude-cli-runner.js +0 -3
- package/dist/agents/error-classifier.js +0 -251
- package/dist/agents/live-model-filter.js +0 -84
- package/dist/agents/nvidia-models.js +0 -228
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +0 -34
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +0 -156
- package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +0 -30
- package/dist/agents/provider/config-loader.js +0 -76
- package/dist/agents/provider/index.js +0 -15
- package/dist/agents/provider/models-dev.js +0 -129
- package/dist/agents/provider/session-binding.js +0 -376
- package/dist/agents/queued-file-writer.js +0 -22
- package/dist/agents/skills/bundled-context.js +0 -23
- package/dist/agents/skills/security.js +0 -211
- package/dist/agents/skills/tools-dir.js +0 -9
- package/dist/agents/skills-install-download.js +0 -290
- package/dist/agents/skills-install-output.js +0 -30
- package/dist/agents/skills-install.download-test-utils.js +0 -36
- package/dist/agents/skills.test-helpers.js +0 -13
- package/dist/agents/subagent-announce-reliability.js +0 -160
- package/dist/agents/subagent-registry.mocks.shared.js +0 -12
- package/dist/agents/test-helpers/assistant-message-fixtures.js +0 -29
- package/dist/agents/test-helpers/fast-coding-tools.js +0 -1
- package/dist/agents/test-helpers/fast-core-tools.js +0 -8
- package/dist/agents/test-helpers/fast-tool-stubs.js +0 -18
- package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +0 -74
- package/dist/agents/test-helpers/pi-tools-sandbox-context.js +0 -27
- package/dist/agents/tool-display-common.js +0 -915
- package/dist/agents/tool-policy-shared.js +0 -108
- package/dist/agents/tool-policy.conformance.js +0 -14
- package/dist/agents/tool-result-truncation.js +0 -299
- package/dist/agents/tools/cron-tool.test-helpers.js +0 -12
- package/dist/agents/tools/discord-actions-moderation-shared.js +0 -27
- package/dist/agents/tools/discord-actions-presence.js +0 -78
- package/dist/control-ui/assets/index-D7shnQwQ.js.map +0 -1
- package/dist/discord/discord-improvements.js +0 -167
- package/dist/discord/index.js +0 -2
- package/dist/hooks/bundled/boot-md/HOOK.md +0 -19
- package/dist/hooks/bundled/command-logger/HOOK.md +0 -122
- package/dist/hooks/bundled/session-memory/HOOK.md +0 -86
- package/dist/hooks/bundled/soul-evil/HOOK.md +0 -71
- package/dist/whatsapp/normalize.js +0 -66
- package/dist/whatsapp/resolve-outbound-target.js +0 -42
- /package/dist/{acp/runtime/types.js → auto-reply/auto-reply/reply/commands-types.js} +0 -0
- /package/dist/{agents/pi-embedded-payloads.js → slack/account-surface-fields.js} +0 -0
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
const TOOL_NAME_ALIASES = {
|
|
2
|
-
bash: "exec",
|
|
3
|
-
"apply-patch": "apply_patch",
|
|
4
|
-
};
|
|
5
|
-
export const TOOL_GROUPS = {
|
|
6
|
-
// NOTE: Keep canonical (lowercase) tool names here.
|
|
7
|
-
"group:memory": ["memory_search", "memory_get"],
|
|
8
|
-
"group:web": ["web_search", "web_fetch"],
|
|
9
|
-
// Basic workspace/file tools
|
|
10
|
-
"group:fs": ["read", "write", "edit", "apply_patch"],
|
|
11
|
-
// Host/runtime execution tools
|
|
12
|
-
"group:runtime": ["exec", "process"],
|
|
13
|
-
// Session management tools
|
|
14
|
-
"group:sessions": [
|
|
15
|
-
"sessions_list",
|
|
16
|
-
"sessions_history",
|
|
17
|
-
"sessions_send",
|
|
18
|
-
"sessions_spawn",
|
|
19
|
-
"subagents",
|
|
20
|
-
"session_status",
|
|
21
|
-
],
|
|
22
|
-
// UI helpers
|
|
23
|
-
"group:ui": ["browser", "canvas"],
|
|
24
|
-
// Automation + infra
|
|
25
|
-
"group:automation": ["cron", "gateway"],
|
|
26
|
-
// Messaging surface
|
|
27
|
-
"group:messaging": ["message"],
|
|
28
|
-
// Nodes + device tools
|
|
29
|
-
"group:nodes": ["nodes"],
|
|
30
|
-
// All Pool Bot native tools (excludes provider plugins).
|
|
31
|
-
"group:poolbot": [
|
|
32
|
-
"browser",
|
|
33
|
-
"canvas",
|
|
34
|
-
"nodes",
|
|
35
|
-
"cron",
|
|
36
|
-
"message",
|
|
37
|
-
"gateway",
|
|
38
|
-
"agents_list",
|
|
39
|
-
"sessions_list",
|
|
40
|
-
"sessions_history",
|
|
41
|
-
"sessions_send",
|
|
42
|
-
"sessions_spawn",
|
|
43
|
-
"subagents",
|
|
44
|
-
"session_status",
|
|
45
|
-
"memory_search",
|
|
46
|
-
"memory_get",
|
|
47
|
-
"web_search",
|
|
48
|
-
"web_fetch",
|
|
49
|
-
"image",
|
|
50
|
-
],
|
|
51
|
-
};
|
|
52
|
-
const TOOL_PROFILES = {
|
|
53
|
-
minimal: {
|
|
54
|
-
allow: ["session_status"],
|
|
55
|
-
},
|
|
56
|
-
coding: {
|
|
57
|
-
allow: ["group:fs", "group:runtime", "group:sessions", "group:memory", "image"],
|
|
58
|
-
},
|
|
59
|
-
messaging: {
|
|
60
|
-
allow: [
|
|
61
|
-
"group:messaging",
|
|
62
|
-
"sessions_list",
|
|
63
|
-
"sessions_history",
|
|
64
|
-
"sessions_send",
|
|
65
|
-
"session_status",
|
|
66
|
-
],
|
|
67
|
-
},
|
|
68
|
-
full: {},
|
|
69
|
-
};
|
|
70
|
-
export function normalizeToolName(name) {
|
|
71
|
-
const normalized = name.trim().toLowerCase();
|
|
72
|
-
return TOOL_NAME_ALIASES[normalized] ?? normalized;
|
|
73
|
-
}
|
|
74
|
-
export function normalizeToolList(list) {
|
|
75
|
-
if (!list) {
|
|
76
|
-
return [];
|
|
77
|
-
}
|
|
78
|
-
return list.map(normalizeToolName).filter(Boolean);
|
|
79
|
-
}
|
|
80
|
-
export function expandToolGroups(list) {
|
|
81
|
-
const normalized = normalizeToolList(list);
|
|
82
|
-
const expanded = [];
|
|
83
|
-
for (const value of normalized) {
|
|
84
|
-
const group = TOOL_GROUPS[value];
|
|
85
|
-
if (group) {
|
|
86
|
-
expanded.push(...group);
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
expanded.push(value);
|
|
90
|
-
}
|
|
91
|
-
return Array.from(new Set(expanded));
|
|
92
|
-
}
|
|
93
|
-
export function resolveToolProfilePolicy(profile) {
|
|
94
|
-
if (!profile) {
|
|
95
|
-
return undefined;
|
|
96
|
-
}
|
|
97
|
-
const resolved = TOOL_PROFILES[profile];
|
|
98
|
-
if (!resolved) {
|
|
99
|
-
return undefined;
|
|
100
|
-
}
|
|
101
|
-
if (!resolved.allow && !resolved.deny) {
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
allow: resolved.allow ? [...resolved.allow] : undefined,
|
|
106
|
-
deny: resolved.deny ? [...resolved.deny] : undefined,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Conformance snapshot for tool policy.
|
|
3
|
-
*
|
|
4
|
-
* Security note:
|
|
5
|
-
* - This is static, build-time information (no runtime I/O, no network exposure).
|
|
6
|
-
* - Intended for CI/tools to detect drift between the implementation policy and
|
|
7
|
-
* the formal models/extractors.
|
|
8
|
-
*/
|
|
9
|
-
import { TOOL_GROUPS } from "./tool-policy.js";
|
|
10
|
-
// Tool name aliases are intentionally not exported from tool-policy today.
|
|
11
|
-
// Keep the conformance snapshot focused on exported policy constants.
|
|
12
|
-
export const TOOL_POLICY_CONFORMANCE = {
|
|
13
|
-
toolGroups: TOOL_GROUPS,
|
|
14
|
-
};
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Result Truncation & Context Pruning
|
|
3
|
-
*
|
|
4
|
-
* Implements:
|
|
5
|
-
* - Head+tail truncation (preserves diagnostics)
|
|
6
|
-
* - Context pruning for tool-results during soft-trim
|
|
7
|
-
* - Preserve recent turns verbatim
|
|
8
|
-
* - Multimodal + tool-result hints
|
|
9
|
-
*
|
|
10
|
-
* OpenClaw #32384, #30951
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Default truncation config
|
|
14
|
-
* Head+tail approach preserves important diagnostics
|
|
15
|
-
*/
|
|
16
|
-
export const DEFAULT_TRUNCATION_CONFIG = {
|
|
17
|
-
maxToolResultChars: 50_000,
|
|
18
|
-
headChars: 10_000,
|
|
19
|
-
tailChars: 10_000,
|
|
20
|
-
minCharsForTruncation: 20_000,
|
|
21
|
-
preserveErrors: true,
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Truncate tool result content with head+tail strategy
|
|
25
|
-
* OpenClaw #32384 - preserves diagnostic information
|
|
26
|
-
*/
|
|
27
|
-
export function truncateToolResult(content, config = DEFAULT_TRUNCATION_CONFIG) {
|
|
28
|
-
const originalLength = content.length;
|
|
29
|
-
// Don't truncate if under threshold
|
|
30
|
-
if (originalLength <= config.minCharsForTruncation) {
|
|
31
|
-
return { truncated: content, wasTruncated: false, originalLength };
|
|
32
|
-
}
|
|
33
|
-
// Don't truncate if under max
|
|
34
|
-
if (originalLength <= config.maxToolResultChars) {
|
|
35
|
-
return { truncated: content, wasTruncated: false, originalLength };
|
|
36
|
-
}
|
|
37
|
-
// Head+tail truncation
|
|
38
|
-
const head = content.slice(0, config.headChars);
|
|
39
|
-
const tail = content.slice(-config.tailChars);
|
|
40
|
-
const omitted = originalLength - config.headChars - config.tailChars;
|
|
41
|
-
const truncated = `${head}\n\n[...${omitted.toLocaleString()} characters omitted...]\n\n${tail}`;
|
|
42
|
-
return { truncated, wasTruncated: true, originalLength };
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Check if a message is a tool result
|
|
46
|
-
*/
|
|
47
|
-
export function isToolResultMessage(message) {
|
|
48
|
-
return message.role === "toolResult";
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Check if a tool result contains an error
|
|
52
|
-
*/
|
|
53
|
-
export function isToolResultError(message) {
|
|
54
|
-
if (!isToolResultMessage(message)) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
return message.isError === true;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Extract tool result content from message
|
|
61
|
-
*/
|
|
62
|
-
export function extractToolResultContent(message) {
|
|
63
|
-
const content = message.content;
|
|
64
|
-
if (typeof content === "string") {
|
|
65
|
-
return content;
|
|
66
|
-
}
|
|
67
|
-
if (content && typeof content === "object") {
|
|
68
|
-
try {
|
|
69
|
-
return JSON.stringify(content);
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
return JSON.stringify({ error: "Failed to stringify content" });
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return "";
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Apply truncation to tool result messages
|
|
79
|
-
* Preserves errors by default
|
|
80
|
-
*/
|
|
81
|
-
export function truncateToolResultMessages(messages, config = DEFAULT_TRUNCATION_CONFIG) {
|
|
82
|
-
return messages.map((message) => {
|
|
83
|
-
if (!isToolResultMessage(message)) {
|
|
84
|
-
return message;
|
|
85
|
-
}
|
|
86
|
-
// Preserve errors if configured
|
|
87
|
-
if (config.preserveErrors && isToolResultError(message)) {
|
|
88
|
-
return message;
|
|
89
|
-
}
|
|
90
|
-
const content = extractToolResultContent(message);
|
|
91
|
-
const { truncated, wasTruncated } = truncateToolResult(content, config);
|
|
92
|
-
if (!wasTruncated) {
|
|
93
|
-
return message;
|
|
94
|
-
}
|
|
95
|
-
// Create new message with truncated content
|
|
96
|
-
return {
|
|
97
|
-
...message,
|
|
98
|
-
content: truncated,
|
|
99
|
-
};
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Default context pruning config
|
|
104
|
-
*/
|
|
105
|
-
export const DEFAULT_CONTEXT_PRUNING_CONFIG = {
|
|
106
|
-
keepRecentTurns: 10,
|
|
107
|
-
pruneToolResultsOlderThan: 20,
|
|
108
|
-
keepErrorToolResults: true,
|
|
109
|
-
keepMultimodalContent: true,
|
|
110
|
-
compressToolResults: false,
|
|
111
|
-
};
|
|
112
|
-
/**
|
|
113
|
-
* Count turns in message history
|
|
114
|
-
* A turn = user message + assistant response
|
|
115
|
-
*/
|
|
116
|
-
export function countTurns(messages) {
|
|
117
|
-
let turns = 0;
|
|
118
|
-
let hasUserMessage = false;
|
|
119
|
-
for (const message of messages) {
|
|
120
|
-
const role = message.role;
|
|
121
|
-
if (role === "user") {
|
|
122
|
-
hasUserMessage = true;
|
|
123
|
-
}
|
|
124
|
-
else if (role === "assistant" && hasUserMessage) {
|
|
125
|
-
turns += 1;
|
|
126
|
-
hasUserMessage = false;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
// Count incomplete turn if there's a user message without response
|
|
130
|
-
if (hasUserMessage) {
|
|
131
|
-
turns += 1;
|
|
132
|
-
}
|
|
133
|
-
return turns;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Prune context for soft-trim while preserving important information
|
|
137
|
-
* OpenClaw #30951 - maintains diagnostic quality
|
|
138
|
-
*/
|
|
139
|
-
export function pruneContextForSoftTrim(messages, config = DEFAULT_CONTEXT_PRUNING_CONFIG) {
|
|
140
|
-
let currentTurn = 0;
|
|
141
|
-
// Process messages in reverse to identify recent turns
|
|
142
|
-
const reversedMessages = [...messages].reverse();
|
|
143
|
-
const keptMessages = [];
|
|
144
|
-
for (const message of reversedMessages) {
|
|
145
|
-
const role = message.role;
|
|
146
|
-
const isToolResult = isToolResultMessage(message);
|
|
147
|
-
const isToolError = isToolResultError(message);
|
|
148
|
-
const hasMultimodal = hasMultimodalContent(message);
|
|
149
|
-
// Always keep user and assistant messages in recent turns
|
|
150
|
-
if (role === "user" || role === "assistant") {
|
|
151
|
-
if (currentTurn < config.keepRecentTurns) {
|
|
152
|
-
keptMessages.unshift(message);
|
|
153
|
-
if (role === "assistant") {
|
|
154
|
-
currentTurn += 1;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
// Older turns: selectively prune
|
|
159
|
-
if (!isToolResult) {
|
|
160
|
-
keptMessages.unshift(message);
|
|
161
|
-
}
|
|
162
|
-
else if (config.keepErrorToolResults && isToolError) {
|
|
163
|
-
keptMessages.unshift(message);
|
|
164
|
-
}
|
|
165
|
-
else if (config.keepMultimodalContent && hasMultimodal) {
|
|
166
|
-
keptMessages.unshift(message);
|
|
167
|
-
}
|
|
168
|
-
else if (config.compressToolResults) {
|
|
169
|
-
// Compress to summary instead of full content
|
|
170
|
-
const compressed = compressToolResult(message);
|
|
171
|
-
keptMessages.unshift(compressed);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
// Tool results: apply pruning rules
|
|
177
|
-
if (isToolResult) {
|
|
178
|
-
if (currentTurn < config.keepRecentTurns) {
|
|
179
|
-
// Keep recent tool results
|
|
180
|
-
keptMessages.unshift(message);
|
|
181
|
-
}
|
|
182
|
-
else if (config.keepErrorToolResults && isToolError) {
|
|
183
|
-
// Always keep errors
|
|
184
|
-
keptMessages.unshift(message);
|
|
185
|
-
}
|
|
186
|
-
else if (config.keepMultimodalContent && hasMultimodal) {
|
|
187
|
-
// Keep multimodal content
|
|
188
|
-
keptMessages.unshift(message);
|
|
189
|
-
}
|
|
190
|
-
else if (config.compressToolResults) {
|
|
191
|
-
// Compress older tool results
|
|
192
|
-
const compressed = compressToolResult(message);
|
|
193
|
-
keptMessages.unshift(compressed);
|
|
194
|
-
}
|
|
195
|
-
// Otherwise: prune (don't add to keptMessages)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
return keptMessages;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Check if a message has multimodal content (images, files, etc.)
|
|
202
|
-
*/
|
|
203
|
-
export function hasMultimodalContent(message) {
|
|
204
|
-
const content = message.content;
|
|
205
|
-
if (!content) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
if (Array.isArray(content)) {
|
|
209
|
-
return content.some((item) => {
|
|
210
|
-
if (!item || typeof item !== "object") {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
const record = item;
|
|
214
|
-
return (typeof record.image === "string" ||
|
|
215
|
-
typeof record.file === "string" ||
|
|
216
|
-
typeof record.data === "string" ||
|
|
217
|
-
typeof record.url === "string");
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Compress tool result to summary (for context pruning)
|
|
224
|
-
*/
|
|
225
|
-
export function compressToolResult(message) {
|
|
226
|
-
if (!isToolResultMessage(message)) {
|
|
227
|
-
return message;
|
|
228
|
-
}
|
|
229
|
-
const toolName = message.toolName;
|
|
230
|
-
const toolNameStr = typeof toolName === "string" && toolName.trim() ? toolName : "unknown";
|
|
231
|
-
const content = extractToolResultContent(message);
|
|
232
|
-
// Create summary instead of full content
|
|
233
|
-
const summary = `[Tool: ${toolNameStr}] - ${content.length.toLocaleString()} characters`;
|
|
234
|
-
return {
|
|
235
|
-
...message,
|
|
236
|
-
content: summary,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Audit compaction quality
|
|
241
|
-
* OpenClaw #30951 - ensures compaction doesn't lose critical information
|
|
242
|
-
*/
|
|
243
|
-
export function auditCompactionQuality(params) {
|
|
244
|
-
const { originalMessages, compactedMessages, summary } = params;
|
|
245
|
-
const issues = [];
|
|
246
|
-
const recommendations = [];
|
|
247
|
-
let score = 100;
|
|
248
|
-
// Check 1: Tool errors preserved
|
|
249
|
-
const originalErrors = originalMessages.filter(isToolResultError).length;
|
|
250
|
-
const compactedErrors = compactedMessages.filter(isToolResultError).length;
|
|
251
|
-
if (compactedErrors < originalErrors) {
|
|
252
|
-
issues.push(`Lost ${originalErrors - compactedErrors} tool error messages`);
|
|
253
|
-
recommendations.push("Preserve all tool errors during compaction");
|
|
254
|
-
score -= 20;
|
|
255
|
-
}
|
|
256
|
-
// Check 2: Recent turns preserved
|
|
257
|
-
const originalTurns = countTurns(originalMessages);
|
|
258
|
-
const compactedTurns = countTurns(compactedMessages);
|
|
259
|
-
if (compactedTurns < originalTurns * 0.3) {
|
|
260
|
-
issues.push("Compaction ratio too aggressive (<30% of turns preserved)");
|
|
261
|
-
recommendations.push("Keep at least 30% of recent turns verbatim");
|
|
262
|
-
score -= 15;
|
|
263
|
-
}
|
|
264
|
-
// Check 3: Summary quality
|
|
265
|
-
if (summary) {
|
|
266
|
-
if (summary.length < 50) {
|
|
267
|
-
issues.push("Summary too short (may lack detail)");
|
|
268
|
-
recommendations.push("Generate more detailed summaries (min 50 chars)");
|
|
269
|
-
score -= 10;
|
|
270
|
-
}
|
|
271
|
-
if (summary.length > 5000) {
|
|
272
|
-
issues.push("Summary too long (defeats compaction purpose)");
|
|
273
|
-
recommendations.push("Keep summaries concise (<5000 chars)");
|
|
274
|
-
score -= 5;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
// Check 4: Multimodal content
|
|
278
|
-
const originalMultimodal = originalMessages.filter(hasMultimodalContent).length;
|
|
279
|
-
const compactedMultimodal = compactedMessages.filter(hasMultimodalContent).length;
|
|
280
|
-
if (compactedMultimodal < originalMultimodal) {
|
|
281
|
-
issues.push(`Lost ${originalMultimodal - compactedMultimodal} multimodal messages`);
|
|
282
|
-
recommendations.push("Preserve multimodal content during compaction");
|
|
283
|
-
score -= 15;
|
|
284
|
-
}
|
|
285
|
-
// Check 5: Message order
|
|
286
|
-
const lastOriginalRole = originalMessages[originalMessages.length - 1]?.role;
|
|
287
|
-
const lastCompactedRole = compactedMessages[compactedMessages.length - 1]?.role;
|
|
288
|
-
if (lastOriginalRole !== lastCompactedRole) {
|
|
289
|
-
issues.push("Message order may be incorrect (last message role mismatch)");
|
|
290
|
-
recommendations.push("Verify message ordering after compaction");
|
|
291
|
-
score -= 10;
|
|
292
|
-
}
|
|
293
|
-
return {
|
|
294
|
-
score: Math.max(0, score),
|
|
295
|
-
issues,
|
|
296
|
-
recommendations,
|
|
297
|
-
passed: score >= 70,
|
|
298
|
-
};
|
|
299
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { vi } from "vitest";
|
|
2
|
-
export const callGatewayMock = vi.fn();
|
|
3
|
-
vi.mock("../../gateway/call.js", () => ({
|
|
4
|
-
callGateway: (opts) => callGatewayMock(opts),
|
|
5
|
-
}));
|
|
6
|
-
vi.mock("../agent-scope.js", () => ({
|
|
7
|
-
resolveSessionAgentId: () => "agent-123",
|
|
8
|
-
}));
|
|
9
|
-
export function resetCronToolGatewayMock() {
|
|
10
|
-
callGatewayMock.mockReset();
|
|
11
|
-
callGatewayMock.mockResolvedValue({ ok: true });
|
|
12
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { PermissionFlagsBits } from "discord-api-types/v10";
|
|
2
|
-
import { readNumberParam, readStringParam } from "./common.js";
|
|
3
|
-
const moderationPermissions = {
|
|
4
|
-
timeout: PermissionFlagsBits.ModerateMembers,
|
|
5
|
-
kick: PermissionFlagsBits.KickMembers,
|
|
6
|
-
ban: PermissionFlagsBits.BanMembers,
|
|
7
|
-
};
|
|
8
|
-
export function isDiscordModerationAction(action) {
|
|
9
|
-
return action === "timeout" || action === "kick" || action === "ban";
|
|
10
|
-
}
|
|
11
|
-
export function requiredGuildPermissionForModerationAction(action) {
|
|
12
|
-
return moderationPermissions[action];
|
|
13
|
-
}
|
|
14
|
-
export function readDiscordModerationCommand(action, params) {
|
|
15
|
-
if (!isDiscordModerationAction(action)) {
|
|
16
|
-
throw new Error(`Unsupported Discord moderation action: ${action}`);
|
|
17
|
-
}
|
|
18
|
-
return {
|
|
19
|
-
action,
|
|
20
|
-
guildId: readStringParam(params, "guildId", { required: true }),
|
|
21
|
-
userId: readStringParam(params, "userId", { required: true }),
|
|
22
|
-
durationMinutes: readNumberParam(params, "durationMinutes", { integer: true }),
|
|
23
|
-
until: readStringParam(params, "until"),
|
|
24
|
-
reason: readStringParam(params, "reason"),
|
|
25
|
-
deleteMessageDays: readNumberParam(params, "deleteMessageDays", { integer: true }),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { getGateway } from "../../discord/monitor/gateway-registry.js";
|
|
2
|
-
import { jsonResult, readStringParam } from "./common.js";
|
|
3
|
-
const ACTIVITY_TYPE_MAP = {
|
|
4
|
-
playing: 0,
|
|
5
|
-
streaming: 1,
|
|
6
|
-
listening: 2,
|
|
7
|
-
watching: 3,
|
|
8
|
-
custom: 4,
|
|
9
|
-
competing: 5,
|
|
10
|
-
};
|
|
11
|
-
const VALID_STATUSES = new Set(["online", "dnd", "idle", "invisible"]);
|
|
12
|
-
export async function handleDiscordPresenceAction(action, params, isActionEnabled) {
|
|
13
|
-
if (action !== "setPresence") {
|
|
14
|
-
throw new Error(`Unknown presence action: ${action}`);
|
|
15
|
-
}
|
|
16
|
-
if (!isActionEnabled("presence", false)) {
|
|
17
|
-
throw new Error("Discord presence changes are disabled.");
|
|
18
|
-
}
|
|
19
|
-
const accountId = readStringParam(params, "accountId");
|
|
20
|
-
const gateway = getGateway(accountId);
|
|
21
|
-
if (!gateway) {
|
|
22
|
-
throw new Error(`Discord gateway not available${accountId ? ` for account "${accountId}"` : ""}. The bot may not be connected.`);
|
|
23
|
-
}
|
|
24
|
-
if (!gateway.isConnected) {
|
|
25
|
-
throw new Error(`Discord gateway is not connected${accountId ? ` for account "${accountId}"` : ""}.`);
|
|
26
|
-
}
|
|
27
|
-
const statusRaw = readStringParam(params, "status") ?? "online";
|
|
28
|
-
if (!VALID_STATUSES.has(statusRaw)) {
|
|
29
|
-
throw new Error(`Invalid status "${statusRaw}". Must be one of: ${[...VALID_STATUSES].join(", ")}`);
|
|
30
|
-
}
|
|
31
|
-
const status = statusRaw;
|
|
32
|
-
const activityTypeRaw = readStringParam(params, "activityType");
|
|
33
|
-
const activityName = readStringParam(params, "activityName");
|
|
34
|
-
const activities = [];
|
|
35
|
-
if (activityTypeRaw || activityName) {
|
|
36
|
-
if (!activityTypeRaw) {
|
|
37
|
-
throw new Error("activityType is required when activityName is provided. " +
|
|
38
|
-
`Valid types: ${Object.keys(ACTIVITY_TYPE_MAP).join(", ")}`);
|
|
39
|
-
}
|
|
40
|
-
const typeNum = ACTIVITY_TYPE_MAP[activityTypeRaw.toLowerCase()];
|
|
41
|
-
if (typeNum === undefined) {
|
|
42
|
-
throw new Error(`Invalid activityType "${activityTypeRaw}". Must be one of: ${Object.keys(ACTIVITY_TYPE_MAP).join(", ")}`);
|
|
43
|
-
}
|
|
44
|
-
const activity = {
|
|
45
|
-
name: activityName ?? "",
|
|
46
|
-
type: typeNum,
|
|
47
|
-
};
|
|
48
|
-
// Streaming URL (Twitch/YouTube). May not render for bots but is the correct payload shape.
|
|
49
|
-
if (typeNum === 1) {
|
|
50
|
-
const url = readStringParam(params, "activityUrl");
|
|
51
|
-
if (url) {
|
|
52
|
-
activity.url = url;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const state = readStringParam(params, "activityState");
|
|
56
|
-
if (state) {
|
|
57
|
-
activity.state = state;
|
|
58
|
-
}
|
|
59
|
-
activities.push(activity);
|
|
60
|
-
}
|
|
61
|
-
const presenceData = {
|
|
62
|
-
since: null,
|
|
63
|
-
activities,
|
|
64
|
-
status,
|
|
65
|
-
afk: false,
|
|
66
|
-
};
|
|
67
|
-
gateway.updatePresence(presenceData);
|
|
68
|
-
return jsonResult({
|
|
69
|
-
ok: true,
|
|
70
|
-
status,
|
|
71
|
-
activities: activities.map((a) => ({
|
|
72
|
-
type: a.type,
|
|
73
|
-
name: a.name,
|
|
74
|
-
...(a.url ? { url: a.url } : {}),
|
|
75
|
-
...(a.state ? { state: a.state } : {}),
|
|
76
|
-
})),
|
|
77
|
-
});
|
|
78
|
-
}
|