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.
- checksums.yaml +4 -4
- data/.vimproject +138 -50
- data/README.md +171 -290
- data/Rakefile +17 -1
- data/VERSION +1 -1
- data/doc/Improvements.md +325 -0
- data/doc/StartHere.md +110 -0
- data/doc/developer/Architecture.md +126 -0
- data/doc/developer/Backends.md +199 -0
- data/doc/developer/ChatLifecycle.md +183 -0
- data/doc/developer/DelegationInternals.md +295 -0
- data/doc/developer/DesignPrinciples.md +245 -0
- data/doc/developer/PromptProcessing.md +292 -0
- data/doc/developer/Provenance.md +317 -0
- data/doc/user/BuildingAgents.md +345 -0
- data/doc/user/Cookbook.md +333 -0
- data/doc/user/CoreConcepts.md +181 -0
- data/doc/user/Delegation.md +191 -0
- data/doc/user/GettingStarted.md +159 -0
- data/doc/user/ManagingContext.md +163 -0
- data/doc/user/MultiAgentWorkflows.md +256 -0
- data/doc/user/Python.md +159 -0
- data/doc/user/RunningInference.md +200 -0
- data/doc/user/ToolCalling.md +193 -0
- data/doc/user/WritingChats.md +197 -0
- data/lib/scout/llm/agent/chat.rb +61 -11
- data/lib/scout/llm/agent/delegate.rb +274 -65
- data/lib/scout/llm/agent/iterate.rb +2 -2
- data/lib/scout/llm/agent/save.rb +273 -0
- data/lib/scout/llm/agent/workflow.rb +164 -0
- data/lib/scout/llm/agent.rb +86 -61
- data/lib/scout/llm/ask.rb +62 -17
- data/lib/scout/llm/backends/anthropic.rb +9 -2
- data/lib/scout/llm/backends/bedrock.rb +15 -3
- data/lib/scout/llm/backends/default.rb +183 -99
- data/lib/scout/llm/backends/glm.rb +58 -0
- data/lib/scout/llm/backends/huggingface.rb +196 -26
- data/lib/scout/llm/backends/ollama.rb +13 -1
- data/lib/scout/llm/backends/openai.rb +0 -2
- data/lib/scout/llm/backends/openwebui.rb +20 -13
- data/lib/scout/llm/backends/relay.rb +22 -22
- data/lib/scout/llm/backends/responses.rb +1 -1
- data/lib/scout/llm/chat/agent_meta.rb +264 -0
- data/lib/scout/llm/chat/annotation.rb +39 -10
- data/lib/scout/llm/chat/parse.rb +28 -6
- data/lib/scout/llm/chat/persist.rb +25 -0
- data/lib/scout/llm/chat/process/clear.rb +41 -6
- data/lib/scout/llm/chat/process/files.rb +21 -6
- data/lib/scout/llm/chat/process/meta.rb +421 -34
- data/lib/scout/llm/chat/process/options.rb +21 -1
- data/lib/scout/llm/chat/process/tools.rb +56 -15
- data/lib/scout/llm/chat/process.rb +4 -0
- data/lib/scout/llm/chat/prompt/shorten_tools.rb +125 -0
- data/lib/scout/llm/chat/prompt/shorten_tools_epoch.rb +365 -0
- data/lib/scout/llm/chat/prompt.rb +48 -0
- data/lib/scout/llm/chat/provenance.rb +775 -0
- data/lib/scout/llm/chat/tool_calls.rb +76 -0
- data/lib/scout/llm/chat.rb +18 -2
- data/lib/scout/llm/embed.rb +11 -3
- data/lib/scout/llm/image.rb +86 -0
- data/lib/scout/llm/mcp.rb +10 -2
- data/lib/scout/llm/rag.rb +3 -3
- data/lib/scout/llm/tools/call.rb +160 -11
- data/lib/scout/llm/tools/knowledge_base.rb +1 -1
- data/lib/scout/llm/tools/workflow.rb +32 -16
- data/lib/scout/model/python/huggingface/causal.rb +23 -5
- data/lib/scout/model/python/huggingface.rb +2 -1
- data/lib/scout-ai.rb +1 -0
- data/python/README.md +197 -14
- data/python/scout_ai/huggingface/eval.py +245 -34
- data/python/tests/test_huggingface_eval.py +58 -0
- data/research/ChatAnalyst-required-changes.md +167 -0
- data/research/agent-delegation-analysis.md +810 -0
- data/research/agent-meta-provenance-integration-plan.md +622 -0
- data/research/agent-workflow-analysis.md +1120 -0
- data/research/backends-analysis.md +836 -0
- data/research/chat-core-analysis.md +946 -0
- data/research/chatanalyst-provenance/00-baseline.md +30 -0
- data/research/chatanalyst-provenance/01-repo-map.md +60 -0
- data/research/chatanalyst-provenance/02-event-reconstruction.md +55 -0
- data/research/chatanalyst-provenance/03-duplication-evidence.md +45 -0
- data/research/chatanalyst-provenance/04-tooling-root-cause.md +57 -0
- data/research/chatanalyst-provenance/05-fix-plan.md +46 -0
- data/research/chatanalyst-provenance/07-critic-review.md +25 -0
- data/research/chatanalyst-provenance/final-report.md +45 -0
- data/research/chatanalyst-provenance/resumption.md +37 -0
- data/research/coding-philosophy-analysis.md +928 -0
- data/research/commands-analysis.md +947 -0
- data/research/multi-agent-patterns-analysis.md +853 -0
- data/research/prompt-strategies-analysis.md +630 -0
- data/research/prov-verbosity-fix-notes.md +77 -0
- data/research/provenance-analysis.md +469 -0
- data/research/provenance-navigation-design.md +640 -0
- data/research/synthesis-report.md +487 -0
- data/research/tools-system-analysis.md +779 -0
- data/scout-ai.gemspec +100 -11
- data/scout_commands/agent/ask +13 -3
- data/scout_commands/agent/kb +2 -0
- data/scout_commands/llm/ask +11 -4
- data/scout_commands/llm/md +76 -0
- data/scout_commands/llm/process_queries +48 -0
- data/scout_commands/llm/prov +602 -0
- data/scout_commands/llm/word +71 -0
- data/scout_commands/workflow/mcp +43 -0
- data/share/word/reference.docx +0 -0
- data/test/etc/AI/mock.yaml +11 -0
- data/test/fixtures/backends/anthropic.json +19 -0
- data/test/fixtures/backends/anthropic_tool_use.json +24 -0
- data/test/fixtures/backends/bedrock.json +8 -0
- data/test/fixtures/backends/bedrock_embedding.json +3 -0
- data/test/fixtures/backends/bedrock_tool_use.json +17 -0
- data/test/fixtures/backends/ollama.json +16 -0
- data/test/fixtures/backends/ollama_tool_call.json +27 -0
- data/test/fixtures/backends/openai_chat.json +21 -0
- data/test/fixtures/backends/openai_chat_tool_call.json +31 -0
- data/test/fixtures/backends/responses.json +33 -0
- data/test/fixtures/backends/responses_tool_call.json +28 -0
- data/test/integration/README.md +32 -0
- data/test/integration/scout/llm/backends/test_endpoints.rb +34 -0
- data/test/integration/scout/llm/backends/test_openwebui.rb +61 -0
- data/test/integration/scout/llm/backends/test_relay.rb +52 -0
- data/test/integration/scout/llm/test_infrastructure.rb +74 -0
- data/test/{scout → integration/scout}/llm/test_mcp.rb +1 -1
- data/test/integration/scout/llm/tools/test_mcp.rb +42 -0
- data/test/integration/scout/model/test_base.rb +91 -0
- data/test/scout/llm/agent/test_chat.rb +8 -2
- data/test/scout/llm/agent/test_save.rb +413 -0
- data/test/scout/llm/agent/test_workflow.rb +110 -0
- data/test/scout/llm/backends/test_anthropic.rb +93 -10
- data/test/scout/llm/backends/test_bedrock.rb +118 -2
- data/test/scout/llm/backends/test_huggingface.rb +137 -42
- data/test/scout/llm/backends/test_ollama.rb +70 -20
- data/test/scout/llm/backends/test_openwebui.rb +42 -40
- data/test/scout/llm/backends/test_relay.rb +4 -2
- data/test/scout/llm/chat/agent_meta_fixtures.rb +131 -0
- data/test/scout/llm/chat/process/test_meta.rb +518 -0
- data/test/scout/llm/chat/process/test_normalize_usage.rb +183 -0
- data/test/scout/llm/chat/test_agent_meta.rb +357 -0
- data/test/scout/llm/chat/test_agent_meta_provenance.rb +467 -0
- data/test/scout/llm/chat/test_agent_meta_tokens.rb +594 -0
- data/test/scout/llm/chat/test_parse.rb +70 -15
- data/test/scout/llm/chat/test_prov_cli.rb +274 -0
- data/test/scout/llm/chat/test_provenance.rb +240 -0
- data/test/scout/llm/chat/test_tool_calls.rb +38 -0
- data/test/scout/llm/test_agent.rb +13 -36
- data/test/scout/llm/test_ask.rb +75 -52
- data/test/scout/llm/test_chat.rb +107 -13
- data/test/scout/llm/test_embed.rb +48 -0
- data/test/scout/llm/test_rag.rb +23 -16
- data/test/scout/llm/test_tools.rb +12 -1
- data/test/scout/llm/tools/test_knowledge_base.rb +0 -1
- data/test/scout/llm/tools/test_mcp.rb +5 -3
- data/test/scout/llm/tools/test_workflow.rb +23 -2
- data/test/scout/model/python/huggingface/causal/test_next_token.rb +11 -5
- data/test/scout/model/python/huggingface/test_causal.rb +9 -3
- data/test/scout/model/python/huggingface/test_classification.rb +11 -2
- data/test/scout/model/python/test_torch.rb +2 -0
- data/test/scout/model/python/torch/test_helpers.rb +4 -0
- data/test/scout/model/test_base.rb +4 -2
- data/test/support/availability.rb +231 -0
- data/test/support/fake_clients.rb +138 -0
- data/test/support/fixtures.rb +21 -0
- data/test/support/infrastructure_probes.rb +136 -0
- data/test/support/mock_backend.rb +215 -0
- data/test/test_helper.rb +32 -2
- metadata +99 -10
- data/doc/Agent.md +0 -327
- data/doc/Chat.md +0 -458
- data/doc/LLM.md +0 -340
- data/doc/RAG.md +0 -129
- data/scout_commands/documenter +0 -148
- data/test/scout/llm/backends/test_openai.rb +0 -192
- data/test/scout/llm/backends/test_responses.rb +0 -238
- data/test/scout/llm/test_parse.rb +0 -98
data/doc/Improvements.md
ADDED
|
@@ -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.
|