scout-ai 1.2.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +138 -50
  3. data/README.md +171 -290
  4. data/Rakefile +17 -1
  5. data/VERSION +1 -1
  6. data/doc/Improvements.md +325 -0
  7. data/doc/StartHere.md +110 -0
  8. data/doc/developer/Architecture.md +126 -0
  9. data/doc/developer/Backends.md +199 -0
  10. data/doc/developer/ChatLifecycle.md +183 -0
  11. data/doc/developer/DelegationInternals.md +295 -0
  12. data/doc/developer/DesignPrinciples.md +245 -0
  13. data/doc/developer/PromptProcessing.md +292 -0
  14. data/doc/developer/Provenance.md +317 -0
  15. data/doc/user/BuildingAgents.md +345 -0
  16. data/doc/user/Cookbook.md +333 -0
  17. data/doc/user/CoreConcepts.md +181 -0
  18. data/doc/user/Delegation.md +191 -0
  19. data/doc/user/GettingStarted.md +159 -0
  20. data/doc/user/ManagingContext.md +163 -0
  21. data/doc/user/MultiAgentWorkflows.md +256 -0
  22. data/doc/user/Python.md +159 -0
  23. data/doc/user/RunningInference.md +200 -0
  24. data/doc/user/ToolCalling.md +193 -0
  25. data/doc/user/WritingChats.md +197 -0
  26. data/lib/scout/llm/agent/chat.rb +61 -11
  27. data/lib/scout/llm/agent/delegate.rb +274 -65
  28. data/lib/scout/llm/agent/iterate.rb +2 -2
  29. data/lib/scout/llm/agent/save.rb +273 -0
  30. data/lib/scout/llm/agent/workflow.rb +164 -0
  31. data/lib/scout/llm/agent.rb +86 -61
  32. data/lib/scout/llm/ask.rb +62 -17
  33. data/lib/scout/llm/backends/anthropic.rb +9 -2
  34. data/lib/scout/llm/backends/bedrock.rb +15 -3
  35. data/lib/scout/llm/backends/default.rb +183 -99
  36. data/lib/scout/llm/backends/glm.rb +58 -0
  37. data/lib/scout/llm/backends/huggingface.rb +196 -26
  38. data/lib/scout/llm/backends/ollama.rb +13 -1
  39. data/lib/scout/llm/backends/openai.rb +0 -2
  40. data/lib/scout/llm/backends/openwebui.rb +20 -13
  41. data/lib/scout/llm/backends/relay.rb +22 -22
  42. data/lib/scout/llm/backends/responses.rb +1 -1
  43. data/lib/scout/llm/chat/agent_meta.rb +264 -0
  44. data/lib/scout/llm/chat/annotation.rb +39 -10
  45. data/lib/scout/llm/chat/parse.rb +28 -6
  46. data/lib/scout/llm/chat/persist.rb +25 -0
  47. data/lib/scout/llm/chat/process/clear.rb +41 -6
  48. data/lib/scout/llm/chat/process/files.rb +21 -6
  49. data/lib/scout/llm/chat/process/meta.rb +421 -34
  50. data/lib/scout/llm/chat/process/options.rb +21 -1
  51. data/lib/scout/llm/chat/process/tools.rb +56 -15
  52. data/lib/scout/llm/chat/process.rb +4 -0
  53. data/lib/scout/llm/chat/prompt/shorten_tools.rb +125 -0
  54. data/lib/scout/llm/chat/prompt/shorten_tools_epoch.rb +365 -0
  55. data/lib/scout/llm/chat/prompt.rb +48 -0
  56. data/lib/scout/llm/chat/provenance.rb +775 -0
  57. data/lib/scout/llm/chat/tool_calls.rb +76 -0
  58. data/lib/scout/llm/chat.rb +18 -2
  59. data/lib/scout/llm/embed.rb +11 -3
  60. data/lib/scout/llm/image.rb +86 -0
  61. data/lib/scout/llm/mcp.rb +10 -2
  62. data/lib/scout/llm/rag.rb +3 -3
  63. data/lib/scout/llm/tools/call.rb +160 -11
  64. data/lib/scout/llm/tools/knowledge_base.rb +1 -1
  65. data/lib/scout/llm/tools/workflow.rb +32 -16
  66. data/lib/scout/model/python/huggingface/causal.rb +23 -5
  67. data/lib/scout/model/python/huggingface.rb +2 -1
  68. data/lib/scout-ai.rb +1 -0
  69. data/python/README.md +197 -14
  70. data/python/scout_ai/huggingface/eval.py +245 -34
  71. data/python/tests/test_huggingface_eval.py +58 -0
  72. data/research/ChatAnalyst-required-changes.md +167 -0
  73. data/research/agent-delegation-analysis.md +810 -0
  74. data/research/agent-meta-provenance-integration-plan.md +622 -0
  75. data/research/agent-workflow-analysis.md +1120 -0
  76. data/research/backends-analysis.md +836 -0
  77. data/research/chat-core-analysis.md +946 -0
  78. data/research/chatanalyst-provenance/00-baseline.md +30 -0
  79. data/research/chatanalyst-provenance/01-repo-map.md +60 -0
  80. data/research/chatanalyst-provenance/02-event-reconstruction.md +55 -0
  81. data/research/chatanalyst-provenance/03-duplication-evidence.md +45 -0
  82. data/research/chatanalyst-provenance/04-tooling-root-cause.md +57 -0
  83. data/research/chatanalyst-provenance/05-fix-plan.md +46 -0
  84. data/research/chatanalyst-provenance/07-critic-review.md +25 -0
  85. data/research/chatanalyst-provenance/final-report.md +45 -0
  86. data/research/chatanalyst-provenance/resumption.md +37 -0
  87. data/research/coding-philosophy-analysis.md +928 -0
  88. data/research/commands-analysis.md +947 -0
  89. data/research/multi-agent-patterns-analysis.md +853 -0
  90. data/research/prompt-strategies-analysis.md +630 -0
  91. data/research/prov-verbosity-fix-notes.md +77 -0
  92. data/research/provenance-analysis.md +469 -0
  93. data/research/provenance-navigation-design.md +640 -0
  94. data/research/synthesis-report.md +487 -0
  95. data/research/tools-system-analysis.md +779 -0
  96. data/scout-ai.gemspec +100 -11
  97. data/scout_commands/agent/ask +13 -3
  98. data/scout_commands/agent/kb +2 -0
  99. data/scout_commands/llm/ask +11 -4
  100. data/scout_commands/llm/md +76 -0
  101. data/scout_commands/llm/process_queries +48 -0
  102. data/scout_commands/llm/prov +602 -0
  103. data/scout_commands/llm/word +71 -0
  104. data/scout_commands/workflow/mcp +43 -0
  105. data/share/word/reference.docx +0 -0
  106. data/test/etc/AI/mock.yaml +11 -0
  107. data/test/fixtures/backends/anthropic.json +19 -0
  108. data/test/fixtures/backends/anthropic_tool_use.json +24 -0
  109. data/test/fixtures/backends/bedrock.json +8 -0
  110. data/test/fixtures/backends/bedrock_embedding.json +3 -0
  111. data/test/fixtures/backends/bedrock_tool_use.json +17 -0
  112. data/test/fixtures/backends/ollama.json +16 -0
  113. data/test/fixtures/backends/ollama_tool_call.json +27 -0
  114. data/test/fixtures/backends/openai_chat.json +21 -0
  115. data/test/fixtures/backends/openai_chat_tool_call.json +31 -0
  116. data/test/fixtures/backends/responses.json +33 -0
  117. data/test/fixtures/backends/responses_tool_call.json +28 -0
  118. data/test/integration/README.md +32 -0
  119. data/test/integration/scout/llm/backends/test_endpoints.rb +34 -0
  120. data/test/integration/scout/llm/backends/test_openwebui.rb +61 -0
  121. data/test/integration/scout/llm/backends/test_relay.rb +52 -0
  122. data/test/integration/scout/llm/test_infrastructure.rb +74 -0
  123. data/test/{scout → integration/scout}/llm/test_mcp.rb +1 -1
  124. data/test/integration/scout/llm/tools/test_mcp.rb +42 -0
  125. data/test/integration/scout/model/test_base.rb +91 -0
  126. data/test/scout/llm/agent/test_chat.rb +8 -2
  127. data/test/scout/llm/agent/test_save.rb +413 -0
  128. data/test/scout/llm/agent/test_workflow.rb +110 -0
  129. data/test/scout/llm/backends/test_anthropic.rb +93 -10
  130. data/test/scout/llm/backends/test_bedrock.rb +118 -2
  131. data/test/scout/llm/backends/test_huggingface.rb +137 -42
  132. data/test/scout/llm/backends/test_ollama.rb +70 -20
  133. data/test/scout/llm/backends/test_openwebui.rb +42 -40
  134. data/test/scout/llm/backends/test_relay.rb +4 -2
  135. data/test/scout/llm/chat/agent_meta_fixtures.rb +131 -0
  136. data/test/scout/llm/chat/process/test_meta.rb +518 -0
  137. data/test/scout/llm/chat/process/test_normalize_usage.rb +183 -0
  138. data/test/scout/llm/chat/test_agent_meta.rb +357 -0
  139. data/test/scout/llm/chat/test_agent_meta_provenance.rb +467 -0
  140. data/test/scout/llm/chat/test_agent_meta_tokens.rb +594 -0
  141. data/test/scout/llm/chat/test_parse.rb +70 -15
  142. data/test/scout/llm/chat/test_prov_cli.rb +274 -0
  143. data/test/scout/llm/chat/test_provenance.rb +240 -0
  144. data/test/scout/llm/chat/test_tool_calls.rb +38 -0
  145. data/test/scout/llm/test_agent.rb +13 -36
  146. data/test/scout/llm/test_ask.rb +75 -52
  147. data/test/scout/llm/test_chat.rb +107 -13
  148. data/test/scout/llm/test_embed.rb +48 -0
  149. data/test/scout/llm/test_rag.rb +23 -16
  150. data/test/scout/llm/test_tools.rb +12 -1
  151. data/test/scout/llm/tools/test_knowledge_base.rb +0 -1
  152. data/test/scout/llm/tools/test_mcp.rb +5 -3
  153. data/test/scout/llm/tools/test_workflow.rb +23 -2
  154. data/test/scout/model/python/huggingface/causal/test_next_token.rb +11 -5
  155. data/test/scout/model/python/huggingface/test_causal.rb +9 -3
  156. data/test/scout/model/python/huggingface/test_classification.rb +11 -2
  157. data/test/scout/model/python/test_torch.rb +2 -0
  158. data/test/scout/model/python/torch/test_helpers.rb +4 -0
  159. data/test/scout/model/test_base.rb +4 -2
  160. data/test/support/availability.rb +231 -0
  161. data/test/support/fake_clients.rb +138 -0
  162. data/test/support/fixtures.rb +21 -0
  163. data/test/support/infrastructure_probes.rb +136 -0
  164. data/test/support/mock_backend.rb +215 -0
  165. data/test/test_helper.rb +32 -2
  166. metadata +99 -10
  167. data/doc/Agent.md +0 -327
  168. data/doc/Chat.md +0 -458
  169. data/doc/LLM.md +0 -340
  170. data/doc/RAG.md +0 -129
  171. data/scout_commands/documenter +0 -148
  172. data/test/scout/llm/backends/test_openai.rb +0 -192
  173. data/test/scout/llm/backends/test_responses.rb +0 -238
  174. data/test/scout/llm/test_parse.rb +0 -98
