diff --git a/openhands-cli/openhands_cli/agent_chat.py b/openhands-cli/openhands_cli/agent_chat.py
index 1782463502..1e08f0ff16 100644
--- a/openhands-cli/openhands_cli/agent_chat.py
+++ b/openhands-cli/openhands_cli/agent_chat.py
@@ -8,7 +8,6 @@ import sys
from datetime import datetime
from openhands.sdk import (
- BaseConversation,
Message,
TextContent,
)
@@ -17,7 +16,7 @@ from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import HTML
from openhands_cli.runner import ConversationRunner
-from openhands_cli.setup import MissingAgentSpec, setup_conversation
+from openhands_cli.setup import MissingAgentSpec, setup_conversation, start_fresh_conversation
from openhands_cli.tui.settings.mcp_screen import MCPScreen
from openhands_cli.tui.settings.settings_screen import SettingsScreen
from openhands_cli.tui.status import display_status
@@ -29,32 +28,6 @@ from openhands_cli.user_actions import UserConfirmation, exit_session_confirmati
from openhands_cli.user_actions.utils import get_session_prompter
-def _start_fresh_conversation(resume_conversation_id: str | None = None) -> BaseConversation:
- """Start a fresh conversation by creating a new conversation instance.
-
- Handles the complete conversation setup process including settings screen
- if agent configuration is missing.
-
- Args:
- resume_conversation_id: Optional conversation ID to resume
-
- Returns:
- BaseConversation: A new conversation instance
- """
- conversation = None
- settings_screen = SettingsScreen()
- try:
- conversation = setup_conversation(resume_conversation_id)
- return conversation
- except MissingAgentSpec:
- # For first-time users, show the full settings flow with choice between basic/advanced
- settings_screen.configure_settings(first_time=True)
-
-
- # Try once again after settings setup attempt
- return setup_conversation(resume_conversation_id)
-
-
def _restore_tty() -> None:
"""
Ensure terminal modes are reset in case prompt_toolkit cleanup didn't run.
@@ -92,7 +65,7 @@ def run_cli_entry(resume_conversation_id: str | None = None) -> None:
"""
try:
- conversation = _start_fresh_conversation(resume_conversation_id)
+ conversation = start_fresh_conversation(resume_conversation_id)
except MissingAgentSpec:
print_formatted_text(HTML('\nSetup is required to use OpenHands CLI.'))
print_formatted_text(HTML('\nGoodbye! 👋'))
@@ -152,7 +125,7 @@ def run_cli_entry(resume_conversation_id: str | None = None) -> None:
elif command == '/new':
try:
# Start a fresh conversation (no resume ID = new conversation)
- conversation = _start_fresh_conversation()
+ conversation = setup_conversation()
runner = ConversationRunner(conversation)
display_welcome(conversation.id, resume=False)
print_formatted_text(
@@ -176,7 +149,7 @@ def run_cli_entry(resume_conversation_id: str | None = None) -> None:
elif command == '/confirm':
runner.toggle_confirmation_mode()
new_status = (
- 'enabled' if runner.is_confirmation_mode_enabled else 'disabled'
+ 'enabled' if runner.is_confirmation_mode_active else 'disabled'
)
print_formatted_text(
HTML(f'Confirmation mode {new_status}')
diff --git a/openhands-cli/openhands_cli/runner.py b/openhands-cli/openhands_cli/runner.py
index d61f70af54..816c3f4c2e 100644
--- a/openhands-cli/openhands_cli/runner.py
+++ b/openhands-cli/openhands_cli/runner.py
@@ -11,6 +11,7 @@ from openhands.sdk.security.confirmation_policy import (
from openhands_cli.listeners.pause_listener import PauseListener, pause_listener
from openhands_cli.user_actions import ask_user_confirmation
from openhands_cli.user_actions.types import UserConfirmation
+from openhands_cli.setup import setup_conversation
class ConversationRunner:
@@ -20,20 +21,30 @@ class ConversationRunner:
self.conversation = conversation
@property
- def is_confirmation_mode_enabled(self):
- return self.conversation.confirmation_policy_active
+ def is_confirmation_mode_active(self):
+ return self.conversation.is_confirmation_mode_active
def toggle_confirmation_mode(self):
- if self.is_confirmation_mode_enabled:
- self.set_confirmation_policy(NeverConfirm())
- else:
+ new_confirmation_mode_state = not self.is_confirmation_mode_active
+
+ self.conversation = setup_conversation(
+ self.conversation.id,
+ include_security_analyzer=new_confirmation_mode_state
+ )
+
+ if new_confirmation_mode_state:
+ # Enable confirmation mode: set AlwaysConfirm policy
self.set_confirmation_policy(AlwaysConfirm())
+ else:
+ # Disable confirmation mode: set NeverConfirm policy and remove security analyzer
+ self.set_confirmation_policy(NeverConfirm())
def set_confirmation_policy(
self, confirmation_policy: ConfirmationPolicyBase
) -> None:
self.conversation.set_confirmation_policy(confirmation_policy)
+
def _start_listener(self) -> None:
self.listener = PauseListener(on_pause=self.conversation.pause)
self.listener.start()
@@ -68,7 +79,7 @@ class ConversationRunner:
if message:
self.conversation.send_message(message)
- if self.is_confirmation_mode_enabled:
+ if self.is_confirmation_mode_active:
self._run_with_confirmation()
else:
self._run_without_confirmation()
@@ -145,7 +156,9 @@ class ConversationRunner:
'Confirmation mode disabled. Agent will proceed without asking.'
)
)
- self.set_confirmation_policy(policy_change)
+
+ # Remove security analyzer when policy is never confirm
+ self.toggle_confirmation_mode()
return decision
if isinstance(policy_change, ConfirmRisky):
@@ -155,6 +168,8 @@ class ConversationRunner:
'LOW/MEDIUM risk actions will auto-confirm, HIGH risk actions will ask for confirmation.'
)
)
+
+ # Keep security analyzer, change existing policy
self.set_confirmation_policy(policy_change)
return decision
diff --git a/openhands-cli/openhands_cli/setup.py b/openhands-cli/openhands_cli/setup.py
index 025a05eb9e..9e74fa99be 100644
--- a/openhands-cli/openhands_cli/setup.py
+++ b/openhands-cli/openhands_cli/setup.py
@@ -9,6 +9,11 @@ from openhands.tools.task_tracker import TaskTrackerTool
from openhands_cli.listeners import LoadingContext
from openhands_cli.locations import CONVERSATIONS_DIR, WORK_DIR
from openhands_cli.tui.settings.store import AgentStore
+from openhands.sdk.security.confirmation_policy import (
+ AlwaysConfirm,
+)
+from openhands_cli.tui.settings.settings_screen import SettingsScreen
+
register_tool('BashTool', BashTool)
register_tool('FileEditorTool', FileEditorTool)
@@ -21,7 +26,10 @@ class MissingAgentSpec(Exception):
pass
-def setup_conversation(conversation_id: str | None = None) -> BaseConversation:
+def setup_conversation(
+ conversation_id: str | None = None,
+ include_security_analyzer: bool = True
+) -> BaseConversation:
"""
Setup the conversation with agent.
@@ -54,8 +62,15 @@ def setup_conversation(conversation_id: str | None = None) -> BaseConversation:
'Agent specification not found. Please configure your agent settings.'
)
+
+ if not include_security_analyzer:
+ # Remove security analyzer from agent spec
+ agent = agent.model_copy(
+ update={"security_analyzer": None}
+ )
+
# Create conversation - agent context is now set in AgentStore.load()
- conversation = Conversation(
+ conversation: BaseConversation = Conversation(
agent=agent,
workspace=Workspace(working_dir=WORK_DIR),
# Conversation will add / to this path
@@ -63,7 +78,39 @@ def setup_conversation(conversation_id: str | None = None) -> BaseConversation:
conversation_id=conversation_id,
)
+ if include_security_analyzer:
+ conversation.set_confirmation_policy(AlwaysConfirm())
+
print_formatted_text(
HTML(f'✓ Agent initialized with model: {agent.llm.model}')
)
return conversation
+
+
+
+def start_fresh_conversation(
+ resume_conversation_id: str | None = None
+) -> BaseConversation:
+ """Start a fresh conversation by creating a new conversation instance.
+
+ Handles the complete conversation setup process including settings screen
+ if agent configuration is missing.
+
+ Args:
+ resume_conversation_id: Optional conversation ID to resume
+
+ Returns:
+ BaseConversation: A new conversation instance
+ """
+ conversation = None
+ settings_screen = SettingsScreen()
+ try:
+ conversation = setup_conversation(resume_conversation_id)
+ return conversation
+ except MissingAgentSpec:
+ # For first-time users, show the full settings flow with choice between basic/advanced
+ settings_screen.configure_settings(first_time=True)
+
+
+ # Try once again after settings setup attempt
+ return setup_conversation(resume_conversation_id)
diff --git a/openhands-cli/openhands_cli/tui/settings/settings_screen.py b/openhands-cli/openhands_cli/tui/settings/settings_screen.py
index 4aa36cd0e2..35cd76e1de 100644
--- a/openhands-cli/openhands_cli/tui/settings/settings_screen.py
+++ b/openhands-cli/openhands_cli/tui/settings/settings_screen.py
@@ -67,9 +67,7 @@ class SettingsScreen:
(
' Confirmation Mode',
'Enabled'
- if not isinstance(
- self.conversation.state.confirmation_policy, NeverConfirm
- )
+ if self.conversation.is_confirmation_mode_active
else 'Disabled',
),
(
diff --git a/openhands-cli/pyproject.toml b/openhands-cli/pyproject.toml
index b947d0b9ef..9c66ef9521 100644
--- a/openhands-cli/pyproject.toml
+++ b/openhands-cli/pyproject.toml
@@ -96,5 +96,5 @@ disallow_untyped_defs = true
ignore_missing_imports = true
[tool.uv.sources]
-openhands-sdk = { git = "https://github.com/All-Hands-AI/agent-sdk.git", subdirectory = "openhands/sdk", rev = "3ce74a16565be0e3f7e7617174bd0323e866597f" }
-openhands-tools = { git = "https://github.com/All-Hands-AI/agent-sdk.git", subdirectory = "openhands/tools", rev = "3ce74a16565be0e3f7e7617174bd0323e866597f" }
+openhands-sdk = { git = "https://github.com/All-Hands-AI/agent-sdk.git", subdirectory = "openhands/sdk", rev = "189979a5013751aa86852ab41afe9a79555e62ac" }
+openhands-tools = { git = "https://github.com/All-Hands-AI/agent-sdk.git", subdirectory = "openhands/tools", rev = "189979a5013751aa86852ab41afe9a79555e62ac" }
diff --git a/openhands-cli/tests/commands/test_confirm_command.py b/openhands-cli/tests/commands/test_confirm_command.py
new file mode 100644
index 0000000000..95c8d0a4e0
--- /dev/null
+++ b/openhands-cli/tests/commands/test_confirm_command.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python3
+
+from unittest.mock import MagicMock, patch, call
+import pytest
+
+from openhands_cli.runner import ConversationRunner
+from openhands.sdk.security.confirmation_policy import AlwaysConfirm, NeverConfirm
+
+CONV_ID = "test-conversation-id"
+
+
+# ---------- Helpers ----------
+def make_conv(enabled: bool) -> MagicMock:
+ """Return a conversation mock in enabled/disabled confirmation mode."""
+ m = MagicMock()
+ m.id = CONV_ID
+ m.agent.security_analyzer = MagicMock() if enabled else None
+ m.confirmation_policy_active = enabled
+ m.is_confirmation_mode_active = enabled
+ return m
+
+
+@pytest.fixture
+def runner_disabled() -> ConversationRunner:
+ """Runner starting with confirmation mode disabled."""
+ return ConversationRunner(make_conv(enabled=False))
+
+
+@pytest.fixture
+def runner_enabled() -> ConversationRunner:
+ """Runner starting with confirmation mode enabled."""
+ return ConversationRunner(make_conv(enabled=True))
+
+
+# ---------- Core toggle behavior (parametrized) ----------
+@pytest.mark.parametrize(
+ "start_enabled, include_security_analyzer, expected_enabled, expected_policy_cls",
+ [
+ # disabled -> enable
+ (False, True, True, AlwaysConfirm),
+ # enabled -> disable
+ (True, False, False, NeverConfirm),
+ ],
+)
+def test_toggle_confirmation_mode_transitions(
+ start_enabled, include_security_analyzer, expected_enabled, expected_policy_cls
+):
+ # Arrange: pick starting runner & prepare the target conversation
+ runner = ConversationRunner(make_conv(enabled=start_enabled))
+ target_conv = make_conv(enabled=expected_enabled)
+
+ with patch("openhands_cli.runner.setup_conversation", return_value=target_conv) as mock_setup:
+ # Act
+ runner.toggle_confirmation_mode()
+
+ # Assert state
+ assert runner.is_confirmation_mode_active is expected_enabled
+ assert runner.conversation is target_conv
+
+ # Assert setup called with same conversation ID + correct analyzer flag
+ mock_setup.assert_called_once_with(CONV_ID, include_security_analyzer=include_security_analyzer)
+
+ # Assert policy applied to the *new* conversation
+ target_conv.set_confirmation_policy.assert_called_once()
+ assert isinstance(target_conv.set_confirmation_policy.call_args.args[0], expected_policy_cls)
+
+
+# ---------- Conversation ID is preserved across multiple toggles ----------
+def test_maintains_conversation_id_across_toggles(runner_disabled: ConversationRunner):
+ enabled_conv = make_conv(enabled=True)
+ disabled_conv = make_conv(enabled=False)
+
+ with patch("openhands_cli.runner.setup_conversation") as mock_setup:
+ mock_setup.side_effect = [enabled_conv, disabled_conv]
+
+ # Toggle on, then off
+ runner_disabled.toggle_confirmation_mode()
+ runner_disabled.toggle_confirmation_mode()
+
+ assert runner_disabled.conversation.id == CONV_ID
+ mock_setup.assert_has_calls(
+ [
+ call(CONV_ID, include_security_analyzer=True),
+ call(CONV_ID, include_security_analyzer=False),
+ ],
+ any_order=False,
+ )
+
+
+# ---------- Idempotency under rapid alternating toggles ----------
+def test_rapid_alternating_toggles_produce_expected_states(runner_disabled: ConversationRunner):
+ enabled_conv = make_conv(enabled=True)
+ disabled_conv = make_conv(enabled=False)
+
+ with patch("openhands_cli.runner.setup_conversation") as mock_setup:
+ mock_setup.side_effect = [enabled_conv, disabled_conv, enabled_conv, disabled_conv]
+
+ # Start disabled
+ assert runner_disabled.is_confirmation_mode_active is False
+
+ # Enable, Disable, Enable, Disable
+ runner_disabled.toggle_confirmation_mode()
+ assert runner_disabled.is_confirmation_mode_active is True
+
+ runner_disabled.toggle_confirmation_mode()
+ assert runner_disabled.is_confirmation_mode_active is False
+
+ runner_disabled.toggle_confirmation_mode()
+ assert runner_disabled.is_confirmation_mode_active is True
+
+ runner_disabled.toggle_confirmation_mode()
+ assert runner_disabled.is_confirmation_mode_active is False
+
+ mock_setup.assert_has_calls(
+ [
+ call(CONV_ID, include_security_analyzer=True),
+ call(CONV_ID, include_security_analyzer=False),
+ call(CONV_ID, include_security_analyzer=True),
+ call(CONV_ID, include_security_analyzer=False),
+ ],
+ any_order=False,
+ )
diff --git a/openhands-cli/tests/test_new_command.py b/openhands-cli/tests/commands/test_new_command.py
similarity index 80%
rename from openhands-cli/tests/test_new_command.py
rename to openhands-cli/tests/commands/test_new_command.py
index 33682c416b..8b6d10249e 100644
--- a/openhands-cli/tests/test_new_command.py
+++ b/openhands-cli/tests/commands/test_new_command.py
@@ -2,36 +2,34 @@
from unittest.mock import MagicMock, patch
from uuid import UUID
-from openhands_cli.agent_chat import _start_fresh_conversation
-from unittest.mock import MagicMock, patch
from prompt_toolkit.input.defaults import create_pipe_input
from prompt_toolkit.output.defaults import DummyOutput
-from openhands_cli.setup import MissingAgentSpec
+from openhands_cli.setup import MissingAgentSpec, start_fresh_conversation
from openhands_cli.user_actions import UserConfirmation
-@patch('openhands_cli.agent_chat.setup_conversation')
+@patch('openhands_cli.setup.setup_conversation')
def test_start_fresh_conversation_success(mock_setup_conversation):
- """Test that _start_fresh_conversation creates a new conversation successfully."""
+ """Test that start_fresh_conversation creates a new conversation successfully."""
# Mock the conversation object
mock_conversation = MagicMock()
mock_conversation.id = UUID('12345678-1234-5678-9abc-123456789abc')
mock_setup_conversation.return_value = mock_conversation
# Call the function
- result = _start_fresh_conversation()
+ result = start_fresh_conversation()
# Verify the result
assert result == mock_conversation
mock_setup_conversation.assert_called_once_with(None)
-@patch('openhands_cli.agent_chat.SettingsScreen')
-@patch('openhands_cli.agent_chat.setup_conversation')
+@patch('openhands_cli.setup.SettingsScreen')
+@patch('openhands_cli.setup.setup_conversation')
def test_start_fresh_conversation_missing_agent_spec(
mock_setup_conversation,
mock_settings_screen_class
):
- """Test that _start_fresh_conversation handles MissingAgentSpec exception."""
+ """Test that start_fresh_conversation handles MissingAgentSpec exception."""
# Mock the SettingsScreen instance
mock_settings_screen = MagicMock()
mock_settings_screen_class.return_value = mock_settings_screen
@@ -45,7 +43,7 @@ def test_start_fresh_conversation_missing_agent_spec(
]
# Call the function
- result = _start_fresh_conversation()
+ result = start_fresh_conversation()
# Verify the result
assert result == mock_conversation
@@ -61,9 +59,11 @@ def test_start_fresh_conversation_missing_agent_spec(
@patch('openhands_cli.agent_chat.exit_session_confirmation')
@patch('openhands_cli.agent_chat.get_session_prompter')
@patch('openhands_cli.agent_chat.setup_conversation')
+@patch('openhands_cli.agent_chat.start_fresh_conversation')
@patch('openhands_cli.agent_chat.ConversationRunner')
def test_new_command_resets_confirmation_mode(
mock_runner_cls,
+ mock_start_fresh_conversation,
mock_setup_conversation,
mock_get_session_prompter,
mock_exit_confirm,
@@ -73,11 +73,12 @@ def test_new_command_resets_confirmation_mode(
conv1 = MagicMock(); conv1.id = UUID('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa')
conv2 = MagicMock(); conv2.id = UUID('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb')
- mock_setup_conversation.side_effect = [conv1, conv2]
+ mock_start_fresh_conversation.return_value = conv1
+ mock_setup_conversation.side_effect = [conv2]
# Distinct runner instances for each conversation
- runner1 = MagicMock(); runner1.is_confirmation_mode_enabled = True
- runner2 = MagicMock(); runner2.is_confirmation_mode_enabled = False
+ runner1 = MagicMock(); runner1.is_confirmation_mode_active = True
+ runner2 = MagicMock(); runner2.is_confirmation_mode_active = False
mock_runner_cls.side_effect = [runner1, runner2]
# Real session fed by a pipe (no interactive confirmation now)
diff --git a/openhands-cli/tests/test_status_command.py b/openhands-cli/tests/commands/test_status_command.py
similarity index 100%
rename from openhands-cli/tests/test_status_command.py
rename to openhands-cli/tests/commands/test_status_command.py
diff --git a/openhands-cli/tests/test_confirmation_mode.py b/openhands-cli/tests/test_confirmation_mode.py
index 44562e6382..f0744fd687 100644
--- a/openhands-cli/tests/test_confirmation_mode.py
+++ b/openhands-cli/tests/test_confirmation_mode.py
@@ -98,6 +98,7 @@ class TestConfirmationMode:
mock_conversation = MagicMock()
mock_conversation.confirmation_policy_active = False
+ mock_conversation.is_confirmation_mode_active = False
runner = ConversationRunner(mock_conversation)
# Test enabling confirmation mode
@@ -113,10 +114,11 @@ class TestConfirmationMode:
mock_conversation = MagicMock()
mock_conversation.confirmation_policy_active = False
+ mock_conversation.is_confirmation_mode_active = False
runner = ConversationRunner(mock_conversation)
# Verify initial state
- assert runner.is_confirmation_mode_enabled is False
+ assert runner.is_confirmation_mode_active is False
def test_ask_user_confirmation_empty_actions(self) -> None:
"""Test that ask_user_confirmation returns ACCEPT for empty actions list."""
@@ -373,11 +375,12 @@ class TestConfirmationMode:
"""Test that ConversationRunner disables confirmation mode when NeverConfirm policy is returned."""
mock_conversation = MagicMock()
mock_conversation.confirmation_policy_active = True
+ mock_conversation.is_confirmation_mode_active = True
runner = ConversationRunner(mock_conversation)
# Enable confirmation mode first
runner.set_confirmation_policy(AlwaysConfirm())
- assert runner.is_confirmation_mode_enabled is True
+ assert runner.is_confirmation_mode_active is True
# Mock get_unmatched_actions to return some actions
with patch(
@@ -398,14 +401,26 @@ class TestConfirmationMode:
# Mock print_formatted_text to avoid output during test
with patch('openhands_cli.runner.print_formatted_text'):
- result = runner._handle_confirmation_request()
+ # Mock setup_conversation to avoid real conversation creation
+ with patch('openhands_cli.runner.setup_conversation') as mock_setup:
+ # Return a new mock conversation with confirmation mode disabled
+ new_mock_conversation = MagicMock()
+ new_mock_conversation.id = mock_conversation.id
+ new_mock_conversation.is_confirmation_mode_active = False
+ mock_setup.return_value = new_mock_conversation
+
+ result = runner._handle_confirmation_request()
- # Verify that confirmation mode was disabled
- assert result == UserConfirmation.ACCEPT
- # Should have called set_confirmation_policy with NeverConfirm
- mock_conversation.set_confirmation_policy.assert_called_with(
- NeverConfirm()
- )
+ # Verify that confirmation mode was disabled
+ assert result == UserConfirmation.ACCEPT
+ # Should have called setup_conversation to toggle confirmation mode
+ mock_setup.assert_called_once_with(
+ mock_conversation.id, include_security_analyzer=False
+ )
+ # Should have called set_confirmation_policy with NeverConfirm on new conversation
+ new_mock_conversation.set_confirmation_policy.assert_called_with(
+ NeverConfirm()
+ )
@patch('openhands_cli.user_actions.agent_action.cli_confirm')
def test_ask_user_confirmation_auto_confirm_safe(
@@ -432,11 +447,12 @@ class TestConfirmationMode:
"""Test that ConversationRunner sets ConfirmRisky policy when policy_change is provided."""
mock_conversation = MagicMock()
mock_conversation.confirmation_policy_active = True
+ mock_conversation.is_confirmation_mode_active = True
runner = ConversationRunner(mock_conversation)
# Enable confirmation mode first
runner.set_confirmation_policy(AlwaysConfirm())
- assert runner.is_confirmation_mode_enabled is True
+ assert runner.is_confirmation_mode_active is True
# Mock get_unmatched_actions to return some actions
with patch(
diff --git a/openhands-cli/tests/test_conversation_runner.py b/openhands-cli/tests/test_conversation_runner.py
index dc15111ea6..447c0edd17 100644
--- a/openhands-cli/tests/test_conversation_runner.py
+++ b/openhands-cli/tests/test_conversation_runner.py
@@ -102,6 +102,11 @@ class TestConversationRunner:
"""
if final_status == AgentExecutionStatus.FINISHED:
agent.finish_on_step = 1
+
+ # Add a mock security analyzer to enable confirmation mode
+ from unittest.mock import MagicMock
+ agent.security_analyzer = MagicMock()
+
convo = Conversation(agent)
convo.state.agent_status = AgentExecutionStatus.WAITING_FOR_CONFIRMATION
cr = ConversationRunner(convo)
diff --git a/openhands-cli/uv.lock b/openhands-cli/uv.lock
index 9fad3fc7b1..494d47d1fe 100644
--- a/openhands-cli/uv.lock
+++ b/openhands-cli/uv.lock
@@ -1642,8 +1642,8 @@ dev = [
[package.metadata]
requires-dist = [
- { name = "openhands-sdk", git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Fsdk&rev=3ce74a16565be0e3f7e7617174bd0323e866597f" },
- { name = "openhands-tools", git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Ftools&rev=3ce74a16565be0e3f7e7617174bd0323e866597f" },
+ { name = "openhands-sdk", git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Fsdk&rev=189979a5013751aa86852ab41afe9a79555e62ac" },
+ { name = "openhands-tools", git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Ftools&rev=189979a5013751aa86852ab41afe9a79555e62ac" },
{ name = "prompt-toolkit", specifier = ">=3" },
{ name = "typer", specifier = ">=0.17.4" },
]
@@ -1667,7 +1667,7 @@ dev = [
[[package]]
name = "openhands-sdk"
version = "1.0.0"
-source = { git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Fsdk&rev=3ce74a16565be0e3f7e7617174bd0323e866597f#3ce74a16565be0e3f7e7617174bd0323e866597f" }
+source = { git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Fsdk&rev=189979a5013751aa86852ab41afe9a79555e62ac#189979a5013751aa86852ab41afe9a79555e62ac" }
dependencies = [
{ name = "fastmcp" },
{ name = "litellm" },
@@ -1681,7 +1681,7 @@ dependencies = [
[[package]]
name = "openhands-tools"
version = "1.0.0"
-source = { git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Ftools&rev=3ce74a16565be0e3f7e7617174bd0323e866597f#3ce74a16565be0e3f7e7617174bd0323e866597f" }
+source = { git = "https://github.com/All-Hands-AI/agent-sdk.git?subdirectory=openhands%2Ftools&rev=189979a5013751aa86852ab41afe9a79555e62ac#189979a5013751aa86852ab41afe9a79555e62ac" }
dependencies = [
{ name = "bashlex" },
{ name = "binaryornot" },