@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,186 @@
1
+ # Memory API
2
+
3
+ Read, write, and delete agent and global memory files via HTTP.
4
+
5
+ Memory files are plain Markdown stored under `.veil/memory/`. They are injected into the agent's system prompt at session start.
6
+
7
+ ---
8
+
9
+ ## Agent Memory
10
+
11
+ ### `GET /agents/:name/memory`
12
+
13
+ List all memory files for an agent.
14
+
15
+ ```bash
16
+ curl http://localhost:5050/agents/assistant/memory
17
+ ```
18
+
19
+ **Response:**
20
+ ```json
21
+ {
22
+ "agentName": "assistant",
23
+ "files": [
24
+ { "name": "MEMORY.md", "size": 1240, "modified": "2025-03-04T12:00:00.000Z" }
25
+ ]
26
+ }
27
+ ```
28
+
29
+ ---
30
+
31
+ ### `GET /agents/:name/memory/:file`
32
+
33
+ Read a specific memory file.
34
+
35
+ ```bash
36
+ curl http://localhost:5050/agents/assistant/memory/MEMORY.md
37
+ ```
38
+
39
+ **Response:**
40
+ ```json
41
+ {
42
+ "agentName": "assistant",
43
+ "file": "MEMORY.md",
44
+ "content": "## Notes\n\nProject uses port 5050."
45
+ }
46
+ ```
47
+
48
+ **Errors:** `404 NOT_FOUND` if file does not exist.
49
+
50
+ ---
51
+
52
+ ### `PUT /agents/:name/memory/:file`
53
+
54
+ Write or replace a memory file. Creates the file if it does not exist.
55
+
56
+ ```bash
57
+ curl -X PUT http://localhost:5050/agents/assistant/memory/MEMORY.md \
58
+ -H "Content-Type: application/json" \
59
+ -d '{"content": "## Project Notes\n\nThis project uses port 5050."}'
60
+ ```
61
+
62
+ **Request body:**
63
+ | Field | Type | Required | Description |
64
+ |-------|------|----------|-------------|
65
+ | `content` | string | ✓ | Full Markdown content to write |
66
+
67
+ **Response:**
68
+ ```json
69
+ {
70
+ "agentName": "assistant",
71
+ "file": "MEMORY.md",
72
+ "size": 47
73
+ }
74
+ ```
75
+
76
+ **Errors:** `400 VALIDATION_ERROR` if `content` is not a string or filename is invalid.
77
+
78
+ ---
79
+
80
+ ### `DELETE /agents/:name/memory/:file`
81
+
82
+ Delete a memory file.
83
+
84
+ ```bash
85
+ curl -X DELETE http://localhost:5050/agents/assistant/memory/MEMORY.md
86
+ ```
87
+
88
+ **Response:**
89
+ ```json
90
+ { "agentName": "assistant", "file": "MEMORY.md", "status": "deleted" }
91
+ ```
92
+
93
+ **Errors:** `404 NOT_FOUND` if file does not exist.
94
+
95
+ ---
96
+
97
+ ---
98
+
99
+ ## Global Memory
100
+
101
+ Global memory files are shared across all agents. Stored at `.veil/memory/`.
102
+
103
+ ### `GET /memory`
104
+
105
+ List all global memory files.
106
+
107
+ ```bash
108
+ curl http://localhost:5050/memory
109
+ ```
110
+
111
+ **Response:**
112
+ ```json
113
+ {
114
+ "files": [
115
+ { "name": "MEMORY.md", "size": 512, "modified": "2025-03-04T12:00:00.000Z" }
116
+ ]
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ### `GET /memory/:file`
123
+
124
+ Read a global memory file.
125
+
126
+ ```bash
127
+ curl http://localhost:5050/memory/MEMORY.md
128
+ ```
129
+
130
+ **Response:**
131
+ ```json
132
+ {
133
+ "file": "MEMORY.md",
134
+ "content": "## Global Notes\n\nShared across all agents."
135
+ }
136
+ ```
137
+
138
+ ---
139
+
140
+ ### `PUT /memory/:file`
141
+
142
+ Write or replace a global memory file.
143
+
144
+ ```bash
145
+ curl -X PUT http://localhost:5050/memory/MEMORY.md \
146
+ -H "Content-Type: application/json" \
147
+ -d '{"content": "## Global Notes\n\nUpdated content."}'
148
+ ```
149
+
150
+ **Response:**
151
+ ```json
152
+ {
153
+ "file": "MEMORY.md",
154
+ "size": 35
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ### `DELETE /memory/:file`
161
+
162
+ Delete a global memory file.
163
+
164
+ ```bash
165
+ curl -X DELETE http://localhost:5050/memory/MEMORY.md
166
+ ```
167
+
168
+ **Response:**
169
+ ```json
170
+ { "file": "MEMORY.md", "status": "deleted" }
171
+ ```
172
+
173
+ ---
174
+
175
+ ## File Name Rules
176
+
177
+ Memory file names must match the pattern `[a-z0-9A-Z_-]+.md`. Path traversal (`../`) is rejected with `400 VALIDATION_ERROR`.
178
+
179
+ ---
180
+
181
+ ## Notes
182
+
183
+ - Agent-scoped files: `.veil/memory/agents/<name>/<file>`
184
+ - Global files: `.veil/memory/<file>`
185
+ - Changes take effect on the **next session** — currently running sessions are not affected.
186
+ - To seed an agent's memory before first run, use this API to write a `MEMORY.md` file.
@@ -0,0 +1,133 @@
1
+ # Settings API
2
+
3
+ Read and live-update workspace configuration via HTTP. No server restart required.
4
+
5
+ ---
6
+
7
+ ## `GET /settings`
8
+
9
+ Returns settings for the workspace. API keys are **redacted** (shown as `sk-…xxxx`).
10
+
11
+ **Query parameters**
12
+
13
+ | Param | Type | Description |
14
+ |-------|------|-------------|
15
+ | `level` | string | Which layer to read. Default: `merged` |
16
+
17
+ **Level values**
18
+
19
+ | Value | Source file | Description |
20
+ |-------|-------------|-------------|
21
+ | `merged` | *(all layers)* | Full effective settings — defaults → global → project → local merged. **(default)** |
22
+ | `project` | `.veil/settings.json` | Project-level overrides only |
23
+ | `global` | `~/.veil/settings.json` | User-level global overrides only |
24
+ | `local` | `.veil/settings.local.json` | Local machine overrides only (gitignored) |
25
+
26
+ **Response**
27
+ ```json
28
+ {
29
+ "level": "merged",
30
+ "exists": true,
31
+ "path": null,
32
+ "settings": {
33
+ "port": 5050,
34
+ "models": {
35
+ "main": {
36
+ "base_url": "https://openrouter.ai/api/v1",
37
+ "api_key": "sk-…1234",
38
+ "model": "anthropic/claude-sonnet-4-5"
39
+ }
40
+ },
41
+ "permissions": { "allow": [], "deny": [], "ask": [] },
42
+ "memory": { "enabled": true, "maxLines": 500 },
43
+ "maxIterations": 20,
44
+ "maxDurationSeconds": 300
45
+ }
46
+ }
47
+ ```
48
+
49
+ | Field | Description |
50
+ |-------|-------------|
51
+ | `level` | The level that was read |
52
+ | `exists` | Whether the settings file exists on disk (`false` for `merged` is never returned) |
53
+ | `path` | Absolute path to the file (`null` for `merged`) |
54
+ | `settings` | The settings object (raw file contents for non-merged levels; `{}` if file absent) |
55
+
56
+ **Examples**
57
+ ```bash
58
+ # Full merged settings (default)
59
+ curl http://localhost:5050/settings
60
+
61
+ # Only what's in .veil/settings.json
62
+ curl http://localhost:5050/settings?level=project
63
+
64
+ # Only what's in ~/.veil/settings.json
65
+ curl http://localhost:5050/settings?level=global
66
+ ```
67
+
68
+ **Error responses**
69
+
70
+ | Code | Condition |
71
+ |------|-----------|
72
+ | `400 INVALID_LEVEL` | `level` is not one of the valid values |
73
+
74
+ ---
75
+
76
+ ## `PUT /settings`
77
+
78
+ Validate and write settings to the specified level file. Immediately live-reloads merged settings — all subsequent requests use the new effective values.
79
+
80
+ **Query parameters**
81
+
82
+ | Param | Type | Description |
83
+ |-------|------|-------------|
84
+ | `level` | string | Which file to write. Default: `project`. `merged` is not writable. |
85
+
86
+ | Value | Writes to |
87
+ |-------|----------|
88
+ | `project` | `.veil/settings.json` **(default)** |
89
+ | `global` | `~/.veil/settings.json` |
90
+ | `local` | `.veil/settings.local.json` |
91
+
92
+ **Request body:** A valid settings object (see [Configuration guide](../guide/03-configuration.md)). Validated against the settings schema before writing.
93
+
94
+ **Response**
95
+ ```json
96
+ {
97
+ "status": "updated",
98
+ "level": "project",
99
+ "path": "/home/user/workspace/.veil/settings.json",
100
+ "settings": { ... }
101
+ }
102
+ ```
103
+
104
+ `settings` in the response is the full **merged** effective settings after the write.
105
+
106
+ **Examples**
107
+ ```bash
108
+ # Write to project settings (default)
109
+ curl -X PUT http://localhost:5050/settings \
110
+ -H "Content-Type: application/json" \
111
+ -d '{"maxIterations": 30, "memory": {"enabled": true}}'
112
+
113
+ # Write to global settings
114
+ curl -X PUT "http://localhost:5050/settings?level=global" \
115
+ -H "Content-Type: application/json" \
116
+ -d '{"models": {"main": {"model": "anthropic/claude-sonnet-4-5"}}}'
117
+ ```
118
+
119
+ **Error responses**
120
+
121
+ | Code | Condition |
122
+ |------|-----------|
123
+ | `400 INVALID_LEVEL` | `level` is `merged` (read-only) or not a valid value |
124
+ | `400 VALIDATION_ERROR` | Body fails schema validation (field-level error messages included) |
125
+
126
+ ---
127
+
128
+ ## Notes
129
+
130
+ - The settings layer stack is: **defaults → global → project → local**. Each layer overrides the previous.
131
+ - Model credentials (`api_key`) must be set via `auth.json` — not via this endpoint.
132
+ - Live reload only affects in-memory settings. Currently running tasks/loops see the old settings until they complete.
133
+ - `PUT` with `?level=local` is useful for machine-specific overrides that should not be committed to version control.
@@ -0,0 +1,119 @@
1
+ # Models
2
+
3
+ The models API exposes the local model index built from OpenRouter's public model catalogue. It is used internally to populate `context_size_limit` on new sessions and to fall back to a calculated cost when the LLM provider does not return a `usage.cost` field in its response.
4
+
5
+ The index is stored in `config/models.json` and loaded once at startup (cached in memory). Refresh it any time with `POST /models/refresh` or `npm run fetch-models`.
6
+
7
+ ---
8
+
9
+ ## GET /models
10
+
11
+ Returns the full model index.
12
+
13
+ **Response**
14
+ ```json
15
+ {
16
+ "updated_at": "2026-03-06T03:00:00.000Z",
17
+ "models": [
18
+ {
19
+ "id": "anthropic/claude-sonnet-4.6",
20
+ "name": "Anthropic: Claude Sonnet 4.6",
21
+ "context_length": 1000000,
22
+ "max_completion_tokens": 128000,
23
+ "pricing": {
24
+ "prompt": 0.000003,
25
+ "completion": 0.000015,
26
+ "cache_read": 0.0000003,
27
+ "cache_write": 0.00000375
28
+ },
29
+ "input_modalities": ["text", "image"],
30
+ "output_modalities": ["text"]
31
+ }
32
+ ]
33
+ }
34
+ ```
35
+
36
+ **Model object fields**
37
+
38
+ | Field | Type | Description |
39
+ |-------|------|-------------|
40
+ | `id` | string | OpenRouter model identifier (e.g. `anthropic/claude-sonnet-4.6`) |
41
+ | `name` | string | Human-readable display name |
42
+ | `context_length` | integer\|null | Context window size in tokens |
43
+ | `max_completion_tokens` | integer\|null | Maximum output tokens the provider allows |
44
+ | `pricing.prompt` | number | Price per input token in USD |
45
+ | `pricing.completion` | number | Price per output token in USD |
46
+ | `pricing.cache_read` | number | Price per cached input token (0 if not applicable) |
47
+ | `pricing.cache_write` | number | Price per cache-write token (0 if not applicable) |
48
+ | `input_modalities` | string[] | Supported input types (e.g. `["text", "image"]`) |
49
+ | `output_modalities` | string[] | Supported output types |
50
+
51
+ **Example**
52
+ ```bash
53
+ curl http://localhost:5050/models
54
+ ```
55
+
56
+ ---
57
+
58
+ ## GET /models/:provider/:name
59
+
60
+ Get a single model by its two-part ID.
61
+
62
+ **Path parameters**
63
+
64
+ | Param | Description |
65
+ |-------|-------------|
66
+ | `provider` | Provider slug, e.g. `anthropic` |
67
+ | `name` | Model slug, e.g. `claude-sonnet-4.6` |
68
+
69
+ **Response** — same shape as a single entry from `GET /models`
70
+
71
+ **Error responses**
72
+
73
+ | Code | Condition |
74
+ |------|-----------|
75
+ | `404 MODEL_NOT_FOUND` | Model ID not in the local index |
76
+
77
+ **Example**
78
+ ```bash
79
+ curl http://localhost:5050/models/anthropic/claude-sonnet-4.6
80
+ ```
81
+
82
+ ---
83
+
84
+ ## POST /models/refresh
85
+
86
+ Re-fetch the full model list from OpenRouter and reload the in-memory cache.
87
+
88
+ Internally runs `scripts/fetch-models.js`, which writes the result to `config/models.json`.
89
+
90
+ **Response**
91
+ ```json
92
+ {
93
+ "refreshed": true,
94
+ "updated_at": "2026-03-06T03:15:22.000Z",
95
+ "models": [ ... ]
96
+ }
97
+ ```
98
+
99
+ **Example**
100
+ ```bash
101
+ curl -X POST http://localhost:5050/models/refresh
102
+ ```
103
+
104
+ ---
105
+
106
+ ## CLI Shortcut
107
+
108
+ ```bash
109
+ npm run fetch-models
110
+ ```
111
+
112
+ Runs the same fetch script directly, without starting the server.
113
+
114
+ ---
115
+
116
+ ## Internal Usage
117
+
118
+ - **`context_size_limit` on sessions** — when a new session is created (`POST /sessions` or first chat turn), `createSession` looks up the model in the index and stores its `context_length` as `context_size_limit` on the session row.
119
+ - **Cost fallback in the loop** — after each LLM turn, if the API response does not include a `usage.cost` field (or returns `0`), the loop calculates an estimated cost using `pricing.prompt`, `pricing.completion`, and `pricing.cache_read` from the index.