Skip to content

feat: API design: launched agent profile provenance names#3788

Merged
enyst merged 1 commit into
mainfrom
clarify-launched-agent-profile
Jun 18, 2026
Merged

feat: API design: launched agent profile provenance names#3788
enyst merged 1 commit into
mainfrom
clarify-launched-agent-profile

Conversation

@enyst

@enyst enyst commented Jun 18, 2026

Copy link
Copy Markdown
Member

HUMAN:
We now have LLM profiles and Agent profiles: this PR proposes simply to keep the API clear on which is which.

AGENT:

Why

Follow-up to review feedback on #3784: the codebase now has both LLM profiles and agent profiles, so newly added public API names should make the profile kind explicit where the shorter profile wording could be ambiguous.

Summary

  • Renamed the new conversation provenance model from LaunchedProfile to LaunchedAgentProfile.
  • Renamed the API/persistence field from launched_profile to launched_agent_profile.
  • Renamed the nested provenance ID from profile_id to agent_profile_id.

Issue Number

Follow-up to #3784 / #3720.

How to Test

Validated locally with:

uv run pytest tests/agent_server/test_agent_profile_conv_start.py -q

Result:

21 passed, 6 warnings in 0.69s

Also ran pre-commit on all changed files:

uv run pre-commit run --files \
  openhands-agent-server/openhands/agent_server/conversation_service.py \
  openhands-agent-server/openhands/agent_server/models.py \
  openhands-sdk/openhands/sdk/profiles/agent_profile.py \
  openhands-sdk/openhands/sdk/profiles/__init__.py \
  tests/agent_server/test_agent_profile_conv_start.py

Result:

Ruff format..............................................................Passed
Ruff lint................................................................Passed
PEP8 style check (pycodestyle)...........................................Passed
Type check with pyright..................................................Passed
Check import dependency rules............................................Passed
Check Tool subclass registration.........................................Passed

Video/Screenshots

No UI changes. The affected behavior is an agent-server/SDK response and persistence schema naming cleanup; targeted unit tests cover the updated serialization shape.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

I intentionally did not rename the existing legacy LLM-profile API surfaces such as /api/profiles, active_profile, or switch_profile; those are already established and documented as LLM-profile paths. This PR focuses on the new agent-profile provenance names introduced by #3784, where changing the names now is still small and targeted.

Because #3784 only merged today and this change is intended to land before release, this PR does not carry compatibility aliases for the short-lived launched_profile.profile_id shape.

This PR description AGENT section was updated 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: 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:acde9b2-python

Run

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

All tags pushed for this build

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

About Multi-Architecture Support

  • Each variant tag (e.g., acde9b2-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., acde9b2-python-amd64) are also available if needed

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-agent-server/openhands/agent_server
   conversation_service.py64912580%146–147, 156, 182–183, 187–188, 193, 275–276, 279–280, 290, 419–420, 451, 454, 461–467, 494, 500, 596, 602, 607, 613, 621–622, 631–634, 643, 655, 663, 708–709, 770, 811–815, 817–818, 821–822, 832, 844–849, 947, 954–958, 961–962, 966–970, 973–974, 978–982, 985–986, 1008–1009, 1013–1014, 1016–1018, 1020, 1023, 1031–1035, 1044, 1052–1056, 1059–1064, 1066–1067, 1081, 1091, 1095, 1097–1098, 1103–1104, 1110–1111, 1121, 1139–1140, 1170, 1185, 1218, 1518, 1521
openhands-sdk/openhands/sdk/profiles
   agent_profile.py901385%237, 240, 294–296, 299–302, 306–307, 311, 335
TOTAL32782692378% 

@enyst enyst changed the title Clarify launched agent profile provenance names feat: API design: launched agent profile provenance names Jun 18, 2026

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

⚠️ QA Report: PASS WITH ISSUES

Runtime verification confirms the PR delivers the explicit launched agent profile provenance names and keeps the short-lived legacy payload loadable; the only issue observed is an unrelated PR-description CI gate failure requiring human input.

Does this PR achieve its stated goal?

Yes. On main, the public model/export is still LaunchedProfile and conversation JSON reserializes provenance as launched_profile.profile_id; on the PR branch, the same runtime checks expose LaunchedAgentProfile, persist/return launched_agent_profile.agent_profile_id, and load the legacy launched_profile.profile_id payload before reserializing it to the explicit names. This directly verifies the PR goal of clarifying provenance names while preserving compatibility for conversations created with the short-lived merged payload shape.

Phase Result
Environment Setup uv sync --dev completed successfully; no repo files modified.
CI Status ⚠️ 27 successful, 1 failed (Validate PR description), 2 skipped, 3 in progress at snapshot time.
Functional Verification ✅ Before/after runtime script exercised SDK imports, persistence JSON, legacy loading, and ConversationInfo response shape.
Functional Verification