data/scout-ai.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: scout-ai 1.2.3 ruby lib
5
+ # stub: scout-ai 2.0.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-ai".freeze
9
- s.version = "1.2.3".freeze
9
+ s.version = "2.0.0".freeze
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
@@ -29,20 +29,39 @@ Gem::Specification.new do |s|
29
29
  "Rakefile",
30
30
  "VERSION",
31
31
  "bin/scout-ai",
32
- "doc/Agent.md",
33
- "doc/Chat.md",
34
- "doc/LLM.md",
32
+ "doc/Improvements.md",
35
33
  "doc/Model.md",
36
- "doc/RAG.md",
34
+ "doc/StartHere.md",
35
+ "doc/developer/Architecture.md",
36
+ "doc/developer/Backends.md",
37
+ "doc/developer/ChatLifecycle.md",
38
+ "doc/developer/DelegationInternals.md",
39
+ "doc/developer/DesignPrinciples.md",
40
+ "doc/developer/PromptProcessing.md",
41
+ "doc/developer/Provenance.md",
42
+ "doc/user/BuildingAgents.md",
43
+ "doc/user/Cookbook.md",
44
+ "doc/user/CoreConcepts.md",
45
+ "doc/user/Delegation.md",
46
+ "doc/user/GettingStarted.md",
47
+ "doc/user/ManagingContext.md",
48
+ "doc/user/MultiAgentWorkflows.md",
49
+ "doc/user/Python.md",
50
+ "doc/user/RunningInference.md",
51
+ "doc/user/ToolCalling.md",
52
+ "doc/user/WritingChats.md",
37
53
  "lib/scout-ai.rb",
38
54
  "lib/scout/llm/agent.rb",
39
55
  "lib/scout/llm/agent/chat.rb",
40
56
  "lib/scout/llm/agent/delegate.rb",
41
57
  "lib/scout/llm/agent/iterate.rb",
58
+ "lib/scout/llm/agent/save.rb",
59
+ "lib/scout/llm/agent/workflow.rb",
42
60
  "lib/scout/llm/ask.rb",
43
61
  "lib/scout/llm/backends/anthropic.rb",
44
62
  "lib/scout/llm/backends/bedrock.rb",
45
63
  "lib/scout/llm/backends/default.rb",
64
+ "lib/scout/llm/backends/glm.rb",
46
65
  "lib/scout/llm/backends/huggingface.rb",
47
66
  "lib/scout/llm/backends/ollama.rb",
48
67
  "lib/scout/llm/backends/openai.rb",
@@ -51,15 +70,23 @@ Gem::Specification.new do |s|
51
70
  "lib/scout/llm/backends/responses.rb",
52
71
  "lib/scout/llm/backends/vllm.rb",
53
72
  "lib/scout/llm/chat.rb",
73
+ "lib/scout/llm/chat/agent_meta.rb",
54
74
  "lib/scout/llm/chat/annotation.rb",
55
75
  "lib/scout/llm/chat/parse.rb",
