scout-ai 1.2.5 → 2.0.0

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 (164) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +111 -31
  3. data/README.md +171 -320
  4. data/Rakefile +17 -1
  5. data/VERSION +1 -1
  6. data/doc/Improvements.md +325 -0
  7. data/doc/StartHere.md +110 -0
  8. data/doc/developer/Architecture.md +126 -0
  9. data/doc/developer/Backends.md +199 -0
  10. data/doc/developer/ChatLifecycle.md +183 -0
  11. data/doc/developer/DelegationInternals.md +295 -0
  12. data/doc/developer/DesignPrinciples.md +245 -0
  13. data/doc/developer/PromptProcessing.md +292 -0
  14. data/doc/developer/Provenance.md +317 -0
  15. data/doc/user/BuildingAgents.md +345 -0
  16. data/doc/user/Cookbook.md +333 -0
  17. data/doc/user/CoreConcepts.md +181 -0
  18. data/doc/user/Delegation.md +191 -0
  19. data/doc/user/GettingStarted.md +159 -0
  20. data/doc/user/ManagingContext.md +163 -0
  21. data/doc/user/MultiAgentWorkflows.md +256 -0
  22. data/doc/user/Python.md +159 -0
  23. data/doc/user/RunningInference.md +200 -0
  24. data/doc/user/ToolCalling.md +193 -0
  25. data/doc/user/WritingChats.md +197 -0
  26. data/lib/scout/llm/agent/chat.rb +62 -12
  27. data/lib/scout/llm/agent/delegate.rb +274 -65
  28. data/lib/scout/llm/agent/iterate.rb +2 -2
  29. data/lib/scout/llm/agent/save.rb +273 -0
  30. data/lib/scout/llm/agent/workflow.rb +164 -0
  31. data/lib/scout/llm/agent.rb +86 -61
  32. data/lib/scout/llm/ask.rb +36 -6
  33. data/lib/scout/llm/backends/anthropic.rb +9 -1
  34. data/lib/scout/llm/backends/bedrock.rb +15 -3
  35. data/lib/scout/llm/backends/default.rb +129 -89
  36. data/lib/scout/llm/backends/glm.rb +58 -0
  37. data/lib/scout/llm/backends/huggingface.rb +13 -1
  38. data/lib/scout/llm/backends/ollama.rb +13 -0
  39. data/lib/scout/llm/backends/openwebui.rb +8 -3
  40. data/lib/scout/llm/chat/agent_meta.rb +264 -0
  41. data/lib/scout/llm/chat/annotation.rb +37 -14
  42. data/lib/scout/llm/chat/parse.rb +28 -6
  43. data/lib/scout/llm/chat/persist.rb +25 -0
  44. data/lib/scout/llm/chat/process/clear.rb +19 -1
  45. data/lib/scout/llm/chat/process/files.rb +16 -1
  46. data/lib/scout/llm/chat/process/meta.rb +422 -32
  47. data/lib/scout/llm/chat/process/options.rb +21 -1
  48. data/lib/scout/llm/chat/process/tools.rb +49 -12
  49. data/lib/scout/llm/chat/process.rb +4 -0
  50. data/lib/scout/llm/chat/prompt/shorten_tools.rb +125 -0
  51. data/lib/scout/llm/chat/prompt/shorten_tools_epoch.rb +365 -0
  52. data/lib/scout/llm/chat/prompt.rb +48 -0
  53. data/lib/scout/llm/chat/provenance.rb +775 -0
  54. data/lib/scout/llm/chat/tool_calls.rb +76 -0
  55. data/lib/scout/llm/chat.rb +18 -2
  56. data/lib/scout/llm/embed.rb +8 -3
  57. data/lib/scout/llm/image.rb +86 -0
  58. data/lib/scout/llm/rag.rb +3 -3
  59. data/lib/scout/llm/tools/call.rb +159 -10
  60. data/lib/scout/llm/tools/knowledge_base.rb +1 -1
  61. data/lib/scout/llm/tools/workflow.rb +13 -5
  62. data/lib/scout-ai.rb +1 -0
  63. data/research/ChatAnalyst-required-changes.md +167 -0
  64. data/research/agent-delegation-analysis.md +810 -0
  65. data/research/agent-meta-provenance-integration-plan.md +622 -0
  66. data/research/agent-workflow-analysis.md +1120 -0
  67. data/research/backends-analysis.md +836 -0
  68. data/research/chat-core-analysis.md +946 -0
  69. data/research/chatanalyst-provenance/00-baseline.md +30 -0
  70. data/research/chatanalyst-provenance/01-repo-map.md +60 -0
  71. data/research/chatanalyst-provenance/02-event-reconstruction.md +55 -0
  72. data/research/chatanalyst-provenance/03-duplication-evidence.md +45 -0
  73. data/research/chatanalyst-provenance/04-tooling-root-cause.md +57 -0
  74. data/research/chatanalyst-provenance/05-fix-plan.md +46 -0
  75. data/research/chatanalyst-provenance/07-critic-review.md +25 -0
  76. data/research/chatanalyst-provenance/final-report.md +45 -0
  77. data/research/chatanalyst-provenance/resumption.md +37 -0
  78. data/research/coding-philosophy-analysis.md +928 -0
  79. data/research/commands-analysis.md +947 -0
  80. data/research/multi-agent-patterns-analysis.md +853 -0
  81. data/research/prompt-strategies-analysis.md +630 -0
  82. data/research/prov-verbosity-fix-notes.md +77 -0
  83. data/research/provenance-analysis.md +469 -0
  84. data/research/provenance-navigation-design.md +640 -0
  85. data/research/synthesis-report.md +487 -0
  86. data/research/tools-system-analysis.md +779 -0
  87. data/scout-ai.gemspec +97 -13
  88. data/scout_commands/agent/ask +13 -3
  89. data/scout_commands/agent/kb +2 -0
  90. data/scout_commands/llm/ask +11 -4
  91. data/scout_commands/llm/md +76 -0
  92. data/scout_commands/llm/prov +602 -0
  93. data/scout_commands/llm/word +71 -0
  94. data/share/word/reference.docx +0 -0
  95. data/test/etc/AI/mock.yaml +11 -0
  96. data/test/fixtures/backends/anthropic.json +19 -0
  97. data/test/fixtures/backends/anthropic_tool_use.json +24 -0
  98. data/test/fixtures/backends/bedrock.json +8 -0
  99. data/test/fixtures/backends/bedrock_embedding.json +3 -0
  100. data/test/fixtures/backends/bedrock_tool_use.json +17 -0
  101. data/test/fixtures/backends/ollama.json +16 -0
  102. data/test/fixtures/backends/ollama_tool_call.json +27 -0
  103. data/test/fixtures/backends/openai_chat.json +21 -0
  104. data/test/fixtures/backends/openai_chat_tool_call.json +31 -0
  105. data/test/fixtures/backends/responses.json +33 -0
  106. data/test/fixtures/backends/responses_tool_call.json +28 -0
  107. data/test/integration/README.md +32 -0
  108. data/test/integration/scout/llm/backends/test_endpoints.rb +34 -0
  109. data/test/integration/scout/llm/backends/test_openwebui.rb +61 -0
  110. data/test/integration/scout/llm/backends/test_relay.rb +52 -0
  111. data/test/integration/scout/llm/test_infrastructure.rb +74 -0
  112. data/test/{scout → integration/scout}/llm/test_mcp.rb +1 -1
  113. data/test/integration/scout/llm/tools/test_mcp.rb +42 -0
  114. data/test/integration/scout/model/test_base.rb +91 -0
  115. data/test/scout/llm/agent/test_chat.rb +8 -2
  116. data/test/scout/llm/agent/test_save.rb +413 -0
  117. data/test/scout/llm/agent/test_workflow.rb +110 -0
  118. data/test/scout/llm/backends/test_anthropic.rb +93 -10
  119. data/test/scout/llm/backends/test_bedrock.rb +118 -2
  120. data/test/scout/llm/backends/test_ollama.rb +70 -20
  121. data/test/scout/llm/backends/test_openwebui.rb +42 -40
  122. data/test/scout/llm/backends/test_relay.rb +4 -2
  123. data/test/scout/llm/chat/agent_meta_fixtures.rb +131 -0
  124. data/test/scout/llm/chat/process/test_meta.rb +518 -0
  125. data/test/scout/llm/chat/process/test_normalize_usage.rb +183 -0
  126. data/test/scout/llm/chat/test_agent_meta.rb +357 -0
  127. data/test/scout/llm/chat/test_agent_meta_provenance.rb +467 -0
  128. data/test/scout/llm/chat/test_agent_meta_tokens.rb +594 -0
  129. data/test/scout/llm/chat/test_parse.rb +70 -15
  130. data/test/scout/llm/chat/test_prov_cli.rb +274 -0
  131. data/test/scout/llm/chat/test_provenance.rb +240 -0
  132. data/test/scout/llm/chat/test_tool_calls.rb +38 -0
  133. data/test/scout/llm/test_agent.rb +13 -36
  134. data/test/scout/llm/test_ask.rb +75 -52
  135. data/test/scout/llm/test_chat.rb +107 -13
  136. data/test/scout/llm/test_embed.rb +48 -0
  137. data/test/scout/llm/test_rag.rb +23 -16
  138. data/test/scout/llm/test_tools.rb +12 -1
  139. data/test/scout/llm/tools/test_knowledge_base.rb +0 -1
  140. data/test/scout/llm/tools/test_mcp.rb +5 -3
  141. data/test/scout/llm/tools/test_workflow.rb +23 -2
  142. data/test/scout/model/python/huggingface/causal/test_next_token.rb +11 -5
  143. data/test/scout/model/python/huggingface/test_causal.rb +9 -3
  144. data/test/scout/model/python/huggingface/test_classification.rb +11 -2
  145. data/test/scout/model/python/test_torch.rb +2 -0
  146. data/test/scout/model/python/torch/test_helpers.rb +4 -0
  147. data/test/scout/model/test_base.rb +4 -2
  148. data/test/support/availability.rb +231 -0
  149. data/test/support/fake_clients.rb +138 -0
  150. data/test/support/fixtures.rb +21 -0
  151. data/test/support/infrastructure_probes.rb +136 -0
  152. data/test/support/mock_backend.rb +215 -0
  153. data/test/test_helper.rb +32 -2
  154. metadata +96 -12
  155. data/doc/Agent.md +0 -354
  156. data/doc/Chat.md +0 -481
  157. data/doc/LLM.md +0 -356
  158. data/doc/PythonAgentTasks.md +0 -333
  159. data/doc/RAG.md +0 -129
  160. data/doc/USER_GUIDE.md +0 -572
  161. data/scout_commands/documenter +0 -148
  162. data/test/scout/llm/backends/test_openai.rb +0 -192
  163. data/test/scout/llm/backends/test_responses.rb +0 -238
  164. data/test/scout/llm/test_parse.rb +0 -98
