scout-ai 1.2.3 → 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 (174) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +138 -50
  3. data/README.md +171 -290
  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 +61 -11
  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 +62 -17
  33. data/lib/scout/llm/backends/anthropic.rb +9 -2
  34. data/lib/scout/llm/backends/bedrock.rb +15 -3
  35. data/lib/scout/llm/backends/default.rb +183 -99
  36. data/lib/scout/llm/backends/glm.rb +58 -0
  37. data/lib/scout/llm/backends/huggingface.rb +196 -26
  38. data/lib/scout/llm/backends/ollama.rb +13 -1
  39. data/lib/scout/llm/backends/openai.rb +0 -2
  40. data/lib/scout/llm/backends/openwebui.rb +20 -13
  41. data/lib/scout/llm/backends/relay.rb +22 -22
  42. data/lib/scout/llm/backends/responses.rb +1 -1
  43. data/lib/scout/llm/chat/agent_meta.rb +264 -0
  44. data/lib/scout/llm/chat/annotation.rb +39 -10
  45. data/lib/scout/llm/chat/parse.rb +28 -6
  46. data/lib/scout/llm/chat/persist.rb +25 -0
  47. data/lib/scout/llm/chat/process/clear.rb +41 -6
  48. data/lib/scout/llm/chat/process/files.rb +21 -6
  49. data/lib/scout/llm/chat/process/meta.rb +421 -34
  50. data/lib/scout/llm/chat/process/options.rb +21 -1
  51. data/lib/scout/llm/chat/process/tools.rb +56 -15
  52. data/lib/scout/llm/chat/process.rb +4 -0
  53. data/lib/scout/llm/chat/prompt/shorten_tools.rb +125 -0
  54. data/lib/scout/llm/chat/prompt/shorten_tools_epoch.rb +365 -0
  55. data/lib/scout/llm/chat/prompt.rb +48 -0
  56. data/lib/scout/llm/chat/provenance.rb +775 -0
  57. data/lib/scout/llm/chat/tool_calls.rb +76 -0
  58. data/lib/scout/llm/chat.rb +18 -2
  59. data/lib/scout/llm/embed.rb +11 -3
  60. data/lib/scout/llm/image.rb +86 -0
  61. data/lib/scout/llm/mcp.rb +10 -2
  62. data/lib/scout/llm/rag.rb +3 -3
  63. data/lib/scout/llm/tools/call.rb +160 -11
  64. data/lib/scout/llm/tools/knowledge_base.rb +1 -1
  65. data/lib/scout/llm/tools/workflow.rb +32 -16
  66. data/lib/scout/model/python/huggingface/causal.rb +23 -5
  67. data/lib/scout/model/python/huggingface.rb +2 -1
  68. data/lib/scout-ai.rb +1 -0
  69. data/python/README.md +197 -14
  70. data/python/scout_ai/huggingface/eval.py +245 -34
  71. data/python/tests/test_huggingface_eval.py +58 -0
  72. data/research/ChatAnalyst-required-changes.md +167 -0
  73. data/research/agent-delegation-analysis.md +810 -0
  74. data/research/agent-meta-provenance-integration-plan.md +622 -0
  75. data/research/agent-workflow-analysis.md +1120 -0
  76. data/research/backends-analysis.md +836 -0
  77. data/research/chat-core-analysis.md +946 -0
  78. data/research/chatanalyst-provenance/00-baseline.md +30 -0
  79. data/research/chatanalyst-provenance/01-repo-map.md +60 -0
  80. data/research/chatanalyst-provenance/02-event-reconstruction.md +55 -0
  81. data/research/chatanalyst-provenance/03-duplication-evidence.md +45 -0
  82. data/research/chatanalyst-provenance/04-tooling-root-cause.md +57 -0
  83. data/research/chatanalyst-provenance/05-fix-plan.md +46 -0
  84. data/research/chatanalyst-provenance/07-critic-review.md +25 -0
  85. data/research/chatanalyst-provenance/final-report.md +45 -0
  86. data/research/chatanalyst-provenance/resumption.md +37 -0
  87. data/research/coding-philosophy-analysis.md +928 -0
  88. data/research/commands-analysis.md +947 -0
  89. data/research/multi-agent-patterns-analysis.md +853 -0
  90. data/research/prompt-strategies-analysis.md +630 -0
  91. data/research/prov-verbosity-fix-notes.md +77 -0
  92. data/research/provenance-analysis.md +469 -0
  93. data/research/provenance-navigation-design.md +640 -0
  94. data/research/synthesis-report.md +487 -0
  95. data/research/tools-system-analysis.md +779 -0
  96. data/scout-ai.gemspec +100 -11
  97. data/scout_commands/agent/ask +13 -3
  98. data/scout_commands/agent/kb +2 -0
  99. data/scout_commands/llm/ask +11 -4
  100. data/scout_commands/llm/md +76 -0
  101. data/scout_commands/llm/process_queries +48 -0
  102. data/scout_commands/llm/prov +602 -0
  103. data/scout_commands/llm/word +71 -0
  104. data/scout_commands/workflow/mcp +43 -0
  105. data/share/word/reference.docx +0 -0
  106. data/test/etc/AI/mock.yaml +11 -0
  107. data/test/fixtures/backends/anthropic.json +19 -0
  108. data/test/fixtures/backends/anthropic_tool_use.json +24 -0
  109. data/test/fixtures/backends/bedrock.json +8 -0
  110. data/test/fixtures/backends/bedrock_embedding.json +3 -0
  111. data/test/fixtures/backends/bedrock_tool_use.json +17 -0
  112. data/test/fixtures/backends/ollama.json +16 -0
  113. data/test/fixtures/backends/ollama_tool_call.json +27 -0
  114. data/test/fixtures/backends/openai_chat.json +21 -0
  115. data/test/fixtures/backends/openai_chat_tool_call.json +31 -0
  116. data/test/fixtures/backends/responses.json +33 -0
  117. data/test/fixtures/backends/responses_tool_call.json +28 -0
  118. data/test/integration/README.md +32 -0
  119. data/test/integration/scout/llm/backends/test_endpoints.rb +34 -0
  120. data/test/integration/scout/llm/backends/test_openwebui.rb +61 -0
  121. data/test/integration/scout/llm/backends/test_relay.rb +52 -0
  122. data/test/integration/scout/llm/test_infrastructure.rb +74 -0
  123. data/test/{scout → integration/scout}/llm/test_mcp.rb +1 -1
  124. data/test/integration/scout/llm/tools/test_mcp.rb +42 -0
  125. data/test/integration/scout/model/test_base.rb +91 -0
  126. data/test/scout/llm/agent/test_chat.rb +8 -2
  127. data/test/scout/llm/agent/test_save.rb +413 -0
  128. data/test/scout/llm/agent/test_workflow.rb +110 -0
  129. data/test/scout/llm/backends/test_anthropic.rb +93 -10
  130. data/test/scout/llm/backends/test_bedrock.rb +118 -2
  131. data/test/scout/llm/backends/test_huggingface.rb +137 -42
  132. data/test/scout/llm/backends/test_ollama.rb +70 -20
  133. data/test/scout/llm/backends/test_openwebui.rb +42 -40
  134. data/test/scout/llm/backends/test_relay.rb +4 -2
  135. data/test/scout/llm/chat/agent_meta_fixtures.rb +131 -0
  136. data/test/scout/llm/chat/process/test_meta.rb +518 -0
  137. data/test/scout/llm/chat/process/test_normalize_usage.rb +183 -0
  138. data/test/scout/llm/chat/test_agent_meta.rb +357 -0
  139. data/test/scout/llm/chat/test_agent_meta_provenance.rb +467 -0
  140. data/test/scout/llm/chat/test_agent_meta_tokens.rb +594 -0
  141. data/test/scout/llm/chat/test_parse.rb +70 -15
  142. data/test/scout/llm/chat/test_prov_cli.rb +274 -0
  143. data/test/scout/llm/chat/test_provenance.rb +240 -0
  144. data/test/scout/llm/chat/test_tool_calls.rb +38 -0
  145. data/test/scout/llm/test_agent.rb +13 -36
  146. data/test/scout/llm/test_ask.rb +75 -52
  147. data/test/scout/llm/test_chat.rb +107 -13
  148. data/test/scout/llm/test_embed.rb +48 -0
  149. data/test/scout/llm/test_rag.rb +23 -16
  150. data/test/scout/llm/test_tools.rb +12 -1
  151. data/test/scout/llm/tools/test_knowledge_base.rb +0 -1
  152. data/test/scout/llm/tools/test_mcp.rb +5 -3
  153. data/test/scout/llm/tools/test_workflow.rb +23 -2
  154. data/test/scout/model/python/huggingface/causal/test_next_token.rb +11 -5
  155. data/test/scout/model/python/huggingface/test_causal.rb +9 -3
  156. data/test/scout/model/python/huggingface/test_classification.rb +11 -2
  157. data/test/scout/model/python/test_torch.rb +2 -0
  158. data/test/scout/model/python/torch/test_helpers.rb +4 -0
  159. data/test/scout/model/test_base.rb +4 -2
  160. data/test/support/availability.rb +231 -0
  161. data/test/support/fake_clients.rb +138 -0
  162. data/test/support/fixtures.rb +21 -0
  163. data/test/support/infrastructure_probes.rb +136 -0
  164. data/test/support/mock_backend.rb +215 -0
  165. data/test/test_helper.rb +32 -2
  166. metadata +99 -10
  167. data/doc/Agent.md +0 -327
  168. data/doc/Chat.md +0 -458
  169. data/doc/LLM.md +0 -340
  170. data/doc/RAG.md +0 -129
  171. data/scout_commands/documenter +0 -148
  172. data/test/scout/llm/backends/test_openai.rb +0 -192
  173. data/test/scout/llm/backends/test_responses.rb +0 -238
  174. data/test/scout/llm/test_parse.rb +0 -98
