Skip to content

Conversation

@simonrosenberg
Copy link
Collaborator

@simonrosenberg simonrosenberg commented Oct 21, 2025

Summary

This PR renames AgentExecutionStatus to ConversationExecutionStatus to better reflect the actual semantics of the enum.

Changes Made

  • Renamed enum class: AgentExecutionStatusConversationExecutionStatus in openhands/sdk/conversation/state.py
  • Updated all imports: Replaced all import statements across the codebase to use the new name
  • Updated all usage references: Updated variable references, type annotations, and enum value usage
  • Renamed test file: test_agent_status_enum.pytest_conversation_execution_status_enum.py
  • Added backward compatibility: Added alias AgentExecutionStatus = ConversationExecutionStatus to maintain backward compatibility
  • Updated documentation: Updated docstrings and comments to reference 'conversation' instead of 'agent'

Rationale

  1. Agent is stateless: Agents themselves have no status - they are stateless entities
  2. Status belongs to conversation: The execution status is actually a property of the conversation state
  3. Improved clarity: The new name makes it impossible to guess wrong paths for this class, as mentioned in the issue
  4. Better semantics: The name now accurately reflects what the enum represents

Backward Compatibility

A backward compatibility alias has been added:

AgentExecutionStatus = ConversationExecutionStatus

This ensures existing code will continue to work without modification.

Testing

  • ✅ All existing tests pass
  • ✅ Backward compatibility alias works correctly
  • ✅ Pre-commit hooks pass (formatting, linting, type checking)

Fixes #838

@simonrosenberg 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 Base Image Docs / Tags
golang golang:1.21-bookworm Link
java eclipse-temurin:17-jdk Link
python nikolaik/python-nodejs:python3.12-nodejs22 Link

Pull (multi-arch manifest)

docker pull ghcr.io/openhands/agent-server:14a6481-python

Run

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

All tags pushed for this build

ghcr.io/openhands/agent-server:14a6481-golang
ghcr.io/openhands/agent-server:v1.0.0a3_golang_tag_1.21-bookworm_binary
ghcr.io/openhands/agent-server:14a6481-java
ghcr.io/openhands/agent-server:v1.0.0a3_eclipse-temurin_tag_17-jdk_binary
ghcr.io/openhands/agent-server:14a6481-python
ghcr.io/openhands/agent-server:v1.0.0a3_nikolaik_s_python-nodejs_tag_python3.12-nodejs22_binary

The 14a6481 tag is a multi-arch manifest (amd64/arm64); your client pulls the right arch automatically.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 21, 2025

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/agent
   agent.py1585366%57–58, 63–64, 75, 77, 141, 145–146, 153–154, 156–158, 160–162, 178, 193, 196, 201, 204–205, 209, 216, 242, 247, 277, 281, 286, 297, 300, 322–324, 326, 338–339, 344–345, 357–360, 368–369, 374, 386–387, 392–393, 423, 444
   base.py1621690%145, 151, 169–171, 220, 228–229, 260, 306, 313, 326, 363–364, 374–375
openhands-sdk/openhands/sdk/conversation
   base.py601378%95, 106, 160, 162, 170, 173–174, 176, 178, 184–187
   state.py1321787%131, 172, 197, 242–244, 249, 251, 256, 259–261, 290, 308, 317, 332, 338
openhands-sdk/openhands/sdk/conversation/impl
   local_conversation.py1594770%132–133, 153, 158, 169, 186, 194–196, 200–201, 228, 250–251, 254, 261, 282–283, 285, 289–291, 299, 301, 303, 307, 309–311, 313, 315, 321–322, 335–336, 338, 340, 344–347, 369, 371–373, 390, 392
   remote_conversation.py35123931%47–59, 66–69, 89–94, 97–101, 104–108, 111–113, 115–118, 121–124, 127–128, 130–142, 145–150, 167–171, 173, 177, 179–180, 182–185, 187, 193, 195, 197–199, 201–203, 207, 209–212, 216, 221–222, 224, 227, 236–237, 240–241, 254–256, 259–260, 264, 266–267, 270, 273–275, 279, 281, 283–285, 288–290, 295–297, 299, 304, 309, 314–317, 320, 329, 337–340, 343, 348–349, 354–358, 363–367, 372–375, 378, 382–383, 387, 391, 394, 434–438, 440–441, 453, 456, 458–460, 463, 466, 468, 471, 474–475, 478–479, 482–485, 487, 490, 493, 499, 502, 504–505, 509, 514, 519–521, 527, 533–535, 538, 543, 550–551, 558, 560–564, 567–568, 577, 585, 590–592, 594, 597, 599–600, 616, 623, 629–630, 633, 635–639, 641–644, 647–650
