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
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Test support: LLM::Mock, an offline scripted backend.
|
|
2
|
+
#
|
|
3
|
+
# Not named test_*.rb on purpose: the Rakefile test pattern
|
|
4
|
+
# ('test/**/test_*.rb') must not collect this file.
|
|
5
|
+
#
|
|
6
|
+
# Registered into LLM::BACKENDS so it is reachable from LLM.ask / LLM.embed
|
|
7
|
+
# once the endpoint yaml selects `backend: mock`.
|
|
8
|
+
#
|
|
9
|
+
# Scripting model
|
|
10
|
+
# ---------------
|
|
11
|
+
# LLM::Mock.responses = ['an answer']
|
|
12
|
+
# LLM::Mock.responses = [{role: 'assistant', content: 'an answer'}]
|
|
13
|
+
# LLM::Mock.responses = ['first', {tool_calls: [{name: 'f', arguments: {}}]}, 'final']
|
|
14
|
+
# LLM::Mock.script('a') { ... } # same, resetting first
|
|
15
|
+
#
|
|
16
|
+
# Each response entry may be:
|
|
17
|
+
# * a String -> plain answer
|
|
18
|
+
# * a Hash message (role/content) -> one message
|
|
19
|
+
# * an Array of Hash messages -> several messages at once
|
|
20
|
+
# * a Hash with :tool_calls -> tool call round: the calls are
|
|
21
|
+
# delegated to LLM.process_calls (using options[:tools]) so the
|
|
22
|
+
# function_call / function_call_output messages match the real backends
|
|
23
|
+
# * a Proc called with (messages, options) returning any of the above
|
|
24
|
+
# * an Exception instance -> raised
|
|
25
|
+
#
|
|
26
|
+
# Entries replay in order; when exhausted the last entry repeats.
|
|
27
|
+
#
|
|
28
|
+
# Tool loops: the real backends return output ending in a
|
|
29
|
+
# function_call_output message and then re-enter `ask` with
|
|
30
|
+
# messages + output (Backend#chain_tools). LLM.ask dispatches to the backend
|
|
31
|
+
# only once, so the mock drives the same rounds internally; to keep tests
|
|
32
|
+
# able to assert on what the model would see next, every round is recorded
|
|
33
|
+
# in `.calls` with the messages accumulated so far (round 1 = the original
|
|
34
|
+
# messages, round 2 = messages + marriages output, ...), matching the shape
|
|
35
|
+
# of the repeated asks of the real backends.
|
|
36
|
+
#
|
|
37
|
+
# ScoutCoder: IndiferentHash#pretty_print takes 0 args while Ruby's PP passes
|
|
38
|
+
# 1, so pp-ing one of these hashes inside a test failure (assertion diffs call
|
|
39
|
+
# PP) raises ArgumentError and hides the real failure. Use Log.fingerprint or
|
|
40
|
+
# .inspect when debugging IndiferentHash values in tests instead of pp.
|
|
41
|
+
module LLM
|
|
42
|
+
module Mock
|
|
43
|
+
DIMENSIONS = 64
|
|
44
|
+
|
|
45
|
+
class << self
|
|
46
|
+
attr_accessor :responses
|
|
47
|
+
|
|
48
|
+
def script(*responses, &block)
|
|
49
|
+
self.reset!
|
|
50
|
+
@responses = responses.flatten
|
|
51
|
+
@setup = block if block_given?
|
|
52
|
+
self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def reset!
|
|
56
|
+
@responses = []
|
|
57
|
+
@index = 0
|
|
58
|
+
@calls = []
|
|
59
|
+
@setup = nil
|
|
60
|
+
@tool_definitions = {}
|
|
61
|
+
self
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def calls
|
|
65
|
+
@calls ||= []
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def next_response(messages = nil, options = {})
|
|
69
|
+
@index ||= 0
|
|
70
|
+
@responses = [@responses].flatten.compact
|
|
71
|
+
entry = @responses[@index] || @responses.last
|
|
72
|
+
@index += 1
|
|
73
|
+
|
|
74
|
+
if Proc === entry
|
|
75
|
+
entry = entry.call(messages, options)
|
|
76
|
+
end
|
|
77
|
+
entry
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def index
|
|
81
|
+
@index ||= 0
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#{{{ ask
|
|
85
|
+
|
|
86
|
+
# Tool definitions resolved for the last ask (same {name => [obj, def]}
|
|
87
|
+
# shape the real backends build), for assertions.
|
|
88
|
+
def tool_definitions
|
|
89
|
+
@tool_definitions ||= {}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def ask(messages, options = {}, &block)
|
|
93
|
+
messages = Chat.setup(Chat.prepare_prompt(messages)) unless Array === messages
|
|
94
|
+
options = IndiferentHash.setup(options.dup)
|
|
95
|
+
|
|
96
|
+
# Mirror Backend::ClassMethods: resolve tool:/kb:/association:
|
|
97
|
+
# directives (and explicit options[:tools]) once per ask. LLM.tools
|
|
98
|
+
# consumes the directive messages, so resolve before recording.
|
|
99
|
+
@tool_definitions = LLM::Mock.tools(messages, options)
|
|
100
|
+
|
|
101
|
+
tool_calls, response = [], []
|
|
102
|
+
round_messages = messages
|
|
103
|
+
|
|
104
|
+
loop do
|
|
105
|
+
calls << [round_messages, options]
|
|
106
|
+
|
|
107
|
+
entry = next_response(round_messages, options)
|
|
108
|
+
|
|
109
|
+
case entry
|
|
110
|
+
when Hash
|
|
111
|
+
if entry[:tool_calls]
|
|
112
|
+
script_calls = entry[:tool_calls].collect do |info|
|
|
113
|
+
info = IndiferentHash.setup(info.dup)
|
|
114
|
+
{ name: info[:name] || info.dig(:function, :name),
|
|
115
|
+
arguments: info[:arguments] || info.dig(:function, :arguments) || {},
|
|
116
|
+
id: info[:id] || info[:call_id] || "call_#{@index}" }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
new_calls = LLM.process_calls(tool_definitions, script_calls, &block).flatten
|
|
120
|
+
tool_calls.concat new_calls
|
|
121
|
+
# next round sees the original messages plus the tool call
|
|
122
|
+
# round, exactly like Backend#chain_tools does
|
|
123
|
+
round_messages = Chat.setup(messages + tool_calls)
|
|
124
|
+
next
|
|
125
|
+
else
|
|
126
|
+
response << IndiferentHash.setup(entry.dup)
|
|
127
|
+
end
|
|
128
|
+
when Array
|
|
129
|
+
entry.each { |m| response << IndiferentHash.setup(m.dup) }
|
|
130
|
+
when String
|
|
131
|
+
response << IndiferentHash.setup(role: :assistant, content: entry)
|
|
132
|
+
when nil
|
|
133
|
+
response << IndiferentHash.setup(role: :assistant, content: '')
|
|
134
|
+
else
|
|
135
|
+
raise Exception, entry if Exception === entry
|
|
136
|
+
response << IndiferentHash.setup(role: :assistant, content: entry.to_s)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
break
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
output = (tool_calls + response).flatten
|
|
143
|
+
|
|
144
|
+
if options[:return_messages]
|
|
145
|
+
Chat.setup output
|
|
146
|
+
else
|
|
147
|
+
Chat.setup(output)
|
|
148
|
+
cleaned = Chat.clean(output)
|
|
149
|
+
return '' if cleaned.nil? || cleaned.empty?
|
|
150
|
+
cleaned.last[:content]
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Mirrors Backend::ClassMethods#tools: explicit options[:tools] plus the
|
|
155
|
+
# tool:/kb:/association: directives resolved from the messages
|
|
156
|
+
# (LLM.tools / LLM.associations -> Chat.tools / Chat.associations), so a
|
|
157
|
+
# scripted tool-call round exercises the same object/definition pairing
|
|
158
|
+
# the real backends use ({name => [obj, definition]}).
|
|
159
|
+
#
|
|
160
|
+
# ScoutCoder: 'tool:'/'association:'/'kb:' chat directives are NOT
|
|
161
|
+
# resolved by LLM.ask itself; each backend's #tools(messages, options)
|
|
162
|
+
# does it, and it *deletes* options[:tools] while at it. A custom backend
|
|
163
|
+
# registered in LLM::BACKENDS therefore has to call LLM.tools /
|
|
164
|
+
# LLM.associations itself or the directives are silently dropped.
|
|
165
|
+
def tools(messages, options)
|
|
166
|
+
tools = options[:tools]
|
|
167
|
+
|
|
168
|
+
case tools
|
|
169
|
+
when Array
|
|
170
|
+
tools = tools.inject({}) do |acc, definition|
|
|
171
|
+
definition = definition[:function] if Hash === definition && definition[:function] && definition[:name].nil?
|
|
172
|
+
acc.merge(definition[:name] => [nil, definition])
|
|
173
|
+
end
|
|
174
|
+
when nil
|
|
175
|
+
tools = {}
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
tools.merge!(LLM.tools(messages))
|
|
179
|
+
tools.merge!(LLM.associations(messages))
|
|
180
|
+
tools
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
#{{{ embed
|
|
184
|
+
|
|
185
|
+
# Deterministic bag-of-words embedding: each downcased word is hashed to
|
|
186
|
+
# a dimension and counted, then L2-normalized, so identical texts yield
|
|
187
|
+
# identical vectors and texts sharing words land near each other
|
|
188
|
+
# (cosine) for RAG nearest-neighbour assertions.
|
|
189
|
+
def embed(text, _options = {})
|
|
190
|
+
case text
|
|
191
|
+
when Array
|
|
192
|
+
text.collect { |t| embed_one(t) }
|
|
193
|
+
else
|
|
194
|
+
embed_one(text)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def embed_one(text)
|
|
199
|
+
vector = Array.new(DIMENSIONS, 0.0)
|
|
200
|
+
|
|
201
|
+
text.to_s.downcase.split(/\W+/).each do |word|
|
|
202
|
+
next if word.empty?
|
|
203
|
+
position = word.sum % DIMENSIONS
|
|
204
|
+
vector[position] += 1.0
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
norm = Math.sqrt(vector.inject(0.0) { |acc, v| v * v })
|
|
208
|
+
return vector if norm.zero?
|
|
209
|
+
vector.collect { |v| v / norm }
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
LLM::BACKENDS[:mock] = LLM::Mock
|
data/test/test_helper.rb
CHANGED
|
@@ -2,6 +2,36 @@ require 'test/unit'
|
|
|
2
2
|
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
|
3
3
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
|
4
4
|
require 'scout'
|
|
5
|
+
require 'scout-ai'
|
|
6
|
+
|
|
7
|
+
# Offline test endpoints/fixtures support. Files under test/support are
|
|
8
|
+
# deliberately NOT named test_*.rb so the Rakefile pattern
|
|
9
|
+
# ('test/**/test_*.rb') does not collect them as tests.
|
|
10
|
+
require File.join(File.dirname(__FILE__), 'support', 'fixtures')
|
|
11
|
+
require File.join(File.dirname(__FILE__), 'support', 'mock_backend')
|
|
12
|
+
require File.join(File.dirname(__FILE__), 'support', 'fake_clients')
|
|
13
|
+
require File.join(File.dirname(__FILE__), 'support', 'availability')
|
|
14
|
+
|
|
15
|
+
# ScoutCoder: Scout.etc.AI['name'] resolves through the Scout path maps, and
|
|
16
|
+
# the first map in Scout.map_order wins. Scout.prepend_path(:name, map) adds
|
|
17
|
+
# the map AND unshifts it into map_order, which is what makes the repo-local
|
|
18
|
+
# test/etc tree take precedence over ~/.scout/etc. Note the map must include
|
|
19
|
+
# the literal '{TOPLEVEL}/{SUBPATH}' suffix and, because the path is 'etc/AI'
|
|
20
|
+
# (TOPLEVEL 'etc', SUBPATH 'AI'), the map root must be the test directory so
|
|
21
|
+
# it expands to <repo>/test/etc/AI/... .
|
|
22
|
+
#
|
|
23
|
+
# Only the offline 'mock' endpoint lives here. In particular the repo does
|
|
24
|
+
# NOT define a 'test' endpoint: 'test' is expected to be provided at
|
|
25
|
+
# installation level (~/.scout/etc/AI/test.yaml) and is consumed by the
|
|
26
|
+
# infrastructure suite (`rake test_infrastructure`), never by `rake test`.
|
|
27
|
+
Scout.prepend_path :test_etc, File.join(File.expand_path(File.dirname(__FILE__)), '{TOPLEVEL}/{SUBPATH}')
|
|
28
|
+
|
|
29
|
+
# Default offline LLM configuration for the unit tests: backend is the
|
|
30
|
+
# registered LLM::Mock (test/support/mock_backend.rb). No endpoint is set
|
|
31
|
+
# at all, so no endpoint yaml is ever resolved on the unit path and no real
|
|
32
|
+
# inference service can be reached from `rake test`.
|
|
33
|
+
Scout::Config.set({backend: :mock}, :ask, :llm)
|
|
34
|
+
Scout::Config.set({backend: :mock}, :embed, :llm)
|
|
5
35
|
|
|
6
36
|
class Test::Unit::TestCase
|
|
7
37
|
|
|
@@ -27,8 +57,9 @@ class Test::Unit::TestCase
|
|
|
27
57
|
Workflow.directory = tmpdir.var.jobs
|
|
28
58
|
Workflow.workflows.each{|wf| wf.directory = Workflow.directory[wf.name] }
|
|
29
59
|
Entity.entity_property_cache = tmpdir.entity_properties if defined?(Entity)
|
|
60
|
+
LLM::Mock.reset! if defined?(LLM::Mock)
|
|
30
61
|
end
|
|
31
|
-
|
|
62
|
+
|
|
32
63
|
teardown do
|
|
33
64
|
Open.rm_rf tmpdir
|
|
34
65
|
end
|
|
@@ -51,7 +82,6 @@ class Test::Unit::TestCase
|
|
|
51
82
|
|
|
52
83
|
def agent(name = nil, options = {})
|
|
53
84
|
require 'scout/llm/agent'
|
|
54
|
-
options[:endpoint] = Scout::Config.get(:endpoint, :test)
|
|
55
85
|
if name.nil?
|
|
56
86
|
LLM::Agent.new(**options)
|
|
57
87
|
else
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scout-ai
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miguel Vazquez
|
|
@@ -97,20 +97,39 @@ files:
|
|
|
97
97
|
- Rakefile
|
|
98
98
|
- VERSION
|
|
99
99
|
- bin/scout-ai
|
|
100
|
-
- doc/
|
|
101
|
-
- doc/Chat.md
|
|
102
|
-
- doc/LLM.md
|
|
100
|
+
- doc/Improvements.md
|
|
103
101
|
- doc/Model.md
|
|
104
|
-
- doc/
|
|
102
|
+
- doc/StartHere.md
|
|
103
|
+
- doc/developer/Architecture.md
|
|
104
|
+
- doc/developer/Backends.md
|
|
105
|
+
- doc/developer/ChatLifecycle.md
|
|
106
|
+
- doc/developer/DelegationInternals.md
|
|
107
|
+
- doc/developer/DesignPrinciples.md
|
|
108
|
+
- doc/developer/PromptProcessing.md
|
|
109
|
+
- doc/developer/Provenance.md
|
|
110
|
+
- doc/user/BuildingAgents.md
|
|
111
|
+
- doc/user/Cookbook.md
|
|
112
|
+
- doc/user/CoreConcepts.md
|
|
113
|
+
- doc/user/Delegation.md
|
|
114
|
+
- doc/user/GettingStarted.md
|
|
115
|
+
- doc/user/ManagingContext.md
|
|
116
|
+
- doc/user/MultiAgentWorkflows.md
|
|
117
|
+
- doc/user/Python.md
|
|
118
|
+
- doc/user/RunningInference.md
|
|
119
|
+
- doc/user/ToolCalling.md
|
|
120
|
+
- doc/user/WritingChats.md
|
|
105
121
|
- lib/scout-ai.rb
|
|
106
122
|
- lib/scout/llm/agent.rb
|
|
107
123
|
- lib/scout/llm/agent/chat.rb
|
|
108
124
|
- lib/scout/llm/agent/delegate.rb
|
|
109
125
|
- lib/scout/llm/agent/iterate.rb
|
|
126
|
+
- lib/scout/llm/agent/save.rb
|
|
127
|
+
- lib/scout/llm/agent/workflow.rb
|
|
110
128
|
- lib/scout/llm/ask.rb
|
|
111
129
|
- lib/scout/llm/backends/anthropic.rb
|
|
112
130
|
- lib/scout/llm/backends/bedrock.rb
|
|
113
131
|
- lib/scout/llm/backends/default.rb
|
|
132
|
+
- lib/scout/llm/backends/glm.rb
|
|
114
133
|
- lib/scout/llm/backends/huggingface.rb
|
|
115
134
|
- lib/scout/llm/backends/ollama.rb
|
|
116
135
|
- lib/scout/llm/backends/openai.rb
|
|
@@ -119,15 +138,23 @@ files:
|
|
|
119
138
|
- lib/scout/llm/backends/responses.rb
|
|
120
139
|
- lib/scout/llm/backends/vllm.rb
|
|
121
140
|
- lib/scout/llm/chat.rb
|
|
141
|
+
- lib/scout/llm/chat/agent_meta.rb
|
|
122
142
|
- lib/scout/llm/chat/annotation.rb
|
|
123
143
|
- lib/scout/llm/chat/parse.rb
|
|
144
|
+
- lib/scout/llm/chat/persist.rb
|
|
124
145
|
- lib/scout/llm/chat/process.rb
|
|
125
146
|
- lib/scout/llm/chat/process/clear.rb
|
|
126
147
|
- lib/scout/llm/chat/process/files.rb
|
|
127
148
|
- lib/scout/llm/chat/process/meta.rb
|
|
128
149
|
- lib/scout/llm/chat/process/options.rb
|
|
129
150
|
- lib/scout/llm/chat/process/tools.rb
|
|
151
|
+
- lib/scout/llm/chat/prompt.rb
|
|
152
|
+
- lib/scout/llm/chat/prompt/shorten_tools.rb
|
|
153
|
+
- lib/scout/llm/chat/prompt/shorten_tools_epoch.rb
|
|
154
|
+
- lib/scout/llm/chat/provenance.rb
|
|
155
|
+
- lib/scout/llm/chat/tool_calls.rb
|
|
130
156
|
- lib/scout/llm/embed.rb
|
|
157
|
+
- lib/scout/llm/image.rb
|
|
131
158
|
- lib/scout/llm/mcp.rb
|
|
132
159
|
- lib/scout/llm/rag.rb
|
|
133
160
|
- lib/scout/llm/tools.rb
|
|
@@ -170,41 +197,98 @@ files:
|
|
|
170
197
|
- python/scout_ai/runner.py
|
|
171
198
|
- python/scout_ai/util.py
|
|
172
199
|
- python/tests/test_chat_agent.py
|
|
200
|
+
- python/tests/test_huggingface_eval.py
|
|
173
201
|
- python/tests/test_runner.py
|
|
202
|
+
- research/ChatAnalyst-required-changes.md
|
|
203
|
+
- research/agent-delegation-analysis.md
|
|
204
|
+
- research/agent-meta-provenance-integration-plan.md
|
|
205
|
+
- research/agent-workflow-analysis.md
|
|
206
|
+
- research/backends-analysis.md
|
|
207
|
+
- research/chat-core-analysis.md
|
|
208
|
+
- research/chatanalyst-provenance/00-baseline.md
|
|
209
|
+
- research/chatanalyst-provenance/01-repo-map.md
|
|
210
|
+
- research/chatanalyst-provenance/02-event-reconstruction.md
|
|
211
|
+
- research/chatanalyst-provenance/03-duplication-evidence.md
|
|
212
|
+
- research/chatanalyst-provenance/04-tooling-root-cause.md
|
|
213
|
+
- research/chatanalyst-provenance/05-fix-plan.md
|
|
214
|
+
- research/chatanalyst-provenance/07-critic-review.md
|
|
215
|
+
- research/chatanalyst-provenance/final-report.md
|
|
216
|
+
- research/chatanalyst-provenance/resumption.md
|
|
217
|
+
- research/coding-philosophy-analysis.md
|
|
218
|
+
- research/commands-analysis.md
|
|
219
|
+
- research/multi-agent-patterns-analysis.md
|
|
220
|
+
- research/prompt-strategies-analysis.md
|
|
221
|
+
- research/prov-verbosity-fix-notes.md
|
|
222
|
+
- research/provenance-analysis.md
|
|
223
|
+
- research/provenance-navigation-design.md
|
|
224
|
+
- research/synthesis-report.md
|
|
225
|
+
- research/tools-system-analysis.md
|
|
174
226
|
- scout-ai.gemspec
|
|
175
227
|
- scout_commands/agent/ask
|
|
176
228
|
- scout_commands/agent/find
|
|
177
229
|
- scout_commands/agent/kb
|
|
178
|
-
- scout_commands/documenter
|
|
179
230
|
- scout_commands/llm/ask
|
|
180
231
|
- scout_commands/llm/json
|
|
232
|
+
- scout_commands/llm/md
|
|
181
233
|
- scout_commands/llm/process
|
|
234
|
+
- scout_commands/llm/process_queries
|
|
235
|
+
- scout_commands/llm/prov
|
|
182
236
|
- scout_commands/llm/server
|
|
183
237
|
- scout_commands/llm/template
|
|
238
|
+
- scout_commands/llm/word
|
|
239
|
+
- scout_commands/workflow/mcp
|
|
184
240
|
- share/server/chat.html
|
|
185
241
|
- share/server/chat.js
|
|
242
|
+
- share/word/reference.docx
|
|
186
243
|
- test/data/cat.jpg
|
|
187
244
|
- test/data/person/brothers
|
|
188
245
|
- test/data/person/identifiers
|
|
189
246
|
- test/data/person/marriages
|
|
190
247
|
- test/data/person/parents
|
|
248
|
+
- test/etc/AI/mock.yaml
|
|
249
|
+
- test/fixtures/backends/anthropic.json
|
|
250
|
+
- test/fixtures/backends/anthropic_tool_use.json
|
|
251
|
+
- test/fixtures/backends/bedrock.json
|
|
252
|
+
- test/fixtures/backends/bedrock_embedding.json
|
|
253
|
+
- test/fixtures/backends/bedrock_tool_use.json
|
|
254
|
+
- test/fixtures/backends/ollama.json
|
|
255
|
+
- test/fixtures/backends/ollama_tool_call.json
|
|
256
|
+
- test/fixtures/backends/openai_chat.json
|
|
257
|
+
- test/fixtures/backends/openai_chat_tool_call.json
|
|
258
|
+
- test/fixtures/backends/responses.json
|
|
259
|
+
- test/fixtures/backends/responses_tool_call.json
|
|
260
|
+
- test/integration/README.md
|
|
261
|
+
- test/integration/scout/llm/backends/test_endpoints.rb
|
|
262
|
+
- test/integration/scout/llm/backends/test_openwebui.rb
|
|
263
|
+
- test/integration/scout/llm/backends/test_relay.rb
|
|
264
|
+
- test/integration/scout/llm/test_infrastructure.rb
|
|
265
|
+
- test/integration/scout/llm/test_mcp.rb
|
|
266
|
+
- test/integration/scout/llm/tools/test_mcp.rb
|
|
267
|
+
- test/integration/scout/model/test_base.rb
|
|
191
268
|
- test/scout/llm/agent/test_chat.rb
|
|
269
|
+
- test/scout/llm/agent/test_save.rb
|
|
270
|
+
- test/scout/llm/agent/test_workflow.rb
|
|
192
271
|
- test/scout/llm/backends/test_anthropic.rb
|
|
193
272
|
- test/scout/llm/backends/test_bedrock.rb
|
|
194
273
|
- test/scout/llm/backends/test_huggingface.rb
|
|
195
274
|
- test/scout/llm/backends/test_ollama.rb
|
|
196
|
-
- test/scout/llm/backends/test_openai.rb
|
|
197
275
|
- test/scout/llm/backends/test_openwebui.rb
|
|
198
276
|
- test/scout/llm/backends/test_relay.rb
|
|
199
|
-
- test/scout/llm/
|
|
277
|
+
- test/scout/llm/chat/agent_meta_fixtures.rb
|
|
278
|
+
- test/scout/llm/chat/process/test_meta.rb
|
|
279
|
+
- test/scout/llm/chat/process/test_normalize_usage.rb
|
|
280
|
+
- test/scout/llm/chat/test_agent_meta.rb
|
|
281
|
+
- test/scout/llm/chat/test_agent_meta_provenance.rb
|
|
282
|
+
- test/scout/llm/chat/test_agent_meta_tokens.rb
|
|
200
283
|
- test/scout/llm/chat/test_parse.rb
|
|
201
284
|
- test/scout/llm/chat/test_process.rb
|
|
285
|
+
- test/scout/llm/chat/test_prov_cli.rb
|
|
286
|
+
- test/scout/llm/chat/test_provenance.rb
|
|
287
|
+
- test/scout/llm/chat/test_tool_calls.rb
|
|
202
288
|
- test/scout/llm/test_agent.rb
|
|
203
289
|
- test/scout/llm/test_ask.rb
|
|
204
290
|
- test/scout/llm/test_chat.rb
|
|
205
291
|
- test/scout/llm/test_embed.rb
|
|
206
|
-
- test/scout/llm/test_mcp.rb
|
|
207
|
-
- test/scout/llm/test_parse.rb
|
|
208
292
|
- test/scout/llm/test_rag.rb
|
|
209
293
|
- test/scout/llm/test_tools.rb
|
|
210
294
|
- test/scout/llm/test_utils.rb
|
|
@@ -224,6 +308,11 @@ files:
|
|
|
224
308
|
- test/scout/network/test_entity.rb
|
|
225
309
|
- test/scout/network/test_knowledge_base.rb
|
|
226
310
|
- test/scout/network/test_paths.rb
|
|
311
|
+
- test/support/availability.rb
|
|
312
|
+
- test/support/fake_clients.rb
|
|
313
|
+
- test/support/fixtures.rb
|
|
314
|
+
- test/support/infrastructure_probes.rb
|
|
315
|
+
- test/support/mock_backend.rb
|
|
227
316
|
- test/test_helper.rb
|
|
228
317
|
homepage: http://github.com/mikisvaz/scout-ai
|
|
229
318
|
licenses:
|