@openhands/extensions 0.19.0 → 0.21.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/.github/workflows/check-extensions.yml +4 -0
- package/.github/workflows/pr-artifacts.yml +294 -0
- package/.github/workflows/pr-description-check.yml +4 -2
- package/.release-please-manifest.json +1 -1
- package/AGENTS.md +28 -4
- package/README.md +5 -2
- package/automations/README.md +52 -36
- package/automations/bundle-index.js +13 -3
- package/automations/catalog/custom-automation/manifest.json +229 -0
- package/automations/catalog/github-agents-md-maintainer/manifest.json +2 -1
- package/automations/catalog/github-issue-to-pr/manifest.json +3 -2
- package/automations/catalog/github-issue-triage/manifest.json +72 -0
- package/automations/catalog/github-pr-reviewer/manifest.json +3 -2
- package/automations/catalog/gitlab-issue-to-mr/manifest.json +124 -0
- package/automations/catalog/qa-changes/manifest.json +1 -1
- package/automations/catalog-index.js +23 -17
- package/automations/catalog.schema.json +81 -7
- package/automations/index.d.ts +52 -2
- package/automations/interface.json +2 -1
- package/integrations/catalog/gitlab.json +27 -5
- package/integrations/catalog/reportportal.json +76 -0
- package/integrations/catalog-index.js +6 -4
- package/marketplaces/openhands-extensions.json +36 -0
- package/package.json +1 -1
- package/pyproject.toml +2 -2
- package/python/openhands_extensions/_version.py +1 -1
- package/skills/github/scripts/github_client.py +204 -0
- package/skills/github-agents-md-maintainer/SKILL.md +7 -1
- package/skills/github-agents-md-maintainer/scripts/main.py +4 -40
- package/skills/github-issue-to-pr/SKILL.md +8 -1
- package/skills/github-issue-to-pr/scripts/main.py +3 -40
- package/skills/github-issue-triage/.plugin/plugin.json +9 -0
- package/skills/github-issue-triage/README.md +9 -0
- package/skills/github-issue-triage/SKILL.md +37 -0
- package/skills/github-issue-triage/commands/github-issue-triage.md +8 -0
- package/skills/github-issue-triage/scripts/worker.py +123 -0
- package/skills/github-pr-reviewer/SKILL.md +8 -1
- package/skills/github-pr-reviewer/scripts/main.py +3 -41
- package/skills/github-repo-monitor/SKILL.md +7 -1
- package/skills/github-repo-monitor/scripts/main.py +4 -46
- package/skills/gitlab-issue-to-mr/.plugin/plugin.json +19 -0
- package/skills/gitlab-issue-to-mr/README.md +92 -0
- package/skills/gitlab-issue-to-mr/SKILL.md +408 -0
- package/skills/gitlab-issue-to-mr/commands/issue-to-mr-setup.md +8 -0
- package/skills/gitlab-issue-to-mr/references/state-schema.md +140 -0
- package/skills/gitlab-issue-to-mr/scripts/main.py +1448 -0
- package/skills/index.js +43 -6
- package/skills/openhands-automation/README.md +1 -1
- package/skills/openhands-automation/SKILL.md +18 -8
- package/skills/openhands-enterprise-troubleshooting/.plugin/plugin.json +20 -0
- package/skills/openhands-enterprise-troubleshooting/README.md +79 -0
- package/skills/openhands-enterprise-troubleshooting/SKILL.md +339 -0
- package/skills/openhands-enterprise-troubleshooting/references/diagnostics.md +698 -0
- package/skills/openhands-enterprise-troubleshooting/references/support-bundle-analysis.md +570 -0
- package/skills/openhands-enterprise-troubleshooting/scripts/bundle_triage.py +532 -0
- package/skills/openhands-sdk/SKILL.md +2 -0
- package/tests/fixtures/automations/custom-automation.json +398 -0
- package/tests/fixtures/automations/github-pr-reviewer.json +9 -9
- package/tests/github_automation_helpers.py +25 -0
- package/tests/test_automation_setup.py +340 -92
- package/tests/test_github_automation_foundation.py +73 -0
- package/tests/test_github_skill_installation.py +63 -0
- package/tests/test_github_triage_delivery.py +53 -0
- package/tests/test_gitlab_issue_to_mr.py +823 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# State Schema
|
|
2
|
+
|
|
3
|
+
The automation maintains a JSON state document **per project**, persisted across
|
|
4
|
+
polling runs. It is the source of truth for which trigger-label events have
|
|
5
|
+
already queued work, which conversations are still active, and which clones are
|
|
6
|
+
still on disk.
|
|
7
|
+
|
|
8
|
+
Each project in `PROJECTS` gets its own document, so issue IIDs from different
|
|
9
|
+
projects never share a bucket.
|
|
10
|
+
|
|
11
|
+
The document holds only what a poll needs in order to decide what to do next.
|
|
12
|
+
Issue metadata that can be read back from GitLab is not mirrored here, so there
|
|
13
|
+
is nothing to drift.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Storage
|
|
18
|
+
|
|
19
|
+
**Primary (cloud):** The state is stored in the automation service's built-in KV
|
|
20
|
+
store under the key `state:{group}__{project}` - for example
|
|
21
|
+
`state:gitlab-org__gitlab`. Subgroups keep their separators, so
|
|
22
|
+
`group/team/service` becomes `state:group__team__service`. The KV store is
|
|
23
|
+
available when `AUTOMATION_KV_TOKEN` is injected into the run environment. Each
|
|
24
|
+
automation has its own isolated namespace.
|
|
25
|
+
|
|
26
|
+
**Fallback (local/dev):** When the KV store is not available, the state is
|
|
27
|
+
written to a local JSON file at:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
{WORKSPACE_BASE_ROOT}/automation-state/gitlab_issue_to_mr_{automation_id}_{group}__{project}.json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`WORKSPACE_BASE_ROOT` is derived by going two levels up from the `WORKSPACE_BASE`
|
|
34
|
+
environment variable, stripping `automation-runs/{run_id}`.
|
|
35
|
+
|
|
36
|
+
Example on a local install:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
~/.openhands/workspaces/automation-state/gitlab_issue_to_mr_abc12345-..._myorg__backend.json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The `automation_id` is read from the `AUTOMATION_EVENT_PAYLOAD` environment
|
|
43
|
+
variable, field `automation_id`.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Top-Level Schema
|
|
48
|
+
|
|
49
|
+
```jsonc
|
|
50
|
+
{
|
|
51
|
+
"version": 1,
|
|
52
|
+
"project": "group/project",
|
|
53
|
+
"trigger_label": "openhands",
|
|
54
|
+
"updated_at": 1717200000.0,
|
|
55
|
+
"tasks": {}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## `tasks` Map
|
|
62
|
+
|
|
63
|
+
Key: `"{issue_iid}:label:{label_event_id}"`. This makes the latest GitLab
|
|
64
|
+
resource label event with `action: "add"` the idempotency key. Re-applying the
|
|
65
|
+
trigger label creates a new event and therefore a new task, on a new branch.
|
|
66
|
+
|
|
67
|
+
Value: **TaskRecord**
|
|
68
|
+
|
|
69
|
+
```jsonc
|
|
70
|
+
{
|
|
71
|
+
"issue_iid": 42,
|
|
72
|
+
"issue_title": "Retry uploads on a 502",
|
|
73
|
+
"trigger_label_event_id": 123456789,
|
|
74
|
+
"trigger_label_event_created_at": "2026-06-12T00:00:00Z",
|
|
75
|
+
"web_url": "https://gitlab.com/group/project/-/issues/42",
|
|
76
|
+
"base_branch": "main",
|
|
77
|
+
"base_sha": "0123456789abcdef...",
|
|
78
|
+
"branch": "openhands/issue-42",
|
|
79
|
+
"status": "active",
|
|
80
|
+
"conversation_id": "conv_abc123",
|
|
81
|
+
"workspace_dir": "/workspace/issue-to-mr/group__project/issue-42-123456789",
|
|
82
|
+
"last_activity": 1717200000.0,
|
|
83
|
+
"finalize_attempts": 1,
|
|
84
|
+
"merge_request_url": "https://gitlab.com/group/project/-/merge_requests/57",
|
|
85
|
+
"merge_request_iid": 57,
|
|
86
|
+
"completed_at": 1717203600.0,
|
|
87
|
+
"expired_after": 7200.5,
|
|
88
|
+
"error": "git push origin ... failed (128): ..."
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
| Field | Written when | Meaning |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `issue_iid` | claim | The issue being implemented, by its project-scoped IID |
|
|
95
|
+
| `issue_title` | claim | Used for the commit message and the merge request title |
|
|
96
|
+
| `trigger_label_event_id` | claim | The GitLab label event this task belongs to |
|
|
97
|
+
| `trigger_label_event_created_at` | claim | When that label was applied |
|
|
98
|
+
| `web_url` | claim | The issue URL |
|
|
99
|
+
| `base_branch` | claim | The project's default branch at claim time |
|
|
100
|
+
| `base_sha` | start | The commit the clone starts from; commits are counted against it |
|
|
101
|
+
| `branch` | start | The branch the merge request is opened from |
|
|
102
|
+
| `status` | throughout | See the lifecycle below |
|
|
103
|
+
| `conversation_id` | start | The OpenHands conversation doing the work |
|
|
104
|
+
| `workspace_dir` | start | The clone. Removed, and the field dropped, once the task ends |
|
|
105
|
+
| `last_activity` | throughout | Drives the debounce, the two-hour abandonment, and the stalled-claim release |
|
|
106
|
+
| `finalize_attempts` | finalize | How many times pushing and opening the merge request has been tried |
|
|
107
|
+
| `merge_request_url` / `merge_request_iid` | success | The merge request that was opened |
|
|
108
|
+
| `completed_at` | end | When the task reached a terminal status |
|
|
109
|
+
| `expired_after` | expiry | Seconds the conversation ran before being abandoned |
|
|
110
|
+
| `error` | failure | The last finalization error, after the retries ran out |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Task Lifecycle
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
label event seen
|
|
118
|
+
│
|
|
119
|
+
▼
|
|
120
|
+
"starting" ── claim persisted before the slow work, so an
|
|
121
|
+
│ overlapping poll cannot start it twice.
|
|
122
|
+
│ Released after 15 minutes if the poll died.
|
|
123
|
+
clone + conversation
|
|
124
|
+
│
|
|
125
|
+
▼
|
|
126
|
+
"active"
|
|
127
|
+
│
|
|
128
|
+
┌─────────────┬───────┴────────┬──────────────┬─────────────────┐
|
|
129
|
+
▼ ▼ ▼ ▼ ▼
|
|
130
|
+
"issue-closed" "failed" "no-changes" "closed" "expired"
|
|
131
|
+
issue closed conversation agent produced merge request no terminal
|
|
132
|
+
meanwhile errored, or no commits; opened and status within
|
|
133
|
+
push/MR gave its answer is linked on the two hours
|
|
134
|
+
up after 3 posted on the issue
|
|
135
|
+
attempts issue
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Every terminal status releases the clone, but only once the conversation is
|
|
139
|
+
confirmed stopped. When that cannot be confirmed, `workspace_dir` stays in the
|
|
140
|
+
record and a later poll retries the removal.
|