openhands-agent-server 1.25.0__tar.gz → 1.26.0__tar.gz
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.
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/PKG-INFO +1 -1
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/mcp_router.py +142 -12
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/skills_service.py +3 -3
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands_agent_server.egg-info/PKG-INFO +1 -1
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/pyproject.toml +1 -1
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/__init__.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/__main__.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/_secrets_exposure.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/api.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/auth_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/bash_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/bash_service.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/cloud_proxy_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/config.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/conversation_lease.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/conversation_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/conversation_router_acp.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/conversation_service.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/dependencies.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/desktop_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/desktop_service.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/docker/Dockerfile +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/docker/build.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/docker/wallpaper.svg +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/env_parser.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/event_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/event_service.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/file_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/git_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/hooks_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/hooks_service.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/llm_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/logging_config.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/middleware.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/models.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/openapi.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/persistence/__init__.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/persistence/models.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/persistence/store.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/profiles_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/pub_sub.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/py.typed +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/server_details_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/settings_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/skills_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/sockets.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/tool_preload_service.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/tool_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/utils.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/vscode_extensions/openhands-settings/extension.js +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/vscode_extensions/openhands-settings/package.json +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/vscode_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/vscode_service.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/workspace_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/workspaces_router.py +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands_agent_server.egg-info/SOURCES.txt +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands_agent_server.egg-info/dependency_links.txt +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands_agent_server.egg-info/entry_points.txt +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands_agent_server.egg-info/requires.txt +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands_agent_server.egg-info/top_level.txt +0 -0
- {openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openhands-agent-server
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.26.0
|
|
4
4
|
Summary: OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent
|
|
5
5
|
Project-URL: Source, https://github.com/OpenHands/software-agent-sdk
|
|
6
6
|
Project-URL: Homepage, https://github.com/OpenHands/software-agent-sdk
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/mcp_router.py
RENAMED
|
@@ -6,9 +6,12 @@ to settings, where a misconfiguration would otherwise surface only at
|
|
|
6
6
|
conversation start (and there manifest as a noisy traceback that aborts
|
|
7
7
|
agent initialization).
|
|
8
8
|
|
|
9
|
-
The endpoint
|
|
10
|
-
connection, lists the advertised tools,
|
|
11
|
-
|
|
9
|
+
The endpoint never mutates server state or touches stored settings: it
|
|
10
|
+
spins up the MCP connection, lists the advertised tools, optionally invokes
|
|
11
|
+
one caller-chosen tool (``tool_call``), then tears the connection down.
|
|
12
|
+
The optional tool call exists because listing tools does not exercise the
|
|
13
|
+
credentials many servers only use inside tool handlers (e.g. the Slack MCP
|
|
14
|
+
server starts fine with a bogus token); callers must pick a read-only tool.
|
|
12
15
|
"""
|
|
13
16
|
|
|
14
17
|
from __future__ import annotations
|
|
@@ -16,12 +19,16 @@ from __future__ import annotations
|
|
|
16
19
|
import asyncio
|
|
17
20
|
from typing import Annotated, Any, Literal
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
import mcp.types
|
|
23
|
+
from fastapi import APIRouter, Request
|
|
20
24
|
from pydantic import BaseModel, Field, model_validator
|
|
21
25
|
|
|
26
|
+
from openhands.agent_server._secrets_exposure import get_cipher
|
|
22
27
|
from openhands.sdk.logger import get_logger
|
|
23
28
|
from openhands.sdk.mcp import create_mcp_tools
|
|
24
29
|
from openhands.sdk.mcp.exceptions import MCPError, MCPTimeoutError
|
|
30
|
+
from openhands.sdk.utils.cipher import Cipher
|
|
31
|
+
from openhands.sdk.utils.pydantic_secrets import decrypt_str_with_cipher_or_keep
|
|
25
32
|
|
|
26
33
|
|
|
27
34
|
logger = get_logger(__name__)
|
|
@@ -85,6 +92,22 @@ class _RemoteMCPServerSpec(BaseModel):
|
|
|
85
92
|
return out
|
|
86
93
|
|
|
87
94
|
|
|
95
|
+
class MCPToolCallSpec(BaseModel):
|
|
96
|
+
"""A single tool invocation to run as part of the connection test.
|
|
97
|
+
|
|
98
|
+
Listing tools does not exercise the credentials many servers only use
|
|
99
|
+
inside tool handlers, so callers can name one tool to invoke after the
|
|
100
|
+
listing succeeds. Callers are responsible for choosing a read-only tool;
|
|
101
|
+
the endpoint executes it verbatim.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
name: str = Field(..., min_length=1, description="Name of the tool to invoke")
|
|
105
|
+
arguments: dict[str, Any] = Field(
|
|
106
|
+
default_factory=dict,
|
|
107
|
+
description="Arguments passed to the tool unchanged.",
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
88
111
|
class MCPTestRequest(BaseModel):
|
|
89
112
|
"""Body for ``POST /api/mcp/test``."""
|
|
90
113
|
|
|
@@ -108,6 +131,15 @@ class MCPTestRequest(BaseModel):
|
|
|
108
131
|
le=120,
|
|
109
132
|
description="Seconds to wait for connection + tools/list to complete.",
|
|
110
133
|
)
|
|
134
|
+
tool_call: MCPToolCallSpec | None = Field(
|
|
135
|
+
default=None,
|
|
136
|
+
description=(
|
|
137
|
+
"Optional read-only tool to invoke after listing succeeds, so "
|
|
138
|
+
"callers can verify credentials the server only exercises on "
|
|
139
|
+
"tool invocation. Its outcome is reported verbatim in "
|
|
140
|
+
"`tool_result` without affecting `ok`."
|
|
141
|
+
),
|
|
142
|
+
)
|
|
111
143
|
|
|
112
144
|
@model_validator(mode="after")
|
|
113
145
|
def _strip_name(self) -> MCPTestRequest:
|
|
@@ -117,6 +149,19 @@ class MCPTestRequest(BaseModel):
|
|
|
117
149
|
return self
|
|
118
150
|
|
|
119
151
|
|
|
152
|
+
class MCPToolCallResult(BaseModel):
|
|
153
|
+
"""Verbatim outcome of the requested ``tool_call``.
|
|
154
|
+
|
|
155
|
+
The endpoint stays provider-neutral: many servers report upstream
|
|
156
|
+
failures (e.g. Slack's ``{"ok": false, "error": "invalid_auth"}``)
|
|
157
|
+
as ordinary text content with ``isError`` unset, so interpreting the
|
|
158
|
+
payload is the caller's job.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
is_error: bool = Field(description="The MCP-level isError flag of the result.")
|
|
162
|
+
text: str = Field(description="Concatenated text content of the result.")
|
|
163
|
+
|
|
164
|
+
|
|
120
165
|
class MCPTestSuccess(BaseModel):
|
|
121
166
|
"""Response when the candidate server connects and lists its tools."""
|
|
122
167
|
|
|
@@ -125,6 +170,10 @@ class MCPTestSuccess(BaseModel):
|
|
|
125
170
|
default_factory=list,
|
|
126
171
|
description="Names of tools advertised by the MCP server.",
|
|
127
172
|
)
|
|
173
|
+
tool_result: MCPToolCallResult | None = Field(
|
|
174
|
+
default=None,
|
|
175
|
+
description=("Outcome of the requested `tool_call`, when one was supplied."),
|
|
176
|
+
)
|
|
128
177
|
|
|
129
178
|
|
|
130
179
|
class MCPTestFailure(BaseModel):
|
|
@@ -151,18 +200,81 @@ MCPTestResponse = MCPTestSuccess | MCPTestFailure
|
|
|
151
200
|
# ---------------------------------------------------------------------------
|
|
152
201
|
|
|
153
202
|
|
|
154
|
-
def
|
|
203
|
+
def _decrypt_mapping(cipher: Cipher | None, mapping: dict[str, str]) -> dict[str, str]:
|
|
204
|
+
"""Decrypt Fernet-encrypted values round-tripped from settings.
|
|
205
|
+
|
|
206
|
+
The GUI fetches stored settings with ``X-Expose-Secrets: encrypted`` and
|
|
207
|
+
forwards the ciphertext unchanged so the edit flow can test the *real*
|
|
208
|
+
stored credentials without ever seeing them. Plaintext values (the
|
|
209
|
+
common case: freshly typed input) pass through untouched.
|
|
210
|
+
"""
|
|
211
|
+
if cipher is None:
|
|
212
|
+
return dict(mapping)
|
|
213
|
+
return {
|
|
214
|
+
key: decrypt_str_with_cipher_or_keep(
|
|
215
|
+
cipher, value, description="MCP test env/headers"
|
|
216
|
+
)
|
|
217
|
+
for key, value in mapping.items()
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def _server_to_fastmcp_dict(
|
|
222
|
+
spec: _StdioMCPServerSpec | _RemoteMCPServerSpec, cipher: Cipher | None
|
|
223
|
+
) -> dict:
|
|
155
224
|
if isinstance(spec, _StdioMCPServerSpec):
|
|
156
225
|
out: dict[str, Any] = {"command": spec.command, "args": list(spec.args)}
|
|
157
226
|
if spec.env:
|
|
158
|
-
out["env"] =
|
|
227
|
+
out["env"] = _decrypt_mapping(cipher, spec.env)
|
|
159
228
|
if spec.cwd:
|
|
160
229
|
out["cwd"] = spec.cwd
|
|
161
230
|
return out
|
|
162
|
-
|
|
231
|
+
remote = spec.to_fastmcp_dict()
|
|
232
|
+
if "headers" in remote:
|
|
233
|
+
remote["headers"] = _decrypt_mapping(cipher, remote["headers"])
|
|
234
|
+
return remote
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _run_tool_call(
|
|
238
|
+
client: Any, spec: MCPToolCallSpec, tool_names: list[str], timeout: float
|
|
239
|
+
) -> MCPToolCallResult:
|
|
240
|
+
"""Invoke the requested tool on the connected client.
|
|
241
|
+
|
|
242
|
+
Uses ``call_tool_mcp`` (not ``call_tool``, which raises on ``isError``)
|
|
243
|
+
so in-band failures come back as data -- mirrors ``MCPToolExecutor``.
|
|
244
|
+
A timeout is reported as an errored result rather than failing the
|
|
245
|
+
whole test: the server did connect and list, which is still useful.
|
|
246
|
+
"""
|
|
247
|
+
if spec.name not in tool_names:
|
|
248
|
+
return MCPToolCallResult(
|
|
249
|
+
is_error=True,
|
|
250
|
+
text=(
|
|
251
|
+
f"Tool {spec.name!r} not advertised by server "
|
|
252
|
+
f"(available: {', '.join(tool_names) or 'none'})"
|
|
253
|
+
),
|
|
254
|
+
)
|
|
255
|
+
try:
|
|
256
|
+
result: mcp.types.CallToolResult = client.call_async_from_sync(
|
|
257
|
+
client.call_tool_mcp,
|
|
258
|
+
name=spec.name,
|
|
259
|
+
arguments=spec.arguments,
|
|
260
|
+
timeout=timeout,
|
|
261
|
+
)
|
|
262
|
+
except TimeoutError:
|
|
263
|
+
return MCPToolCallResult(
|
|
264
|
+
is_error=True,
|
|
265
|
+
text=f"Tool {spec.name!r} call timed out after {timeout} seconds",
|
|
266
|
+
)
|
|
267
|
+
text = "\n".join(
|
|
268
|
+
block.text
|
|
269
|
+
for block in result.content
|
|
270
|
+
if isinstance(block, mcp.types.TextContent)
|
|
271
|
+
)
|
|
272
|
+
return MCPToolCallResult(is_error=bool(result.isError), text=text)
|
|
163
273
|
|
|
164
274
|
|
|
165
|
-
def _probe_mcp_server(
|
|
275
|
+
def _probe_mcp_server(
|
|
276
|
+
request: MCPTestRequest, cipher: Cipher | None
|
|
277
|
+
) -> MCPTestResponse:
|
|
166
278
|
"""Synchronous probe -- safe to run inside ``run_in_executor``.
|
|
167
279
|
|
|
168
280
|
``create_mcp_tools`` already runs its own event loop in a background
|
|
@@ -171,14 +283,22 @@ def _probe_mcp_server(request: MCPTestRequest) -> MCPTestResponse:
|
|
|
171
283
|
threadpool first.
|
|
172
284
|
"""
|
|
173
285
|
|
|
174
|
-
config = {
|
|
286
|
+
config = {
|
|
287
|
+
"mcpServers": {request.name: _server_to_fastmcp_dict(request.server, cipher)}
|
|
288
|
+
}
|
|
175
289
|
|
|
176
290
|
try:
|
|
177
291
|
# ``create_mcp_tools`` returns a client that owns a background loop
|
|
178
292
|
# and a (possibly long-lived) subprocess. Use the context-manager
|
|
179
293
|
# form so we always tear it down, even when listing succeeded.
|
|
180
294
|
with create_mcp_tools(config, timeout=request.timeout) as client:
|
|
181
|
-
|
|
295
|
+
tool_names = [tool.name for tool in client.tools]
|
|
296
|
+
tool_result: MCPToolCallResult | None = None
|
|
297
|
+
if request.tool_call is not None:
|
|
298
|
+
tool_result = _run_tool_call(
|
|
299
|
+
client, request.tool_call, tool_names, request.timeout
|
|
300
|
+
)
|
|
301
|
+
return MCPTestSuccess(tools=tool_names, tool_result=tool_result)
|
|
182
302
|
except MCPTimeoutError as exc:
|
|
183
303
|
logger.info("MCP test timed out for server %r: %s", request.name, exc)
|
|
184
304
|
return MCPTestFailure(error=str(exc), error_kind="timeout")
|
|
@@ -215,11 +335,21 @@ def _probe_mcp_server(request: MCPTestRequest) -> MCPTestResponse:
|
|
|
215
335
|
"Attempt to connect to a candidate MCP server and list its tools, "
|
|
216
336
|
"without persisting any settings. Useful for validating user input "
|
|
217
337
|
"in 'add MCP server' flows before storing the config. "
|
|
338
|
+
"Optionally invokes one caller-chosen (read-only) tool via "
|
|
339
|
+
"`tool_call` and reports its outcome in `tool_result`, so callers "
|
|
340
|
+
"can verify credentials that are only exercised on tool invocation. "
|
|
341
|
+
"Encrypted `env`/`headers` values round-tripped from settings are "
|
|
342
|
+
"decrypted before the connection is attempted. "
|
|
218
343
|
"Returns 200 with `ok=false` for connection / timeout failures "
|
|
219
344
|
"(those are expected during validation, not server errors)."
|
|
220
345
|
),
|
|
221
346
|
)
|
|
222
|
-
async def test_mcp_server(
|
|
347
|
+
async def test_mcp_server(
|
|
348
|
+
request: MCPTestRequest, http_request: Request
|
|
349
|
+
) -> MCPTestResponse:
|
|
223
350
|
"""Probe a single MCP server config and report whether it works."""
|
|
351
|
+
# Resolve the cipher here: the threadpool function below must not
|
|
352
|
+
# reach back into ``http_request.app.state``.
|
|
353
|
+
cipher = get_cipher(http_request)
|
|
224
354
|
loop = asyncio.get_running_loop()
|
|
225
|
-
return await loop.run_in_executor(None, _probe_mcp_server, request)
|
|
355
|
+
return await loop.run_in_executor(None, _probe_mcp_server, request, cipher)
|
|
@@ -40,7 +40,7 @@ from openhands.sdk.skills import (
|
|
|
40
40
|
)
|
|
41
41
|
from openhands.sdk.skills.skill import (
|
|
42
42
|
DEFAULT_MARKETPLACE_PATH,
|
|
43
|
-
|
|
43
|
+
PUBLIC_SKILLS_REF,
|
|
44
44
|
PUBLIC_SKILLS_REPO,
|
|
45
45
|
_invalidate_public_skills_cache,
|
|
46
46
|
load_skills_from_dir,
|
|
@@ -391,7 +391,7 @@ def sync_public_skills() -> tuple[bool, str]:
|
|
|
391
391
|
try:
|
|
392
392
|
cache_dir = get_skills_cache_dir()
|
|
393
393
|
result = update_skills_repository(
|
|
394
|
-
PUBLIC_SKILLS_REPO,
|
|
394
|
+
PUBLIC_SKILLS_REPO, PUBLIC_SKILLS_REF, cache_dir
|
|
395
395
|
)
|
|
396
396
|
|
|
397
397
|
if result:
|
|
@@ -634,7 +634,7 @@ def _fetch_catalog_entries(marketplace_path: str) -> list[_CatalogEntry]:
|
|
|
634
634
|
"""
|
|
635
635
|
cache_dir = get_skills_cache_dir()
|
|
636
636
|
repo_path = update_skills_repository(
|
|
637
|
-
PUBLIC_SKILLS_REPO,
|
|
637
|
+
PUBLIC_SKILLS_REPO, PUBLIC_SKILLS_REF, cache_dir
|
|
638
638
|
)
|
|
639
639
|
|
|
640
640
|
if repo_path is None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openhands-agent-server
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.26.0
|
|
4
4
|
Summary: OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent
|
|
5
5
|
Project-URL: Source, https://github.com/OpenHands/software-agent-sdk
|
|
6
6
|
Project-URL: Homepage, https://github.com/OpenHands/software-agent-sdk
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/__init__.py
RENAMED
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/env_parser.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/git_router.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/llm_router.py
RENAMED
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/middleware.py
RENAMED
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/models.py
RENAMED
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/openapi.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/pub_sub.py
RENAMED
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/sockets.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhands_agent_server-1.25.0 → openhands_agent_server-1.26.0}/openhands/agent_server/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|