@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.
Files changed (199) hide show
  1. package/.veil/agents/analyst/AGENT.md +21 -0
  2. package/.veil/agents/analyst/agent.json +23 -0
  3. package/.veil/agents/assistant/AGENT.md +15 -0
  4. package/.veil/agents/assistant/agent.json +19 -0
  5. package/.veil/agents/coder/AGENT.md +18 -0
  6. package/.veil/agents/coder/agent.json +19 -0
  7. package/.veil/agents/hello/AGENT.md +5 -0
  8. package/.veil/agents/hello/agent.json +13 -0
  9. package/.veil/agents/writer/AGENT.md +12 -0
  10. package/.veil/agents/writer/agent.json +17 -0
  11. package/.veil/memory/MEMORY.md +343 -0
  12. package/.veil/memory/agents/analyst/MEMORY.md +55 -0
  13. package/.veil/memory/agents/hello/MEMORY.md +12 -0
  14. package/.veil/runtime.pid +1 -0
  15. package/.veil/settings.json +10 -0
  16. package/.veil-studio/studio.db +0 -0
  17. package/.veil-studio/studio.db-shm +0 -0
  18. package/.veil-studio/studio.db-wal +0 -0
  19. package/PLAN/01-vision.md +26 -0
  20. package/PLAN/02-tech-stack.md +94 -0
  21. package/PLAN/03-agents.md +232 -0
  22. package/PLAN/04-runtime.md +171 -0
  23. package/PLAN/05-tools.md +211 -0
  24. package/PLAN/06-communication.md +243 -0
  25. package/PLAN/07-storage.md +218 -0
  26. package/PLAN/08-api-cli.md +153 -0
  27. package/PLAN/09-permissions.md +108 -0
  28. package/PLAN/10-ably.md +105 -0
  29. package/PLAN/11-file-formats.md +442 -0
  30. package/PLAN/12-folder-structure.md +205 -0
  31. package/PLAN/13-operations.md +212 -0
  32. package/PLAN/README.md +23 -0
  33. package/README.md +128 -0
  34. package/REPORT.md +174 -0
  35. package/TODO.md +45 -0
  36. package/ai-tests/FRONTEND_PROMPT.md +220 -0
  37. package/ai-tests/Research & Planning.md +814 -0
  38. package/ai-tests/prompt-001-basic-api.md +230 -0
  39. package/ai-tests/prompt-002-basic-flows.md +230 -0
  40. package/ai-tests/prompt-003-agent-behaviors.md +220 -0
  41. package/api/middleware.js +60 -0
  42. package/api/routes/agents.js +193 -0
  43. package/api/routes/chat.js +93 -0
  44. package/api/routes/completions.js +122 -0
  45. package/api/routes/daemons.js +80 -0
  46. package/api/routes/memory.js +169 -0
  47. package/api/routes/models.js +40 -0
  48. package/api/routes/remote-methods.js +74 -0
  49. package/api/routes/sessions.js +208 -0
  50. package/api/routes/settings.js +108 -0
  51. package/api/routes/system.js +50 -0
  52. package/api/routes/tasks.js +270 -0
  53. package/api/server.js +120 -0
  54. package/cli/formatter.js +70 -0
  55. package/cli/index.js +443 -0
  56. package/cli/parser.js +113 -0
  57. package/config/config.json +10 -0
  58. package/config/models.json +6826 -0
  59. package/core/agent.js +329 -0
  60. package/core/cancel.js +38 -0
  61. package/core/compaction.js +176 -0
  62. package/core/events.js +13 -0
  63. package/core/loop.js +564 -0
  64. package/core/memory.js +51 -0
  65. package/core/prompt.js +185 -0
  66. package/core/queue.js +96 -0
  67. package/core/registry.js +291 -0
  68. package/core/remote-methods.js +124 -0
  69. package/core/router.js +386 -0
  70. package/core/running-sessions.js +18 -0
  71. package/docs/api/01-system.md +84 -0
  72. package/docs/api/02-agents.md +374 -0
  73. package/docs/api/03-chat.md +269 -0
  74. package/docs/api/04-tasks.md +470 -0
  75. package/docs/api/05-sessions.md +444 -0
  76. package/docs/api/06-daemons.md +142 -0
  77. package/docs/api/07-memory.md +186 -0
  78. package/docs/api/08-settings.md +133 -0
  79. package/docs/api/09-models.md +119 -0
  80. package/docs/api/09-websocket.md +350 -0
  81. package/docs/api/10-completions.md +134 -0
  82. package/docs/api/README.md +116 -0
  83. package/docs/guide/01-quickstart.md +220 -0
  84. package/docs/guide/02-folder-structure.md +185 -0
  85. package/docs/guide/03-configuration.md +252 -0
  86. package/docs/guide/04-agents.md +267 -0
  87. package/docs/guide/05-cli.md +290 -0
  88. package/docs/guide/06-tools.md +643 -0
  89. package/docs/guide/07-permissions.md +236 -0
  90. package/docs/guide/08-memory.md +139 -0
  91. package/docs/guide/09-multi-agent.md +271 -0
  92. package/docs/guide/10-daemons.md +226 -0
  93. package/docs/guide/README.md +53 -0
  94. package/docs/index.html +623 -0
  95. package/examples/README.md +151 -0
  96. package/examples/agents/assistant/AGENT.md +31 -0
  97. package/examples/agents/assistant/SOUL.md +9 -0
  98. package/examples/agents/assistant/agent.json +74 -0
  99. package/examples/agents/hello/AGENT.md +15 -0
  100. package/examples/agents/hello/agent.json +14 -0
  101. package/examples/agents/monitor/AGENT.md +51 -0
  102. package/examples/agents/monitor/agent.json +33 -0
  103. package/examples/agents/monitor/heartbeats/monitor.md +24 -0
  104. package/examples/agents/orchestrator/AGENT.md +70 -0
  105. package/examples/agents/orchestrator/agent.json +30 -0
  106. package/examples/agents/researcher/AGENT.md +52 -0
  107. package/examples/agents/researcher/agent.json +49 -0
  108. package/examples/agents/researcher/skills/web-research.md +28 -0
  109. package/examples/skills/code-review.md +72 -0
  110. package/examples/skills/summarise.md +59 -0
  111. package/examples/skills/web-research.md +42 -0
  112. package/examples/tools/word-count/index.js +27 -0
  113. package/examples/tools/word-count/tool.json +18 -0
  114. package/infrastructure/database.js +563 -0
  115. package/infrastructure/scheduler.js +122 -0
  116. package/llm/client.js +206 -0
  117. package/migrations/001-initial.sql +121 -0
  118. package/migrations/002-debuggability.sql +13 -0
  119. package/migrations/003-drop-orphaned-columns.sql +72 -0
  120. package/migrations/004-session-message-token-fields.sql +78 -0
  121. package/migrations/005-session-thinking.sql +5 -0
  122. package/package.json +30 -0
  123. package/schemas/agent.json +143 -0
  124. package/schemas/settings.json +111 -0
  125. package/scripts/fetch-models.js +93 -0
  126. package/session-debug-scenario.md +248 -0
  127. package/settings/fields.js +52 -0
  128. package/system-prompts/base-core.md +7 -0
  129. package/system-prompts/environment.md +13 -0
  130. package/system-prompts/reminders/anti-drift.md +6 -0
  131. package/system-prompts/reminders/stall-recovery.md +10 -0
  132. package/system-prompts/safety-rules.md +25 -0
  133. package/system-prompts/task-heuristics.md +27 -0
  134. package/test/client.js +71 -0
  135. package/test/integration/01-health.test.js +25 -0
  136. package/test/integration/02-agents.test.js +80 -0
  137. package/test/integration/03-chat-hello.test.js +48 -0
  138. package/test/integration/04-chat-multiturn.test.js +61 -0
  139. package/test/integration/05-chat-writer.test.js +48 -0
  140. package/test/integration/06-task-basic.test.js +68 -0
  141. package/test/integration/07-task-tools.test.js +74 -0
  142. package/test/integration/08-task-code-analysis.test.js +69 -0
  143. package/test/integration/09-memory-analyst.test.js +63 -0
  144. package/test/integration/10-task-advanced.test.js +85 -0
  145. package/test/integration/11-sessions-advanced.test.js +84 -0
  146. package/test/integration/12-assistant-chat-tools.test.js +75 -0
  147. package/test/integration/13-edge-cases.test.js +99 -0
  148. package/test/integration/14-cancel.test.js +62 -0
  149. package/test/integration/15-debug.test.js +106 -0
  150. package/test/integration/16-memory-api.test.js +83 -0
  151. package/test/integration/17-settings-api.test.js +41 -0
  152. package/test/integration/18-tool-search-activation.test.js +119 -0
  153. package/test/results/.gitkeep +0 -0
  154. package/test/runner.js +206 -0
  155. package/test/smoke.js +216 -0
  156. package/tools/agent_message.js +85 -0
  157. package/tools/agent_send.js +80 -0
  158. package/tools/agent_spawn.js +44 -0
  159. package/tools/bash.js +49 -0
  160. package/tools/edit_file.js +41 -0
  161. package/tools/glob.js +64 -0
  162. package/tools/grep.js +82 -0
  163. package/tools/list_dir.js +63 -0
  164. package/tools/log_write.js +31 -0
  165. package/tools/memory_read.js +38 -0
  166. package/tools/memory_search.js +65 -0
  167. package/tools/memory_write.js +42 -0
  168. package/tools/read_file.js +48 -0
  169. package/tools/sleep.js +22 -0
  170. package/tools/task_create.js +41 -0
  171. package/tools/task_respond.js +37 -0
  172. package/tools/task_spawn.js +64 -0
  173. package/tools/task_status.js +39 -0
  174. package/tools/task_subscribe.js +37 -0
  175. package/tools/todo_read.js +26 -0
  176. package/tools/todo_write.js +38 -0
  177. package/tools/tool_activate.js +24 -0
  178. package/tools/tool_search.js +24 -0
  179. package/tools/web_fetch.js +50 -0
  180. package/tools/web_search.js +52 -0
  181. package/tools/write_file.js +28 -0
  182. package/ui/api.js +190 -0
  183. package/ui/app.js +281 -0
  184. package/ui/index.html +382 -0
  185. package/ui/views/agents.js +377 -0
  186. package/ui/views/chat.js +610 -0
  187. package/ui/views/connection.js +96 -0
  188. package/ui/views/daemons.js +129 -0
  189. package/ui/views/feed.js +194 -0
  190. package/ui/views/memory.js +263 -0
  191. package/ui/views/models.js +146 -0
  192. package/ui/views/sessions.js +314 -0
  193. package/ui/views/settings.js +142 -0
  194. package/ui/views/tasks.js +415 -0
  195. package/utils/context.js +49 -0
  196. package/utils/id.js +16 -0
  197. package/utils/models.js +88 -0
  198. package/utils/paths.js +213 -0
  199. 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
+ ```