Rename Conversation to ServerConversation and AppConfig to OpenHandsConfig
This PR renames the Conversation class in the server directory to ServerConversation and the AppConfig class to OpenHandsConfig throughout the codebase. It also renames the file app_config.py to openhands_config.py and updates all import statements and references accordingly.
Changes include:
- Renamed
ConversationtoServerConversationin server, evaluation, and tests directories - Renamed
AppConfigtoOpenHandsConfigthroughout the codebase - Renamed
app_config.pytoopenhands_config.py - Updated all import statements and references
- Updated function name
load_app_configtoload_openhands_config - Fixed formatting issues with pre-commit hooks
To run this PR locally, use the following command:
docker run -it --rm -p 3000:3000 -v /var/run/docker.sock:/var/run/docker.sock --add-host host.docker.internal:host-gateway -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:32c19bd-nikolaik --name openhands-app-32c19bd docker.all-hands.dev/all-hands-ai/openhands:32c19bd
@openhands update tehse tests
test_event_stream = EventStream(sid='test', file_store=<openhands.storage.memory.InMemoryFileStore object at 0x7f050b38bce0>, user_id=None, cur_id=6, cache_size=25)
@pytest.mark.asyncio
async def test_run_controller_with_context_window_exceeded_without_truncation(
mock_agent, mock_runtime, mock_memory, test_event_stream
):
"""Tests that the controller would quit upon context window exceeded errors without enable_history_truncation ON."""
class StepState:
def __init__(self):
self.has_errored = False
def step(self, state: State):
# If the state has more than one message and we haven't errored yet,
# throw the context window exceeded error
if len(state.history) > 3 and not self.has_errored:
error = ContextWindowExceededError(
message='prompt is too long: 233885 tokens > 200000 maximum',
model='',
llm_provider='',
)
self.has_errored = True
raise error
return MessageAction(content=f'STEP {len(state.history)}')
step_state = StepState()
mock_agent.step = step_state.step
mock_agent.config = AgentConfig()
mock_agent.config.enable_history_truncation = False
def on_event_memory(event: Event):
if isinstance(event, RecallAction):
microagent_obs = RecallObservation(
content='Test microagent content',
recall_type=RecallType.KNOWLEDGE,
)
microagent_obs._cause = event.id
test_event_stream.add_event(microagent_obs, EventSource.ENVIRONMENT)
test_event_stream.subscribe(
EventStreamSubscriber.MEMORY, on_event_memory, str(uuid4())
)
mock_runtime.event_stream = test_event_stream
try:
state = await asyncio.wait_for(
run_controller(
config=OpenHandsConfig(max_iterations=3),
initial_user_action=MessageAction(content='INITIAL'),
runtime=mock_runtime,
sid='test',
agent=mock_agent,
fake_user_response_fn=lambda _: 'repeat',
memory=mock_memory,
),
timeout=10,
)
# A timeout error indicates the run_controller entrypoint is not making
# progress
except asyncio.TimeoutError as e:
raise AssertionError(
'The run_controller function did not complete in time.'
) from e
# Hitting the iteration limit indicates the controller is failing for the
# expected reason
# With the refactored system message handling, the iteration count is different
assert state.iteration == 1
assert state.agent_state == AgentState.ERROR
> assert (
state.last_error
== 'LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error'
)
E AssertionError: assert 'LLMContextWindowExceedError: Conversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error' == 'LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error'
E
E - LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error
E ? ------
E + LLMContextWindowExceedError: Conversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error
tests/unit/test_agent_controller.py:1045: AssertionError
_____________________ test_update_conversation_with_title ______________________
[gw0] linux -- Python 3.12.4 /home/runner/.cache/pypoetry/virtualenvs/openhands-ai-2f2V0C4o-py3.12/bin/python
@pytest.mark.asyncio
async def test_update_conversation_with_title():
"""Test that _update_conversation_for_event updates the title when needed."""
# Mock dependencies
sio = MagicMock()
sio.emit = AsyncMock()
file_store = InMemoryFileStore()
server_config = MagicMock()
# Create test conversation
conversation_id = 'test-conversation'
user_id = 'test-user'
# Create test settings
settings = Settings(
llm_model='test-model',
llm_api_key='test-key',
llm_base_url='test-url',
)
# Mock the conversation store and metadata
mock_conversation_store = AsyncMock()
mock_metadata = MagicMock()
mock_metadata.title = f'ServerConversation {conversation_id[:5]}' # Default title
mock_conversation_store.get_metadata.return_value = mock_metadata
# Create the conversation manager
manager = StandaloneConversationManager(
sio=sio,
config=OpenHandsConfig(),
file_store=file_store,
server_config=server_config,
monitoring_listener=MonitoringListener(),
)
# Mock the _get_conversation_store method
manager._get_conversation_store = AsyncMock(return_value=mock_conversation_store)
# Mock the auto_generate_title function
with patch(
'openhands.server.conversation_manager.standalone_conversation_manager.auto_generate_title',
AsyncMock(return_value='Generated Title'),
):
# Call the method
await manager._update_conversation_for_event(user_id, conversation_id, settings)
# Verify the title was updated
> assert mock_metadata.title == 'Generated Title'
E AssertionError: assert 'ServerConversation test-' == 'Generated Title'
E
E - Generated Title
E + ServerConversation test-
tests/unit/test_auto_generate_title.py:228: AssertionError
=========================== short test summary info ============================
FAILED tests/unit/test_agent_controller.py::test_run_controller_with_context_window_exceeded_without_truncation
FAILED tests/unit/test_auto_generate_title.py::test_update_conversation_with_title
============ 2 failed, 1137 passed, 23 skipped in 71.03s (0:01:11) =============
I'm on it! rbren can track my progress at all-hands.dev
Work Summary
I successfully addressed the failing tests in the PR #8754 on the rename-conversation-appconfig branch. The PR was renaming AppConfig to OpenHandsConfig throughout the codebase, but there were two failing tests that needed to be fixed:
Changes Made:
-
Fixed the error message assertion in
test_agent_controller.py:- Changed the expected error message from
'LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit...'to'LLMContextWindowExceedError: Conversation history longer than LLM context window limit...' - This aligns with the actual error message defined in the
LLMContextWindowExceedErrorclass.
- Changed the expected error message from
-
Fixed the default title in
test_auto_generate_title.py:- Changed the mock title from
f'ServerConversation {conversation_id[:5]}'tof'Conversation {conversation_id[:5]}' - This matches the actual implementation in the
get_default_conversation_titlefunction.
- Changed the mock title from
Verification:
- All changes passed the pre-commit hooks, including ruff, mypy, and formatting checks.
- The changes were successfully committed and pushed to the
rename-conversation-appconfigbranch.
These changes should fix the failing tests that were mentioned in the PR comment, allowing the PR to pass CI checks.
@openhands update this test
=================================== FAILURES ===================================
_____ test_run_controller_with_context_window_exceeded_without_truncation ______
[gw3] linux -- Python 3.12.4 /home/runner/.cache/pypoetry/virtualenvs/openhands-ai-2f2V0C4o-py3.12/bin/python
mock_agent = <MagicMock spec='Agent' id='139887724626864'>
mock_runtime = <MagicMock spec='ActionExecutionClient' id='139887722237536'>
mock_memory = <MagicMock spec='Memory' id='139887722241184'>
test_event_stream = EventStream(sid='test', file_store=<openhands.storage.memory.InMemoryFileStore object at 0x7f3a25fe2210>, user_id=None, cur_id=6, cache_size=25)
@pytest.mark.asyncio
async def test_run_controller_with_context_window_exceeded_without_truncation(
mock_agent, mock_runtime, mock_memory, test_event_stream
):
"""Tests that the controller would quit upon context window exceeded errors without enable_history_truncation ON."""
class StepState:
def __init__(self):
self.has_errored = False
def step(self, state: State):
# If the state has more than one message and we haven't errored yet,
# throw the context window exceeded error
if len(state.history) > 3 and not self.has_errored:
error = ContextWindowExceededError(
message='prompt is too long: 233885 tokens > 200000 maximum',
model='',
llm_provider='',
)
self.has_errored = True
raise error
return MessageAction(content=f'STEP {len(state.history)}')
step_state = StepState()
mock_agent.step = step_state.step
mock_agent.config = AgentConfig()
mock_agent.config.enable_history_truncation = False
def on_event_memory(event: Event):
if isinstance(event, RecallAction):
microagent_obs = RecallObservation(
content='Test microagent content',
recall_type=RecallType.KNOWLEDGE,
)
microagent_obs._cause = event.id
test_event_stream.add_event(microagent_obs, EventSource.ENVIRONMENT)
test_event_stream.subscribe(
EventStreamSubscriber.MEMORY, on_event_memory, str(uuid4())
)
mock_runtime.event_stream = test_event_stream
try:
state = await asyncio.wait_for(
run_controller(
config=OpenHandsConfig(max_iterations=3),
initial_user_action=MessageAction(content='INITIAL'),
runtime=mock_runtime,
sid='test',
agent=mock_agent,
fake_user_response_fn=lambda _: 'repeat',
memory=mock_memory,
),
timeout=10,
)
# A timeout error indicates the run_controller entrypoint is not making
# progress
except asyncio.TimeoutError as e:
raise AssertionError(
'The run_controller function did not complete in time.'
) from e
# Hitting the iteration limit indicates the controller is failing for the
# expected reason
# With the refactored system message handling, the iteration count is different
assert state.iteration == 1
assert state.agent_state == AgentState.ERROR
assert (
state.last_error
== 'LLMContextWindowExceedError: Conversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error'
)
error_observations = test_event_stream.get_matching_events(
reverse=True, limit=1, event_types=(AgentStateChangedObservation)
)
assert len(error_observations) == 1
error_observation = error_observations[0]
> assert (
error_observation.reason
== 'LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error'
)
E AssertionError: assert 'LLMContextWindowExceedError: Conversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error' == 'LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error'
E
E - LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error
E ? ------
E + LLMContextWindowExceedError: Conversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error
tests/unit/test_agent_controller.py:1055: AssertionError
=========================== short test summary info ============================
FAILED tests/unit/test_agent_controller.py::test_run_controller_with_context_window_exceeded_without_truncation
============ 1 failed, 1138 passed, 23 skipped in 72.41s (0:01:12) =============
make sure it passes
I'm on it! rbren can track my progress at all-hands.dev
Work Summary
I successfully fixed the failing test in PR #8754 on the rename-conversation-appconfig branch.
Issue Identified
The test test_run_controller_with_context_window_exceeded_without_truncation was failing because of a mismatch in the expected error message. The test was expecting:
LLMContextWindowExceedError: ServerConversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error
But the actual error message was:
LLMContextWindowExceedError: Conversation history longer than LLM context window limit. Consider turning on enable_history_truncation config to avoid this error
Solution Implemented
I updated the test to match the actual error message by removing "Server" from "ServerConversation" in the expected error message. This aligns with the PR's purpose of renaming AppConfig to OpenHandsConfig and related changes.
Changes Made
- Modified the assertion in
tests/unit/test_agent_controller.pyto match the actual error message - Verified the fix by running the test, which now passes
- Committed and pushed the changes to the
rename-conversation-appconfigbranch
The PR should now pass all tests and be ready for review.