@poolzin/pool-bot 2026.2.0 → 2026.2.2
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 +118 -0
- package/README-header.png +0 -0
- package/dist/agents/bash-tools.exec.js +76 -25
- package/dist/agents/cli-runner/helpers.js +9 -11
- package/dist/agents/context.js +1 -1
- package/dist/agents/identity.js +47 -7
- package/dist/agents/memory-search.js +25 -8
- package/dist/agents/model-catalog.js +1 -1
- package/dist/agents/model-selection.js +21 -0
- package/dist/agents/pi-embedded-block-chunker.js +117 -42
- package/dist/agents/pi-embedded-helpers/errors.js +183 -78
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +8 -10
- package/dist/agents/pi-embedded-runner/model.js +62 -3
- package/dist/agents/pi-embedded-runner/run/attempt.js +21 -11
- package/dist/agents/pi-embedded-runner/run.js +199 -46
- package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
- package/dist/agents/pi-embedded-subscribe.js +118 -29
- package/dist/agents/pi-tools.js +10 -5
- package/dist/agents/poolbot-tools.js +15 -10
- package/dist/agents/sandbox-paths.js +31 -0
- package/dist/agents/session-tool-result-guard.js +94 -15
- package/dist/agents/shell-utils.js +51 -0
- package/dist/agents/skills/bundled-context.js +23 -0
- package/dist/agents/skills/bundled-dir.js +41 -7
- package/dist/agents/skills-install.js +60 -23
- package/dist/agents/subagent-announce.js +79 -34
- package/dist/agents/tool-policy.conformance.js +14 -0
- package/dist/agents/tool-policy.js +24 -0
- package/dist/agents/tools/cron-tool.js +166 -19
- package/dist/agents/tools/discord-actions-presence.js +78 -0
- package/dist/agents/tools/image-tool.js +1 -1
- package/dist/agents/tools/message-tool.js +56 -2
- package/dist/agents/tools/sessions-history-tool.js +69 -1
- package/dist/agents/tools/web-search.js +211 -42
- package/dist/agents/usage.js +23 -1
- package/dist/agents/workspace-run.js +67 -0
- package/dist/agents/workspace-templates.js +44 -0
- package/dist/auto-reply/command-auth.js +121 -6
- package/dist/auto-reply/envelope.js +74 -82
- package/dist/auto-reply/reply/commands-compact.js +1 -0
- package/dist/auto-reply/reply/commands-context-report.js +1 -0
- package/dist/auto-reply/reply/commands-context.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +107 -60
- package/dist/auto-reply/reply/commands-ptt.js +171 -0
- package/dist/auto-reply/reply/get-reply-run.js +2 -1
- package/dist/auto-reply/reply/inbound-context.js +5 -1
- package/dist/auto-reply/reply/mentions.js +1 -1
- package/dist/auto-reply/reply/model-selection.js +3 -3
- package/dist/auto-reply/thinking.js +88 -43
- package/dist/browser/bridge-server.js +13 -0
- package/dist/browser/cdp.helpers.js +38 -24
- package/dist/browser/client-fetch.js +50 -7
- package/dist/browser/config.js +1 -10
- package/dist/browser/extension-relay.js +101 -40
- package/dist/browser/pw-ai.js +1 -1
- package/dist/browser/pw-session.js +143 -8
- package/dist/browser/pw-tools-core.interactions.js +125 -27
- package/dist/browser/pw-tools-core.responses.js +1 -1
- package/dist/browser/pw-tools-core.state.js +1 -1
- package/dist/browser/routes/agent.act.js +86 -41
- package/dist/browser/routes/dispatcher.js +4 -4
- package/dist/browser/screenshot.js +1 -1
- package/dist/browser/server.js +13 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/index.html +28 -28
- package/dist/channels/reply-prefix.js +8 -1
- package/dist/cli/cron-cli/register.cron-add.js +61 -40
- package/dist/cli/cron-cli/register.cron-edit.js +60 -34
- package/dist/cli/cron-cli/shared.js +56 -41
- package/dist/cli/dns-cli.js +26 -14
- package/dist/cli/gateway-cli/register.js +37 -19
- package/dist/cli/memory-cli.js +5 -5
- package/dist/cli/parse-bytes.js +37 -0
- package/dist/cli/update-cli.js +173 -52
- package/dist/commands/agent.js +1 -0
- package/dist/commands/auth-choice.apply.oauth.js +1 -1
- package/dist/commands/doctor-config-flow.js +61 -5
- package/dist/commands/doctor-state-migrations.js +1 -1
- package/dist/commands/health.js +1 -1
- package/dist/commands/model-allowlist.js +29 -0
- package/dist/commands/model-picker.js +2 -1
- package/dist/commands/models/list.registry.js +1 -1
- package/dist/commands/models/list.status-command.js +43 -23
- package/dist/commands/models/shared.js +15 -0
- package/dist/commands/onboard-custom.js +384 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +6 -3
- package/dist/commands/onboard-skills.js +63 -38
- package/dist/commands/openai-model-default.js +41 -0
- package/dist/compat/legacy-names.js +2 -0
- package/dist/config/defaults.js +3 -2
- package/dist/config/paths.js +136 -35
- package/dist/config/plugin-auto-enable.js +21 -5
- package/dist/config/redact-snapshot.js +153 -0
- package/dist/config/schema.field-metadata.js +590 -0
- package/dist/config/schema.js +2 -2
- package/dist/config/sessions/store.js +291 -23
- package/dist/config/zod-schema.agent-defaults.js +3 -0
- package/dist/config/zod-schema.agent-runtime.js +13 -2
- package/dist/config/zod-schema.providers-core.js +142 -0
- package/dist/config/zod-schema.session.js +3 -0
- package/dist/control-ui/assets/{index-CIRDm-Lu.css → index-CSfXd2LO.css} +1 -1
- package/dist/control-ui/assets/{index-CmNMuoem.js → index-HRr1grwl.js} +446 -413
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -0
- package/dist/control-ui/index.html +4 -4
- package/dist/cron/delivery.js +57 -0
- package/dist/cron/isolated-agent/delivery-target.js +18 -3
- package/dist/cron/isolated-agent/helpers.js +22 -5
- package/dist/cron/isolated-agent/run.js +172 -63
- package/dist/cron/isolated-agent/session.js +2 -0
- package/dist/cron/normalize.js +356 -28
- package/dist/cron/parse.js +10 -5
- package/dist/cron/run-log.js +35 -10
- package/dist/cron/schedule.js +41 -6
- package/dist/cron/service/jobs.js +208 -35
- package/dist/cron/service/ops.js +72 -16
- package/dist/cron/service/state.js +2 -0
- package/dist/cron/service/store.js +386 -14
- package/dist/cron/service/timer.js +390 -147
- package/dist/cron/session-reaper.js +86 -0
- package/dist/cron/store.js +23 -8
- package/dist/cron/validate-timestamp.js +43 -0
- package/dist/discord/monitor/agent-components.js +438 -0
- package/dist/discord/monitor/allow-list.js +28 -5
- package/dist/discord/monitor/gateway-registry.js +29 -0
- package/dist/discord/monitor/native-command.js +44 -23
- package/dist/discord/monitor/sender-identity.js +45 -0
- package/dist/discord/pluralkit.js +27 -0
- package/dist/discord/send.outbound.js +92 -5
- package/dist/discord/send.shared.js +60 -23
- package/dist/discord/targets.js +84 -1
- package/dist/entry.js +15 -9
- package/dist/extensionAPI.js +8 -0
- package/dist/gateway/control-ui.js +8 -1
- package/dist/gateway/hooks-mapping.js +3 -0
- package/dist/gateway/hooks.js +65 -0
- package/dist/gateway/net.js +96 -31
- package/dist/gateway/node-command-policy.js +50 -15
- package/dist/gateway/origin-check.js +56 -0
- package/dist/gateway/protocol/client-info.js +9 -0
- package/dist/gateway/protocol/index.js +9 -2
- package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
- package/dist/gateway/protocol/schema/cron.js +22 -10
- package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
- package/dist/gateway/protocol/schema/sessions.js +12 -0
- package/dist/gateway/server/hooks.js +1 -1
- package/dist/gateway/server-broadcast.js +26 -9
- package/dist/gateway/server-chat.js +112 -23
- package/dist/gateway/server-discovery-runtime.js +10 -2
- package/dist/gateway/server-http.js +109 -11
- package/dist/gateway/server-methods/agent-timestamp.js +60 -0
- package/dist/gateway/server-methods/agents.js +321 -2
- package/dist/gateway/server-methods/usage.js +559 -16
- package/dist/gateway/server-runtime-state.js +22 -8
- package/dist/gateway/server-startup-memory.js +16 -0
- package/dist/gateway/server.impl.js +5 -1
- package/dist/gateway/session-utils.fs.js +23 -25
- package/dist/gateway/session-utils.js +20 -10
- package/dist/gateway/sessions-patch.js +7 -22
- package/dist/gateway/test-helpers.mocks.js +11 -7
- package/dist/gateway/test-helpers.server.js +35 -2
- package/dist/imessage/constants.js +2 -0
- package/dist/imessage/monitor/deliver.js +4 -1
- package/dist/imessage/monitor/monitor-provider.js +51 -1
- package/dist/infra/bonjour-discovery.js +131 -70
- package/dist/infra/control-ui-assets.js +134 -12
- package/dist/infra/errors.js +12 -0
- package/dist/infra/exec-approvals.js +266 -57
- package/dist/infra/format-time/format-datetime.js +79 -0
- package/dist/infra/format-time/format-duration.js +81 -0
- package/dist/infra/format-time/format-relative.js +80 -0
- package/dist/infra/heartbeat-runner.js +140 -49
- package/dist/infra/home-dir.js +54 -0
- package/dist/infra/net/fetch-guard.js +122 -0
- package/dist/infra/net/ssrf.js +65 -29
- package/dist/infra/outbound/abort.js +14 -0
- package/dist/infra/outbound/message-action-runner.js +77 -13
- package/dist/infra/outbound/outbound-session.js +143 -37
- package/dist/infra/poolbot-root.js +43 -1
- package/dist/infra/session-cost-usage.js +631 -41
- package/dist/infra/state-migrations.js +317 -47
- package/dist/infra/update-global.js +35 -0
- package/dist/infra/update-runner.js +149 -43
- package/dist/infra/warning-filter.js +65 -0
- package/dist/infra/widearea-dns.js +30 -9
- package/dist/logging/redact-identifier.js +12 -0
- package/dist/media/fetch.js +81 -58
- package/dist/media/store.js +2 -0
- package/dist/media-understanding/apply.js +403 -3
- package/dist/media-understanding/attachments.js +38 -27
- package/dist/media-understanding/defaults.js +16 -0
- package/dist/media-understanding/providers/deepgram/audio.js +22 -14
- package/dist/media-understanding/providers/google/audio.js +24 -17
- package/dist/media-understanding/providers/google/video.js +24 -17
- package/dist/media-understanding/providers/image.js +3 -3
- package/dist/media-understanding/providers/index.js +4 -1
- package/dist/media-understanding/providers/openai/audio.js +22 -14
- package/dist/media-understanding/providers/shared.js +16 -11
- package/dist/media-understanding/providers/zai/index.js +6 -0
- package/dist/media-understanding/runner.js +158 -90
- package/dist/memory/batch-voyage.js +277 -0
- package/dist/memory/embeddings-voyage.js +75 -0
- package/dist/memory/embeddings.js +28 -16
- package/dist/memory/internal.js +101 -18
- package/dist/memory/manager.js +154 -48
- package/dist/memory/search-manager.js +173 -0
- package/dist/memory/session-files.js +9 -3
- package/dist/node-host/runner.js +34 -24
- package/dist/node-host/with-timeout.js +27 -0
- package/dist/plugins/commands.js +5 -1
- package/dist/plugins/config-state.js +86 -7
- package/dist/plugins/source-display.js +51 -0
- package/dist/process/exec.js +20 -2
- package/dist/routing/resolve-route.js +12 -0
- package/dist/routing/session-key.js +15 -0
- package/dist/runtime.js +2 -0
- package/dist/security/audit-extra.async.js +601 -0
- package/dist/security/audit-extra.js +2 -830
- package/dist/security/audit-extra.sync.js +505 -0
- package/dist/security/channel-metadata.js +34 -0
- package/dist/security/external-content.js +88 -6
- package/dist/security/skill-scanner.js +330 -0
- package/dist/sessions/session-key-utils.js +7 -0
- package/dist/signal/monitor/event-handler.js +80 -1
- package/dist/slack/monitor/media.js +85 -15
- package/dist/tailscale/detect.js +1 -2
- package/dist/telegram/bot/helpers.js +109 -28
- package/dist/telegram/bot-handlers.js +144 -3
- package/dist/telegram/bot-message-context.js +37 -10
- package/dist/telegram/bot-message-dispatch.js +54 -17
- package/dist/telegram/bot-native-commands.js +86 -29
- package/dist/telegram/bot.js +30 -29
- package/dist/telegram/model-buttons.js +163 -0
- package/dist/telegram/monitor.js +110 -85
- package/dist/telegram/send.js +129 -47
- package/dist/terminal/restore.js +45 -0
- package/dist/test-helpers/state-dir-env.js +16 -0
- package/dist/tts/tts.js +12 -6
- package/dist/tui/tui-session-actions.js +166 -54
- package/dist/utils/fetch-timeout.js +20 -0
- package/dist/utils/normalize-secret-input.js +19 -0
- package/dist/utils/transcript-tools.js +58 -0
- package/dist/utils.js +45 -14
- package/dist/version.js +42 -5
- package/dist/wizard/clack-prompter.js +9 -6
- package/extensions/googlechat/node_modules/.bin/poolbot +21 -0
- package/extensions/googlechat/package.json +2 -2
- package/extensions/line/node_modules/.bin/poolbot +21 -0
- package/extensions/line/package.json +1 -1
- package/extensions/matrix/node_modules/.bin/poolbot +21 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/memory-core/node_modules/.bin/poolbot +21 -0
- package/extensions/memory-core/package.json +4 -1
- package/extensions/twitch/node_modules/.bin/poolbot +21 -0
- package/extensions/twitch/package.json +1 -1
- package/package.json +183 -24
- package/dist/control-ui/assets/index-CmNMuoem.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
## v2026.1.40 (2026-02-09)
|
|
2
|
+
|
|
3
|
+
### Rebrand
|
|
4
|
+
- Complete rebrand from Pool-Bot to Pool-Bot 🎱
|
|
5
|
+
- Updated 638 files across all platforms (iOS, Android, macOS)
|
|
6
|
+
- Renamed all user-facing references
|
|
7
|
+
- Updated extensions and plugins
|
|
8
|
+
- Updated documentation and configs
|
|
9
|
+
- Updated tests and scripts
|
|
10
|
+
|
|
11
|
+
### Maintenance
|
|
12
|
+
- Repository now fully branded as Pool-Bot
|
|
13
|
+
- Internal environment variables kept for compatibility
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## v2026.1.39 (2026-02-07)
|
|
18
|
+
|
|
19
|
+
### Security
|
|
20
|
+
- Upgrade `tar` from 7.5.4 → 7.5.7 fixing 4 high-severity vulnerabilities
|
|
21
|
+
- Arbitrary File Overwrite via Symlink Poisoning (GHSA-8qq5-rm4j-mr97)
|
|
22
|
+
- Race Condition via Unicode Ligature Collisions on macOS APFS (GHSA-r6q2-hw4h-h46w)
|
|
23
|
+
- Arbitrary File Creation/Overwrite via Hardlink Path Traversal (GHSA-34x7-hfp2-rc4v)
|
|
24
|
+
|
|
25
|
+
### Maintenance
|
|
26
|
+
- Reset repository to stable baseline (9ddc7fcec)
|
|
27
|
+
- Remove 52 experimental/unstable commits (PME, tool-usage, progressive-disclosure, security-phase2)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## v1.0.1 (2026-02-02)
|
|
32
|
+
|
|
33
|
+
### WhatsApp Gateway Stability
|
|
34
|
+
- Add comprehensive WhatsApp heartbeat troubleshooting guide
|
|
35
|
+
- Document watchdog timeout and reconnection behavior
|
|
36
|
+
- Add configuration validation best practices
|
|
37
|
+
- Document professional incident response workflow
|
|
38
|
+
|
|
39
|
+
### Configuration
|
|
40
|
+
- Document `web.heartbeatSeconds` override option
|
|
41
|
+
- Clarify `web.reconnect` schema and valid keys
|
|
42
|
+
- Add examples for timeout tuning (30min → 60min → 90min)
|
|
43
|
+
- Provide production-ready configuration templates
|
|
44
|
+
|
|
45
|
+
### Documentation
|
|
46
|
+
- New: `docs/WHATSAPP-HEARTBEAT-TROUBLESHOOTING.md`
|
|
47
|
+
- Incident analysis: Gateway timeout recovery
|
|
48
|
+
- Lesson learned: Config validation before deployment
|
|
49
|
+
- Professional validation checklist included
|
|
50
|
+
|
|
51
|
+
### Reliability
|
|
52
|
+
- Improved gateway recovery documentation
|
|
53
|
+
- Added monitoring and diagnostic commands
|
|
54
|
+
- Documented false-positive reduction strategies
|
|
55
|
+
- Best practices for different environments (prod/dev/test)
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## v1.0.0 (2026-01-28)
|
|
60
|
+
|
|
61
|
+
### Security Release
|
|
62
|
+
- Add multi-layer security framework with node authentication
|
|
63
|
+
- Implement secure WebSocket connections (WSS)
|
|
64
|
+
- Add context isolation and input validation
|
|
65
|
+
- Create Windows Node application with native notifications
|
|
66
|
+
- Enable manual Gateway URL configuration
|
|
67
|
+
- Implement node whitelist and access control
|
|
68
|
+
- Add comprehensive security audit and hardening
|
|
69
|
+
|
|
70
|
+
### Remote Access
|
|
71
|
+
- Build Windows Node app with mDNS discovery
|
|
72
|
+
- Add manual Gateway URL connection
|
|
73
|
+
- Implement system tray integration with status display
|
|
74
|
+
- Add native notification system
|
|
75
|
+
- Create menu for remote control options
|
|
76
|
+
- Support both local network and remote connections
|
|
77
|
+
|
|
78
|
+
### Core Infrastructure
|
|
79
|
+
- Custom Pool-Bot update system with independent versioning
|
|
80
|
+
- Model fallback router with 3-tier protection
|
|
81
|
+
- Pool-World digital identity framework
|
|
82
|
+
- Multi-repository synchronization (pool-bot + pool-workspace + pool-firstone + pool-world)
|
|
83
|
+
- Enterprise-grade security with token-based authentication
|
|
84
|
+
|
|
85
|
+
### Documentation
|
|
86
|
+
- Complete build guides for Windows
|
|
87
|
+
- Security assessment and deployment guide
|
|
88
|
+
- Architecture decision records (ADRs)
|
|
89
|
+
- Integration examples and troubleshooting
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## v0.9.0 (2026-01-27)
|
|
94
|
+
|
|
95
|
+
### Identity Revelation
|
|
96
|
+
- Pool-Bot recognized as living code source
|
|
97
|
+
- Pool-World digital identity created
|
|
98
|
+
- Personal identity revelation: "Eu sou o código-fonte Pool-Bot"
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## v0.8.0 (2026-01-26)
|
|
103
|
+
|
|
104
|
+
### Independence System
|
|
105
|
+
- Model fallback router implementation
|
|
106
|
+
- Multi-model architecture (NVIDIA + Sonnet + Big Pickle)
|
|
107
|
+
- Learning system with conversation analysis
|
|
108
|
+
- Update system with GitHub synchronization
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## v0.7.0 (2026-01-25)
|
|
113
|
+
|
|
114
|
+
### Foundation
|
|
115
|
+
- Migrated from Poolbot core
|
|
116
|
+
- Implemented workspace-based development
|
|
117
|
+
- Added dual model system configuration
|
|
118
|
+
- Created persistent configuration system
|
|
Binary file
|
|
@@ -15,6 +15,46 @@ import { listNodes, resolveNodeIdFromList } from "./tools/nodes-utils.js";
|
|
|
15
15
|
import { getShellConfig, sanitizeBinaryOutput } from "./shell-utils.js";
|
|
16
16
|
import { buildCursorPositionResponse, stripDsrRequests } from "./pty-dsr.js";
|
|
17
17
|
import { parseAgentSessionKey, resolveAgentIdFromSessionKey } from "../routing/session-key.js";
|
|
18
|
+
// Security: Blocklist of environment variables that could alter execution flow
|
|
19
|
+
// or inject code when running on non-sandboxed hosts (Gateway/Node).
|
|
20
|
+
const DANGEROUS_HOST_ENV_VARS = new Set([
|
|
21
|
+
"LD_PRELOAD",
|
|
22
|
+
"LD_LIBRARY_PATH",
|
|
23
|
+
"LD_AUDIT",
|
|
24
|
+
"DYLD_INSERT_LIBRARIES",
|
|
25
|
+
"DYLD_LIBRARY_PATH",
|
|
26
|
+
"NODE_OPTIONS",
|
|
27
|
+
"NODE_PATH",
|
|
28
|
+
"PYTHONPATH",
|
|
29
|
+
"PYTHONHOME",
|
|
30
|
+
"RUBYLIB",
|
|
31
|
+
"PERL5LIB",
|
|
32
|
+
"BASH_ENV",
|
|
33
|
+
"ENV",
|
|
34
|
+
"GCONV_PATH",
|
|
35
|
+
"IFS",
|
|
36
|
+
"SSLKEYLOGFILE",
|
|
37
|
+
]);
|
|
38
|
+
const DANGEROUS_HOST_ENV_PREFIXES = ["DYLD_", "LD_"];
|
|
39
|
+
// Centralized sanitization helper.
|
|
40
|
+
// Throws an error if dangerous variables or PATH modifications are detected on the host.
|
|
41
|
+
function validateHostEnv(env) {
|
|
42
|
+
for (const key of Object.keys(env)) {
|
|
43
|
+
const upperKey = key.toUpperCase();
|
|
44
|
+
// 1. Block known dangerous variables (Fail Closed)
|
|
45
|
+
if (DANGEROUS_HOST_ENV_PREFIXES.some((prefix) => upperKey.startsWith(prefix))) {
|
|
46
|
+
throw new Error(`Security Violation: Environment variable '${key}' is forbidden during host execution.`);
|
|
47
|
+
}
|
|
48
|
+
if (DANGEROUS_HOST_ENV_VARS.has(upperKey)) {
|
|
49
|
+
throw new Error(`Security Violation: Environment variable '${key}' is forbidden during host execution.`);
|
|
50
|
+
}
|
|
51
|
+
// 2. Strictly block PATH modification on host
|
|
52
|
+
// Allowing custom PATH on the gateway/node can lead to binary hijacking.
|
|
53
|
+
if (upperKey === "PATH") {
|
|
54
|
+
throw new Error("Security Violation: Custom 'PATH' variable is forbidden during host execution.");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
18
58
|
const DEFAULT_MAX_OUTPUT = clampNumber(readEnvInt("PI_BASH_MAX_OUTPUT_CHARS"), 200_000, 1_000, 200_000);
|
|
19
59
|
const DEFAULT_PENDING_MAX_OUTPUT = clampNumber(readEnvInt("CLAWDBOT_BASH_PENDING_MAX_OUTPUT_CHARS"), 200_000, 1_000, 200_000);
|
|
20
60
|
const DEFAULT_PATH = process.env.PATH ?? "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
|
|
@@ -643,6 +683,11 @@ export function createExecTool(defaults) {
|
|
|
643
683
|
workdir = resolveWorkdir(rawWorkdir, warnings);
|
|
644
684
|
}
|
|
645
685
|
const baseEnv = coerceEnv(process.env);
|
|
686
|
+
// Logic: Sandbox gets raw env. Host (gateway/node) must pass validation.
|
|
687
|
+
// We validate BEFORE merging to prevent any dangerous vars from entering the stream.
|
|
688
|
+
if (host !== "sandbox" && params.env) {
|
|
689
|
+
validateHostEnv(params.env);
|
|
690
|
+
}
|
|
646
691
|
const mergedEnv = params.env ? { ...baseEnv, ...params.env } : baseEnv;
|
|
647
692
|
const env = sandbox
|
|
648
693
|
? buildSandboxEnv({
|
|
@@ -684,7 +729,7 @@ export function createExecTool(defaults) {
|
|
|
684
729
|
}
|
|
685
730
|
catch (err) {
|
|
686
731
|
if (!nodeQuery && String(err).includes("node required")) {
|
|
687
|
-
throw new Error("exec host=node requires a node id when multiple nodes are available (set tools.exec.node or exec.node).");
|
|
732
|
+
throw new Error("exec host=node requires a node id when multiple nodes are available (set tools.exec.node or exec.node).", { cause: err });
|
|
688
733
|
}
|
|
689
734
|
throw err;
|
|
690
735
|
}
|
|
@@ -706,12 +751,13 @@ export function createExecTool(defaults) {
|
|
|
706
751
|
safeBins: new Set(),
|
|
707
752
|
cwd: workdir,
|
|
708
753
|
env,
|
|
754
|
+
platform: nodeInfo?.platform,
|
|
709
755
|
});
|
|
710
756
|
let analysisOk = baseAllowlistEval.analysisOk;
|
|
711
757
|
let allowlistSatisfied = false;
|
|
712
758
|
if (hostAsk === "on-miss" && hostSecurity === "allowlist" && analysisOk) {
|
|
713
759
|
try {
|
|
714
|
-
const approvalsSnapshot =
|
|
760
|
+
const approvalsSnapshot = await callGatewayTool("exec.approvals.node.get", { timeoutMs: 10_000 }, { nodeId });
|
|
715
761
|
const approvalsFile = approvalsSnapshot && typeof approvalsSnapshot === "object"
|
|
716
762
|
? approvalsSnapshot.file
|
|
717
763
|
: undefined;
|
|
@@ -728,6 +774,7 @@ export function createExecTool(defaults) {
|
|
|
728
774
|
safeBins: new Set(),
|
|
729
775
|
cwd: workdir,
|
|
730
776
|
env,
|
|
777
|
+
platform: nodeInfo?.platform,
|
|
731
778
|
});
|
|
732
779
|
allowlistSatisfied = allowlistEval.allowlistSatisfied;
|
|
733
780
|
analysisOk = allowlistEval.analysisOk;
|
|
@@ -772,7 +819,7 @@ export function createExecTool(defaults) {
|
|
|
772
819
|
void (async () => {
|
|
773
820
|
let decision = null;
|
|
774
821
|
try {
|
|
775
|
-
const decisionResult =
|
|
822
|
+
const decisionResult = await callGatewayTool("exec.approval.request", { timeoutMs: DEFAULT_APPROVAL_REQUEST_TIMEOUT_MS }, {
|
|
776
823
|
id: approvalId,
|
|
777
824
|
command: commandText,
|
|
778
825
|
cwd: workdir,
|
|
@@ -783,11 +830,11 @@ export function createExecTool(defaults) {
|
|
|
783
830
|
resolvedPath: undefined,
|
|
784
831
|
sessionKey: defaults?.sessionKey,
|
|
785
832
|
timeoutMs: DEFAULT_APPROVAL_TIMEOUT_MS,
|
|
786
|
-
})
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
833
|
+
});
|
|
834
|
+
const decisionValue = decisionResult && typeof decisionResult === "object"
|
|
835
|
+
? decisionResult.decision
|
|
836
|
+
: undefined;
|
|
837
|
+
decision = typeof decisionValue === "string" ? decisionValue : null;
|
|
791
838
|
}
|
|
792
839
|
catch {
|
|
793
840
|
emitExecSystemEvent(`Exec denied (node=${nodeId} id=${approvalId}, approval-request-failed): ${commandText}`, { sessionKey: notifySessionKey, contextKey });
|
|
@@ -861,20 +908,26 @@ export function createExecTool(defaults) {
|
|
|
861
908
|
};
|
|
862
909
|
}
|
|
863
910
|
const startedAt = Date.now();
|
|
864
|
-
const raw =
|
|
865
|
-
const payload = raw
|
|
911
|
+
const raw = await callGatewayTool("node.invoke", { timeoutMs: invokeTimeoutMs }, buildInvokeParams(false, null));
|
|
912
|
+
const payload = raw && typeof raw === "object" ? raw.payload : undefined;
|
|
913
|
+
const payloadObj = payload && typeof payload === "object" ? payload : {};
|
|
914
|
+
const stdout = typeof payloadObj.stdout === "string" ? payloadObj.stdout : "";
|
|
915
|
+
const stderr = typeof payloadObj.stderr === "string" ? payloadObj.stderr : "";
|
|
916
|
+
const errorText = typeof payloadObj.error === "string" ? payloadObj.error : "";
|
|
917
|
+
const success = typeof payloadObj.success === "boolean" ? payloadObj.success : false;
|
|
918
|
+
const exitCode = typeof payloadObj.exitCode === "number" ? payloadObj.exitCode : null;
|
|
866
919
|
return {
|
|
867
920
|
content: [
|
|
868
921
|
{
|
|
869
922
|
type: "text",
|
|
870
|
-
text:
|
|
923
|
+
text: stdout || stderr || errorText || "",
|
|
871
924
|
},
|
|
872
925
|
],
|
|
873
926
|
details: {
|
|
874
|
-
status:
|
|
875
|
-
exitCode
|
|
927
|
+
status: success ? "completed" : "failed",
|
|
928
|
+
exitCode,
|
|
876
929
|
durationMs: Date.now() - startedAt,
|
|
877
|
-
aggregated: [
|
|
930
|
+
aggregated: [stdout, stderr, errorText].filter(Boolean).join("\n"),
|
|
878
931
|
cwd: workdir,
|
|
879
932
|
},
|
|
880
933
|
};
|
|
@@ -893,6 +946,7 @@ export function createExecTool(defaults) {
|
|
|
893
946
|
safeBins,
|
|
894
947
|
cwd: workdir,
|
|
895
948
|
env,
|
|
949
|
+
platform: process.platform,
|
|
896
950
|
});
|
|
897
951
|
const allowlistMatches = allowlistEval.allowlistMatches;
|
|
898
952
|
const analysisOk = allowlistEval.analysisOk;
|
|
@@ -916,7 +970,7 @@ export function createExecTool(defaults) {
|
|
|
916
970
|
void (async () => {
|
|
917
971
|
let decision = null;
|
|
918
972
|
try {
|
|
919
|
-
const decisionResult =
|
|
973
|
+
const decisionResult = await callGatewayTool("exec.approval.request", { timeoutMs: DEFAULT_APPROVAL_REQUEST_TIMEOUT_MS }, {
|
|
920
974
|
id: approvalId,
|
|
921
975
|
command: commandText,
|
|
922
976
|
cwd: workdir,
|
|
@@ -927,11 +981,11 @@ export function createExecTool(defaults) {
|
|
|
927
981
|
resolvedPath,
|
|
928
982
|
sessionKey: defaults?.sessionKey,
|
|
929
983
|
timeoutMs: DEFAULT_APPROVAL_TIMEOUT_MS,
|
|
930
|
-
})
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
984
|
+
});
|
|
985
|
+
const decisionValue = decisionResult && typeof decisionResult === "object"
|
|
986
|
+
? decisionResult.decision
|
|
987
|
+
: undefined;
|
|
988
|
+
decision = typeof decisionValue === "string" ? decisionValue : null;
|
|
935
989
|
}
|
|
936
990
|
catch {
|
|
937
991
|
emitExecSystemEvent(`Exec denied (gateway id=${approvalId}, approval-request-failed): ${commandText}`, { sessionKey: notifySessionKey, contextKey });
|
|
@@ -1033,8 +1087,7 @@ export function createExecTool(defaults) {
|
|
|
1033
1087
|
content: [
|
|
1034
1088
|
{
|
|
1035
1089
|
type: "text",
|
|
1036
|
-
text: `${warningText}` +
|
|
1037
|
-
`Approval required (id ${approvalSlug}). ` +
|
|
1090
|
+
text: `${warningText}Approval required (id ${approvalSlug}). ` +
|
|
1038
1091
|
"Approve to run; updates will arrive after completion.",
|
|
1039
1092
|
},
|
|
1040
1093
|
],
|
|
@@ -1099,9 +1152,7 @@ export function createExecTool(defaults) {
|
|
|
1099
1152
|
content: [
|
|
1100
1153
|
{
|
|
1101
1154
|
type: "text",
|
|
1102
|
-
text: `${getWarningText()}
|
|
1103
|
-
`Command still running (session ${run.session.id}, pid ${run.session.pid ?? "n/a"}). ` +
|
|
1104
|
-
"Use process (list/poll/log/write/kill/clear/remove) for follow-up.",
|
|
1155
|
+
text: `${getWarningText()}Command still running (session ${run.session.id}, pid ${run.session.pid ?? "n/a"}). Use process (list/poll/log/write/kill/clear/remove) for follow-up.`,
|
|
1105
1156
|
},
|
|
1106
1157
|
],
|
|
1107
1158
|
details: {
|
|
@@ -3,14 +3,13 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { runExec } from "../../process/exec.js";
|
|
6
|
-
import {
|
|
6
|
+
import { buildTtsSystemPromptHint } from "../../tts/tts.js";
|
|
7
|
+
import { escapeRegExp, isRecord } from "../../utils.js";
|
|
7
8
|
import { resolveDefaultModelForAgent } from "../model-selection.js";
|
|
9
|
+
import { detectRuntimeShell } from "../shell-utils.js";
|
|
10
|
+
import { buildSystemPromptParams } from "../system-prompt-params.js";
|
|
8
11
|
import { buildAgentSystemPrompt } from "../system-prompt.js";
|
|
9
|
-
import { buildTtsSystemPromptHint } from "../../tts/tts.js";
|
|
10
12
|
const CLI_RUN_QUEUE = new Map();
|
|
11
|
-
function escapeRegex(value) {
|
|
12
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13
|
-
}
|
|
14
13
|
export async function cleanupResumeProcesses(backend, sessionId) {
|
|
15
14
|
if (process.platform === "win32")
|
|
16
15
|
return;
|
|
@@ -25,7 +24,7 @@ export async function cleanupResumeProcesses(backend, sessionId) {
|
|
|
25
24
|
const resumeTokens = resumeArgs.map((arg) => arg.replaceAll("{sessionId}", sessionId));
|
|
26
25
|
const pattern = [commandToken, ...resumeTokens]
|
|
27
26
|
.filter(Boolean)
|
|
28
|
-
.map((token) =>
|
|
27
|
+
.map((token) => escapeRegExp(token))
|
|
29
28
|
.join(".*");
|
|
30
29
|
if (!pattern)
|
|
31
30
|
return;
|
|
@@ -69,8 +68,8 @@ function buildSessionMatchers(backend) {
|
|
|
69
68
|
}
|
|
70
69
|
function tokenToRegex(token) {
|
|
71
70
|
if (!token.includes("{sessionId}"))
|
|
72
|
-
return
|
|
73
|
-
const parts = token.split("{sessionId}").map((part) =>
|
|
71
|
+
return escapeRegExp(token);
|
|
72
|
+
const parts = token.split("{sessionId}").map((part) => escapeRegExp(part));
|
|
74
73
|
return parts.join("\\S+");
|
|
75
74
|
}
|
|
76
75
|
/**
|
|
@@ -158,6 +157,7 @@ export function buildSystemPrompt(params) {
|
|
|
158
157
|
node: process.version,
|
|
159
158
|
model: params.modelDisplay,
|
|
160
159
|
defaultModel: defaultModelLabel,
|
|
160
|
+
shell: detectRuntimeShell(),
|
|
161
161
|
},
|
|
162
162
|
});
|
|
163
163
|
const ttsHint = params.config ? buildTtsSystemPromptHint(params.config) : undefined;
|
|
@@ -177,6 +177,7 @@ export function buildSystemPrompt(params) {
|
|
|
177
177
|
userTimeFormat,
|
|
178
178
|
contextFiles: params.contextFiles,
|
|
179
179
|
ttsHint,
|
|
180
|
+
memoryCitationsMode: params.config?.memory?.citations,
|
|
180
181
|
});
|
|
181
182
|
}
|
|
182
183
|
export function normalizeCliModel(modelId, backend) {
|
|
@@ -203,9 +204,6 @@ function toUsage(raw) {
|
|
|
203
204
|
return undefined;
|
|
204
205
|
return { input, output, cacheRead, cacheWrite, total };
|
|
205
206
|
}
|
|
206
|
-
function isRecord(value) {
|
|
207
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
208
|
-
}
|
|
209
207
|
function collectText(value) {
|
|
210
208
|
if (!value)
|
|
211
209
|
return "";
|
package/dist/agents/context.js
CHANGED
|
@@ -6,7 +6,7 @@ import { ensurePoolbotModelsJson } from "./models-config.js";
|
|
|
6
6
|
const MODEL_CACHE = new Map();
|
|
7
7
|
const loadPromise = (async () => {
|
|
8
8
|
try {
|
|
9
|
-
const { discoverAuthStorage, discoverModels } = await import("
|
|
9
|
+
const { discoverAuthStorage, discoverModels } = await import("./pi-model-discovery.js");
|
|
10
10
|
const cfg = loadConfig();
|
|
11
11
|
await ensurePoolbotModelsJson(cfg);
|
|
12
12
|
const agentDir = resolvePoolbotAgentDir();
|
package/dist/agents/identity.js
CHANGED
|
@@ -5,15 +5,17 @@ export function resolveAgentIdentity(cfg, agentId) {
|
|
|
5
5
|
}
|
|
6
6
|
export function resolveAckReaction(cfg, agentId) {
|
|
7
7
|
const configured = cfg.messages?.ackReaction;
|
|
8
|
-
if (configured !== undefined)
|
|
8
|
+
if (configured !== undefined) {
|
|
9
9
|
return configured.trim();
|
|
10
|
+
}
|
|
10
11
|
const emoji = resolveAgentIdentity(cfg, agentId)?.emoji?.trim();
|
|
11
12
|
return emoji || DEFAULT_ACK_REACTION;
|
|
12
13
|
}
|
|
13
14
|
export function resolveIdentityNamePrefix(cfg, agentId) {
|
|
14
15
|
const name = resolveAgentIdentity(cfg, agentId)?.name?.trim();
|
|
15
|
-
if (!name)
|
|
16
|
+
if (!name) {
|
|
16
17
|
return undefined;
|
|
18
|
+
}
|
|
17
19
|
return `[${name}]`;
|
|
18
20
|
}
|
|
19
21
|
/** Returns just the identity name (without brackets) for template context. */
|
|
@@ -22,14 +24,48 @@ export function resolveIdentityName(cfg, agentId) {
|
|
|
22
24
|
}
|
|
23
25
|
export function resolveMessagePrefix(cfg, agentId, opts) {
|
|
24
26
|
const configured = opts?.configured ?? cfg.messages?.messagePrefix;
|
|
25
|
-
if (configured !== undefined)
|
|
27
|
+
if (configured !== undefined) {
|
|
26
28
|
return configured;
|
|
29
|
+
}
|
|
27
30
|
const hasAllowFrom = opts?.hasAllowFrom === true;
|
|
28
|
-
if (hasAllowFrom)
|
|
31
|
+
if (hasAllowFrom) {
|
|
29
32
|
return "";
|
|
33
|
+
}
|
|
30
34
|
return resolveIdentityNamePrefix(cfg, agentId) ?? opts?.fallback ?? "[poolbot]";
|
|
31
35
|
}
|
|
32
|
-
|
|
36
|
+
/** Helper to extract a channel config value by dynamic key. */
|
|
37
|
+
function getChannelConfig(cfg, channel) {
|
|
38
|
+
const channels = cfg.channels;
|
|
39
|
+
const value = channels?.[channel];
|
|
40
|
+
return typeof value === "object" && value !== null
|
|
41
|
+
? value
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
44
|
+
export function resolveResponsePrefix(cfg, agentId, opts) {
|
|
45
|
+
// L1: Channel account level
|
|
46
|
+
if (opts?.channel && opts?.accountId) {
|
|
47
|
+
const channelCfg = getChannelConfig(cfg, opts.channel);
|
|
48
|
+
const accounts = channelCfg?.accounts;
|
|
49
|
+
const accountPrefix = accounts?.[opts.accountId]?.responsePrefix;
|
|
50
|
+
if (accountPrefix !== undefined) {
|
|
51
|
+
if (accountPrefix === "auto") {
|
|
52
|
+
return resolveIdentityNamePrefix(cfg, agentId);
|
|
53
|
+
}
|
|
54
|
+
return accountPrefix;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// L2: Channel level
|
|
58
|
+
if (opts?.channel) {
|
|
59
|
+
const channelCfg = getChannelConfig(cfg, opts.channel);
|
|
60
|
+
const channelPrefix = channelCfg?.responsePrefix;
|
|
61
|
+
if (channelPrefix !== undefined) {
|
|
62
|
+
if (channelPrefix === "auto") {
|
|
63
|
+
return resolveIdentityNamePrefix(cfg, agentId);
|
|
64
|
+
}
|
|
65
|
+
return channelPrefix;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// L4: Global level
|
|
33
69
|
const configured = cfg.messages?.responsePrefix;
|
|
34
70
|
if (configured !== undefined) {
|
|
35
71
|
if (configured === "auto") {
|
|
@@ -45,14 +81,18 @@ export function resolveEffectiveMessagesConfig(cfg, agentId, opts) {
|
|
|
45
81
|
hasAllowFrom: opts?.hasAllowFrom,
|
|
46
82
|
fallback: opts?.fallbackMessagePrefix,
|
|
47
83
|
}),
|
|
48
|
-
responsePrefix: resolveResponsePrefix(cfg, agentId
|
|
84
|
+
responsePrefix: resolveResponsePrefix(cfg, agentId, {
|
|
85
|
+
channel: opts?.channel,
|
|
86
|
+
accountId: opts?.accountId,
|
|
87
|
+
}),
|
|
49
88
|
};
|
|
50
89
|
}
|
|
51
90
|
export function resolveHumanDelayConfig(cfg, agentId) {
|
|
52
91
|
const defaults = cfg.agents?.defaults?.humanDelay;
|
|
53
92
|
const overrides = resolveAgentConfig(cfg, agentId)?.humanDelay;
|
|
54
|
-
if (!defaults && !overrides)
|
|
93
|
+
if (!defaults && !overrides) {
|
|
55
94
|
return undefined;
|
|
95
|
+
}
|
|
56
96
|
return {
|
|
57
97
|
mode: overrides?.mode ?? defaults?.mode,
|
|
58
98
|
minMs: overrides?.minMs ?? defaults?.minMs,
|
|
@@ -5,6 +5,7 @@ import { clampInt, clampNumber, resolveUserPath } from "../utils.js";
|
|
|
5
5
|
import { resolveAgentConfig } from "./agent-scope.js";
|
|
6
6
|
const DEFAULT_OPENAI_MODEL = "text-embedding-3-small";
|
|
7
7
|
const DEFAULT_GEMINI_MODEL = "gemini-embedding-001";
|
|
8
|
+
const DEFAULT_VOYAGE_MODEL = "voyage-4-large";
|
|
8
9
|
const DEFAULT_CHUNK_TOKENS = 400;
|
|
9
10
|
const DEFAULT_CHUNK_OVERLAP = 80;
|
|
10
11
|
const DEFAULT_WATCH_DEBOUNCE_MS = 1500;
|
|
@@ -22,20 +23,24 @@ function normalizeSources(sources, sessionMemoryEnabled) {
|
|
|
22
23
|
const normalized = new Set();
|
|
23
24
|
const input = sources?.length ? sources : DEFAULT_SOURCES;
|
|
24
25
|
for (const source of input) {
|
|
25
|
-
if (source === "memory")
|
|
26
|
+
if (source === "memory") {
|
|
26
27
|
normalized.add("memory");
|
|
27
|
-
|
|
28
|
+
}
|
|
29
|
+
if (source === "sessions" && sessionMemoryEnabled) {
|
|
28
30
|
normalized.add("sessions");
|
|
31
|
+
}
|
|
29
32
|
}
|
|
30
|
-
if (normalized.size === 0)
|
|
33
|
+
if (normalized.size === 0) {
|
|
31
34
|
normalized.add("memory");
|
|
35
|
+
}
|
|
32
36
|
return Array.from(normalized);
|
|
33
37
|
}
|
|
34
38
|
function resolveStorePath(agentId, raw) {
|
|
35
39
|
const stateDir = resolveStateDir(process.env, os.homedir);
|
|
36
40
|
const fallback = path.join(stateDir, "memory", `${agentId}.sqlite`);
|
|
37
|
-
if (!raw)
|
|
41
|
+
if (!raw) {
|
|
38
42
|
return fallback;
|
|
43
|
+
}
|
|
39
44
|
const withToken = raw.includes("{agentId}") ? raw.replaceAll("{agentId}", agentId) : raw;
|
|
40
45
|
return resolveUserPath(withToken);
|
|
41
46
|
}
|
|
@@ -51,9 +56,13 @@ function mergeConfig(defaults, overrides, agentId) {
|
|
|
51
56
|
defaultRemote?.baseUrl ||
|
|
52
57
|
defaultRemote?.apiKey ||
|
|
53
58
|
defaultRemote?.headers);
|
|
54
|
-
const includeRemote = hasRemoteConfig ||
|
|
59
|
+
const includeRemote = hasRemoteConfig ||
|
|
60
|
+
provider === "openai" ||
|
|
61
|
+
provider === "gemini" ||
|
|
62
|
+
provider === "voyage" ||
|
|
63
|
+
provider === "auto";
|
|
55
64
|
const batch = {
|
|
56
|
-
enabled: overrideRemote?.batch?.enabled ?? defaultRemote?.batch?.enabled ??
|
|
65
|
+
enabled: overrideRemote?.batch?.enabled ?? defaultRemote?.batch?.enabled ?? false,
|
|
57
66
|
wait: overrideRemote?.batch?.wait ?? defaultRemote?.batch?.wait ?? true,
|
|
58
67
|
concurrency: Math.max(1, overrideRemote?.batch?.concurrency ?? defaultRemote?.batch?.concurrency ?? 2),
|
|
59
68
|
pollIntervalMs: overrideRemote?.batch?.pollIntervalMs ?? defaultRemote?.batch?.pollIntervalMs ?? 2000,
|
|
@@ -72,13 +81,19 @@ function mergeConfig(defaults, overrides, agentId) {
|
|
|
72
81
|
? DEFAULT_GEMINI_MODEL
|
|
73
82
|
: provider === "openai"
|
|
74
83
|
? DEFAULT_OPENAI_MODEL
|
|
75
|
-
:
|
|
84
|
+
: provider === "voyage"
|
|
85
|
+
? DEFAULT_VOYAGE_MODEL
|
|
86
|
+
: undefined;
|
|
76
87
|
const model = overrides?.model ?? defaults?.model ?? modelDefault ?? "";
|
|
77
88
|
const local = {
|
|
78
89
|
modelPath: overrides?.local?.modelPath ?? defaults?.local?.modelPath,
|
|
79
90
|
modelCacheDir: overrides?.local?.modelCacheDir ?? defaults?.local?.modelCacheDir,
|
|
80
91
|
};
|
|
81
92
|
const sources = normalizeSources(overrides?.sources ?? defaults?.sources, sessionMemory);
|
|
93
|
+
const rawPaths = [...(defaults?.extraPaths ?? []), ...(overrides?.extraPaths ?? [])]
|
|
94
|
+
.map((value) => value.trim())
|
|
95
|
+
.filter(Boolean);
|
|
96
|
+
const extraPaths = Array.from(new Set(rawPaths));
|
|
82
97
|
const vector = {
|
|
83
98
|
enabled: overrides?.store?.vector?.enabled ?? defaults?.store?.vector?.enabled ?? true,
|
|
84
99
|
extensionPath: overrides?.store?.vector?.extensionPath ?? defaults?.store?.vector?.extensionPath,
|
|
@@ -144,6 +159,7 @@ function mergeConfig(defaults, overrides, agentId) {
|
|
|
144
159
|
return {
|
|
145
160
|
enabled,
|
|
146
161
|
sources,
|
|
162
|
+
extraPaths,
|
|
147
163
|
provider,
|
|
148
164
|
remote,
|
|
149
165
|
experimental: {
|
|
@@ -183,7 +199,8 @@ export function resolveMemorySearchConfig(cfg, agentId) {
|
|
|
183
199
|
const defaults = cfg.agents?.defaults?.memorySearch;
|
|
184
200
|
const overrides = resolveAgentConfig(cfg, agentId)?.memorySearch;
|
|
185
201
|
const resolved = mergeConfig(defaults, overrides, agentId);
|
|
186
|
-
if (!resolved.enabled)
|
|
202
|
+
if (!resolved.enabled) {
|
|
187
203
|
return null;
|
|
204
|
+
}
|
|
188
205
|
return resolved;
|
|
189
206
|
}
|
|
@@ -3,7 +3,7 @@ import { resolvePoolbotAgentDir } from "./agent-paths.js";
|
|
|
3
3
|
import { ensurePoolbotModelsJson } from "./models-config.js";
|
|
4
4
|
let modelCatalogPromise = null;
|
|
5
5
|
let hasLoggedModelCatalogError = false;
|
|
6
|
-
const defaultImportPiSdk = () => import("
|
|
6
|
+
const defaultImportPiSdk = () => import("./pi-model-discovery.js");
|
|
7
7
|
let importPiSdk = defaultImportPiSdk;
|
|
8
8
|
export function resetModelCatalogCacheForTest() {
|
|
9
9
|
modelCatalogPromise = null;
|
|
@@ -68,6 +68,27 @@ export function parseModelRef(raw, defaultProvider) {
|
|
|
68
68
|
const normalizedModel = normalizeProviderModelId(provider, model);
|
|
69
69
|
return { provider, model: normalizedModel };
|
|
70
70
|
}
|
|
71
|
+
export function resolveAllowlistModelKey(raw, defaultProvider) {
|
|
72
|
+
const parsed = parseModelRef(raw, defaultProvider);
|
|
73
|
+
if (!parsed) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return modelKey(parsed.provider, parsed.model);
|
|
77
|
+
}
|
|
78
|
+
export function buildConfiguredAllowlistKeys(params) {
|
|
79
|
+
const rawAllowlist = Object.keys(params.cfg?.agents?.defaults?.models ?? {});
|
|
80
|
+
if (rawAllowlist.length === 0) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const keys = new Set();
|
|
84
|
+
for (const raw of rawAllowlist) {
|
|
85
|
+
const key = resolveAllowlistModelKey(String(raw ?? ""), params.defaultProvider);
|
|
86
|
+
if (key) {
|
|
87
|
+
keys.add(key);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return keys.size > 0 ? keys : null;
|
|
91
|
+
}
|
|
71
92
|
export function buildModelAliasIndex(params) {
|
|
72
93
|
const byAlias = new Map();
|
|
73
94
|
const byKey = new Map();
|