data/doc/Chat.md DELETED
@@ -1,481 +0,0 @@
1
- # Chat
2
-
3
- `Chat` is Scout-AI’s conversation format.
4
-
5
- It serves two related purposes:
6
-
7
- 1) **An on-disk “chat file” format** (human editable) where each message is written as:
8
-
9
- ```text
10
- role:
11
-
12
- ...content...
13
- ```
14
-
15
- 2) **A Ruby builder** over an `Array` of `{role:, content:}` hashes.
16
-
17
- The important nuance: a chat is not just prompts. In addition to `user/system/assistant`, Scout-AI supports “control” roles that are interpreted by `LLM.chat` **before** the model is queried:
18
-
19
- - imports (`import`, `continue`, `last`)
20
- - files (`file`, `directory`, `image`, `pdf`)
21
- - workflow integration (`tool`, `task`, `inline_task`, `job`, `inline_job`)
22
- - knowledge base integration (`association`, `kb`)
23
- - MCP tool integration (`mcp`)
24
- - options (`endpoint`, `backend`, `model`, `format`, `persist`, `previous_response_id`, `option`, `sticky_option`)
25
- - conversation maintenance (`clear`, `skip`, `clear_tools`, `clear_associations`)
26
-
27
- This document is the reference for **all chat roles and options**, and how they behave.
28
-
29
- Related docs:
30
-
31
- - `USER_GUIDE.md` — first practical guide to chats, agents, workflows, and multi-agent patterns
32
- - `../python/README.md` — Python SDK for `Chat` and `Agent` wrappers
33
- - `doc/LLM.md` — how `LLM.ask` expands/executes chats and calls backends
34
- - `doc/Agent.md` — stateful agents and programmatic control loops
35
-
36
- ---
37
-
38
- ## 0. Mental model
39
-
40
- A chat file is best understood as two things at once:
41
-
42
- - a persistent conversation record
43
- - a declarative control surface for tools, files, jobs, and options
44
-
45
- The roles fall into a few families:
46
-
47
- - conversation: `system`, `user`, `assistant`
48
- - composition: `import`, `continue`, `last`
49
- - attached context: `file`, `directory`, `image`, `pdf`
50
- - executable toolkits: `introduce`, `tool`, `task`, `exec_task`, `job`, `inline_job`
51
- - retrieval and external tool providers: `association`, `kb`, `mcp`
52
- - runtime options: `endpoint`, `backend`, `model`, `format`, `persist`, `previous_response_id`, `option`, `sticky_option`
53
- - maintenance: `clear`, `skip`, `clear_tools`, `clear_associations`
54
-
55
- For a tutorial-style walkthrough, start with `USER_GUIDE.md` and come back here as a reference.
56
-
57
- ---
58
-
59
- ## 1. Data model
60
-
61
- A chat is an array of messages.
62
-
63
- Each message is a Hash:
64
-
65
- ```ruby
66
- { role: "user", content: "Hello" }
67
- ```
68
-
69
- Roles are strings (symbols are accepted but are stringified).
70
-
71
- In Ruby, `Chat.setup(array)` annotates an array so it gains the builder methods (`user`, `system`, `file`, …).
72
-
73
- ```ruby
74
- chat = Chat.setup([])
75
- chat.system "You are a helpful assistant"
76
- chat.user "Say hi"
77
- puts chat.ask
78
- ```
79
-
80
- ---
81
-
82
- ## 2. Chat file syntax (parser rules)
83
-
84
- Chat files are parsed by `Chat.parse`.
85
-
86
- ### 2.1 Role headers
87
-
88
- A **role header** is any line matching:
89
-
90
- ```text
91
- ^[a-z0-9_]+:.*$
92
- ```
93
-
94
- Examples:
95
-
96
- ```text
97
- user:
98
- assistant:
99
- endpoint: nano
100
- previous_response_id: resp_123
101
- ```
102
-
103
- There are two forms:
104
-
105
- 1) **Block form**:
106
-
107
- ```text
108
- user:
109
-
110
- This is a multi-line user message.
111
- It continues until the next role header.
112
- ```
113
-
114
- 2) **Inline form** (single line):
115
-
116
- ```text
117
- endpoint: nano
118
- model: gpt-5-nano
119
- ```
120
-
121
- Inline headers become their own messages and do not “switch” the role for the following lines (except `previous_response_id`, see below).
122
-
123
- ### 2.2 Special parser protections (to avoid accidental role-splitting)
124
-
125
- The parser tries hard to avoid splitting a message when content contains colons.
126
-
127
- Protected regions:
128
-
129
- - **Markdown code fences**: content between triple backticks is kept in the same message even if it contains `something:` lines.
130
- - **XML-style blocks**: if the text contains `<tag ...>` and later `</tag>`, the whole block is treated as protected.
131
- - **Square-bracket protection**: `[[ ... ]]` protects multi-line content that may include role-looking headers.
132
- - The `[[` and `]]` markers are stripped.
133
- - **Command output shorthand**: lines like:
134
- - `shell:-- ls {{{` become `<cmd_output cmd="ls">`
135
- - `shell:-- ls }}}` become `</cmd_output>`
136
-
137
- ### 2.3 `previous_response_id` nuance
138
-
139
- `previous_response_id: ...` is special: after an inline `previous_response_id`, the parser resets the next block back to `user`.
140
-
141
- This makes it convenient to append a new user question *after* a response id marker.
142
-
143
- ---
144
-
145
- ## 3. Expansion pipeline: what `LLM.chat` does to a chat
146
-
147
- When you call `LLM.ask(chat)` or `chat.ask`, Scout-AI first expands the chat via `LLM.chat`.
148
-
149
- Expansion order (important):
150
-
151
- 1) **Imports** (`import`, `continue`, `last`)
152
- 2) **Clear** (`clear`)
153
- 3) **Clean** (drops empty messages and `skip`)
154
- 4) **Tasks** (`task`, `inline_task`, `exec_task` → jobs)
155
- 5) **Jobs** (`job`, `inline_job` → function_call/function_call_output or file)
156
- 6) **Files** (`file`, `directory`, `image`, `pdf`)
157
-
158
- After this, backends may do another pass to extract tool definitions.
159
-
160
- ---
161
-
162
- ## 4. Role reference (chat file / Chat DSL)
163
-
164
- ### 4.1 Standard conversational roles
165
-
166
- | Role | Meaning |
167
- |---|---|
168
- | `system` | System instructions / policy / persona |
169
- | `user` | User message |
170
- | `assistant` | Assistant message (usually produced by the model) |
171
-
172
- ### 4.2 Imports and composition
173
-
174
- Imports are processed by `Chat.imports` during `LLM.chat`.
175
-
176
- | Role | Effect | Notes |
177
- |---|---|---|
178
- | `import` | Inline the referenced chat file(s) | Imports **all** messages from the imported file, except `previous_response_id` |
179
- | `continue` | Import **only the last non-empty message** from the referenced file | Useful to “continue from the last user/assistant turn” |
180
- | `last` | Import **only the last non-empty message**, after removing `previous_response_id` | Often used to grab the last assistant answer |
181
-
182
- Resolution rules for imported paths:
183
-
184
- - absolute paths work
185
- - relative paths are resolved relative to the current chat file
186
- - names may resolve via `Scout.chats[...]`
187
-
188
- Example:
189
-
190
- ```text
191
- import: scout-ai/test_stdio
192
- continue: my_previous_chat
193
- last: summary_chat
194
- ```
195
-
196
- ### 4.3 Files and directories
197
-
198
- Files are processed by `Chat.files` during `LLM.chat`.
199
-
200
- | Role | Effect |
201
- |---|---|
202
- | `file` | Reads the file and inserts it as a tagged `<file name="...">...</file>` inside a `user` message |
203
- | `directory` | Expands to many `file` insertions for all files under the directory (recursive) |
204
- | `image` | Resolves to a path (not inlined). Responses backend will upload as base64 when possible |
205
- | `pdf` | Resolves to a path (not inlined). Responses backend will upload as base64 when possible |
206
-
207
- Example:
208
-
209
- ```text
210
- user:
211
-
212
- Please review these files.
213
-
214
- directory: lib/scout/llm
215
- file: README.md
216
- image: test/data/cat.jpg
217
- ```
218
-
219
- ### 4.4 Workflow tools (function calling)
220
-
221
- There are two related mechanisms:
222
-
223
- 1) **Expose tools** (so the model can call them)
224
- 2) **Run tasks/jobs ahead of time** (so their outputs are available as context)
225
-
226
- #### `tool` — expose workflow tasks as callable tools
227
-
228
- `tool: <WorkflowName> [<task_name> [<input1> <input2> ...]]`
229
-
230
- - If you provide only the workflow name, all exported tasks are available as tools.
231
- - If you provide a task name, only that task is exposed.
232
- - If you provide input names, only those inputs are exposed in the JSON schema.
233
- - You can also provide defaults with `input=value`.
234
-
235
- Examples:
236
-
237
- ```text
238
- tool: Baking
239
- tool: Baking bake_muffin_tray
240
- tool: Baking bake_muffin_tray blueberries=true
241
- tool: Baking bake_muffin_tray blueberries
242
- ```
243
-
244
- #### `introduce` — inject workflow documentation into the chat
245
-
246
- `introduce: <WorkflowName>` expands into a `user` message containing the workflow documentation (`workflow.documentation`).
247
-
248
- This is useful when you want the LLM to “understand what the tools do”, not just have access to them.
249
-
250
- Example:
251
-
252
- ```text
253
- introduce: Baking
254
- tool: Baking
255
- ```
256
-
257
- #### `task`, `inline_task`, `exec_task` — run a workflow job during compilation
258
-
259
- `task:` lines are executed **before** the model call.
260
-
261
- Syntax:
262
-
263
- ```text
264
- task: <WorkflowName> <task_name> key=value key2=value2
265
- inline_task: <WorkflowName> <task_name> key=value
266
- exec_task: <WorkflowName> <task_name> key=value
267
- ```
268
-
269
- Behavior:
270
-
271
- - `task` → runs the workflow job and replaces itself with a `job:` marker.
272
- - `inline_task` → runs the workflow job and replaces itself with an `inline_job:` marker.
273
- - `exec_task` → executes the job immediately and inlines its output into a `user` message.
274
-
275
- #### `job` / `inline_job` — include a precomputed Step result
276
-
277
- If you already have a job path (a `Step`), you can embed it:
278
-
279
- - `inline_job` becomes `file:` (the result is inlined as `<file>`)
280
- - `job` becomes a pair of messages:
281
- - `function_call` with `{name, arguments, id}`
282
- - `function_call_output` with `{id, content}`
283
-
284
- This is how saved chats can preserve tool-call traces.
285
-
286
- ### 4.5 Knowledge base tools
287
-
288
- Two ways:
289
-
290
- #### `association` — register a database from a file path
291
-
292
- `association: <name> <path> [options...]`
293
-
294
- Example:
295
-
296
- ```text
297
- system:
298
-
299
- Query the knowledge base to answer.
300
-
301
- association: brothers test/data/person/brothers undirected=true
302
- association: marriages test/data/person/marriages undirected=true source="=>Alias" target="=>Alias"
303
- ```
304
-
305
- This dynamically registers the database inside a temporary `KnowledgeBase` and exports tools for it.
306
-
307
- If a database has fields, an extra tool `<db>_association_details` is also exposed.
308
-
309
- #### `kb` — load an existing KnowledgeBase directory
310
-
311
- `kb: <knowledge_base_name_or_path> [db1 db2 ...]`
312
-
313
- This loads a KB via `KnowledgeBase.load` and exposes tools for all (or selected) databases.
314
-
315
- ### 4.6 MCP tools
316
-
317
- `mcp: <url_or_stdio> [tool1 tool2 ...]`
318
-
319
- This loads tool definitions from an MCP server and makes them available as tools.
320
-
321
- Examples:
322
-
323
- ```text
324
- mcp: http://localhost:8765
325
- mcp: stdio 'npx -y @modelcontextprotocol/server-filesystem ${pwd}'
326
- ```
327
-
328
- If you list tool names after the URL, only those tools are exposed.
329
-
330
- ### 4.7 Options and session control
331
-
332
- Options are extracted by `Chat.options` and merged into `LLM.ask` options.
333
-
334
- There are two categories:
335
-
336
- - **Sticky options**: persist across turns (until overridden)
337
- - **Transient options**: cleared after an `assistant` message
338
-
339
- #### Sticky options
340
-
341
- | Role | Meaning |
342
- |---|---|
343
- | `endpoint` | Named endpoint configuration (merged from `~/.scout/etc/AI/<endpoint>`) |
344
- | `backend` | Backend selector (`responses`, `openai`, `ollama`, `bedrock`, …) |
345
- | `model` | Model id for the backend |
346
- | `agent` | Agent name to load (see doc/Agent.md) |
347
- | `previous_response_id` | Continue a Responses API conversation session |
348
-
349
- #### Transient options
350
-
351
- | Role | Meaning |
352
- |---|---|
353
- | `format` | Output format: `:json`, `json_object`, or a JSON schema hash |
354
- | `persist` | Cache control for `LLM.ask` (see `doc/LLM.md`) |
355
- | `option` | Generic `key value` (cleared after assistant) |
356
- | `sticky_option` | Generic `key value` (persists across assistant turns) |
357
-
358
- Examples:
359
-
360
- ```text
361
- endpoint: nano
362
- model: gpt-5-nano
363
- format: json
364
-
365
- option: websearch true
366
- sticky_option: endpoint anthropic
367
- previous_response_id: resp_034e...
368
- ```
369
-
370
- #### `websearch` (Responses backend)
371
-
372
- If a message with role `websearch` is present, or if you pass option `websearch: true`, the Responses backend will include the `web_search_preview` tool.
373
-
374
- Example:
375
-
376
- ```text
377
- endpoint: deep
378
- websearch: true
379
-
380
- user:
381
-
382
- Find current information about ...
383
- ```
384
-
385
- ### 4.8 Maintenance roles
386
-
387
- | Role | Meaning |
388
- |---|---|
389
- | `clear` | Drop all messages *before* the last `clear:` marker |
390
- | `skip` | Drop this message |
391
- | `clear_tools` | Remove all previously declared tools (in this compilation) |
392
- | `clear_associations` | Remove all previously declared associations (in this compilation) |
393
-
394
- ---
395
-
396
- ## 5. Running a chat (Ruby)
397
-
398
- ### 5.1 `ask` vs `chat`
399
-
400
- - `chat.ask(...)` → returns assistant output (string)
401
- - `chat.chat(...)` → asks with `return_messages: true` and appends the resulting message trace to the chat
402
-
403
- ### 5.2 JSON helpers
404
-
405
- ```ruby
406
- chat.format :json
407
- obj = chat.json
408
- ```
409
-
410
- Or with a schema:
411
-
412
- ```ruby
413
- obj = chat.json_format({
414
- name: 'answer',
415
- type: 'object',
416
- properties: {content: {type: 'array', items: {type: 'string'}}},
417
- required: ['content'],
418
- additionalProperties: false,
419
- })
420
- ```
421
-
422
- ---
423
-
424
- ## 6. Using chat files from the CLI
425
-
426
- Chat files are primarily used via:
427
-
428
- ```bash
429
- scout-ai llm ask --chat my.chat "your question"
430
- ```
431
-
432
- Behavior:
433
-
434
- - the file is parsed into messages
435
- - the model is called
436
- - the assistant reply (and tool call trace when present) is appended back to the file
437
-
438
- You can keep typing into the file in an editor and re-run the command.
439
-
440
- ---
441
-
442
- ## 7. Example chat file (with tools + previous_response_id)
443
-
444
- ```text
445
- user:
446
-
447
- endpoint: nano
448
- agent: Baking
449
-
450
- bake some muffins using bake_muffin_tray, use blueberries
451
-
452
- function_call: {"name":"bake_muffin_tray","arguments":{"blueberries":true},"id":"call_123"}
453
- function_call_output: {"name":"bake_muffin_tray","content":"...","id":"call_123"}
454
-
455
- assistant:
456
-
457
- Blueberry muffins are in the oven.
458
-
459
- previous_response_id: resp_034e...
460
-
461
- Can you also bake one without blueberries?
462
- ```
463
-
464
- Notes:
465
-
466
- - `endpoint:` and `agent:` are parsed as their own messages even when written inside a `user:` block.
467
- - `function_call` / `function_call_output` are how tool traces are persisted in chat logs.
468
- - `previous_response_id` enables session continuation for the Responses backend.
469
-
470
- ---
471
-
472
- ## 8. Summary
473
-
474
- Use `Chat` when you want:
475
-
476
- - a reproducible, append-only conversation artifact on disk
477
- - a safe way to inline files/directories
478
- - a declarative way to expose workflow/KB/MCP tools
479
- - a convenient place to store endpoint/model/options per conversation
480
-
481
- The key to using chat files effectively is understanding the “control roles” above and the compilation order.