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/README.md
CHANGED
|
@@ -1,326 +1,207 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
# Scout-AI
|
|
2
|
+
|
|
3
|
+
Scout-AI is a programmable agent harness: it supplies the machinery — persistent
|
|
4
|
+
conversations, real tools, context management, delegation, workflow-based
|
|
5
|
+
orchestration, provenance, and swappable inference backends — that turns an
|
|
6
|
+
LLM's reasoning into inspectable, reproducible agents. The model provides the
|
|
7
|
+
reasoning; Scout-AI provides everything else, and all of it is programmable.
|
|
8
|
+
|
|
9
|
+
Scout-AI is reasoning layered onto Scout's computational model: Scout turns
|
|
10
|
+
computation into persistent, composable, inspectable work; Scout-AI extends
|
|
11
|
+
that model to reasoning. It is an agent and LLM layer built on top of
|
|
12
|
+
[Scout](https://github.com/mikisvaz/scout-gear): tool calls run as real
|
|
13
|
+
workflow jobs, multi-agent orchestration as typed, inspectable workflow
|
|
14
|
+
tasks. New here? Start at **[doc/StartHere.md](doc/StartHere.md)**.
|
|
15
|
+
|
|
16
|
+
## The problem
|
|
17
|
+
|
|
18
|
+
An LLM call is not an agent: a raw API call produces one answer and leaves
|
|
19
|
+
nothing behind — no conversation to inspect, no grounding in your data, no
|
|
20
|
+
tools, no record of what ran. An agent needs machinery around the model:
|
|
21
|
+
**state** that persists and can be versioned, **context** as a view not a
|
|
22
|
+
destructive edit, **tools** that query real data and run real code,
|
|
23
|
+
**provenance** for the calls, jobs, and tokens behind an answer,
|
|
24
|
+
**iteration** so tool calls loop to a final answer, **orchestration** to
|
|
25
|
+
compose agents and jobs into pipelines. Scout-AI supplies each as a
|
|
26
|
+
first-class object.
|
|
27
|
+
|
|
28
|
+
None of that machinery is invented here: Scout already gives deterministic
|
|
29
|
+
computation persistence and provenance — a workflow runs as jobs, jobs
|
|
30
|
+
produce artifacts, steps record what ran. Scout-AI brings reasoning into
|
|
31
|
+
the same model — the agent's reasoning runs as a workflow job, its
|
|
32
|
+
conversation is a persisted artifact, and the next tool call or your own
|
|
33
|
+
code picks up from there.
|
|
34
|
+
|
|
35
|
+
## The four building blocks
|
|
36
|
+
|
|
37
|
+
| Concept | What it is | What problem it solves |
|
|
38
|
+
|---------|-----------|----------------------|
|
|
39
|
+
| **Chat** | A conversation format (plain text on disk, Array of hashes in memory) | Reproducibility: every conversation is inspectable, editable, and versionable |
|
|
40
|
+
| **Agent** | A stateful wrapper around a Chat with persistent defaults and tools | Persistence: your agent keeps its system prompt, tools, and options across conversations |
|
|
41
|
+
| **Tools** | Callable functions the LLM can invoke during inference | Grounding: the model can query real data and run real code instead of hallucinating |
|
|
42
|
+
| **Inference Endpoint** | A named configuration for a provider + model + credentials | Portability: switch provider or model without changing application code |
|
|
43
|
+
|
|
44
|
+
They compose: an agent holds a chat, carries tools, and sends the chat to a named
|
|
45
|
+
endpoint — [CoreConcepts](doc/user/CoreConcepts.md).
|
|
46
|
+
|
|
47
|
+
## What makes it different
|
|
48
|
+
|
|
49
|
+
**Conversations are plain data.** A Chat is a plain-text file on disk and an Array of message
|
|
50
|
+
hashes in memory; `Chat` is an annotation over Array (`chat.class # => Array`), so standard
|
|
51
|
+
Array operations work and every conversation serializes to the same diffable format. Context
|
|
52
|
+
management is ephemeral: strategies reshape what the model sees while the stored chat
|
|
53
|
+
retains full-fidelity data.
|
|
54
|
+
→ [WritingChats](doc/user/WritingChats.md) · [ManagingContext](doc/user/ManagingContext.md)
|
|
55
|
+
|
|
56
|
+
**Tools are real Scout workflow jobs.** Tools come from three sources — Scout workflow
|
|
57
|
+
tasks, knowledge base databases, MCP servers. A task's typed inputs and outputs become
|
|
58
|
+
the tool parameter schema, the call runs as a real workflow job with dependency resolution
|
|
59
|
+
and caching, and the tool-calling loop is automatic, including multi-tool iterations.
|
|
60
|
+
→ [ToolCalling](doc/user/ToolCalling.md)
|
|
61
|
+
|
|
62
|
+
**Agent architecture as code.** An agent is a named directory — `start_chat`, `workflow.rb`,
|
|
63
|
+
`knowledge_base/`, `python/` — discovered by convention, no registration calls or plugin
|
|
64
|
+
manifests. Agents delegate to each other: `socialize` exposes one generic `ask` tool where
|
|
65
|
+
the model picks the specialist, `delegate` pre-registers named `hand_off_to_<name>` tools,
|
|
66
|
+
and inheritance modes (`none`, `tools`, `conversation`) control how much caller context
|
|
67
|
+
flows to the specialist; named conversations persist across calls.
|
|
68
|
+
→ [BuildingAgents](doc/user/BuildingAgents.md) · [Delegation](doc/user/Delegation.md)
|
|
69
|
+
|
|
70
|
+
**Multi-agent orchestration as typed, inspectable workflow jobs.** Include the
|
|
71
|
+
`AgentWorkflow` mixin and use `chat_task`: each agent run becomes a Scout workflow job
|
|
72
|
+
with caching, provenance, and dependency tracking; documented patterns include linear
|
|
73
|
+
pipelines, manager-worker, critic loops, branched exploration, and artifact-first
|
|
74
|
+
collaboration.
|
|
75
|
+
→ [MultiAgentWorkflows](doc/user/MultiAgentWorkflows.md)
|
|
76
|
+
|
|
77
|
+
**Provenance and inspectable, reproducible runs.** Provenance is modeled over exactly two
|
|
78
|
+
node kinds — chat files and workflow steps — traversed by `Chat.traverse_provenance`.
|
|
79
|
+
Per-inference metadata records token usage with `inference_id`-based deduplication,
|
|
80
|
+
delegated-agent receipts embed child inference evidence in parent tool outputs, and
|
|
81
|
+
inference results are persisted by default; `scout-ai llm prov <chat>` renders tree, flow,
|
|
82
|
+
DOT, and evidence views. The inspectability story is one chain: agent decision → tool call
|
|
83
|
+
→ workflow job → dependent jobs → artifacts → provenance.
|
|
84
|
+
→ [Provenance](doc/developer/Provenance.md)
|
|
85
|
+
|
|
86
|
+
**Model independence as an architectural property.** Backends are stateless module
|
|
87
|
+
adapters composed with the shared inference pipeline — no abstract base class — and unknown
|
|
88
|
+
backend names resolve as module names, so third-party backends load dynamically. Providers
|
|
89
|
+
are addressed through named endpoints: your agent code and chat files stay the same across
|
|
90
|
+
OpenAI, Anthropic, Ollama, vLLM and other OpenAI-compatible servers, AWS Bedrock, and more.
|
|
91
|
+
→ [Backends](doc/developer/Backends.md) · [RunningInference](doc/user/RunningInference.md)
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
The Scout stack (each layer sits on the one below):
|
|
95
|
+
scout-ai chats, agents, tools, orchestration
|
|
96
|
+
scout-gear workflow engine, knowledge bases, TSV
|
|
97
|
+
scout-essentials paths, IO, persistence, caching, log
|
|
98
|
+
|
|
99
|
+
Inside scout-ai:
|
|
100
|
+
LLM.ask LLM.chat LLM.load_agent
|
|
101
|
+
| | |
|
|
102
|
+
Backend LLM::Agent Tools
|
|
103
|
+
(adapter) (stateful) (WF/KB/MCP)
|
|
104
|
+
| holds | task tools
|
|
105
|
+
v v
|
|
106
|
+
Chat <--------- Workflow jobs
|
|
107
|
+
(Array + Annotation) as tools
|
|
49
108
|
```
|
|
50
109
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Backends and endpoints can be configured via:
|
|
54
|
-
|
|
55
|
-
- per-endpoint YAML files (recommended): `~/.scout/etc/AI/<endpoint>`
|
|
56
|
-
- environment variables per backend (see `doc/LLM.md`)
|
|
57
|
-
|
|
58
|
-
Most teams create a few named endpoints (e.g. `nano`, `deep`, `ollama`) and then reference them with:
|
|
59
|
-
|
|
60
|
-
- Ruby: `endpoint: :nano`
|
|
61
|
-
- CLI: `-e nano`
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
## Quick starts
|
|
65
|
-
|
|
66
|
-
### Configure an endpoint (once)
|
|
67
|
-
|
|
68
|
-
Create `~/.scout/etc/AI/nano`:
|
|
110
|
+
Dependency direction is Agent → Chat → Annotation: Chat and backends work without an
|
|
111
|
+
agent, agents without the workflow mixin — [Architecture](doc/developer/Architecture.md).
|
|
69
112
|
|
|
70
|
-
|
|
71
|
-
backend: responses
|
|
72
|
-
model: gpt-5-nano
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Or a higher-effort endpoint `~/.scout/etc/AI/deep`:
|
|
113
|
+
## Quick taste
|
|
76
114
|
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
reasoning_effort: high
|
|
81
|
-
text_verbosity: high
|
|
115
|
+
```bash
|
|
116
|
+
scout-ai llm ask "What is the capital of France?" # one question
|
|
117
|
+
scout-ai llm ask -c hello.chat # run a saved conversation
|
|
82
118
|
```
|
|
83
119
|
|
|
84
|
-
|
|
120
|
+
When using the `-c` option the result is appended into the chat file.
|
|
85
121
|
|
|
86
|
-
|
|
122
|
+
A chat file — write it by hand, run it, edit it, diff it:
|
|
87
123
|
|
|
88
|
-
|
|
124
|
+
If agents are used, either through the `scout-ai agent ask` or defined inside
|
|
125
|
+
the chat file, additional logs are placed in a sidecar directory (e.g.
|
|
126
|
+
`hello.chat.files/log/`) storing all chats across the agentic society (agents can
|
|
127
|
+
delegate on other agents).
|
|
89
128
|
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
answer = LLM.ask "What is the capital of France?", endpoint: :nano
|
|
93
|
-
puts answer
|
|
94
|
-
```
|
|
129
|
+
```text
|
|
130
|
+
system:
|
|
95
131
|
|
|
96
|
-
|
|
132
|
+
You are a friendly assistant.
|
|
97
133
|
|
|
98
|
-
|
|
99
|
-
scout-ai llm ask -e nano "What is the capital of France?"
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Chat builder:
|
|
134
|
+
user:
|
|
103
135
|
|
|
104
|
-
|
|
105
|
-
chat = Chat.setup []
|
|
106
|
-
chat.system "You are a terse assistant"
|
|
107
|
-
chat.user "List three colors"
|
|
108
|
-
puts chat.ask(endpoint: :nano)
|
|
136
|
+
What is 2 + 2?
|
|
109
137
|
```
|
|
110
138
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Export Workflow tasks as callable tools—let the model call them functionally.
|
|
114
|
-
|
|
115
|
-
```ruby
|
|
116
|
-
require 'scout-gear' # defines Workflow
|
|
117
|
-
|
|
118
|
-
m = Module.new do
|
|
119
|
-
extend Workflow
|
|
120
|
-
self.name = "Registration"
|
|
121
|
-
|
|
122
|
-
input :name, :string
|
|
123
|
-
input :age, :integer
|
|
124
|
-
input :gender, :select, nil, select_options: %w(male female)
|
|
125
|
-
task :person => :yaml do
|
|
126
|
-
inputs.to_hash
|
|
127
|
-
end
|
|
128
|
-
end
|
|
139
|
+
An agent is a directory, invoked by name
|
|
140
|
+
(`scout-ai agent ask Greeter "Hi, I'm Alice!"`):
|
|
129
141
|
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
```text
|
|
143
|
+
Agent/Greeter/
|
|
144
|
+
start_chat # system prompt + tool declarations
|
|
145
|
+
workflow.rb # optional Scout workflow providing tools
|
|
132
146
|
```
|
|
133
147
|
|
|
134
|
-
|
|
148
|
+
A multi-agent pipeline is an ordinary Scout workflow (module with
|
|
149
|
+
`extend Workflow; include AgentWorkflow`); more recipes in
|
|
150
|
+
[Cookbook](doc/user/Cookbook.md):
|
|
135
151
|
|
|
136
152
|
```ruby
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
kb = KnowledgeBase.new dir
|
|
141
|
-
kb.register :brothers, datafile_test(:person).brothers, undirected: true
|
|
142
|
-
kb.register :marriages, datafile_test(:person).marriages,
|
|
143
|
-
undirected: true, source: "=>Alias", target: "=>Alias"
|
|
144
|
-
kb.register :parents, datafile_test(:person).parents
|
|
145
|
-
|
|
146
|
-
agent = LLM::Agent.new(knowledge_base: kb, endpoint: :nano)
|
|
153
|
+
chat_task :analyze do |input|
|
|
154
|
+
agent = self.agent('Analyst', chat: chat)
|
|
155
|
+
agent.socialize # may delegate to specialists
|
|
147
156
|
agent.start
|
|
148
|
-
agent.user
|
|
149
|
-
|
|
157
|
+
agent.user input
|
|
158
|
+
agent.chat
|
|
150
159
|
end
|
|
151
160
|
```
|
|
152
161
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
```ruby
|
|
156
|
-
agent = LLM::Agent.new(endpoint: :nano)
|
|
157
|
-
agent.iterate("List three steps to bake bread") { |step| puts "- #{step}" }
|
|
158
|
-
|
|
159
|
-
agent.iterate_dictionary("Give capital cities for FR, ES, IT") do |country, capital|
|
|
160
|
-
puts "#{country}: #{capital}"
|
|
161
|
-
end
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Use a Hugging Face classifier inside a Workflow
|
|
165
|
-
|
|
166
|
-
From the ExTRI2 workflow (see below):
|
|
162
|
+
## Installation
|
|
167
163
|
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
model.extract_features do |_, rows|
|
|
174
|
-
rows.map do |text, tf, tg|
|
|
175
|
-
text.sub("[TF]", "<TF>#{tf}</TF>").sub("[TG]", "<TG>#{tg}</TG>")
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
model.init
|
|
180
|
-
preds = model.eval_list tsv.slice(%w(Text TF Gene)).values
|
|
181
|
-
tsv.add_field "Valid score" do
|
|
182
|
-
non_valid, valid = preds.shift
|
|
183
|
-
Misc.softmax([valid, non_valid]).first rescue 0
|
|
184
|
-
end
|
|
164
|
+
```bash
|
|
165
|
+
gem install scout-ai
|
|
166
|
+
export OPENAI_API_KEY="sk-..."
|
|
167
|
+
scout-ai config set openai model=gpt-4o
|
|
185
168
|
```
|
|
186
169
|
|
|
170
|
+
Requires Ruby 3.0+. Endpoints, providers, CLI:
|
|
171
|
+
[RunningInference](doc/user/RunningInference.md); first-run walkthrough:
|
|
172
|
+
[GettingStarted](doc/user/GettingStarted.md).
|
|
187
173
|
|
|
188
|
-
##
|
|
189
|
-
|
|
190
|
-
### LLM (doc/LLM.md)
|
|
191
|
-
|
|
192
|
-
A compact, multi‑backend layer to ask LLMs, wire function‑calling tools, parse/print chats, and compute embeddings.
|
|
193
|
-
|
|
194
|
-
- `LLM.ask(question, options={}, &block)` — compile `question` via `LLM.chat`, merge endpoint/model/format options, call backend
|
|
195
|
-
- Backends: Responses, OpenAI, Anthropic, Ollama, vLLM, OpenWebUI, AWS Bedrock, Relay
|
|
196
|
-
- Tools: export Workflow tasks and KnowledgeBase databases as function tools
|
|
197
|
-
- Chat compilation pipeline: imports, clear/skip, tasks/jobs, files/directories
|
|
198
|
-
- Endpoint configuration: `~/.scout/etc/AI/<endpoint>`
|
|
199
|
-
|
|
200
|
-
### Chat (doc/Chat.md)
|
|
201
|
-
|
|
202
|
-
Chat is both:
|
|
203
|
-
|
|
204
|
-
- a builder over an Array of `{role:, content:}` messages
|
|
205
|
-
- a stable on-disk “chat file” format used by the CLI
|
|
206
|
-
|
|
207
|
-
See `doc/Chat.md` for the full list of special roles (options, tools, imports, files, tasks, MCP, KB).
|
|
208
|
-
|
|
209
|
-
### Agent (doc/Agent.md)
|
|
210
|
-
|
|
211
|
-
An Agent is a stateful wrapper around Chat and LLM:
|
|
212
|
-
|
|
213
|
-
- maintains a current conversation (`start_chat`, `start`, `current_chat`)
|
|
214
|
-
- auto-exports Workflow tasks and KnowledgeBase databases as tools
|
|
215
|
-
- provides `chat/json/json_format/iterate` helpers
|
|
216
|
-
|
|
217
|
-
### Model (doc/Model.md)
|
|
218
|
-
|
|
219
|
-
A composable framework to wrap models with a consistent API:
|
|
220
|
-
|
|
221
|
-
- ScoutModel — base: define init/eval/eval_list/extract_features/post_process/train; persist behavior and state to a directory
|
|
222
|
-
- PythonModel — initialize and drive a Python class via ScoutPython
|
|
223
|
-
- TorchModel — helpers for PyTorch: training loop, tensors, save/load state, layer introspection
|
|
224
|
-
- HuggingfaceModel — Transformers convenience; specializations:
|
|
225
|
-
- SequenceClassificationModel — text classification, logits→labels
|
|
226
|
-
- CausalModel — chat/causal generation (supports apply_chat_template)
|
|
227
|
-
- NextTokenModel — simple next‑token fine‑tuning loop
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
## Example: ExTRI2 workflow (models in practice)
|
|
231
|
-
|
|
232
|
-
The ExTRI2 Workflow (Rbbt‑Workflows) uses HuggingfaceModel to score TRI sentences and determine Mode of Regulation (MoR):
|
|
233
|
-
|
|
234
|
-
- Feature extraction marks [TF]/[TG] spans as inline tags for the model
|
|
235
|
-
- Batch evaluation over a TSV (“Text”, “TF”, “Gene” columns)
|
|
236
|
-
- Adds fields “Valid score” and “Valid” to the TSV
|
|
237
|
-
- Runs a second SequenceClassification model to produce “MoR” and “MoR scores”
|
|
238
|
-
|
|
239
|
-
See workflow.rb in that repository for the full implementation. http://github.com/Rbbt-Workflows/ExTRI2
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
## Command‑Line Interface
|
|
243
|
-
|
|
244
|
-
The bin/scout dispatcher locates scripts under scout_commands across installed packages and workflows using the Path subsystem.
|
|
245
|
-
|
|
246
|
-
You can run it as:
|
|
247
|
-
|
|
248
|
-
- `scout ...` (the standard Scout CLI), or
|
|
249
|
-
- `scout-ai ...` (a thin wrapper that loads Scout with `scout-ai` available)
|
|
250
|
-
|
|
251
|
-
### scout llm …
|
|
252
|
-
|
|
253
|
-
Ask an LLM, manage chat files, run a minimal web UI, or process queued requests. Scripts live under scout_commands/llm.
|
|
254
|
-
|
|
255
|
-
- Ask
|
|
256
|
-
- `scout llm ask [options] [question]`
|
|
257
|
-
- `scout-ai llm ask [options] [question]`
|
|
258
|
-
- -t|--template <file_or_key> — load a prompt template; substitutes “???” or appends
|
|
259
|
-
- -c|--chat <chat_file> — load/extend a conversation (appends the reply)
|
|
260
|
-
- -i|--inline <file> — answer “# ask: …” directives inline in a source file
|
|
261
|
-
- -f|--file <file> — prepend file content or substitute where “...” appears
|
|
262
|
-
- -m|--model, -e|--endpoint, -b|--backend — select backend/model; merged with endpoint configs
|
|
263
|
-
- -d|--dry_run — expand and print the conversation (no ask)
|
|
264
|
-
|
|
265
|
-
- Relay processor (for the Relay backend)
|
|
266
|
-
- `scout llm process [directory]` — watches a queue directory and answers ask JSONs
|
|
267
|
-
|
|
268
|
-
- Web UI server
|
|
269
|
-
- `scout llm server` — static chat UI over ./chats with a small JSON API
|
|
270
|
-
|
|
271
|
-
- Templates
|
|
272
|
-
- `scout llm template` — list installed prompt templates (Scout.questions)
|
|
273
|
-
|
|
274
|
-
Run `scout llm` alone to see available subcommands.
|
|
275
|
-
|
|
276
|
-
### scout agent …
|
|
277
|
-
|
|
278
|
-
Stateful agents with Workflow and KnowledgeBase tooled up. Scripts live under scout_commands/agent.
|
|
279
|
-
|
|
280
|
-
- Ask via an Agent
|
|
281
|
-
- `scout agent ask [options] [agent_name] [question]`
|
|
282
|
-
- `scout-ai agent ask [options] [agent_name] [question]`
|
|
283
|
-
- -l|--log <level> — set log severity
|
|
284
|
-
- -t|--template <file_or_key>
|
|
285
|
-
- -c|--chat <chat_file>
|
|
286
|
-
- -m|--model, -e|--endpoint
|
|
287
|
-
- -f|--file <path>
|
|
288
|
-
- -wt|--workflow_tasks <comma_list> — export only selected tasks
|
|
289
|
-
- agent_name resolves via Scout.workflows[agent_name] (a workflow) or Scout.chats[agent_name] (an agent directory with workflow.rb/knowledge_base/start_chat)
|
|
290
|
-
|
|
291
|
-
- KnowledgeBase passthrough
|
|
292
|
-
- `scout agent kb <agent_name> <kb subcommand...>`
|
|
293
|
-
|
|
294
|
-
Note: Workflows also have extensive CLI commands (`scout workflow …`) for job execution, provenance, orchestration, and queue processing.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
## Configuration, persistence and reproducibility
|
|
298
|
-
|
|
299
|
-
- Endpoint presets: place YAML under `~/.scout/etc/AI/<endpoint>` to preconfigure url/model/backend and backend-specific knobs
|
|
300
|
-
- Tool calling: Workflow tasks are exported as JSON schemas per backend; results are serialized back to the model as tool replies
|
|
301
|
-
- Caching: `LLM.ask` persists responses (by default) using `Persist.persist`; disable with `persist: false`
|
|
302
|
-
- Chats: save printable conversations with Chat#save; reuse with `scout-ai llm ask -c <file>`
|
|
174
|
+
## Python
|
|
303
175
|
|
|
176
|
+
Use chats and agents from Python through the thin SDK in
|
|
177
|
+
[python/README.md](python/README.md) (`from scout_ai import load_agent`),
|
|
178
|
+
which delegates execution to the Ruby runtime; and write agent tools in Python — a `python/` subdirectory of an agent directory is auto-loaded as workflow tasks ([doc/user/Python.md](doc/user/Python.md)).
|
|
304
179
|
|
|
305
180
|
## Where to go next
|
|
306
181
|
|
|
307
|
-
|
|
308
|
-
- doc/LLM.md — orchestration, endpoints, backends, tools, CLI
|
|
309
|
-
- doc/Chat.md — chat files: roles/options and compilation behavior
|
|
310
|
-
- doc/Agent.md — stateful agents, Workflow/KB wiring, delegation, iterate helpers
|
|
311
|
-
- doc/Model.md — model wrappers; ScoutModel, Python/Torch/Hugging Face
|
|
312
|
-
|
|
313
|
-
- Browse real‑world workflows (including ExTRI2) in Rbbt‑Workflows:
|
|
314
|
-
- https://github.com/Rbbt-Workflows
|
|
182
|
+
[doc/StartHere.md](doc/StartHere.md) is the documentation entry point:
|
|
315
183
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
184
|
+
| Task | Reading path |
|
|
185
|
+
|---|---|
|
|
186
|
+
| Build my first agent | [GettingStarted](doc/user/GettingStarted.md) → [CoreConcepts](doc/user/CoreConcepts.md) → [BuildingAgents](doc/user/BuildingAgents.md) |
|
|
187
|
+
| Wire up tools | [ToolCalling](doc/user/ToolCalling.md) → [Python](doc/user/Python.md) |
|
|
188
|
+
| Configure inference | [RunningInference](doc/user/RunningInference.md) → [ManagingContext](doc/user/ManagingContext.md) |
|
|
189
|
+
| Build multi-agent systems | [Delegation](doc/user/Delegation.md) → [MultiAgentWorkflows](doc/user/MultiAgentWorkflows.md) → [DelegationInternals](doc/developer/DelegationInternals.md) |
|
|
190
|
+
| Understand the internals | [Architecture](doc/developer/Architecture.md) → [ChatLifecycle](doc/developer/ChatLifecycle.md) → [Backends](doc/developer/Backends.md) |
|
|
191
|
+
| Track provenance | [Provenance](doc/developer/Provenance.md) |
|
|
192
|
+
| Deep code investigations | [research/](research/) (unmaintained reports) |
|
|
319
193
|
|
|
320
|
-
|
|
321
|
-
- https://github.com/mikisvaz/scout-rig
|
|
194
|
+
## Ecosystem
|
|
322
195
|
|
|
196
|
+
Scout-AI is part of the Scout stack, all under
|
|
197
|
+
[github.com/mikisvaz](https://github.com/mikisvaz): the two layers shown above, plus
|
|
198
|
+
[scout-rig](https://github.com/mikisvaz/scout-rig) (language bridges, Python) and
|
|
199
|
+
[scout-camp](https://github.com/mikisvaz/scout-camp) (servers, cloud, web). Scout
|
|
200
|
+
originates from the Rbbt ecosystem; example workflows live in
|
|
201
|
+
[Rbbt-Workflows](https://github.com/Rbbt-Workflows). The machine-learning model
|
|
202
|
+
subsystem is documented separately in [doc/Model.md](doc/Model.md) and is intentionally
|
|
203
|
+
standalone from the agent layer.
|
|
323
204
|
|
|
324
|
-
## License
|
|
205
|
+
## License
|
|
325
206
|
|
|
326
|
-
|
|
207
|
+
MIT-style, see [LICENSE.txt](LICENSE.txt). Issues and PRs welcome.
|
data/Rakefile
CHANGED
|
@@ -26,10 +26,26 @@ Juwelier::RubygemsDotOrgTasks.new
|
|
|
26
26
|
require 'rake/testtask'
|
|
27
27
|
Rake::TestTask.new(:test) do |test|
|
|
28
28
|
test.libs << 'lib' << 'test'
|
|
29
|
-
|
|
29
|
+
# Unit tests only: real-infrastructure tests live under test/integration
|
|
30
|
+
# and are collected by the separate :test_integration task.
|
|
31
|
+
# ScoutCoder: Rake::TestTask#file_list concatenates pattern and test_files,
|
|
32
|
+
# so setting pattern here would leak test/integration/** into `rake test`;
|
|
33
|
+
# assigning only the already-excluded FileList to test_files keeps the
|
|
34
|
+
# default suite unit-only.
|
|
35
|
+
test.test_files = FileList['test/**/test_*.rb'].exclude('test/integration/**/test_*.rb')
|
|
30
36
|
test.verbose = true
|
|
31
37
|
end
|
|
32
38
|
|
|
39
|
+
desc "Run infrastructure tests (test/integration/**/test_*.rb): real inference through the 'test' endpoint or the default, plus per-backend endpoint probes"
|
|
40
|
+
Rake::TestTask.new(:test_infrastructure) do |test|
|
|
41
|
+
test.libs << 'lib' << 'test'
|
|
42
|
+
test.pattern = 'test/integration/**/test_*.rb'
|
|
43
|
+
test.verbose = true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
desc "Alias of test_infrastructure"
|
|
47
|
+
task :test_integration => :test_infrastructure
|
|
48
|
+
|
|
33
49
|
desc "Code coverage detail"
|
|
34
50
|
task :simplecov do
|
|
35
51
|
ENV['COVERAGE'] = "true"
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2.0.0
|