Skip to content

feat: Expose agent final response via REST API endpoint#2690

Merged
xingyaoww merged 6 commits intomainfrom
openhands/expose-agent-final-response
Apr 9, 2026
Merged

feat: Expose agent final response via REST API endpoint#2690
xingyaoww merged 6 commits intomainfrom
openhands/expose-agent-final-response

Conversation

@xingyaoww
Copy link
Copy Markdown
Collaborator

@xingyaoww xingyaoww commented Apr 3, 2026

Summary

Adds a new REST API endpoint GET /api/conversations/{conversation_id}/response that returns the agent's final response text for a conversation. This uses the existing SDK utility get_agent_final_response() to extract the text from either a FinishAction message or the last agent MessageEvent.

This eliminates the need for every client (Slack, Discord, WhatsApp, GitHub integration, etc.) to independently search through events via /search and reimplement the same extraction logic to find "what did the agent conclude?".

Changes

  • models.py: Added AgentResponseResult response model with a response: str field
  • event_service.py: Added get_agent_final_response() / _get_agent_final_response_sync() methods that delegate to the SDK's get_agent_final_response() utility, following the existing sync/async executor pattern
  • conversation_router.py: Added GET /{conversation_id}/response endpoint that returns AgentResponseResult
  • test_conversation_response.py: 7 tests covering endpoint behavior (success, empty response, 404) and service-layer logic (FinishAction, MessageEvent, empty events, inactive service)

Design

Follows Option A from the SDK comment: a dedicated endpoint that keeps ConversationInfo focused on metadata/status. The endpoint returns a simple string response matching the agreed approach in the issue discussion.

Fixes #2689

Checklist

  • If the PR is changing/adding functionality, are there tests to reflect this?
  • If there is an example, have you run the example to make sure that it works?
  • If there are instructions on how to run the code, have you followed the instructions and made sure that it works?
  • If the feature is significant enough to require documentation, is there a PR open on the OpenHands/docs repository with the same branch name?
  • Is the github CI passing?

This PR was created by an AI assistant (OpenHands) on behalf of @xingyaoww.

@xingyaoww can click here to continue refining the PR


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:d64d1d3-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-d64d1d3-python \
  ghcr.io/openhands/agent-server:d64d1d3-python

All tags pushed for this build

ghcr.io/openhands/agent-server:d64d1d3-golang-amd64
ghcr.io/openhands/agent-server:d64d1d3-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:d64d1d3-golang-arm64
ghcr.io/openhands/agent-server:d64d1d3-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:d64d1d3-java-amd64
ghcr.io/openhands/agent-server:d64d1d3-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:d64d1d3-java-arm64
ghcr.io/openhands/agent-server:d64d1d3-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:d64d1d3-python-amd64
ghcr.io/openhands/agent-server:d64d1d3-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:d64d1d3-python-arm64
ghcr.io/openhands/agent-server:d64d1d3-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:d64d1d3-golang
ghcr.io/openhands/agent-server:d64d1d3-java
ghcr.io/openhands/agent-server:d64d1d3-python

About Multi-Architecture Support

  • Each variant tag (e.g., d64d1d3-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., d64d1d3-python-amd64) are also available if needed

Add GET /api/conversations/{id}/response endpoint that returns the
agent's final response text using the existing SDK utility
get_agent_final_response(). This allows clients (Slack, Discord,
WhatsApp, GitHub integrations) to retrieve the agent's conclusion
without having to search through events and reimplement the extraction
logic.

- Add AgentResponseResult model to models.py
- Add get_agent_final_response() method to EventService
- Add /response endpoint to conversation_router
- Add tests for the endpoint and service method

Closes #2689

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-agent-server/openhands/agent_server
   conversation_router.py120992%286, 344–347, 359–362
   event_service.py3478974%56–57, 75–77, 86–90, 93–96, 116, 220, 237, 278, 288, 312–313, 317, 325, 328, 368–369, 385, 387, 391–393, 397, 406–407, 409, 413, 419, 421, 451–456, 601, 603–604, 608, 622–624, 626, 630–633, 637–640, 648–651, 670–671, 673–680, 682–683, 692–693, 695–696, 703–704, 706–707, 727, 733, 739, 748–749
TOTAL225581016954% 

openhands-agent and others added 2 commits April 3, 2026 16:56
Rename the REST API endpoint path to match the programmatic API naming:
- /{conversation_id}/response -> /{conversation_id}/agent_final_response
- Updated handler function name accordingly
- Updated test URL paths

Co-authored-by: openhands <openhands@all-hands.dev>
@xingyaoww xingyaoww marked this pull request as ready for review April 5, 2026 17:25
Copy link
Copy Markdown
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Good taste - Simple, focused endpoint that reuses SDK utilities and follows established patterns. Comprehensive tests validate real behavior (FinishAction, MessageEvent, edge cases) rather than just asserting mocks. No complexity issues, no breaking changes, no security concerns. LGTM! ✅

Add end-to-end test in test_remote_conversation_live_server.py that:
- Creates a conversation with a patched LLM returning finish(message=...)
- Runs the agent to completion
- Hits GET /api/conversations/{id}/agent_final_response
- Verifies the response text matches the finish message
- Checks 404 for unknown conversation IDs

Also update openhands-agent-server/AGENTS.md to document that small
endpoint additions should include a live server integration test.

Co-authored-by: openhands <openhands@all-hands.dev>
@xingyaoww xingyaoww requested a review from enyst April 5, 2026 17:30
@xingyaoww
Copy link
Copy Markdown
Collaborator Author

xingyaoww commented Apr 6, 2026

@enyst would appreciate quick 👀 here

Copy link
Copy Markdown
Collaborator

@enyst enyst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@xingyaoww xingyaoww enabled auto-merge (squash) April 9, 2026 09:25
@xingyaoww xingyaoww merged commit d020315 into main Apr 9, 2026
23 checks passed
@xingyaoww xingyaoww deleted the openhands/expose-agent-final-response branch April 9, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose last Agent event contents in agent-server REST API

4 participants