@openhands/extensions 0.32.0 → 0.32.1
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/automations/bundle-index.js +3 -3
- package/automations/catalog/github-issue-to-pr/manifest.json +2 -2
- package/automations/catalog/github-issue-triage/manifest.json +2 -2
- package/automations/catalog/github-pr-reviewer/manifest.json +2 -2
- package/package.json +1 -1
- package/plugins/vulnerability-remediation/skills/github/scripts/agent_conversation.py +26 -11
- package/pyproject.toml +1 -1
- package/python/openhands_extensions/_version.py +1 -1
- package/skills/github/scripts/agent_conversation.py +26 -11
- package/skills/github-issue-to-pr/scripts/agent_conversation.py +26 -11
- package/skills/github-issue-triage/scripts/agent_conversation.py +26 -11
- package/skills/github-pr-reviewer/scripts/agent_conversation.py +26 -11
- package/tests/fixtures/automations/github-pr-reviewer.json +9 -9
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
100
|
"bundle": {
|
|
101
|
-
"version": "1.2.
|
|
101
|
+
"version": "1.2.4",
|
|
102
102
|
"entrypoint": "python3 worker.py",
|
|
103
103
|
"timeout": 300,
|
|
104
104
|
"files": {
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
},
|
|
118
118
|
"message": "Configure the repositories, labels, branch prefix, pull request mode, agent profile, and schedule."
|
|
119
119
|
},
|
|
120
|
-
"version": "1.2.
|
|
120
|
+
"version": "1.2.3"
|
|
121
121
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "github-issue-triage",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"name": "GitHub issue triage",
|
|
5
5
|
"category": "Project management",
|
|
6
6
|
"description": "Prioritize open issues and establish acceptance criteria before marking them ready for development.",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"bundle": {
|
|
57
|
-
"version": "1.4.
|
|
57
|
+
"version": "1.4.2",
|
|
58
58
|
"entrypoint": "python3 worker.py",
|
|
59
59
|
"timeout": 300,
|
|
60
60
|
"files": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "github-pr-reviewer",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.2",
|
|
4
4
|
"name": "GitHub code review",
|
|
5
5
|
"category": "Code review",
|
|
6
6
|
"description": "Review requested pull-request heads, resume an outstanding reviewer request on a schedule once its checks are green, classify all open non-draft pull requests that nobody requested and review eligible green heads, drain the backlog oldest-first under a small per-scan new-conversation bound, record exact-head decisions, stop early on out-of-scope changes, and optionally request a code-aware human maintainer after approval or a maintainer-decision scope stop only when a successfully fetched same-repository closing issue has priority:medium or priority:high.",
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
}
|
|
136
136
|
},
|
|
137
137
|
"bundle": {
|
|
138
|
-
"version": "1.11.
|
|
138
|
+
"version": "1.11.2",
|
|
139
139
|
"entrypoint": "python3 worker.py",
|
|
140
140
|
"timeout": 300,
|
|
141
141
|
"files": {
|
package/package.json
CHANGED
|
@@ -104,16 +104,16 @@ class CloudConversations:
|
|
|
104
104
|
return found[0] if found else None
|
|
105
105
|
|
|
106
106
|
def start(self, conversation_id, profile_id, title: str, prompt: str) -> None:
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
107
|
+
body = {
|
|
108
|
+
"conversation_id": str(conversation_id),
|
|
109
|
+
"title": title,
|
|
110
|
+
"initial_message": _user_message(prompt),
|
|
111
|
+
}
|
|
112
|
+
if profile_id is not None:
|
|
113
|
+
# Without one the API launches the member's active profile, or the
|
|
114
|
+
# default settings when none is active.
|
|
115
|
+
body["agent_profile_id"] = str(profile_id)
|
|
116
|
+
self._request("POST", "/api/v1/app-conversations", body)
|
|
117
117
|
|
|
118
118
|
def agent_profiles(self) -> list[dict]:
|
|
119
119
|
listing = self._request("GET", "/api/agent-profiles")
|
|
@@ -177,7 +177,10 @@ class AgentConversationDispatcher:
|
|
|
177
177
|
# local Agent Canvas; elsewhere conversations go through the OpenHands API.
|
|
178
178
|
self.agent_url = os.environ.get("AGENT_SERVER_URL")
|
|
179
179
|
self.api_key = os.environ["SESSION_API_KEY"]
|
|
180
|
-
|
|
180
|
+
# The automation service sets the variable only when the automation
|
|
181
|
+
# names an agent profile; a run without one launches the default.
|
|
182
|
+
profile_id = os.environ.get("AUTOMATION_AGENT_PROFILE_ID")
|
|
183
|
+
self.profile_id = UUID(profile_id) if profile_id else None
|
|
181
184
|
payload = json.loads(os.environ["AUTOMATION_EVENT_PAYLOAD"])
|
|
182
185
|
self.automation_id = str(payload["automation_id"])
|
|
183
186
|
self._cloud = None if self.agent_url else CloudConversations()
|
|
@@ -187,6 +190,18 @@ class AgentConversationDispatcher:
|
|
|
187
190
|
def __enter__(self):
|
|
188
191
|
if self._cloud:
|
|
189
192
|
return self
|
|
193
|
+
if self.profile_id is None:
|
|
194
|
+
# The Agent Server starts a conversation from a profile, and always
|
|
195
|
+
# has an active one: its listing seeds `default` when the store is
|
|
196
|
+
# empty.
|
|
197
|
+
listing = self._agent_server_get("/api/agent-profiles")
|
|
198
|
+
active = (listing or {}).get("active_agent_profile_id")
|
|
199
|
+
if not active:
|
|
200
|
+
raise RuntimeError(
|
|
201
|
+
"No agent profile is selected and the Agent Server has "
|
|
202
|
+
"none active"
|
|
203
|
+
)
|
|
204
|
+
self.profile_id = UUID(active)
|
|
190
205
|
_register_tools()
|
|
191
206
|
self._workspace = RemoteWorkspace(
|
|
192
207
|
host=self.agent_url,
|
package/pyproject.toml
CHANGED
|
@@ -18,7 +18,7 @@ from importlib.metadata import PackageNotFoundError, version
|
|
|
18
18
|
#: Kept in lock-step with pyproject.toml/package.json by the version test.
|
|
19
19
|
#: release-please only rewrites a semver found on the annotated line itself, so
|
|
20
20
|
#: the annotation must stay on the assignment; on its own line it is a no-op.
|
|
21
|
-
_FALLBACK_VERSION = "0.32.
|
|
21
|
+
_FALLBACK_VERSION = "0.32.1" # x-release-please-version
|
|
22
22
|
|
|
23
23
|
try:
|
|
24
24
|
__version__: str = version("openhands-extensions")
|
|
@@ -104,16 +104,16 @@ class CloudConversations:
|
|
|
104
104
|
return found[0] if found else None
|
|
105
105
|
|
|
106
106
|
def start(self, conversation_id, profile_id, title: str, prompt: str) -> None:
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
107
|
+
body = {
|
|
108
|
+
"conversation_id": str(conversation_id),
|
|
109
|
+
"title": title,
|
|
110
|
+
"initial_message": _user_message(prompt),
|
|
111
|
+
}
|
|
112
|
+
if profile_id is not None:
|
|
113
|
+
# Without one the API launches the member's active profile, or the
|
|
114
|
+
# default settings when none is active.
|
|
115
|
+
body["agent_profile_id"] = str(profile_id)
|
|
116
|
+
self._request("POST", "/api/v1/app-conversations", body)
|
|
117
117
|
|
|
118
118
|
def agent_profiles(self) -> list[dict]:
|
|
119
119
|
listing = self._request("GET", "/api/agent-profiles")
|
|
@@ -177,7 +177,10 @@ class AgentConversationDispatcher:
|
|
|
177
177
|
# local Agent Canvas; elsewhere conversations go through the OpenHands API.
|
|
178
178
|
self.agent_url = os.environ.get("AGENT_SERVER_URL")
|
|
179
179
|
self.api_key = os.environ["SESSION_API_KEY"]
|
|
180
|
-
|
|
180
|
+
# The automation service sets the variable only when the automation
|
|
181
|
+
# names an agent profile; a run without one launches the default.
|
|
182
|
+
profile_id = os.environ.get("AUTOMATION_AGENT_PROFILE_ID")
|
|
183
|
+
self.profile_id = UUID(profile_id) if profile_id else None
|
|
181
184
|
payload = json.loads(os.environ["AUTOMATION_EVENT_PAYLOAD"])
|
|
182
185
|
self.automation_id = str(payload["automation_id"])
|
|
183
186
|
self._cloud = None if self.agent_url else CloudConversations()
|
|
@@ -187,6 +190,18 @@ class AgentConversationDispatcher:
|
|
|
187
190
|
def __enter__(self):
|
|
188
191
|
if self._cloud:
|
|
189
192
|
return self
|
|
193
|
+
if self.profile_id is None:
|
|
194
|
+
# The Agent Server starts a conversation from a profile, and always
|
|
195
|
+
# has an active one: its listing seeds `default` when the store is
|
|
196
|
+
# empty.
|
|
197
|
+
listing = self._agent_server_get("/api/agent-profiles")
|
|
198
|
+
active = (listing or {}).get("active_agent_profile_id")
|
|
199
|
+
if not active:
|
|
200
|
+
raise RuntimeError(
|
|
201
|
+
"No agent profile is selected and the Agent Server has "
|
|
202
|
+
"none active"
|
|
203
|
+
)
|
|
204
|
+
self.profile_id = UUID(active)
|
|
190
205
|
_register_tools()
|
|
191
206
|
self._workspace = RemoteWorkspace(
|
|
192
207
|
host=self.agent_url,
|
|
@@ -104,16 +104,16 @@ class CloudConversations:
|
|
|
104
104
|
return found[0] if found else None
|
|
105
105
|
|
|
106
106
|
def start(self, conversation_id, profile_id, title: str, prompt: str) -> None:
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
107
|
+
body = {
|
|
108
|
+
"conversation_id": str(conversation_id),
|
|
109
|
+
"title": title,
|
|
110
|
+
"initial_message": _user_message(prompt),
|
|
111
|
+
}
|
|
112
|
+
if profile_id is not None:
|
|
113
|
+
# Without one the API launches the member's active profile, or the
|
|
114
|
+
# default settings when none is active.
|
|
115
|
+
body["agent_profile_id"] = str(profile_id)
|
|
116
|
+
self._request("POST", "/api/v1/app-conversations", body)
|
|
117
117
|
|
|
118
118
|
def agent_profiles(self) -> list[dict]:
|
|
119
119
|
listing = self._request("GET", "/api/agent-profiles")
|
|
@@ -177,7 +177,10 @@ class AgentConversationDispatcher:
|
|
|
177
177
|
# local Agent Canvas; elsewhere conversations go through the OpenHands API.
|
|
178
178
|
self.agent_url = os.environ.get("AGENT_SERVER_URL")
|
|
179
179
|
self.api_key = os.environ["SESSION_API_KEY"]
|
|
180
|
-
|
|
180
|
+
# The automation service sets the variable only when the automation
|
|
181
|
+
# names an agent profile; a run without one launches the default.
|
|
182
|
+
profile_id = os.environ.get("AUTOMATION_AGENT_PROFILE_ID")
|
|
183
|
+
self.profile_id = UUID(profile_id) if profile_id else None
|
|
181
184
|
payload = json.loads(os.environ["AUTOMATION_EVENT_PAYLOAD"])
|
|
182
185
|
self.automation_id = str(payload["automation_id"])
|
|
183
186
|
self._cloud = None if self.agent_url else CloudConversations()
|
|
@@ -187,6 +190,18 @@ class AgentConversationDispatcher:
|
|
|
187
190
|
def __enter__(self):
|
|
188
191
|
if self._cloud:
|
|
189
192
|
return self
|
|
193
|
+
if self.profile_id is None:
|
|
194
|
+
# The Agent Server starts a conversation from a profile, and always
|
|
195
|
+
# has an active one: its listing seeds `default` when the store is
|
|
196
|
+
# empty.
|
|
197
|
+
listing = self._agent_server_get("/api/agent-profiles")
|
|
198
|
+
active = (listing or {}).get("active_agent_profile_id")
|
|
199
|
+
if not active:
|
|
200
|
+
raise RuntimeError(
|
|
201
|
+
"No agent profile is selected and the Agent Server has "
|
|
202
|
+
"none active"
|
|
203
|
+
)
|
|
204
|
+
self.profile_id = UUID(active)
|
|
190
205
|
_register_tools()
|
|
191
206
|
self._workspace = RemoteWorkspace(
|
|
192
207
|
host=self.agent_url,
|
|
@@ -104,16 +104,16 @@ class CloudConversations:
|
|
|
104
104
|
return found[0] if found else None
|
|
105
105
|
|
|
106
106
|
def start(self, conversation_id, profile_id, title: str, prompt: str) -> None:
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
107
|
+
body = {
|
|
108
|
+
"conversation_id": str(conversation_id),
|
|
109
|
+
"title": title,
|
|
110
|
+
"initial_message": _user_message(prompt),
|
|
111
|
+
}
|
|
112
|
+
if profile_id is not None:
|
|
113
|
+
# Without one the API launches the member's active profile, or the
|
|
114
|
+
# default settings when none is active.
|
|
115
|
+
body["agent_profile_id"] = str(profile_id)
|
|
116
|
+
self._request("POST", "/api/v1/app-conversations", body)
|
|
117
117
|
|
|
118
118
|
def agent_profiles(self) -> list[dict]:
|
|
119
119
|
listing = self._request("GET", "/api/agent-profiles")
|
|
@@ -177,7 +177,10 @@ class AgentConversationDispatcher:
|
|
|
177
177
|
# local Agent Canvas; elsewhere conversations go through the OpenHands API.
|
|
178
178
|
self.agent_url = os.environ.get("AGENT_SERVER_URL")
|
|
179
179
|
self.api_key = os.environ["SESSION_API_KEY"]
|
|
180
|
-
|
|
180
|
+
# The automation service sets the variable only when the automation
|
|
181
|
+
# names an agent profile; a run without one launches the default.
|
|
182
|
+
profile_id = os.environ.get("AUTOMATION_AGENT_PROFILE_ID")
|
|
183
|
+
self.profile_id = UUID(profile_id) if profile_id else None
|
|
181
184
|
payload = json.loads(os.environ["AUTOMATION_EVENT_PAYLOAD"])
|
|
182
185
|
self.automation_id = str(payload["automation_id"])
|
|
183
186
|
self._cloud = None if self.agent_url else CloudConversations()
|
|
@@ -187,6 +190,18 @@ class AgentConversationDispatcher:
|
|
|
187
190
|
def __enter__(self):
|
|
188
191
|
if self._cloud:
|
|
189
192
|
return self
|
|
193
|
+
if self.profile_id is None:
|
|
194
|
+
# The Agent Server starts a conversation from a profile, and always
|
|
195
|
+
# has an active one: its listing seeds `default` when the store is
|
|
196
|
+
# empty.
|
|
197
|
+
listing = self._agent_server_get("/api/agent-profiles")
|
|
198
|
+
active = (listing or {}).get("active_agent_profile_id")
|
|
199
|
+
if not active:
|
|
200
|
+
raise RuntimeError(
|
|
201
|
+
"No agent profile is selected and the Agent Server has "
|
|
202
|
+
"none active"
|
|
203
|
+
)
|
|
204
|
+
self.profile_id = UUID(active)
|
|
190
205
|
_register_tools()
|
|
191
206
|
self._workspace = RemoteWorkspace(
|
|
192
207
|
host=self.agent_url,
|
|
@@ -104,16 +104,16 @@ class CloudConversations:
|
|
|
104
104
|
return found[0] if found else None
|
|
105
105
|
|
|
106
106
|
def start(self, conversation_id, profile_id, title: str, prompt: str) -> None:
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
107
|
+
body = {
|
|
108
|
+
"conversation_id": str(conversation_id),
|
|
109
|
+
"title": title,
|
|
110
|
+
"initial_message": _user_message(prompt),
|
|
111
|
+
}
|
|
112
|
+
if profile_id is not None:
|
|
113
|
+
# Without one the API launches the member's active profile, or the
|
|
114
|
+
# default settings when none is active.
|
|
115
|
+
body["agent_profile_id"] = str(profile_id)
|
|
116
|
+
self._request("POST", "/api/v1/app-conversations", body)
|
|
117
117
|
|
|
118
118
|
def agent_profiles(self) -> list[dict]:
|
|
119
119
|
listing = self._request("GET", "/api/agent-profiles")
|
|
@@ -177,7 +177,10 @@ class AgentConversationDispatcher:
|
|
|
177
177
|
# local Agent Canvas; elsewhere conversations go through the OpenHands API.
|
|
178
178
|
self.agent_url = os.environ.get("AGENT_SERVER_URL")
|
|
179
179
|
self.api_key = os.environ["SESSION_API_KEY"]
|
|
180
|
-
|
|
180
|
+
# The automation service sets the variable only when the automation
|
|
181
|
+
# names an agent profile; a run without one launches the default.
|
|
182
|
+
profile_id = os.environ.get("AUTOMATION_AGENT_PROFILE_ID")
|
|
183
|
+
self.profile_id = UUID(profile_id) if profile_id else None
|
|
181
184
|
payload = json.loads(os.environ["AUTOMATION_EVENT_PAYLOAD"])
|
|
182
185
|
self.automation_id = str(payload["automation_id"])
|
|
183
186
|
self._cloud = None if self.agent_url else CloudConversations()
|
|
@@ -187,6 +190,18 @@ class AgentConversationDispatcher:
|
|
|
187
190
|
def __enter__(self):
|
|
188
191
|
if self._cloud:
|
|
189
192
|
return self
|
|
193
|
+
if self.profile_id is None:
|
|
194
|
+
# The Agent Server starts a conversation from a profile, and always
|
|
195
|
+
# has an active one: its listing seeds `default` when the store is
|
|
196
|
+
# empty.
|
|
197
|
+
listing = self._agent_server_get("/api/agent-profiles")
|
|
198
|
+
active = (listing or {}).get("active_agent_profile_id")
|
|
199
|
+
if not active:
|
|
200
|
+
raise RuntimeError(
|
|
201
|
+
"No agent profile is selected and the Agent Server has "
|
|
202
|
+
"none active"
|
|
203
|
+
)
|
|
204
|
+
self.profile_id = UUID(active)
|
|
190
205
|
_register_tools()
|
|
191
206
|
self._workspace = RemoteWorkspace(
|
|
192
207
|
host=self.agent_url,
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"timeout": 300,
|
|
69
69
|
"template": {
|
|
70
70
|
"id": "github-pr-reviewer",
|
|
71
|
-
"version": "1.11.
|
|
71
|
+
"version": "1.11.2",
|
|
72
72
|
"config": {
|
|
73
73
|
"repos": [
|
|
74
74
|
"OpenHands/agent-server-gui"
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"timeout": 300,
|
|
109
109
|
"template": {
|
|
110
110
|
"id": "github-pr-reviewer",
|
|
111
|
-
"version": "1.11.
|
|
111
|
+
"version": "1.11.2",
|
|
112
112
|
"config": {
|
|
113
113
|
"repos": [
|
|
114
114
|
"OpenHands/agent-server-gui"
|
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
"timeout": 300,
|
|
214
214
|
"template": {
|
|
215
215
|
"id": "github-pr-reviewer",
|
|
216
|
-
"version": "1.11.
|
|
216
|
+
"version": "1.11.2",
|
|
217
217
|
"config": {
|
|
218
218
|
"repos": [
|
|
219
219
|
"OpenHands/agent-server-gui",
|
|
@@ -254,7 +254,7 @@
|
|
|
254
254
|
"timeout": 300,
|
|
255
255
|
"template": {
|
|
256
256
|
"id": "github-pr-reviewer",
|
|
257
|
-
"version": "1.11.
|
|
257
|
+
"version": "1.11.2",
|
|
258
258
|
"config": {
|
|
259
259
|
"repos": [
|
|
260
260
|
"OpenHands/agent-server-gui",
|
|
@@ -296,7 +296,7 @@
|
|
|
296
296
|
"preset_metadata": {
|
|
297
297
|
"template": {
|
|
298
298
|
"id": "github-pr-reviewer",
|
|
299
|
-
"version": "1.11.
|
|
299
|
+
"version": "1.11.2",
|
|
300
300
|
"config": {
|
|
301
301
|
"repos": [
|
|
302
302
|
"OpenHands/agent-server-gui",
|
|
@@ -351,7 +351,7 @@
|
|
|
351
351
|
"timeout": 300,
|
|
352
352
|
"template": {
|
|
353
353
|
"id": "github-pr-reviewer",
|
|
354
|
-
"version": "1.11.
|
|
354
|
+
"version": "1.11.2",
|
|
355
355
|
"config": {
|
|
356
356
|
"repos": [
|
|
357
357
|
"OpenHands/agent-server-gui"
|
|
@@ -444,7 +444,7 @@
|
|
|
444
444
|
"timeout": 300,
|
|
445
445
|
"template": {
|
|
446
446
|
"id": "github-pr-reviewer",
|
|
447
|
-
"version": "1.11.
|
|
447
|
+
"version": "1.11.2",
|
|
448
448
|
"config": {
|
|
449
449
|
"repos": [
|
|
450
450
|
"OpenHands/agent-server-gui"
|
|
@@ -540,7 +540,7 @@
|
|
|
540
540
|
"timeout": 300,
|
|
541
541
|
"template": {
|
|
542
542
|
"id": "github-pr-reviewer",
|
|
543
|
-
"version": "1.11.
|
|
543
|
+
"version": "1.11.2",
|
|
544
544
|
"config": {
|
|
545
545
|
"repos": [
|
|
546
546
|
"OpenHands/agent-server-gui"
|
|
@@ -616,7 +616,7 @@
|
|
|
616
616
|
"timeout": 300,
|
|
617
617
|
"template": {
|
|
618
618
|
"id": "github-pr-reviewer",
|
|
619
|
-
"version": "1.11.
|
|
619
|
+
"version": "1.11.2",
|
|
620
620
|
"config": {
|
|
621
621
|
"repos": [
|
|
622
622
|
"OpenHands/automation"
|