Skip to content

Node and Rust SDK transport for native AHP endpoints - #2721

Draft
SteveSandersonMS wants to merge 2 commits into
mainfrom
slice1-native-ahp-endpoints
Draft

SteveSandersonMS wants to merge 2 commits into
mainfrom
slice1-native-ahp-endpoints

Conversation

@SteveSandersonMS

@SteveSandersonMS SteveSandersonMS commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Add transport-neutral Node and Rust SDK APIs for native runtime AHP 0.9 endpoints. Applications own their listener and forward opaque messages; the SDKs do not implement an AHP agent mapping or start a second runtime.

  • Endpoint registration, independent logical connections, bounded per-direction delivery, exposure refresh, capabilities, and idempotent cleanup.
  • Executable create/resume/list/control callbacks, endpoint-local authorization, reentrant ordinary SDK calls, and explicit failure/cancellation handling.
  • Rust wire types and typed RPC methods generated directly from the locally built companion runtime schemas. The generated-file refresh includes the other contract changes in that runtime; the generator also distinguishes a literal unknown enum value from its forward-compatible catch-all.
  • Reference documentation, Node WebSocket server/client examples, and recorded end-to-end agent coverage through the standard AHP client.

Runtime companion: https://github.com/github/copilot-agent-runtime/pull/21650. Runtime support must land before releasing this SDK API.

Runtime integration and scope

The companion imports copilotd’s AHP 0.9 host and agent mapping into the runtime and connects it to existing native sessions. CLI sharing and standalone --ahp-host use that common implementation in place of the separate hosting implementations on runtime main.

The imported subset supports client-contributed tools/plugins and the AHP MCP OAuth bridge. Remote terminal/PTY services, filesystem services/watches, copilotd Mission Control mirroring, and project/worktree provisioning are not included. Ordinary runtime tools and the CLI’s existing Mission Control integration remain available.

Applications supply the physical listener, authentication, and session-policy callbacks. The runtime owns AHP state and protocol mapping; the SDKs handle endpoint connection and delivery lifecycle. No runtime-owned public listener, internal SDK client, or additional runtime process is introduced. The CLI uses the same raw ahp.* protocol over an in-process connection without importing either SDK package.

Recorded end-to-end coverage

Two Rust E2E scenarios start an application-owned WebSocket listener and launch the official @microsoft/agent-host-protocol client:

  • Attach an existing Rust-owned SDK session and drive an agent/tool turn through AHP.
  • Create a session through the Rust policy callback, then drive its agent/tool turn through AHP.

Both scenarios require the Rust encrypt_string tool handler to execute exactly once, observe successful AHP tool completion and the model response, reject an excluded session URI, reconnect and recover history, and confirm endpoint disposal leaves the ordinary SDK owners alive.

These use the existing CapiProxy record-replay mechanism and the shared test/snapshots/tools/invokes_custom_tool.yaml recording. They do not fabricate AHP responses or make live model calls. Both passed against the locally built companion runtime. The runtime prerequisite is explicit; unsupported runtimes fail rather than silently skipping the scenarios.

Rust transport coverage also exercises opaque UTF-8 forwarding, physical-delivery acknowledgments, wire ordering, independent connections, input/output bounds including in-flight work, callback reentrancy, cancellation ordering, abandoned registration cleanup, disposal, and unsupported-runtime errors. Local validation: 232 library tests, 11 AHP transport tests, 11 JSON-RPC tests, both recorded AHP E2Es, all-targets Clippy, rustdoc, formatting, and reproducible schema generation.

Rollout

AHP 0.9 only; this is not full copilotd parity. This SDK PR remains draft and depends on the runtime companion. The current published CLI pin does not yet supply these endpoints; advance it to a release containing the companion before landing/releasing this API and its E2Es.

Add bounded opaque message transport, application-owned lifecycle and exposure callbacks, endpoint cleanup, and a standard-client WebSocket sample.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Generate Rust wire contracts from the matching local runtime schemas. Add transport-neutral endpoint policies, bounded ordered delivery, cancellation and lifecycle handling, and standard AHP-client replay scenarios for Rust-owned sessions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@SteveSandersonMS SteveSandersonMS changed the title Node SDK transport for native AHP endpoints Node and Rust SDK transport for native AHP endpoints Sep 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

SDK Consistency Review — PR #2721

This PR touches only the Node.js and Rust SDKs.

✅ Native AHP endpoints (createAhpEndpoint) — consistent by design

The new experimental AHP endpoint feature (ahp.ts in Node.js, ahp.rs in Rust) is added to both SDKs together, with matching semantics (opaque-message transport, endpoint/connection lifecycle, callback policy hooks, per-direction buffering limits) and cross-referencing docs (nodejs/docs/ahp-endpoints.mdrust/README.md). Both are explicitly marked experimental and require a runtime with native ahp.* RPC support, so it's reasonable this isn't rolled out to Python/Go/.NET/Java yet. No action needed here.

⚠️ One parity gap found

SessionConfig.name (a new optional friendly-name field for session creation, forwarded as name in the session.create request) was added only to the Node.js SDK. Python, Go, .NET, Java, and Rust don't expose an equivalent option. Left an inline comment with suggestions for language-idiomatic naming in each SDK.

Other changes

  • scripts/codegen/rust.ts: minor codegen fix for unknown enum variant naming — Rust-only tooling change, no parity concern.

Generated by SDK Consistency Review Agent for #2721 · copilot · sonnet50 · 96.1 AIC · ⌖ 12.4 AIC · ⊞ 7.8K ·

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for #2721 · copilot · sonnet50 · 96.1 AIC · ⌖ 12.4 AIC · ⊞ 7.8K

Comment thread nodejs/src/types.ts
/**
* Optional friendly name. A named session is persisted even before its first turn.
*/
name?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This adds a new name option to SessionConfig (persisted friendly name, set at session creation) but only in the Node.js SDK. The other SDKs (Python create_session, Go CreateSession, .NET SessionConfig, Java SessionConfig, Rust SessionConfig) don't expose an equivalent parameter for setting a session's friendly name at creation time.

Since this is a new user-facing capability (not an internal/runtime-specific optimization), consider adding the equivalent option to the other SDKs for parity, using each language's naming convention (e.g. Python name: str | None, Go Name string, .NET Name, Java setName, Rust name: Option<String>) — assuming the underlying session.create RPC field is available to all of them.

This branch has not been deployed

No deployments
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.

1 participant