aia 2.0.0.0.pre.alpha → 2.0.0.0.pre.beta2
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/.envrc +5 -1
- data/.loki +3 -223
- data/.reek.yml +160 -0
- data/.rubocop_strict.yml +15 -0
- data/.version +1 -1
- data/CHANGELOG.md +10 -5
- data/README.md +1 -1
- data/Rakefile +0 -113
- data/_typos.toml +10 -0
- data/aia.gemspec +92 -0
- data/config/aia.yml +13 -0
- data/lib/aia/chat_loop.rb +8 -52
- data/lib/aia/config/cli_parser.rb +66 -57
- data/lib/aia/config/mcp_parser.rb +27 -19
- data/lib/aia/config/validator.rb +83 -94
- data/lib/aia/config.rb +3 -2
- data/lib/aia/content_extractor.rb +2 -0
- data/lib/aia/cost_calculator.rb +1 -0
- data/lib/aia/debate_handler.rb +28 -20
- data/lib/aia/delegate_handler.rb +7 -3
- data/lib/aia/directive.rb +10 -8
- data/lib/aia/directives/configuration_directives.rb +115 -101
- data/lib/aia/directives/context_directives.rb +31 -28
- data/lib/aia/directives/execution_directives.rb +18 -13
- data/lib/aia/directives/model_directives.rb +134 -154
- data/lib/aia/directives/trakflow_directives.rb +27 -9
- data/lib/aia/directives/utility_directives.rb +71 -71
- data/lib/aia/directives/web_and_file_directives.rb +63 -50
- data/lib/aia/layered_orchestrator.rb +66 -43
- data/lib/aia/logger.rb +21 -21
- data/lib/aia/mcp_connection_manager.rb +50 -40
- data/lib/aia/mcp_server_config.rb +30 -0
- data/lib/aia/mcp_utility.rb +7 -4
- data/lib/aia/mention_router.rb +7 -50
- data/lib/aia/network_builder.rb +10 -5
- data/lib/aia/network_memory_manager.rb +6 -6
- data/lib/aia/pipeline_orchestrator.rb +20 -10
- data/lib/aia/plugin_monitor.rb +9 -6
- data/lib/aia/prompt_decomposer.rb +5 -3
- data/lib/aia/prompt_handler.rb +43 -49
- data/lib/aia/robot_factory.rb +12 -8
- data/lib/aia/robot_namer.rb +2 -8
- data/lib/aia/session.rb +7 -3
- data/lib/aia/session_tracker.rb +39 -41
- data/lib/aia/similarity_scorer.rb +5 -3
- data/lib/aia/special_mode_handler.rb +52 -32
- data/lib/aia/speech.rb +67 -0
- data/lib/aia/startup_coordinator.rb +1 -0
- data/lib/aia/streaming_runner.rb +6 -3
- data/lib/aia/system_prompt_assembler.rb +11 -7
- data/lib/aia/task_coordinator.rb +10 -5
- data/lib/aia/timing.rb +15 -0
- data/lib/aia/tool_filter.rb +1 -0
- data/lib/aia/tool_filter_strategy.rb +28 -25
- data/lib/aia/tool_introspection.rb +17 -0
- data/lib/aia/tool_loader.rb +12 -6
- data/lib/aia/tools/task_board_tool.rb +1 -0
- data/lib/aia/trakflow_bridge.rb +5 -3
- data/lib/aia/turn_state.rb +1 -0
- data/lib/aia/ui_presenter.rb +67 -59
- data/lib/aia/utility.rb +5 -3
- data/lib/aia/variable_input_collector.rb +1 -0
- data/lib/aia/verification_network.rb +1 -2
- data/lib/aia.rb +16 -0
- metadata +15 -9
- data/.quality/flay_baseline.txt +0 -1
- data/.quality/flog_baseline.txt +0 -29
- data/.quality/reek_baseline.txt +0 -80
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a4bbfc1e0e1f0e293c55ce308b069b4a36af679797fcdaa2daeb47f05211d31f
|
|
4
|
+
data.tar.gz: 2d358bec6a2dfd8e57c55266099dcbd5ab96c776532fd6829862df30cd668323
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a62160a13b4b6827b837191a7b0001fe6d075cc3a3e628f1c943f82c970da7c22c6ed031e11792e0d43a188e2b5e2895994cfd5a5265309bbf81d849537be569
|
|
7
|
+
data.tar.gz: dae8328bdbc222221ac6380e71037d4ea0d32df2f6f04d091beac65632bc3c58e9b190735854440e71df20e1368509313c8b678d5f765870433ce2b0687ec43a
|
data/.envrc
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# robot_lab_project/aia/.envrc
|
|
2
|
+
|
|
1
3
|
source_up
|
|
2
4
|
|
|
3
5
|
export RR=$(pwd)
|
|
@@ -12,4 +14,6 @@ export AIA_PLUGINS_DIR=$RR/plugins
|
|
|
12
14
|
# Use a comma to seperate the models in a multi-model setup
|
|
13
15
|
#
|
|
14
16
|
# export AIA_MODEL=claude-haiku-4-5,gpt-4o-mini
|
|
15
|
-
export AIA_MODEL=
|
|
17
|
+
export AIA_MODEL=lms/qwen3.8
|
|
18
|
+
|
|
19
|
+
export BUNDLE_GEMFILE=Gemfile
|
data/.loki
CHANGED
|
@@ -1,231 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# aia/.loki — asgard task runner for the aia gem
|
|
3
3
|
|
|
4
|
+
import_up "repo_dev.loki"
|
|
5
|
+
|
|
4
6
|
class Tasks
|
|
5
|
-
@@
|
|
7
|
+
@@gem_name ||= "aia".freeze
|
|
6
8
|
|
|
7
9
|
header "aia — AI Assistant CLI gem"
|
|
8
10
|
footer "Run `asgard help TASK` for details on any task"
|
|
9
|
-
|
|
10
|
-
map "t" => :test
|
|
11
|
-
map "i" => :install
|
|
12
|
-
map "inc" => :bump
|
|
13
|
-
|
|
14
|
-
default_task :list
|
|
15
|
-
|
|
16
|
-
# ── Terminal utilities ─────────────────────────────────────────────────────
|
|
17
|
-
|
|
18
|
-
desc "Fix half-duplex terminal"
|
|
19
|
-
def fix = sh "stty sane"
|
|
20
|
-
|
|
21
|
-
desc "Clear the scroll-back buffer"
|
|
22
|
-
def clear_buffer = sh 'printf "\e[3J"'
|
|
23
|
-
|
|
24
|
-
# ── Mods ──────────────────────────────────────────────────────────────────
|
|
25
|
-
|
|
26
|
-
desc "Delete all mods saved conversations"
|
|
27
|
-
def mods_delete_all
|
|
28
|
-
sh "mods -l | awk '{print $1}' | xargs -I {} mods -d {}"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# ── Run ───────────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
|
-
desc "aia [ARGS]", "Run the aia CLI with pass-through arguments (e.g. asgard aia --chat)"
|
|
34
|
-
def aia(*args)
|
|
35
|
-
sh "#{@@rr}/bin/aia #{args.join(' ')}"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# ── Tests & Quality ────────────────────────────────────────────────────────
|
|
39
|
-
|
|
40
|
-
desc "Run unit tests"
|
|
41
|
-
def test = sh "bundle exec rake test"
|
|
42
|
-
|
|
43
|
-
depends_on :test
|
|
44
|
-
desc "Open coverage report in browser (depends on: test)"
|
|
45
|
-
def coverage = sh "open #{@@rr}/coverage/index.html"
|
|
46
|
-
|
|
47
|
-
desc "Check code complexity with Flog"
|
|
48
|
-
def flog = sh "bundle exec rake flog_check > flog_output.txt 2>&1"
|
|
49
|
-
|
|
50
|
-
desc "Check for structural duplication with Flay"
|
|
51
|
-
def flay = sh "bundle exec rake flay_check > flay_output.txt 2>&1"
|
|
52
|
-
|
|
53
|
-
desc "Check code smells with Reek (fails only on new or worsened files)"
|
|
54
|
-
def reek
|
|
55
|
-
current = reek_scan
|
|
56
|
-
baseline = load_reek_baseline
|
|
57
|
-
|
|
58
|
-
new_files = current.reject { |f, _| baseline.key?(f) }
|
|
59
|
-
worsened = current.select { |f, c| baseline.key?(f) && c > baseline[f] }
|
|
60
|
-
improved = baseline.count { |f, c| current.key?(f) && current[f] < c }
|
|
61
|
-
cleaned = baseline.keys - current.keys
|
|
62
|
-
|
|
63
|
-
total_current = current.values.sum
|
|
64
|
-
total_baseline = baseline.values.sum
|
|
65
|
-
|
|
66
|
-
puts "\nReek: #{total_current} warning(s) across #{current.size} file(s) " \
|
|
67
|
-
"(#{total_baseline} grandfathered across #{baseline.size} file(s))."
|
|
68
|
-
puts " #{cleaned.size} file(s) fully clean — run `asgard reek_baseline` to prune." unless cleaned.empty?
|
|
69
|
-
puts " #{improved} file(s) improved — run `asgard reek_baseline` to ratchet down." unless improved.zero?
|
|
70
|
-
|
|
71
|
-
problems = new_files.map { |f, c| format("NEW %3d warning(s): %s", c, f) } +
|
|
72
|
-
worsened.map { |f, c| format("WORSENED %3d -> %3d: %s", baseline[f], c, f) }
|
|
73
|
-
|
|
74
|
-
if problems.empty?
|
|
75
|
-
puts "Reek quality gate passed (no new or worsened files)."
|
|
76
|
-
else
|
|
77
|
-
puts "\nReek quality gate FAILED:"
|
|
78
|
-
problems.each { |p| puts " #{p}" }
|
|
79
|
-
abort "\nReek: #{problems.size} file(s) regressed. Fix smells, or `asgard reek_baseline` if intentional."
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
desc "Regenerate the Reek baseline (grandfathers current smell counts per file)"
|
|
84
|
-
def reek_baseline
|
|
85
|
-
require 'fileutils'
|
|
86
|
-
FileUtils.mkdir_p('.quality')
|
|
87
|
-
warnings = reek_scan
|
|
88
|
-
body = warnings.sort_by { |f, _| f }.map { |f, c| "#{c}\t#{f}" }.join("\n")
|
|
89
|
-
File.write('.quality/reek_baseline.txt', body.empty? ? '' : "#{body}\n")
|
|
90
|
-
puts "Wrote #{warnings.size} file(s) with smells to .quality/reek_baseline.txt"
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
desc "Check code style with RuboCop"
|
|
94
|
-
def rubocop = sh "bundle exec rubocop > rubocop_output.txt 2>&1"
|
|
95
|
-
|
|
96
|
-
desc "Auto-correct RuboCop offenses"
|
|
97
|
-
def rubocop_fix = sh "bundle exec rubocop -a"
|
|
98
|
-
|
|
99
|
-
desc "Run all quality gates: tests + Flog + Flay + Reek + RuboCop"
|
|
100
|
-
def quality
|
|
101
|
-
gates = {
|
|
102
|
-
test: -> { system("bundle exec rake test") },
|
|
103
|
-
flog: -> { system("bundle exec rake flog_check > flog_output.txt 2>&1") },
|
|
104
|
-
flay: -> { system("bundle exec rake flay_check > flay_output.txt 2>&1") },
|
|
105
|
-
reek: -> { reek_gate },
|
|
106
|
-
rubocop: -> { system("bundle exec rubocop > rubocop_output.txt 2>&1") }
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
results = gates.transform_values { |gate| gate.call }
|
|
110
|
-
|
|
111
|
-
puts "\n Quality Gate Summary"
|
|
112
|
-
puts " #{'─' * 32}"
|
|
113
|
-
results.each do |gate, ok|
|
|
114
|
-
badge = ok ? "\e[32mPASS\e[0m" : "\e[31mFAIL\e[0m"
|
|
115
|
-
file = gate == :test ? "test_output.txt" : "#{gate}_output.txt"
|
|
116
|
-
puts " #{badge} #{gate.to_s.ljust(10)} see #{file}"
|
|
117
|
-
end
|
|
118
|
-
puts " #{'─' * 32}"
|
|
119
|
-
|
|
120
|
-
if results.values.all?
|
|
121
|
-
puts "\n \e[32mAll quality gates passed.\e[0m\n\n"
|
|
122
|
-
else
|
|
123
|
-
failed = results.reject { |_, v| v }.keys.join(', ')
|
|
124
|
-
abort "\n \e[31mFailed: #{failed}\e[0m\n\n"
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# ── Documentation ─────────────────────────────────────────────────────────
|
|
129
|
-
|
|
130
|
-
desc "Update README table of contents"
|
|
131
|
-
def update_toc_in_readmen = sh "rake toc"
|
|
132
|
-
|
|
133
|
-
depends_on :update_toc_in_readmen
|
|
134
|
-
desc "Generate documentation (depends on: update_toc_in_readmen)"
|
|
135
|
-
def gen_doc = puts "Documentation generated."
|
|
136
|
-
|
|
137
|
-
# ── Build & Install ────────────────────────────────────────────────────────
|
|
138
|
-
|
|
139
|
-
depends_on :update_toc_in_readmen
|
|
140
|
-
desc "Install gem locally (depends on: update_toc_in_readmen)"
|
|
141
|
-
def install = sh "rake install"
|
|
142
|
-
|
|
143
|
-
# ── Backup ────────────────────────────────────────────────────────────────
|
|
144
|
-
|
|
145
|
-
desc "Backup .envrc and *.loki support files"
|
|
146
|
-
def backup_support_files
|
|
147
|
-
backup_loki_files
|
|
148
|
-
backup_envrc_files
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# ── Version management ────────────────────────────────────────────────────
|
|
152
|
-
|
|
153
|
-
desc "Create a git tag for the current version"
|
|
154
|
-
def tag = sh "git tag v#{current_version}"
|
|
155
|
-
|
|
156
|
-
desc "Push commits and all tags to origin"
|
|
157
|
-
def push
|
|
158
|
-
sh "git push"
|
|
159
|
-
sh "git push origin --tags"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
desc "bump [LEVEL]", "Increment version level: major, minor, or patch (default: patch)"
|
|
163
|
-
def bump(level = "patch")
|
|
164
|
-
require "versionaire"
|
|
165
|
-
path = version_filepath
|
|
166
|
-
old_ver = Versionaire::Version(File.read(path).strip)
|
|
167
|
-
new_ver = old_ver.bump(level.to_sym)
|
|
168
|
-
puts "Bumping #{level}: #{old_ver} to #{new_ver}"
|
|
169
|
-
File.write(path, "#{new_ver}\n")
|
|
170
|
-
sh "git add #{path}", silent: true
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
depends_on :tag, :push, :bump
|
|
174
|
-
desc "Tag the current commit, push it, then bump the version"
|
|
175
|
-
def tag_push_and_bump = puts "Tagged, pushed, and bumped."
|
|
176
|
-
|
|
177
|
-
# ── List ──────────────────────────────────────────────────────────────────
|
|
178
|
-
|
|
179
|
-
desc "List available tasks (default)"
|
|
180
|
-
def list = sh "asgard help"
|
|
181
|
-
|
|
182
|
-
# ── Private helpers ───────────────────────────────────────────────────────
|
|
183
|
-
|
|
184
|
-
private
|
|
185
|
-
|
|
186
|
-
def version_filepath = File.join(@@rr, ".version")
|
|
187
|
-
def current_version = File.read(version_filepath).strip
|
|
188
|
-
|
|
189
|
-
def backup_loki_files = sh "backup_just.rb", silent: true
|
|
190
|
-
def backup_envrc_files = sh "backup_envrc.rb", silent: true
|
|
191
|
-
|
|
192
|
-
def reek_scan
|
|
193
|
-
require 'reek'
|
|
194
|
-
require 'reek/configuration/app_configuration'
|
|
195
|
-
config_path = Pathname.new('.reek.yml')
|
|
196
|
-
config = config_path.exist? ? Reek::Configuration::AppConfiguration.from_path(config_path) : nil
|
|
197
|
-
sources = Dir.glob('lib/**/*.rb') + Dir.glob('plugins/**/*.rb')
|
|
198
|
-
sources.each_with_object({}) do |f, acc|
|
|
199
|
-
examiner = Reek::Examiner.new(File.read(f), configuration: config)
|
|
200
|
-
count = examiner.smells.size
|
|
201
|
-
acc[f] = count if count > 0
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
def load_reek_baseline
|
|
206
|
-
path = File.join(@@rr, '.quality', 'reek_baseline.txt')
|
|
207
|
-
return {} unless File.exist?(path)
|
|
208
|
-
|
|
209
|
-
File.readlines(path).each_with_object({}) do |line, acc|
|
|
210
|
-
count, file = line.strip.split("\t", 2)
|
|
211
|
-
acc[file] = count.to_i if file && !file.empty?
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
def reek_gate
|
|
216
|
-
current = reek_scan
|
|
217
|
-
baseline = load_reek_baseline
|
|
218
|
-
new_files = current.reject { |f, _| baseline.key?(f) }
|
|
219
|
-
worsened = current.select { |f, c| baseline.key?(f) && c > baseline[f] }
|
|
220
|
-
(new_files.empty? && worsened.empty?).tap do |ok|
|
|
221
|
-
File.write('reek_output.txt', ok ? "Reek quality gate passed.\n" : reek_failure_report(new_files, worsened, current, baseline))
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def reek_failure_report(new_files, worsened, current, baseline)
|
|
226
|
-
lines = ["Reek quality gate FAILED:\n"]
|
|
227
|
-
lines += new_files.map { |f, c| format(" NEW %3d warning(s): %s\n", c, f) }
|
|
228
|
-
lines += worsened.map { |f, c| format(" WORSENED %3d -> %3d: %s\n", baseline[f], c, f) }
|
|
229
|
-
lines.join
|
|
230
|
-
end
|
|
231
11
|
end
|
data/.reek.yml
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
detectors:
|
|
3
|
+
|
|
4
|
+
# Disabled: conflicts with project no-comment coding style.
|
|
5
|
+
IrresponsibleModule:
|
|
6
|
+
enabled: false
|
|
7
|
+
|
|
8
|
+
# Disabled: private helpers that don't reference self are fine where they are.
|
|
9
|
+
UtilityFunction:
|
|
10
|
+
enabled: false
|
|
11
|
+
|
|
12
|
+
# Disabled: respond_to? duck-typing is intentional in this codebase.
|
|
13
|
+
ManualDispatch:
|
|
14
|
+
enabled: false
|
|
15
|
+
|
|
16
|
+
# Disabled: attr_accessor is standard Ruby; public attributes are a design choice.
|
|
17
|
+
Attribute:
|
|
18
|
+
enabled: false
|
|
19
|
+
|
|
20
|
+
# Disabled: bang methods without non-bang counterparts are common in internal APIs.
|
|
21
|
+
MissingSafeMethod:
|
|
22
|
+
enabled: false
|
|
23
|
+
|
|
24
|
+
# Disabled: explicit nil checks are idiomatic Ruby (nil? / unless nil, etc.).
|
|
25
|
+
NilCheck:
|
|
26
|
+
enabled: false
|
|
27
|
+
|
|
28
|
+
# Disabled: handler/directive protocol methods must accept the full interface
|
|
29
|
+
# signature even when individual implementations don't use every parameter.
|
|
30
|
+
UnusedParameters:
|
|
31
|
+
enabled: false
|
|
32
|
+
|
|
33
|
+
# Disabled: same trade-off as UtilityFunction above — private formatting and
|
|
34
|
+
# extraction helpers deliberately operate on a passed-in value (result, tool,
|
|
35
|
+
# robot_result, raw metrics hash) next to their single caller; most of those
|
|
36
|
+
# values are Hashes or third-party objects we can't (and shouldn't) add
|
|
37
|
+
# methods to.
|
|
38
|
+
FeatureEnvy:
|
|
39
|
+
enabled: false
|
|
40
|
+
|
|
41
|
+
# Disabled: the detector fires on the codebase's configuration-cascade style —
|
|
42
|
+
# `arg || default` dependency-injection fallbacks in constructors and CLI
|
|
43
|
+
# override-precedence checks (e.g. LoggerManager#effective_log_file). Those
|
|
44
|
+
# conditionals ARE the method's purpose, not hidden polymorphism.
|
|
45
|
+
ControlParameter:
|
|
46
|
+
enabled: false
|
|
47
|
+
|
|
48
|
+
# Disabled: guard-clause style (see disabled IfUnlessModifier in rubocop) —
|
|
49
|
+
# cheap predicates like `available?`, `tracking`, `show_cost` guard each
|
|
50
|
+
# public method independently. Extracting a null-object/state machine for a
|
|
51
|
+
# CLI would be over-engineering; every flagged condition was a guard.
|
|
52
|
+
RepeatedConditional:
|
|
53
|
+
enabled: false
|
|
54
|
+
|
|
55
|
+
# Disabled: the detector doesn't follow initialize's delegation to reset
|
|
56
|
+
# helpers (Session#initialize_components, TurnState#clear!,
|
|
57
|
+
# ContextDirectives#reset!, Fzf#build_command) and flags `||=` memoization
|
|
58
|
+
# and class-level singleton caches. All 21 flagged ivars were audited
|
|
59
|
+
# (2026-09): every one is assigned before first read; zero nil-read risks.
|
|
60
|
+
InstanceVariableAssumption:
|
|
61
|
+
enabled: false
|
|
62
|
+
|
|
63
|
+
# 2-deep iteration (rendering a collection of collections, grouped output)
|
|
64
|
+
# is idiomatic Ruby; 30 of the 31 flagged sites were simple 2-deep
|
|
65
|
+
# each/map display or grouping loops.
|
|
66
|
+
NestedIterators:
|
|
67
|
+
max_allowed_nesting: 2
|
|
68
|
+
|
|
69
|
+
# Default is 1 — fires whenever a method is called even twice. Raise to 2.
|
|
70
|
+
DuplicateMethodCall:
|
|
71
|
+
max_calls: 2
|
|
72
|
+
|
|
73
|
+
# Default is 5; was 8. Raised to 12 with data (2026-09): 84 of the 166
|
|
74
|
+
# flagged methods sat at 9-12 statements — linear OptionParser registrations
|
|
75
|
+
# (CLIParser#setup_*), sequential display/formatting output, and step-wise
|
|
76
|
+
# orchestration with no added branching. Real complexity stays bounded by
|
|
77
|
+
# flog (warn >=20 / fail >=50) and rubocop Metrics (MethodLength 35, AbcSize
|
|
78
|
+
# 40). Methods above 12 are fixed or justified per site, not by threshold.
|
|
79
|
+
TooManyStatements:
|
|
80
|
+
max_statements: 12
|
|
81
|
+
|
|
82
|
+
# Default is 3 — extreme for this codebase.
|
|
83
|
+
LongParameterList:
|
|
84
|
+
max_params: 5
|
|
85
|
+
overrides:
|
|
86
|
+
initialize:
|
|
87
|
+
max_params: 7
|
|
88
|
+
|
|
89
|
+
# Default is 15; several AIA coordinator/handler classes legitimately exceed this.
|
|
90
|
+
TooManyMethods:
|
|
91
|
+
max_methods: 20
|
|
92
|
+
|
|
93
|
+
# Default is 4 — far too low for config and session classes with many fields.
|
|
94
|
+
TooManyInstanceVariables:
|
|
95
|
+
max_instance_variables: 8
|
|
96
|
+
|
|
97
|
+
# Default is 5; some modules carry more constants by design.
|
|
98
|
+
TooManyConstants:
|
|
99
|
+
max_constants: 8
|
|
100
|
+
|
|
101
|
+
# Raise min_clump_size so only truly repeated parameter groups are flagged.
|
|
102
|
+
DataClump:
|
|
103
|
+
max_copies: 2
|
|
104
|
+
min_clump_size: 3
|
|
105
|
+
|
|
106
|
+
# Accept standard Ruby short-name conventions for limited-scope variables.
|
|
107
|
+
UncommunicativeVariableName:
|
|
108
|
+
accept:
|
|
109
|
+
- _ # intentionally ignored
|
|
110
|
+
- a # array / argument
|
|
111
|
+
- b # body / block
|
|
112
|
+
- c # char / count / config
|
|
113
|
+
- d # data / dir
|
|
114
|
+
- e # rescue => e
|
|
115
|
+
- f # file / format / flag
|
|
116
|
+
- h # hash
|
|
117
|
+
- i # index
|
|
118
|
+
- k # key
|
|
119
|
+
- l # line / list
|
|
120
|
+
- m # match / message
|
|
121
|
+
- n # number / name
|
|
122
|
+
- p # path / param
|
|
123
|
+
- q # query
|
|
124
|
+
- r # result / response
|
|
125
|
+
- s # string / source
|
|
126
|
+
- t # time / token / type
|
|
127
|
+
- v # value
|
|
128
|
+
- w # word / width
|
|
129
|
+
|
|
130
|
+
UncommunicativeParameterName:
|
|
131
|
+
accept:
|
|
132
|
+
- a # vector math pairs (cosine_similarity(a, b))
|
|
133
|
+
- e
|
|
134
|
+
- i
|
|
135
|
+
- f
|
|
136
|
+
- k
|
|
137
|
+
- v
|
|
138
|
+
- t
|
|
139
|
+
- r
|
|
140
|
+
- s
|
|
141
|
+
- m
|
|
142
|
+
- n
|
|
143
|
+
- q
|
|
144
|
+
- b
|
|
145
|
+
|
|
146
|
+
directories:
|
|
147
|
+
# plugins/ — standalone LLM tool wrappers; execute() keyword arg lists map
|
|
148
|
+
# directly to LLM-visible parameters and are intentionally wide.
|
|
149
|
+
"plugins":
|
|
150
|
+
LongParameterList:
|
|
151
|
+
max_params: 20
|
|
152
|
+
TooManyMethods:
|
|
153
|
+
max_methods: 25
|
|
154
|
+
|
|
155
|
+
exclude_paths:
|
|
156
|
+
- test
|
|
157
|
+
- examples
|
|
158
|
+
- docs
|
|
159
|
+
- coverage
|
|
160
|
+
- pkg
|
data/.rubocop_strict.yml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Cops that must always fire, regardless of .rubocop_todo.yml or inline directives.
|
|
2
|
+
# Listed LAST in inherit_from to override any Exclude entries from todo files.
|
|
3
|
+
|
|
4
|
+
Lint/Debugger:
|
|
5
|
+
Enabled: true
|
|
6
|
+
Exclude: []
|
|
7
|
+
|
|
8
|
+
Security/Eval:
|
|
9
|
+
Enabled: true
|
|
10
|
+
Exclude: []
|
|
11
|
+
|
|
12
|
+
Lint/SuppressedException:
|
|
13
|
+
Enabled: true
|
|
14
|
+
Exclude: []
|
|
15
|
+
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.0.0.0-
|
|
1
|
+
2.0.0.0-beta2
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
This section captures all changes since v1.1.0.
|
|
6
6
|
|
|
7
|
+
## [2.0.0.pre.beta2] 2026-09-09
|
|
8
|
+
|
|
9
|
+
Using robot_lab v0.2.5
|
|
10
|
+
Using lumberjack v2.1.0
|
|
11
|
+
|
|
7
12
|
### Added
|
|
8
13
|
|
|
9
14
|
- **`--[no-]thinking` flag** (`lib/aia/config/cli_parser.rb`, `lib/aia/config/defaults.yml`, `lib/aia/config.rb`, `lib/aia/streaming_runner.rb`): Controls whether raw reasoning blocks from local models (e.g. `qwen3` on Ollama) are shown. Such models stream their chain-of-thought wrapped in `<think>...</think>` tags; AIA now filters these out by default so only the final answer is displayed. Pass `--thinking` to show the reasoning. The `StreamingRunner` strips the tags inline, tracking open spans across chunk boundaries. Config key: `flags.thinking` (env: `AIA_FLAGS__THINKING`); default `false`.
|
|
@@ -987,7 +992,7 @@ aia --chat -m gpt-4o-mini,gpt-3.5-turbo
|
|
|
987
992
|
- fixed a problem with a priming prompt in a chat loop
|
|
988
993
|
|
|
989
994
|
## [0.9.0] 2025-05-13
|
|
990
|
-
- Adding experimental MCP Client
|
|
995
|
+
- Adding experimental MCP Client support
|
|
991
996
|
- removed the CLI options --erb and --shell but kept them in the config file with a default of true for both
|
|
992
997
|
|
|
993
998
|
## [0.8.6] 2025-04-23
|
|
@@ -1059,7 +1064,7 @@ aia --chat -m gpt-4o-mini,gpt-3.5-turbo
|
|
|
1059
1064
|
- Added --image_size and --image_quality (--is --iq)
|
|
1060
1065
|
|
|
1061
1066
|
## [0.5.15] 2024-03-30
|
|
1062
|
-
- Added the ability to accept piped in text to be
|
|
1067
|
+
- Added the ability to accept piped in text to be appended to the end of the prompt text: curl $URL | aia ad_hoc
|
|
1063
1068
|
- Fixed bugs with entering directives as follow-up prompts during a chat session
|
|
1064
1069
|
|
|
1065
1070
|
## [0.5.14] 2024-03-09
|
|
@@ -1131,7 +1136,7 @@ aia --chat -m gpt-4o-mini,gpt-3.5-turbo
|
|
|
1131
1136
|
|
|
1132
1137
|
## [0.3.20] 2023-12-28
|
|
1133
1138
|
- added work around to issue with multiple context files going to the `mods` backend
|
|
1134
|
-
- added shellwords gem to
|
|
1139
|
+
- added shellwords gem to sanitize prompt text on the command line
|
|
1135
1140
|
|
|
1136
1141
|
## [0.3.19] 2023-12-26
|
|
1137
1142
|
- major code refactoring.
|
|
@@ -1139,7 +1144,7 @@ aia --chat -m gpt-4o-mini,gpt-3.5-turbo
|
|
|
1139
1144
|
- usage implemented as a man page. --help will display the man page/
|
|
1140
1145
|
- added "--dump <yml|yaml|toml>" to send current configuration to STDOUT
|
|
1141
1146
|
- added "--completion <bash|fish|zsh>" to send a a completion function for the indicated shell to STDOUT
|
|
1142
|
-
- added system environment variable (envar) over-rides of default config values uppercase environment variables prefixed with "AIA_" + config item name for example AIA_PROMPTS_DIR and AIA_MODEL. All config items can be over-ridden by their
|
|
1147
|
+
- added system environment variable (envar) over-rides of default config values uppercase environment variables prefixed with "AIA_" + config item name for example AIA_PROMPTS_DIR and AIA_MODEL. All config items can be over-ridden by their corresponding envars.
|
|
1143
1148
|
- config value hierarchy is:
|
|
1144
1149
|
1. values from config file over-rides ...
|
|
1145
1150
|
2. command line values over-rides ...
|
|
@@ -1148,7 +1153,7 @@ aia --chat -m gpt-4o-mini,gpt-3.5-turbo
|
|
|
1148
1153
|
|
|
1149
1154
|
## [0.3.0] = 2023-11-23
|
|
1150
1155
|
|
|
1151
|
-
- Matching version to [prompt_manager](https://github.com/prompt_manager) This version allows for the user of history in the
|
|
1156
|
+
- Matching version to [prompt_manager](https://github.com/prompt_manager) This version allows for the user of history in the entry of values to prompt keywords. KW_HISTORY_MAX is set at 5. Changed CLI interaction to use historical selection and editing of prior keyword values.
|
|
1152
1157
|
|
|
1153
1158
|
## [0.1.0] - 2023-11-23
|
|
1154
1159
|
|
data/README.md
CHANGED
|
@@ -1533,7 +1533,7 @@ Create executable prompts:
|
|
|
1533
1533
|
#!/usr/bin/env aia --no-output
|
|
1534
1534
|
# Get current storm activity for the east and south coast of the US
|
|
1535
1535
|
|
|
1536
|
-
Summarize the tropical storm outlook
|
|
1536
|
+
Summarize the tropical storm outlook for the Atlantic, Caribbean Sea and Gulf of America.
|
|
1537
1537
|
|
|
1538
1538
|
/webpage https://www.nhc.noaa.gov/text/refresh/MIATWOAT+shtml/201724_MIATWOAT.shtml
|
|
1539
1539
|
```
|
data/Rakefile
CHANGED
|
@@ -44,117 +44,4 @@ end
|
|
|
44
44
|
desc "Run all tests including integration tests"
|
|
45
45
|
task all_tests: %i[test integration]
|
|
46
46
|
|
|
47
|
-
# Quality gates use a committed BASELINE so accumulated debt doesn't block every
|
|
48
|
-
# change: they fail only on NEW or WORSENED items, not on pre-existing ones.
|
|
49
|
-
# Regenerate after intentionally accepting (or clearing) debt with the
|
|
50
|
-
# corresponding *_baseline task. Ratchet down by re-baselining once you fix items.
|
|
51
|
-
QUALITY_DIR = '.quality'
|
|
52
|
-
FLOG_BASELINE = File.join(QUALITY_DIR, 'flog_baseline.txt')
|
|
53
|
-
FLAY_BASELINE = File.join(QUALITY_DIR, 'flay_baseline.txt')
|
|
54
|
-
FLOG_FAIL = 50.0
|
|
55
|
-
FLOG_WARN = 20.0
|
|
56
|
-
FLOG_EPSILON = 0.5 # tolerate float jitter when comparing to the baseline
|
|
57
|
-
|
|
58
|
-
# @return [Hash{String=>Float}] method => score for methods over the fail line
|
|
59
|
-
def flog_failures
|
|
60
|
-
require 'flog'
|
|
61
|
-
flogger = Flog.new(all: true)
|
|
62
|
-
flogger.flog(*Dir.glob('lib/**/*.rb'))
|
|
63
|
-
failures = {}
|
|
64
|
-
flogger.each_by_score do |method, score|
|
|
65
|
-
next if method.end_with?('#none')
|
|
66
|
-
|
|
67
|
-
failures[method] = score if score > FLOG_FAIL
|
|
68
|
-
end
|
|
69
|
-
failures
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def load_flog_baseline
|
|
73
|
-
return {} unless File.exist?(FLOG_BASELINE)
|
|
74
|
-
|
|
75
|
-
File.readlines(FLOG_BASELINE).each_with_object({}) do |line, acc|
|
|
76
|
-
score, method = line.strip.split("\t", 2)
|
|
77
|
-
acc[method] = score.to_f if method && !method.empty?
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# @return [Flay] processed + analyzed flay instance
|
|
82
|
-
def flay_patterns
|
|
83
|
-
require 'flay'
|
|
84
|
-
flay = Flay.new(mass: 50, diff: false, verbose: false, summary: false, timeout: 60)
|
|
85
|
-
flay.process(*Dir.glob('lib/**/*.rb'))
|
|
86
|
-
flay.analyze
|
|
87
|
-
flay
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def load_flay_baseline
|
|
91
|
-
return [] unless File.exist?(FLAY_BASELINE)
|
|
92
|
-
|
|
93
|
-
File.readlines(FLAY_BASELINE).map(&:strip).reject(&:empty?)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
desc "Regenerate the flog baseline (grandfathers current methods >= #{FLOG_FAIL})"
|
|
97
|
-
task :flog_baseline do
|
|
98
|
-
require 'fileutils'
|
|
99
|
-
FileUtils.mkdir_p(QUALITY_DIR)
|
|
100
|
-
failures = flog_failures
|
|
101
|
-
body = failures.sort_by { |_, s| -s }.map { |m, s| format("%.1f\t%s", s, m) }.join("\n")
|
|
102
|
-
File.write(FLOG_BASELINE, body.empty? ? '' : "#{body}\n")
|
|
103
|
-
puts "Wrote #{failures.size} grandfathered method(s) to #{FLOG_BASELINE}"
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
desc "Check complexity with Flog (fails only on NEW or worsened methods >= #{FLOG_FAIL})"
|
|
107
|
-
task :flog_check do
|
|
108
|
-
current = flog_failures
|
|
109
|
-
baseline = load_flog_baseline
|
|
110
|
-
|
|
111
|
-
new_items = current.reject { |m, _| baseline.key?(m) }
|
|
112
|
-
worsened = current.select { |m, s| baseline.key?(m) && s > baseline[m] + FLOG_EPSILON }
|
|
113
|
-
fixed = baseline.keys - current.keys
|
|
114
|
-
|
|
115
|
-
puts "\nFlog: #{current.size} method(s) >= #{FLOG_FAIL} (#{baseline.size} grandfathered)."
|
|
116
|
-
puts " #{fixed.size} now under threshold — run `rake flog_baseline` to prune." unless fixed.empty?
|
|
117
|
-
|
|
118
|
-
problems = new_items.map { |m, s| format("NEW %.1f: %s", s, m) } +
|
|
119
|
-
worsened.map { |m, s| format("WORSENED %.1f (baseline %.1f): %s", s, baseline[m], m) }
|
|
120
|
-
|
|
121
|
-
if problems.empty?
|
|
122
|
-
puts "Flog quality gate passed (no new or worsened methods)."
|
|
123
|
-
else
|
|
124
|
-
puts "\nFlog quality gate failed:"
|
|
125
|
-
problems.each { |p| puts " #{p}" }
|
|
126
|
-
abort "\nFlog: #{problems.size} new/worsened method(s). Refactor them, or `rake flog_baseline` if intentional."
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
desc "Regenerate the flay baseline (grandfathers current duplication patterns)"
|
|
131
|
-
task :flay_baseline do
|
|
132
|
-
require 'fileutils'
|
|
133
|
-
FileUtils.mkdir_p(QUALITY_DIR)
|
|
134
|
-
hashes = flay_patterns.hashes.keys.map(&:to_s).sort
|
|
135
|
-
File.write(FLAY_BASELINE, hashes.empty? ? '' : "#{hashes.join("\n")}\n")
|
|
136
|
-
puts "Wrote #{hashes.size} grandfathered duplication pattern(s) to #{FLAY_BASELINE}"
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
desc "Check duplication with Flay (fails only on NEW patterns, mass >= 50)"
|
|
140
|
-
task :flay_check do
|
|
141
|
-
flay = flay_patterns
|
|
142
|
-
baseline = load_flay_baseline
|
|
143
|
-
current = flay.hashes.keys.map(&:to_s)
|
|
144
|
-
|
|
145
|
-
new_patterns = current - baseline
|
|
146
|
-
fixed = baseline - current
|
|
147
|
-
|
|
148
|
-
puts "\nFlay: #{current.size} duplication pattern(s) (#{baseline.size} grandfathered)."
|
|
149
|
-
puts " #{fixed.size} baseline pattern(s) gone — run `rake flay_baseline` to prune." unless fixed.empty?
|
|
150
|
-
|
|
151
|
-
if new_patterns.empty?
|
|
152
|
-
puts "Flay quality gate passed (no new duplication)."
|
|
153
|
-
else
|
|
154
|
-
puts "\nFlay quality gate failed: #{new_patterns.size} NEW pattern(s) (see report):"
|
|
155
|
-
flay.report
|
|
156
|
-
abort "\nFlay: new duplication introduced. Remove it, or `rake flay_baseline` if intentional."
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
47
|
task default: :test
|
data/_typos.toml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
[files]
|
|
2
|
+
# Generated by the asgard quality checks; may quote source lines that trip
|
|
3
|
+
# other checks (e.g. this file's own past runs), so keep it out of scope.
|
|
4
|
+
extend-exclude = ["*_output.txt"]
|
|
5
|
+
|
|
6
|
+
[default.extend-words]
|
|
7
|
+
# "trak" is part of the trak_flow gem's name (TrakFlow, trakflow_dir, ...),
|
|
8
|
+
# not a misspelling of "track".
|
|
9
|
+
trak = "trak"
|
|
10
|
+
trakflow = "trakflow"
|