-
Notifications
You must be signed in to change notification settings - Fork 108
refactor: remove reconciliation methods, use runtime agent directly #1542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Coverage Report •
|
||||||||||||||||||||||||||||||||||||||||
76b5add to
5b3198d
Compare
Remove all reconciliation methods (resolve_diff_from_deserialized) and use the runtime agent directly when restoring conversations. Key changes: - LLM: Remove resolve_diff_from_deserialized method entirely - AgentBase: Remove resolve_diff_from_deserialized method entirely - ConversationState.create(): Use runtime agent directly, no compatibility checking. User is free to change LLM, tools, condenser, agent_context, etc. between sessions. Execution flow for new conversation: 1. Create ConversationState with runtime agent (Pydantic validation happens here) 2. Initialize EventLog for event storage 3. Save initial base state to persistence 4. Return the new state Execution flow for restored conversation: 1. Load persisted base_state.json (only to get conversation metadata) 2. Verify conversation ID matches 3. Create ConversationState with the runtime agent (Pydantic validation happens here - runtime agent is always used) 4. Restore persisted conversation metadata (execution_status, etc.) 5. Attach EventLog to load persisted events 6. Save updated base state (with runtime agent) 7. Return the resumed state NOTE: There's a case for checking that tools already used in the conversation history are still available - see issue #1533. Closes #1451 Co-authored-by: openhands <[email protected]>
5b3198d to
82b191c
Compare
Reintroduce tools restriction from the original reconcile method: - Add AgentBase.load(persisted) method that validates tools match - Tools must match between runtime and persisted agents (they may have been used in conversation history) - All other config (LLM, agent_context, condenser, etc.) can change freely Update ConversationState.create() to use agent.load() on restore path. Co-authored-by: openhands <[email protected]>
xingyaoww
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Just need to fix a few minor things!
Address review comments: - Rename AgentBase.load() to AgentBase.verify() since it's a verification method, not a load method - Update docstring to say 'Verify that we can resume...' - Capture return value: verified_agent = agent.verify(persisted_state.agent) - Update tests to use verify() instead of load() Co-authored-by: openhands <[email protected]>
Address xingyaoww's review comment: instead of creating state from scratch, load persisted state and update specific fields. This is more future-proof - new fields will automatically be preserved. Co-authored-by: openhands <[email protected]>
Load persisted state but override with runtime-provided values: - agent (verified against persisted) - workspace - max_iterations - stuck_detection Keep from persisted state: - id, persistence_dir, execution_status, confirmation_policy - activated_knowledge_skills, blocked_actions, blocked_messages - secret_registry This gives the best of both approaches: future-proof for new fields while respecting user-provided runtime configuration. Co-authored-by: openhands <[email protected]>
Co-authored-by: openhands <[email protected]>
Test coverage for: - Runtime values used on resume: workspace, max_iterations - Persisted values preserved: execution_status, stuck_detection, blocked_actions, blocked_messages - Stats reset on resume (fresh session) - Conversation ID mismatch raises error Co-authored-by: openhands <[email protected]>
|
@OpenHands I look at the diff of this PR and I don't see all I expected to see. For example, in llm.py we have a class var named OVERRIDE... something, which is, I think, only used in the reconciliation method we removed from LLM. Please track it down and confirm what I said, and if it's unused let's clean it up. Verify if in the other files in this PR, e.g. state or agentbase, we have something similar and do the same. Review the code and clean it up from such redundancies or similar. |
|
I'm on it! enyst can track my progress at all-hands.dev |
Co-authored-by: openhands <[email protected]>
Final summary (new since last summary)Double-check: request coverage
Conciseness check
Git / delivery
Diff recap (this update only):
|
Co-authored-by: openhands <[email protected]>
Co-authored-by: openhands <[email protected]>
Co-authored-by: openhands <[email protected]>
|
Hi! I started running the integration tests on your PR. You will receive a comment with the results shortly. |
🧪 Integration Tests ResultsOverall Success Rate: 87.5% 📁 Detailed Logs & ArtifactsClick the links below to access detailed agent/LLM logs showing the complete reasoning process for each model. On the GitHub Actions page, scroll down to the 'Artifacts' section to download the logs.
📊 Summary
📋 Detailed Resultslitellm_proxy_gpt_5.1_codex_max
Skipped Tests:
Failed Tests:
litellm_proxy_vertex_ai_gemini_3_pro_preview
Failed Tests:
litellm_proxy_mistral_devstral_2512
Skipped Tests:
Failed Tests:
litellm_proxy_moonshot_kimi_k2_thinking
Skipped Tests:
Failed Tests:
litellm_proxy_deepseek_deepseek_chat
Skipped Tests:
Failed Tests:
litellm_proxy_claude_sonnet_4_5_20250929
Failed Tests:
|
…nfig from matrix Co-authored-by: openhands <[email protected]>
|
Hi! I started running the integration tests on your PR. You will receive a comment with the results shortly. |
🧪 Integration Tests ResultsOverall Success Rate: 85.7% 📁 Detailed Logs & ArtifactsClick the links below to access detailed agent/LLM logs showing the complete reasoning process for each model. On the GitHub Actions page, scroll down to the 'Artifacts' section to download the logs.
📊 Summary
📋 Detailed Resultslitellm_proxy_vertex_ai_gemini_3_pro_preview
Failed Tests:
litellm_proxy_claude_sonnet_4_5_20250929
Failed Tests:
litellm_proxy_deepseek_deepseek_chat
Skipped Tests:
Failed Tests:
litellm_proxy_gpt_5.1_codex_max
Skipped Tests:
Failed Tests:
litellm_proxy_moonshot_kimi_k2_thinking
Skipped Tests:
Failed Tests:
litellm_proxy_mistral_devstral_2512
Skipped Tests:
Failed Tests:
|
|
@OpenHands Understand this PR. Then split the integration test changes from it, in a new branch based on this branch, and make a PR to this PR. We want to get those right, but without running it with the whole LLM matrix, and in the same time, we want this branch ready. |
|
I'm on it! enyst can track my progress at all-hands.dev |
Final summary (new since last summary)✅ Verification
✅ What was delivered (per your request)
🔍 Scope of the split (integration-only files)This split PR contains only:
No other refactor/reconciliation-removal code is included. |
…store config from matrix" This reverts commit a2aa1b9.
This reverts commit 8e12188.
…R)\n\nCo-authored-by: openhands <[email protected]>
|
xingyaoww
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it! Really appreciate the effort here @enyst - this will make it much easier to implement the model switching on the fly!
|
@OpenHands please create an issue in OpenHands/OpenHands-CLI - based on the change of this PR, we should update how we handle We should only keep the non-default fields in |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
|
I've successfully created an issue in the OpenHands/OpenHands-CLI repository based on the changes in PR #1542. Issue Created: #302 - Update agent_settings handling to only persist non-default fields The issue describes:
The issue is linked to the SDK PR #1542 for context. |

