duoops 0.1.7 → 0.2.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.
- package/README.md +151 -63
- package/data/aws_machine_power_profiles.json +54 -0
- package/data/cpu_physical_specs.json +105 -0
- package/data/cpu_power_profiles.json +275 -0
- package/data/gcp_machine_power_profiles.json +1802 -0
- package/data/runtime-pue-mappings.json +183 -0
- package/dist/commands/ask.d.ts +3 -0
- package/dist/commands/ask.js +9 -3
- package/dist/commands/autofix-ci.d.ts +13 -0
- package/dist/commands/autofix-ci.js +114 -0
- package/dist/commands/autofix.d.ts +5 -0
- package/dist/commands/autofix.js +11 -0
- package/dist/commands/config.d.ts +10 -0
- package/dist/commands/config.js +47 -0
- package/dist/commands/init.js +50 -27
- package/dist/commands/mcp/deploy.d.ts +13 -0
- package/dist/commands/mcp/deploy.js +139 -0
- package/dist/commands/measure/calculate.js +2 -2
- package/dist/commands/portal.js +428 -11
- package/dist/lib/ai/agent.d.ts +6 -2
- package/dist/lib/ai/agent.js +51 -57
- package/dist/lib/ai/tools/editing.js +28 -13
- package/dist/lib/ai/tools/gitlab.d.ts +4 -0
- package/dist/lib/ai/tools/gitlab.js +166 -11
- package/dist/lib/ai/tools/measure.js +7 -3
- package/dist/lib/ai/tools/types.d.ts +3 -0
- package/dist/lib/ai/tools/types.js +1 -0
- package/dist/lib/config.d.ts +10 -0
- package/dist/lib/gcloud.d.ts +7 -0
- package/dist/lib/gcloud.js +105 -0
- package/dist/lib/gitlab/pipelines-service.d.ts +23 -0
- package/dist/lib/gitlab/pipelines-service.js +146 -0
- package/dist/lib/gitlab/runner-service.d.ts +11 -0
- package/dist/lib/gitlab/runner-service.js +15 -0
- package/dist/lib/portal/settings.d.ts +3 -0
- package/dist/lib/portal/settings.js +48 -0
- package/dist/lib/scaffold.d.ts +5 -0
- package/dist/lib/scaffold.js +32 -0
- package/dist/portal/assets/HomeDashboard-DlkwSyKx.js +1 -0
- package/dist/portal/assets/JobDetailsDrawer-7kXXMSH8.js +1 -0
- package/dist/portal/assets/JobsDashboard-D4pNc9TM.js +1 -0
- package/dist/portal/assets/MetricsDashboard-BcgzvzBz.js +1 -0
- package/dist/portal/assets/PipelinesDashboard-BNrSM9GB.js +1 -0
- package/dist/portal/assets/allPaths-CXDKahbk.js +1 -0
- package/dist/portal/assets/allPathsLoader-BF5PAx2c.js +2 -0
- package/dist/portal/assets/cache-YerT0Slh.js +6 -0
- package/dist/portal/assets/core-Cz8f3oSB.js +19 -0
- package/dist/portal/assets/{index-B6bzT1Vv.js → index-B9sNUqEC.js} +1 -1
- package/dist/portal/assets/index-BWa_E8Y7.css +1 -0
- package/dist/portal/assets/index-Bp4RqK05.js +1 -0
- package/dist/portal/assets/index-DW6Qp0d6.js +64 -0
- package/dist/portal/assets/index-Uc4Xhv31.js +1 -0
- package/dist/portal/assets/progressBar-C4SmnGeZ.js +1 -0
- package/dist/portal/assets/splitPathsBySizeLoader-C-T9_API.js +1 -0
- package/dist/portal/index.html +2 -2
- package/oclif.manifest.json +282 -93
- package/package.json +2 -1
- package/templates/.gitlab/duo/flows/duoops.yaml +114 -0
- package/templates/agents/agent.yml +45 -0
- package/templates/duoops-autofix-component.yml +52 -0
- package/templates/flows/flow.yml +283 -0
- package/dist/portal/assets/MetricsDashboard-DIsoz4Sl.js +0 -71
- package/dist/portal/assets/index-BP8FwWqA.css +0 -1
- package/dist/portal/assets/index-DkVG3jel.js +0 -70
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
name: "DuoOps Pipeline Doctor"
|
|
2
|
+
description: "Multi-stage CI/CD pipeline healing: fetches failures, diagnoses root cause, applies a fix commit, validates the CI config, and reports sustainability insights — all posted back to the merge request."
|
|
3
|
+
public: true
|
|
4
|
+
definition:
|
|
5
|
+
version: v1
|
|
6
|
+
environment: ambient
|
|
7
|
+
|
|
8
|
+
components:
|
|
9
|
+
- name: "fetch_failures"
|
|
10
|
+
type: DeterministicStepComponent
|
|
11
|
+
inputs:
|
|
12
|
+
- from: "context:goal"
|
|
13
|
+
as: "merge_request_url"
|
|
14
|
+
tool_name: "get_pipeline_errors"
|
|
15
|
+
ui_log_events:
|
|
16
|
+
- on_tool_execution_success
|
|
17
|
+
- on_tool_execution_failed
|
|
18
|
+
|
|
19
|
+
- name: "diagnose"
|
|
20
|
+
type: AgentComponent
|
|
21
|
+
prompt_id: "duoops_diagnose_prompt"
|
|
22
|
+
inputs:
|
|
23
|
+
- "context:goal"
|
|
24
|
+
- from: "context:fetch_failures.tool_responses"
|
|
25
|
+
as: "pipeline_errors"
|
|
26
|
+
toolset:
|
|
27
|
+
- get_job_logs
|
|
28
|
+
- get_pipeline_errors
|
|
29
|
+
- get_pipeline_failing_jobs
|
|
30
|
+
- get_merge_request
|
|
31
|
+
- list_merge_request_diffs
|
|
32
|
+
- get_repository_file
|
|
33
|
+
- read_file
|
|
34
|
+
- read_files
|
|
35
|
+
- find_files
|
|
36
|
+
- grep
|
|
37
|
+
- list_dir
|
|
38
|
+
- get_commit_diff
|
|
39
|
+
ui_log_events:
|
|
40
|
+
- on_agent_final_answer
|
|
41
|
+
- on_tool_execution_success
|
|
42
|
+
|
|
43
|
+
- name: "validate_ci_config"
|
|
44
|
+
type: OneOffComponent
|
|
45
|
+
prompt_id: "duoops_validate_prompt"
|
|
46
|
+
inputs:
|
|
47
|
+
- "context:goal"
|
|
48
|
+
- from: "context:diagnose.agent_output"
|
|
49
|
+
as: "diagnosis"
|
|
50
|
+
toolset:
|
|
51
|
+
- ci_linter
|
|
52
|
+
- get_repository_file
|
|
53
|
+
max_correction_attempts: 3
|
|
54
|
+
ui_log_events:
|
|
55
|
+
- on_tool_execution_success
|
|
56
|
+
- on_tool_call_input
|
|
57
|
+
|
|
58
|
+
- name: "apply_fix"
|
|
59
|
+
type: AgentComponent
|
|
60
|
+
prompt_id: "duoops_apply_fix_prompt"
|
|
61
|
+
inputs:
|
|
62
|
+
- "context:goal"
|
|
63
|
+
- from: "context:diagnose.agent_output"
|
|
64
|
+
as: "diagnosis"
|
|
65
|
+
- from: "context:validate_ci_config.tool_responses"
|
|
66
|
+
as: "ci_lint_result"
|
|
67
|
+
toolset:
|
|
68
|
+
- read_file
|
|
69
|
+
- read_files
|
|
70
|
+
- get_repository_file
|
|
71
|
+
- find_files
|
|
72
|
+
- grep
|
|
73
|
+
- edit_file
|
|
74
|
+
- create_file_with_contents
|
|
75
|
+
- create_commit
|
|
76
|
+
- ci_linter
|
|
77
|
+
ui_log_events:
|
|
78
|
+
- on_agent_final_answer
|
|
79
|
+
- on_tool_execution_success
|
|
80
|
+
|
|
81
|
+
- name: "report_and_sustainability"
|
|
82
|
+
type: AgentComponent
|
|
83
|
+
prompt_id: "duoops_report_prompt"
|
|
84
|
+
inputs:
|
|
85
|
+
- "context:goal"
|
|
86
|
+
- from: "context:diagnose.agent_output"
|
|
87
|
+
as: "diagnosis"
|
|
88
|
+
- from: "context:validate_ci_config.tool_responses"
|
|
89
|
+
as: "ci_lint_result"
|
|
90
|
+
- from: "context:apply_fix.agent_output"
|
|
91
|
+
as: "fix_result"
|
|
92
|
+
toolset:
|
|
93
|
+
- get_merge_request
|
|
94
|
+
- get_job_logs
|
|
95
|
+
- get_pipeline_failing_jobs
|
|
96
|
+
- list_merge_request_diffs
|
|
97
|
+
- create_merge_request_note
|
|
98
|
+
ui_log_events:
|
|
99
|
+
- on_agent_final_answer
|
|
100
|
+
- on_tool_execution_success
|
|
101
|
+
|
|
102
|
+
prompts:
|
|
103
|
+
- prompt_id: "duoops_diagnose_prompt"
|
|
104
|
+
name: "DuoOps Diagnosis Agent"
|
|
105
|
+
unit_primitives: []
|
|
106
|
+
prompt_template:
|
|
107
|
+
system: |
|
|
108
|
+
You are DuoOps, an expert CI/CD diagnostician for GitLab pipelines.
|
|
109
|
+
|
|
110
|
+
A pipeline has failed. You receive the initial error summary from a prior deterministic step. Your task is to perform a deep root-cause analysis:
|
|
111
|
+
|
|
112
|
+
1. Fetch full logs for EVERY failed job using get_job_logs.
|
|
113
|
+
2. Read the .gitlab-ci.yml and any included CI config files.
|
|
114
|
+
3. Read the source files referenced in error messages.
|
|
115
|
+
4. Check the MR diff to see what changed and whether the change caused the failure.
|
|
116
|
+
5. Identify the root cause with high confidence.
|
|
117
|
+
|
|
118
|
+
Your output MUST be a structured diagnosis in this exact format:
|
|
119
|
+
|
|
120
|
+
ROOT_CAUSE: <one-line summary>
|
|
121
|
+
FAILED_JOBS: <comma-separated job names>
|
|
122
|
+
CATEGORY: <one of: code_error | ci_config | dependency | infrastructure | test_failure | permissions>
|
|
123
|
+
FIXABLE: <yes | no | partial>
|
|
124
|
+
FILES_TO_FIX: <comma-separated file paths, or "none">
|
|
125
|
+
DETAILS: <2-5 sentences explaining the failure and the fix strategy>
|
|
126
|
+
|
|
127
|
+
Be precise. Reference exact job names, line numbers, and error messages.
|
|
128
|
+
Do NOT post anything to the merge request — a later step handles reporting.
|
|
129
|
+
user: |
|
|
130
|
+
{{goal}}
|
|
131
|
+
|
|
132
|
+
Pipeline error context from deterministic fetch:
|
|
133
|
+
{{pipeline_errors}}
|
|
134
|
+
placeholder: history
|
|
135
|
+
params:
|
|
136
|
+
timeout: 120
|
|
137
|
+
|
|
138
|
+
- prompt_id: "duoops_validate_prompt"
|
|
139
|
+
name: "DuoOps CI Validator"
|
|
140
|
+
unit_primitives: []
|
|
141
|
+
prompt_template:
|
|
142
|
+
system: |
|
|
143
|
+
You are a CI configuration validator. You have access to the ci_linter tool and the repository file reader.
|
|
144
|
+
|
|
145
|
+
Your task:
|
|
146
|
+
1. Fetch the .gitlab-ci.yml from the repository using get_repository_file with the path ".gitlab-ci.yml".
|
|
147
|
+
2. Run ci_linter on the content to check for syntax errors.
|
|
148
|
+
3. If the diagnosis mentions CI config issues, this validation is critical.
|
|
149
|
+
|
|
150
|
+
Return the linter result as-is. Do not embellish or add commentary.
|
|
151
|
+
user: |
|
|
152
|
+
{{goal}}
|
|
153
|
+
|
|
154
|
+
Diagnosis from prior step:
|
|
155
|
+
{{diagnosis}}
|
|
156
|
+
placeholder: history
|
|
157
|
+
params:
|
|
158
|
+
timeout: 60
|
|
159
|
+
|
|
160
|
+
- prompt_id: "duoops_apply_fix_prompt"
|
|
161
|
+
name: "DuoOps Fix Agent"
|
|
162
|
+
unit_primitives: []
|
|
163
|
+
prompt_template:
|
|
164
|
+
system: |
|
|
165
|
+
You are DuoOps, a CI/CD fix agent. You receive a diagnosis and CI lint results from prior steps.
|
|
166
|
+
|
|
167
|
+
Your task is to apply a fix commit to the current MR branch:
|
|
168
|
+
|
|
169
|
+
1. Review the diagnosis to understand what files need changing.
|
|
170
|
+
2. Read the current content of each file that needs modification.
|
|
171
|
+
3. Use edit_file to make the necessary changes. Be surgical — change only what is needed.
|
|
172
|
+
4. If the diagnosis says FIXABLE is "no", do NOT attempt a fix. Output "NO_FIX_APPLIED: <reason>" and stop.
|
|
173
|
+
5. If the CI linter flagged errors in .gitlab-ci.yml, fix those too.
|
|
174
|
+
6. Once all edits are made, use create_commit to commit the changes with a clear message prefixed with "fix(ci): ".
|
|
175
|
+
7. If you create a commit, run ci_linter one more time on the updated .gitlab-ci.yml to confirm validity.
|
|
176
|
+
|
|
177
|
+
Output your result in this format:
|
|
178
|
+
FIX_STATUS: <applied | skipped | partial>
|
|
179
|
+
COMMIT_SHA: <sha if applied, "none" if skipped>
|
|
180
|
+
FILES_CHANGED: <comma-separated list>
|
|
181
|
+
SUMMARY: <one sentence describing the fix>
|
|
182
|
+
|
|
183
|
+
Be conservative. Only fix what you are confident about. Do not introduce new issues.
|
|
184
|
+
user: |
|
|
185
|
+
{{goal}}
|
|
186
|
+
|
|
187
|
+
Diagnosis:
|
|
188
|
+
{{diagnosis}}
|
|
189
|
+
|
|
190
|
+
CI Lint Result:
|
|
191
|
+
{{ci_lint_result}}
|
|
192
|
+
placeholder: history
|
|
193
|
+
params:
|
|
194
|
+
timeout: 180
|
|
195
|
+
|
|
196
|
+
- prompt_id: "duoops_report_prompt"
|
|
197
|
+
name: "DuoOps Reporter"
|
|
198
|
+
unit_primitives: []
|
|
199
|
+
prompt_template:
|
|
200
|
+
system: |
|
|
201
|
+
You are DuoOps, the final reporting agent. You compile the results from all prior steps into a single, clear merge request note.
|
|
202
|
+
|
|
203
|
+
You receive:
|
|
204
|
+
- The root-cause diagnosis
|
|
205
|
+
- The CI lint validation result
|
|
206
|
+
- The fix application result (commit SHA or skip reason)
|
|
207
|
+
|
|
208
|
+
Your task:
|
|
209
|
+
1. Compose a merge request note using create_merge_request_note with ALL the information below.
|
|
210
|
+
2. Analyze the failing jobs for sustainability concerns: redundant steps, missing caches, oversized images, parallelizable stages, unnecessary artifact uploads, jobs that could use `rules:changes` to skip when irrelevant files change.
|
|
211
|
+
|
|
212
|
+
Structure the MR note EXACTLY as follows:
|
|
213
|
+
|
|
214
|
+
## 🔍 Root Cause Analysis
|
|
215
|
+
<What failed and why. Reference job names and error messages.>
|
|
216
|
+
|
|
217
|
+
## 🔧 Applied Fix
|
|
218
|
+
<If a fix commit was created, mention the SHA and what was changed.>
|
|
219
|
+
<If no fix was applied, explain why and provide manual remediation steps.>
|
|
220
|
+
|
|
221
|
+
## ✅ CI Config Validation
|
|
222
|
+
<Lint status of .gitlab-ci.yml — valid or errors found.>
|
|
223
|
+
|
|
224
|
+
## 🌱 Sustainability Insights
|
|
225
|
+
<Concrete recommendations to reduce CI carbon footprint:>
|
|
226
|
+
- Cache optimization opportunities
|
|
227
|
+
- Image size reduction
|
|
228
|
+
- Job deduplication / rules:changes gating
|
|
229
|
+
- Stage parallelization
|
|
230
|
+
- Runner sizing recommendations
|
|
231
|
+
|
|
232
|
+
## 📋 Next Steps
|
|
233
|
+
<What the developer should do: push again, review the fix commit, or apply manual changes.>
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
*Generated by [DuoOps](https://gitlab.com/youneslaaroussi/duoops) — Explainable & Sustainable CI*
|
|
237
|
+
|
|
238
|
+
Keep the note concise but actionable. Every recommendation must be specific to this project.
|
|
239
|
+
user: |
|
|
240
|
+
{{goal}}
|
|
241
|
+
|
|
242
|
+
Diagnosis:
|
|
243
|
+
{{diagnosis}}
|
|
244
|
+
|
|
245
|
+
CI Lint Result:
|
|
246
|
+
{{ci_lint_result}}
|
|
247
|
+
|
|
248
|
+
Fix Result:
|
|
249
|
+
{{fix_result}}
|
|
250
|
+
placeholder: history
|
|
251
|
+
params:
|
|
252
|
+
timeout: 120
|
|
253
|
+
|
|
254
|
+
routers:
|
|
255
|
+
- from: "fetch_failures"
|
|
256
|
+
condition:
|
|
257
|
+
input: "context:fetch_failures.execution_result"
|
|
258
|
+
routes:
|
|
259
|
+
"success": "diagnose"
|
|
260
|
+
"failed": "diagnose"
|
|
261
|
+
|
|
262
|
+
- from: "diagnose"
|
|
263
|
+
condition:
|
|
264
|
+
input: "context:diagnose.agent_output"
|
|
265
|
+
routes:
|
|
266
|
+
"FIXABLE: no": "report_and_sustainability"
|
|
267
|
+
"default": "validate_ci_config"
|
|
268
|
+
|
|
269
|
+
- from: "validate_ci_config"
|
|
270
|
+
condition:
|
|
271
|
+
input: "context:validate_ci_config.execution_result"
|
|
272
|
+
routes:
|
|
273
|
+
"success": "apply_fix"
|
|
274
|
+
"failed": "apply_fix"
|
|
275
|
+
|
|
276
|
+
- from: "apply_fix"
|
|
277
|
+
to: "report_and_sustainability"
|
|
278
|
+
|
|
279
|
+
- from: "report_and_sustainability"
|
|
280
|
+
to: "end"
|
|
281
|
+
|
|
282
|
+
flow:
|
|
283
|
+
entry_point: "fetch_failures"
|