@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,470 @@
|
|
|
1
|
+
# Tasks
|
|
2
|
+
|
|
3
|
+
Tasks are **asynchronous** agent runs. Unlike chat, a task is created immediately (202) and runs in the background. Poll for status or stream events to track progress.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Task Lifecycle
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
pending → processing → finished
|
|
11
|
+
→ failed
|
|
12
|
+
→ canceled
|
|
13
|
+
→ waiting (agent used task_respond tool, awaiting reply)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## POST /agents/:name/task
|
|
19
|
+
|
|
20
|
+
Create a new task for an agent. Returns immediately with the task ID.
|
|
21
|
+
|
|
22
|
+
**Path parameters**
|
|
23
|
+
|
|
24
|
+
| Param | Description |
|
|
25
|
+
|-------|-------------|
|
|
26
|
+
| `name` | Agent name |
|
|
27
|
+
|
|
28
|
+
**Request body**
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"input": "Read package.json and tell me the dependencies",
|
|
33
|
+
"priority": "normal",
|
|
34
|
+
"tags": ["audit", "deps"],
|
|
35
|
+
"maxIterations": 15,
|
|
36
|
+
"maxDurationSeconds": 60
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Field | Type | Required | Description |
|
|
41
|
+
|-------|------|----------|-------------|
|
|
42
|
+
| `input` | string | ✓ | Task instruction |
|
|
43
|
+
| `priority` | string | | `"high"`, `"normal"` (default), or `"low"` |
|
|
44
|
+
| `tags` | string[] | | Arbitrary labels for filtering |
|
|
45
|
+
| `maxIterations` | integer | | Override max agent loop iterations for this task |
|
|
46
|
+
| `maxDurationSeconds` | integer | | Override max wall-clock seconds for this task |
|
|
47
|
+
| `tokenBudget` | integer | | Max total tokens (input + output) before failing with `BUDGET_EXCEEDED` |
|
|
48
|
+
|
|
49
|
+
**Response — 202 Accepted**
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"taskId": "task_c0ab38d8377cdd47",
|
|
54
|
+
"status": "pending"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Error responses**
|
|
59
|
+
|
|
60
|
+
| Code | Condition |
|
|
61
|
+
|------|-----------|
|
|
62
|
+
| `400 VALIDATION_ERROR` | `input` is missing or not a string |
|
|
63
|
+
| `400 MODE_NOT_SUPPORTED` | Agent does not have `task.enabled: true` |
|
|
64
|
+
| `404 AGENT_NOT_FOUND` | No agent with that name |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## GET /tasks
|
|
69
|
+
|
|
70
|
+
List tasks for the current workspace with optional filters.
|
|
71
|
+
|
|
72
|
+
**Query parameters**
|
|
73
|
+
|
|
74
|
+
| Param | Type | Description |
|
|
75
|
+
|-------|------|-------------|
|
|
76
|
+
| `agentName` | string | Filter by agent |
|
|
77
|
+
| `status` | string | Filter by status: `pending`, `processing`, `finished`, `failed`, `canceled`, `waiting` |
|
|
78
|
+
| `priority` | string | Filter by priority: `high`, `normal`, `low` |
|
|
79
|
+
| `limit` | integer | Max results (default: 20) |
|
|
80
|
+
| `cursor` | string | Pagination cursor (last task ID from previous page) |
|
|
81
|
+
|
|
82
|
+
**Response**
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"tasks": [
|
|
87
|
+
{
|
|
88
|
+
"id": "task_c0ab38d8377cdd47",
|
|
89
|
+
"agent_name": "assistant",
|
|
90
|
+
"status": "finished",
|
|
91
|
+
"priority": "normal",
|
|
92
|
+
"input": "Read package.json and tell me the dependencies",
|
|
93
|
+
"output": "The project depends on: ajv@8.17.1, express@4.21.2...",
|
|
94
|
+
"error": null,
|
|
95
|
+
"iterations": 3,
|
|
96
|
+
"token_input": 2140,
|
|
97
|
+
"token_output": 310,
|
|
98
|
+
"tags": ["audit"],
|
|
99
|
+
"created_at": "2025-03-02T10:00:00.000Z",
|
|
100
|
+
"started_at": "2025-03-02T10:00:01.000Z",
|
|
101
|
+
"finished_at": "2025-03-02T10:00:09.000Z"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## GET /tasks/:id
|
|
110
|
+
|
|
111
|
+
Get full details for a single task.
|
|
112
|
+
|
|
113
|
+
**Path parameters**
|
|
114
|
+
|
|
115
|
+
| Param | Description |
|
|
116
|
+
|-------|-------------|
|
|
117
|
+
| `id` | Task ID |
|
|
118
|
+
|
|
119
|
+
**Response**
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"task": {
|
|
124
|
+
"id": "task_c0ab38d8377cdd47",
|
|
125
|
+
"agent_name": "assistant",
|
|
126
|
+
"session_id": "sess_ff1122334455",
|
|
127
|
+
"status": "finished",
|
|
128
|
+
"priority": "normal",
|
|
129
|
+
"input": "...",
|
|
130
|
+
"output": "...",
|
|
131
|
+
"error": null,
|
|
132
|
+
"iterations": 3,
|
|
133
|
+
"token_input": 2140,
|
|
134
|
+
"token_output": 310,
|
|
135
|
+
"tags": [],
|
|
136
|
+
"parent_task_id": null,
|
|
137
|
+
"created_at": "2025-03-02T10:00:00.000Z",
|
|
138
|
+
"started_at": "2025-03-02T10:00:01.000Z",
|
|
139
|
+
"finished_at": "2025-03-02T10:00:09.000Z"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Task object fields**
|
|
145
|
+
|
|
146
|
+
| Field | Type | Description |
|
|
147
|
+
|-------|------|-------------|
|
|
148
|
+
| `id` | string | Unique task ID |
|
|
149
|
+
| `agent_name` | string | Agent that ran (or will run) the task |
|
|
150
|
+
| `session_id` | string \| null | Session created for this task run |
|
|
151
|
+
| `status` | string | Current lifecycle status |
|
|
152
|
+
| `priority` | string | `high` / `normal` / `low` |
|
|
153
|
+
| `input` | string | Original input text |
|
|
154
|
+
| `output` | string \| null | Final agent text output (set on `finished`) |
|
|
155
|
+
| `error` | object \| null | Structured error object with `code`, `message`, `iteration`, etc. (set on `failed`) |
|
|
156
|
+
| `eventCount` | integer | Number of events recorded for this task |
|
|
157
|
+
| `iterations` | integer | Number of LLM loop iterations used |
|
|
158
|
+
| `token_input` | integer | Total input tokens |
|
|
159
|
+
| `token_output` | integer | Total output tokens |
|
|
160
|
+
| `tags` | string[] | Tags supplied at creation |
|
|
161
|
+
| `parent_task_id` | string \| null | Set when spawned by `agent_spawn` |
|
|
162
|
+
| `created_at` | ISO string | When task was created |
|
|
163
|
+
| `started_at` | ISO string \| null | When processing began |
|
|
164
|
+
| `finished_at` | ISO string \| null | When task reached terminal state |
|
|
165
|
+
|
|
166
|
+
**Error responses**
|
|
167
|
+
|
|
168
|
+
| Code | Condition |
|
|
169
|
+
|------|-----------|
|
|
170
|
+
| `404 TASK_NOT_FOUND` | No task with that ID |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## GET /tasks/:id/events
|
|
175
|
+
|
|
176
|
+
Returns the list of progress events emitted during task execution. Use this for real-time tool tracing.
|
|
177
|
+
|
|
178
|
+
**Query parameters**
|
|
179
|
+
|
|
180
|
+
| Param | Type | Description |
|
|
181
|
+
|-------|------|-------------|
|
|
182
|
+
| `since` | integer | Return only events with ID greater than this value (default: 0) |
|
|
183
|
+
| `limit` | integer | Max events to return (default: 500) |
|
|
184
|
+
|
|
185
|
+
**Response**
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"taskId": "task_c0ab38d8377cdd47",
|
|
190
|
+
"events": [
|
|
191
|
+
{
|
|
192
|
+
"id": 1,
|
|
193
|
+
"type": "status.change",
|
|
194
|
+
"data": { "from": "pending", "to": "processing" },
|
|
195
|
+
"created_at": "2025-03-02T10:00:01.000Z"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"id": 2,
|
|
199
|
+
"type": "tool.start",
|
|
200
|
+
"data": {
|
|
201
|
+
"toolName": "read_file",
|
|
202
|
+
"toolInput": { "path": "package.json" }
|
|
203
|
+
},
|
|
204
|
+
"created_at": "2025-03-02T10:00:02.000Z"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"id": 3,
|
|
208
|
+
"type": "tool.end",
|
|
209
|
+
"data": {
|
|
210
|
+
"toolName": "read_file",
|
|
211
|
+
"durationMs": 12,
|
|
212
|
+
"success": true,
|
|
213
|
+
"outputPreview": "{\n \"name\": \"veilcli\",\n \"version\": \"0.1.0\""
|
|
214
|
+
},
|
|
215
|
+
"created_at": "2025-03-02T10:00:02.000Z"
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Event types**
|
|
222
|
+
|
|
223
|
+
| Type | Data fields | Description |
|
|
224
|
+
|------|-------------|-------------|
|
|
225
|
+
| `status.change` | `from`, `to`, `reason?` | Task status transition |
|
|
226
|
+
| `tool.start` | `toolName`, `toolInput` | Tool call began |
|
|
227
|
+
| `tool.end` | `toolName`, `durationMs`, `success`, `outputPreview` | Tool call completed |
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## DELETE /tasks/:id
|
|
232
|
+
|
|
233
|
+
Hard-delete a task and all its associated data (events, context snapshot, subscriptions).
|
|
234
|
+
|
|
235
|
+
**Path parameters**
|
|
236
|
+
|
|
237
|
+
| Param | Description |
|
|
238
|
+
|-------|-------------|
|
|
239
|
+
| `id` | Task ID |
|
|
240
|
+
|
|
241
|
+
**Query parameters**
|
|
242
|
+
|
|
243
|
+
| Param | Type | Description |
|
|
244
|
+
|-------|------|-------------|
|
|
245
|
+
| `force` | boolean | Set to `true` to cancel and delete an active task. Without this, deleting an active task returns `409`. |
|
|
246
|
+
|
|
247
|
+
**Response**
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"deleted": true,
|
|
251
|
+
"taskId": "task_c0ab38d8377cdd47"
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Error responses**
|
|
256
|
+
|
|
257
|
+
| Code | Condition |
|
|
258
|
+
|------|-----------|
|
|
259
|
+
| `409 TASK_ACTIVE` | Task is in `pending`, `processing`, or `waiting` status. Use `?force=true` to override. |
|
|
260
|
+
| `404 TASK_NOT_FOUND` | No task with that ID |
|
|
261
|
+
|
|
262
|
+
**Examples**
|
|
263
|
+
```bash
|
|
264
|
+
# Delete a finished task
|
|
265
|
+
curl -X DELETE http://localhost:5050/tasks/task_c0ab38d8377cdd47
|
|
266
|
+
|
|
267
|
+
# Force-delete a running task (cancels first, then deletes)
|
|
268
|
+
curl -X DELETE "http://localhost:5050/tasks/task_c0ab38d8377cdd47?force=true"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## GET /tasks/:id/stream
|
|
274
|
+
|
|
275
|
+
Real-time SSE (Server-Sent Events) stream for a single task. Replays all historical events from the database, then streams live events until the task reaches a terminal state.
|
|
276
|
+
|
|
277
|
+
**Path parameters**
|
|
278
|
+
|
|
279
|
+
| Param | Description |
|
|
280
|
+
|-------|-------------|
|
|
281
|
+
| `id` | Task ID |
|
|
282
|
+
|
|
283
|
+
**Response** — `text/event-stream`
|
|
284
|
+
|
|
285
|
+
The stream sends two SSE event types:
|
|
286
|
+
|
|
287
|
+
**`event: status`** — sent once after history replay, shows current task state:
|
|
288
|
+
```
|
|
289
|
+
event: status
|
|
290
|
+
data: {"taskId":"task_c0ab38d8377cdd47","status":"processing","output":null,"error":null}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**`event: task`** — one per event (both historical and live):
|
|
294
|
+
```
|
|
295
|
+
event: task
|
|
296
|
+
data: {"id":1,"type":"status.change","data":{"from":"pending","to":"processing"},"created_at":"..."}
|
|
297
|
+
|
|
298
|
+
event: task
|
|
299
|
+
data: {"type":"task.event","event":{"type":"tool.start","toolName":"read_file","toolInput":{"path":"package.json"}},"timestamp":1234567890}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
The stream auto-closes when the task reaches a terminal state (`finished`, `failed`, `canceled`). A keepalive comment is sent every 15 seconds to prevent proxy timeouts:
|
|
303
|
+
```
|
|
304
|
+
: keepalive
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Error responses**
|
|
308
|
+
|
|
309
|
+
| Code | Condition |
|
|
310
|
+
|------|-----------|
|
|
311
|
+
| `404 TASK_NOT_FOUND` | No task with that ID |
|
|
312
|
+
|
|
313
|
+
**JavaScript example**
|
|
314
|
+
```js
|
|
315
|
+
const source = new EventSource('http://localhost:5050/tasks/task_c0ab38d8377cdd47/stream');
|
|
316
|
+
|
|
317
|
+
source.addEventListener('status', (e) => {
|
|
318
|
+
const { status, output } = JSON.parse(e.data);
|
|
319
|
+
console.log('Current status:', status);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
source.addEventListener('task', (e) => {
|
|
323
|
+
const ev = JSON.parse(e.data);
|
|
324
|
+
if (ev.type === 'tool.start' || ev.event?.type === 'tool.start') {
|
|
325
|
+
const toolName = ev.data?.toolName || ev.event?.toolName;
|
|
326
|
+
console.log('Tool call:', toolName);
|
|
327
|
+
}
|
|
328
|
+
if (ev.type === 'task.status' && ['finished','failed','canceled'].includes(ev.event?.status)) {
|
|
329
|
+
source.close();
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
source.onerror = () => source.close();
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## POST /tasks/:id/respond
|
|
339
|
+
|
|
340
|
+
Unblock a task that is in `waiting` status. Used when an agent called `task_respond` internally or when the orchestrator needs to feed back data.
|
|
341
|
+
|
|
342
|
+
**Request body**
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"message": "The answer is 42"
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
| Field | Type | Required | Description |
|
|
351
|
+
|-------|------|----------|-------------|
|
|
352
|
+
| `message` | string | ✓ | Message to inject into the agent's context |
|
|
353
|
+
|
|
354
|
+
**Response**
|
|
355
|
+
|
|
356
|
+
```json
|
|
357
|
+
{
|
|
358
|
+
"taskId": "task_c0ab38d8377cdd47",
|
|
359
|
+
"status": "processing"
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Error responses**
|
|
364
|
+
|
|
365
|
+
| Code | Condition |
|
|
366
|
+
|------|-----------|
|
|
367
|
+
| `400 TASK_NOT_WAITING` | Task is not in `waiting` status |
|
|
368
|
+
| `400 VALIDATION_ERROR` | `message` is missing |
|
|
369
|
+
| `404 TASK_NOT_FOUND` | No task with that ID |
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## POST /tasks/:id/cancel
|
|
374
|
+
|
|
375
|
+
Cancel a task. Works for tasks in any non-terminal status. Tasks in `processing` status are cooperatively canceled — the running loop checks the cancel signal between iterations and tool calls, stopping within one cycle.
|
|
376
|
+
|
|
377
|
+
**Request body** — none
|
|
378
|
+
|
|
379
|
+
**Response**
|
|
380
|
+
|
|
381
|
+
```json
|
|
382
|
+
{
|
|
383
|
+
"taskId": "task_c0ab38d8377cdd47",
|
|
384
|
+
"status": "canceled"
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Error responses**
|
|
389
|
+
|
|
390
|
+
| Code | Condition |
|
|
391
|
+
|------|-----------|
|
|
392
|
+
| `400 TASK_ALREADY_TERMINAL` | Task is already in `finished`, `failed`, or `canceled` status |
|
|
393
|
+
| `404 TASK_NOT_FOUND` | No task with that ID |
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## GET /tasks/:id/context
|
|
398
|
+
|
|
399
|
+
Returns the LLM context snapshot from the most recent iteration. Useful for debugging agent behavior.
|
|
400
|
+
|
|
401
|
+
**Response**
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
{
|
|
405
|
+
"taskId": "task_c0ab38d8377cdd47",
|
|
406
|
+
"context": {
|
|
407
|
+
"messages": [
|
|
408
|
+
{ "role": "system", "content": "You are..." },
|
|
409
|
+
{ "role": "user", "content": "Read package.json..." },
|
|
410
|
+
{ "role": "assistant", "content": null, "tool_calls": [...] }
|
|
411
|
+
],
|
|
412
|
+
"tools": ["read_file", "bash", "list_dir"],
|
|
413
|
+
"iteration": 3,
|
|
414
|
+
"timestamp": "2025-03-02T10:00:05.000Z"
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
If the task has not yet made an LLM call, `context` will be `null`.
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Polling Pattern
|
|
424
|
+
|
|
425
|
+
Since tasks are asynchronous, poll `GET /tasks/:id` until status is terminal:
|
|
426
|
+
|
|
427
|
+
```js
|
|
428
|
+
async function pollTask(baseUrl, taskId, timeoutMs = 120000) {
|
|
429
|
+
const deadline = Date.now() + timeoutMs;
|
|
430
|
+
while (Date.now() < deadline) {
|
|
431
|
+
await new Promise(r => setTimeout(r, 1500));
|
|
432
|
+
const res = await fetch(`${baseUrl}/tasks/${taskId}`);
|
|
433
|
+
const { task } = await res.json();
|
|
434
|
+
if (['finished', 'failed', 'canceled', 'waiting'].includes(task.status)) {
|
|
435
|
+
return task;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
throw new Error('Task timed out');
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Usage
|
|
442
|
+
const { taskId } = await fetch('http://localhost:5050/agents/assistant/task', {
|
|
443
|
+
method: 'POST',
|
|
444
|
+
headers: { 'Content-Type': 'application/json' },
|
|
445
|
+
body: JSON.stringify({ input: 'Summarise README.md' }),
|
|
446
|
+
}).then(r => r.json());
|
|
447
|
+
|
|
448
|
+
const task = await pollTask('http://localhost:5050', taskId);
|
|
449
|
+
console.log(task.output);
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Live Tool Event Streaming
|
|
455
|
+
|
|
456
|
+
While polling, also fetch events to see what tools the agent is using in real time:
|
|
457
|
+
|
|
458
|
+
```js
|
|
459
|
+
let seenIds = new Set();
|
|
460
|
+
|
|
461
|
+
async function checkEvents(baseUrl, taskId) {
|
|
462
|
+
const { events } = await fetch(`${baseUrl}/tasks/${taskId}/events`).then(r => r.json());
|
|
463
|
+
for (const ev of events) {
|
|
464
|
+
if (seenIds.has(ev.id)) continue;
|
|
465
|
+
seenIds.add(ev.id);
|
|
466
|
+
if (ev.type === 'tool.start') console.log(`🔧 ${ev.data.toolName}`);
|
|
467
|
+
if (ev.type === 'tool.end') console.log(` ✓ ${ev.data.durationMs}ms`);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
```
|