feat(sdk): add ask_oracle tool - #3673
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Python API breakage checks — ✅ PASSEDResult: ✅ PASSED |
REST API breakage checks (OpenAPI) — ✅ PASSEDResult: ✅ PASSED |
This comment was marked as outdated.
This comment was marked as outdated.
Co-authored-by: openhands <openhands@all-hands.dev>
08d4edd to
9c2b227
Compare
Coverage Report •
|
|||||||||||||||||||||||||||||||||||||||||||||
Updated the description of the Oracle to clarify its purpose and capabilities.
This comment was marked as outdated.
This comment was marked as outdated.
Co-authored-by: openhands <openhands@all-hands.dev>
This comment was marked as outdated.
This comment was marked as outdated.
Co-authored-by: openhands <openhands@all-hands.dev>
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as outdated.
This comment was marked as outdated.
Co-authored-by: openhands <openhands@all-hands.dev>
This comment was marked as outdated.
This comment was marked as outdated.
Co-authored-by: openhands <openhands@all-hands.dev>
This comment was marked as outdated.
This comment was marked as outdated.
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
This comment was marked as outdated.
This comment was marked as outdated.
all-hands-bot
left a comment
There was a problem hiding this comment.
This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.
Summary
The ask_oracle tool is well-structured and consistently follows the existing auxiliary-LLM tool pattern established by vision_inspect and switch_llm: synchronous __call__, get_or_create_profile_llm for profile resolution, make_llm_completion for the one-shot call, and comprehensive error handling that returns actionable is_error observations rather than raising.
No material code issues found. The profile_store_dir parameter on LocalConversation is a clean, backward-compatible addition (defaults to None → ~/.openhands/profiles). Tests use real code paths (TestLLM, execute_tool) and cover the key edges: missing profile, empty response, no conversation, successful round-trip with message-shape verification. The OpenAPI allowlist entry follows the existing per-tool pattern.
Eval-risk flagging
This PR adds a new agent tool with behavior-guiding prompt language ("Treat the Oracle's response as strong guidance and follow its recommendation unless you have a clear reason not to"). While the tool is opt-in (not in BUILT_IN_TOOLS, requires an explicit Tool(name="ask_oracle") and a saved oracle profile), it still falls in the eval-risk category.
Noting that:
- Run tests ✅ passed for the current head SHA.
- All other CI checks (pre-commit, API breakage, REST breakage, Agent Server) ✅ passed.
- Run Integration Tests has not run for the current head SHA (
194c8ce). The last integration test run (2026-06-11, 100% success) was against a substantially different version of the code (before the tool was moved from SDK builtins toopenhands-tools). - No eval monitor link or human eval confirmation is present.
Recommend a human maintainer decide after running lightweight evals / integration tests on the current head.
Risk Assessment
🟢 LOW — No bugs, security issues, or design flaws. The code is clean and consistent with established patterns. The only open item is eval validation for the current head SHA, which is a process gate, not a code defect.
Co-authored-by: openhands <openhands@all-hands.dev>
|
Hi! I started running the integration tests on your PR. You will receive a comment with the results shortly. |
🧪 Integration Tests ResultsOverall Success Rate: 97.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_deepseek_deepseek_v4_flash
Skipped Tests:
litellm_proxy_anthropic_claude_sonnet_4_6
Failed Tests:
litellm_proxy_gemini_3.1_pro_preview
litellm_proxy_openai_gpt_5.5
litellm_proxy_minimax_MiniMax_M2.7
Skipped Tests:
|
Co-authored-by: openhands <openhands@all-hands.dev>
HUMAN:
This PR proposes an
Oracletool, for the agent to ask a more capable LLM when it encounters a difficulty, when it needs a second opinion, or when the user tells it to.AGENT:
Why
Agents sometimes need a second opinion from a stronger or more specialized saved LLM profile without permanently switching the active conversation profile. This adds a minimal
ask_oracletool powered by anoracleprofile name so the agent can consult that Oracle profile statelessly, get a response, and continue with its current LLM.Since the tool is defined in the
toolspackage, we should probably not make a setting in the SDK for it. Instead, if users define theoracleLLM profile, it will be used for the Oracle tool.Execution model
ask_oraclefollows the existing synchronous tool-executor pattern: it implements__call__and usesmake_llm_completion. WhenLocalConversation.arun()executes the tool, synchronous executors run in the thread pool, so the Oracle request does not block the event loop. This is the same pattern used by the siblingvision_inspectandswitch_llmtools. A native__acall__/amake_llm_completionpath could avoid occupying a worker for a high-latency request, but this PR stays consistent with those tools; async support can be added across the auxiliary LLM tools together if it becomes necessary.Summary
ask_oracletool inopenhands-toolsthat asks a saved Oracle LLM profile (resolved by convention under the nameoracle) for stateless second-opinion guidance.LocalConversationto use a custom LLM profile directory so the example can isolate its temporary Oracle profile.Closes #3672.
Documentation: OpenHands/docs#566
REST API contract changes
Compared with base OpenAPI
90917f02ab23for public/api/**paths.Validation
The five-model integration run completed successfully at 43/44 applicable scenarios (97.7%). The sole Claude miss was an unrelated executable-bit omission in
t02_add_bash_hello; a targeted rerun passed 1/1.How to Test
uv run pre-commit run --files openhands-sdk/openhands/sdk/tool/builtins/__init__.py openhands-tools/openhands/tools/__init__.py openhands-tools/openhands/tools/ask_oracle/__init__.py openhands-tools/openhands/tools/ask_oracle/definition.py openhands-tools/openhands/tools/ask_oracle/impl.py tests/tools/ask_oracle/test_ask_oracle.py openhands-sdk/openhands/sdk/conversation/impl/local_conversation.py tests/sdk/conversation/test_switch_model.py tests/examples/test_examples.py examples/01_standalone_sdk/58_ask_oracle_tool/main.pyuv run pytest tests/tools/ask_oracle/test_ask_oracle.py tests/sdk/conversation/test_switch_model.py -k 'ask_oracle or switch_profile_uses_custom_profile_store'uv run pytest tests/examples/test_examples.py --run-examples -k 58_ask_oracle_toolCI=true uv run python -m pytest -q tests/sdkThis PR was created by an AI agent (OpenHands) on behalf of the user.
@enyst can click here to continue refining the PR
🐳 Agent Server images for this PR — GHCR package, pull/run commands, and all pushed tags (click to expand)
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.13-nodejs22-slimgolang: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:5a094a6-pythonRun
All tags pushed for this build
About Multi-Architecture Support
5a094a6-python) is a multi-arch manifest supporting both amd64 and arm645a094a6-python-amd64) are also available if needed