@poolzin/pool-bot 2026.3.9 → 2026.3.10
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 +24 -0
- package/README.md +147 -69
- package/dist/.buildstamp +1 -1
- package/dist/agents/error-classifier.js +26 -77
- package/dist/agents/skills/security.js +1 -7
- package/dist/build-info.json +3 -3
- package/dist/cli/cron-cli/register.cron-dashboard.js +339 -0
- package/dist/cli/cron-cli/register.js +2 -0
- package/dist/cli/errors.js +187 -0
- package/dist/cli/program/command-registry.js +13 -0
- package/dist/cli/program/register.maintenance.js +21 -0
- package/dist/cli/program/register.subclis.js +9 -0
- package/dist/cli/swarm-cli/register.js +8 -0
- package/dist/cli/swarm-cli/register.swarm-status.js +488 -0
- package/dist/cli/telemetry-cli/register.js +10 -0
- package/dist/cli/telemetry-cli/register.telemetry-alerts.js +176 -0
- package/dist/cli/telemetry-cli/register.telemetry-metrics.js +323 -0
- package/dist/cli/telemetry-cli/register.telemetry-status.js +179 -0
- package/dist/commands/doctor-checks.js +498 -0
- package/dist/context-engine/index.js +1 -1
- package/dist/context-engine/legacy.js +1 -3
- package/dist/context-engine/summarizing.js +5 -8
- package/dist/cron/service/timer.js +18 -0
- package/dist/gateway/protocol/index.js +5 -2
- package/dist/gateway/protocol/schema/error-codes.js +1 -0
- package/dist/gateway/protocol/schema/swarm.js +80 -0
- package/dist/gateway/protocol/schema.js +1 -0
- package/dist/gateway/server-close.js +4 -0
- package/dist/gateway/server-constants.js +1 -0
- package/dist/gateway/server-cron.js +29 -0
- package/dist/gateway/server-maintenance.js +35 -2
- package/dist/gateway/server-methods/swarm.js +58 -0
- package/dist/gateway/server-methods/telemetry.js +71 -0
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +9 -2
- package/dist/gateway/server.impl.js +33 -16
- package/dist/infra/abort-pattern.js +4 -4
- package/dist/infra/retry.js +3 -1
- package/dist/skills/commands.js +7 -25
- package/dist/skills/index.js +14 -17
- package/dist/skills/parser.js +12 -27
- package/dist/skills/registry.js +3 -6
- package/dist/skills/security.js +2 -8
- package/dist/swarm/service.js +247 -0
- package/dist/telemetry/alert-engine.js +258 -0
- package/dist/telemetry/cron-instrumentation.js +49 -0
- package/dist/telemetry/gateway-instrumentation.js +80 -0
- package/dist/telemetry/instrumentation.js +66 -0
- package/dist/telemetry/service.js +345 -0
- package/dist/tui/components/assistant-message.js +6 -2
- package/dist/tui/components/hyperlink-markdown.js +32 -0
- package/dist/tui/components/searchable-select-list.js +12 -1
- package/dist/tui/components/user-message.js +6 -2
- package/dist/tui/index.js +22 -6
- package/dist/tui/theme/theme-detection.js +226 -0
- package/dist/tui/tui-command-handlers.js +20 -0
- package/dist/tui/tui-formatters.js +4 -3
- package/dist/tui/utils/ctrl-c-handler.js +67 -0
- package/dist/tui/utils/osc8-hyperlinks.js +208 -0
- package/dist/tui/utils/safe-stop.js +180 -0
- package/dist/tui/utils/session-key-utils.js +81 -0
- package/dist/tui/utils/text-sanitization.js +284 -0
- package/dist/utils/lru-cache.js +116 -0
- package/dist/utils/performance.js +199 -0
- package/dist/utils/retry.js +240 -0
- package/docs/MELHORIAS_IMPLEMENTADAS.md +228 -0
- package/docs/MELHORIAS_PROFISSIONAIS.md +282 -0
- package/docs/PLANO_ACAO_TUI.md +357 -0
- package/docs/PROGRESSO_TUI.md +66 -0
- package/docs/RELATORIO_FINAL.md +217 -0
- package/docs/diagnostico-shell-completion.md +265 -0
- package/docs/features/advanced-memory.md +585 -0
- package/docs/features/discord-components-v2.md +277 -0
- package/docs/features/swarm.md +100 -0
- package/docs/features/telemetry.md +284 -0
- package/docs/integrations/INTEGRATION_PLAN.md +665 -345
- package/docs/models/provider-infrastructure.md +400 -0
- package/docs/security/exec-approvals.md +294 -0
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/hexstrike-bridge/README.md +119 -0
- package/extensions/hexstrike-bridge/index.test.ts +247 -0
- package/extensions/hexstrike-bridge/index.ts +487 -0
- package/extensions/hexstrike-bridge/package.json +17 -0
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mcp-server/index.ts +14 -0
- package/extensions/mcp-server/package.json +11 -0
- package/extensions/mcp-server/src/service.ts +540 -0
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +8 -1
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Provider Infrastructure
|
|
2
|
+
|
|
3
|
+
PoolBot includes resilient provider infrastructure for LLM integrations, featuring token pools for multi-key setups and automatic failover between providers.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The provider infrastructure provides:
|
|
8
|
+
|
|
9
|
+
- **Token Pools** - Distribute load across multiple API keys
|
|
10
|
+
- **Rate Limit Handling** - Automatic retry and fallback on rate limits
|
|
11
|
+
- **Automatic Failover** - Seamless switching between providers
|
|
12
|
+
- **Request Monitoring** - Tracking for debugging and optimization
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
User Request
|
|
18
|
+
│
|
|
19
|
+
▼
|
|
20
|
+
┌─────────────────────────────────────┐
|
|
21
|
+
│ Provider Resolution │
|
|
22
|
+
│ ┌──────────┬──────────┬─────────┐ │
|
|
23
|
+
│ │ Provider │ Provider │Provider │ │
|
|
24
|
+
│ │ A │ B │ C │ │
|
|
25
|
+
│ │ [Key 1] │ [Key 1] │ [Key 1] │ │
|
|
26
|
+
│ │ [Key 2] │ │ │ │
|
|
27
|
+
│ └────┬─────┴────┬─────┴────┬────┘ │
|
|
28
|
+
│ │ │ │ │
|
|
29
|
+
│ └──────────┼──────────┘ │
|
|
30
|
+
│ ▼ │
|
|
31
|
+
│ ┌─────────────┐ │
|
|
32
|
+
│ │Rate Limit / │ │
|
|
33
|
+
│ │ Failover │ │
|
|
34
|
+
│ │ Handling │ │
|
|
35
|
+
│ └──────┬──────┘ │
|
|
36
|
+
└────────────────┼─────────────────────┘
|
|
37
|
+
▼
|
|
38
|
+
Provider
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Token Pools
|
|
42
|
+
|
|
43
|
+
For high-volume deployments, configure multiple API keys:
|
|
44
|
+
|
|
45
|
+
### Basic Token Pool
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"models": {
|
|
50
|
+
"providers": {
|
|
51
|
+
"openai": {
|
|
52
|
+
"baseUrl": "https://api.openai.com/v1",
|
|
53
|
+
"tokens": [
|
|
54
|
+
{ "key": "${OPENAI_API_KEY_1}" },
|
|
55
|
+
{ "key": "${OPENAI_API_KEY_2}" }
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Weighted Distribution
|
|
64
|
+
|
|
65
|
+
Control traffic distribution across keys:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"models": {
|
|
70
|
+
"providers": {
|
|
71
|
+
"openai": {
|
|
72
|
+
"tokens": [
|
|
73
|
+
{ "key": "${OPENAI_KEY_1}", "weight": 60 },
|
|
74
|
+
{ "key": "${OPENAI_KEY_2}", "weight": 40 }
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Priority Tiers
|
|
83
|
+
|
|
84
|
+
Use priority for primary/backup key organization:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"models": {
|
|
89
|
+
"providers": {
|
|
90
|
+
"openai": {
|
|
91
|
+
"tokens": [
|
|
92
|
+
{ "key": "${OPENAI_KEY_1}", "priority": 1, "weight": 50 },
|
|
93
|
+
{ "key": "${OPENAI_KEY_2}", "priority": 1, "weight": 50 },
|
|
94
|
+
{ "key": "${OPENAI_KEY_3}", "priority": 2, "weight": 100 }
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Keys with lower priority numbers are tried first.
|
|
103
|
+
|
|
104
|
+
## Rate Limit Handling
|
|
105
|
+
|
|
106
|
+
PoolBot automatically handles rate limits:
|
|
107
|
+
|
|
108
|
+
### Automatic Retry
|
|
109
|
+
|
|
110
|
+
When a rate limit (429) is encountered:
|
|
111
|
+
1. Mark the key as rate-limited with cooldown
|
|
112
|
+
2. Try the next available key in the pool
|
|
113
|
+
3. Apply exponential backoff for retries
|
|
114
|
+
|
|
115
|
+
### Error Classification
|
|
116
|
+
|
|
117
|
+
PoolBot classifies provider errors:
|
|
118
|
+
|
|
119
|
+
| Error Type | Handling |
|
|
120
|
+
|------------|----------|
|
|
121
|
+
| `rate_limit` | Retry with next key, exponential backoff |
|
|
122
|
+
| `context_overflow` | Fail fast, suggest smaller context |
|
|
123
|
+
| `auth_error` | Mark key as invalid, try next |
|
|
124
|
+
| `server_error` | Retry with backoff |
|
|
125
|
+
| `timeout` | Retry with next key |
|
|
126
|
+
|
|
127
|
+
### Cooldown Management
|
|
128
|
+
|
|
129
|
+
Failed keys enter cooldown with exponential backoff:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Attempt 1: 1 second cooldown
|
|
133
|
+
Attempt 2: 2 seconds
|
|
134
|
+
Attempt 3: 4 seconds
|
|
135
|
+
Attempt 4: 8 seconds
|
|
136
|
+
...
|
|
137
|
+
Maximum: 5 minutes
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Failover
|
|
141
|
+
|
|
142
|
+
### Provider-Level Failover
|
|
143
|
+
|
|
144
|
+
Configure fallback providers at the agent level:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"agents": {
|
|
149
|
+
"defaults": {
|
|
150
|
+
"model": {
|
|
151
|
+
"provider": "openai/gpt-4o",
|
|
152
|
+
"fallback": [
|
|
153
|
+
"anthropic/claude-sonnet-4",
|
|
154
|
+
"google/gemini-1.5-pro"
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Failover Triggers
|
|
163
|
+
|
|
164
|
+
Failover occurs on:
|
|
165
|
+
- Rate limit (429)
|
|
166
|
+
- Server error (5xx)
|
|
167
|
+
- Timeout
|
|
168
|
+
- Authentication error (401/403)
|
|
169
|
+
- Context overflow (when primary can't handle the request)
|
|
170
|
+
|
|
171
|
+
### Failover Behavior
|
|
172
|
+
|
|
173
|
+
1. Try primary provider with all available keys
|
|
174
|
+
2. If all keys exhausted, try fallback providers in order
|
|
175
|
+
3. Return best available response or aggregate error
|
|
176
|
+
|
|
177
|
+
## Request Monitoring
|
|
178
|
+
|
|
179
|
+
### Profile Tracking
|
|
180
|
+
|
|
181
|
+
PoolBot tracks usage per auth profile:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
{
|
|
185
|
+
profileId: "openai-key-1",
|
|
186
|
+
requestsCount: 15432,
|
|
187
|
+
lastUsedAt: 1709823456789,
|
|
188
|
+
cooldownUntil: 0,
|
|
189
|
+
failureCount: 2
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Ring Buffer
|
|
194
|
+
|
|
195
|
+
Recent requests are tracked for debugging:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"models": {
|
|
200
|
+
"monitoring": {
|
|
201
|
+
"ringBufferSize": 1000
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Configuration Reference
|
|
208
|
+
|
|
209
|
+
### Provider Configuration
|
|
210
|
+
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"models": {
|
|
214
|
+
"providers": {
|
|
215
|
+
"openai": {
|
|
216
|
+
"baseUrl": "https://api.openai.com/v1",
|
|
217
|
+
"apiKey": "${OPENAI_API_KEY}",
|
|
218
|
+
"tokens": [
|
|
219
|
+
{
|
|
220
|
+
"key": "sk-...",
|
|
221
|
+
"weight": 50,
|
|
222
|
+
"priority": 1
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
"anthropic": {
|
|
227
|
+
"baseUrl": "https://api.anthropic.com",
|
|
228
|
+
"apiKey": "${ANTHROPIC_API_KEY}"
|
|
229
|
+
},
|
|
230
|
+
"google": {
|
|
231
|
+
"baseUrl": "https://generativelanguage.googleapis.com",
|
|
232
|
+
"apiKey": "${GEMINI_API_KEY}"
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Agent Model Configuration
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"agents": {
|
|
244
|
+
"defaults": {
|
|
245
|
+
"model": {
|
|
246
|
+
"provider": "openai/gpt-4o",
|
|
247
|
+
"fallback": [
|
|
248
|
+
"anthropic/claude-sonnet-4",
|
|
249
|
+
"google/gemini-1.5-pro"
|
|
250
|
+
],
|
|
251
|
+
"temperature": 0.7,
|
|
252
|
+
"maxTokens": 4096
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Best Practices
|
|
260
|
+
|
|
261
|
+
### Production Setup
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"models": {
|
|
266
|
+
"providers": {
|
|
267
|
+
"openai": {
|
|
268
|
+
"tokens": [
|
|
269
|
+
{ "key": "${OPENAI_KEY_1}", "weight": 50 },
|
|
270
|
+
{ "key": "${OPENAI_KEY_2}", "weight": 50 }
|
|
271
|
+
]
|
|
272
|
+
},
|
|
273
|
+
"anthropic": {
|
|
274
|
+
"apiKey": "${ANTHROPIC_KEY}"
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"agents": {
|
|
279
|
+
"defaults": {
|
|
280
|
+
"model": {
|
|
281
|
+
"provider": "openai/gpt-4o",
|
|
282
|
+
"fallback": ["anthropic/claude-sonnet-4"]
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Cost Optimization
|
|
290
|
+
|
|
291
|
+
Use cheaper models as fallbacks:
|
|
292
|
+
|
|
293
|
+
```json
|
|
294
|
+
{
|
|
295
|
+
"agents": {
|
|
296
|
+
"defaults": {
|
|
297
|
+
"model": {
|
|
298
|
+
"provider": "openai/gpt-4o",
|
|
299
|
+
"fallback": [
|
|
300
|
+
"openai/gpt-4o-mini",
|
|
301
|
+
"google/gemini-1.5-flash"
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### High Availability
|
|
310
|
+
|
|
311
|
+
Configure multiple providers:
|
|
312
|
+
|
|
313
|
+
```json
|
|
314
|
+
{
|
|
315
|
+
"models": {
|
|
316
|
+
"providers": {
|
|
317
|
+
"openai": { "apiKey": "${OPENAI_KEY}" },
|
|
318
|
+
"anthropic": { "apiKey": "${ANTHROPIC_KEY}" },
|
|
319
|
+
"google": { "apiKey": "${GEMINI_KEY}" }
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
"agents": {
|
|
323
|
+
"defaults": {
|
|
324
|
+
"model": {
|
|
325
|
+
"provider": "openai/gpt-4o",
|
|
326
|
+
"fallback": [
|
|
327
|
+
"anthropic/claude-sonnet-4",
|
|
328
|
+
"google/gemini-1.5-pro"
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Troubleshooting
|
|
337
|
+
|
|
338
|
+
### Rate Limit Errors
|
|
339
|
+
|
|
340
|
+
1. Add more API keys to the token pool
|
|
341
|
+
2. Check if keys are properly configured
|
|
342
|
+
3. Review request patterns for spikes
|
|
343
|
+
4. Consider adding fallback providers
|
|
344
|
+
|
|
345
|
+
### High Latency
|
|
346
|
+
|
|
347
|
+
1. Check provider status pages
|
|
348
|
+
2. Review token pool distribution
|
|
349
|
+
3. Consider regional providers
|
|
350
|
+
4. Enable request monitoring to identify bottlenecks
|
|
351
|
+
|
|
352
|
+
### Failover Not Working
|
|
353
|
+
|
|
354
|
+
1. Verify fallback providers are configured
|
|
355
|
+
2. Check provider credentials are valid
|
|
356
|
+
3. Review gateway logs for error details
|
|
357
|
+
4. Test providers individually
|
|
358
|
+
|
|
359
|
+
### Authentication Errors
|
|
360
|
+
|
|
361
|
+
1. Verify API keys are correct
|
|
362
|
+
2. Check key hasn't expired
|
|
363
|
+
3. Ensure environment variables are set
|
|
364
|
+
4. Review key permissions/scopes
|
|
365
|
+
|
|
366
|
+
## Monitoring
|
|
367
|
+
|
|
368
|
+
### Gateway Status
|
|
369
|
+
|
|
370
|
+
Check provider status:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
poolbot status --deep
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Model List
|
|
377
|
+
|
|
378
|
+
List configured providers and models:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
poolbot models list
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Live Testing
|
|
385
|
+
|
|
386
|
+
Test providers with live requests:
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
# Test specific provider
|
|
390
|
+
poolbot models list --live --provider openai
|
|
391
|
+
|
|
392
|
+
# Test all providers
|
|
393
|
+
poolbot models list --live
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## See Also
|
|
397
|
+
|
|
398
|
+
- [Model Configuration](./configuration.md)
|
|
399
|
+
- [Agent Configuration](../agents/configuration.md)
|
|
400
|
+
- [Gateway Operations](../gateway/operations.md)
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Exec Approvals
|
|
2
|
+
|
|
3
|
+
PoolBot's **Exec Approval System** provides security guardrails for executing commands on host systems. It prevents unauthorized command execution while maintaining usability through configurable allowlists.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
When agents attempt to execute system commands (via `exec` tool), PoolBot can require explicit approval before execution. This protects against:
|
|
8
|
+
|
|
9
|
+
- Accidental data loss
|
|
10
|
+
- Malicious command injection
|
|
11
|
+
- Unintended system modifications
|
|
12
|
+
|
|
13
|
+
## How It Works
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Agent requests command ──► PoolBot analyzes ──► Check allowlist
|
|
17
|
+
│
|
|
18
|
+
◄────────── Execute ◄─────┤ (if allowed)
|
|
19
|
+
(approval required) ◄─────┘ (if not in allowlist)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Configuration
|
|
23
|
+
|
|
24
|
+
Exec approvals are configured per-agent in `~/.poolbot/exec-approvals.json`:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"version": 1,
|
|
29
|
+
"defaults": {
|
|
30
|
+
"security": "allowlist",
|
|
31
|
+
"ask": "on-miss",
|
|
32
|
+
"askFallback": "deny",
|
|
33
|
+
"autoAllowSkills": false
|
|
34
|
+
},
|
|
35
|
+
"agents": {
|
|
36
|
+
"main": {
|
|
37
|
+
"security": "allowlist",
|
|
38
|
+
"ask": "on-miss",
|
|
39
|
+
"allowlist": [
|
|
40
|
+
{ "id": "uuid-1", "pattern": "git status", "lastUsedAt": 1709823456789 },
|
|
41
|
+
{ "id": "uuid-2", "pattern": "ls -la", "lastUsedAt": 1709823459999 }
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Security Levels
|
|
49
|
+
|
|
50
|
+
| Level | Description |
|
|
51
|
+
|-------|-------------|
|
|
52
|
+
| `deny` | All commands blocked |
|
|
53
|
+
| `allowlist` | Only allowlisted commands permitted |
|
|
54
|
+
| `full` | All commands permitted (use with caution) |
|
|
55
|
+
|
|
56
|
+
### Ask Modes
|
|
57
|
+
|
|
58
|
+
| Mode | Description |
|
|
59
|
+
|------|-------------|
|
|
60
|
+
| `always` | Always request approval |
|
|
61
|
+
| `on-miss` | Request approval only if not in allowlist |
|
|
62
|
+
| `off` | Never request approval |
|
|
63
|
+
|
|
64
|
+
## Approval Workflow
|
|
65
|
+
|
|
66
|
+
### 1. Command Request
|
|
67
|
+
|
|
68
|
+
Agent attempts to run a command through the `exec` tool.
|
|
69
|
+
|
|
70
|
+
### 2. Analysis
|
|
71
|
+
|
|
72
|
+
PoolBot analyzes the command:
|
|
73
|
+
- Resolves the binary path
|
|
74
|
+
- Checks against allowlist patterns
|
|
75
|
+
- Determines if approval is required
|
|
76
|
+
|
|
77
|
+
### 3. Approval Request
|
|
78
|
+
|
|
79
|
+
If approval is needed, PoolBot sends a request via Unix domain socket to the gateway:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
{
|
|
83
|
+
id: "req-uuid",
|
|
84
|
+
request: {
|
|
85
|
+
command: "npm install",
|
|
86
|
+
cwd: "/workspace/project",
|
|
87
|
+
host: "sandbox",
|
|
88
|
+
security: "allowlist",
|
|
89
|
+
ask: "on-miss",
|
|
90
|
+
agentId: "main"
|
|
91
|
+
},
|
|
92
|
+
createdAtMs: 1709823456789,
|
|
93
|
+
expiresAtMs: 1709823576789
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 4. User Decision
|
|
98
|
+
|
|
99
|
+
The user can respond with:
|
|
100
|
+
- `allow-once` - Approve this execution only
|
|
101
|
+
- `allow-always` - Add to allowlist and approve
|
|
102
|
+
- `deny` - Reject the command
|
|
103
|
+
|
|
104
|
+
## Allowlist Management
|
|
105
|
+
|
|
106
|
+
### Pattern Matching
|
|
107
|
+
|
|
108
|
+
Allowlist entries support pattern matching:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"pattern": "git *"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This matches:
|
|
117
|
+
- `git status`
|
|
118
|
+
- `git log`
|
|
119
|
+
- `git commit -m "message"`
|
|
120
|
+
|
|
121
|
+
### Automatic Updates
|
|
122
|
+
|
|
123
|
+
When you approve with "always", PoolBot automatically:
|
|
124
|
+
1. Adds the pattern to the allowlist
|
|
125
|
+
2. Records metadata (last used, resolved path)
|
|
126
|
+
3. Persists to `~/.poolbot/exec-approvals.json`
|
|
127
|
+
|
|
128
|
+
## Per-Agent Configuration
|
|
129
|
+
|
|
130
|
+
Different agents can have different security policies:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"agents": {
|
|
135
|
+
"main": {
|
|
136
|
+
"security": "allowlist",
|
|
137
|
+
"ask": "on-miss"
|
|
138
|
+
},
|
|
139
|
+
"unsafe-agent": {
|
|
140
|
+
"security": "deny"
|
|
141
|
+
},
|
|
142
|
+
"trusted-agent": {
|
|
143
|
+
"security": "allowlist",
|
|
144
|
+
"ask": "off",
|
|
145
|
+
"autoAllowSkills": true
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Integration with Tools
|
|
152
|
+
|
|
153
|
+
### Default Configuration
|
|
154
|
+
|
|
155
|
+
When using the `exec` tool, the agent's exec approval settings are applied:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// The tool inherits settings from exec-approvals.json
|
|
159
|
+
const result = await exec({
|
|
160
|
+
command: "npm install",
|
|
161
|
+
cwd: "/workspace/project"
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Sandbox Mode
|
|
166
|
+
|
|
167
|
+
Exec approvals work with sandbox mode for additional isolation:
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"tools": {
|
|
172
|
+
"exec": {
|
|
173
|
+
"host": "sandbox",
|
|
174
|
+
"sandbox": {
|
|
175
|
+
"image": "node:20-alpine"
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## File Location
|
|
183
|
+
|
|
184
|
+
Exec approvals are stored at:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
~/.poolbot/exec-approvals.json
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The file has strict permissions (0o600) and contains:
|
|
191
|
+
- Version number
|
|
192
|
+
- Socket configuration for gateway communication
|
|
193
|
+
- Default settings
|
|
194
|
+
- Per-agent configurations and allowlists
|
|
195
|
+
|
|
196
|
+
## Socket Communication
|
|
197
|
+
|
|
198
|
+
The CLI and gateway communicate via Unix domain socket:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
~/.poolbot/exec-approvals.sock
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
This enables:
|
|
205
|
+
- Real-time approval requests
|
|
206
|
+
- Secure cross-process communication
|
|
207
|
+
- Token-based authentication
|
|
208
|
+
|
|
209
|
+
## Best Practices
|
|
210
|
+
|
|
211
|
+
### Development Environment
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"defaults": {
|
|
216
|
+
"security": "allowlist",
|
|
217
|
+
"ask": "on-miss"
|
|
218
|
+
},
|
|
219
|
+
"agents": {
|
|
220
|
+
"main": {
|
|
221
|
+
"allowlist": [
|
|
222
|
+
{ "pattern": "git *" },
|
|
223
|
+
{ "pattern": "npm *" },
|
|
224
|
+
{ "pattern": "ls *" },
|
|
225
|
+
{ "pattern": "cat *" }
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Production Environment
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"defaults": {
|
|
237
|
+
"security": "allowlist",
|
|
238
|
+
"ask": "always"
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### CI/CD Environment
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"agents": {
|
|
248
|
+
"ci-agent": {
|
|
249
|
+
"security": "full",
|
|
250
|
+
"ask": "off"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Troubleshooting
|
|
257
|
+
|
|
258
|
+
### Approval Not Received
|
|
259
|
+
|
|
260
|
+
1. Check gateway is running: `poolbot status`
|
|
261
|
+
2. Verify socket exists: `ls -la ~/.poolbot/exec-approvals.sock`
|
|
262
|
+
3. Check file permissions on `~/.poolbot/exec-approvals.json`
|
|
263
|
+
|
|
264
|
+
### Commands Blocked Unexpectedly
|
|
265
|
+
|
|
266
|
+
1. Review allowlist patterns
|
|
267
|
+
2. Check agent-specific settings
|
|
268
|
+
3. Verify `security` level is not set to `deny`
|
|
269
|
+
|
|
270
|
+
### Socket Errors
|
|
271
|
+
|
|
272
|
+
If the socket is corrupted or inaccessible:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# Remove the socket file
|
|
276
|
+
rm ~/.poolbot/exec-approvals.sock
|
|
277
|
+
|
|
278
|
+
# Restart the gateway
|
|
279
|
+
poolbot gateway restart
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Security Considerations
|
|
283
|
+
|
|
284
|
+
- The allowlist file contains sensitive patterns - keep permissions strict (0o600)
|
|
285
|
+
- Socket communication is local-only
|
|
286
|
+
- Tokens are auto-generated and rotated
|
|
287
|
+
- Pattern matching is case-insensitive
|
|
288
|
+
- Resolved binary paths are tracked for auditing
|
|
289
|
+
|
|
290
|
+
## See Also
|
|
291
|
+
|
|
292
|
+
- [Security Overview](../security/overview.md)
|
|
293
|
+
- [Sandbox Mode](../security/sandbox.md)
|
|
294
|
+
- [Agent Configuration](../agents/configuration.md)
|