aidp 0.26.0 → 0.28.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 +89 -0
- data/lib/aidp/cli/checkpoint_command.rb +198 -0
- data/lib/aidp/cli/config_command.rb +71 -0
- data/lib/aidp/cli/enhanced_input.rb +2 -0
- data/lib/aidp/cli/first_run_wizard.rb +8 -7
- data/lib/aidp/cli/harness_command.rb +102 -0
- data/lib/aidp/cli/jobs_command.rb +3 -3
- data/lib/aidp/cli/mcp_dashboard.rb +4 -3
- data/lib/aidp/cli/models_command.rb +661 -0
- data/lib/aidp/cli/providers_command.rb +223 -0
- data/lib/aidp/cli.rb +45 -464
- data/lib/aidp/config.rb +54 -0
- data/lib/aidp/daemon/runner.rb +2 -2
- data/lib/aidp/debug_mixin.rb +25 -10
- data/lib/aidp/execute/agent_signal_parser.rb +22 -0
- data/lib/aidp/execute/async_work_loop_runner.rb +2 -1
- data/lib/aidp/execute/checkpoint_display.rb +38 -37
- data/lib/aidp/execute/interactive_repl.rb +2 -1
- data/lib/aidp/execute/prompt_manager.rb +4 -4
- data/lib/aidp/execute/repl_macros.rb +2 -2
- data/lib/aidp/execute/steps.rb +94 -1
- data/lib/aidp/execute/work_loop_runner.rb +238 -19
- data/lib/aidp/execute/workflow_selector.rb +4 -27
- data/lib/aidp/firewall/provider_requirements_collector.rb +262 -0
- data/lib/aidp/harness/ai_decision_engine.rb +35 -2
- data/lib/aidp/harness/config_manager.rb +5 -10
- data/lib/aidp/harness/config_schema.rb +8 -0
- data/lib/aidp/harness/configuration.rb +40 -2
- data/lib/aidp/harness/enhanced_runner.rb +25 -19
- data/lib/aidp/harness/error_handler.rb +23 -73
- data/lib/aidp/harness/model_cache.rb +269 -0
- data/lib/aidp/harness/model_discovery_service.rb +259 -0
- data/lib/aidp/harness/model_registry.rb +201 -0
- data/lib/aidp/harness/provider_factory.rb +11 -2
- data/lib/aidp/harness/runner.rb +5 -0
- data/lib/aidp/harness/state_manager.rb +0 -7
- data/lib/aidp/harness/thinking_depth_manager.rb +202 -7
- data/lib/aidp/harness/ui/enhanced_tui.rb +8 -18
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +0 -18
- data/lib/aidp/harness/ui/progress_display.rb +6 -2
- data/lib/aidp/harness/user_interface.rb +0 -58
- data/lib/aidp/init/runner.rb +7 -2
- data/lib/aidp/message_display.rb +0 -46
- data/lib/aidp/planning/analyzers/feedback_analyzer.rb +365 -0
- data/lib/aidp/planning/builders/agile_plan_builder.rb +387 -0
- data/lib/aidp/planning/builders/project_plan_builder.rb +193 -0
- data/lib/aidp/planning/generators/gantt_generator.rb +190 -0
- data/lib/aidp/planning/generators/iteration_plan_generator.rb +392 -0
- data/lib/aidp/planning/generators/legacy_research_planner.rb +473 -0
- data/lib/aidp/planning/generators/marketing_report_generator.rb +348 -0
- data/lib/aidp/planning/generators/mvp_scope_generator.rb +310 -0
- data/lib/aidp/planning/generators/user_test_plan_generator.rb +373 -0
- data/lib/aidp/planning/generators/wbs_generator.rb +259 -0
- data/lib/aidp/planning/mappers/persona_mapper.rb +163 -0
- data/lib/aidp/planning/parsers/document_parser.rb +141 -0
- data/lib/aidp/planning/parsers/feedback_data_parser.rb +252 -0
- data/lib/aidp/provider_manager.rb +8 -32
- data/lib/aidp/providers/adapter.rb +2 -4
- data/lib/aidp/providers/aider.rb +264 -0
- data/lib/aidp/providers/anthropic.rb +206 -121
- data/lib/aidp/providers/base.rb +123 -3
- data/lib/aidp/providers/capability_registry.rb +0 -1
- data/lib/aidp/providers/codex.rb +75 -70
- data/lib/aidp/providers/cursor.rb +87 -59
- data/lib/aidp/providers/gemini.rb +57 -60
- data/lib/aidp/providers/github_copilot.rb +19 -66
- data/lib/aidp/providers/kilocode.rb +35 -80
- data/lib/aidp/providers/opencode.rb +35 -80
- data/lib/aidp/setup/wizard.rb +555 -8
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/build_processor.rb +211 -30
- data/lib/aidp/watch/change_request_processor.rb +128 -14
- data/lib/aidp/watch/ci_fix_processor.rb +103 -37
- data/lib/aidp/watch/ci_log_extractor.rb +258 -0
- data/lib/aidp/watch/github_state_extractor.rb +177 -0
- data/lib/aidp/watch/implementation_verifier.rb +284 -0
- data/lib/aidp/watch/plan_generator.rb +95 -52
- data/lib/aidp/watch/plan_processor.rb +7 -6
- data/lib/aidp/watch/repository_client.rb +245 -17
- data/lib/aidp/watch/review_processor.rb +100 -19
- data/lib/aidp/watch/reviewers/base_reviewer.rb +1 -1
- data/lib/aidp/watch/runner.rb +181 -29
- data/lib/aidp/watch/state_store.rb +22 -1
- data/lib/aidp/workflows/definitions.rb +147 -0
- data/lib/aidp/workflows/guided_agent.rb +3 -3
- data/lib/aidp/workstream_cleanup.rb +245 -0
- data/lib/aidp/worktree.rb +19 -0
- data/templates/aidp-development.yml.example +2 -2
- data/templates/aidp-production.yml.example +3 -3
- data/templates/aidp.yml.example +57 -0
- data/templates/implementation/generate_tdd_specs.md +213 -0
- data/templates/implementation/iterative_implementation.md +122 -0
- data/templates/planning/agile/analyze_feedback.md +183 -0
- data/templates/planning/agile/generate_iteration_plan.md +179 -0
- data/templates/planning/agile/generate_legacy_research_plan.md +171 -0
- data/templates/planning/agile/generate_marketing_report.md +162 -0
- data/templates/planning/agile/generate_mvp_scope.md +127 -0
- data/templates/planning/agile/generate_user_test_plan.md +143 -0
- data/templates/planning/agile/ingest_feedback.md +174 -0
- data/templates/planning/assemble_project_plan.md +113 -0
- data/templates/planning/assign_personas.md +108 -0
- data/templates/planning/create_tasks.md +52 -6
- data/templates/planning/generate_gantt.md +86 -0
- data/templates/planning/generate_wbs.md +85 -0
- data/templates/planning/initialize_planning_mode.md +70 -0
- data/templates/skills/README.md +2 -2
- data/templates/skills/marketing_strategist/SKILL.md +279 -0
- data/templates/skills/product_manager/SKILL.md +177 -0
- data/templates/skills/ruby_aidp_planning/SKILL.md +497 -0
- data/templates/skills/ruby_rspec_tdd/SKILL.md +514 -0
- data/templates/skills/ux_researcher/SKILL.md +222 -0
- metadata +47 -1
|
@@ -8,10 +8,66 @@ module Aidp
|
|
|
8
8
|
class Gemini < Base
|
|
9
9
|
include Aidp::DebugMixin
|
|
10
10
|
|
|
11
|
+
# Model name pattern for Gemini models
|
|
12
|
+
MODEL_PATTERN = /^gemini-[\d.]+-(?:pro|flash|ultra)(?:-\d+)?$/i
|
|
13
|
+
|
|
11
14
|
def self.available?
|
|
12
15
|
!!Aidp::Util.which("gemini")
|
|
13
16
|
end
|
|
14
17
|
|
|
18
|
+
# Normalize a provider-specific model name to its model family
|
|
19
|
+
#
|
|
20
|
+
# Gemini may use version suffixes (e.g., "gemini-1.5-pro-001").
|
|
21
|
+
# This method strips version suffixes to get the family name.
|
|
22
|
+
#
|
|
23
|
+
# @param provider_model_name [String] The model name
|
|
24
|
+
# @return [String] The model family name
|
|
25
|
+
def self.model_family(provider_model_name)
|
|
26
|
+
# Strip version suffix: "gemini-1.5-pro-001" → "gemini-1.5-pro"
|
|
27
|
+
provider_model_name.sub(/-\d+$/, "")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Convert a model family name to the provider's preferred model name
|
|
31
|
+
#
|
|
32
|
+
# @param family_name [String] The model family name
|
|
33
|
+
# @return [String] The provider-specific model name (same as family)
|
|
34
|
+
def self.provider_model_name(family_name)
|
|
35
|
+
family_name
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Check if this provider supports a given model family
|
|
39
|
+
#
|
|
40
|
+
# @param family_name [String] The model family name
|
|
41
|
+
# @return [Boolean] True if it matches Gemini model pattern
|
|
42
|
+
def self.supports_model_family?(family_name)
|
|
43
|
+
MODEL_PATTERN.match?(family_name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Discover available models from Gemini
|
|
47
|
+
#
|
|
48
|
+
# Note: Gemini CLI doesn't have a standard model listing command
|
|
49
|
+
# Returns registry-based models that match Gemini patterns
|
|
50
|
+
#
|
|
51
|
+
# @return [Array<Hash>] Array of discovered models
|
|
52
|
+
def self.discover_models
|
|
53
|
+
return [] unless available?
|
|
54
|
+
|
|
55
|
+
discover_models_from_registry(MODEL_PATTERN, "gemini")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Get firewall requirements for Gemini provider
|
|
59
|
+
def self.firewall_requirements
|
|
60
|
+
{
|
|
61
|
+
domains: [
|
|
62
|
+
"generativelanguage.googleapis.com",
|
|
63
|
+
"oauth2.googleapis.com",
|
|
64
|
+
"accounts.google.com",
|
|
65
|
+
"www.googleapis.com"
|
|
66
|
+
],
|
|
67
|
+
ip_ranges: []
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
15
71
|
def name
|
|
16
72
|
"gemini"
|
|
17
73
|
end
|
|
@@ -29,16 +85,9 @@ module Aidp
|
|
|
29
85
|
debug_provider("gemini", "Starting execution", {timeout: timeout_seconds})
|
|
30
86
|
debug_log("📝 Sending prompt to gemini...", level: :info)
|
|
31
87
|
|
|
32
|
-
# Check if streaming mode is enabled
|
|
33
|
-
streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
|
|
34
|
-
if streaming_enabled
|
|
35
|
-
display_message("📺 Display streaming enabled - output buffering reduced (gemini CLI does not support true streaming)", type: :info)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
88
|
begin
|
|
39
89
|
command_args = ["--prompt", prompt]
|
|
40
|
-
|
|
41
|
-
result = debug_execute_command("gemini", args: command_args, timeout: timeout_seconds, streaming: streaming_enabled)
|
|
90
|
+
result = debug_execute_command("gemini", args: command_args, timeout: timeout_seconds)
|
|
42
91
|
|
|
43
92
|
# Log the results
|
|
44
93
|
debug_command("gemini", args: command_args, input: nil, output: result.out, error: result.err, exit_code: result.exit_status)
|
|
@@ -56,58 +105,6 @@ module Aidp
|
|
|
56
105
|
end
|
|
57
106
|
|
|
58
107
|
private
|
|
59
|
-
|
|
60
|
-
def calculate_timeout
|
|
61
|
-
# Priority order for timeout calculation:
|
|
62
|
-
# 1. Quick mode (for testing)
|
|
63
|
-
# 2. Environment variable override
|
|
64
|
-
# 3. Adaptive timeout based on step type
|
|
65
|
-
# 4. Default timeout
|
|
66
|
-
|
|
67
|
-
if ENV["AIDP_QUICK_MODE"]
|
|
68
|
-
display_message("⚡ Quick mode enabled - #{TIMEOUT_QUICK_MODE / 60} minute timeout", type: :highlight)
|
|
69
|
-
return TIMEOUT_QUICK_MODE
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
if ENV["AIDP_GEMINI_TIMEOUT"]
|
|
73
|
-
return ENV["AIDP_GEMINI_TIMEOUT"].to_i
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Adaptive timeout based on step type
|
|
77
|
-
step_timeout = get_adaptive_timeout
|
|
78
|
-
if step_timeout
|
|
79
|
-
display_message("🧠 Using adaptive timeout: #{step_timeout} seconds", type: :info)
|
|
80
|
-
return step_timeout
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Default timeout
|
|
84
|
-
display_message("📋 Using default timeout: #{TIMEOUT_DEFAULT / 60} minutes", type: :info)
|
|
85
|
-
TIMEOUT_DEFAULT
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def get_adaptive_timeout
|
|
89
|
-
# Timeout recommendations based on step type patterns
|
|
90
|
-
step_name = ENV["AIDP_CURRENT_STEP"] || ""
|
|
91
|
-
|
|
92
|
-
case step_name
|
|
93
|
-
when /REPOSITORY_ANALYSIS/
|
|
94
|
-
TIMEOUT_REPOSITORY_ANALYSIS
|
|
95
|
-
when /ARCHITECTURE_ANALYSIS/
|
|
96
|
-
TIMEOUT_ARCHITECTURE_ANALYSIS
|
|
97
|
-
when /TEST_ANALYSIS/
|
|
98
|
-
TIMEOUT_TEST_ANALYSIS
|
|
99
|
-
when /FUNCTIONALITY_ANALYSIS/
|
|
100
|
-
TIMEOUT_FUNCTIONALITY_ANALYSIS
|
|
101
|
-
when /DOCUMENTATION_ANALYSIS/
|
|
102
|
-
TIMEOUT_DOCUMENTATION_ANALYSIS
|
|
103
|
-
when /STATIC_ANALYSIS/
|
|
104
|
-
TIMEOUT_STATIC_ANALYSIS
|
|
105
|
-
when /REFACTORING_RECOMMENDATIONS/
|
|
106
|
-
TIMEOUT_REFACTORING_RECOMMENDATIONS
|
|
107
|
-
else
|
|
108
|
-
nil # Use default
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
108
|
end
|
|
112
109
|
end
|
|
113
110
|
end
|
|
@@ -14,6 +14,23 @@ module Aidp
|
|
|
14
14
|
!!Aidp::Util.which("copilot")
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
# Get firewall requirements for GitHub Copilot provider
|
|
18
|
+
def self.firewall_requirements
|
|
19
|
+
{
|
|
20
|
+
domains: [
|
|
21
|
+
"copilot-proxy.githubusercontent.com",
|
|
22
|
+
"api.githubcopilot.com",
|
|
23
|
+
"copilot-telemetry.githubusercontent.com",
|
|
24
|
+
"default.exp-tas.com",
|
|
25
|
+
"copilot-completions.githubusercontent.com",
|
|
26
|
+
"business.githubcopilot.com",
|
|
27
|
+
"enterprise.githubcopilot.com",
|
|
28
|
+
"individual.githubcopilot.com"
|
|
29
|
+
],
|
|
30
|
+
ip_ranges: []
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
|
|
17
34
|
def name
|
|
18
35
|
"github_copilot"
|
|
19
36
|
end
|
|
@@ -43,12 +60,6 @@ module Aidp
|
|
|
43
60
|
debug_provider("copilot", "Starting execution", {timeout: timeout_seconds})
|
|
44
61
|
debug_log("📝 Sending prompt to copilot (length: #{prompt.length})", level: :info)
|
|
45
62
|
|
|
46
|
-
# Check if streaming mode is enabled
|
|
47
|
-
streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
|
|
48
|
-
if streaming_enabled
|
|
49
|
-
display_message("📺 Display streaming enabled - output buffering reduced (copilot CLI does not support true streaming)", type: :info)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
63
|
# Set up activity monitoring
|
|
53
64
|
setup_activity_monitoring("copilot", method(:activity_callback))
|
|
54
65
|
record_activity("Starting copilot execution")
|
|
@@ -80,7 +91,7 @@ module Aidp
|
|
|
80
91
|
end
|
|
81
92
|
|
|
82
93
|
# Use debug_execute_command for better debugging (no input since prompt is in args)
|
|
83
|
-
result = debug_execute_command("copilot", args: args, timeout: timeout_seconds
|
|
94
|
+
result = debug_execute_command("copilot", args: args, timeout: timeout_seconds)
|
|
84
95
|
|
|
85
96
|
# Log the results
|
|
86
97
|
debug_command("copilot", args: args, input: prompt, output: result.out, error: result.err, exit_code: result.exit_status)
|
|
@@ -178,17 +189,11 @@ module Aidp
|
|
|
178
189
|
debug_provider("copilot", "Starting execution", {timeout: timeout_seconds, args: args})
|
|
179
190
|
debug_log("📝 Sending prompt to copilot with custom args", level: :info)
|
|
180
191
|
|
|
181
|
-
# Check if streaming mode is enabled
|
|
182
|
-
streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
|
|
183
|
-
if streaming_enabled
|
|
184
|
-
display_message("📺 Display streaming enabled - output buffering reduced (copilot CLI does not support true streaming)", type: :info)
|
|
185
|
-
end
|
|
186
|
-
|
|
187
192
|
setup_activity_monitoring("copilot", method(:activity_callback))
|
|
188
193
|
record_activity("Starting copilot execution with custom args")
|
|
189
194
|
|
|
190
195
|
begin
|
|
191
|
-
result = debug_execute_command("copilot", args: args, timeout: timeout_seconds
|
|
196
|
+
result = debug_execute_command("copilot", args: args, timeout: timeout_seconds)
|
|
192
197
|
debug_command("copilot", args: args, output: result.out, error: result.err, exit_code: result.exit_status)
|
|
193
198
|
|
|
194
199
|
if result.exit_status == 0
|
|
@@ -206,58 +211,6 @@ module Aidp
|
|
|
206
211
|
end
|
|
207
212
|
end
|
|
208
213
|
|
|
209
|
-
def calculate_timeout
|
|
210
|
-
# Priority order for timeout calculation:
|
|
211
|
-
# 1. Quick mode (for testing)
|
|
212
|
-
# 2. Environment variable override
|
|
213
|
-
# 3. Adaptive timeout based on step type
|
|
214
|
-
# 4. Default timeout
|
|
215
|
-
|
|
216
|
-
if ENV["AIDP_QUICK_MODE"]
|
|
217
|
-
display_message("⚡ Quick mode enabled - #{TIMEOUT_QUICK_MODE / 60} minute timeout", type: :highlight)
|
|
218
|
-
return TIMEOUT_QUICK_MODE
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
if ENV["AIDP_GITHUB_COPILOT_TIMEOUT"]
|
|
222
|
-
return ENV["AIDP_GITHUB_COPILOT_TIMEOUT"].to_i
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
if adaptive_timeout
|
|
226
|
-
display_message("🧠 Using adaptive timeout: #{adaptive_timeout} seconds", type: :info)
|
|
227
|
-
return adaptive_timeout
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
# Default timeout
|
|
231
|
-
display_message("📋 Using default timeout: #{TIMEOUT_DEFAULT / 60} minutes", type: :info)
|
|
232
|
-
TIMEOUT_DEFAULT
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def adaptive_timeout
|
|
236
|
-
@adaptive_timeout ||= begin
|
|
237
|
-
# Timeout recommendations based on step type patterns
|
|
238
|
-
step_name = ENV["AIDP_CURRENT_STEP"] || ""
|
|
239
|
-
|
|
240
|
-
case step_name
|
|
241
|
-
when /REPOSITORY_ANALYSIS/
|
|
242
|
-
TIMEOUT_REPOSITORY_ANALYSIS
|
|
243
|
-
when /ARCHITECTURE_ANALYSIS/
|
|
244
|
-
TIMEOUT_ARCHITECTURE_ANALYSIS
|
|
245
|
-
when /TEST_ANALYSIS/
|
|
246
|
-
TIMEOUT_TEST_ANALYSIS
|
|
247
|
-
when /FUNCTIONALITY_ANALYSIS/
|
|
248
|
-
TIMEOUT_FUNCTIONALITY_ANALYSIS
|
|
249
|
-
when /DOCUMENTATION_ANALYSIS/
|
|
250
|
-
TIMEOUT_DOCUMENTATION_ANALYSIS
|
|
251
|
-
when /STATIC_ANALYSIS/
|
|
252
|
-
TIMEOUT_STATIC_ANALYSIS
|
|
253
|
-
when /REFACTORING_RECOMMENDATIONS/
|
|
254
|
-
TIMEOUT_REFACTORING_RECOMMENDATIONS
|
|
255
|
-
else
|
|
256
|
-
nil # Use default
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
end
|
|
260
|
-
|
|
261
214
|
def activity_callback(state, message, provider)
|
|
262
215
|
# Handle activity state changes
|
|
263
216
|
case state
|
|
@@ -10,10 +10,44 @@ module Aidp
|
|
|
10
10
|
class Kilocode < Base
|
|
11
11
|
include Aidp::DebugMixin
|
|
12
12
|
|
|
13
|
+
# Model name pattern for OpenAI models (since Kilocode uses OpenAI)
|
|
14
|
+
MODEL_PATTERN = /^gpt-[\d.o-]+(?:-turbo)?(?:-mini)?$/i
|
|
15
|
+
|
|
13
16
|
def self.available?
|
|
14
17
|
!!Aidp::Util.which("kilocode")
|
|
15
18
|
end
|
|
16
19
|
|
|
20
|
+
# Check if this provider supports a given model family
|
|
21
|
+
#
|
|
22
|
+
# @param family_name [String] The model family name
|
|
23
|
+
# @return [Boolean] True if it matches OpenAI model pattern
|
|
24
|
+
def self.supports_model_family?(family_name)
|
|
25
|
+
MODEL_PATTERN.match?(family_name)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Discover available models from registry
|
|
29
|
+
#
|
|
30
|
+
# Note: Kilocode CLI doesn't have a standard model listing command
|
|
31
|
+
# Returns registry-based models that match OpenAI patterns
|
|
32
|
+
#
|
|
33
|
+
# @return [Array<Hash>] Array of discovered models
|
|
34
|
+
def self.discover_models
|
|
35
|
+
return [] unless available?
|
|
36
|
+
|
|
37
|
+
discover_models_from_registry(MODEL_PATTERN, "kilocode")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Get firewall requirements for Kilocode provider
|
|
41
|
+
def self.firewall_requirements
|
|
42
|
+
{
|
|
43
|
+
domains: [
|
|
44
|
+
"kilocode.ai",
|
|
45
|
+
"api.kilocode.ai"
|
|
46
|
+
],
|
|
47
|
+
ip_ranges: []
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
17
51
|
def name
|
|
18
52
|
"kilocode"
|
|
19
53
|
end
|
|
@@ -31,12 +65,6 @@ module Aidp
|
|
|
31
65
|
debug_provider("kilocode", "Starting execution", {timeout: timeout_seconds})
|
|
32
66
|
debug_log("📝 Sending prompt to kilocode (length: #{prompt.length})", level: :info)
|
|
33
67
|
|
|
34
|
-
# Check if streaming mode is enabled
|
|
35
|
-
streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
|
|
36
|
-
if streaming_enabled
|
|
37
|
-
display_message("📺 Display streaming enabled - output buffering reduced", type: :info)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
68
|
# Check if prompt is too large and warn
|
|
41
69
|
if prompt.length > 3000
|
|
42
70
|
debug_log("⚠️ Large prompt detected (#{prompt.length} chars) - this may cause rate limiting", level: :warn)
|
|
@@ -85,7 +113,7 @@ module Aidp
|
|
|
85
113
|
end
|
|
86
114
|
|
|
87
115
|
# Use debug_execute_command for better debugging
|
|
88
|
-
result = debug_execute_command("kilocode", args: args, input: prompt, timeout: timeout_seconds,
|
|
116
|
+
result = debug_execute_command("kilocode", args: args, input: prompt, timeout: timeout_seconds, env: env_vars)
|
|
89
117
|
|
|
90
118
|
# Log the results
|
|
91
119
|
debug_command("kilocode", args: args, input: prompt, output: result.out, error: result.err, exit_code: result.exit_status)
|
|
@@ -112,58 +140,6 @@ module Aidp
|
|
|
112
140
|
|
|
113
141
|
private
|
|
114
142
|
|
|
115
|
-
def calculate_timeout
|
|
116
|
-
# Priority order for timeout calculation:
|
|
117
|
-
# 1. Quick mode (for testing)
|
|
118
|
-
# 2. Environment variable override
|
|
119
|
-
# 3. Adaptive timeout based on step type
|
|
120
|
-
# 4. Default timeout
|
|
121
|
-
|
|
122
|
-
if ENV["AIDP_QUICK_MODE"]
|
|
123
|
-
display_message("⚡ Quick mode enabled - #{TIMEOUT_QUICK_MODE / 60} minute timeout", type: :highlight)
|
|
124
|
-
return TIMEOUT_QUICK_MODE
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
if ENV["AIDP_KILOCODE_TIMEOUT"]
|
|
128
|
-
return ENV["AIDP_KILOCODE_TIMEOUT"].to_i
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
if adaptive_timeout
|
|
132
|
-
display_message("🧠 Using adaptive timeout: #{adaptive_timeout} seconds", type: :info)
|
|
133
|
-
return adaptive_timeout
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Default timeout
|
|
137
|
-
display_message("📋 Using default timeout: #{TIMEOUT_DEFAULT / 60} minutes", type: :info)
|
|
138
|
-
TIMEOUT_DEFAULT
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def adaptive_timeout
|
|
142
|
-
@adaptive_timeout ||= begin
|
|
143
|
-
# Timeout recommendations based on step type patterns
|
|
144
|
-
step_name = ENV["AIDP_CURRENT_STEP"] || ""
|
|
145
|
-
|
|
146
|
-
case step_name
|
|
147
|
-
when /REPOSITORY_ANALYSIS/
|
|
148
|
-
TIMEOUT_REPOSITORY_ANALYSIS
|
|
149
|
-
when /ARCHITECTURE_ANALYSIS/
|
|
150
|
-
TIMEOUT_ARCHITECTURE_ANALYSIS
|
|
151
|
-
when /TEST_ANALYSIS/
|
|
152
|
-
TIMEOUT_TEST_ANALYSIS
|
|
153
|
-
when /FUNCTIONALITY_ANALYSIS/
|
|
154
|
-
TIMEOUT_FUNCTIONALITY_ANALYSIS
|
|
155
|
-
when /DOCUMENTATION_ANALYSIS/
|
|
156
|
-
TIMEOUT_DOCUMENTATION_ANALYSIS
|
|
157
|
-
when /STATIC_ANALYSIS/
|
|
158
|
-
TIMEOUT_STATIC_ANALYSIS
|
|
159
|
-
when /REFACTORING_RECOMMENDATIONS/
|
|
160
|
-
TIMEOUT_REFACTORING_RECOMMENDATIONS
|
|
161
|
-
else
|
|
162
|
-
nil # Use default
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
143
|
def activity_callback(state, message, provider)
|
|
168
144
|
# This is now handled by the animated display thread
|
|
169
145
|
# Only print static messages for state changes
|
|
@@ -176,27 +152,6 @@ module Aidp
|
|
|
176
152
|
display_message("❌ kilocode execution failed: #{message}", type: :error)
|
|
177
153
|
end
|
|
178
154
|
end
|
|
179
|
-
|
|
180
|
-
def setup_activity_monitoring(provider_name, callback)
|
|
181
|
-
@activity_callback = callback
|
|
182
|
-
@activity_state = :starting
|
|
183
|
-
@activity_start_time = Time.now
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def record_activity(message)
|
|
187
|
-
@activity_state = :running
|
|
188
|
-
@activity_callback&.call(:running, message, "kilocode")
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def mark_completed
|
|
192
|
-
@activity_state = :completed
|
|
193
|
-
@activity_callback&.call(:completed, "Execution completed", "kilocode")
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def mark_failed(reason)
|
|
197
|
-
@activity_state = :failed
|
|
198
|
-
@activity_callback&.call(:failed, reason, "kilocode")
|
|
199
|
-
end
|
|
200
155
|
end
|
|
201
156
|
end
|
|
202
157
|
end
|
|
@@ -10,10 +10,44 @@ module Aidp
|
|
|
10
10
|
class Opencode < Base
|
|
11
11
|
include Aidp::DebugMixin
|
|
12
12
|
|
|
13
|
+
# Model name pattern for OpenAI models (since OpenCode uses OpenAI)
|
|
14
|
+
MODEL_PATTERN = /^gpt-[\d.o-]+(?:-turbo)?(?:-mini)?$/i
|
|
15
|
+
|
|
13
16
|
def self.available?
|
|
14
17
|
!!Aidp::Util.which("opencode")
|
|
15
18
|
end
|
|
16
19
|
|
|
20
|
+
# Check if this provider supports a given model family
|
|
21
|
+
#
|
|
22
|
+
# @param family_name [String] The model family name
|
|
23
|
+
# @return [Boolean] True if it matches OpenAI model pattern
|
|
24
|
+
def self.supports_model_family?(family_name)
|
|
25
|
+
MODEL_PATTERN.match?(family_name)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Discover available models from registry
|
|
29
|
+
#
|
|
30
|
+
# Note: OpenCode CLI doesn't have a standard model listing command
|
|
31
|
+
# Returns registry-based models that match OpenAI patterns
|
|
32
|
+
#
|
|
33
|
+
# @return [Array<Hash>] Array of discovered models
|
|
34
|
+
def self.discover_models
|
|
35
|
+
return [] unless available?
|
|
36
|
+
|
|
37
|
+
discover_models_from_registry(MODEL_PATTERN, "opencode")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Get firewall requirements for OpenCode provider
|
|
41
|
+
def self.firewall_requirements
|
|
42
|
+
{
|
|
43
|
+
domains: [
|
|
44
|
+
"api.opencode.ai",
|
|
45
|
+
"auth.opencode.ai"
|
|
46
|
+
],
|
|
47
|
+
ip_ranges: []
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
17
51
|
def name
|
|
18
52
|
"opencode"
|
|
19
53
|
end
|
|
@@ -31,12 +65,6 @@ module Aidp
|
|
|
31
65
|
debug_provider("opencode", "Starting execution", {timeout: timeout_seconds})
|
|
32
66
|
debug_log("📝 Sending prompt to opencode (length: #{prompt.length})", level: :info)
|
|
33
67
|
|
|
34
|
-
# Check if streaming mode is enabled
|
|
35
|
-
streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
|
|
36
|
-
if streaming_enabled
|
|
37
|
-
display_message("📺 Display streaming enabled - output buffering reduced (opencode does not support true streaming)", type: :info)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
68
|
# Check if prompt is too large and warn
|
|
41
69
|
if prompt.length > 3000
|
|
42
70
|
debug_log("⚠️ Large prompt detected (#{prompt.length} chars) - this may cause rate limiting", level: :warn)
|
|
@@ -67,7 +95,7 @@ module Aidp
|
|
|
67
95
|
# Use debug_execute_command for better debugging
|
|
68
96
|
# opencode run command with prompt and model
|
|
69
97
|
model = ENV["OPENCODE_MODEL"] || "github-copilot/claude-3.5-sonnet"
|
|
70
|
-
result = debug_execute_command("opencode", args: ["run", "-m", model, prompt], timeout: timeout_seconds
|
|
98
|
+
result = debug_execute_command("opencode", args: ["run", "-m", model, prompt], timeout: timeout_seconds)
|
|
71
99
|
|
|
72
100
|
# Log the results
|
|
73
101
|
debug_command("opencode", args: ["run", "-m", model, prompt], input: nil, output: result.out, error: result.err, exit_code: result.exit_status)
|
|
@@ -94,58 +122,6 @@ module Aidp
|
|
|
94
122
|
|
|
95
123
|
private
|
|
96
124
|
|
|
97
|
-
def calculate_timeout
|
|
98
|
-
# Priority order for timeout calculation:
|
|
99
|
-
# 1. Quick mode (for testing)
|
|
100
|
-
# 2. Environment variable override
|
|
101
|
-
# 3. Adaptive timeout based on step type
|
|
102
|
-
# 4. Default timeout
|
|
103
|
-
|
|
104
|
-
if ENV["AIDP_QUICK_MODE"]
|
|
105
|
-
display_message("⚡ Quick mode enabled - #{TIMEOUT_QUICK_MODE / 60} minute timeout", type: :highlight)
|
|
106
|
-
return TIMEOUT_QUICK_MODE
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
if ENV["AIDP_OPENCODE_TIMEOUT"]
|
|
110
|
-
return ENV["AIDP_OPENCODE_TIMEOUT"].to_i
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
if adaptive_timeout
|
|
114
|
-
display_message("🧠 Using adaptive timeout: #{adaptive_timeout} seconds", type: :info)
|
|
115
|
-
return adaptive_timeout
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Default timeout
|
|
119
|
-
display_message("📋 Using default timeout: #{TIMEOUT_DEFAULT / 60} minutes", type: :info)
|
|
120
|
-
TIMEOUT_DEFAULT
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def adaptive_timeout
|
|
124
|
-
@adaptive_timeout ||= begin
|
|
125
|
-
# Timeout recommendations based on step type patterns
|
|
126
|
-
step_name = ENV["AIDP_CURRENT_STEP"] || ""
|
|
127
|
-
|
|
128
|
-
case step_name
|
|
129
|
-
when /REPOSITORY_ANALYSIS/
|
|
130
|
-
TIMEOUT_REPOSITORY_ANALYSIS
|
|
131
|
-
when /ARCHITECTURE_ANALYSIS/
|
|
132
|
-
TIMEOUT_ARCHITECTURE_ANALYSIS
|
|
133
|
-
when /TEST_ANALYSIS/
|
|
134
|
-
TIMEOUT_TEST_ANALYSIS
|
|
135
|
-
when /FUNCTIONALITY_ANALYSIS/
|
|
136
|
-
TIMEOUT_FUNCTIONALITY_ANALYSIS
|
|
137
|
-
when /DOCUMENTATION_ANALYSIS/
|
|
138
|
-
TIMEOUT_DOCUMENTATION_ANALYSIS
|
|
139
|
-
when /STATIC_ANALYSIS/
|
|
140
|
-
TIMEOUT_STATIC_ANALYSIS
|
|
141
|
-
when /REFACTORING_RECOMMENDATIONS/
|
|
142
|
-
TIMEOUT_REFACTORING_RECOMMENDATIONS
|
|
143
|
-
else
|
|
144
|
-
nil # Use default
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
125
|
def activity_callback(state, message, provider)
|
|
150
126
|
# This is now handled by the animated display thread
|
|
151
127
|
# Only print static messages for state changes
|
|
@@ -158,27 +134,6 @@ module Aidp
|
|
|
158
134
|
display_message("❌ opencode execution failed: #{message}", type: :error)
|
|
159
135
|
end
|
|
160
136
|
end
|
|
161
|
-
|
|
162
|
-
def setup_activity_monitoring(provider_name, callback)
|
|
163
|
-
@activity_callback = callback
|
|
164
|
-
@activity_state = :starting
|
|
165
|
-
@activity_start_time = Time.now
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def record_activity(message)
|
|
169
|
-
@activity_state = :running
|
|
170
|
-
@activity_callback&.call(:running, message, "opencode")
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def mark_completed
|
|
174
|
-
@activity_state = :completed
|
|
175
|
-
@activity_callback&.call(:completed, "Execution completed", "opencode")
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def mark_failed(reason)
|
|
179
|
-
@activity_state = :failed
|
|
180
|
-
@activity_callback&.call(:failed, reason, "opencode")
|
|
181
|
-
end
|
|
182
137
|
end
|
|
183
138
|
end
|
|
184
139
|
end
|