Summary
This PR removes all reconciliation methods (
resolve_diff_from_deserialized) and uses the provided Agent directly when restoring conversations. This is an alternative approach to issue #1451.What Was Happening on Main
On
main, when restoring a conversation,resolve_diff_from_deserializedwould:Override from runtime:
agent_context(skills, system_message_suffix, user_message_suffix, secrets)llmsecrets (api_key, aws credentials, litellm_extra_body)condenser.llmsecretsRestore from persistence (and require exact match with runtime):
toolsmcp_configfilter_tools_regexsystem_prompt_filenamesecurity_policy_filenamesystem_prompt_kwargscondenser(except its llm secrets)llmconfig (model, temperature, etc.)The final equality check meant users effectively couldn't change most Agent configuration between sessions.
What This PR Does
Removes reconciliation. The provided Agent is used directly - subject to limitations that would otherwise not work at all, such as, it has to be the same Agent class, or the same tools.
Users are now free to change Agent configuration between sessions:
llm(model, api_key, all settings)mcp_configfilter_tools_regexagent_contextsystem_prompt_filenamesecurity_policy_filenamesystem_prompt_kwargscondenserLimitations:
toolsstateattributes like Confirmation PolicyExecution Flow
New Conversation:
Restored Conversation:
Validation
Pydantic validation happens when creating instances (LLM, Agent, ConversationState) via the constructor.
Note on Tools
From issue #1533 , tools already used in the conversation history are still available.
Scope: LocalConversation Only
This PR only affects LocalConversation.
For RemoteConversation, the server always creates the Agent from the persisted
meta.json- the client's Agent is ignored when restoring. Making RemoteConversation support Agent changes would require:This is out of scope for this PR but could be a follow-up.
Closes #1451
Checklist
Agent Server images for this PR
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.12-nodejs22golang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:521d39f-pythonRun
All tags pushed for this build
About Multi-Architecture Support
521d39f-python) is a multi-arch manifest supporting both amd64 and arm64521d39f-python-amd64) are also available if needed