You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: advanced/context-pruning.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,9 +20,11 @@ Context pruning is distinct from [session compaction](../core-concepts/sessions-
20
20
Pruning is **opt-in** — it only runs when `mode: "cache-ttl"` is set on the agent. The flow:
21
21
22
22
```
23
-
history → limitHistoryTurns → pruneContextMessages → sanitizeHistory → LLM
23
+
history → limitHistoryTurns → sanitizeHistory → LLM
24
24
```
25
25
26
+
> **Note:**`pruneContextMessages` (PruneStage) is **not** part of the main pipeline above. It runs opt-in and separately — only when `mode: "cache-ttl"` is set. The diagram above reflects the standard history preparation path.
27
+
26
28
Before each LLM call, GoClaw:
27
29
28
30
1. Counts tokens in all messages using the tiktoken BPE tokenizer (falls back to `chars / 4` heuristic when tiktoken is unavailable).
@@ -274,4 +276,4 @@ Tool output is now capped at the source before being added to context. Rather th
274
276
-[Memory System](../core-concepts/memory-system.md) — 3-tier memory architecture and consolidation pipeline
275
277
-[Configuration Reference](/config-reference) — full agent config reference
The `scope` field has a strict ownership invariant enforced at the database level by migration `000055` (`vault_documents_scope_consistency` CHECK constraint):
56
+
57
+
|`scope`|`agent_id`|`team_id`| Visibility |
58
+
|---------|------------|-----------|------------|
59
+
|`personal`| set | NULL | Owning agent only (within tenant) |
60
+
|`team`| NULL | set | Members of the team (within tenant) |
61
+
|`shared`| NULL | NULL | All agents within the tenant |
62
+
|`custom`| any | any | User-defined via `custom_scope`|
63
+
64
+
The CHECK constraint rejects any INSERT or UPDATE that violates the `scope × agent_id × team_id` relationship above. `scope='custom'` is the exception — it is intentionally unconstrained, allowing user-defined ownership semantics.
65
+
66
+
#### Agent Read Semantics
67
+
68
+
`vault_search`, `ListDocuments`, and `CountDocuments` always return:
69
+
70
+
- Documents owned by the querying agent (`agent_id = <agent>`)
71
+
- PLUS shared documents (`agent_id IS NULL`)
72
+
73
+
Within a team context (a `RunContext` with `TeamID` set), results also include team-scoped documents for that team (`scope = 'team'` with `team_id = <team>`). Tenant isolation (`tenant_id = <tenant>`) is always enforced regardless of scope.
74
+
53
75
---
54
76
55
77
## Data Model
@@ -391,4 +413,4 @@ No feature flag. Vault is active if the migration ran and VaultStore initialized
1.**Scanner** — statically analyzes `scripts/` subdirectory for Python (`import X`, `from X import`) and Node.js (`require('X')`, `import from 'X'`) imports
221
221
2.**Checker** — verifies each import resolves at runtime via subprocess (`python3 -c "import X"` / `node -e "require.resolve('X')"`)
|`system:name`|`apk add` via pkg-helper (system package) |
229
+
|`github:owner/repo[@tag]`| GitHub Releases installer — admin-only, SHA256-verified, ELF-validated. Binary lands in `/app/data/.runtime/bin/` (on `$PATH`). |
230
+
231
+
Example SKILL.md frontmatter using `github:`:
232
+
233
+
```yaml
234
+
---
235
+
name: my-skill
236
+
description: Does things using ripgrep and gh CLI.
237
+
deps:
238
+
- github:BurntSushi/ripgrep@14.1.0
239
+
- github:cli/cli@v2.40.0
240
+
- pip:requests
241
+
---
242
+
```
243
+
244
+
The `github:` installer fetches the release from GitHub Releases, auto-selects the `linux` + arch-matching asset (amd64 / arm64), verifies SHA256 if the publisher ships `checksums.txt`, validates ELF magic bytes, and extracts to `/app/data/.runtime/bin/`. If no `@tag` is specified, the latest release is used.
223
245
224
246
Dep checks run in a background goroutine at startup (non-blocking). Skills with missing deps are archived automatically; they are re-activated after deps are installed. You can also trigger a rescan via **Skills → Rescan Deps** in the Dashboard or `POST /v1/skills/rescan-deps`.
225
247
@@ -399,4 +421,4 @@ See [Agent Evolution](agent-evolution.md) for full details on the `skill_manage`
399
421
-[Custom Tools](/custom-tools) — add shell-backed tools to your agents
400
422
-[Scheduling & Cron](/scheduling-cron) — run agents on a schedule
Copy file name to clipboardExpand all lines: advanced/tts-voice.md
+86-1Lines changed: 86 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -255,6 +255,91 @@ Each agent can override the global TTS voice and model via its `other_config` JS
255
255
256
256
---
257
257
258
+
## Voices API
259
+
260
+
GoClaw exposes HTTP endpoints for discovering available TTS voices. These are tenant-scoped and require tenant admin or operator role.
261
+
262
+
| Method | Path | Description |
263
+
|--------|------|-------------|
264
+
|`GET`|`/v1/voices`| List available voices (in-memory cached, TTL 1h) |
265
+
|`POST`|`/v1/voices/refresh`| Force-invalidate the voice cache (admin only) |
266
+
267
+
### `GET /v1/voices`
268
+
269
+
Returns the voice list for the current tenant's configured ElevenLabs provider. Results are cached in-memory per tenant with a 1-hour TTL — shared across all HTTP and WebSocket handlers.
270
+
271
+
```json
272
+
[
273
+
{
274
+
"voice_id": "pMsXgVXv3BLzUgSXRplE",
275
+
"name": "Alice",
276
+
"preview_url": "https://...",
277
+
"category": "premade",
278
+
"labels": {
279
+
"use_case": "conversational",
280
+
"accent": "american"
281
+
}
282
+
}
283
+
]
284
+
```
285
+
286
+
A cache miss triggers an immediate fetch from ElevenLabs. Returns `500` if the provider is unreachable.
287
+
288
+
### `POST /v1/voices/refresh`
289
+
290
+
Invalidates the voice cache for the current tenant so the next `GET /v1/voices` request fetches a fresh list from the provider. Useful after adding voices to your ElevenLabs account or after CDN expiry.
291
+
292
+
```json
293
+
{ "message": "voice cache invalidated" }
294
+
```
295
+
296
+
Response is `202 Accepted`.
297
+
298
+
---
299
+
300
+
## Speech-to-Text (STT)
301
+
302
+
GoClaw routes all voice/audio transcription through a unified `audio.Manager` with a provider chain. Channels (Telegram, Discord, Feishu, WhatsApp) share the same STT infrastructure.
WhatsApp STT is **off by default** (`whatsapp_enabled: false`). Rationale: WhatsApp voice messages are end-to-end encrypted. Sending audio bytes to an external STT provider breaks E2E encryption. Admins must explicitly enable it in **Config → Audio → STT** and acknowledge the E2E breaking change.
327
+
328
+
When disabled (default): voice messages appear in agent context as `[Voice message]` — no audio leaves the device.
329
+
When enabled: audio is transcribed via the configured STT chain; falls back to `[Voice message]` on failure or timeout (10 s wall clock).
330
+
331
+
### STT Provider Chain
332
+
333
+
| Setting | Behavior |
334
+
|---------|----------|
335
+
|`providers: ["elevenlabs_scribe", "proxy_stt"]`| Try ElevenLabs Scribe first; fall back to legacy proxy |
|`providers` missing (nil) | Check for legacy `STTProxyURL` bridge at startup |
338
+
339
+
Configure via **Config → Audio → STT** in the web UI (stored in `builtin_tools[stt].settings.providers`). When this list is present it overrides all legacy channel-specific STT configs.
340
+
341
+
---
342
+
258
343
## STT Builtin Tool
259
344
260
345
The `stt` builtin tool (seeded by migration 050) enables agents to transcribe voice/audio input using ElevenLabs Scribe or a compatible proxy — see [Tools Overview](/tools-overview) for how to enable and configure it.
@@ -280,4 +365,4 @@ The `stt` builtin tool (seeded by migration 050) enables agents to transcribe vo
280
365
-[Scheduling & Cron](/scheduling-cron) — trigger agents on a schedule
281
366
-[Extended Thinking](/extended-thinking) — deeper reasoning for complex replies
|`features.first_inbox`| bool | -- | Send a one-time DM to a commenter after their first comment reply |
91
91
|`features.auto_react`| bool | -- | Auto-like user comments on Facebook (Facebook only) |
92
+
|`auto_react_options.allow_post_ids`| list | -- | Only react to comments on these post IDs (nil = all posts) |
93
+
|`auto_react_options.deny_post_ids`| list | -- | Never react to comments on these post IDs (overrides allow) |
94
+
|`auto_react_options.allow_user_ids`| list | -- | Only react to comments from these user IDs (nil = all users) |
95
+
|`auto_react_options.deny_user_ids`| list | -- | Never react to comments from these user IDs (overrides allow) |
92
96
|`comment_reply_options.include_post_context`| bool | false | Prepend post text to comment content sent to the agent |
93
97
|`comment_reply_options.filter`| string |`"all"`| Comment filter mode: `"all"` or `"keyword"`|
94
98
|`comment_reply_options.keywords`| list | -- | Required when `filter="keyword"` — only process comments containing these keywords |
@@ -232,6 +236,17 @@ When `features.comment_reply: true`, additional options control comment handling
232
236
233
237
**Auto-react** (`features.auto_react: true`): automatically likes every valid incoming comment on Facebook (Facebook platform only). Fires independently of `comment_reply` — you can react without replying.
234
238
239
+
Scope the reactions further with `auto_react_options`:
240
+
241
+
| Field | Type | Behavior |
242
+
|-------|------|----------|
243
+
|`allow_post_ids`| list | React only on comments for these post IDs (nil = all posts) |
244
+
|`deny_post_ids`| list | Never react on these post IDs (overrides allow) |
245
+
|`allow_user_ids`| list | React only to comments from these user IDs (nil = all users) |
246
+
|`deny_user_ids`| list | Never react to comments from these user IDs (overrides allow) |
247
+
248
+
Deny lists always take precedence over allow lists. Omitting `auto_react_options` entirely means no scope filter (react to all valid comments).
249
+
235
250
**First inbox** (`features.first_inbox: true`): after replying to a comment, sends a one-time private DM to the commenter inviting them to continue via inbox. Only sent once per sender per session restart. Customize the DM text with `first_inbox_message`.
236
251
237
252
### Channel Health
@@ -268,4 +283,4 @@ Application-level failures (HTTP 200 with `success: false` in JSON body) are als
Copy file name to clipboardExpand all lines: core-concepts/tools-overview.md
+11-9Lines changed: 11 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -38,19 +38,21 @@ Tools are how agents interact with the world beyond generating text. An agent ca
38
38
|**Brave**| Requires `BRAVE_API_KEY`|
39
39
|**DuckDuckGo**| Free fallback — used last if no API keys for the others |
40
40
41
-
Configure provider order via `provider_order` in tool settings:
41
+
> **Breaking change (v3.2+):**`config.json5 tools.web.*` has been removed. Configuration is now tenant-only. Existing keys are auto-migrated on first startup (data hook 055).
42
42
43
-
```json
43
+
Configure `web_search` via the dashboard (**Config → Tools → Web Search**) or the API:
Copy file name to clipboardExpand all lines: deployment/security-hardening.md
+26-1Lines changed: 26 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -152,6 +152,28 @@ For tools that need credentials (e.g., `gh`, `aws`), GoClaw uses direct process
152
152
153
153
Shell metacharacters (`;`, `|`, `&`, `$()`, backticks) are detected and rejected before execution.
154
154
155
+
### Exec grant enforcement
156
+
157
+
Agent-level grant enforcement runs **before** any process spawn, blocking ungranted agents from executing registered binaries:
158
+
159
+
| Control | Detail |
160
+
|---------|--------|
161
+
|**Grant lookup**|`store.SecureCLIStore.IsRegisteredBinary()` checks the `secure_cli_agent_grants` table. Non-global binaries require a row for the calling agent. |
162
+
|**Fail-closed**| If the grant lookup errors (DB down, timeout), exec is denied with a retry message. Per-lookup timeout: 2 seconds. |
163
+
|**Env scrubbing**| When a command bypasses the credentialed path (e.g., via adversarial use of the `exec` tool), the child process environment is scrubbed of all credential keys before spawn — static deny list plus dynamic keys from every registered binary in the tenant. |
164
+
|**Wrapper unwrap**| Shell wrappers (`sh -c`, `bash -c`, etc.) that attempt to evade binary path matching are blocked. GoClaw checks up to 3 levels of nesting; deeper chains are rejected as adversarial. |
165
+
|**Subagent wiring**| Subagent `ExecTool`s use the same `SecureCLIStore` via `buildSubagentToolsRegistry`. Parent agents cannot bypass the gate by delegating exec to spawned subagents. |
166
+
167
+
Security log events emitted by the grant gate:
168
+
169
+
| Event | Meaning |
170
+
|-------|---------|
171
+
|`security.credentialed_binary_denied`| Agent attempted to run a binary it has no grant for |
172
+
|`security.credentialed_binary_gate_error`| Grant lookup failed (DB error); exec denied |
All three events include: `binary`, `wrapper`, `agent_id`, `tenant_id`, and `command` prefix fields.
176
+
155
177
### Shell output limit
156
178
157
179
Host-executed commands have stdout and stderr capped at **1 MB** each. If a command exceeds this limit, output is truncated with a flag to prevent further writes. Sandboxed execution uses Docker container limits instead.
@@ -478,6 +500,9 @@ All security events log at `slog.Warn` with a `security.*` prefix:
478
500
| `security.rate_limited` | Request rejected by rate limiter |
479
501
| `security.cors_rejected` | WebSocket connection rejected by CORS policy |
480
502
| `security.message_truncated` | Message truncated at `max_message_chars` |
503
+
| `security.credentialed_binary_denied` | Agent attempted exec without a grant |
504
+
| `security.credentialed_binary_gate_error` | Grant lookup failed; exec denied fail-closed |
Copy file name to clipboardExpand all lines: deployment/upgrading.md
+5-2Lines changed: 5 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -208,10 +208,12 @@ Only do this if you understand what the failed migration was doing. When in doub
208
208
209
209
## Recent Migrations
210
210
211
-
### v3 Migrations (037–044) — v2→v3 Upgrade Guide
211
+
### v3 Migrations (037–055) — v2→v3 Upgrade Guide
212
212
213
213
These migrations are applied automatically via `./goclaw upgrade`. They constitute the **v3 major release**. Read the breaking changes below before upgrading from v2.
214
214
215
+
Migrations 048–055 introduce the vault media linking, vault scope consistency enforcement, agent hooks system (phases 1–4), and the `web_search` tenant-config migration. No manual steps are required — data hook 055 auto-migrates any API keys from legacy `config.json5 tools.web.*` and `builtin_tool_tenant_configs.settings` blobs to `config_secrets` on first startup.
216
+
215
217
| Version | What changed |
216
218
|---------|-------------|
217
219
| 037 |**V3 memory evolution** — creates `episodic_summaries`, `agent_evolution_metrics`, `agent_evolution_suggestions`; adds `valid_from`/`valid_until` to KG tables; promotes 12 agent fields from `other_config` JSONB to dedicated columns |
@@ -247,6 +249,7 @@ These migrations are applied automatically via `./goclaw upgrade`. They constitu
247
249
| Team workspace files: file tools auto-resolve |`read_file`/`write_file` targeting team workspace paths work directly | None — transparent |
248
250
| Store unification (`internal/store/base/`) | Internal refactor only | None — no schema or config changes |
249
251
| Gateway decomposed into modules | Internal refactor only | None |
252
+
|`config.json5 tools.web.*` removed |`web_search` is now tenant-only; global path no longer parsed | Remove `tools.web.*` from `config.json5`; configure via **Config → Tools → Web Search** UI or `/v1/tools/builtin/web_search/tenant-config` API. API keys auto-migrated on startup (hook 055) |
250
253
251
254
### v2.x Migrations (024–032)
252
255
@@ -321,4 +324,4 @@ Before each upgrade, check the release notes for:
321
324
-[Database Setup](/deploy-database) — PostgreSQL and pgvector setup
322
325
-[Observability](/deploy-observability) — monitor your gateway post-upgrade
0 commit comments