TOTAL7986342357% 

Copy link
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.

It's... accurate that Agents themselves don't 'hold' this status, but I always think of it as a descriptive term, not a term about composition. 🤔
It describes the situation in which the agent is...
On the other hand, I'm looking at the code in the whole PR, and it seems like 'attaching' it to conversation makes sense too.

I guess the question is, which one is more clear to client developers / UIs / users? Do we want them to understand and speak about Conversations rather than about Agents?
Is this rename related to the delegation discussion?

@simonrosenberg
Copy link
Collaborator Author

simonrosenberg commented Oct 21, 2025

It's... accurate that Agents themselves don't 'hold' this status, but I always think of it as a descriptive term, not a term about composition. 🤔 It describes the situation in which the agent is... On the other hand, I'm looking at the code in the whole PR, and it seems like 'attaching' it to conversation makes sense too.

I guess the question is, which one is more clear to client developers / UIs / users? Do we want them to understand and speak about Conversations rather than about Agents? Is this rename related to the delegation discussion?

No. It's just that copilot guessed wrong the path to import the "agent execution status" because it's not anywhere near the agent, and it got me thinking.

It is descriptive, but it's deceitful concerning our implementation.
"Conversation status" is also pretty natural imo "oh the conversation is paused" "Oh the conversation is running again! yay!" I could imagine developers saying that while monitoring an agentic workflow :p

@simonrosenberg
Copy link
Collaborator Author

simonrosenberg commented Oct 21, 2025

It's... accurate that Agents themselves don't 'hold' this status, but I always think of it as a descriptive term, not a term about composition. 🤔 It describes the situation in which the agent is... On the other hand, I'm looking at the code in the whole PR, and it seems like 'attaching' it to conversation makes sense too.

I guess the question is, which one is more clear to client developers / UIs / users? Do we want them to understand and speak about Conversations rather than about Agents? Is this rename related to the delegation discussion?

We should also probably rename state.agent_status to state.execution_status

Perhaps we should also rename ConversationExecutionStatus -> ConversationStateExecutionStatus so it's really programmatic? But State + Status is super redundant @enyst

Updated test calls in test_conversation_service.py to use the new parameter name 'execution_status' instead of the old 'agent_status' parameter name.

Co-authored-by: openhands <[email protected]>
- Added execution_status property to RemoteState class to satisfy ConversationStateProtocol
- Made agent_status a backward compatibility property that delegates to execution_status
- Added backward compatibility for reading both execution_status and agent_status from server response
- Fixed type checking errors in remote conversation implementation

Co-authored-by: openhands <[email protected]>
- Removed AgentExecutionStatus alias for ConversationExecutionStatus
- Removed agent_status backward compatibility properties from ConversationState and RemoteState
- Removed agent_status property from ConversationStateProtocol
- Simplified RemoteState execution_status property to only read execution_status field
- Cleaned up codebase by removing all backward compatibility layers

Co-authored-by: openhands <[email protected]>
@simonrosenberg simonrosenberg changed the title Rename AgentExecutionStatus to ConversationExecutionStatus Rename AgentExecutionStatus -> ConversationExecutionStatus & state.agent_status -> executiong_status Oct 21, 2025
@simonrosenberg simonrosenberg changed the title Rename AgentExecutionStatus -> ConversationExecutionStatus & state.agent_status -> executiong_status Rename AgentExecutionStatus -> ConversationExecutionStatus & state's agent_status -> executiong_status Oct 21, 2025
@simonrosenberg simonrosenberg changed the title Rename AgentExecutionStatus -> ConversationExecutionStatus & state's agent_status -> executiong_status refactor: rename AgentExecutionStatus -> ConversationExecutionStatus & state's agent_status -> executiong_status Oct 21, 2025
@simonrosenberg simonrosenberg requested a review from enyst October 21, 2025 09:32
@enyst
Copy link
Collaborator