Test 1: Public provenance model name and serialized nested ID

Step 1 — Establish baseline on origin/main:
Ran OPENHANDS_SUPPRESS_BANNER=1 uv run python /tmp/qa_agent_profile_provenance.py after git checkout --detach origin/main:

commit 76e0e790

== Public profile provenance imports ==
LaunchedAgentProfile import/use: FAIL ImportError cannot import name 'LaunchedAgentProfile' from 'openhands.sdk.profiles'
LaunchedProfile import: OK
LaunchedProfile dump: {"profile_id": "55bc66e6-3b5f-440b-b606-2ed40587f318", "revision": 7}

This shows the baseline API still used the ambiguous LaunchedProfile name and profile_id JSON key.

Step 2 — Apply the PR's changes:
Checked out clarify-launched-agent-profile at 08e687c4.

Step 3 — Re-run with the PR branch:
Ran OPENHANDS_SUPPRESS_BANNER=1 uv run python /tmp/qa_agent_profile_provenance.py:

commit 08e687c4

== Public profile provenance imports ==
LaunchedAgentProfile import: OK
LaunchedAgentProfile dump: {"agent_profile_id": "e79df535-2672-476c-b78a-8fef172a1334", "revision": 7}
LaunchedProfile import/use: FAIL ImportError cannot import name 'LaunchedProfile' from 'openhands.sdk.profiles'

This confirms the public exported model and nested serialized ID now use the explicit agent-profile naming.

Test 2: StoredConversation persistence shape and legacy compatibility

Step 1 — Establish baseline on origin/main:
The same baseline run produced:

== StoredConversation new-shape persistence ==
new-shape kwarg accepted by model: True
dump has launched_agent_profile: False
dump has launched_profile: False

== Legacy short-lived payload compatibility ==
legacy payload loads: OK
reserialized keys: ['launched_profile']
reserialized provenance: {"launched_profile": {"profile_id": "55bc66e6-3b5f-440b-b606-2ed40587f318", "revision": 4}}

This shows main did not persist the new explicit field name and still reserialized the legacy payload using the old names.

Step 2 — Apply the PR's changes:
Checked out clarify-launched-agent-profile at 08e687c4.

Step 3 — Re-run with the PR branch:
The PR branch run produced:

== StoredConversation new-shape persistence ==
dump has launched_agent_profile: True
dump has launched_profile: False
dumped provenance: {"agent_profile_id": "e79df535-2672-476c-b78a-8fef172a1334", "revision": 7}
json reload agent_profile_id: e79df535-2672-476c-b78a-8fef172a1334

== Legacy short-lived payload compatibility ==
legacy payload loads: OK
reserialized keys: ['launched_agent_profile']
reserialized provenance: {"launched_agent_profile": {"agent_profile_id": "e79df535-2672-476c-b78a-8fef172a1334", "revision": 4}}

This confirms new persistence uses launched_agent_profile.agent_profile_id, JSON round-trip preserves it, and legacy launched_profile.profile_id still loads but reserializes to the explicit names.

Test 3: ConversationInfo response shape

Step 1 — Establish baseline on origin/main:
The baseline run produced:

== ConversationInfo response shape ==
response launched keys: ['launched_profile']
response provenance: {"launched_profile": {"profile_id": "55bc66e6-3b5f-440b-b606-2ed40587f318", "revision": 3}}

This shows user-facing conversation info responses previously exposed the ambiguous field names.

Step 2 — Apply the PR's changes:
Checked out clarify-launched-agent-profile at 08e687c4.

Step 3 — Re-run with the PR branch:
The PR branch run produced:

== ConversationInfo response shape ==
response launched keys: ['launched_agent_profile']
response provenance: {"launched_agent_profile": {"agent_profile_id": "e79df535-2672-476c-b78a-8fef172a1334", "revision": 3}}

This confirms the API response model now serializes the explicit provenance field/key pair.

Issues Found

  • 🟡 Non-functional CI issue: Validate PR description is failing because the first visible PR description line is not HUMAN: and a human-written note is missing. Per repo guidance, I did not edit the human-only PR description fields. Remaining in-progress checks at snapshot time: Build & Push (java-amd64), Build & Push (java-arm64), and qa-changes.

This review was generated by an AI agent (OpenHands) on behalf of the user.

Rename the conversation-start provenance model and API field to explicitly reference agent profiles, while accepting the short-lived legacy payload names during validation.

Co-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst force-pushed the clarify-launched-agent-profile branch from 08e687c to acde9b2 Compare June 18, 2026 13:21
@enyst enyst merged commit d7392de into main Jun 18, 2026
37 of 38 checks passed
@enyst enyst deleted the clarify-launched-agent-profile branch June 18, 2026 13:42
@enyst enyst mentioned this pull request Jun 18, 2026
5 tasks
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.

3 participants