openhands-agent-server 1.10.0__tar.gz → 1.11.1__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.
Files changed (45) hide show
  1. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/PKG-INFO +1 -1
  2. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/__main__.py +50 -0
  3. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/bash_router.py +9 -0
  4. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/bash_service.py +6 -0
  5. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/conversation_service.py +10 -2
  6. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/docker/Dockerfile +2 -0
  7. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/docker/build.py +4 -0
  8. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands_agent_server.egg-info/PKG-INFO +1 -1
  9. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/pyproject.toml +1 -1
  10. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/__init__.py +0 -0
  11. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/api.py +0 -0
  12. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/config.py +0 -0
  13. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/conversation_router.py +0 -0
  14. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/dependencies.py +0 -0
  15. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/desktop_router.py +0 -0
  16. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/desktop_service.py +0 -0
  17. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/docker/wallpaper.svg +0 -0
  18. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/env_parser.py +0 -0
  19. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/event_router.py +0 -0
  20. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/event_service.py +0 -0
  21. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/file_router.py +0 -0
  22. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/git_router.py +0 -0
  23. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/logging_config.py +0 -0
  24. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/middleware.py +0 -0
  25. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/models.py +0 -0
  26. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/openapi.py +0 -0
  27. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/pub_sub.py +0 -0
  28. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/py.typed +0 -0
  29. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/server_details_router.py +0 -0
  30. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/skills_router.py +0 -0
  31. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/skills_service.py +0 -0
  32. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/sockets.py +0 -0
  33. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/tool_preload_service.py +0 -0
  34. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/tool_router.py +0 -0
  35. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/utils.py +0 -0
  36. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/vscode_extensions/openhands-settings/extension.js +0 -0
  37. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/vscode_extensions/openhands-settings/package.json +0 -0
  38. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/vscode_router.py +0 -0
  39. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands/agent_server/vscode_service.py +0 -0
  40. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands_agent_server.egg-info/SOURCES.txt +0 -0
  41. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands_agent_server.egg-info/dependency_links.txt +0 -0
  42. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands_agent_server.egg-info/entry_points.txt +0 -0
  43. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands_agent_server.egg-info/requires.txt +0 -0
  44. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/openhands_agent_server.egg-info/top_level.txt +0 -0
  45. {openhands_agent_server-1.10.0 → openhands_agent_server-1.11.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhands-agent-server
3
- Version: 1.10.0
3
+ Version: 1.11.1
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
@@ -2,6 +2,7 @@ import argparse
2
2
  import atexit
3
3
  import faulthandler
4
4
  import signal
5
+ import sys
5
6
  from types import FrameType
6
7
 
7
8
  import uvicorn
@@ -14,6 +15,43 @@ from openhands.sdk.logger import DEBUG, get_logger
14
15
  logger = get_logger(__name__)
15
16
 
16
17
 
18
+ def check_browser():
19
+ """Check if browser functionality can render about:blank."""
20
+ executor = None
21
+ try:
22
+ # Register tools to ensure browser tools are available
23
+ from openhands.tools.preset.default import register_default_tools
24
+
25
+ register_default_tools(enable_browser=True)
26
+
27
+ # Import browser components
28
+ from openhands.tools.browser_use.definition import BrowserNavigateAction
29
+ from openhands.tools.browser_use.impl import BrowserToolExecutor
30
+
31
+ # Create executor
32
+ executor = BrowserToolExecutor(headless=True, session_timeout_minutes=2)
33
+
34
+ # Try to navigate to about:blank
35
+ action = BrowserNavigateAction(url="about:blank")
36
+ result = executor(action)
37
+
38
+ # Check if the operation was successful
39
+ if result.is_error:
40
+ print(f"Browser check failed: {str(result.content)}")
41
+ return False
42
+
43
+ print("Browser check passed: Successfully rendered about:blank")
44
+ return True
45
+
46
+ except Exception as e:
47
+ print(f"Browser check failed: {e}")
48
+ return False
49
+ finally:
50
+ # Ensure cleanup happens even if an error occurs
51
+ if executor is not None:
52
+ executor.close()
53
+
54
+
17
55
  class LoggingServer(uvicorn.Server):
18
56
  """Custom uvicorn Server that logs signal handling events.
19
57
 
@@ -67,9 +105,21 @@ def main() -> None:
67
105
  action="store_true",
68
106
  help="Enable auto-reload (disabled by default)",
69
107
  )
108
+ parser.add_argument(
109
+ "--check-browser",
110
+ action="store_true",
111
+ help="Check if browser functionality works and exit",
112
+ )
70
113
 
71
114
  args = parser.parse_args()
72
115
 
116
+ # Handle browser check
117
+ if args.check_browser:
118
+ if check_browser():
119
+ sys.exit(0)
120
+ else:
121
+ sys.exit(1)
122
+
73
123
  print(f"🙌 Starting OpenHands Agent Server on {args.host}:{args.port}")
74
124
  print(f"📖 API docs will be available at http://{args.host}:{args.port}/docs")
75
125
  print(f"🔄 Auto-reload: {'enabled' if args.reload else 'disabled'}")
@@ -36,6 +36,14 @@ async def search_bash_events(
36
36
  command_id__eq: UUID | None = None,
37
37
  timestamp__gte: datetime | None = None,
38
38
  timestamp__lt: datetime | None = None,
39
+ order__gt: Annotated[
40
+ int | None,
41
+ Query(
42
+ title="Filter to events with order greater than this value",
43
+ description="Only returns BashOutput events with order > this value. "
44
+ "Useful for polling to fetch only new events since the last poll.",
45
+ ),
46
+ ] = None,
39
47
  sort_order: BashEventSortOrder = BashEventSortOrder.TIMESTAMP,
40
48
  page_id: Annotated[
41
49
  str | None,
@@ -55,6 +63,7 @@ async def search_bash_events(
55
63
  command_id__eq=command_id__eq,
56
64
  timestamp__gte=timestamp__gte,
57
65
  timestamp__lt=timestamp__lt,
66
+ order__gt=order__gt,
58
67
  sort_order=sort_order,
59
68
  page_id=page_id,
60
69
  limit=limit,
@@ -104,6 +104,7 @@ class BashEventService:
104
104
  command_id__eq: UUID | None = None,
105
105
  timestamp__gte: datetime | None = None,
106
106
  timestamp__lt: datetime | None = None,
107
+ order__gt: int | None = None,
107
108
  sort_order: BashEventSortOrder = BashEventSortOrder.TIMESTAMP,
108
109
  page_id: str | None = None,
109
110
  limit: int = 100,
@@ -168,6 +169,11 @@ class BashEventService:
168
169
  for file_path in page_files:
169
170
  event = self._load_event_from_file(file_path)
170
171
  if event is not None:
172
+ # Filter by order if specified (only applies to BashOutput events)
173
+ if order__gt is not None:
174
+ event_order = getattr(event, "order", None)
175
+ if event_order is not None and event_order <= order__gt:
176
+ continue
171
177
  page_events.append(event)
172
178
 
173
179
  return BashEventPage(items=page_events, next_page_id=next_page_id)
@@ -34,8 +34,11 @@ logger = logging.getLogger(__name__)
34
34
  def _compose_conversation_info(
35
35
  stored: StoredConversation, state: ConversationState
36
36
  ) -> ConversationInfo:
37
+ # Use mode='json' so SecretStr in nested structures (e.g. LookupSecret.headers,
38
+ # agent.agent_context.secrets) serialize to strings. Without it, validation
39
+ # fails because ConversationInfo expects dict[str, str] but receives SecretStr.
37
40
  return ConversationInfo(
38
- **state.model_dump(),
41
+ **state.model_dump(mode="json"),
39
42
  title=stored.title,
40
43
  metrics=stored.metrics,
41
44
  created_at=stored.created_at,
@@ -241,9 +244,14 @@ class ConversationService:
241
244
  # 1. Fetch and load plugins on first run()/send_message()
242
245
  # 2. Resolve refs to commit SHAs for deterministic resume
243
246
  # 3. Merge plugin skills/MCP/hooks into the agent
247
+ #
248
+ # Use mode='json' so SecretStr in nested structures (e.g. LookupSecret.headers)
249
+ # serialize to plain strings. Pass expose_secrets=True so StaticSecret values
250
+ # are preserved through the round-trip; the dict is only used in-process to
251
+ # construct StoredConversation, not sent over the network.
244
252
  stored = StoredConversation(
245
253
  id=conversation_id,
246
- **request.model_dump(),
254
+ **request.model_dump(mode="json", context={"expose_secrets": True}),
247
255
  )
248
256
  event_service = await self._start_event_service(stored)
249
257
  initial_message = request.initial_message
@@ -1,5 +1,7 @@
1
1
  # syntax=docker/dockerfile:1.7
2
2
 
3
+ # NOTE: Using Python 3.12 due to PyInstaller+libtmux compatibility issue
4
+ # with Python 3.13. See issue #1886 for details.
3
5
  ARG BASE_IMAGE=nikolaik/python-nodejs:python3.12-nodejs22
4
6
  ARG USERNAME=openhands
5
7
  ARG UID=10001
@@ -333,6 +333,8 @@ _DEFAULT_PACKAGE_VERSION = _package_version()
333
333
 
334
334
 
335
335
  class BuildOptions(BaseModel):
336
+ # NOTE: Using Python 3.12 due to PyInstaller+libtmux compatibility issue
337
+ # with Python 3.13. See issue #1886 for details.
336
338
  base_image: str = Field(default="nikolaik/python-nodejs:python3.12-nodejs22")
337
339
  custom_tags: str = Field(
338
340
  default="", description="Comma-separated list of custom tags."
@@ -662,6 +664,8 @@ def main(argv: list[str]) -> int:
662
664
  )
663
665
  parser.add_argument(
664
666
  "--base-image",
667
+ # NOTE: Using Python 3.12 due to PyInstaller+libtmux compatibility issue
668
+ # with Python 3.13. See issue #1886.
665
669
  default=_env("BASE_IMAGE", "nikolaik/python-nodejs:python3.12-nodejs22"),
666
670
  help="Base image to use (default from $BASE_IMAGE).",
667
671
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhands-agent-server
3
- Version: 1.10.0
3
+ Version: 1.11.1
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openhands-agent-server"
3
- version = "1.10.0"
3
+ version = "1.11.1"
4
4
  description = "OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent"
5
5
 
6
6
  requires-python = ">=3.12"