enyst commented Oct 21, 2025

Aha, I'm not sure though! Tiny fun detail about this:

Do we want them to understand and speak about Conversations rather than about Agents?

I was just mulling these days about... what's in a name. 😅

slack bit

It turns out that we believe Agent Skills sound more cool than mundane things like "writing a md file", even though md files is what reality is under the hood.

Whether "Conversation status" is better than "Agent status", I don't know.

I do agree with you that what LLMs do actually has the right to matter! In fact, I made myself a theory on LLM-driven development... about this time last year, when I first saw o1 unable to fix tests because we were breaking the assumptions of some Pydantic annotation in our code. It was fascinating to see it try over and over, and every time the Pydantic world knowledge took over and made it stumble. 😅 ❤️
(I eventually fixed that annotation instead of forcing the poor thing through it - which was of course the right thing to do!)

In this case, though, Copilot is bad, lol, and I haven't seen GPT-5 get confused, on the contrary it will find things. I'd love to get more opinions on this one!

What LLM was Copilot using?

@simonrosenberg
Copy link
Collaborator Author

simonrosenberg commented Oct 21, 2025

I do agree with you that what LLMs do actually has the right to matter! In fact, I made myself a theory on LLM-driven development... about this time last year, when I first saw o1 unable to fix tests because we were breaking the assumptions of some Pydantic annotation in our code. It was fascinating to see it try over and over, and every time the Pydantic world knowledge took over and made it stumble. 😅 ❤️ (I eventually fixed that annotation instead of forcing the poor thing through it - which was of course the right thing to do!)

Poor o1 stuck in a logic loop :p

In this case, though, Copilot is bad, lol, and I haven't seen GPT-5 get confused, on the contrary it will find things. I'd love to get more opinions on this one!
What LLM was Copilot using?

It was the free-tier autocompletion model GPT-4o Copilot. Probably not the brightest model out there :p
Sure, a better model would have found it, but it's not a reason to make things slightly more tricky than it should be in our repo... I think following the principle of least surprise her makes sense.
Agreed that it's a good idea to name objects so the codebase attracts user attention. But in that case it's a pretty deep object that probably won't be getting much user attention, so I don't know...

@simonrosenberg simonrosenberg self-assigned this Oct 21, 2025
@simonrosenberg simonrosenberg added the review-this This label triggers a PR review by OpenHands label Oct 21, 2025
@openhands-ai
Copy link

openhands-ai bot commented Oct 21, 2025

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • PR Review by OpenHands

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #839 at branch `openhands/rename-agent-execution-status-to-conversation-execution-status`

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

Copy link
Collaborator

@xingyaoww xingyaoww left a comment

Choose a reason for hiding this comment

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

Let's wait for @tofarr's confirmation!

@simonrosenberg
Copy link
Collaborator Author

@tofarr bump

Copy link
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.

What if maybe we table this until we finish Delegation and its follow-up? Over there, it seems we might want to rethink the Agent doing too much, like executing things. That will likely change what Conversation does, and it might affect how state / status feels like.

I'd personally incline to keep it Agent status. Conversation is an orchestrator.

Not a strong opinion, though, and FWIW I'm usually too conservative on this kind of stuff. Happy to go with what you like.


To note, the important part 😊 !

it's not a reason to make things slightly more tricky than it should be in our repo... I think following the principle of least surprise her makes sense.

I hear you! I wonder what others do.

I do think that LLM Driven Development should be a thing - and I've been nitpicking any PRs for long, to design and name things in an easier way for LLMs. Still, Copilot with 4o is really bad, sorry, I just don't think it's a good indicator yet.

@blacksmith-sh
Copy link
Contributor

blacksmith-sh bot commented Oct 30, 2025

[Automatic Post]: It has been a while since there was any activity on this PR. @simonrosenberg, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-this This label triggers a PR review by OpenHands

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rename AgentExecutionStatus to ConversationExecutionStatus

5 participants