@poolzin/pool-bot 2026.3.25 → 2026.3.27
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 +32 -257
- 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,209 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ACP Persistent Bindings Store
|
|
3
|
-
* Persists tool bindings across sessions with validation
|
|
4
|
-
*/
|
|
5
|
-
import * as fs from "fs";
|
|
6
|
-
import * as path from "path";
|
|
7
|
-
/**
|
|
8
|
-
* Persistent store for ACP tool bindings
|
|
9
|
-
*/
|
|
10
|
-
export class BindingsStore {
|
|
11
|
-
dataDir;
|
|
12
|
-
bindingsFile;
|
|
13
|
-
cache = new Map();
|
|
14
|
-
validateOnLoad;
|
|
15
|
-
constructor(options) {
|
|
16
|
-
this.dataDir = options.dataDir;
|
|
17
|
-
this.bindingsFile = path.join(this.dataDir, "bindings.json");
|
|
18
|
-
this.validateOnLoad = options.validateOnLoad ?? true;
|
|
19
|
-
// Ensure data directory exists
|
|
20
|
-
if (!fs.existsSync(this.dataDir)) {
|
|
21
|
-
fs.mkdirSync(this.dataDir, { recursive: true });
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Load bindings from disk
|
|
26
|
-
*/
|
|
27
|
-
async load() {
|
|
28
|
-
const errors = [];
|
|
29
|
-
const warnings = [];
|
|
30
|
-
if (!fs.existsSync(this.bindingsFile)) {
|
|
31
|
-
return { valid: true, errors, warnings };
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
const content = fs.readFileSync(this.bindingsFile, "utf-8");
|
|
35
|
-
const data = JSON.parse(content);
|
|
36
|
-
// Clear cache
|
|
37
|
-
this.cache.clear();
|
|
38
|
-
// Load and validate each binding
|
|
39
|
-
for (const binding of data) {
|
|
40
|
-
if (this.validateOnLoad) {
|
|
41
|
-
const validation = this.validateBinding(binding);
|
|
42
|
-
errors.push(...validation.errors.map((e) => `Binding ${binding.id}: ${e}`));
|
|
43
|
-
warnings.push(...validation.warnings.map((w) => `Binding ${binding.id}: ${w}`));
|
|
44
|
-
if (!validation.valid) {
|
|
45
|
-
continue; // Skip invalid bindings
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Check expiration
|
|
49
|
-
if (binding.expiresAt && binding.expiresAt < Date.now()) {
|
|
50
|
-
warnings.push(`Binding ${binding.id}: expired`);
|
|
51
|
-
continue; // Skip expired bindings
|
|
52
|
-
}
|
|
53
|
-
this.cache.set(binding.id, binding);
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
valid: errors.length === 0,
|
|
57
|
-
errors,
|
|
58
|
-
warnings,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
catch (e) {
|
|
62
|
-
errors.push(`Failed to load bindings: ${e.message}`);
|
|
63
|
-
return { valid: false, errors, warnings };
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Save bindings to disk
|
|
68
|
-
*/
|
|
69
|
-
async save() {
|
|
70
|
-
const bindings = Array.from(this.cache.values());
|
|
71
|
-
const content = JSON.stringify(bindings, null, 2);
|
|
72
|
-
fs.writeFileSync(this.bindingsFile, content, "utf-8");
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Add a new binding
|
|
76
|
-
*/
|
|
77
|
-
addBinding(binding) {
|
|
78
|
-
this.cache.set(binding.id, binding);
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Get a binding by ID
|
|
82
|
-
*/
|
|
83
|
-
getBinding(id) {
|
|
84
|
-
return this.cache.get(id);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Remove a binding by ID
|
|
88
|
-
*/
|
|
89
|
-
removeBinding(id) {
|
|
90
|
-
return this.cache.delete(id);
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Get all bindings for a session
|
|
94
|
-
*/
|
|
95
|
-
getSessionBindings(sessionId) {
|
|
96
|
-
return Array.from(this.cache.values()).filter((b) => b.scope === "session" && b.sessionId === sessionId);
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Get all bindings for an agent
|
|
100
|
-
*/
|
|
101
|
-
getAgentBindings(agentId) {
|
|
102
|
-
return Array.from(this.cache.values()).filter((b) => b.scope === "agent" && b.agentId === agentId);
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Get all global bindings
|
|
106
|
-
*/
|
|
107
|
-
getGlobalBindings() {
|
|
108
|
-
return Array.from(this.cache.values()).filter((b) => b.scope === "global");
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Get all bindings (optionally filtered by scope)
|
|
112
|
-
*/
|
|
113
|
-
getAllBindings(scope) {
|
|
114
|
-
const all = Array.from(this.cache.values());
|
|
115
|
-
if (scope) {
|
|
116
|
-
return all.filter((b) => b.scope === scope);
|
|
117
|
-
}
|
|
118
|
-
return all;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Clear expired bindings
|
|
122
|
-
*/
|
|
123
|
-
clearExpired() {
|
|
124
|
-
const now = Date.now();
|
|
125
|
-
let cleared = 0;
|
|
126
|
-
for (const [id, binding] of this.cache.entries()) {
|
|
127
|
-
if (binding.expiresAt && binding.expiresAt < now) {
|
|
128
|
-
this.cache.delete(id);
|
|
129
|
-
cleared++;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return cleared;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Clear all bindings
|
|
136
|
-
*/
|
|
137
|
-
clearAll() {
|
|
138
|
-
this.cache.clear();
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Validate a single binding
|
|
142
|
-
*/
|
|
143
|
-
validateBinding(binding) {
|
|
144
|
-
const errors = [];
|
|
145
|
-
const warnings = [];
|
|
146
|
-
// Required fields
|
|
147
|
-
if (!binding.id) {
|
|
148
|
-
errors.push("Missing required field: id");
|
|
149
|
-
}
|
|
150
|
-
if (!binding.name) {
|
|
151
|
-
errors.push("Missing required field: name");
|
|
152
|
-
}
|
|
153
|
-
if (!binding.scope) {
|
|
154
|
-
errors.push("Missing required field: scope");
|
|
155
|
-
}
|
|
156
|
-
else if (!["session", "global", "agent"].includes(binding.scope)) {
|
|
157
|
-
errors.push(`Invalid scope: ${binding.scope}`);
|
|
158
|
-
}
|
|
159
|
-
// Scope-specific validation
|
|
160
|
-
if (binding.scope === "session" && !binding.sessionId) {
|
|
161
|
-
errors.push("Session scope requires sessionId");
|
|
162
|
-
}
|
|
163
|
-
if (binding.scope === "agent" && !binding.agentId) {
|
|
164
|
-
errors.push("Agent scope requires agentId");
|
|
165
|
-
}
|
|
166
|
-
// Timestamp validation
|
|
167
|
-
if (!binding.createdAt) {
|
|
168
|
-
errors.push("Missing required field: createdAt");
|
|
169
|
-
}
|
|
170
|
-
if (binding.expiresAt && binding.expiresAt <= binding.createdAt) {
|
|
171
|
-
errors.push("expiresAt must be after createdAt");
|
|
172
|
-
}
|
|
173
|
-
// Warnings
|
|
174
|
-
if (binding.expiresAt && binding.expiresAt - binding.createdAt > 86400000 * 30) {
|
|
175
|
-
warnings.push("Binding expires in more than 30 days");
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
valid: errors.length === 0,
|
|
179
|
-
errors,
|
|
180
|
-
warnings,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Get store statistics
|
|
185
|
-
*/
|
|
186
|
-
getStats() {
|
|
187
|
-
const all = Array.from(this.cache.values());
|
|
188
|
-
const now = Date.now();
|
|
189
|
-
return {
|
|
190
|
-
total: all.length,
|
|
191
|
-
byScope: {
|
|
192
|
-
session: all.filter((b) => b.scope === "session").length,
|
|
193
|
-
global: all.filter((b) => b.scope === "global").length,
|
|
194
|
-
agent: all.filter((b) => b.scope === "agent").length,
|
|
195
|
-
},
|
|
196
|
-
expired: all.filter((b) => b.expiresAt && b.expiresAt < now).length,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Create a default bindings store
|
|
202
|
-
*/
|
|
203
|
-
export function createBindingsStore(dataDir) {
|
|
204
|
-
const dir = dataDir || path.join(process.cwd(), ".poolbot", "bindings");
|
|
205
|
-
return new BindingsStore({
|
|
206
|
-
dataDir: dir,
|
|
207
|
-
validateOnLoad: true,
|
|
208
|
-
});
|
|
209
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export class RuntimeCache {
|
|
2
|
-
cache = new Map();
|
|
3
|
-
size() {
|
|
4
|
-
return this.cache.size;
|
|
5
|
-
}
|
|
6
|
-
has(actorKey) {
|
|
7
|
-
return this.cache.has(actorKey);
|
|
8
|
-
}
|
|
9
|
-
get(actorKey, params = {}) {
|
|
10
|
-
const entry = this.cache.get(actorKey);
|
|
11
|
-
if (!entry) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
if (params.touch !== false) {
|
|
15
|
-
entry.lastTouchedAt = params.now ?? Date.now();
|
|
16
|
-
}
|
|
17
|
-
return entry.state;
|
|
18
|
-
}
|
|
19
|
-
peek(actorKey) {
|
|
20
|
-
return this.get(actorKey, { touch: false });
|
|
21
|
-
}
|
|
22
|
-
getLastTouchedAt(actorKey) {
|
|
23
|
-
return this.cache.get(actorKey)?.lastTouchedAt ?? null;
|
|
24
|
-
}
|
|
25
|
-
set(actorKey, state, params = {}) {
|
|
26
|
-
this.cache.set(actorKey, {
|
|
27
|
-
state,
|
|
28
|
-
lastTouchedAt: params.now ?? Date.now(),
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
clear(actorKey) {
|
|
32
|
-
this.cache.delete(actorKey);
|
|
33
|
-
}
|
|
34
|
-
snapshot(params = {}) {
|
|
35
|
-
const now = params.now ?? Date.now();
|
|
36
|
-
const entries = [];
|
|
37
|
-
for (const [actorKey, entry] of this.cache.entries()) {
|
|
38
|
-
entries.push({
|
|
39
|
-
actorKey,
|
|
40
|
-
state: entry.state,
|
|
41
|
-
lastTouchedAt: entry.lastTouchedAt,
|
|
42
|
-
idleMs: Math.max(0, now - entry.lastTouchedAt),
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
return entries;
|
|
46
|
-
}
|
|
47
|
-
collectIdleCandidates(params) {
|
|
48
|
-
if (!Number.isFinite(params.maxIdleMs) || params.maxIdleMs <= 0) {
|
|
49
|
-
return [];
|
|
50
|
-
}
|
|
51
|
-
const now = params.now ?? Date.now();
|
|
52
|
-
return this.snapshot({ now }).filter((entry) => entry.idleMs >= params.maxIdleMs);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import { isAbsolute } from "node:path";
|
|
2
|
-
import { AcpRuntimeError } from "../runtime/errors.js";
|
|
3
|
-
const MAX_RUNTIME_MODE_LENGTH = 64;
|
|
4
|
-
const MAX_MODEL_LENGTH = 200;
|
|
5
|
-
const MAX_PERMISSION_PROFILE_LENGTH = 80;
|
|
6
|
-
const MAX_CWD_LENGTH = 4096;
|
|
7
|
-
const MIN_TIMEOUT_SECONDS = 1;
|
|
8
|
-
const MAX_TIMEOUT_SECONDS = 24 * 60 * 60;
|
|
9
|
-
const MAX_BACKEND_OPTION_KEY_LENGTH = 64;
|
|
10
|
-
const MAX_BACKEND_OPTION_VALUE_LENGTH = 512;
|
|
11
|
-
const MAX_BACKEND_EXTRAS = 32;
|
|
12
|
-
const SAFE_OPTION_KEY_RE = /^[a-z0-9][a-z0-9._:-]*$/i;
|
|
13
|
-
function failInvalidOption(message) {
|
|
14
|
-
throw new AcpRuntimeError("ACP_INVALID_RUNTIME_OPTION", message);
|
|
15
|
-
}
|
|
16
|
-
function validateNoControlChars(value, field) {
|
|
17
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
18
|
-
const code = value.charCodeAt(i);
|
|
19
|
-
if (code < 32 || code === 127) {
|
|
20
|
-
failInvalidOption(`${field} must not include control characters.`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return value;
|
|
24
|
-
}
|
|
25
|
-
function validateBoundedText(params) {
|
|
26
|
-
const normalized = normalizeText(params.value);
|
|
27
|
-
if (!normalized) {
|
|
28
|
-
failInvalidOption(`${params.field} must not be empty.`);
|
|
29
|
-
}
|
|
30
|
-
if (normalized.length > params.maxLength) {
|
|
31
|
-
failInvalidOption(`${params.field} must be at most ${params.maxLength} characters.`);
|
|
32
|
-
}
|
|
33
|
-
return validateNoControlChars(normalized, params.field);
|
|
34
|
-
}
|
|
35
|
-
function validateBackendOptionKey(rawKey) {
|
|
36
|
-
const key = validateBoundedText({
|
|
37
|
-
value: rawKey,
|
|
38
|
-
field: "ACP config key",
|
|
39
|
-
maxLength: MAX_BACKEND_OPTION_KEY_LENGTH,
|
|
40
|
-
});
|
|
41
|
-
if (!SAFE_OPTION_KEY_RE.test(key)) {
|
|
42
|
-
failInvalidOption("ACP config key must use letters, numbers, dots, colons, underscores, or dashes.");
|
|
43
|
-
}
|
|
44
|
-
return key;
|
|
45
|
-
}
|
|
46
|
-
function validateBackendOptionValue(rawValue) {
|
|
47
|
-
return validateBoundedText({
|
|
48
|
-
value: rawValue,
|
|
49
|
-
field: "ACP config value",
|
|
50
|
-
maxLength: MAX_BACKEND_OPTION_VALUE_LENGTH,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
export function validateRuntimeModeInput(rawMode) {
|
|
54
|
-
return validateBoundedText({
|
|
55
|
-
value: rawMode,
|
|
56
|
-
field: "Runtime mode",
|
|
57
|
-
maxLength: MAX_RUNTIME_MODE_LENGTH,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
export function validateRuntimeModelInput(rawModel) {
|
|
61
|
-
return validateBoundedText({
|
|
62
|
-
value: rawModel,
|
|
63
|
-
field: "Model id",
|
|
64
|
-
maxLength: MAX_MODEL_LENGTH,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
export function validateRuntimePermissionProfileInput(rawProfile) {
|
|
68
|
-
return validateBoundedText({
|
|
69
|
-
value: rawProfile,
|
|
70
|
-
field: "Permission profile",
|
|
71
|
-
maxLength: MAX_PERMISSION_PROFILE_LENGTH,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
export function validateRuntimeCwdInput(rawCwd) {
|
|
75
|
-
const cwd = validateBoundedText({
|
|
76
|
-
value: rawCwd,
|
|
77
|
-
field: "Working directory",
|
|
78
|
-
maxLength: MAX_CWD_LENGTH,
|
|
79
|
-
});
|
|
80
|
-
if (!isAbsolute(cwd)) {
|
|
81
|
-
failInvalidOption(`Working directory must be an absolute path. Received "${cwd}".`);
|
|
82
|
-
}
|
|
83
|
-
return cwd;
|
|
84
|
-
}
|
|
85
|
-
export function validateRuntimeTimeoutSecondsInput(rawTimeout) {
|
|
86
|
-
if (typeof rawTimeout !== "number" || !Number.isFinite(rawTimeout)) {
|
|
87
|
-
failInvalidOption("Timeout must be a positive integer in seconds.");
|
|
88
|
-
}
|
|
89
|
-
const timeout = Math.round(rawTimeout);
|
|
90
|
-
if (timeout < MIN_TIMEOUT_SECONDS || timeout > MAX_TIMEOUT_SECONDS) {
|
|
91
|
-
failInvalidOption(`Timeout must be between ${MIN_TIMEOUT_SECONDS} and ${MAX_TIMEOUT_SECONDS} seconds.`);
|
|
92
|
-
}
|
|
93
|
-
return timeout;
|
|
94
|
-
}
|
|
95
|
-
export function validateRuntimeConfigOptionInput(rawKey, rawValue) {
|
|
96
|
-
return {
|
|
97
|
-
key: validateBackendOptionKey(rawKey),
|
|
98
|
-
value: validateBackendOptionValue(rawValue),
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
export function validateRuntimeOptionPatch(patch) {
|
|
102
|
-
if (!patch) {
|
|
103
|
-
return {};
|
|
104
|
-
}
|
|
105
|
-
const rawPatch = patch;
|
|
106
|
-
const allowedKeys = new Set([
|
|
107
|
-
"runtimeMode",
|
|
108
|
-
"model",
|
|
109
|
-
"cwd",
|
|
110
|
-
"permissionProfile",
|
|
111
|
-
"timeoutSeconds",
|
|
112
|
-
"backendExtras",
|
|
113
|
-
]);
|
|
114
|
-
for (const key of Object.keys(rawPatch)) {
|
|
115
|
-
if (!allowedKeys.has(key)) {
|
|
116
|
-
failInvalidOption(`Unknown runtime option "${key}".`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
const next = {};
|
|
120
|
-
if (Object.hasOwn(rawPatch, "runtimeMode")) {
|
|
121
|
-
next.runtimeMode =
|
|
122
|
-
rawPatch.runtimeMode === undefined
|
|
123
|
-
? undefined
|
|
124
|
-
: validateRuntimeModeInput(rawPatch.runtimeMode);
|
|
125
|
-
}
|
|
126
|
-
if (Object.hasOwn(rawPatch, "model")) {
|
|
127
|
-
next.model =
|
|
128
|
-
rawPatch.model === undefined ? undefined : validateRuntimeModelInput(rawPatch.model);
|
|
129
|
-
}
|
|
130
|
-
if (Object.hasOwn(rawPatch, "cwd")) {
|
|
131
|
-
next.cwd = rawPatch.cwd === undefined ? undefined : validateRuntimeCwdInput(rawPatch.cwd);
|
|
132
|
-
}
|
|
133
|
-
if (Object.hasOwn(rawPatch, "permissionProfile")) {
|
|
134
|
-
next.permissionProfile =
|
|
135
|
-
rawPatch.permissionProfile === undefined
|
|
136
|
-
? undefined
|
|
137
|
-
: validateRuntimePermissionProfileInput(rawPatch.permissionProfile);
|
|
138
|
-
}
|
|
139
|
-
if (Object.hasOwn(rawPatch, "timeoutSeconds")) {
|
|
140
|
-
next.timeoutSeconds =
|
|
141
|
-
rawPatch.timeoutSeconds === undefined
|
|
142
|
-
? undefined
|
|
143
|
-
: validateRuntimeTimeoutSecondsInput(rawPatch.timeoutSeconds);
|
|
144
|
-
}
|
|
145
|
-
if (Object.hasOwn(rawPatch, "backendExtras")) {
|
|
146
|
-
const rawExtras = rawPatch.backendExtras;
|
|
147
|
-
if (rawExtras === undefined) {
|
|
148
|
-
next.backendExtras = undefined;
|
|
149
|
-
}
|
|
150
|
-
else if (!rawExtras || typeof rawExtras !== "object" || Array.isArray(rawExtras)) {
|
|
151
|
-
failInvalidOption("Backend extras must be a key/value object.");
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
const entries = Object.entries(rawExtras);
|
|
155
|
-
if (entries.length > MAX_BACKEND_EXTRAS) {
|
|
156
|
-
failInvalidOption(`Backend extras must include at most ${MAX_BACKEND_EXTRAS} entries.`);
|
|
157
|
-
}
|
|
158
|
-
const extras = {};
|
|
159
|
-
for (const [entryKey, entryValue] of entries) {
|
|
160
|
-
const { key, value } = validateRuntimeConfigOptionInput(entryKey, entryValue);
|
|
161
|
-
extras[key] = value;
|
|
162
|
-
}
|
|
163
|
-
next.backendExtras = Object.keys(extras).length > 0 ? extras : undefined;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return next;
|
|
167
|
-
}
|
|
168
|
-
export function normalizeText(value) {
|
|
169
|
-
if (typeof value !== "string") {
|
|
170
|
-
return undefined;
|
|
171
|
-
}
|
|
172
|
-
const trimmed = value.trim();
|
|
173
|
-
return trimmed || undefined;
|
|
174
|
-
}
|
|
175
|
-
export function normalizeRuntimeOptions(options) {
|
|
176
|
-
const runtimeMode = normalizeText(options?.runtimeMode);
|
|
177
|
-
const model = normalizeText(options?.model);
|
|
178
|
-
const cwd = normalizeText(options?.cwd);
|
|
179
|
-
const permissionProfile = normalizeText(options?.permissionProfile);
|
|
180
|
-
let timeoutSeconds;
|
|
181
|
-
if (typeof options?.timeoutSeconds === "number" && Number.isFinite(options.timeoutSeconds)) {
|
|
182
|
-
const rounded = Math.round(options.timeoutSeconds);
|
|
183
|
-
if (rounded > 0) {
|
|
184
|
-
timeoutSeconds = rounded;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
const backendExtrasEntries = Object.entries(options?.backendExtras ?? {})
|
|
188
|
-
.map(([key, value]) => [normalizeText(key), normalizeText(value)])
|
|
189
|
-
.filter(([key, value]) => Boolean(key && value));
|
|
190
|
-
const backendExtras = backendExtrasEntries.length > 0 ? Object.fromEntries(backendExtrasEntries) : undefined;
|
|
191
|
-
return {
|
|
192
|
-
...(runtimeMode ? { runtimeMode } : {}),
|
|
193
|
-
...(model ? { model } : {}),
|
|
194
|
-
...(cwd ? { cwd } : {}),
|
|
195
|
-
...(permissionProfile ? { permissionProfile } : {}),
|
|
196
|
-
...(typeof timeoutSeconds === "number" ? { timeoutSeconds } : {}),
|
|
197
|
-
...(backendExtras ? { backendExtras } : {}),
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
export function mergeRuntimeOptions(params) {
|
|
201
|
-
const current = normalizeRuntimeOptions(params.current);
|
|
202
|
-
const patch = normalizeRuntimeOptions(validateRuntimeOptionPatch(params.patch));
|
|
203
|
-
const mergedExtras = {
|
|
204
|
-
...current.backendExtras,
|
|
205
|
-
...patch.backendExtras,
|
|
206
|
-
};
|
|
207
|
-
return normalizeRuntimeOptions({
|
|
208
|
-
...current,
|
|
209
|
-
...patch,
|
|
210
|
-
...(Object.keys(mergedExtras).length > 0 ? { backendExtras: mergedExtras } : {}),
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
export function runtimeOptionsEqual(a, b) {
|
|
214
|
-
return JSON.stringify(normalizeRuntimeOptions(a)) === JSON.stringify(normalizeRuntimeOptions(b));
|
|
215
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { KeyedAsyncQueue } from "../../plugin-sdk/keyed-async-queue.js";
|
|
2
|
-
export class SessionActorQueue {
|
|
3
|
-
queue = new KeyedAsyncQueue();
|
|
4
|
-
pendingBySession = new Map();
|
|
5
|
-
tailMap = new Map();
|
|
6
|
-
getTailMapForTesting() {
|
|
7
|
-
return this.tailMap;
|
|
8
|
-
}
|
|
9
|
-
getTotalPendingCount() {
|
|
10
|
-
let total = 0;
|
|
11
|
-
for (const count of this.pendingBySession.values()) {
|
|
12
|
-
total += count;
|
|
13
|
-
}
|
|
14
|
-
return total;
|
|
15
|
-
}
|
|
16
|
-
getPendingCountForSession(actorKey) {
|
|
17
|
-
return this.pendingBySession.get(actorKey) ?? 0;
|
|
18
|
-
}
|
|
19
|
-
async run(actorKey, op) {
|
|
20
|
-
this.pendingBySession.set(actorKey, (this.pendingBySession.get(actorKey) ?? 0) + 1);
|
|
21
|
-
await this.queue.acquire(actorKey);
|
|
22
|
-
try {
|
|
23
|
-
return await op();
|
|
24
|
-
}
|
|
25
|
-
finally {
|
|
26
|
-
this.queue.release(actorKey);
|
|
27
|
-
const pending = (this.pendingBySession.get(actorKey) ?? 1) - 1;
|
|
28
|
-
if (pending <= 0) {
|
|
29
|
-
this.pendingBySession.delete(actorKey);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
this.pendingBySession.set(actorKey, pending);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
package/dist/acp/index.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
export const ACP_ERROR_CODES = [
|
|
2
|
-
"ACP_BACKEND_MISSING",
|
|
3
|
-
"ACP_BACKEND_UNAVAILABLE",
|
|
4
|
-
"ACP_BACKEND_UNSUPPORTED_CONTROL",
|
|
5
|
-
"ACP_DISPATCH_DISABLED",
|
|
6
|
-
"ACP_INVALID_RUNTIME_OPTION",
|
|
7
|
-
"ACP_SESSION_INIT_FAILED",
|
|
8
|
-
"ACP_TURN_FAILED",
|
|
9
|
-
];
|
|
10
|
-
export class AcpRuntimeError extends Error {
|
|
11
|
-
code;
|
|
12
|
-
cause;
|
|
13
|
-
constructor(code, message, options) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.name = "AcpRuntimeError";
|
|
16
|
-
this.code = code;
|
|
17
|
-
this.cause = options?.cause;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
export function isAcpRuntimeError(value) {
|
|
21
|
-
return value instanceof AcpRuntimeError;
|
|
22
|
-
}
|
|
23
|
-
export function toAcpRuntimeError(params) {
|
|
24
|
-
if (params.error instanceof AcpRuntimeError) {
|
|
25
|
-
return params.error;
|
|
26
|
-
}
|
|
27
|
-
if (params.error instanceof Error) {
|
|
28
|
-
return new AcpRuntimeError(params.fallbackCode, params.error.message, {
|
|
29
|
-
cause: params.error,
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
return new AcpRuntimeError(params.fallbackCode, params.fallbackMessage, {
|
|
33
|
-
cause: params.error,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
export async function withAcpRuntimeErrorBoundary(params) {
|
|
37
|
-
try {
|
|
38
|
-
return await params.run();
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
throw toAcpRuntimeError({
|
|
42
|
-
error,
|
|
43
|
-
fallbackCode: params.fallbackCode,
|
|
44
|
-
fallbackMessage: params.fallbackMessage,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { AcpRuntimeError } from "./errors.js";
|
|
2
|
-
const ACP_RUNTIME_REGISTRY_STATE_KEY = Symbol.for("poolbot.acpRuntimeRegistryState");
|
|
3
|
-
function createAcpRuntimeRegistryGlobalState() {
|
|
4
|
-
return {
|
|
5
|
-
backendsById: new Map(),
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
function resolveAcpRuntimeRegistryGlobalState() {
|
|
9
|
-
const runtimeGlobal = globalThis;
|
|
10
|
-
if (!runtimeGlobal[ACP_RUNTIME_REGISTRY_STATE_KEY]) {
|
|
11
|
-
runtimeGlobal[ACP_RUNTIME_REGISTRY_STATE_KEY] = createAcpRuntimeRegistryGlobalState();
|
|
12
|
-
}
|
|
13
|
-
return runtimeGlobal[ACP_RUNTIME_REGISTRY_STATE_KEY];
|
|
14
|
-
}
|
|
15
|
-
const ACP_BACKENDS_BY_ID = resolveAcpRuntimeRegistryGlobalState().backendsById;
|
|
16
|
-
function normalizeBackendId(id) {
|
|
17
|
-
return id?.trim().toLowerCase() || "";
|
|
18
|
-
}
|
|
19
|
-
function isBackendHealthy(backend) {
|
|
20
|
-
if (!backend.healthy) {
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
try {
|
|
24
|
-
return backend.healthy();
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
export function registerAcpRuntimeBackend(backend) {
|
|
31
|
-
const id = normalizeBackendId(backend.id);
|
|
32
|
-
if (!id) {
|
|
33
|
-
throw new Error("ACP runtime backend id is required");
|
|
34
|
-
}
|
|
35
|
-
if (!backend.runtime) {
|
|
36
|
-
throw new Error(`ACP runtime backend "${id}" is missing runtime implementation`);
|
|
37
|
-
}
|
|
38
|
-
ACP_BACKENDS_BY_ID.set(id, {
|
|
39
|
-
...backend,
|
|
40
|
-
id,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
export function unregisterAcpRuntimeBackend(id) {
|
|
44
|
-
const normalized = normalizeBackendId(id);
|
|
45
|
-
if (!normalized) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
ACP_BACKENDS_BY_ID.delete(normalized);
|
|
49
|
-
}
|
|
50
|
-
export function getAcpRuntimeBackend(id) {
|
|
51
|
-
const normalized = normalizeBackendId(id);
|
|
52
|
-
if (normalized) {
|
|
53
|
-
return ACP_BACKENDS_BY_ID.get(normalized) ?? null;
|
|
54
|
-
}
|
|
55
|
-
if (ACP_BACKENDS_BY_ID.size === 0) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
for (const backend of ACP_BACKENDS_BY_ID.values()) {
|
|
59
|
-
if (isBackendHealthy(backend)) {
|
|
60
|
-
return backend;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return ACP_BACKENDS_BY_ID.values().next().value ?? null;
|
|
64
|
-
}
|
|
65
|
-
export function requireAcpRuntimeBackend(id) {
|
|
66
|
-
const normalized = normalizeBackendId(id);
|
|
67
|
-
const backend = getAcpRuntimeBackend(normalized || undefined);
|
|
68
|
-
if (!backend) {
|
|
69
|
-
throw new AcpRuntimeError("ACP_BACKEND_MISSING", "ACP runtime backend is not configured. Install and enable the acpx runtime plugin.");
|
|
70
|
-
}
|
|
71
|
-
if (!isBackendHealthy(backend)) {
|
|
72
|
-
throw new AcpRuntimeError("ACP_BACKEND_UNAVAILABLE", "ACP runtime backend is currently unavailable. Try again in a moment.");
|
|
73
|
-
}
|
|
74
|
-
if (normalized && backend.id !== normalized) {
|
|
75
|
-
throw new AcpRuntimeError("ACP_BACKEND_MISSING", `ACP runtime backend "${normalized}" is not registered.`);
|
|
76
|
-
}
|
|
77
|
-
return backend;
|
|
78
|
-
}
|
|
79
|
-
export const __testing = {
|
|
80
|
-
resetAcpRuntimeBackendsForTests() {
|
|
81
|
-
ACP_BACKENDS_BY_ID.clear();
|
|
82
|
-
},
|
|
83
|
-
getAcpRuntimeRegistryGlobalStateForTests() {
|
|
84
|
-
return resolveAcpRuntimeRegistryGlobalState();
|
|
85
|
-
},
|
|
86
|
-
};
|
package/dist/acp/secret-file.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import { resolveUserPath } from "../utils.js";
|
|
3
|
-
export function readSecretFromFile(filePath, label) {
|
|
4
|
-
const resolvedPath = resolveUserPath(filePath.trim());
|
|
5
|
-
if (!resolvedPath) {
|
|
6
|
-
throw new Error(`${label} file path is empty.`);
|
|
7
|
-
}
|
|
8
|
-
let raw = "";
|
|
9
|
-
try {
|
|
10
|
-
raw = fs.readFileSync(resolvedPath, "utf8");
|
|
11
|
-
}
|
|
12
|
-
catch (err) {
|
|
13
|
-
throw new Error(`Failed to read ${label} file at ${resolvedPath}: ${String(err)}`, {
|
|
14
|
-
cause: err,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
const secret = raw.trim();
|
|
18
|
-
if (!secret) {
|
|
19
|
-
throw new Error(`${label} file at ${resolvedPath} is empty.`);
|
|
20
|
-
}
|
|
21
|
-
return secret;
|
|
22
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export const ANTHROPIC_STORE = {
|
|
2
|
-
version: 1,
|
|
3
|
-
profiles: {
|
|
4
|
-
"anthropic:default": {
|
|
5
|
-
type: "api_key",
|
|
6
|
-
provider: "anthropic",
|
|
7
|
-
key: "sk-default",
|
|
8
|
-
},
|
|
9
|
-
"anthropic:work": {
|
|
10
|
-
type: "api_key",
|
|
11
|
-
provider: "anthropic",
|
|
12
|
-
key: "sk-work",
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
export const ANTHROPIC_CFG = {
|
|
17
|
-
auth: {
|
|
18
|
-
profiles: {
|
|
19
|
-
"anthropic:default": { provider: "anthropic", mode: "api_key" },
|
|
20
|
-
"anthropic:work": { provider: "anthropic", mode: "api_key" },
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|