aidp 0.17.1 → 0.19.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/README.md +69 -0
- data/lib/aidp/cli/terminal_io.rb +5 -2
- data/lib/aidp/cli.rb +43 -2
- data/lib/aidp/config.rb +9 -14
- data/lib/aidp/execute/agent_signal_parser.rb +20 -0
- data/lib/aidp/execute/persistent_tasklist.rb +220 -0
- data/lib/aidp/execute/prompt_manager.rb +128 -1
- data/lib/aidp/execute/repl_macros.rb +719 -0
- data/lib/aidp/execute/work_loop_runner.rb +162 -1
- data/lib/aidp/harness/ai_decision_engine.rb +376 -0
- data/lib/aidp/harness/capability_registry.rb +273 -0
- data/lib/aidp/harness/config_schema.rb +305 -1
- data/lib/aidp/harness/configuration.rb +452 -0
- data/lib/aidp/harness/enhanced_runner.rb +7 -1
- data/lib/aidp/harness/provider_factory.rb +0 -2
- data/lib/aidp/harness/runner.rb +7 -1
- data/lib/aidp/harness/thinking_depth_manager.rb +335 -0
- data/lib/aidp/harness/zfc_condition_detector.rb +395 -0
- data/lib/aidp/init/devcontainer_generator.rb +274 -0
- data/lib/aidp/init/runner.rb +37 -10
- data/lib/aidp/init.rb +1 -0
- data/lib/aidp/prompt_optimization/context_composer.rb +286 -0
- data/lib/aidp/prompt_optimization/optimizer.rb +335 -0
- data/lib/aidp/prompt_optimization/prompt_builder.rb +309 -0
- data/lib/aidp/prompt_optimization/relevance_scorer.rb +256 -0
- data/lib/aidp/prompt_optimization/source_code_fragmenter.rb +308 -0
- data/lib/aidp/prompt_optimization/style_guide_indexer.rb +240 -0
- data/lib/aidp/prompt_optimization/template_indexer.rb +250 -0
- data/lib/aidp/provider_manager.rb +0 -2
- data/lib/aidp/providers/anthropic.rb +19 -0
- data/lib/aidp/setup/wizard.rb +299 -4
- data/lib/aidp/utils/devcontainer_detector.rb +166 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/build_processor.rb +72 -6
- data/lib/aidp/watch/repository_client.rb +2 -1
- data/lib/aidp.rb +1 -1
- data/templates/aidp.yml.example +128 -0
- metadata +15 -2
- data/lib/aidp/providers/macos_ui.rb +0 -102
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
|
|
6
|
+
module Aidp
|
|
7
|
+
module Harness
|
|
8
|
+
# Stores and queries model capability metadata from the catalog
|
|
9
|
+
# Provides information about model tiers, features, costs, and context windows
|
|
10
|
+
class CapabilityRegistry
|
|
11
|
+
# Valid thinking depth tiers
|
|
12
|
+
VALID_TIERS = %w[mini standard thinking pro max].freeze
|
|
13
|
+
|
|
14
|
+
# Tier priority for escalation (lower index = lower tier)
|
|
15
|
+
TIER_PRIORITY = {
|
|
16
|
+
"mini" => 0,
|
|
17
|
+
"standard" => 1,
|
|
18
|
+
"thinking" => 2,
|
|
19
|
+
"pro" => 3,
|
|
20
|
+
"max" => 4
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
attr_reader :catalog_path
|
|
24
|
+
|
|
25
|
+
def initialize(catalog_path: nil, root_dir: nil)
|
|
26
|
+
@root_dir = root_dir || Dir.pwd
|
|
27
|
+
@catalog_path = catalog_path || default_catalog_path
|
|
28
|
+
@catalog_data = nil
|
|
29
|
+
@loaded_at = nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Load catalog from YAML file
|
|
33
|
+
def load_catalog
|
|
34
|
+
return false unless File.exist?(@catalog_path)
|
|
35
|
+
|
|
36
|
+
@catalog_data = YAML.safe_load_file(
|
|
37
|
+
@catalog_path,
|
|
38
|
+
permitted_classes: [Symbol],
|
|
39
|
+
symbolize_names: false
|
|
40
|
+
)
|
|
41
|
+
@loaded_at = Time.now
|
|
42
|
+
|
|
43
|
+
validate_catalog(@catalog_data)
|
|
44
|
+
Aidp.log_debug("capability_registry", "Loaded catalog", path: @catalog_path, providers: provider_names.size)
|
|
45
|
+
true
|
|
46
|
+
rescue => e
|
|
47
|
+
Aidp.log_error("capability_registry", "Failed to load catalog", error: e.message, path: @catalog_path)
|
|
48
|
+
@catalog_data = nil
|
|
49
|
+
false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Get catalog data (lazy load if needed)
|
|
53
|
+
def catalog
|
|
54
|
+
load_catalog if @catalog_data.nil?
|
|
55
|
+
@catalog_data || default_empty_catalog
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Get all provider names in catalog
|
|
59
|
+
def provider_names
|
|
60
|
+
catalog.dig("providers")&.keys || []
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get all models for a provider
|
|
64
|
+
def models_for_provider(provider_name)
|
|
65
|
+
provider_data = catalog.dig("providers", provider_name)
|
|
66
|
+
return {} unless provider_data
|
|
67
|
+
|
|
68
|
+
provider_data["models"] || {}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Get tier for a specific model
|
|
72
|
+
def tier_for_model(provider_name, model_name)
|
|
73
|
+
model_data = model_info(provider_name, model_name)
|
|
74
|
+
return nil unless model_data
|
|
75
|
+
|
|
76
|
+
model_data["tier"]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Get all models matching a specific tier
|
|
80
|
+
# Returns hash: { provider_name => [model_name, ...] }
|
|
81
|
+
def models_by_tier(tier, provider: nil)
|
|
82
|
+
validate_tier!(tier)
|
|
83
|
+
|
|
84
|
+
results = {}
|
|
85
|
+
providers_to_search = provider ? [provider] : provider_names
|
|
86
|
+
|
|
87
|
+
providers_to_search.each do |provider_name|
|
|
88
|
+
matching_models = []
|
|
89
|
+
models_for_provider(provider_name).each do |model_name, model_data|
|
|
90
|
+
matching_models << model_name if model_data["tier"] == tier
|
|
91
|
+
end
|
|
92
|
+
results[provider_name] = matching_models unless matching_models.empty?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
results
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Get complete info for a specific model
|
|
99
|
+
def model_info(provider_name, model_name)
|
|
100
|
+
catalog.dig("providers", provider_name, "models", model_name)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Get display name for a provider
|
|
104
|
+
def provider_display_name(provider_name)
|
|
105
|
+
catalog.dig("providers", provider_name, "display_name") || provider_name
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Get all tiers supported by a provider
|
|
109
|
+
def supported_tiers(provider_name)
|
|
110
|
+
models = models_for_provider(provider_name)
|
|
111
|
+
tiers = models.values.map { |m| m["tier"] }.compact.uniq
|
|
112
|
+
tiers.sort_by { |t| TIER_PRIORITY[t] || 999 }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Check if a tier is valid
|
|
116
|
+
def valid_tier?(tier)
|
|
117
|
+
VALID_TIERS.include?(tier)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Get tier priority (0 = lowest, 4 = highest)
|
|
121
|
+
def tier_priority(tier)
|
|
122
|
+
TIER_PRIORITY[tier]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Compare two tiers (returns -1, 0, 1 like <=>)
|
|
126
|
+
def compare_tiers(tier1, tier2)
|
|
127
|
+
priority1 = tier_priority(tier1) || -1
|
|
128
|
+
priority2 = tier_priority(tier2) || -1
|
|
129
|
+
priority1 <=> priority2
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Get next higher tier (or nil if already at max)
|
|
133
|
+
def next_tier(tier)
|
|
134
|
+
validate_tier!(tier)
|
|
135
|
+
current_priority = tier_priority(tier)
|
|
136
|
+
return nil if current_priority >= TIER_PRIORITY["max"]
|
|
137
|
+
|
|
138
|
+
TIER_PRIORITY.key(current_priority + 1)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Get next lower tier (or nil if already at mini)
|
|
142
|
+
def previous_tier(tier)
|
|
143
|
+
validate_tier!(tier)
|
|
144
|
+
current_priority = tier_priority(tier)
|
|
145
|
+
return nil if current_priority <= TIER_PRIORITY["mini"]
|
|
146
|
+
|
|
147
|
+
TIER_PRIORITY.key(current_priority - 1)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Find best model for a tier and provider
|
|
151
|
+
# Returns [model_name, model_data] or nil
|
|
152
|
+
def best_model_for_tier(tier, provider_name)
|
|
153
|
+
validate_tier!(tier)
|
|
154
|
+
models = models_for_provider(provider_name)
|
|
155
|
+
|
|
156
|
+
# Find all models matching tier
|
|
157
|
+
tier_models = models.select { |_name, data| data["tier"] == tier }
|
|
158
|
+
return nil if tier_models.empty?
|
|
159
|
+
|
|
160
|
+
# Prefer newer models (higher in the list)
|
|
161
|
+
# Sort by cost (cheaper first) as tiebreaker
|
|
162
|
+
tier_models.min_by do |_name, data|
|
|
163
|
+
cost = data["cost_per_mtok_input"] || 0
|
|
164
|
+
[cost]
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Get tier recommendations from catalog
|
|
169
|
+
def tier_recommendations
|
|
170
|
+
catalog["tier_recommendations"] || {}
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Recommend tier based on complexity score (0.0-1.0)
|
|
174
|
+
def recommend_tier_for_complexity(complexity_score)
|
|
175
|
+
return "mini" if complexity_score <= 0.0
|
|
176
|
+
|
|
177
|
+
recommendations = tier_recommendations.sort_by do |_name, data|
|
|
178
|
+
data["complexity_threshold"] || 0.0
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Find first recommendation where complexity exceeds threshold
|
|
182
|
+
recommendation = recommendations.find do |_name, data|
|
|
183
|
+
complexity_score <= (data["complexity_threshold"] || 0.0)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
recommendation ? recommendation[1]["recommended_tier"] : "max"
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Reload catalog from disk
|
|
190
|
+
def reload
|
|
191
|
+
@catalog_data = nil
|
|
192
|
+
@loaded_at = nil
|
|
193
|
+
load_catalog
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Check if catalog needs reload (based on file modification time)
|
|
197
|
+
def stale?(max_age_seconds = 3600)
|
|
198
|
+
return true unless @loaded_at
|
|
199
|
+
return true unless File.exist?(@catalog_path)
|
|
200
|
+
|
|
201
|
+
file_mtime = File.mtime(@catalog_path)
|
|
202
|
+
file_mtime > @loaded_at || (Time.now - @loaded_at) > max_age_seconds
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Export catalog as structured data for display
|
|
206
|
+
def export_for_display
|
|
207
|
+
{
|
|
208
|
+
schema_version: catalog["schema_version"],
|
|
209
|
+
providers: provider_names.map do |provider_name|
|
|
210
|
+
{
|
|
211
|
+
name: provider_name,
|
|
212
|
+
display_name: provider_display_name(provider_name),
|
|
213
|
+
tiers: supported_tiers(provider_name),
|
|
214
|
+
models: models_for_provider(provider_name)
|
|
215
|
+
}
|
|
216
|
+
end,
|
|
217
|
+
tier_order: VALID_TIERS
|
|
218
|
+
}
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
private
|
|
222
|
+
|
|
223
|
+
def default_catalog_path
|
|
224
|
+
File.join(@root_dir, ".aidp", "models_catalog.yml")
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def default_empty_catalog
|
|
228
|
+
{
|
|
229
|
+
"schema_version" => "1.0",
|
|
230
|
+
"providers" => {},
|
|
231
|
+
"tier_order" => VALID_TIERS,
|
|
232
|
+
"tier_recommendations" => {}
|
|
233
|
+
}
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def validate_catalog(data)
|
|
237
|
+
unless data.is_a?(Hash)
|
|
238
|
+
raise ArgumentError, "Catalog must be a hash"
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
unless data["providers"].is_a?(Hash)
|
|
242
|
+
raise ArgumentError, "Catalog must have 'providers' hash"
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Validate each provider has models
|
|
246
|
+
data["providers"].each do |provider_name, provider_data|
|
|
247
|
+
unless provider_data.is_a?(Hash) && provider_data["models"].is_a?(Hash)
|
|
248
|
+
raise ArgumentError, "Provider #{provider_name} must have 'models' hash"
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Validate each model has required fields
|
|
252
|
+
provider_data["models"].each do |model_name, model_data|
|
|
253
|
+
unless model_data["tier"]
|
|
254
|
+
raise ArgumentError, "Model #{provider_name}/#{model_name} missing 'tier'"
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
unless valid_tier?(model_data["tier"])
|
|
258
|
+
raise ArgumentError, "Model #{provider_name}/#{model_name} has invalid tier: #{model_data["tier"]}"
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
Aidp.log_debug("capability_registry", "Catalog validation passed", providers: data["providers"].size)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def validate_tier!(tier)
|
|
267
|
+
unless valid_tier?(tier)
|
|
268
|
+
raise ArgumentError, "Invalid tier: #{tier}. Must be one of: #{VALID_TIERS.join(", ")}"
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
@@ -375,7 +375,11 @@ module Aidp
|
|
|
375
375
|
max_iterations: 50,
|
|
376
376
|
test_commands: [],
|
|
377
377
|
lint_commands: [],
|
|
378
|
-
units: {}
|
|
378
|
+
units: {},
|
|
379
|
+
guards: {enabled: false},
|
|
380
|
+
version_control: {tool: "git", behavior: "nothing", conventional_commits: false},
|
|
381
|
+
coverage: {enabled: false},
|
|
382
|
+
interactive_testing: {enabled: false, app_type: "web"}
|
|
379
383
|
},
|
|
380
384
|
properties: {
|
|
381
385
|
enabled: {
|
|
@@ -543,6 +547,300 @@ module Aidp
|
|
|
543
547
|
default: false
|
|
544
548
|
}
|
|
545
549
|
}
|
|
550
|
+
},
|
|
551
|
+
version_control: {
|
|
552
|
+
type: :hash,
|
|
553
|
+
required: false,
|
|
554
|
+
default: {
|
|
555
|
+
tool: "git",
|
|
556
|
+
behavior: "nothing",
|
|
557
|
+
conventional_commits: false
|
|
558
|
+
},
|
|
559
|
+
properties: {
|
|
560
|
+
tool: {
|
|
561
|
+
type: :string,
|
|
562
|
+
required: false,
|
|
563
|
+
default: "git",
|
|
564
|
+
enum: ["git", "svn", "none"]
|
|
565
|
+
},
|
|
566
|
+
behavior: {
|
|
567
|
+
type: :string,
|
|
568
|
+
required: false,
|
|
569
|
+
default: "nothing",
|
|
570
|
+
enum: ["stage", "commit", "nothing"]
|
|
571
|
+
},
|
|
572
|
+
conventional_commits: {
|
|
573
|
+
type: :boolean,
|
|
574
|
+
required: false,
|
|
575
|
+
default: false
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
coverage: {
|
|
580
|
+
type: :hash,
|
|
581
|
+
required: false,
|
|
582
|
+
default: {
|
|
583
|
+
enabled: false
|
|
584
|
+
},
|
|
585
|
+
properties: {
|
|
586
|
+
enabled: {
|
|
587
|
+
type: :boolean,
|
|
588
|
+
required: false,
|
|
589
|
+
default: false
|
|
590
|
+
},
|
|
591
|
+
tool: {
|
|
592
|
+
type: :string,
|
|
593
|
+
required: false,
|
|
594
|
+
enum: ["simplecov", "nyc", "istanbul", "coverage.py", "go-cover", "jest", "other"]
|
|
595
|
+
},
|
|
596
|
+
run_command: {
|
|
597
|
+
type: :string,
|
|
598
|
+
required: false
|
|
599
|
+
},
|
|
600
|
+
report_paths: {
|
|
601
|
+
type: :array,
|
|
602
|
+
required: false,
|
|
603
|
+
default: [],
|
|
604
|
+
items: {
|
|
605
|
+
type: :string
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
fail_on_drop: {
|
|
609
|
+
type: :boolean,
|
|
610
|
+
required: false,
|
|
611
|
+
default: false
|
|
612
|
+
},
|
|
613
|
+
minimum_coverage: {
|
|
614
|
+
type: :number,
|
|
615
|
+
required: false,
|
|
616
|
+
min: 0.0,
|
|
617
|
+
max: 100.0
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
interactive_testing: {
|
|
622
|
+
type: :hash,
|
|
623
|
+
required: false,
|
|
624
|
+
default: {
|
|
625
|
+
enabled: false,
|
|
626
|
+
app_type: "web"
|
|
627
|
+
},
|
|
628
|
+
properties: {
|
|
629
|
+
enabled: {
|
|
630
|
+
type: :boolean,
|
|
631
|
+
required: false,
|
|
632
|
+
default: false
|
|
633
|
+
},
|
|
634
|
+
app_type: {
|
|
635
|
+
type: :string,
|
|
636
|
+
required: false,
|
|
637
|
+
default: "web",
|
|
638
|
+
enum: ["web", "cli", "desktop"]
|
|
639
|
+
},
|
|
640
|
+
tools: {
|
|
641
|
+
type: :hash,
|
|
642
|
+
required: false,
|
|
643
|
+
default: {},
|
|
644
|
+
properties: {
|
|
645
|
+
web: {
|
|
646
|
+
type: :hash,
|
|
647
|
+
required: false,
|
|
648
|
+
default: {},
|
|
649
|
+
properties: {
|
|
650
|
+
playwright_mcp: {
|
|
651
|
+
type: :hash,
|
|
652
|
+
required: false,
|
|
653
|
+
default: {enabled: false},
|
|
654
|
+
properties: {
|
|
655
|
+
enabled: {
|
|
656
|
+
type: :boolean,
|
|
657
|
+
required: false,
|
|
658
|
+
default: false
|
|
659
|
+
},
|
|
660
|
+
run: {
|
|
661
|
+
type: :string,
|
|
662
|
+
required: false
|
|
663
|
+
},
|
|
664
|
+
specs_dir: {
|
|
665
|
+
type: :string,
|
|
666
|
+
required: false,
|
|
667
|
+
default: ".aidp/tests/web"
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
},
|
|
671
|
+
chrome_devtools_mcp: {
|
|
672
|
+
type: :hash,
|
|
673
|
+
required: false,
|
|
674
|
+
default: {enabled: false},
|
|
675
|
+
properties: {
|
|
676
|
+
enabled: {
|
|
677
|
+
type: :boolean,
|
|
678
|
+
required: false,
|
|
679
|
+
default: false
|
|
680
|
+
},
|
|
681
|
+
run: {
|
|
682
|
+
type: :string,
|
|
683
|
+
required: false
|
|
684
|
+
},
|
|
685
|
+
specs_dir: {
|
|
686
|
+
type: :string,
|
|
687
|
+
required: false,
|
|
688
|
+
default: ".aidp/tests/web"
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
},
|
|
694
|
+
cli: {
|
|
695
|
+
type: :hash,
|
|
696
|
+
required: false,
|
|
697
|
+
default: {},
|
|
698
|
+
properties: {
|
|
699
|
+
expect: {
|
|
700
|
+
type: :hash,
|
|
701
|
+
required: false,
|
|
702
|
+
default: {enabled: false},
|
|
703
|
+
properties: {
|
|
704
|
+
enabled: {
|
|
705
|
+
type: :boolean,
|
|
706
|
+
required: false,
|
|
707
|
+
default: false
|
|
708
|
+
},
|
|
709
|
+
run: {
|
|
710
|
+
type: :string,
|
|
711
|
+
required: false
|
|
712
|
+
},
|
|
713
|
+
specs_dir: {
|
|
714
|
+
type: :string,
|
|
715
|
+
required: false,
|
|
716
|
+
default: ".aidp/tests/cli"
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
},
|
|
722
|
+
desktop: {
|
|
723
|
+
type: :hash,
|
|
724
|
+
required: false,
|
|
725
|
+
default: {},
|
|
726
|
+
properties: {
|
|
727
|
+
applescript: {
|
|
728
|
+
type: :hash,
|
|
729
|
+
required: false,
|
|
730
|
+
default: {enabled: false},
|
|
731
|
+
properties: {
|
|
732
|
+
enabled: {
|
|
733
|
+
type: :boolean,
|
|
734
|
+
required: false,
|
|
735
|
+
default: false
|
|
736
|
+
},
|
|
737
|
+
run: {
|
|
738
|
+
type: :string,
|
|
739
|
+
required: false
|
|
740
|
+
},
|
|
741
|
+
specs_dir: {
|
|
742
|
+
type: :string,
|
|
743
|
+
required: false,
|
|
744
|
+
default: ".aidp/tests/desktop"
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
screen_reader: {
|
|
749
|
+
type: :hash,
|
|
750
|
+
required: false,
|
|
751
|
+
default: {enabled: false},
|
|
752
|
+
properties: {
|
|
753
|
+
enabled: {
|
|
754
|
+
type: :boolean,
|
|
755
|
+
required: false,
|
|
756
|
+
default: false
|
|
757
|
+
},
|
|
758
|
+
notes: {
|
|
759
|
+
type: :string,
|
|
760
|
+
required: false
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
},
|
|
774
|
+
thinking: {
|
|
775
|
+
type: :hash,
|
|
776
|
+
required: false,
|
|
777
|
+
properties: {
|
|
778
|
+
default_tier: {
|
|
779
|
+
type: :string,
|
|
780
|
+
required: false,
|
|
781
|
+
default: "standard",
|
|
782
|
+
enum: ["mini", "standard", "thinking", "pro", "max"]
|
|
783
|
+
},
|
|
784
|
+
max_tier: {
|
|
785
|
+
type: :string,
|
|
786
|
+
required: false,
|
|
787
|
+
default: "standard",
|
|
788
|
+
enum: ["mini", "standard", "thinking", "pro", "max"]
|
|
789
|
+
},
|
|
790
|
+
allow_provider_switch: {
|
|
791
|
+
type: :boolean,
|
|
792
|
+
required: false,
|
|
793
|
+
default: true
|
|
794
|
+
},
|
|
795
|
+
escalation: {
|
|
796
|
+
type: :hash,
|
|
797
|
+
required: false,
|
|
798
|
+
properties: {
|
|
799
|
+
on_fail_attempts: {
|
|
800
|
+
type: :integer,
|
|
801
|
+
required: false,
|
|
802
|
+
default: 2,
|
|
803
|
+
min: 1,
|
|
804
|
+
max: 10
|
|
805
|
+
},
|
|
806
|
+
on_complexity_threshold: {
|
|
807
|
+
type: :hash,
|
|
808
|
+
required: false,
|
|
809
|
+
default: {},
|
|
810
|
+
properties: {
|
|
811
|
+
files_changed: {
|
|
812
|
+
type: :integer,
|
|
813
|
+
required: false,
|
|
814
|
+
min: 1
|
|
815
|
+
},
|
|
816
|
+
modules_touched: {
|
|
817
|
+
type: :integer,
|
|
818
|
+
required: false,
|
|
819
|
+
min: 1
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
permissions_by_tier: {
|
|
826
|
+
type: :hash,
|
|
827
|
+
required: false,
|
|
828
|
+
default: {},
|
|
829
|
+
pattern_properties: {
|
|
830
|
+
/^(mini|standard|thinking|pro|max)$/ => {
|
|
831
|
+
type: :string,
|
|
832
|
+
enum: ["safe", "tools", "dangerous"]
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
overrides: {
|
|
837
|
+
type: :hash,
|
|
838
|
+
required: false,
|
|
839
|
+
default: {},
|
|
840
|
+
pattern_properties: {
|
|
841
|
+
/^(skill|template)\..+$/ => {
|
|
842
|
+
type: :string,
|
|
843
|
+
enum: ["mini", "standard", "thinking", "pro", "max"]
|
|
546
844
|
}
|
|
547
845
|
}
|
|
548
846
|
}
|
|
@@ -568,6 +866,12 @@ module Aidp
|
|
|
568
866
|
min: 1,
|
|
569
867
|
max: 10
|
|
570
868
|
},
|
|
869
|
+
model_family: {
|
|
870
|
+
type: :string,
|
|
871
|
+
required: false,
|
|
872
|
+
default: "auto",
|
|
873
|
+
enum: ["auto", "openai_o", "claude", "mistral", "local"]
|
|
874
|
+
},
|
|
571
875
|
max_tokens: {
|
|
572
876
|
type: :integer,
|
|
573
877
|
required: false,
|