76
+ "lib/scout/llm/chat/persist.rb",
56
77
  "lib/scout/llm/chat/process.rb",
57
78
  "lib/scout/llm/chat/process/clear.rb",
58
79
  "lib/scout/llm/chat/process/files.rb",
59
80
  "lib/scout/llm/chat/process/meta.rb",
60
81
  "lib/scout/llm/chat/process/options.rb",
61
82
  "lib/scout/llm/chat/process/tools.rb",
83
+ "lib/scout/llm/chat/prompt.rb",
84
+ "lib/scout/llm/chat/prompt/shorten_tools.rb",
85
+ "lib/scout/llm/chat/prompt/shorten_tools_epoch.rb",
86
+ "lib/scout/llm/chat/provenance.rb",
87
+ "lib/scout/llm/chat/tool_calls.rb",
62
88
  "lib/scout/llm/embed.rb",
89
+ "lib/scout/llm/image.rb",
63
90
  "lib/scout/llm/mcp.rb",
64
91
  "lib/scout/llm/rag.rb",
65
92
  "lib/scout/llm/tools.rb",
@@ -102,41 +129,98 @@ Gem::Specification.new do |s|
102
129
  "python/scout_ai/runner.py",
103
130
  "python/scout_ai/util.py",
104
131
  "python/tests/test_chat_agent.py",
132
+ "python/tests/test_huggingface_eval.py",
105
133
  "python/tests/test_runner.py",
134
+ "research/ChatAnalyst-required-changes.md",
135
+ "research/agent-delegation-analysis.md",
136
+ "research/agent-meta-provenance-integration-plan.md",
137
+ "research/agent-workflow-analysis.md",
138
+ "research/backends-analysis.md",
139
+ "research/chat-core-analysis.md",
140
+ "research/chatanalyst-provenance/00-baseline.md",
141
+ "research/chatanalyst-provenance/01-repo-map.md",
142
+ "research/chatanalyst-provenance/02-event-reconstruction.md",
143
+ "research/chatanalyst-provenance/03-duplication-evidence.md",
144
+ "research/chatanalyst-provenance/04-tooling-root-cause.md",
145
+ "research/chatanalyst-provenance/05-fix-plan.md",
146
+ "research/chatanalyst-provenance/07-critic-review.md",
147
+ "research/chatanalyst-provenance/final-report.md",
148
+ "research/chatanalyst-provenance/resumption.md",
149
+ "research/coding-philosophy-analysis.md",
150
+ "research/commands-analysis.md",
151
+ "research/multi-agent-patterns-analysis.md",
152
+ "research/prompt-strategies-analysis.md",
153
+ "research/prov-verbosity-fix-notes.md",
154
+ "research/provenance-analysis.md",
155
+ "research/provenance-navigation-design.md",
156
+ "research/synthesis-report.md",
157
+ "research/tools-system-analysis.md",
106
158
  "scout-ai.gemspec",
107
159
  "scout_commands/agent/ask",
108
160
  "scout_commands/agent/find",
109
161
  "scout_commands/agent/kb",
110
- "scout_commands/documenter",
111
162
  "scout_commands/llm/ask",
112
163
  "scout_commands/llm/json",
164
+ "scout_commands/llm/md",
113
165
  "scout_commands/llm/process",
166
+ "scout_commands/llm/process_queries",
167
+ "scout_commands/llm/prov",
114
168
  "scout_commands/llm/server",
115
169
  "scout_commands/llm/template",
170
+ "scout_commands/llm/word",
171
+ "scout_commands/workflow/mcp",
116
172
  "share/server/chat.html",
117
173
  "share/server/chat.js",
174
+ "share/word/reference.docx",
118
175
  "test/data/cat.jpg",
119
176
  "test/data/person/brothers",
120
177
  "test/data/person/identifiers",
121
178
  "test/data/person/marriages",
122
179
  "test/data/person/parents",
180
+ "test/etc/AI/mock.yaml",
181
+ "test/fixtures/backends/anthropic.json",
182
+ "test/fixtures/backends/anthropic_tool_use.json",
183
+ "test/fixtures/backends/bedrock.json",
184
+ "test/fixtures/backends/bedrock_embedding.json",
185
+ "test/fixtures/backends/bedrock_tool_use.json",
186
+ "test/fixtures/backends/ollama.json",
187
+ "test/fixtures/backends/ollama_tool_call.json",
188
+ "test/fixtures/backends/openai_chat.json",
189
+ "test/fixtures/backends/openai_chat_tool_call.json",
190
+ "test/fixtures/backends/responses.json",
191
+ "test/fixtures/backends/responses_tool_call.json",
192
+ "test/integration/README.md",
193
+ "test/integration/scout/llm/backends/test_endpoints.rb",
194
+ "test/integration/scout/llm/backends/test_openwebui.rb",
195
+ "test/integration/scout/llm/backends/test_relay.rb",
196
+ "test/integration/scout/llm/test_infrastructure.rb",
197
+ "test/integration/scout/llm/test_mcp.rb",
198
+ "test/integration/scout/llm/tools/test_mcp.rb",
199
+ "test/integration/scout/model/test_base.rb",
123
200
  "test/scout/llm/agent/test_chat.rb",
201
+ "test/scout/llm/agent/test_save.rb",
202
+ "test/scout/llm/agent/test_workflow.rb",
124
203
  "test/scout/llm/backends/test_anthropic.rb",
125
204
  "test/scout/llm/backends/test_bedrock.rb",
126
205
  "test/scout/llm/backends/test_huggingface.rb",
127
206
  "test/scout/llm/backends/test_ollama.rb",
128
- "test/scout/llm/backends/test_openai.rb",
129
207
  "test/scout/llm/backends/test_openwebui.rb",
130
208
  "test/scout/llm/backends/test_relay.rb",
131
- "test/scout/llm/backends/test_responses.rb",
209
+ "test/scout/llm/chat/agent_meta_fixtures.rb",
210
+ "test/scout/llm/chat/process/test_meta.rb",
211
+ "test/scout/llm/chat/process/test_normalize_usage.rb",
212
+ "test/scout/llm/chat/test_agent_meta.rb",
213
+ "test/scout/llm/chat/test_agent_meta_provenance.rb",
214
+ "test/scout/llm/chat/test_agent_meta_tokens.rb",
132
215
  "test/scout/llm/chat/test_parse.rb",
133
216
  "test/scout/llm/chat/test_process.rb",
217
+ "test/scout/llm/chat/test_prov_cli.rb",
218
+ "test/scout/llm/chat/test_provenance.rb",
219
+ "test/scout/llm/chat/test_tool_calls.rb",
134
220
  "test/scout/llm/test_agent.rb",
135
221
  "test/scout/llm/test_ask.rb",
136
222
  "test/scout/llm/test_chat.rb",
137
223
  "test/scout/llm/test_embed.rb",
138
- "test/scout/llm/test_mcp.rb",
139
- "test/scout/llm/test_parse.rb",
140
224
  "test/scout/llm/test_rag.rb",
141
225
  "test/scout/llm/test_tools.rb",
142
226
  "test/scout/llm/test_utils.rb",
@@ -156,6 +240,11 @@ Gem::Specification.new do |s|
156
240
  "test/scout/network/test_entity.rb",
157
241
  "test/scout/network/test_knowledge_base.rb",
158
242
  "test/scout/network/test_paths.rb",
243
+ "test/support/availability.rb",
244
+ "test/support/fake_clients.rb",
245
+ "test/support/fixtures.rb",
246
+ "test/support/infrastructure_probes.rb",
247
+ "test/support/mock_backend.rb",
159
248
  "test/test_helper.rb"
160
249
  ]
161
250
  s.homepage = "http://github.com/mikisvaz/scout-ai".freeze
@@ -85,7 +85,8 @@ if chat
85
85
  conversation.message :tool, workflow if workflow
86
86
 
87
87
  convo_options = LLM.options conversation
88
- agent.start(Chat.setup(conversation)) if conversation.any?
88
+ agent.start
89
+ agent.follow(Chat.setup(conversation)) if conversation.any?
89
90
  agent.current_chat.concat LLM.chat(question) if question && ! question.empty?
90
91
  imports.each{|import| agent.import import } if imports
91
92
 
@@ -94,7 +95,15 @@ if chat
94
95
  exit 0
95
96
  end
96
97
 
97
- new = agent.ask(agent.current_chat, convo_options.merge(options.merge(return_messages: true, endpoint: endpoint, model: model)))
98
+ # ScoutCoder: named-file rule, same as AgentWorkflow#log_agent: the agent
99
+ # chat is named after the agent ('agent.chat' by default, but
100
+ # worker.chat/critic.chat when the CLI is invoked for a named agent), and
101
+ # the society tree is the sibling <name>.society (see
102
+ # LLM::Agent.society_dir_for). Must be set before the first chat call so
103
+ # the Agent#chat ensure-hook and the restart snapshot see it.
104
+ agent.save_file = chat + ".files/#{agent_name || 'agent'}.chat"
105
+ #new = agent.ask(agent.current_chat, convo_options.merge(options.merge(return_messages: true)))
106
+ new = agent.chat(convo_options.merge(options.merge(return_messages: true)))
98
107
  conversation += LLM.chat(question) if question
99
108
  conversation += new
100
109
 
@@ -102,6 +111,7 @@ if chat
102
111
  f.puts LLM.print([{role: :user, content: question}]) unless question.empty?
103
112
  f.puts LLM.print(new)
104
113
  end
114
+ raise "No messages returned" if LLM.purge(new).empty?
105
115
  puts LLM.purge(new).last[:content]
106
116
  elsif inline
107
117
 
@@ -112,7 +122,7 @@ elsif inline
112
122
  pre, question, post =
113
123
  file.partition(/^\s*#\s*ask:(?:.*?)(?=^\s*[^\s#])/smu)
114
124
 
115
- break if post.empty?
125
+ break if question.empty?
116
126
 
117
127
  new_file << pre
118
128
  new_file << question
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'scout-ai'
4
+
3
5
  agent = ARGV.shift
4
6
 
5
7
  agent_dir = Scout.var.Agent[agent]
@@ -75,7 +75,7 @@ elsif file
75
75
  end
76
76
 
77
77
  if chat
78
- conversation = Open.exist?(chat)? LLM.chat(chat) : Chat.setup([])
78
+ conversation = Open.exist?(chat)? Chat.load(chat) : Chat.setup([])
79
79
  imports.each{|import| conversation.import import } if imports
80
80
  convo_options = LLM.options conversation
81
81
  conversation = question.empty? ? conversation : conversation + LLM.chat(question)
@@ -88,7 +88,14 @@ if chat
88
88
  exit 0
89
89
  end
90
90
 
91
- new = LLM.ask(conversation, convo_options.merge(options.merge(return_messages: true)))
91
+ # ScoutCoder: named-file rule (AgentWorkflow#log_agent parity): the agent
92
+ # chat of this CLI conversation lands at <chat>.files/agent.chat, with the
93
+ # society tree at <chat>.files/agent.society (LLM::Agent.society_dir_for).
94
+ # This CLI has no agent option, so the name is always 'agent'; the
95
+ # `agent_save_file` option forwarded to LLM.ask is this very value and is
96
+ # honored verbatim by lib/scout/llm/ask.rb.
97
+ agent_save_file = chat + '.files/agent.chat'
98
+ new = LLM.ask(conversation, convo_options.merge(options.merge(return_messages: true, agent_save_file: agent_save_file)))
92
99
  Open.open(chat, mode: 'a') do |f|
93
100
  f.puts LLM.print([{role: :user, content: question}]) unless question.empty?
94
101
  f.puts LLM.print(new)
@@ -111,10 +118,10 @@ elsif inline
111
118
  chat = [
112
119
  {role: :system, content: "Write a succint reply with no commentary and no formatting."},
113
120
  {role: :user, content: "Find the following question as a comment in the file give a response to be placed inline: #{question}"},
114
- LLM.tag('file', file, inline)
121
+ Chat.tag('file', file, inline)
115
122
  ]
116
123
 
117
- chat = Chat.chat(chat)
124
+ chat = LLM.chat(chat)
118
125
 
119
126
  imports.each{|import| chat.import import } if imports
120
127
 
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'scout'
5
+
6
+ cmd = $previous_commands ?
7
+ "scout #{$previous_commands.any? ? "#{$previous_commands * ' '} " : ''}#{File.basename(__FILE__)}" :
8
+ $PROGRAM_NAME
9
+
10
+ options = SOPT.setup <<~EOF
11
+
12
+ Format a chat in Markdown
13
+
14
+ $ #{cmd} [<options>] <chat> <markdown>
15
+
16
+ -h--help Print this help
17
+ -l--last Format only the last interaction
18
+ EOF
19
+ if options[:help]
20
+ if defined? scout_usage
21
+ scout_usage
22
+ else
23
+ puts SOPT.doc
24
+ end
25
+ exit 0
26
+ end
27
+
28
+ help, last = IndiferentHash.process_options options, :help, :last
29
+
30
+ chat, output, _ = ARGV
31
+
32
+ raise MissingParameterException, :chat if chat.nil?
33
+
34
+ messages = Chat.parse Open.read(chat)
35
+
36
+ if last
37
+ messages = messages.select{|m| %w(user assistant).include? m[:role].to_s }[-2..-1]
38
+ end
39
+
40
+ out = []
41
+ messages.each do |message|
42
+ IndiferentHash.setup(message)
43
+ case message['role']
44
+ when 'user'
45
+ out.push <<-EOF
46
+
47
+ ---
48
+ # 👤 User
49
+ ---
50
+
51
+ #{message['content']}
52
+
53
+ EOF
54
+ when 'assistant'
55
+ out.push <<-EOF
56
+
57
+ ---
58
+ # 🤖 Assistant
59
+ ---
60
+
61
+ #{message['content']}
62
+
63
+ EOF
64
+ else
65
+ next
66
+ end
67
+ end
68
+
69
+ markdown = out * "\n"
70
+
71
+ if output
72
+ Open.write(output, markdown)
73
+ puts output
74
+ else
75
+ puts markdown
76
+ end
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'scout'
4
+ require 'scout-ai'
5
+ require 'scout/llm/backends/relay'
6
+
7
+ $0 = "scout #{$previous_commands.any? ? $previous_commands*" " + " " : "" }#{ File.basename(__FILE__) }" if $previous_commands
8
+
9
+ options = SOPT.setup <<EOF
10
+
11
+ Ask GPT
12
+
13
+ $ #{$0} [<options>] [<directory>]
14
+
15
+ Use STDIN to add context to the question
16
+
17
+ -h--help Print this help
18
+ EOF
19
+ if options[:help]
20
+ if defined? scout_usage
21
+ scout_usage
22
+ else
23
+ puts SOPT.doc
24
+ end
25
+ exit 0
26
+ end
27
+
28
+ Log.severity = options.delete(:log).to_i if options.include? :log
29
+
30
+ directory = ARGV.first || Scout.var.query.find
31
+
32
+ directory = Path.setup directory
33
+
34
+ while true
35
+ files = directory.glob('*.json')
36
+
37
+ files.each do |file|
38
+ id = File.basename(file, '.json')
39
+
40
+ messages, options = Open.json(file)
41
+
42
+ LLM.ask(messages, options.merge(process: id))
43
+
44
+ Open.rm(file)
45
+ end
46
+
47
+ sleep 1 if files.empty?
48
+ end