scout-ai 1.0.0 → 1.0.1
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 +80 -15
- data/README.md +296 -0
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/doc/Agent.md +279 -0
- data/doc/Chat.md +258 -0
- data/doc/LLM.md +446 -0
- data/doc/Model.md +513 -0
- data/doc/RAG.md +129 -0
- data/lib/scout/llm/agent/chat.rb +51 -1
- data/lib/scout/llm/agent/delegate.rb +39 -0
- data/lib/scout/llm/agent/iterate.rb +44 -0
- data/lib/scout/llm/agent.rb +42 -21
- data/lib/scout/llm/ask.rb +38 -6
- data/lib/scout/llm/backends/anthropic.rb +147 -0
- data/lib/scout/llm/backends/bedrock.rb +1 -1
- data/lib/scout/llm/backends/ollama.rb +23 -29
- data/lib/scout/llm/backends/openai.rb +34 -40
- data/lib/scout/llm/backends/responses.rb +158 -110
- data/lib/scout/llm/chat.rb +250 -94
- data/lib/scout/llm/embed.rb +4 -4
- data/lib/scout/llm/mcp.rb +28 -0
- data/lib/scout/llm/parse.rb +1 -0
- data/lib/scout/llm/rag.rb +9 -0
- data/lib/scout/llm/tools/call.rb +66 -0
- data/lib/scout/llm/tools/knowledge_base.rb +158 -0
- data/lib/scout/llm/tools/mcp.rb +59 -0
- data/lib/scout/llm/tools/workflow.rb +69 -0
- data/lib/scout/llm/tools.rb +58 -143
- data/lib/scout-ai.rb +1 -0
- data/scout-ai.gemspec +31 -18
- data/scout_commands/agent/ask +28 -71
- data/scout_commands/documenter +148 -0
- data/scout_commands/llm/ask +2 -2
- data/scout_commands/llm/server +319 -0
- data/share/server/chat.html +138 -0
- data/share/server/chat.js +468 -0
- data/test/scout/llm/backends/test_anthropic.rb +134 -0
- data/test/scout/llm/backends/test_openai.rb +45 -6
- data/test/scout/llm/backends/test_responses.rb +124 -0
- data/test/scout/llm/test_agent.rb +0 -70
- data/test/scout/llm/test_ask.rb +3 -1
- data/test/scout/llm/test_chat.rb +43 -1
- data/test/scout/llm/test_mcp.rb +29 -0
- data/test/scout/llm/tools/test_knowledge_base.rb +22 -0
- data/test/scout/llm/tools/test_mcp.rb +11 -0
- data/test/scout/llm/tools/test_workflow.rb +39 -0
- metadata +56 -17
- data/README.rdoc +0 -18
- data/python/scout_ai/__pycache__/__init__.cpython-310.pyc +0 -0
- data/python/scout_ai/__pycache__/__init__.cpython-311.pyc +0 -0
- data/python/scout_ai/__pycache__/huggingface.cpython-310.pyc +0 -0
- data/python/scout_ai/__pycache__/huggingface.cpython-311.pyc +0 -0
- data/python/scout_ai/__pycache__/util.cpython-310.pyc +0 -0
- data/python/scout_ai/__pycache__/util.cpython-311.pyc +0 -0
- data/python/scout_ai/atcold/plot_lib.py +0 -141
- data/python/scout_ai/atcold/spiral.py +0 -27
- data/python/scout_ai/huggingface/train/__pycache__/__init__.cpython-310.pyc +0 -0
- data/python/scout_ai/huggingface/train/__pycache__/next_token.cpython-310.pyc +0 -0
- data/python/scout_ai/language_model.py +0 -70
- /data/{python/scout_ai/atcold/__init__.py → test/scout/llm/tools/test_call.rb} +0 -0
data/scout-ai.gemspec
CHANGED
@@ -2,37 +2,45 @@
|
|
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.0.
|
5
|
+
# stub: scout-ai 1.0.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "scout-ai".freeze
|
9
|
-
s.version = "1.0.
|
9
|
+
s.version = "1.0.1".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]
|
13
13
|
s.authors = ["Miguel Vazquez".freeze]
|
14
|
-
s.date = "
|
14
|
+
s.date = "1980-01-02"
|
15
15
|
s.description = "assorted functionalities to help scouts use AI".freeze
|
16
16
|
s.email = "mikisvaz@gmail.com".freeze
|
17
17
|
s.executables = ["scout-ai".freeze]
|
18
18
|
s.extra_rdoc_files = [
|
19
19
|
"LICENSE",
|
20
20
|
"LICENSE.txt",
|
21
|
-
"README.
|
21
|
+
"README.md"
|
22
22
|
]
|
23
23
|
s.files = [
|
24
24
|
".document",
|
25
25
|
".vimproject",
|
26
26
|
"LICENSE",
|
27
27
|
"LICENSE.txt",
|
28
|
-
"README.
|
28
|
+
"README.md",
|
29
29
|
"Rakefile",
|
30
30
|
"VERSION",
|
31
31
|
"bin/scout-ai",
|
32
|
+
"doc/Agent.md",
|
33
|
+
"doc/Chat.md",
|
34
|
+
"doc/LLM.md",
|
35
|
+
"doc/Model.md",
|
36
|
+
"doc/RAG.md",
|
32
37
|
"lib/scout-ai.rb",
|
33
38
|
"lib/scout/llm/agent.rb",
|
34
39
|
"lib/scout/llm/agent/chat.rb",
|
40
|
+
"lib/scout/llm/agent/delegate.rb",
|
41
|
+
"lib/scout/llm/agent/iterate.rb",
|
35
42
|
"lib/scout/llm/ask.rb",
|
43
|
+
"lib/scout/llm/backends/anthropic.rb",
|
36
44
|
"lib/scout/llm/backends/bedrock.rb",
|
37
45
|
"lib/scout/llm/backends/huggingface.rb",
|
38
46
|
"lib/scout/llm/backends/ollama.rb",
|
@@ -42,9 +50,14 @@ Gem::Specification.new do |s|
|
|
42
50
|
"lib/scout/llm/backends/responses.rb",
|
43
51
|
"lib/scout/llm/chat.rb",
|
44
52
|
"lib/scout/llm/embed.rb",
|
53
|
+
"lib/scout/llm/mcp.rb",
|
45
54
|
"lib/scout/llm/parse.rb",
|
46
55
|
"lib/scout/llm/rag.rb",
|
47
56
|
"lib/scout/llm/tools.rb",
|
57
|
+
"lib/scout/llm/tools/call.rb",
|
58
|
+
"lib/scout/llm/tools/knowledge_base.rb",
|
59
|
+
"lib/scout/llm/tools/mcp.rb",
|
60
|
+
"lib/scout/llm/tools/workflow.rb",
|
48
61
|
"lib/scout/llm/utils.rb",
|
49
62
|
"lib/scout/model/base.rb",
|
50
63
|
"lib/scout/model/python/base.rb",
|
@@ -61,37 +74,30 @@ Gem::Specification.new do |s|
|
|
61
74
|
"lib/scout/model/util/run.rb",
|
62
75
|
"lib/scout/model/util/save.rb",
|
63
76
|
"python/scout_ai/__init__.py",
|
64
|
-
"python/scout_ai/__pycache__/__init__.cpython-310.pyc",
|
65
|
-
"python/scout_ai/__pycache__/__init__.cpython-311.pyc",
|
66
|
-
"python/scout_ai/__pycache__/huggingface.cpython-310.pyc",
|
67
|
-
"python/scout_ai/__pycache__/huggingface.cpython-311.pyc",
|
68
|
-
"python/scout_ai/__pycache__/util.cpython-310.pyc",
|
69
|
-
"python/scout_ai/__pycache__/util.cpython-311.pyc",
|
70
|
-
"python/scout_ai/atcold/__init__.py",
|
71
|
-
"python/scout_ai/atcold/plot_lib.py",
|
72
|
-
"python/scout_ai/atcold/spiral.py",
|
73
77
|
"python/scout_ai/huggingface/data.py",
|
74
78
|
"python/scout_ai/huggingface/eval.py",
|
75
79
|
"python/scout_ai/huggingface/model.py",
|
76
80
|
"python/scout_ai/huggingface/rlhf.py",
|
77
81
|
"python/scout_ai/huggingface/train/__init__.py",
|
78
|
-
"python/scout_ai/huggingface/train/__pycache__/__init__.cpython-310.pyc",
|
79
|
-
"python/scout_ai/huggingface/train/__pycache__/next_token.cpython-310.pyc",
|
80
82
|
"python/scout_ai/huggingface/train/next_token.py",
|
81
|
-
"python/scout_ai/language_model.py",
|
82
83
|
"python/scout_ai/util.py",
|
83
84
|
"scout-ai.gemspec",
|
84
85
|
"scout_commands/agent/ask",
|
85
86
|
"scout_commands/agent/kb",
|
87
|
+
"scout_commands/documenter",
|
86
88
|
"scout_commands/llm/ask",
|
87
89
|
"scout_commands/llm/process",
|
90
|
+
"scout_commands/llm/server",
|
88
91
|
"scout_commands/llm/template",
|
92
|
+
"share/server/chat.html",
|
93
|
+
"share/server/chat.js",
|
89
94
|
"test/data/cat.jpg",
|
90
95
|
"test/data/person/brothers",
|
91
96
|
"test/data/person/identifiers",
|
92
97
|
"test/data/person/marriages",
|
93
98
|
"test/data/person/parents",
|
94
99
|
"test/scout/llm/agent/test_chat.rb",
|
100
|
+
"test/scout/llm/backends/test_anthropic.rb",
|
95
101
|
"test/scout/llm/backends/test_bedrock.rb",
|
96
102
|
"test/scout/llm/backends/test_huggingface.rb",
|
97
103
|
"test/scout/llm/backends/test_ollama.rb",
|
@@ -103,10 +109,15 @@ Gem::Specification.new do |s|
|
|
103
109
|
"test/scout/llm/test_ask.rb",
|
104
110
|
"test/scout/llm/test_chat.rb",
|
105
111
|
"test/scout/llm/test_embed.rb",
|
112
|
+
"test/scout/llm/test_mcp.rb",
|
106
113
|
"test/scout/llm/test_parse.rb",
|
107
114
|
"test/scout/llm/test_rag.rb",
|
108
115
|
"test/scout/llm/test_tools.rb",
|
109
116
|
"test/scout/llm/test_utils.rb",
|
117
|
+
"test/scout/llm/tools/test_call.rb",
|
118
|
+
"test/scout/llm/tools/test_knowledge_base.rb",
|
119
|
+
"test/scout/llm/tools/test_mcp.rb",
|
120
|
+
"test/scout/llm/tools/test_workflow.rb",
|
110
121
|
"test/scout/model/python/huggingface/causal/test_next_token.rb",
|
111
122
|
"test/scout/model/python/huggingface/test_causal.rb",
|
112
123
|
"test/scout/model/python/huggingface/test_classification.rb",
|
@@ -120,11 +131,13 @@ Gem::Specification.new do |s|
|
|
120
131
|
]
|
121
132
|
s.homepage = "http://github.com/mikisvaz/scout-ai".freeze
|
122
133
|
s.licenses = ["MIT".freeze]
|
123
|
-
s.rubygems_version = "3.
|
134
|
+
s.rubygems_version = "3.7.0.dev".freeze
|
124
135
|
s.summary = "AI gear for scouts".freeze
|
125
136
|
|
126
137
|
s.specification_version = 4
|
127
138
|
|
128
139
|
s.add_runtime_dependency(%q<scout-rig>.freeze, [">= 0".freeze])
|
140
|
+
s.add_runtime_dependency(%q<ruby-openai>.freeze, [">= 0".freeze])
|
141
|
+
s.add_runtime_dependency(%q<ruby-mcp-client>.freeze, [">= 0".freeze])
|
129
142
|
end
|
130
143
|
|
data/scout_commands/agent/ask
CHANGED
@@ -22,8 +22,9 @@ Use STDIN to add context to the question
|
|
22
22
|
-c--chat* Follow a conversation
|
23
23
|
-m--model* Model to use
|
24
24
|
-e--endpoint* Endpoint to use
|
25
|
-
-f--file* Incorporate file
|
25
|
+
-f--file* Incorporate file
|
26
26
|
-wt--workflow_tasks* Export these tasks to the agent
|
27
|
+
-i--imports* Chat files to import, separated by comma
|
27
28
|
EOF
|
28
29
|
if options[:help]
|
29
30
|
if defined? scout_usage
|
@@ -36,84 +37,38 @@ end
|
|
36
37
|
|
37
38
|
Log.severity = options.delete(:log).to_i if options.include? :log
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
#workflow = begin
|
50
|
-
# if agent_dir.workflow.set_extension('rb').exists?
|
51
|
-
# Workflow.require_workflow agent_dir.workflow.set_extension('rb').find
|
52
|
-
# else
|
53
|
-
# Misc.with_env "SCOUT_WORKFLOW_AUTOINSTALL", false do
|
54
|
-
# Workflow.require_workflow agent
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
# rescue
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
#if workflow_tasks and workflow
|
61
|
-
# workflow.clear_exports
|
62
|
-
# workflow.export_asynchronous *workflow_tasks.split(',')
|
63
|
-
#end
|
64
|
-
#
|
65
|
-
#knowledge_base = KnowledgeBase.load(agent_dir.knowledge_base) if agent_dir.knowledge_base.exists?
|
66
|
-
#knowledge_base ||= begin workflow.knowledge_base rescue nil end || KnowledgeBase.new(agent_dir.knowledge_base)
|
67
|
-
#
|
68
|
-
#agent = LLM::Agent.new **options.merge(workflow: workflow, knowledge_base: knowledge_base)
|
69
|
-
|
70
|
-
#question = question_parts * " "
|
71
|
-
#
|
72
|
-
#if template = options.delete(:template)
|
73
|
-
# if Open.exists?(template)
|
74
|
-
# template_question = Open.read(template)
|
75
|
-
# else
|
76
|
-
# template_question = Scout.questions[template].read
|
77
|
-
# end
|
78
|
-
# if template_question.include?('???')
|
79
|
-
# question = template_question.sub('???', question)
|
80
|
-
# else
|
81
|
-
# question = template_question
|
82
|
-
# end
|
83
|
-
#end
|
84
|
-
#
|
85
|
-
#if question.include?('...')
|
86
|
-
# context = file ? Open.read(file) : STDIN.read
|
87
|
-
# question = question.sub('...', context)
|
88
|
-
#end
|
89
|
-
#
|
90
|
-
#if chat
|
91
|
-
# conversation = Open.exist?(chat)? Open.read(chat) : ""
|
92
|
-
# question = question.empty? ? conversation : conversation + "\nuser:\n" + question
|
93
|
-
# new = agent.ask(question, options)
|
94
|
-
# conversation = question + "\nassistant:\n" + new
|
95
|
-
# Open.write(chat, conversation)
|
96
|
-
#else
|
97
|
-
# puts agent.ask(question, options)
|
98
|
-
#end
|
99
|
-
|
100
|
-
file, chat, inline, template, dry_run = IndiferentHash.process_options options, :file, :chat, :inline, :template, :dry_run
|
101
|
-
|
102
|
-
agent, question = ARGV * " "
|
40
|
+
agent_name, *question_parts = ARGV
|
41
|
+
|
42
|
+
question = question_parts * " "
|
43
|
+
|
44
|
+
file, chat, inline, template, dry_run, imports = IndiferentHash.process_options options, :file, :chat, :inline, :template, :dry_run, :imports
|
45
|
+
|
46
|
+
file = Path.setup(file) if file
|
47
|
+
|
48
|
+
imports = imports.split(/,\s*/) if imports
|
49
|
+
|
103
50
|
|
104
51
|
agent_name ||= 'default'
|
105
|
-
agent_file = Scout.chats[agent_name]
|
106
52
|
|
107
|
-
agent_file =
|
53
|
+
agent_file = Scout.workflows[agent_name]
|
54
|
+
|
55
|
+
agent_file = Scout.chats[agent_name] unless agent_file.exists?
|
56
|
+
|
57
|
+
agent_file = agent_file.find_with_extension('rb') unless agent_file.exists?
|
58
|
+
|
108
59
|
|
109
60
|
if agent_file.exists?
|
110
61
|
if agent_file.directory?
|
111
|
-
|
62
|
+
if agent_file.agent.find_with_extension('rb').exists?
|
63
|
+
agent = load agent_file.agent.find_with_extension('rb')
|
64
|
+
else
|
65
|
+
agent = LLM::Agent.load_from_path agent_file
|
66
|
+
end
|
112
67
|
else
|
113
68
|
agent = load agent_file
|
114
69
|
end
|
115
70
|
else
|
116
|
-
raise ParameterException agent_file
|
71
|
+
#raise ParameterException agent_file
|
117
72
|
end
|
118
73
|
|
119
74
|
if template
|
@@ -139,7 +94,7 @@ if question.include?('...')
|
|
139
94
|
context = file ? Open.read(file) : STDIN.read
|
140
95
|
question = question.sub('...', context)
|
141
96
|
elsif file
|
142
|
-
question = "<file basename=#{File.basename file}
|
97
|
+
question = "<file basename=#{File.basename file}>\n" + Open.read(file) + "\n</file>\n\n" + question
|
143
98
|
end
|
144
99
|
|
145
100
|
if chat
|
@@ -184,5 +139,7 @@ elsif inline
|
|
184
139
|
new_file << file
|
185
140
|
Open.write(inline, new_file)
|
186
141
|
else
|
187
|
-
|
142
|
+
conversation = Chat.setup(LLM.chat question)
|
143
|
+
imports.each{|import| conversation.import import } if imports
|
144
|
+
puts agent.ask(conversation, nil, options)
|
188
145
|
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'scout'
|
4
|
+
|
5
|
+
$0 = "scout-ai #{$previous_commands.any? ? $previous_commands*" " + " " : "" }#{ File.basename(__FILE__) }" if $previous_commands
|
6
|
+
|
7
|
+
options = SOPT.setup <<EOF
|
8
|
+
Scout documenter tool
|
9
|
+
|
10
|
+
$ #{$0} [<options>] <topic>
|
11
|
+
|
12
|
+
Generates technical, example-driven documentation for a given Scout topic by
|
13
|
+
analyzing Ruby source and corresponding test files. For a specified topic, it
|
14
|
+
locates main and subtopic files, invokes an LLM agent to synthesize markdown
|
15
|
+
documentation using real test behavior and examples, then outputs comprehensive
|
16
|
+
topic and subtopic documentation files.
|
17
|
+
|
18
|
+
-h--help Print this help
|
19
|
+
EOF
|
20
|
+
if options[:help]
|
21
|
+
if defined? scout_usage
|
22
|
+
scout_usage
|
23
|
+
else
|
24
|
+
puts SOPT.doc
|
25
|
+
end
|
26
|
+
exit 0
|
27
|
+
end
|
28
|
+
|
29
|
+
require 'scout-ai'
|
30
|
+
|
31
|
+
topic = ARGV.first
|
32
|
+
|
33
|
+
raise MissingParameterException if topic.nil?
|
34
|
+
|
35
|
+
src_files = Scout.lib.scout.glob("#{topic}*/**/*") + Scout.lib.scout.glob("#{topic}.rb")
|
36
|
+
src_files.collect! do |file|
|
37
|
+
file.sub(Dir.pwd, '.')
|
38
|
+
end
|
39
|
+
|
40
|
+
bin_files = Scout.scout_commands.glob("**/*").select{|file| file.include?(topic) && ! file.directory? }
|
41
|
+
|
42
|
+
main = src_files.select{|f| f.split("/").length == 4}.first
|
43
|
+
subtopics = src_files.select{|f| f.split("/").length == 5}.collect{|f| File.basename(f).sub(".rb",'') }.uniq
|
44
|
+
|
45
|
+
def source_to_test(file)
|
46
|
+
file.sub(%r{\A./lib/}, './test/').sub(%r{([^/]+)\.rb\z}, 'test_\1.rb')
|
47
|
+
end
|
48
|
+
|
49
|
+
documenter = LLM::Agent.new
|
50
|
+
|
51
|
+
documenter.start_chat.system <<-EOF
|
52
|
+
You are a world-class Ruby documentation author. For each (source, test) file
|
53
|
+
pair given, produce technically precise module- and file-level documentation,
|
54
|
+
incorporating specific code usage and behavior from the test file as worked
|
55
|
+
examples, code idioms, and edge-case handling.
|
56
|
+
|
57
|
+
Never insert your own example code: always use live content from the tests as examples.
|
58
|
+
|
59
|
+
Integrate documentation and test-derived examples smoothly.
|
60
|
+
|
61
|
+
You will be given first the main topic documentation for the main file and
|
62
|
+
test_file, then you will be asked to produce documentation for a subtopic.
|
63
|
+
|
64
|
+
Finally you will be ask to aggregate all the documentation portions into
|
65
|
+
a final topic documentation file
|
66
|
+
|
67
|
+
User markdown
|
68
|
+
|
69
|
+
Avoid initial and final comments like: Certainly! I'll do this and that
|
70
|
+
EOF
|
71
|
+
|
72
|
+
documenter.start_chat.file main
|
73
|
+
documenter.start_chat.file source_to_test(main)
|
74
|
+
|
75
|
+
documenter.start_chat.user <<-EOF
|
76
|
+
This is the basic topic file. Write the markdown documentation for it.
|
77
|
+
EOF
|
78
|
+
|
79
|
+
docs = {}
|
80
|
+
subtopics.each do |subtopic|
|
81
|
+
src = src_files.select{|f| f.include? subtopic}.select{|f| f.end_with?(".rb") }
|
82
|
+
test = src.collect{|f| source_to_test(f) }.select{|f| Open.exists? f }.select{|f| f.end_with?(".rb")}
|
83
|
+
|
84
|
+
documenter.start
|
85
|
+
(src + test + bin_files).each do |file|
|
86
|
+
documenter.file file
|
87
|
+
end
|
88
|
+
|
89
|
+
documenter.start_chat.user <<-EOF
|
90
|
+
Write documentation for topic #{topic} subtopic #{subtopic}
|
91
|
+
EOF
|
92
|
+
docs[subtopic] = documenter.respond
|
93
|
+
end
|
94
|
+
|
95
|
+
documenter.start
|
96
|
+
|
97
|
+
docs.each do |subtopic, documentation|
|
98
|
+
documenter.user <<-EOF
|
99
|
+
Please construct a comprehensive documentation on topic #{topic}. For each
|
100
|
+
subtopic reproduce all the most important from the original documentation
|
101
|
+
files. The subtopic documentation files will not be available anymore, so
|
102
|
+
don't leave anything imporant out
|
103
|
+
|
104
|
+
<file subtopic=#{subtopic}>
|
105
|
+
#{documentation}
|
106
|
+
<file>
|
107
|
+
EOF
|
108
|
+
end
|
109
|
+
|
110
|
+
main_documentation = documenter.chat
|
111
|
+
|
112
|
+
documenter.start_chat.user <<-EOF
|
113
|
+
This is the revise documentation for the topic:
|
114
|
+
|
115
|
+
---
|
116
|
+
|
117
|
+
#{main_documentation}
|
118
|
+
|
119
|
+
---
|
120
|
+
EOF
|
121
|
+
|
122
|
+
revised_subtopics = {}
|
123
|
+
docs.each do |subtopic, documentation|
|
124
|
+
documenter.start
|
125
|
+
|
126
|
+
src = src_files.select{|f| f.include? subtopic}.select{|f| f.end_with?(".rb") }
|
127
|
+
test = src.collect{|f| source_to_test(f) }.select{|f| Open.exists? f }.select{|f| f.end_with?(".rb")}
|
128
|
+
|
129
|
+
documenter.start
|
130
|
+
(src + test + bin_files).each do |file|
|
131
|
+
documenter.file file
|
132
|
+
end
|
133
|
+
|
134
|
+
documenter.user <<-EOF
|
135
|
+
Please revise the subtopic documentation in light of the revised main_documentation
|
136
|
+
|
137
|
+
<file subtopic=#{subtopic}>
|
138
|
+
#{documentation}
|
139
|
+
<file>
|
140
|
+
EOF
|
141
|
+
revised_subtopics[subtopic] = documenter.respond
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
Open.write Scout.doc.lib.scout[topic + '.md'].find(:current), main_documentation
|
146
|
+
revised_subtopics.each do |subtopic,documentation|
|
147
|
+
Open.write Scout.doc.lib.scout[topic][subtopic + '.md'].find(:current), documentation
|
148
|
+
end
|
data/scout_commands/llm/ask
CHANGED
@@ -88,9 +88,9 @@ elsif inline
|
|
88
88
|
new_file = ""
|
89
89
|
while true
|
90
90
|
pre, question, post =
|
91
|
-
file.partition(/^\s*#\s*ask:(?:.*?)(?=^\s*[^\s#])/smu)
|
91
|
+
file.partition(/^\s*#\s*ask:(?:.*?)(?=^\s*[^\s#]|\z)/smu)
|
92
92
|
|
93
|
-
break if
|
93
|
+
break if question.empty?
|
94
94
|
|
95
95
|
new_file << pre
|
96
96
|
new_file << question
|