@openhands/extensions 0.15.0 → 0.17.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/.release-please-manifest.json +1 -1
- package/AGENTS.md +1 -0
- package/automations/README.md +97 -18
- package/automations/bundle-index.js +9 -0
- package/automations/catalog/github-pr-reviewer/manifest.json +23 -7
- package/automations/catalog/github-repo-monitor/manifest.json +28 -34
- package/automations/catalog/jira-issue-to-pr/manifest.json +3 -3
- package/automations/catalog.schema.json +102 -1
- package/automations/index.d.ts +174 -1
- package/automations/index.js +14 -0
- package/automations/interface.json +93 -6
- package/automations/interface.schema.json +273 -9
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/integrations/catalog/posthog.json +41 -3
- package/integrations/catalog/sonarqube.json +78 -0
- package/integrations/catalog-index.js +65 -63
- package/marketplaces/openhands-extensions.json +11 -0
- package/package.json +1 -1
- package/plugins/qa-changes/action.yml +1 -1
- package/pyproject.toml +1 -1
- package/python/openhands_extensions/_version.py +1 -1
- package/scripts/build-automation-catalog.mjs +30 -0
- package/scripts/build-skills-catalog.mjs +24 -7
- package/skills/add-skill/SKILL.md +1 -1
- package/skills/github-pr-reviewer/README.md +12 -6
- package/skills/github-pr-reviewer/SKILL.md +93 -31
- package/skills/github-pr-reviewer/commands/pr-reviewer-setup.md +1 -1
- package/skills/github-pr-reviewer/references/state-schema.md +68 -18
- package/skills/github-pr-reviewer/scripts/main.py +540 -103
- package/skills/github-pr-reviewer/tests/test_main.py +503 -0
- package/skills/index.d.ts +6 -0
- package/skills/index.js +29 -17
- package/skills/jira-issue-to-pr/scripts/main.py +4 -2
- package/skills/openhands-sdk/SKILL.md +2 -0
- package/skills/skill-creator/SKILL.md +1 -1
- package/skills/slack-channel-monitor/scripts/main.py +3 -2
- package/tests/fixtures/automations/capabilities.json +30 -0
- package/tests/fixtures/automations/github-pr-reviewer.json +319 -55
- package/tests/fixtures/automations/github-repo-monitor.json +153 -62
- package/tests/test_automation_setup.py +226 -31
- package/tests/test_catalogs.py +43 -0
- package/tests/test_interface_manifest.py +20 -0
- package/tests/test_skills_catalog.py +182 -36
- package/tests/test_slack_channel_monitor.py +1 -1
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
# State Schema
|
|
2
2
|
|
|
3
|
-
The automation maintains a JSON state document
|
|
4
|
-
It is the source of truth for which trigger-label events
|
|
5
|
-
|
|
3
|
+
The automation maintains a JSON state document **per repository**, persisted
|
|
4
|
+
across polling runs. It is the source of truth for which trigger-label events
|
|
5
|
+
have queued reviews, which conversations are still active, and which repository
|
|
6
|
+
checkouts are still on disk.
|
|
7
|
+
|
|
8
|
+
Each repository in `REPOS` gets its own document, so pull-request numbers from
|
|
9
|
+
different repositories never share a bucket.
|
|
6
10
|
|
|
7
11
|
---
|
|
8
12
|
|
|
9
13
|
## Storage
|
|
10
14
|
|
|
11
15
|
**Primary (cloud):** The state is stored in the automation service's built-in KV
|
|
12
|
-
store under the key `
|
|
13
|
-
|
|
16
|
+
store under the key `state:{owner}__{repo}` — for example
|
|
17
|
+
`state:OpenHands__extensions`. The KV store is available when
|
|
18
|
+
`AUTOMATION_KV_TOKEN` is injected into the run environment. Each automation has
|
|
19
|
+
its own isolated namespace.
|
|
14
20
|
|
|
15
|
-
**Fallback (local/dev):** When the KV store is not available, the state is
|
|
16
|
-
to a local JSON file at:
|
|
21
|
+
**Fallback (local/dev):** When the KV store is not available, the state is
|
|
22
|
+
written to a local JSON file at:
|
|
17
23
|
|
|
18
24
|
```
|
|
19
|
-
{WORKSPACE_BASE_ROOT}/automation-state/github_pr_reviewer_label_event_{automation_id}.json
|
|
25
|
+
{WORKSPACE_BASE_ROOT}/automation-state/github_pr_reviewer_label_event_{automation_id}_{owner}__{repo}.json
|
|
20
26
|
```
|
|
21
27
|
|
|
22
28
|
`WORKSPACE_BASE_ROOT` is derived by going two levels up from the `WORKSPACE_BASE`
|
|
@@ -25,19 +31,28 @@ environment variable, stripping `automation-runs/{run_id}`.
|
|
|
25
31
|
Example on a local install:
|
|
26
32
|
|
|
27
33
|
```
|
|
28
|
-
~/.openhands/workspaces/automation-state/github_pr_reviewer_label_event_abc12345
|
|
34
|
+
~/.openhands/workspaces/automation-state/github_pr_reviewer_label_event_abc12345-..._myorg__backend.json
|
|
29
35
|
```
|
|
30
36
|
|
|
31
37
|
The `automation_id` is read from the `AUTOMATION_EVENT_PAYLOAD` environment
|
|
32
38
|
variable, field `automation_id`.
|
|
33
39
|
|
|
40
|
+
### Upgrading from a single-repository automation
|
|
41
|
+
|
|
42
|
+
Earlier versions stored one document under the bare key `state` (or a filename
|
|
43
|
+
without the repository suffix). On the first poll after an upgrade, that document
|
|
44
|
+
is adopted for the repository named in its own `repo` field, and written back
|
|
45
|
+
under the new per-repository key. Reviews already handled are therefore not
|
|
46
|
+
re-run. A repository that does not match the legacy document simply starts with
|
|
47
|
+
empty state.
|
|
48
|
+
|
|
34
49
|
---
|
|
35
50
|
|
|
36
51
|
## Top-Level Schema
|
|
37
52
|
|
|
38
53
|
```jsonc
|
|
39
54
|
{
|
|
40
|
-
"version":
|
|
55
|
+
"version": 3,
|
|
41
56
|
"repo": "owner/repo",
|
|
42
57
|
"trigger_label": "openhands-review",
|
|
43
58
|
"updated_at": 1717200000.0,
|
|
@@ -65,6 +80,7 @@ Value: **ReviewRecord**
|
|
|
65
80
|
"html_url": "https://github.com/owner/repo/pull/42",
|
|
66
81
|
"status": "active",
|
|
67
82
|
"conversation_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
83
|
+
"workspace_dir": "/workspace/repositories/owner__repo/pr-42-0123456789ab",
|
|
68
84
|
"last_activity": 1717200000.0
|
|
69
85
|
}
|
|
70
86
|
```
|
|
@@ -73,12 +89,28 @@ Value: **ReviewRecord**
|
|
|
73
89
|
|
|
74
90
|
| Status | Meaning |
|
|
75
91
|
|---|---|
|
|
92
|
+
| `starting` | The label event is claimed and the checkout/conversation is being set up. Written and saved before that work begins, so a poll overlapping the claiming one skips this event instead of reviewing the same commit twice. Becomes `active` once the conversation exists, or the record is deleted if setup fails, so the next poll retries. A `starting` record older than `STALLED_CLAIM_SECONDS` (15 min) belongs to a poll that died mid-setup and is released. |
|
|
76
93
|
| `active` | Review conversation is running or waiting to be collected |
|
|
77
|
-
| `closed` | Final result was
|
|
94
|
+
| `closed` | Final result was handled, or the PR closed before collection |
|
|
78
95
|
| `stale` | PR head SHA changed before the review completed, so the result was suppressed |
|
|
96
|
+
| `expired` | Conversation never reached a terminal status within `MAX_ACTIVE_AGE` (2 h) and was abandoned |
|
|
79
97
|
|
|
80
98
|
When a review becomes stale, `stale_reason` records the old and new head SHAs.
|
|
81
99
|
When a review closes after posting, `completed_at` records the completion time.
|
|
100
|
+
When a review expires, `expired_after` records how many seconds it had been
|
|
101
|
+
waiting.
|
|
102
|
+
|
|
103
|
+
### `workspace_dir`
|
|
104
|
+
|
|
105
|
+
The directory holding the reviewed commit, created by the script before the
|
|
106
|
+
conversation starts and used as that conversation's working directory. It is
|
|
107
|
+
removed once the conversation is confirmed stopped, and the key is deleted from
|
|
108
|
+
the record at the same time.
|
|
109
|
+
|
|
110
|
+
The key therefore doubles as the "still on disk" marker: a record carrying a
|
|
111
|
+
`workspace_dir` after it has left `active` is retried on every later poll until
|
|
112
|
+
the removal succeeds. A checkout is never removed while its conversation is
|
|
113
|
+
still running, and never outside `{WORKSPACE_BASE}/repositories/`.
|
|
82
114
|
|
|
83
115
|
---
|
|
84
116
|
|
|
@@ -108,14 +140,29 @@ because the trigger label was absent.
|
|
|
108
140
|
Trigger label applied on GitHub
|
|
109
141
|
|
|
|
110
142
|
v
|
|
111
|
-
[
|
|
143
|
+
[starting] - label event claimed and saved, before any slow work
|
|
144
|
+
|
|
|
145
|
+
+-- setup fails ----------------------------> record deleted, retried next poll
|
|
146
|
+
|
|
|
147
|
+
+-- claiming poll dies mid-setup -----------> released after 15 min
|
|
148
|
+
|
|
|
149
|
+
v
|
|
150
|
+
checkout prepared at head SHA, conversation created
|
|
151
|
+
|
|
|
152
|
+
v
|
|
153
|
+
[active] - acknowledgement comment posted
|
|
112
154
|
|
|
|
113
|
-
+-- PR closes/merges before collection
|
|
155
|
+
+-- PR closes/merges before collection ------> [closed] without posting
|
|
114
156
|
|
|
|
115
|
-
+-- PR head SHA changes before collection
|
|
157
|
+
+-- PR head SHA changes before collection ---> [stale] without posting
|
|
158
|
+
|
|
|
159
|
+
+-- no terminal status within 2 h -----------> [expired] without posting
|
|
160
|
+
|
|
|
161
|
+
v
|
|
162
|
+
[closed] - review confirmed on GitHub, or the agent's text posted as a comment
|
|
116
163
|
|
|
|
117
164
|
v
|
|
118
|
-
|
|
165
|
+
checkout removed once the conversation has stopped
|
|
119
166
|
```
|
|
120
167
|
|
|
121
168
|
---
|
|
@@ -123,18 +170,21 @@ Trigger label applied on GitHub
|
|
|
123
170
|
## Resetting State
|
|
124
171
|
|
|
125
172
|
To force the automation to reconsider previous label events, delete the state
|
|
126
|
-
from the KV store (cloud) or the fallback file (local).
|
|
173
|
+
for that repository from the KV store (cloud) or the fallback file (local).
|
|
127
174
|
|
|
128
175
|
**Cloud (KV store):**
|
|
129
176
|
```bash
|
|
130
|
-
curl -X DELETE "${OPENHANDS_HOST}/api/automation/v1/kv/state" \
|
|
177
|
+
curl -X DELETE "${OPENHANDS_HOST}/api/automation/v1/kv/state:owner__repo" \
|
|
131
178
|
-H "Authorization: Bearer ${AUTOMATION_KV_TOKEN}"
|
|
132
179
|
```
|
|
133
180
|
|
|
134
181
|
**Local (file fallback):**
|
|
135
182
|
```bash
|
|
136
|
-
rm ~/.openhands/workspaces/automation-state/github_pr_reviewer_label_event_<id
|
|
183
|
+
rm ~/.openhands/workspaces/automation-state/github_pr_reviewer_label_event_<id>_owner__repo.json
|
|
137
184
|
```
|
|
138
185
|
|
|
186
|
+
Resetting state also forgets which checkouts are outstanding, so remove any
|
|
187
|
+
leftover directories under `{WORKSPACE_BASE}/repositories/owner__repo/` yourself.
|
|
188
|
+
|
|
139
189
|
Usually, prefer removing and re-applying the trigger label. That preserves
|
|
140
190
|
history while creating a new review request.
|