Skip to content
This repository was archived by the owner on Sep 7, 2026. It is now read-only.

feat(client): add conversation navigate endpoint - #254

Merged
VascoSch92 merged 3 commits into
mainfrom
vasco/add-navigate-endpoint
Jul 3, 2026
Merged

VascoSch92 merged 3 commits into
mainfrom
vasco/add-navigate-endpoint

Conversation

@VascoSch92

Copy link
Copy Markdown
Member

Summary

Adds client support for POST /api/conversations/{id}/navigate (agent-server / software-agent-sdk #3923, released in v1.31.0). Navigate moves a conversation's HEAD to an existing event, re-rooting the active branch the agent runs on next — all branches stay on disk and, unlike fork, no new conversation is created. Mirrors the Python SDK's RemoteConversation.navigate_to.

Changes

  • ConversationClient.navigateConversation(id, request?, { includeSkills? }) — POST .../navigate, returns the updated ConversationInfo carrying the new leaf_event_id. Follows the forkConversation template.
  • RemoteConversation.navigateTo(eventId) — ergonomic wrapper that posts and then refreshes cached state (leaf_event_id is not broadcast over the WebSocket), matching the Python SDK.
  • Types — NavigateConversationRequest { event_id?: string | null } and an explicit leaf_event_id?: string | null on ConversationInfo. event_id: null selects the empty tree (a deliberate new root).

Tests

  • Unit (api-clients.test.ts): client-level navigate with include_skills, navigate-to-null, and the navigateTo wrapper (POST + state refresh).
  • Integration (deterministic-api.integration.test.ts): re-roots HEAD across two real events and back to the empty tree, plus 404 contract guards for an unknown conversation and an unknown event_id.

Verification

  • tsc --noEmit, eslint, prettier --check: clean
  • Unit suite: all pass
  • Integration: ran against ghcr.io/openhands/agent-server:1.31.0-python (the pinned CI image) — deterministic suite green, including the two navigate tests.

Support POST /api/conversations/{id}/navigate, which moves a conversation's HEAD to an existing event, re-rooting the active branch in place (no new conversation, unlike fork). Mirrors the Python SDK's RemoteConversation.navigate_to.

- ConversationClient.navigateConversation(id, request, { includeSkills }) returns the updated ConversationInfo carrying the new leaf_event_id
- RemoteConversation.navigateTo(eventId) posts then refreshes cached state (leaf_event_id is not broadcast over the WebSocket)
- Add NavigateConversationRequest and an explicit leaf_event_id on ConversationInfo
- Unit tests plus a deterministic integration test covering re-root semantics and the 404 contract guards
@github-actions github-actions Bot added the type: feat A new feature label Jul 2, 2026
@VascoSch92
VascoSch92 requested a review from enyst July 2, 2026 21:30
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Endpoint audit

❌ 6 off-contract call(s) — not on the agent-server · classifiers: cloud

Category Count
❌ Off-contract (not on agent-server) 6
  ⛔ no known backend 5
  ↗️ served by cloud 1
➕ Missing API (agent-server has, client lacks) 10
agent-server endpoints 116
client endpoints 110

❌ Not on agent-server (gated, 6)

⛔ (no known backend) — served by no backend we can see (5)

  • DELETE /api/meta-profiles/{}
  • GET /api/meta-profiles
  • GET /api/meta-profiles/{}
  • POST /api/meta-profiles/{}
  • POST /api/meta-profiles/{}/activate

↗️ served by cloud (1)

  • GET /api/shared-events/search

➕ Missing API — agent-server exposes it, client does not implement (10)

  • GET /
  • GET /api/conversations
  • GET /api/conversations/{}/events
  • GET /api/conversations/{}/workspace
  • GET /api/conversations/{}/workspace/{}
  • GET /api/file/archive
  • GET /api/init
  • POST /api/conversations/{}/load_plugin
  • POST /api/init
  • POST /api/sub-agents

@enyst

enyst commented Jul 3, 2026

Copy link
Copy Markdown
Member

@OpenHands I don’t see any footguns here, do you? /codereview
Feel free to post your review with gh api and event approved or comment

@openhands-ai

openhands-ai Bot commented Jul 3, 2026

Copy link
Copy Markdown

I'm on it! enyst can track my progress at all-hands.dev

@enyst enyst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🟡 Taste Rating: Acceptable

I found one small public-API footgun, not a logic problem in the endpoint implementation:

[IMPROVEMENT OPPORTUNITIES]

  • [src/index.ts] Public type export: NavigateConversationRequest is added in src/models/conversation.ts but is not exported from the package root alongside ForkConversationRequest. Because package.json only exposes . and ./clients (not ./models/conversation), consumers using ConversationClient.navigateConversation(...) cannot name/import the new request type from the published package. Add NavigateConversationRequest to the conversation model export block in src/index.ts. The rest of the route wiring looks consistent with forkConversation: path/body shape, include_skills, null for the empty tree, and the RemoteConversation.navigateTo() refresh are all covered by unit and deterministic integration tests.

I couldn’t run the tests locally because this checkout has no node_modules, but the PR checks are green, including unit, build, endpoint audit, and integration-test.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟢 LOW
    Small additive client API for a pinned server endpoint. No dependency changes, no behavior changes to existing methods, and regression coverage exercises both mocked client calls and the real deterministic server contract. Main risk is packaging/API discoverability of the new request type.

VERDICT:
✅ Worth merging once the type export is added.

KEY INSIGHT:
The implementation itself is simple and sound; the only footgun is making sure the new public request type is actually public in the packaged SDK.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

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

@openhands-ai

openhands-ai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Posted a top-level PR review comment here:

#254 (review)

Summary:

  • No endpoint logic footguns found.
  • Flagged one small public API/package footgun: NavigateConversationRequest is added but not exported from src/index.ts, so published-package consumers can’t easily import/name it.
  • CI checks are green.
  • I did not run local tests because this checkout has no node_modules.

Consumers of ConversationClient.navigateConversation() can now import
and name the request type from the published package, matching
ForkConversationRequest.
@VascoSch92

Copy link
Copy Markdown
Member Author

@enyst corrected ;-)

@VascoSch92
VascoSch92 merged commit 724892b into main Jul 3, 2026
11 checks passed
This was referenced Jul 2, 2026
@openhands-release-bot openhands-release-bot Bot added the released: v1.32.0 Shipped in v1.32.0 label Jul 7, 2026
@openhands-release-bot

Copy link
Copy Markdown
Contributor

🚀 Released in v1.32.0.

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

Labels

released: v1.32.0 Shipped in v1.32.0 type: feat A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants