@newsails/veil-cli 1.0.1
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/.veil/agents/analyst/AGENT.md +21 -0
- package/.veil/agents/analyst/agent.json +23 -0
- package/.veil/agents/assistant/AGENT.md +15 -0
- package/.veil/agents/assistant/agent.json +19 -0
- package/.veil/agents/coder/AGENT.md +18 -0
- package/.veil/agents/coder/agent.json +19 -0
- package/.veil/agents/hello/AGENT.md +5 -0
- package/.veil/agents/hello/agent.json +13 -0
- package/.veil/agents/writer/AGENT.md +12 -0
- package/.veil/agents/writer/agent.json +17 -0
- package/.veil/memory/MEMORY.md +343 -0
- package/.veil/memory/agents/analyst/MEMORY.md +55 -0
- package/.veil/memory/agents/hello/MEMORY.md +12 -0
- package/.veil/runtime.pid +1 -0
- package/.veil/settings.json +10 -0
- package/.veil-studio/studio.db +0 -0
- package/.veil-studio/studio.db-shm +0 -0
- package/.veil-studio/studio.db-wal +0 -0
- package/PLAN/01-vision.md +26 -0
- package/PLAN/02-tech-stack.md +94 -0
- package/PLAN/03-agents.md +232 -0
- package/PLAN/04-runtime.md +171 -0
- package/PLAN/05-tools.md +211 -0
- package/PLAN/06-communication.md +243 -0
- package/PLAN/07-storage.md +218 -0
- package/PLAN/08-api-cli.md +153 -0
- package/PLAN/09-permissions.md +108 -0
- package/PLAN/10-ably.md +105 -0
- package/PLAN/11-file-formats.md +442 -0
- package/PLAN/12-folder-structure.md +205 -0
- package/PLAN/13-operations.md +212 -0
- package/PLAN/README.md +23 -0
- package/README.md +128 -0
- package/REPORT.md +174 -0
- package/TODO.md +45 -0
- package/ai-tests/FRONTEND_PROMPT.md +220 -0
- package/ai-tests/Research & Planning.md +814 -0
- package/ai-tests/prompt-001-basic-api.md +230 -0
- package/ai-tests/prompt-002-basic-flows.md +230 -0
- package/ai-tests/prompt-003-agent-behaviors.md +220 -0
- package/api/middleware.js +60 -0
- package/api/routes/agents.js +193 -0
- package/api/routes/chat.js +93 -0
- package/api/routes/completions.js +122 -0
- package/api/routes/daemons.js +80 -0
- package/api/routes/memory.js +169 -0
- package/api/routes/models.js +40 -0
- package/api/routes/remote-methods.js +74 -0
- package/api/routes/sessions.js +208 -0
- package/api/routes/settings.js +108 -0
- package/api/routes/system.js +50 -0
- package/api/routes/tasks.js +270 -0
- package/api/server.js +120 -0
- package/cli/formatter.js +70 -0
- package/cli/index.js +443 -0
- package/cli/parser.js +113 -0
- package/config/config.json +10 -0
- package/config/models.json +6826 -0
- package/core/agent.js +329 -0
- package/core/cancel.js +38 -0
- package/core/compaction.js +176 -0
- package/core/events.js +13 -0
- package/core/loop.js +564 -0
- package/core/memory.js +51 -0
- package/core/prompt.js +185 -0
- package/core/queue.js +96 -0
- package/core/registry.js +291 -0
- package/core/remote-methods.js +124 -0
- package/core/router.js +386 -0
- package/core/running-sessions.js +18 -0
- package/docs/api/01-system.md +84 -0
- package/docs/api/02-agents.md +374 -0
- package/docs/api/03-chat.md +269 -0
- package/docs/api/04-tasks.md +470 -0
- package/docs/api/05-sessions.md +444 -0
- package/docs/api/06-daemons.md +142 -0
- package/docs/api/07-memory.md +186 -0
- package/docs/api/08-settings.md +133 -0
- package/docs/api/09-models.md +119 -0
- package/docs/api/09-websocket.md +350 -0
- package/docs/api/10-completions.md +134 -0
- package/docs/api/README.md +116 -0
- package/docs/guide/01-quickstart.md +220 -0
- package/docs/guide/02-folder-structure.md +185 -0
- package/docs/guide/03-configuration.md +252 -0
- package/docs/guide/04-agents.md +267 -0
- package/docs/guide/05-cli.md +290 -0
- package/docs/guide/06-tools.md +643 -0
- package/docs/guide/07-permissions.md +236 -0
- package/docs/guide/08-memory.md +139 -0
- package/docs/guide/09-multi-agent.md +271 -0
- package/docs/guide/10-daemons.md +226 -0
- package/docs/guide/README.md +53 -0
- package/docs/index.html +623 -0
- package/examples/README.md +151 -0
- package/examples/agents/assistant/AGENT.md +31 -0
- package/examples/agents/assistant/SOUL.md +9 -0
- package/examples/agents/assistant/agent.json +74 -0
- package/examples/agents/hello/AGENT.md +15 -0
- package/examples/agents/hello/agent.json +14 -0
- package/examples/agents/monitor/AGENT.md +51 -0
- package/examples/agents/monitor/agent.json +33 -0
- package/examples/agents/monitor/heartbeats/monitor.md +24 -0
- package/examples/agents/orchestrator/AGENT.md +70 -0
- package/examples/agents/orchestrator/agent.json +30 -0
- package/examples/agents/researcher/AGENT.md +52 -0
- package/examples/agents/researcher/agent.json +49 -0
- package/examples/agents/researcher/skills/web-research.md +28 -0
- package/examples/skills/code-review.md +72 -0
- package/examples/skills/summarise.md +59 -0
- package/examples/skills/web-research.md +42 -0
- package/examples/tools/word-count/index.js +27 -0
- package/examples/tools/word-count/tool.json +18 -0
- package/infrastructure/database.js +563 -0
- package/infrastructure/scheduler.js +122 -0
- package/llm/client.js +206 -0
- package/migrations/001-initial.sql +121 -0
- package/migrations/002-debuggability.sql +13 -0
- package/migrations/003-drop-orphaned-columns.sql +72 -0
- package/migrations/004-session-message-token-fields.sql +78 -0
- package/migrations/005-session-thinking.sql +5 -0
- package/package.json +30 -0
- package/schemas/agent.json +143 -0
- package/schemas/settings.json +111 -0
- package/scripts/fetch-models.js +93 -0
- package/session-debug-scenario.md +248 -0
- package/settings/fields.js +52 -0
- package/system-prompts/base-core.md +7 -0
- package/system-prompts/environment.md +13 -0
- package/system-prompts/reminders/anti-drift.md +6 -0
- package/system-prompts/reminders/stall-recovery.md +10 -0
- package/system-prompts/safety-rules.md +25 -0
- package/system-prompts/task-heuristics.md +27 -0
- package/test/client.js +71 -0
- package/test/integration/01-health.test.js +25 -0
- package/test/integration/02-agents.test.js +80 -0
- package/test/integration/03-chat-hello.test.js +48 -0
- package/test/integration/04-chat-multiturn.test.js +61 -0
- package/test/integration/05-chat-writer.test.js +48 -0
- package/test/integration/06-task-basic.test.js +68 -0
- package/test/integration/07-task-tools.test.js +74 -0
- package/test/integration/08-task-code-analysis.test.js +69 -0
- package/test/integration/09-memory-analyst.test.js +63 -0
- package/test/integration/10-task-advanced.test.js +85 -0
- package/test/integration/11-sessions-advanced.test.js +84 -0
- package/test/integration/12-assistant-chat-tools.test.js +75 -0
- package/test/integration/13-edge-cases.test.js +99 -0
- package/test/integration/14-cancel.test.js +62 -0
- package/test/integration/15-debug.test.js +106 -0
- package/test/integration/16-memory-api.test.js +83 -0
- package/test/integration/17-settings-api.test.js +41 -0
- package/test/integration/18-tool-search-activation.test.js +119 -0
- package/test/results/.gitkeep +0 -0
- package/test/runner.js +206 -0
- package/test/smoke.js +216 -0
- package/tools/agent_message.js +85 -0
- package/tools/agent_send.js +80 -0
- package/tools/agent_spawn.js +44 -0
- package/tools/bash.js +49 -0
- package/tools/edit_file.js +41 -0
- package/tools/glob.js +64 -0
- package/tools/grep.js +82 -0
- package/tools/list_dir.js +63 -0
- package/tools/log_write.js +31 -0
- package/tools/memory_read.js +38 -0
- package/tools/memory_search.js +65 -0
- package/tools/memory_write.js +42 -0
- package/tools/read_file.js +48 -0
- package/tools/sleep.js +22 -0
- package/tools/task_create.js +41 -0
- package/tools/task_respond.js +37 -0
- package/tools/task_spawn.js +64 -0
- package/tools/task_status.js +39 -0
- package/tools/task_subscribe.js +37 -0
- package/tools/todo_read.js +26 -0
- package/tools/todo_write.js +38 -0
- package/tools/tool_activate.js +24 -0
- package/tools/tool_search.js +24 -0
- package/tools/web_fetch.js +50 -0
- package/tools/web_search.js +52 -0
- package/tools/write_file.js +28 -0
- package/ui/api.js +190 -0
- package/ui/app.js +281 -0
- package/ui/index.html +382 -0
- package/ui/views/agents.js +377 -0
- package/ui/views/chat.js +610 -0
- package/ui/views/connection.js +96 -0
- package/ui/views/daemons.js +129 -0
- package/ui/views/feed.js +194 -0
- package/ui/views/memory.js +263 -0
- package/ui/views/models.js +146 -0
- package/ui/views/sessions.js +314 -0
- package/ui/views/settings.js +142 -0
- package/ui/views/tasks.js +415 -0
- package/utils/context.js +49 -0
- package/utils/id.js +16 -0
- package/utils/models.js +88 -0
- package/utils/paths.js +213 -0
- package/utils/settings.js +172 -0
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
# Built-in Tools
|
|
2
|
+
|
|
3
|
+
VeilCLI ships 25 built-in tools. Agents access tools through the permission system — see [Permissions](07-permissions.md) for how to allow/deny them.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Tool Discovery — Four-Tier Loading
|
|
8
|
+
|
|
9
|
+
VeilCLI uses a four-tier model to keep context lean while giving agents access to unlimited custom tools:
|
|
10
|
+
|
|
11
|
+
| Tier | What | How the LLM sees it | Purpose |
|
|
12
|
+
|------|------|---------------------|---------|
|
|
13
|
+
| 1 | **Built-in tools** | Full schema in `tools[]` on every call | Always callable |
|
|
14
|
+
| 2 | **Custom tools (all)** | Names + one-line descriptions in system prompt | Awareness only |
|
|
15
|
+
| 3 | **`tool_search`** | Full JSON schemas returned as text | Inspect and decide |
|
|
16
|
+
| 4 | **`tool_activate`** | Tool schema added to `tools[]` for the next LLM call | Explicit opt-in to call |
|
|
17
|
+
|
|
18
|
+
**Workflow for using a custom tool:**
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
tool_search("query") → read full schemas, inspect parameters
|
|
22
|
+
tool_activate("chosen_tool") → tool becomes callable in the next iteration
|
|
23
|
+
chosen_tool(args) → executes normally
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`tool_search` is **read-only** — searching does not make any tool callable. The LLM must explicitly call `tool_activate` once it has decided to use a specific custom tool. This prevents speculative searches from polluting the active tool list.
|
|
27
|
+
|
|
28
|
+
`tool_activate` is pre-loaded as a built-in (Tier 1), so it is always available without any prior activation step.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Tool Summary
|
|
33
|
+
|
|
34
|
+
| Tool | Category | Description |
|
|
35
|
+
|------|----------|-------------|
|
|
36
|
+
| [`bash`](#bash) | Shell | Execute shell commands |
|
|
37
|
+
| [`read_file`](#read_file) | File I/O | Read file contents |
|
|
38
|
+
| [`write_file`](#write_file) | File I/O | Write/create files |
|
|
39
|
+
| [`edit_file`](#edit_file) | File I/O | Patch files with find-and-replace |
|
|
40
|
+
| [`list_dir`](#list_dir) | File I/O | List directory contents |
|
|
41
|
+
| [`glob`](#glob) | File I/O | Find files by pattern |
|
|
42
|
+
| [`grep`](#grep) | File I/O | Search file contents by regex |
|
|
43
|
+
| [`web_search`](#web_search) | Web | DuckDuckGo search |
|
|
44
|
+
| [`web_fetch`](#web_fetch) | Web | Fetch a URL |
|
|
45
|
+
| [`memory_read`](#memory_read) | Memory | Read agent or project memory |
|
|
46
|
+
| [`memory_write`](#memory_write) | Memory | Append to agent or project memory |
|
|
47
|
+
| [`memory_search`](#memory_search) | Memory | Search memory for relevant content |
|
|
48
|
+
| [`todo_write`](#todo_write) | Productivity | Write a todo list |
|
|
49
|
+
| [`todo_read`](#todo_read) | Productivity | Read the current todo list |
|
|
50
|
+
| [`task_create`](#task_create) | Multi-agent | Create an async task for any agent |
|
|
51
|
+
| [`task_status`](#task_status) | Multi-agent | Check task status |
|
|
52
|
+
| [`task_respond`](#task_respond) | Multi-agent | Unblock a waiting task |
|
|
53
|
+
| [`task_subscribe`](#task_subscribe) | Multi-agent | Subscribe to task completion |
|
|
54
|
+
| [`agent_spawn`](#agent_spawn) | Multi-agent | Start a new chat session with an agent, get sessionId back |
|
|
55
|
+
| [`task_spawn`](#task_spawn) | Multi-agent | Spawn a sub-agent task (sync or async) |
|
|
56
|
+
| [`agent_message`](#agent_message) | Multi-agent | Send a synchronous message to a specific agent session |
|
|
57
|
+
| [`agent_send`](#agent_send) | Multi-agent | Fire-and-forget message to a specific agent session |
|
|
58
|
+
| [`log_write`](#log_write) | Utility | Write a log entry to the task log |
|
|
59
|
+
| [`sleep`](#sleep) | Utility | Wait N seconds |
|
|
60
|
+
| [`tool_search`](#tool_search) | Utility | Search available tools by name or description |
|
|
61
|
+
| [`tool_activate`](#tool_activate) | Utility | Make a custom tool callable (load into active tool list) |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## File I/O Tools
|
|
66
|
+
|
|
67
|
+
### `bash`
|
|
68
|
+
|
|
69
|
+
Execute a shell command and return its output. The command runs in the workspace directory by default.
|
|
70
|
+
|
|
71
|
+
| Parameter | Type | Required | Description |
|
|
72
|
+
|-----------|------|----------|-------------|
|
|
73
|
+
| `command` | string | ✓ | Shell command to execute |
|
|
74
|
+
| `timeout` | integer | | Timeout in seconds (default: 30) |
|
|
75
|
+
| `workingDir` | string | | Override working directory |
|
|
76
|
+
|
|
77
|
+
Returns stdout on success, or `Exit code: N\nstderr:\n...` on failure.
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
"Run: ls -la /tmp"
|
|
81
|
+
→ "total 1024\ndrwxrwxrwt 18 root root..."
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### `read_file`
|
|
87
|
+
|
|
88
|
+
Read the contents of a file, with optional line range.
|
|
89
|
+
|
|
90
|
+
| Parameter | Type | Required | Description |
|
|
91
|
+
|-----------|------|----------|-------------|
|
|
92
|
+
| `path` | string | ✓ | File path (absolute or relative to workspace) |
|
|
93
|
+
| `offset` | integer | | 1-indexed line number to start from |
|
|
94
|
+
| `limit` | integer | | Number of lines to read |
|
|
95
|
+
|
|
96
|
+
Returns file contents with line numbers. If the file is binary, returns a description.
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
"Read: package.json"
|
|
100
|
+
→ " 1 {\n 2 \"name\": \"veilcli\"..."
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### `write_file`
|
|
106
|
+
|
|
107
|
+
Create or overwrite a file.
|
|
108
|
+
|
|
109
|
+
| Parameter | Type | Required | Description |
|
|
110
|
+
|-----------|------|----------|-------------|
|
|
111
|
+
| `path` | string | ✓ | File path to write |
|
|
112
|
+
| `content` | string | ✓ | Content to write |
|
|
113
|
+
|
|
114
|
+
Creates parent directories if they don't exist.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### `edit_file`
|
|
119
|
+
|
|
120
|
+
Patch a file by replacing an exact string with a new string. Safer than `write_file` for targeted edits.
|
|
121
|
+
|
|
122
|
+
| Parameter | Type | Required | Description |
|
|
123
|
+
|-----------|------|----------|-------------|
|
|
124
|
+
| `path` | string | ✓ | File path |
|
|
125
|
+
| `old_string` | string | ✓ | Exact text to replace (must be unique in the file) |
|
|
126
|
+
| `new_string` | string | ✓ | Replacement text |
|
|
127
|
+
|
|
128
|
+
Returns an error if `old_string` is not found or appears more than once.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### `list_dir`
|
|
133
|
+
|
|
134
|
+
List files and directories in a path.
|
|
135
|
+
|
|
136
|
+
| Parameter | Type | Required | Description |
|
|
137
|
+
|-----------|------|----------|-------------|
|
|
138
|
+
| `dir` | string | ✓ | Directory path |
|
|
139
|
+
| `recursive` | boolean | | Include subdirectories (default: false) |
|
|
140
|
+
|
|
141
|
+
Returns a formatted list with file sizes and types.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### `glob`
|
|
146
|
+
|
|
147
|
+
Find files matching a glob pattern.
|
|
148
|
+
|
|
149
|
+
| Parameter | Type | Required | Description |
|
|
150
|
+
|-----------|------|----------|-------------|
|
|
151
|
+
| `pattern` | string | ✓ | Glob pattern (e.g. `**/*.js`, `src/*.ts`) |
|
|
152
|
+
| `cwd` | string | | Base directory (default: workspace root) |
|
|
153
|
+
| `limit` | integer | | Max results (default: 50) |
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### `grep`
|
|
158
|
+
|
|
159
|
+
Search file contents with a regex or literal string.
|
|
160
|
+
|
|
161
|
+
| Parameter | Type | Required | Description |
|
|
162
|
+
|-----------|------|----------|-------------|
|
|
163
|
+
| `pattern` | string | ✓ | Search pattern (regex or literal) |
|
|
164
|
+
| `path` | string | ✓ | File or directory to search |
|
|
165
|
+
| `recursive` | boolean | | Search subdirectories (default: false) |
|
|
166
|
+
| `case_sensitive` | boolean | | Case-sensitive match (default: false) |
|
|
167
|
+
| `fixed_strings` | boolean | | Treat pattern as literal string (default: false) |
|
|
168
|
+
| `include` | string | | Glob to filter files (e.g. `*.js`) |
|
|
169
|
+
| `context_lines` | integer | | Lines of context around each match |
|
|
170
|
+
|
|
171
|
+
Returns matching lines with file path and line number.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Web Tools
|
|
176
|
+
|
|
177
|
+
### `web_search`
|
|
178
|
+
|
|
179
|
+
Search the web using DuckDuckGo. No API key required.
|
|
180
|
+
|
|
181
|
+
| Parameter | Type | Required | Description |
|
|
182
|
+
|-----------|------|----------|-------------|
|
|
183
|
+
| `query` | string | ✓ | Search query |
|
|
184
|
+
| `numResults` | integer | | Number of results (default: 5, max: 10) |
|
|
185
|
+
|
|
186
|
+
Returns a list of results with titles, URLs, and snippets.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
### `web_fetch`
|
|
191
|
+
|
|
192
|
+
Fetch the content of a URL.
|
|
193
|
+
|
|
194
|
+
| Parameter | Type | Required | Description |
|
|
195
|
+
|-----------|------|----------|-------------|
|
|
196
|
+
| `url` | string | ✓ | URL to fetch |
|
|
197
|
+
| `maxLength` | integer | | Max characters to return (default: 20000) |
|
|
198
|
+
|
|
199
|
+
Returns the response text (HTML stripped to readable text for HTML pages).
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Memory Tools
|
|
204
|
+
|
|
205
|
+
### `memory_read`
|
|
206
|
+
|
|
207
|
+
Read the agent's persistent memory (or project-level memory).
|
|
208
|
+
|
|
209
|
+
| Parameter | Type | Required | Description |
|
|
210
|
+
|-----------|------|----------|-------------|
|
|
211
|
+
| `scope` | string | | `"agent"` (default) or `"global"` |
|
|
212
|
+
|
|
213
|
+
Returns the contents of the memory file, or an empty string if no memory exists yet.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### `memory_write`
|
|
218
|
+
|
|
219
|
+
Append content to persistent memory. Entries are timestamped automatically.
|
|
220
|
+
|
|
221
|
+
| Parameter | Type | Required | Description |
|
|
222
|
+
|-----------|------|----------|-------------|
|
|
223
|
+
| `content` | string | ✓ | Content to append |
|
|
224
|
+
| `scope` | string | | `"agent"` (default) or `"global"` |
|
|
225
|
+
|
|
226
|
+
Memory is stored in `.veil/memory/agents/<name>/MEMORY.md` (agent) or `.veil/memory/MEMORY.md` (global).
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### `memory_search`
|
|
231
|
+
|
|
232
|
+
Search memory for content relevant to a query.
|
|
233
|
+
|
|
234
|
+
| Parameter | Type | Required | Description |
|
|
235
|
+
|-----------|------|----------|-------------|
|
|
236
|
+
| `query` | string | ✓ | Search query |
|
|
237
|
+
| `scope` | string | | `"agent"` (default) or `"global"` |
|
|
238
|
+
| `maxResults` | integer | | Max matching entries (default: 5) |
|
|
239
|
+
|
|
240
|
+
Returns matching memory entries scored by relevance.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Productivity Tools
|
|
245
|
+
|
|
246
|
+
### `todo_write`
|
|
247
|
+
|
|
248
|
+
Write a structured todo list for the current task.
|
|
249
|
+
|
|
250
|
+
| Parameter | Type | Required | Description |
|
|
251
|
+
|-----------|------|----------|-------------|
|
|
252
|
+
| `todos` | array | ✓ | Array of todo items |
|
|
253
|
+
|
|
254
|
+
Each todo item:
|
|
255
|
+
```json
|
|
256
|
+
{
|
|
257
|
+
"id": "1",
|
|
258
|
+
"content": "Read the config file",
|
|
259
|
+
"status": "pending",
|
|
260
|
+
"priority": "high"
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
`status`: `"pending"`, `"in_progress"`, `"completed"`
|
|
265
|
+
`priority`: `"high"`, `"medium"`, `"low"`
|
|
266
|
+
|
|
267
|
+
Todos are stored in the database and can be read with `todo_read`.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
### `todo_read`
|
|
272
|
+
|
|
273
|
+
Read the current todo list for the active task or session.
|
|
274
|
+
|
|
275
|
+
No parameters.
|
|
276
|
+
|
|
277
|
+
Returns a formatted list of todos with statuses and priorities.
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Multi-Agent Tools
|
|
282
|
+
|
|
283
|
+
### `task_create`
|
|
284
|
+
|
|
285
|
+
Create a new task for any agent. Returns immediately with a `taskId` — the task runs asynchronously.
|
|
286
|
+
|
|
287
|
+
| Parameter | Type | Required | Description |
|
|
288
|
+
|-----------|------|----------|-------------|
|
|
289
|
+
| `agent` | string | ✓ | Agent name |
|
|
290
|
+
| `input` | string | ✓ | Task instructions |
|
|
291
|
+
| `priority` | string | | `"high"`, `"normal"`, `"low"` (default: `"normal"`) |
|
|
292
|
+
| `tags` | string[] | | Optional labels |
|
|
293
|
+
| `maxIterations` | integer | | Override max iterations |
|
|
294
|
+
| `maxDurationSeconds` | integer | | Override max duration |
|
|
295
|
+
|
|
296
|
+
Returns: `{ taskId, status: "pending", agent }`
|
|
297
|
+
|
|
298
|
+
Use `task_status` to poll for completion.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
### `task_status`
|
|
303
|
+
|
|
304
|
+
Check the status and output of a task.
|
|
305
|
+
|
|
306
|
+
| Parameter | Type | Required | Description |
|
|
307
|
+
|-----------|------|----------|-------------|
|
|
308
|
+
| `taskId` | string | ✓ | Task ID from `task_create` or `agent_spawn` |
|
|
309
|
+
|
|
310
|
+
Returns a JSON object with the full task record (status, output, error, iterations, tokens).
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
### `task_respond`
|
|
315
|
+
|
|
316
|
+
Send a response to a task that is in `waiting` status (i.e. an agent called `task_respond` internally and is waiting for a reply).
|
|
317
|
+
|
|
318
|
+
| Parameter | Type | Required | Description |
|
|
319
|
+
|-----------|------|----------|-------------|
|
|
320
|
+
| `taskId` | string | ✓ | Task ID |
|
|
321
|
+
| `message` | string | ✓ | Message to inject into the agent's context |
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
### `task_subscribe`
|
|
326
|
+
|
|
327
|
+
Create a durable subscription to a task's completion. When the task finishes, the subscriber session is notified. Subscriptions survive server restarts.
|
|
328
|
+
|
|
329
|
+
| Parameter | Type | Required | Description |
|
|
330
|
+
|-----------|------|----------|-------------|
|
|
331
|
+
| `taskId` | string | ✓ | Task ID to subscribe to |
|
|
332
|
+
|
|
333
|
+
Used by orchestrators to reliably track delegated work.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
### `agent_spawn`
|
|
338
|
+
|
|
339
|
+
Start a new chat session with an agent and send the first message. Returns `{ sessionId, response }`. Use the `sessionId` with `agent_message` or `agent_send` for follow-up exchanges in the same conversation.
|
|
340
|
+
|
|
341
|
+
| Parameter | Type | Required | Description |
|
|
342
|
+
|-----------|------|----------|--------------|
|
|
343
|
+
| `agent` | string | ✓ | Agent name |
|
|
344
|
+
| `message` | string | ✓ | First message to send |
|
|
345
|
+
| `returnMode` | string | | `"full"` (default) → `{ sessionId, response }`, `"responseOnly"` → response text only |
|
|
346
|
+
|
|
347
|
+
Returns an error immediately if the agent does not exist.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
### `task_spawn`
|
|
352
|
+
|
|
353
|
+
Spawn a sub-agent task with an isolated context. The most powerful multi-agent tool for delegating work.
|
|
354
|
+
|
|
355
|
+
| Parameter | Type | Required | Description |
|
|
356
|
+
|-----------|------|----------|--------------|
|
|
357
|
+
| `agent` | string | ✓ | Agent name |
|
|
358
|
+
| `instruction` | string | ✓ | Task instruction. Use `"/skill-name args"` to trigger a skill. |
|
|
359
|
+
| `returnMode` | string | | `"summary"` (default), `"raw"`, or `"lastMessage"` |
|
|
360
|
+
| `wait` | boolean | | `true` = sync (block until done), `false` = async (return taskId immediately). Default: `true` |
|
|
361
|
+
|
|
362
|
+
**Sync (default)**: blocks until the sub-agent completes, returns its output directly.
|
|
363
|
+
|
|
364
|
+
**Async** (`wait: false`): returns immediately with `{ taskId }`. Use `task_status` or `task_subscribe` to track completion. Enables parallel fan-out.
|
|
365
|
+
|
|
366
|
+
Return modes:
|
|
367
|
+
- `"summary"` — returns the agent's final text output
|
|
368
|
+
- `"raw"` — returns `{ taskId, status, output }` as JSON
|
|
369
|
+
- `"lastMessage"` — returns the last message content
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### `agent_message`
|
|
374
|
+
|
|
375
|
+
Send a message to a specific agent session and wait for a reply (synchronous).
|
|
376
|
+
|
|
377
|
+
| Parameter | Type | Required | Description |
|
|
378
|
+
|-----------|------|----------|--------------|
|
|
379
|
+
| `agent` | string | ✓ | Agent name |
|
|
380
|
+
| `sessionId` | string | ✓ | Session ID obtained from `agent_spawn` |
|
|
381
|
+
| `message` | string | ✓ | Message content |
|
|
382
|
+
| `timeout` | integer | | Seconds to wait for reply (default: 60, no cap) |
|
|
383
|
+
|
|
384
|
+
**Routing logic:**
|
|
385
|
+
- If the session's loop is **idle** and mode is `chat` → triggers a new chat turn directly (same as a user message via API)
|
|
386
|
+
- If the session's loop is **active** (mid-processing) → injects the message at the next `drainNonFollowup` checkpoint between tool calls
|
|
387
|
+
- If the loop ends before picking up the message → automatically falls back to `runChat` directly
|
|
388
|
+
|
|
389
|
+
Returns an error immediately if the agent or session does not exist, or if `sessionId` belongs to a different agent.
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
### `agent_send`
|
|
394
|
+
|
|
395
|
+
Fire-and-forget message to a specific agent session. Does not wait for a reply.
|
|
396
|
+
|
|
397
|
+
| Parameter | Type | Required | Description |
|
|
398
|
+
|-----------|------|----------|--------------|
|
|
399
|
+
| `agent` | string | ✓ | Agent name |
|
|
400
|
+
| `sessionId` | string | ✓ | Session ID obtained from `agent_spawn` |
|
|
401
|
+
| `message` | string | ✓ | Message content |
|
|
402
|
+
| `followup` | boolean | | If `true`, delivered only after the agent finishes its current task (default: `false`) |
|
|
403
|
+
|
|
404
|
+
**Routing logic:**
|
|
405
|
+
- **Idle chat session** → fires a new chat turn immediately (fire-and-forget)
|
|
406
|
+
- **Active session** → injects into queue; a background watcher ensures the message is never lost — if the loop ends before draining it, `runChat` is triggered automatically
|
|
407
|
+
|
|
408
|
+
Returns an error immediately if the agent or session does not exist.
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Utility Tools
|
|
413
|
+
|
|
414
|
+
### `log_write`
|
|
415
|
+
|
|
416
|
+
Write a log entry to the current task's log. Useful for agents to document their progress.
|
|
417
|
+
|
|
418
|
+
| Parameter | Type | Required | Description |
|
|
419
|
+
|-----------|------|----------|-------------|
|
|
420
|
+
| `message` | string | ✓ | Log message |
|
|
421
|
+
| `level` | string | | `"info"` (default), `"warn"`, `"error"` |
|
|
422
|
+
| `metadata` | object | | Optional structured data |
|
|
423
|
+
|
|
424
|
+
Logs are stored as task events and visible in `GET /tasks/:id/events`.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
### `sleep`
|
|
429
|
+
|
|
430
|
+
Wait for a specified number of seconds. Time counts against `maxDurationSeconds` but not against `maxIterations`.
|
|
431
|
+
|
|
432
|
+
| Parameter | Type | Required | Description |
|
|
433
|
+
|-----------|------|----------|-------------|
|
|
434
|
+
| `seconds` | number | ✓ | Seconds to wait (max: 300) |
|
|
435
|
+
|
|
436
|
+
Useful for polling loops or rate-limiting.
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### `tool_search`
|
|
441
|
+
|
|
442
|
+
Search the list of available tools (built-in + any custom tools loaded for the agent). Returns full schemas so the LLM can inspect parameter requirements before deciding which tool to activate. **This is read-only — calling `tool_search` does not make any tool callable.**
|
|
443
|
+
|
|
444
|
+
| Parameter | Type | Required | Description |
|
|
445
|
+
|-----------|------|----------|-------------|
|
|
446
|
+
| `query` | string | ✓ | Search term (matches name and description) |
|
|
447
|
+
|
|
448
|
+
Returns an array of matching tool schemas (name, description, input_schema).
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
### `tool_activate`
|
|
453
|
+
|
|
454
|
+
Make a specific custom tool callable by loading its full schema into the active tool list. Call this after `tool_search` once you have decided to use a tool.
|
|
455
|
+
|
|
456
|
+
| Parameter | Type | Required | Description |
|
|
457
|
+
|-----------|------|----------|-------------|
|
|
458
|
+
| `name` | string | ✓ | Exact tool name to activate (as returned by `tool_search`) |
|
|
459
|
+
|
|
460
|
+
Returns `{ "activated": "<name>" }` on success, or a not-found message if the tool doesn't exist. After activation the tool is callable in the same turn.
|
|
461
|
+
|
|
462
|
+
The same whitelist/blocklist rules that apply to built-in tools are enforced at activation time — a blocked tool cannot be activated.
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Custom Tools
|
|
467
|
+
|
|
468
|
+
You can add custom tools to a specific agent by placing `.js` files in `.veil/agents/<name>/tools/`. Each file must export:
|
|
469
|
+
|
|
470
|
+
```js
|
|
471
|
+
module.exports = {
|
|
472
|
+
schema: {
|
|
473
|
+
name: 'my_tool',
|
|
474
|
+
description: 'Does something useful',
|
|
475
|
+
input_schema: {
|
|
476
|
+
type: 'object',
|
|
477
|
+
properties: {
|
|
478
|
+
input: { type: 'string', description: 'Input value' }
|
|
479
|
+
},
|
|
480
|
+
required: ['input']
|
|
481
|
+
},
|
|
482
|
+
timeout: 30, // seconds
|
|
483
|
+
},
|
|
484
|
+
async execute({ input, _cwd, _agent, _sessionId, _taskId, _settings, _remoteMethodExecution }) {
|
|
485
|
+
// _cwd, _agent, _sessionId, _taskId, _settings, _remoteMethodExecution are injected automatically
|
|
486
|
+
return `Processed: ${input}`;
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Custom tools are only available to the agent that owns them (not globally).
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Remote Method Execution
|
|
496
|
+
|
|
497
|
+
`_remoteMethodExecution` lets a custom tool **pause and wait for a response from a connected UI**. This is the mechanism for building interactive UI-side tools — for example, a tool that opens a dialog in the dashboard and resumes once the user answers.
|
|
498
|
+
|
|
499
|
+
### How it works
|
|
500
|
+
|
|
501
|
+
```
|
|
502
|
+
Tool calls _remoteMethodExecution()
|
|
503
|
+
│
|
|
504
|
+
▼
|
|
505
|
+
Server emits method.pending over SSE
|
|
506
|
+
│
|
|
507
|
+
▼
|
|
508
|
+
UI receives event, shows dialog / performs action
|
|
509
|
+
│
|
|
510
|
+
▼
|
|
511
|
+
UI posts result to POST /remote-methods/:id/result
|
|
512
|
+
│
|
|
513
|
+
▼
|
|
514
|
+
Server broadcasts method.done to all SSE clients
|
|
515
|
+
│
|
|
516
|
+
▼
|
|
517
|
+
_remoteMethodExecution() resolves with the result
|
|
518
|
+
│
|
|
519
|
+
▼
|
|
520
|
+
Tool continues execution
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Methods live **in memory only** — they do not survive a server restart.
|
|
524
|
+
|
|
525
|
+
### Tool-side usage
|
|
526
|
+
|
|
527
|
+
```js
|
|
528
|
+
async execute({ question, _remoteMethodExecution }) {
|
|
529
|
+
const response = await _remoteMethodExecution({
|
|
530
|
+
method: 'user-dialog', // arbitrary string — UI uses this to decide how to render
|
|
531
|
+
data: { question }, // any JSON-serialisable value the UI needs
|
|
532
|
+
timeoutMs: 120_000, // optional, default 120 s; throws on timeout
|
|
533
|
+
});
|
|
534
|
+
// response is whatever the UI sent as body.result (any JSON value)
|
|
535
|
+
return `User answered: ${JSON.stringify(response)}`;
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**If no UI is listening** the call will hang until `timeoutMs` elapses, then the tool receives a rejection error. Design your tool to handle this gracefully:
|
|
540
|
+
|
|
541
|
+
```js
|
|
542
|
+
try {
|
|
543
|
+
const answer = await _remoteMethodExecution({ method: 'ask_user', data: { prompt } });
|
|
544
|
+
return `User said: ${answer}`;
|
|
545
|
+
} catch (err) {
|
|
546
|
+
return `No UI responded in time: ${err.message}`;
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### API endpoints
|
|
551
|
+
|
|
552
|
+
#### `GET /remote-methods` *(SSE)*
|
|
553
|
+
|
|
554
|
+
Connect to receive a stream of method events. On connect, all currently-pending methods are replayed so a freshly-connected UI is immediately in sync.
|
|
555
|
+
|
|
556
|
+
**Event types**
|
|
557
|
+
|
|
558
|
+
| type | fields | meaning |
|
|
559
|
+
|------|--------|---------|
|
|
560
|
+
| `method.pending` | `id`, `method`, `data`, `createdAt` | A tool is waiting for a result |
|
|
561
|
+
| `method.done` | `id`, `timedOut` | Method was resolved (or timed out) — discard it |
|
|
562
|
+
|
|
563
|
+
```
|
|
564
|
+
: connected
|
|
565
|
+
|
|
566
|
+
data: {"type":"method.pending","id":"550e8400-e29b-41d4-a716-446655440000","method":"user-dialog","data":{"question":"Continue?"},"createdAt":"2025-01-01T00:00:00.000Z"}
|
|
567
|
+
|
|
568
|
+
data: {"type":"method.done","id":"550e8400-e29b-41d4-a716-446655440000","timedOut":false}
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
Headers required: `Authorization: Bearer <secret>` (same as all other endpoints).
|
|
572
|
+
|
|
573
|
+
#### `POST /remote-methods/:id/result`
|
|
574
|
+
|
|
575
|
+
Deliver the UI's response for a specific pending call.
|
|
576
|
+
|
|
577
|
+
**Body**
|
|
578
|
+
```json
|
|
579
|
+
{ "result": <any JSON value> }
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
**Responses**
|
|
583
|
+
|
|
584
|
+
| Status | Meaning |
|
|
585
|
+
|--------|---------|
|
|
586
|
+
| `200 { ok: true, id }` | Result accepted, waiting tool unblocked |
|
|
587
|
+
| `409 { error: "not_found" }` | ID unknown — already resolved, timed out, or invalid |
|
|
588
|
+
|
|
589
|
+
#### `GET /remote-methods/pending` *(diagnostic)*
|
|
590
|
+
|
|
591
|
+
Returns `{ pending: ["id1", "id2", ...] }` — the IDs of all currently-waiting calls.
|
|
592
|
+
|
|
593
|
+
### UI implementation example
|
|
594
|
+
|
|
595
|
+
```js
|
|
596
|
+
// Connect to the SSE stream
|
|
597
|
+
const es = new EventSource('/remote-methods', {
|
|
598
|
+
headers: { Authorization: `Bearer ${secret}` }
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
es.onmessage = async (e) => {
|
|
602
|
+
const event = JSON.parse(e.data);
|
|
603
|
+
|
|
604
|
+
if (event.type === 'method.pending') {
|
|
605
|
+
if (event.method === 'user-dialog') {
|
|
606
|
+
// Show your dialog
|
|
607
|
+
const answer = await showDialog(event.data);
|
|
608
|
+
|
|
609
|
+
// Post the result back
|
|
610
|
+
await fetch(`/remote-methods/${event.id}/result`, {
|
|
611
|
+
method: 'POST',
|
|
612
|
+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${secret}` },
|
|
613
|
+
body: JSON.stringify({ result: answer }),
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (event.type === 'method.done') {
|
|
619
|
+
// Optionally close/dismiss any pending dialog for event.id
|
|
620
|
+
dismissDialog(event.id);
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### Multi-client behaviour
|
|
626
|
+
|
|
627
|
+
If multiple UIs are connected simultaneously:
|
|
628
|
+
|
|
629
|
+
- **All** receive `method.pending` — the **first** to POST a result wins.
|
|
630
|
+
- The server immediately broadcasts `method.done` to all remaining clients so they can discard the prompt.
|
|
631
|
+
- A late POST returns `409 not_found` — handle this gracefully on the UI side.
|
|
632
|
+
|
|
633
|
+
### Timeouts
|
|
634
|
+
|
|
635
|
+
The default timeout is **120 seconds**. Override per-call:
|
|
636
|
+
|
|
637
|
+
```js
|
|
638
|
+
await _remoteMethodExecution({ method: 'confirm', data: {}, timeoutMs: 30_000 });
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
When a call times out, `method.done` with `timedOut: true` is broadcast to all SSE clients.
|
|
642
|
+
|
|
643
|
+
---
|