aidp 0.34.1 → 0.39.3
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 +14 -14
- data/lib/aidp/agent_harness_adapter.rb +309 -0
- data/lib/aidp/cli/issue_importer.rb +20 -6
- data/lib/aidp/cli/jobs_command.rb +1 -1
- data/lib/aidp/cli/models_command.rb +9 -16
- data/lib/aidp/cli/prompts_command.rb +253 -0
- data/lib/aidp/cli/security_command.rb +4 -10
- data/lib/aidp/cli/storage_command.rb +277 -0
- data/lib/aidp/cli/temporal_command.rb +460 -0
- data/lib/aidp/cli.rb +24 -2
- data/lib/aidp/config.rb +15 -0
- data/lib/aidp/config_paths.rb +12 -2
- data/lib/aidp/database/migrations.rb +114 -0
- data/lib/aidp/database/repositories/checkpoint_repository.rb +174 -0
- data/lib/aidp/database/repositories/deprecated_models_repository.rb +206 -0
- data/lib/aidp/database/repositories/evaluation_repository.rb +208 -0
- data/lib/aidp/database/repositories/harness_state_repository.rb +140 -0
- data/lib/aidp/database/repositories/job_repository.rb +278 -0
- data/lib/aidp/database/repositories/model_cache_repository.rb +194 -0
- data/lib/aidp/database/repositories/progress_repository.rb +210 -0
- data/lib/aidp/database/repositories/prompt_archive_repository.rb +195 -0
- data/lib/aidp/database/repositories/prompt_feedback_repository.rb +266 -0
- data/lib/aidp/database/repositories/provider_info_cache_repository.rb +208 -0
- data/lib/aidp/database/repositories/provider_metrics_repository.rb +245 -0
- data/lib/aidp/database/repositories/secrets_repository.rb +187 -0
- data/lib/aidp/database/repositories/task_repository.rb +231 -0
- data/lib/aidp/database/repositories/template_version_repository.rb +383 -0
- data/lib/aidp/database/repositories/watch_state_repository.rb +472 -0
- data/lib/aidp/database/repositories/workstream_repository.rb +310 -0
- data/lib/aidp/database/repositories/worktree_repository.rb +240 -0
- data/lib/aidp/database/repository.rb +166 -0
- data/lib/aidp/database/schema.rb +347 -0
- data/lib/aidp/database/storage_migrator.rb +693 -0
- data/lib/aidp/database.rb +139 -0
- data/lib/aidp/debug_mixin.rb +2 -2
- data/lib/aidp/execute/checkpoint.rb +26 -0
- data/lib/aidp/execute/checkpoint_display.rb +16 -0
- data/lib/aidp/execute/prompt_evaluator.rb +30 -57
- data/lib/aidp/execute/work_loop_runner.rb +294 -46
- data/lib/aidp/firewall/provider_requirements_collector.rb +7 -23
- data/lib/aidp/harness/agent_harness_provider_manager.rb +275 -0
- data/lib/aidp/harness/ai_decision_engine.rb +78 -296
- data/lib/aidp/harness/config_schema.rb +59 -0
- data/lib/aidp/harness/configuration.rb +229 -10
- data/lib/aidp/harness/deprecation_cache.rb +53 -11
- data/lib/aidp/harness/enhanced_runner.rb +1 -1
- data/lib/aidp/harness/error_handler.rb +11 -5
- data/lib/aidp/harness/provider_config.rb +36 -0
- data/lib/aidp/harness/provider_factory.rb +26 -24
- data/lib/aidp/harness/provider_info.rb +9 -5
- data/lib/aidp/harness/provider_manager.rb +2 -2
- data/lib/aidp/harness/provider_metrics.rb +103 -1
- data/lib/aidp/harness/rspec_command_optimizer.rb +166 -0
- data/lib/aidp/harness/ruby_llm_registry.rb +97 -8
- data/lib/aidp/harness/runner.rb +7 -2
- data/lib/aidp/harness/state_manager.rb +1 -1
- data/lib/aidp/harness/test_runner.rb +167 -11
- data/lib/aidp/harness/thinking_depth_manager.rb +564 -5
- data/lib/aidp/harness/usage_limit.rb +179 -0
- data/lib/aidp/harness/usage_limit_enforcer.rb +240 -0
- data/lib/aidp/harness/usage_limit_tracker.rb +308 -0
- data/lib/aidp/harness/usage_period.rb +234 -0
- data/lib/aidp/init/agent_instructions_generator.rb +317 -0
- data/lib/aidp/init/runner.rb +25 -4
- data/lib/aidp/interfaces/activity_monitor_interface.rb +234 -0
- data/lib/aidp/interfaces/binary_checker_interface.rb +232 -0
- data/lib/aidp/interfaces/command_executor_interface.rb +216 -0
- data/lib/aidp/interfaces/logger_interface.rb +150 -0
- data/lib/aidp/interfaces/ui_interface.rb +254 -0
- data/lib/aidp/logger.rb +25 -7
- data/lib/aidp/orchestration_adapter.rb +279 -0
- data/lib/aidp/pr_worktree_manager.rb +4 -15
- data/lib/aidp/prompts/feedback_collector.rb +198 -0
- data/lib/aidp/prompts/prompt_template_manager.rb +415 -0
- data/lib/aidp/prompts/template_evolver.rb +305 -0
- data/lib/aidp/prompts/template_version_manager.rb +325 -0
- data/lib/aidp/setup/in_memory_config_adapter.rb +257 -0
- data/lib/aidp/setup/in_memory_config_manager.rb +262 -0
- data/lib/aidp/setup/wizard.rb +616 -176
- data/lib/aidp/shell_executor.rb +58 -0
- data/lib/aidp/style_guide/selector.rb +56 -1
- data/lib/aidp/temporal/activities/analyze_issue_activity.rb +198 -0
- data/lib/aidp/temporal/activities/analyze_sub_task_activity.rb +163 -0
- data/lib/aidp/temporal/activities/base_activity.rb +78 -0
- data/lib/aidp/temporal/activities/create_plan_activity.rb +115 -0
- data/lib/aidp/temporal/activities/create_pr_activity.rb +193 -0
- data/lib/aidp/temporal/activities/create_prompt_activity.rb +118 -0
- data/lib/aidp/temporal/activities/diagnose_failure_activity.rb +228 -0
- data/lib/aidp/temporal/activities/prepare_next_iteration_activity.rb +147 -0
- data/lib/aidp/temporal/activities/record_checkpoint_activity.rb +81 -0
- data/lib/aidp/temporal/activities/run_agent_activity.rb +139 -0
- data/lib/aidp/temporal/activities/run_tests_activity.rb +114 -0
- data/lib/aidp/temporal/activities/run_work_loop_iteration_activity.rb +249 -0
- data/lib/aidp/temporal/configuration.rb +169 -0
- data/lib/aidp/temporal/connection.rb +93 -0
- data/lib/aidp/temporal/worker.rb +119 -0
- data/lib/aidp/temporal/workflow_client.rb +171 -0
- data/lib/aidp/temporal/workflows/base_workflow.rb +73 -0
- data/lib/aidp/temporal/workflows/issue_to_pr_workflow.rb +278 -0
- data/lib/aidp/temporal/workflows/sub_issue_workflow.rb +253 -0
- data/lib/aidp/temporal/workflows/work_loop_workflow.rb +321 -0
- data/lib/aidp/temporal.rb +120 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/base_processor.rb +35 -0
- data/lib/aidp/watch/build_processor.rb +132 -0
- data/lib/aidp/watch/github_state_extractor.rb +0 -8
- data/lib/aidp/watch/rebase_processor.rb +245 -0
- data/lib/aidp/watch/round_robin_scheduler.rb +150 -0
- data/lib/aidp/watch/runner.rb +366 -285
- data/lib/aidp/watch/state_store.rb +80 -0
- data/lib/aidp/watch/work_item.rb +96 -0
- data/lib/aidp/watch/worktree_cleanup_job.rb +226 -0
- data/lib/aidp/watch/worktree_reconciler.rb +643 -0
- data/lib/aidp/workflows/guided_agent.rb +1 -1
- data/lib/aidp/worktree.rb +62 -0
- data/templates/aidp.yml.example +70 -0
- metadata +117 -16
- data/lib/aidp/analyze/json_file_storage.rb +0 -292
- data/lib/aidp/execute/future_work_backlog.rb +0 -411
- data/lib/aidp/providers/adapter.rb +0 -239
- data/lib/aidp/providers/aider.rb +0 -264
- data/lib/aidp/providers/anthropic.rb +0 -614
- data/lib/aidp/providers/base.rb +0 -617
- data/lib/aidp/providers/capability_registry.rb +0 -204
- data/lib/aidp/providers/codex.rb +0 -267
- data/lib/aidp/providers/cursor.rb +0 -304
- data/lib/aidp/providers/error_taxonomy.rb +0 -195
- data/lib/aidp/providers/gemini.rb +0 -110
- data/lib/aidp/providers/github_copilot.rb +0 -227
- data/lib/aidp/providers/kilocode.rb +0 -157
- data/lib/aidp/providers/opencode.rb +0 -139
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8cd5163981904da173cfeb433c9d866ac8d138f7020701255d6db3e9b024d9c1
|
|
4
|
+
data.tar.gz: 414b329a3d385dd31a7822af2cb793a974f0ef8e9d231095037c0733fa054c9c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2c0c3826a863f357658f9ff9a6aff38404d9939d6ece54c994b0d658bde2b8025e506f4d6964d61fc37f20f97d3bb6c30a3cb58a65ee01e437d23c93d26d53c2
|
|
7
|
+
data.tar.gz: b1fcd507b193d0f7748790f4e22604e6c5fe4d7b29f9df50221eb4850288337600ac607e057f203661b1167c966982ca09a1e97a01a216357c1b0ae46867867b
|
data/README.md
CHANGED
|
@@ -116,7 +116,7 @@ aidp devcontainer list-backups
|
|
|
116
116
|
aidp devcontainer restore 0
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
See [docs/DEVELOPMENT_CONTAINER.md](docs/DEVELOPMENT_CONTAINER.md) for complete devcontainer management documentation.
|
|
119
|
+
See [docs/how-to/DEVELOPMENT_CONTAINER.md](docs/how-to/DEVELOPMENT_CONTAINER.md) for complete devcontainer management documentation.
|
|
120
120
|
|
|
121
121
|
### Devcontainer Detection
|
|
122
122
|
|
|
@@ -133,7 +133,7 @@ AIDP implements **work loops** - an iterative execution pattern where AI agents
|
|
|
133
133
|
- **Automatic validation**: Tests and linters run after each iteration
|
|
134
134
|
- **Self-correction**: Only failures are fed back for the next iteration
|
|
135
135
|
|
|
136
|
-
See [Work Loops Guide](docs/WORK_LOOPS_GUIDE.md) for details.
|
|
136
|
+
See [Work Loops Guide](docs/how-to/WORK_LOOPS_GUIDE.md) for details.
|
|
137
137
|
|
|
138
138
|
### Waterfall Planning Mode
|
|
139
139
|
|
|
@@ -167,7 +167,7 @@ aidp execute
|
|
|
167
167
|
- **Mermaid Visualizations** - Gantt charts renderable on GitHub/GitLab
|
|
168
168
|
- **TDD Integration** - Optional test-driven development workflow
|
|
169
169
|
|
|
170
|
-
See [Waterfall Planning Mode Guide](docs/WATERFALL_PLANNING_MODE.md) for complete documentation.
|
|
170
|
+
See [Waterfall Planning Mode Guide](docs/how-to/WATERFALL_PLANNING_MODE.md) for complete documentation.
|
|
171
171
|
|
|
172
172
|
### Agile Development Mode
|
|
173
173
|
|
|
@@ -222,7 +222,7 @@ Analyze existing codebase and create user research plan:
|
|
|
222
222
|
- **Marketing Focus** - Translate features into customer value
|
|
223
223
|
- **Three New Personas** - Product Manager, UX Researcher, Marketing Strategist
|
|
224
224
|
|
|
225
|
-
See [Agile Development Mode Guide](docs/AGILE_MODE_GUIDE.md) for complete documentation.
|
|
225
|
+
See [Agile Development Mode Guide](docs/how-to/AGILE_MODE_GUIDE.md) for complete documentation.
|
|
226
226
|
|
|
227
227
|
### GitHub Projects V2 Integration
|
|
228
228
|
|
|
@@ -257,7 +257,7 @@ main
|
|
|
257
257
|
└── aidp/sub-123-126-component-c
|
|
258
258
|
```
|
|
259
259
|
|
|
260
|
-
See [GitHub Projects Guide](docs/GITHUB_PROJECTS.md) for complete documentation.
|
|
260
|
+
See [GitHub Projects Guide](docs/how-to/GITHUB_PROJECTS.md) for complete documentation.
|
|
261
261
|
|
|
262
262
|
### Job Management
|
|
263
263
|
|
|
@@ -323,7 +323,7 @@ aidp ws rm issue-123-fix-auth --delete-branch
|
|
|
323
323
|
- Independent state and history
|
|
324
324
|
- Work on multiple features in parallel
|
|
325
325
|
|
|
326
|
-
See [Workstreams Guide](docs/WORKSTREAMS.md) for detailed usage.
|
|
326
|
+
See [Workstreams Guide](docs/how-to/WORKSTREAMS.md) for detailed usage.
|
|
327
327
|
|
|
328
328
|
### Watch Mode (Automated GitHub Integration)
|
|
329
329
|
|
|
@@ -454,10 +454,10 @@ This ensures AIDP never gets stuck - if it needs more information, it will ask f
|
|
|
454
454
|
|
|
455
455
|
**Additional Documentation:**
|
|
456
456
|
|
|
457
|
-
- [Watch Mode Guide](docs/FULLY_AUTOMATIC_MODE.md) - Complete guide to watch mode setup and operation
|
|
458
|
-
- [Watch Mode Safety](docs/WATCH_MODE_SAFETY.md) - Security features and best practices
|
|
459
|
-
- [PR Automation Guide](docs/PR_AUTOMATION.md) - Detailed guide for code review, CI fixes, and PR changes
|
|
460
|
-
- [PR Change Requests](docs/PR_CHANGE_REQUESTS.md) - Comprehensive documentation for automated PR modifications
|
|
457
|
+
- [Watch Mode Guide](docs/how-to/FULLY_AUTOMATIC_MODE.md) - Complete guide to watch mode setup and operation
|
|
458
|
+
- [Watch Mode Safety](docs/explanation/WATCH_MODE_SAFETY.md) - Security features and best practices
|
|
459
|
+
- [PR Automation Guide](docs/how-to/PR_AUTOMATION.md) - Detailed guide for code review, CI fixes, and PR changes
|
|
460
|
+
- [PR Change Requests](docs/how-to/PR_CHANGE_REQUESTS.md) - Comprehensive documentation for automated PR modifications
|
|
461
461
|
|
|
462
462
|
## Command Reference
|
|
463
463
|
|
|
@@ -844,10 +844,10 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and conventional co
|
|
|
844
844
|
|
|
845
845
|
For detailed information:
|
|
846
846
|
|
|
847
|
-
- **[CLI User Guide](docs/CLI_USER_GUIDE.md)** - Complete guide to using AIDP commands
|
|
848
|
-
- **[Work Loops Guide](docs/WORK_LOOPS_GUIDE.md)** - Iterative workflows with automatic validation
|
|
849
|
-
- **[Configuration Guide](docs/
|
|
850
|
-
- **[
|
|
847
|
+
- **[CLI User Guide](docs/how-to/CLI_USER_GUIDE.md)** - Complete guide to using AIDP commands
|
|
848
|
+
- **[Work Loops Guide](docs/how-to/WORK_LOOPS_GUIDE.md)** - Iterative workflows with automatic validation
|
|
849
|
+
- **[Configuration Guide](docs/reference/CONFIGURATION.md)** - Detailed configuration options and examples
|
|
850
|
+
- **[Debug Guide](docs/how-to/DEBUG_GUIDE.md)** - Debugging and troubleshooting
|
|
851
851
|
|
|
852
852
|
## Manual Workflow (Alternative)
|
|
853
853
|
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "agent_harness"
|
|
4
|
+
|
|
5
|
+
module Aidp
|
|
6
|
+
# Wraps AIDP's logger to provide standard Ruby Logger interface
|
|
7
|
+
# for AgentHarness compatibility
|
|
8
|
+
class LoggerAdapter
|
|
9
|
+
def initialize(aidp_logger, component: "agent_harness")
|
|
10
|
+
@logger = aidp_logger
|
|
11
|
+
@component = component
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def debug(message = nil, &block)
|
|
15
|
+
msg = message || (block ? block.call : "")
|
|
16
|
+
@logger&.debug(@component, msg.to_s)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def info(message = nil, &block)
|
|
20
|
+
msg = message || (block ? block.call : "")
|
|
21
|
+
@logger&.info(@component, msg.to_s)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def warn(message = nil, &block)
|
|
25
|
+
msg = message || (block ? block.call : "")
|
|
26
|
+
@logger&.warn(@component, msg.to_s)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def error(message = nil, &block)
|
|
30
|
+
msg = message || (block ? block.call : "")
|
|
31
|
+
@logger&.error(@component, msg.to_s)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def fatal(message = nil, &block)
|
|
35
|
+
msg = message || (block ? block.call : "")
|
|
36
|
+
@logger&.error(@component, msg.to_s)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def level
|
|
40
|
+
:debug
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def level=(val)
|
|
44
|
+
# no-op
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Adapter for using the AgentHarness gem within AIDP
|
|
49
|
+
#
|
|
50
|
+
# This adapter bridges AIDP's existing provider interface with the
|
|
51
|
+
# new AgentHarness gem, allowing gradual migration.
|
|
52
|
+
#
|
|
53
|
+
# Usage:
|
|
54
|
+
# adapter = Aidp::AgentHarnessAdapter.new(config)
|
|
55
|
+
# response = adapter.send_message(prompt: "Hello", provider: :claude)
|
|
56
|
+
#
|
|
57
|
+
class AgentHarnessAdapter
|
|
58
|
+
attr_reader :conductor
|
|
59
|
+
|
|
60
|
+
# Create a new adapter
|
|
61
|
+
#
|
|
62
|
+
# @param aidp_config [Aidp::Config] AIDP configuration
|
|
63
|
+
# @param logger [Logger] logger instance
|
|
64
|
+
def initialize(aidp_config, logger: nil)
|
|
65
|
+
@aidp_config = aidp_config
|
|
66
|
+
@logger = logger || Aidp.logger
|
|
67
|
+
|
|
68
|
+
configure_agent_harness
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Send a message through AgentHarness
|
|
72
|
+
#
|
|
73
|
+
# @param prompt [String] the prompt to send
|
|
74
|
+
# @param provider [Symbol, nil] provider to use
|
|
75
|
+
# @param options [Hash] additional options
|
|
76
|
+
# @return [Hash] AIDP-compatible response
|
|
77
|
+
def send_message(prompt:, provider: nil, **options)
|
|
78
|
+
start_time = Time.now
|
|
79
|
+
|
|
80
|
+
# Map AIDP options to AgentHarness options
|
|
81
|
+
harness_options = map_options(options)
|
|
82
|
+
|
|
83
|
+
# Use the conductor for orchestrated requests
|
|
84
|
+
response = @conductor.send_message(prompt, provider: provider, **harness_options)
|
|
85
|
+
|
|
86
|
+
# Convert Response to AIDP-compatible hash
|
|
87
|
+
convert_response(response, Time.now - start_time)
|
|
88
|
+
rescue AgentHarness::RateLimitError => e
|
|
89
|
+
handle_rate_limit(e, provider)
|
|
90
|
+
rescue AgentHarness::NoProvidersAvailableError => e
|
|
91
|
+
handle_no_providers(e)
|
|
92
|
+
rescue AgentHarness::Error => e
|
|
93
|
+
handle_error(e, provider)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Get a specific provider instance
|
|
97
|
+
#
|
|
98
|
+
# @param name [Symbol] provider name
|
|
99
|
+
# @return [AgentHarness::Providers::Base] provider instance
|
|
100
|
+
def provider(name)
|
|
101
|
+
@conductor.provider_manager.get_provider(name)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Check if a provider is available
|
|
105
|
+
#
|
|
106
|
+
# @param name [Symbol] provider name
|
|
107
|
+
# @return [Boolean] true if available
|
|
108
|
+
def provider_available?(name)
|
|
109
|
+
provider_class = AgentHarness::Providers::Registry.instance.get(name)
|
|
110
|
+
provider_class.available?
|
|
111
|
+
rescue AgentHarness::ConfigurationError
|
|
112
|
+
false
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Get orchestration status
|
|
116
|
+
#
|
|
117
|
+
# @return [Hash] status information
|
|
118
|
+
def status
|
|
119
|
+
@conductor.status
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Get token usage summary
|
|
123
|
+
#
|
|
124
|
+
# @return [Hash] token usage
|
|
125
|
+
def token_summary
|
|
126
|
+
AgentHarness.token_tracker.summary
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Register callback for token events
|
|
130
|
+
#
|
|
131
|
+
# @yield [TokenEvent] token event
|
|
132
|
+
def on_tokens_used(&block)
|
|
133
|
+
AgentHarness.token_tracker.on_tokens_used(&block)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Reset the adapter (useful for testing)
|
|
137
|
+
def reset!
|
|
138
|
+
@conductor.reset!
|
|
139
|
+
AgentHarness.token_tracker.clear!
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
|
|
144
|
+
def configure_agent_harness
|
|
145
|
+
AgentHarness.configure do |config|
|
|
146
|
+
config.logger = LoggerAdapter.new(@logger)
|
|
147
|
+
config.log_level = begin
|
|
148
|
+
@aidp_config.log_level
|
|
149
|
+
rescue
|
|
150
|
+
:info
|
|
151
|
+
end
|
|
152
|
+
config.default_timeout = begin
|
|
153
|
+
@aidp_config.default_timeout
|
|
154
|
+
rescue
|
|
155
|
+
300
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Set default provider from AIDP config
|
|
159
|
+
config.default_provider = map_provider_name(@aidp_config.default_provider)
|
|
160
|
+
|
|
161
|
+
# Configure fallback providers
|
|
162
|
+
config.fallback_providers = (@aidp_config.fallback_providers || []).map { |p| map_provider_name(p) }
|
|
163
|
+
|
|
164
|
+
# Configure orchestration
|
|
165
|
+
config.orchestration do |orch|
|
|
166
|
+
orch.enabled = true
|
|
167
|
+
orch.auto_switch_on_error = true
|
|
168
|
+
orch.auto_switch_on_rate_limit = true
|
|
169
|
+
|
|
170
|
+
orch.circuit_breaker do |cb|
|
|
171
|
+
cb.enabled = true
|
|
172
|
+
cb.failure_threshold = 5
|
|
173
|
+
cb.timeout = 300
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
orch.retry do |r|
|
|
177
|
+
r.enabled = true
|
|
178
|
+
r.max_attempts = 3
|
|
179
|
+
r.base_delay = 1.0
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Configure providers from AIDP config
|
|
184
|
+
configure_providers(config)
|
|
185
|
+
|
|
186
|
+
# Register token usage callback
|
|
187
|
+
config.on_tokens_used do |event|
|
|
188
|
+
Aidp.log_debug("agent_harness_adapter", "token_usage",
|
|
189
|
+
provider: event.provider,
|
|
190
|
+
total_tokens: event.total_tokens)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Register provider switch callback
|
|
194
|
+
config.on_provider_switch do |event|
|
|
195
|
+
Aidp.log_info("agent_harness_adapter", "provider_switch",
|
|
196
|
+
from: event[:from],
|
|
197
|
+
to: event[:to],
|
|
198
|
+
reason: event[:reason])
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
@conductor = AgentHarness.conductor
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def configure_providers(config)
|
|
206
|
+
# Configure enabled providers from AIDP config
|
|
207
|
+
provider_configs = begin
|
|
208
|
+
@aidp_config.providers
|
|
209
|
+
rescue
|
|
210
|
+
{}
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
provider_configs.each do |name, provider_config|
|
|
214
|
+
harness_name = map_provider_name(name)
|
|
215
|
+
|
|
216
|
+
config.provider(harness_name) do |p|
|
|
217
|
+
p.enabled = provider_config[:enabled] != false
|
|
218
|
+
p.type = provider_config[:type]&.to_sym || :usage_based
|
|
219
|
+
p.priority = provider_config[:priority] || 10
|
|
220
|
+
p.timeout = provider_config[:timeout]
|
|
221
|
+
p.model = provider_config[:model]
|
|
222
|
+
p.models = provider_config[:models] || []
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Ensure default provider is configured
|
|
227
|
+
unless config.providers.key?(config.default_provider)
|
|
228
|
+
config.provider(config.default_provider) { |p| p.enabled = true }
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def map_provider_name(name)
|
|
233
|
+
case name.to_s
|
|
234
|
+
when "anthropic", "claude"
|
|
235
|
+
:claude
|
|
236
|
+
when "github_copilot", "copilot"
|
|
237
|
+
:github_copilot
|
|
238
|
+
else
|
|
239
|
+
name.to_sym
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def map_options(options)
|
|
244
|
+
harness_options = {}
|
|
245
|
+
|
|
246
|
+
harness_options[:model] = options[:model] if options[:model]
|
|
247
|
+
harness_options[:timeout] = options[:timeout] if options[:timeout]
|
|
248
|
+
harness_options[:session] = options[:session] if options[:session]
|
|
249
|
+
harness_options[:dangerous_mode] = options[:dangerous] if options[:dangerous]
|
|
250
|
+
harness_options[:tier] = options[:tier] if options[:tier]
|
|
251
|
+
|
|
252
|
+
harness_options
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def convert_response(response, duration)
|
|
256
|
+
{
|
|
257
|
+
output: response.output,
|
|
258
|
+
success: response.success?,
|
|
259
|
+
exit_code: response.exit_code,
|
|
260
|
+
provider: response.provider,
|
|
261
|
+
model: response.model,
|
|
262
|
+
duration: duration,
|
|
263
|
+
tokens: response.tokens,
|
|
264
|
+
error: response.error
|
|
265
|
+
}
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def handle_rate_limit(error, provider)
|
|
269
|
+
Aidp.log_warn("agent_harness_adapter", "rate_limited",
|
|
270
|
+
provider: provider,
|
|
271
|
+
reset_time: error.reset_time)
|
|
272
|
+
|
|
273
|
+
{
|
|
274
|
+
output: nil,
|
|
275
|
+
success: false,
|
|
276
|
+
error: error.message,
|
|
277
|
+
rate_limited: true,
|
|
278
|
+
reset_time: error.reset_time
|
|
279
|
+
}
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def handle_no_providers(error)
|
|
283
|
+
Aidp.log_error("agent_harness_adapter", "no_providers_available",
|
|
284
|
+
attempted: error.attempted_providers)
|
|
285
|
+
|
|
286
|
+
{
|
|
287
|
+
output: nil,
|
|
288
|
+
success: false,
|
|
289
|
+
error: error.message,
|
|
290
|
+
no_providers: true,
|
|
291
|
+
attempted_providers: error.attempted_providers
|
|
292
|
+
}
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def handle_error(error, provider)
|
|
296
|
+
Aidp.log_error("agent_harness_adapter", "provider_error",
|
|
297
|
+
provider: provider,
|
|
298
|
+
error: error.class.name,
|
|
299
|
+
message: error.message)
|
|
300
|
+
|
|
301
|
+
{
|
|
302
|
+
output: nil,
|
|
303
|
+
success: false,
|
|
304
|
+
error: error.message,
|
|
305
|
+
provider: provider
|
|
306
|
+
}
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
end
|
|
@@ -19,7 +19,8 @@ module Aidp
|
|
|
19
19
|
# @param gh_available [Boolean, nil] (test-only) forcibly sets whether gh CLI is considered
|
|
20
20
|
# available. When nil (default) we auto-detect. This enables deterministic specs without
|
|
21
21
|
# depending on developer environment.
|
|
22
|
-
|
|
22
|
+
# @param project_dir [String] (optional) working directory for the project. Defaults to current directory.
|
|
23
|
+
def initialize(gh_available: nil, enable_bootstrap: true, project_dir: nil)
|
|
23
24
|
disabled_via_env = ENV["AIDP_DISABLE_GH_CLI"] == "1"
|
|
24
25
|
@gh_available = if disabled_via_env
|
|
25
26
|
false
|
|
@@ -27,6 +28,7 @@ module Aidp
|
|
|
27
28
|
gh_available.nil? ? gh_cli_available? : gh_available
|
|
28
29
|
end
|
|
29
30
|
@enable_bootstrap = enable_bootstrap
|
|
31
|
+
@project_dir_override = project_dir
|
|
30
32
|
Aidp.log_debug(COMPONENT, "Initialized importer", gh_available: @gh_available, enable_bootstrap: @enable_bootstrap, disabled_via_env: disabled_via_env)
|
|
31
33
|
Aidp.log_debug(COMPONENT, "GitHub CLI disabled via env flag") if disabled_via_env
|
|
32
34
|
end
|
|
@@ -244,7 +246,7 @@ module Aidp
|
|
|
244
246
|
prompt_content = generate_prompt_content(issue_data)
|
|
245
247
|
|
|
246
248
|
# Use PromptManager to write to .aidp/PROMPT.md and archive immediately
|
|
247
|
-
prompt_manager = Aidp::Execute::PromptManager.new(
|
|
249
|
+
prompt_manager = Aidp::Execute::PromptManager.new(project_dir)
|
|
248
250
|
step_name = "github_issue_#{issue_data[:number]}"
|
|
249
251
|
prompt_manager.write(prompt_content, step_name: step_name)
|
|
250
252
|
|
|
@@ -261,9 +263,9 @@ module Aidp
|
|
|
261
263
|
|
|
262
264
|
## Instructions
|
|
263
265
|
You are working on a GitHub issue imported into AIDP. Your responsibilities:
|
|
264
|
-
1. Read this PROMPT.md
|
|
266
|
+
1. Read this file (`.aidp/PROMPT.md`) to understand what needs to be done
|
|
265
267
|
2. Complete the work described in the issue below
|
|
266
|
-
3. **IMPORTANT**: Edit this PROMPT.md file
|
|
268
|
+
3. **IMPORTANT**: Edit this `.aidp/PROMPT.md` file to:
|
|
267
269
|
- Remove completed items
|
|
268
270
|
- Update with current status
|
|
269
271
|
- Keep it concise (remove unnecessary context)
|
|
@@ -272,7 +274,7 @@ module Aidp
|
|
|
272
274
|
5. If tests/linters fail, you'll see the errors in the next iteration
|
|
273
275
|
|
|
274
276
|
## Completion Criteria
|
|
275
|
-
Mark this issue COMPLETE by adding this line to PROMPT.md
|
|
277
|
+
Mark this issue COMPLETE by adding this line to `.aidp/PROMPT.md`:
|
|
276
278
|
```
|
|
277
279
|
STATUS: COMPLETE
|
|
278
280
|
```
|
|
@@ -487,12 +489,24 @@ module Aidp
|
|
|
487
489
|
+ (result.lint_commands.empty? ? "" : "Lint Commands:\n#{result.lint_commands.map { |c| "- #{c}" }.join("\n")}\n")
|
|
488
490
|
|
|
489
491
|
# Use PromptManager to append to .aidp/PROMPT.md (issue #226)
|
|
490
|
-
prompt_manager = Aidp::Execute::PromptManager.new(
|
|
492
|
+
prompt_manager = Aidp::Execute::PromptManager.new(project_dir)
|
|
491
493
|
current_prompt = prompt_manager.read
|
|
492
494
|
updated_prompt = current_prompt + "\n---\n\n#{tooling_info}"
|
|
493
495
|
prompt_manager.write(updated_prompt, step_name: "github_issue_tooling")
|
|
494
496
|
|
|
495
497
|
display_message("🧪 Detected tooling and appended to PROMPT.md", type: :info)
|
|
496
498
|
end
|
|
499
|
+
|
|
500
|
+
def project_dir
|
|
501
|
+
@project_dir_override || safe_pwd
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def safe_pwd
|
|
505
|
+
Dir.pwd
|
|
506
|
+
rescue Errno::ENOENT
|
|
507
|
+
# If the current directory no longer exists (e.g., in test environment),
|
|
508
|
+
# use ENV["AIDP_PROJECT_DIR"] or fallback to "."
|
|
509
|
+
ENV["AIDP_PROJECT_DIR"] || "."
|
|
510
|
+
end
|
|
497
511
|
end
|
|
498
512
|
end
|
|
@@ -311,7 +311,7 @@ module Aidp
|
|
|
311
311
|
|
|
312
312
|
jobs << job_info
|
|
313
313
|
rescue JSON::ParserError => e
|
|
314
|
-
display_message("Warning: Could not parse harness log #{log_file}: #{e.message}", type: :warning) if
|
|
314
|
+
display_message("Warning: Could not parse harness log #{log_file}: #{e.message}", type: :warning) if Aidp.debug_env_enabled?
|
|
315
315
|
end
|
|
316
316
|
|
|
317
317
|
# Sort by creation time (newest first)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "tty-table"
|
|
4
4
|
require "tty-prompt"
|
|
5
5
|
require "tty-spinner"
|
|
6
|
+
require "agent_harness"
|
|
6
7
|
require_relative "../harness/model_registry"
|
|
7
8
|
require_relative "../harness/ruby_llm_registry"
|
|
8
9
|
|
|
@@ -208,26 +209,19 @@ module Aidp
|
|
|
208
209
|
|
|
209
210
|
def find_providers_for_family(family_name)
|
|
210
211
|
providers = []
|
|
212
|
+
registry = AgentHarness::Providers::Registry.instance
|
|
211
213
|
|
|
212
|
-
# Check each provider
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
Aidp::Providers::Cursor,
|
|
216
|
-
Aidp::Providers::Gemini
|
|
217
|
-
]
|
|
218
|
-
|
|
219
|
-
provider_classes.each do |provider_class|
|
|
214
|
+
# Check each registered provider for support
|
|
215
|
+
registry.all.each do |provider_name|
|
|
216
|
+
provider_class = registry.get(provider_name)
|
|
220
217
|
next unless provider_class.respond_to?(:supports_model_family?)
|
|
221
218
|
|
|
222
219
|
if provider_class.supports_model_family?(family_name)
|
|
223
|
-
|
|
224
|
-
# Or use a simple name mapping
|
|
225
|
-
provider_name = provider_class.name.split("::").last.downcase
|
|
226
|
-
providers << provider_name
|
|
220
|
+
providers << provider_name.to_s
|
|
227
221
|
end
|
|
228
222
|
rescue => e
|
|
229
223
|
# Log but don't fail if provider check fails
|
|
230
|
-
Aidp.log_debug("models_command", "provider check failed", provider:
|
|
224
|
+
Aidp.log_debug("models_command", "provider check failed", provider: provider_name, error: e.message)
|
|
231
225
|
end
|
|
232
226
|
|
|
233
227
|
providers
|
|
@@ -455,9 +449,8 @@ module Aidp
|
|
|
455
449
|
end
|
|
456
450
|
|
|
457
451
|
def get_provider_class(provider_name)
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
rescue NameError
|
|
452
|
+
AgentHarness::Providers::Registry.instance.get(provider_name.to_sym)
|
|
453
|
+
rescue AgentHarness::ConfigurationError
|
|
461
454
|
nil
|
|
462
455
|
end
|
|
463
456
|
|