@@ -0,0 +1,325 @@
1
+ # Improvements Advisory
2
+
3
+ This document catalogs known code issues, documentation gaps, architectural
4
+ suggestions, and anti-patterns to avoid when contributing to Scout-AI. It is
5
+ derived from the research artifacts in [../research/](../research/) and is
6
+ intended as a living reference for maintainers and contributors.
7
+
8
+ Each entry includes a priority to help triage effort:
9
+
10
+ | Priority | Meaning |
11
+ |---|---|
12
+ | **High** | Correctness bug, security concern, or actively misleading behavior. Fix soon. |
13
+ | **Medium** | Technical debt that hampers maintainability or extensibility. Address when touching the area. |
14
+ | **Low** | Cleanup, deprecation, or polish. Good first issue or background work. |
15
+
16
+ ---
17
+
18
+ ## Code Issues
19
+
20
+ ### 1. ~~`prov` command monkey-patches the `Chat` class~~
21
+
22
+ **Priority:** High
23
+
24
+ > **Status: Resolved.** The `info` command has been removed entirely. Its
25
+ > traversal logic is shared `Chat` library code (`Chat.traverse_provenance`),
26
+ > and its flow-graph rendering lives inline in `scout_commands/llm/prov`;
27
+ > there is no separate `Chat::ProvenanceFlow` class. The flow-graph
28
+ > capabilities of `info` (imports, job deduplication, DOT, SVG/PNG/PDF) are
29
+ > available via `scout-ai llm prov -f`, `--dot`, and `-p`/`--plot`.
30
+
31
+ **Sources:** [../research/commands-analysis.md](../research/commands-analysis.md), [../research/provenance-analysis.md](../research/provenance-analysis.md).
32
+
33
+ ---
34
+
35
+ ### 2. ~~`prov` command has a hardcoded fallback path~~
36
+
37
+ **Priority:** High
38
+
39
+ > **Status: Resolved.** The hardcoded fallback path has been removed. The
40
+ > `prov` command now raises `MissingParameterException` if no filename is
41
+ > provided, matching the behavior of other CLI commands.
42
+
43
+ **Sources:** [../research/commands-analysis.md](../research/commands-analysis.md).
44
+
45
+ ---
46
+
47
+ ## Documentation Gaps
48
+
49
+ ### D1. ~~Python integration not integrated into the new documentation structure~~
50
+
51
+ **Priority:** Medium
52
+
53
+ > **Status: Resolved.** See [user/Python.md](user/Python.md).
54
+
55
+ **Sources:** [../research/synthesis-report.md](../research/synthesis-report.md).
56
+
57
+ ---
58
+
59
+ ### D2. Model subsystem documentation remains standalone
60
+
61
+ **Priority:** Low
62
+
63
+ **Problem:**
64
+ `doc/Model.md` documents the `ScoutModel` / `PythonModel` / `TorchModel` /
65
+ `HuggingfaceModel` subsystem — wrapping ML models for evaluation and training.
66
+ This is tangential to the agent/LLM layer and is intentionally kept separate,
67
+ but it is not linked from the new documentation structure.
68
+
69
+ **Recommended action:**
70
+ Keep `Model.md` as a standalone reference. Add a note in [StartHere.md](StartHere.md)
71
+ pointing to it. Optionally move it to `doc/developer/Model.md` for structural
72
+ consistency. Do not merge into the LLM docs unless explicitly requested.
73
+
74
+ **Sources:** [../research/synthesis-report.md](../research/synthesis-report.md).
75
+
76
+ ---
77
+
78
+ ### D3. No dedicated getting-started / installation guide
79
+
80
+ **Priority:** Low
81
+
82
+ **Problem:**
83
+ Installation, Gemfile setup, and first-endpoint configuration are covered in
84
+ [user/GettingStarted.md](user/GettingStarted.md), but it may be too terse for
85
+ users who want a guided walkthrough.
86
+
87
+ **Recommended action:**
88
+ Consider expanding the Getting Started guide with a more linear tutorial (install →
89
+ configure endpoint → first `ask` → first chat file → first agent → first
90
+ workflow). Low priority since the current guide covers the essentials.
91
+
92
+ **Sources:** [../research/synthesis-report.md](../research/synthesis-report.md).
93
+
94
+ ---
95
+
96
+ ## Architectural Suggestions
97
+
98
+ ### A1. Promote ChatAnalyst provenance traversal from SC26 to the core library
99
+
100
+ **Priority:** Medium
101
+
102
+ **Problem:**
103
+ The `ChatAnalyst` agent (currently in `~/git/workflows/SC26/Agent/ChatAnalyst/`)
104
+ implements a `Session` class with BFS-based provenance discovery, token
105
+ accounting, and edge-graph construction. The `info` CLI command independently
106
+ implemented similar logic (`LLMInfoReport`). Having two implementations of the
107
+ same traversal algorithm is a maintenance burden.
108
+
109
+ > **Partial progress:** The `info` command has been removed, and `prov`
110
+ > renders its flow graph inline in `scout_commands/llm/prov` on top of the
111
+ > shared `Chat` traversal primitives; there is no separate
112
+ > `Chat::ProvenanceFlow` class. ChatAnalyst should be updated to consume the
113
+ > shared `Chat` primitives as well.
114
+
115
+ **Recommended action:**
116
+ Update ChatAnalyst's `Session` class to delegate to the shared `Chat`
117
+ provenance primitives (`Chat.traverse_provenance`, `Chat.agent_meta_evidence`,
118
+ `Chat.provenance_token_events`) instead of maintaining its own BFS traversal.
119
+
120
+ **Sources:** [../research/provenance-analysis.md](../research/provenance-analysis.md), [../research/multi-agent-patterns-analysis.md](../research/multi-agent-patterns-analysis.md).
121
+
122
+ ---
123
+
124
+ ### A2. Wire up the custom prompt strategy registry (`REGISTERED_STRATEGIES`)
125
+
126
+ **Priority:** Medium
127
+
128
+ **Problem:**
129
+ The prompt strategy system has a designed extension point
130
+ (`REGISTERED_STRATEGIES`) that is not implemented. This prevents plugins or
131
+ users from registering custom named strategies without modifying the source.
132
+
133
+ **Recommended action:**
134
+ Implement the registry: define `REGISTERED_STRATEGIES = {}` and add a
135
+ `Chat.register_prompt_strategy(name, &block)` class method. Document the
136
+ extension point in [developer/PromptProcessing.md](developer/PromptProcessing.md).
137
+
138
+ **Sources:** [../research/prompt-strategies-analysis.md](../research/prompt-strategies-analysis.md).
139
+
140
+ ---
141
+
142
+ ### A3. ~~Remove `prov` command; let `info` subsume it entirely~~
143
+
144
+ **Priority:** Medium
145
+
146
+ > **Status: Resolved (inverted).** The `info` command has been removed instead.
147
+ > Its flow-graph rendering lives inline in `scout_commands/llm/prov`, on top of
148
+ > the shared `Chat` traversal primitives; there is no separate
149
+ > `Chat::ProvenanceFlow` class. The `prov` command provides both the
150
+ > text-tree report and the flow/DOT/SVG capabilities that were formerly in
151
+ > `info`. `prov` is the sole provenance CLI command.
152
+
153
+ **Sources:** [../research/commands-analysis.md](../research/commands-analysis.md), [../research/provenance-analysis.md](../research/provenance-analysis.md).
154
+
155
+ ---
156
+
157
+ ### A4. Ensure consistent endpoint configuration documentation
158
+
159
+ **Priority:** Low
160
+
161
+ **Problem:**
162
+ Endpoint configuration (YAML keys, `~/.scout/etc/AI/<name>` format, config
163
+ defaults via `~/.scout/etc/config`, environment variables) is documented in
164
+ [user/GettingStarted.md](user/GettingStarted.md) and [developer/Backends.md](developer/Backends.md),
165
+ but the two should be checked for consistency. The research artifacts noted
166
+ that endpoint configuration was a HIGH-priority gap in the original docs.
167
+
168
+ **Recommended action:**
169
+ Review both documents to ensure the endpoint YAML examples, key names, and
170
+ configuration precedence are identical. Cross-link them so readers can find
171
+ the canonical reference.
172
+
173
+ **Sources:** [../research/synthesis-report.md](../research/synthesis-report.md).
174
+
175
+ ---
176
+
177
+ ## Anti-patterns to Watch For
178
+
179
+ These anti-patterns are drawn from the Scout-AI coding philosophy
180
+ ([../research/coding-philosophy-analysis.md](../research/coding-philosophy-analysis.md)).
181
+ They are the most common ways that well-intentioned code fights the library
182
+ instead of composing with it.
183
+
184
+ ---
185
+
186
+ ### AP1. Don't create wrapper classes for Chat
187
+
188
+ **❌ Non-idiomatic:**
189
+ ```ruby
190
+ class MyConversation
191
+ def initialize
192
+ @messages = []
193
+ end
194
+ def add_user(text)
195
+ @messages << { role: 'user', content: text }
196
+ end
197
+ end
198
+ ```
199
+
200
+ **✅ Idiomatic:**
201
+ ```ruby
202
+ chat = Chat.setup([])
203
+ chat.user("Hello")
204
+ ```
205
+
206
+ **Why:** `Chat` is an annotation on a plain `Array`. Wrapping it in a custom
207
+ class breaks serialization, composition, caching, and every helper that
208
+ expects an Array. Use `Chat.setup(any_array)` and the DSL methods.
209
+
210
+ ---
211
+
212
+ ### AP2. Don't hardcode provider logic in `LLM.ask`
213
+
214
+ **❌ Non-idiomatic:**
215
+ ```ruby
216
+ def self.ask(question, options = {})
217
+ if options[:provider] == 'openai'
218
+ # 50 lines of OpenAI-specific code inline
219
+ end
220
+ end
221
+ ```
222
+
223
+ **✅ Idiomatic:**
224
+ ```ruby
225
+ def self.ask(question, options = {})
226
+ options = IndiferentHash.setup(options)
227
+ backend = LLM.resolve_backend(options)
228
+ backend.ask(messages, options, &block)
229
+ end
230
+ ```
231
+
232
+ **Why:** Provider logic belongs in backend modules (composed via
233
+ `prepend`/`include`). `LLM.ask` should dispatch, not implement.
234
+
235
+ ---
236
+
237
+ ### AP3. Don't use plain `Hash` for options that come from user input
238
+
239
+ **❌ Non-idiomatic:**
240
+ ```ruby
241
+ def ask(question, options = {})
242
+ model = options[:model] # fails if user passed 'model' as a string key
243
+ end
244
+ ```
245
+
246
+ **✅ Idiomatic:**
247
+ ```ruby
248
+ def ask(question, options = {})
249
+ options = IndiferentHash.setup(options)
250
+ model = options[:model] # works for both :model and 'model'
251
+ end
252
+ ```
253
+
254
+ **Why:** Options arrive from YAML files, CLI flags, and Ruby hashes with
255
+ inconsistent key types. `IndiferentHash` normalizes access. Always call
256
+ `IndiferentHash.setup` on any options hash at the entry point.
257
+
258
+ ---
259
+
260
+ ### AP4. Don't subclass to add behavior
261
+
262
+ **❌ Non-idiomatic:**
263
+ ```ruby
264
+ class SpecialChat < Array
265
+ def user(content)
266
+ self << { role: 'user', content: content }
267
+ end
268
+ end
269
+ ```
270
+
271
+ **✅ Idiomatic:**
272
+ ```ruby
273
+ module Chat
274
+ extend Annotation
275
+ def user(content)
276
+ message(:user, content)
277
+ end
278
+ end
279
+ # Then: Chat.setup(any_array)
280
+ ```
281
+
282
+ **Why:** Subclassing creates a rigid hierarchy and breaks the "plain Array"
283
+ contract. Annotation and module composition add behavior non-invasively.
284
+
285
+ ---
286
+
287
+ ### AP5. Don't scatter file I/O without `Path` / `Open`
288
+
289
+ **❌ Non-idiomatic:**
290
+ ```ruby
291
+ File.read("/hardcoded/path/#{name}")
292
+ ```
293
+
294
+ **✅ Idiomatic:**
295
+ ```ruby
296
+ path = Scout.var.Agent[name].start_chat
297
+ content = Open.read(path.find) if path.exists?
298
+ ```
299
+
300
+ **Why:** Scout's `Path` API handles convention-based resolution, annotation,
301
+ and existence checks. `Open` provides atomic writes and encoding safety.
302
+ Hardcoded paths break portability and testability.
303
+
304
+ ---
305
+
306
+ ### AP6. Don't define methods on `Agent` that duplicate `Chat`
307
+
308
+ **❌ Non-idiomatic:**
309
+ ```ruby
310
+ class Agent
311
+ def add_user_message(text)
312
+ current_chat << { role: 'user', content: text }
313
+ end
314
+ end
315
+ ```
316
+
317
+ **✅ Idiomatic:**
318
+ ```ruby
319
+ agent.user(text) # works automatically via method_missing → current_chat
320
+ ```
321
+
322
+ **Why:** `Agent` already delegates unknown methods to `current_chat` via
323
+ `method_missing`. Defining wrapper methods on `Agent` creates redundancy and
324
+ maintenance overhead. If the method exists on `Chat`, it already works on
325
+ `Agent`.
data/doc/StartHere.md ADDED
@@ -0,0 +1,110 @@
1
+ # Scout-AI Documentation
2
+
3
+ Scout-AI is an agent and LLM layer built on top of
4
+ [Scout](https://github.com/mikisvaz/scout-gear). It provides a reproducible
5
+ conversation format (`Chat`), tool calling backed by real Scout workflows,
6
+ knowledge bases, and MCP servers, and multi-agent orchestration encoded as
7
+ typed, inspectable workflow jobs.
8
+
9
+ ---
10
+
11
+ ## Choose your path
12
+
13
+ ### I want to build applications with Scout-AI
14
+
15
+ → Go to **[user/](user/)** documentation.
16
+
17
+ The user documentation explains how to use Scout-AI to build agents, define
18
+ tools, configure inference, and orchestrate multi-agent workflows. It is
19
+ organized around concepts and tasks, not internal classes.
20
+
21
+ **Start here:**
22
+ 1. [user/GettingStarted.md](user/GettingStarted.md) — install, configure, first conversation.
23
+ 2. [user/CoreConcepts.md](user/CoreConcepts.md) — the four building blocks.
24
+ 3. Then follow the topic guides as needed.
25
+
26
+ ### I want to extend or modify Scout-AI
27
+
28
+ → Go to **[developer/](developer/)** documentation.
29
+
30
+ The developer documentation explains how Scout-AI is implemented: the
31
+ architecture, the compilation pipeline, the backend abstraction, the
32
+ delegation internals, and the provenance system. It is concise and links to
33
+ [research/](../research/) for deep code investigations.
34
+
35
+ **Start here:**
36
+ 1. [developer/Architecture.md](developer/Architecture.md) — subsystem map and data flow.
37
+ 2. [developer/DesignPrinciples.md](developer/DesignPrinciples.md) — coding philosophy and idioms.
38
+ 3. Then follow the topic guides as needed.
39
+
40
+ ### I need to understand how a subsystem works in detail
41
+
42
+ → Go to **[../research/](../research/)** investigation documents.
43
+
44
+ These are architectural reports produced during code investigations. They are
45
+ not maintained documentation and may be outdated, but they contain detailed
46
+ call graphs, implementation discoveries, and design rationale.
47
+
48
+ ---
49
+
50
+ ## Reading paths for common tasks
51
+
52
+ | Task | Reading path |
53
+ |---|---|
54
+ | **Build my first agent** | user/GettingStarted → user/CoreConcepts → user/BuildingAgents |
55
+ | **Understand multi-agent systems** | user/Delegation → user/MultiAgentWorkflows → developer/DelegationInternals |
56
+ | **Add tool support** | user/ToolCalling → (user/Python if needed) |
57
+ | **Configure inference** | user/RunningInference → user/ManagingContext |
58
+ | **Understand the internals** | developer/Architecture → developer/ChatLifecycle → developer/Backends |
59
+ | **Track and inspect provenance** | developer/Provenance → research/provenance-analysis |
60
+ | **Write idiomatic code** | developer/DesignPrinciples → research/coding-philosophy-analysis |
61
+ | **Use the CLI** | user/Cookbook (quick reference) → research/commands-analysis (full detail) |
62
+
63
+ ---
64
+
65
+ ## Documentation structure
66
+
67
+ ```
68
+ doc/
69
+ ├── StartHere.md ← you are here
70
+ ├── Improvements.md ← known issues and improvement advisory
71
+ ├── Model.md ← ML model subsystem (separate from harness)
72
+ ├── user/ ← building applications with Scout-AI
73
+ │ ├── GettingStarted.md
74
+ │ ├── CoreConcepts.md
75
+ │ ├── WritingChats.md
76
+ │ ├── BuildingAgents.md
77
+ │ ├── ToolCalling.md
78
+ │ ├── RunningInference.md
79
+ │ ├── ManagingContext.md
80
+ │ ├── Delegation.md
81
+ │ ├── MultiAgentWorkflows.md
82
+ │ ├── Python.md
83
+ │ └── Cookbook.md
84
+ ├── developer/ ← extending and modifying Scout-AI
85
+ │ ├── Architecture.md
86
+ │ ├── ChatLifecycle.md
87
+ │ ├── DesignPrinciples.md
88
+ │ ├── PromptProcessing.md
89
+ │ ├── Backends.md
90
+ │ ├── DelegationInternals.md
91
+ │ └── Provenance.md
92
+ └── ../research/ ← architectural investigation reports
93
+ ├── chat-core-analysis.md
94
+ ├── prompt-strategies-analysis.md
95
+ ├── agent-delegation-analysis.md
96
+ ├── agent-workflow-analysis.md
97
+ ├── backends-analysis.md
98
+ ├── tools-system-analysis.md
99
+ ├── provenance-analysis.md
100
+ ├── multi-agent-patterns-analysis.md
101
+ ├── coding-philosophy-analysis.md
102
+ ├── commands-analysis.md
103
+ └── synthesis-report.md
104
+ ```
105
+
106
+ Each layer becomes progressively more detailed and less stable:
107
+
108
+ ```
109
+ Code → Investigation (research/) → Developer docs (doc/developer/) → User docs (doc/user/)
110
+ ```
@@ -0,0 +1,126 @@
1
+ # Architecture
2
+
3
+ This document explains the overall system architecture of Scout-AI and how its
4
+ subsystems interact. It is intended for framework contributors who need a
5
+ mental map before diving into specific subsystems.
6
+
7
+ For deeper investigation of any subsystem, see the corresponding
8
+ [research document](../../research/).
9
+
10
+ ---
11
+
12
+ ## Subsystem map
13
+
14
+ ```
15
+ ┌─────────────────────────────────────────────┐
16
+ │ LLM (module) │
17
+ │ LLM.ask — entry point for all inference │
18
+ │ LLM.chat — parse/compile chat files │
19
+ │ LLM.load_agent — resolve agent directories │
20
+ └───────────────┬───────────────────────────────┘
21
+ │
22
+ ┌───────────────────┼───────────────────────┐
23
+ ▼ ▼ ▼
24
+ ┌──────────┐ ┌──────────────┐ ┌──────────────┐
25
+ │ Backend │ │ LLM::Agent │ │ Tools │
26
+ │ adapter │ │ (stateful) │ │ (WF/KB/MCP) │
27
+ └──────────┘ └──────┬───────┘ └──────┬───────┘
28
+ │ holds │
29
+ ┌─────▼─────┐ ┌──────▼──────┐
30
+ │ Chat │◄────────►│ Workflow │
31
+ │ (Array + │ task │ tasks as │
32
+ │ DSL) │ tools │ tools │
33
+ └───────────┘ └─────────────┘
34
+ │ extends
35
+ ┌─────▼─────┐
36
+ │ Annotation│ (non-invasive mixin)
37
+ └───────────┘
38
+ ```
39
+
40
+ ### The six core abstractions
41
+
42
+ | Abstraction | Realized by | Responsibility |
43
+ |---|---|---|
44
+ | **Chat** | `Chat` module (Annotation on Array) | A conversation: a plain Array of message Hashes, annotated with DSL methods. |
45
+ | **Agent** | `LLM::Agent` class | A stateful conversation holder with tools, a workflow, knowledge bases, and delegation capabilities. |
46
+ | **AgentWorkflow** | `AgentWorkflow` mixin | A `Workflow` mixin that adds `chat_task`, `helper :agent`, and `helper :log_agent` for multi-agent strategies. `log_agent` delegates to `Agent#save`, so workflow jobs and manual agents write to one canonical layout (`<job>.files/<name>.chat` — `agent.chat` by default, `worker.chat`/`critic.chat` for named agents — plus the lazy `<name>.society/<Agent>/<conversation>/…` tree). |
47
+ | **Backend** | `LLM::Backend` module + provider modules | Stateless adapter to a specific LLM provider API. Shares logic via `Backend::ClassMethods`, overrides via `prepend`. |
48
+ | **Tools** | `LLM` module methods | Definition and execution of callable tools: workflow tasks, KB queries, MCP servers. |
49
+ | **Annotation** | `Annotation` (from scout-essentials) | Non-invasive metadata injection onto existing objects without subclassing or wrapping. |
50
+
51
+ ---
52
+
53
+ ## Dependency direction
54
+
55
+ ```
56
+ scout-ai.rb
57
+ └─ scout/llm/ask.rb (requires scout, chat)
58
+ └─ scout/llm/chat.rb (requires chat/annotation, parse, process, prompt, persist, tools, utils)
59
+ └─ scout/llm/agent.rb (requires ask, agent/chat, iterate, delegate, workflow)
60
+ └─ scout/llm/embed.rb
61
+ └─ scout/llm/image.rb
62
+ └─ scout/llm/tools/ (workflow, knowledge_base, mcp, call)
63
+ └─ scout/llm/backends/ (default + provider adapters)
64
+ ```
65
+
66
+ The key direction is **Agent → Chat → Annotation**.
67
+
68
+ Backends depend on Chat and `Backend::ClassMethods`, not on Agent.
69
+ AgentWorkflow depends on Agent and Chat, not on specific Backends.
70
+
71
+ This means you can use Chat and Backends without ever instantiating an Agent,
72
+ and you can use Agents without AgentWorkflow. Each layer adds capability
73
+ without creating hard downward dependencies.
74
+
75
+ ---
76
+
77
+ ## How data flows through the system
78
+
79
+ A single inference request flows through the layers as follows:
80
+
81
+ 1. **Entry**: `LLM.ask(messages, options)` or `Agent#ask(messages, options)`.
82
+ 2. **Chat compilation**: The messages (string, file, or Array) are compiled
83
+ into a canonical Array of Hashes via `Chat.parse`. Options embedded in the
84
+ chat (via `option:`, `model:`, `endpoint:` directives) are extracted into
85
+ the options hash.
86
+ 3. **Tool extraction**: Tool/introduce/association roles are extracted from
87
+ messages. Workflow tasks and KB databases are converted to tool definitions.
88
+ 4. **Prompt preparation**: The message array passes through
89
+ `Chat.prepare_prompt` which applies context-management strategies
90
+ (e.g., `shorten_tools`). This is **ephemeral** — the stored chat is never
91
+ mutated.
92
+ 5. **Backend dispatch**: `LLM.ask` selects the appropriate Backend module
93
+ (OpenAI, Anthropic, etc.) via a registry/case dispatch and calls its
94
+ `ask` method.
95
+ 6. **API call + tool loop**: The Backend formats the prompt for the provider,
96
+ calls the API, parses the response. If the model emitted a tool call, the
97
+ tool is executed and the result appended; then the Backend re-calls the
98
+ API with the growing message list (the `chain_tools` recursive loop).
99
+ 7. **Response**: The Backend returns the response as an annotated Chat (Array
100
+ of Hashes), with provenance metadata (`meta:` messages) interleaved.
101
+
102
+ ---
103
+
104
+ ## Extension points
105
+
106
+ | To extend... | Where to add | Pattern |
107
+ |---|---|---|
108
+ | A new LLM provider | `lib/scout/llm/backends/<provider>.rb` | Define a module that `prepend`s `<Provider>Methods` and `include`s `Backend::ClassMethods`. Override `query`, `process_response`, `format_messages` as needed. |
109
+ | A new tool type | `lib/scout/llm/tools/<type>.rb` | Define a module method that returns `{ name => [executor, definition] }` hashes. |
110
+ | A new prompt strategy | Register in `REGISTERED_STRATEGIES` (currently undefined) or pass a `Proc` via `prompt_strategies:` option. |
111
+ | A new agent type | `Agent/<Name>/` directory with `start_chat`, `agent.rb`, or `workflow.rb`. | Conventional discovery. |
112
+ | A new chat-task workflow | `include_workflow AgentWorkflow` in your Workflow module. | Use `chat_task`, `helper :agent`, etc. |
113
+
114
+ ---
115
+
116
+ ## Cross-references
117
+
118
+ - [ChatLifecycle.md](ChatLifecycle.md) — Chat data model, compilation, annotations.
119
+ - [PromptProcessing.md](PromptProcessing.md) — Context management internals.
120
+ - [Backends.md](Backends.md) — Backend abstraction and inference loop.
121
+ - [DelegationInternals.md](DelegationInternals.md) — Multi-agent mechanics.
122
+ - [Provenance.md](Provenance.md) — Provenance data model and traversal.
123
+ - [DesignPrinciples.md](DesignPrinciples.md) — Coding philosophy and idioms.
124
+
125
+ > For detailed code investigations of each subsystem, browse the
126
+ > [research/](../../research/) directory.