Skip to content

Expose runtime-supervised AHP hosts through the Node SDK - #2738

Closed
SteveSandersonMS wants to merge 29 commits into
mainfrom
workstream-1a/runtime-supervised-lite
Closed

SteveSandersonMS wants to merge 29 commits into
mainfrom
workstream-1a/runtime-supervised-lite

Conversation

@SteveSandersonMS

@SteveSandersonMS SteveSandersonMS commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds experimental Node and Rust APIs for a runtime-supervised AHP host. The existing runtime launches copilotd-lite, reusing copilotd's complete AHP server with a separate SDK participant—not a second runtime.

The requesting SDK connection owns the host. Disposal, owner disconnect, and runtime shutdown close the listener and reap the child without deleting sessions. Handles expose the host ID, URL, PID, optional token, and explicit async disposal; optional exit callbacks run at most once.

Usage

Node

import { CopilotClient } from "@github/copilot-sdk";

await using client = new CopilotClient();
await client.start();
const host = await client.startAhpHost({
    onExit: (exit) => console.log(exit.reason),
});

// Connect an AHP client using host.url and host.token; do not log the token.
// Keep client alive while hosting. Client disposal also stops the host.
// To stop hosting earlier: await host.dispose();

Rust

use github_copilot_sdk::{AhpHostOptions, Client, ClientOptions};

let client = Client::start(ClientOptions::default()).await?;
let host = client.start_ahp_host(
    AhpHostOptions::new().with_on_exit(|exit| println!("{:?}", exit.reason)),
).await?;

// Connect an AHP client using host.url and host.token.as_deref().
// Keep client alive while hosting; dropping the handle does not stop it.
// To stop hosting earlier: host.dispose().await?;
client.stop().await?;

Listener options: hostname, port, token, and requireConnectionToken (Rust: matching with_* builders). Defaults are 127.0.0.1, an OS-allocated port, and a generated required token. Explicit non-loopback binding is supported. Disabling connection-token auth returns no token and cannot be combined with a supplied token; separate AHP resource authentication remains intact. No per-host working-directory override.

Validation

  • Node 8/8 and Rust 9/9 real-AHP E2Es pass against both local source builds and the same assembled candidate, sharing existing inference snapshots.
  • Packaged live-inference smoke passes: AHP streaming, SDK coexistence, and listener/child cleanup.
  • Focused API, generated-binding, type, and lint checks pass.

Dependencies and scope

Companion drafts: host #1292, runtime #22049. Requires their runtime/host artifacts; release publication, acquisition credentials, version pins, platform jobs, and AHP CI activation follow separately. Local validation is Linux x64, not signed cross-platform release evidence.

Application create/resume callbacks and projection migration are out of scope. Lite's GHES shell-credential support is deferred to runtime #22077; traditional copilotd is unchanged.

Draft—do not merge.

SteveSandersonMS and others added 13 commits September 21, 2026 09:04
Use the standard AHP 0.9.0 client, existing inference replay, OS process ancestry checks, and lifecycle coverage for runtime-owned lite hosts. Add a real-client manual smoke.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reuse the runtime host E2Es for assembled candidate packages, checking local source commits and artifact hashes before using the SDK materializer. Remove development overrides from candidate runtime environments and assert bundled lookup at OS level.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep listener connection credentials separate from normal GitHub AHP authentication. Reuse the existing replay harness credential for E2Es and a caller credential for live smoke.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Regenerate Node and Rust bindings from the companion runtime source schema. Include its command queue result union so the current-main Rust bindings compile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add thin generated-RPC start/dispose handles and observable termination. Reject pending requests on owner EOF and preserve URI reconnects without reclaiming hosts. Document ownership and local source provenance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gate runtime download, discovery and launch behind the runtime feature. Preserve default bundled behavior, and add connection-level framed request handlers with EOF cancellation and writer teardown for supervised child shutdown.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use Linux procfs without ps, respect lite private-stream hardening, and assemble candidate packages with the runtime installer and npm pack.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Avoid retaining the Rust Client through registered reverse-RPC handlers. Drain parsed Node JSON-RPC messages through a local queue barrier before disconnect cleanup and pending-request rejection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use advertised protected-resource metadata for both replay endpoints and live dotcom authentication.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep offline provenance validation from acquiring unused cross-platform dependencies.

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

This comment has been minimized.

Assert the real shutdown response, clean host exit notification and child cleanup before SDK-owned runtime reaping; reproduce the shutdown-gate regression without a model turn.

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

This comment has been minimized.

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

This comment has been minimized.

SteveSandersonMS and others added 2 commits September 21, 2026 12:31
Exercise same-home exclusion, owner disconnect, listener restart, forced child death, and SDK baseDirectory across runtime restart with real AHP and existing inference replay. Document deferred coordinated release and CI activation.

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

This comment has been minimized.

Track runtime issue #22077 and clarify that traditional copilotd is unaffected by removing the lite credential workaround.

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

This comment has been minimized.

SteveSandersonMS and others added 7 commits September 21, 2026 14:20
Use the standard pinned Rust AHP client against real local runtime and lite artifacts. Reuse the canonical inference recording and existing candidate materializer for source/candidate parity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expose runtime-owned AHP listeners through generated host RPCs with local one-shot exit callbacks and explicit async disposal. Cover forwarding and lifecycle cleanup with protocol fixtures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Forward every disposal to the runtime, route optional exit callbacks at most once, and keep listener options and lifecycle ownership in the runtime. Regenerate host protocol surfaces from local runtime schemas, with narrowly scoped generator fixes for named references, nullable booleans, and empty dictionary replies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cover IPv6 and localhost, reject wrong connection tokens and fractional ports through direct RPC, and assert listener tokens never enter child arguments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use optional exit callbacks and direct RPC cleanup; cover listener addresses, ports, token modes, and retained AHP resource authentication with existing inference replay.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Regenerate existing language bindings against final local runtime schema documentation, retaining only host changes. Verify the six affected files differ only in comments and documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SteveSandersonMS and others added 3 commits September 21, 2026 14:33
Require the runtime feature, remove conflicting harness COPILOT_HOME when testing base_directory, use the shell's kill builtin, and leave already-exited hosts undisposed so runtime crash errors are not mistaken for successful cleanup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Retain repeated disposal assertions after SIGKILL so source and candidate E2Es verify the runtime fix rather than accepting its stored exit diagnostic as a cleanup error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Consume final canonical schema 6127cf93bea32d903a10761de9a0d03bb4b09c3eefb02f69339b2a0c15cda78d. Preserve nullable exit fields, assert the exact TypeScript wire contract, and forward the optional token directly. Rust generated source remains byte-identical to 14414f5.

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

This comment has been minimized.

Drain received runtime exits first, then report owner disconnection once for remaining callbacks without claiming cleanup acknowledgement. Preserve thin runtime-owned disposal and isolate callback panics.

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

Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

This PR (draft, "do not merge") adds the experimental runtime-supervised AHP host feature. I compared the Node.js and Rust implementations against Go, .NET, Python, and Java.

Findings

Scope matches the stated intent — no action needed.

  • The PR description explicitly scopes this to Node and Rust only ("Adds experimental Node and Rust APIs for a runtime-supervised AHP host"), and both implement the feature consistently:

    • client.startAhpHost(options) (Node) / client.start_ahp_host(options) (Rust) — parallel naming per language convention (camelCase vs snake_case).
    • Both expose hostname, port, token, requireConnectionToken/require_connection_token, and an optional exit callback (onExit / on_exit) fired at most once, with the same ownerDisconnected semantics on connection loss.
    • Both return a small handle (AhpHost) exposing hostId/host_id, url, pid, token, and an explicit async dispose().
    • Disconnection/cleanup handling (disconnectHosts() in Node, the dispatcher's owner-disconnect branch in Rust) is functionally equivalent.
  • Go, .NET, and Python only receive regenerated low-level RPC types (HostStartRequest, HostDisposeRequest, HostExitedNotification, ServerHostApi/Rpc.Host, etc.) as a side effect of the shared codegen scripts — there is no high-level convenience wrapper (StartAhpHost, start_ahp_host) added for these languages yet, and none for Java (no Java files touched by this PR at all).

  • This asymmetry is called out by the author in "Dependencies and scope" as intentional for this draft, with follow-up work (release pins, CI activation) gating a broader rollout.

Suggestion (non-blocking, for follow-up)

When this experimental API is promoted beyond Node/Rust, consider tracking parity work for Go, .NET, Python, and Java convenience wrappers (StartAhpHost/start_ahp_host/startAhpHost) mirroring the same option set and exit-callback semantics, so the low-level bindings already generated here don't stay unused in those SDKs.

No inline comments added — the current PR is internally consistent with its declared Node+Rust-only scope.

Generated by SDK Consistency Review Agent for #2738 · copilot · sonnet50 · 56.9 AIC · ⌖ 11.6 AIC · ⊞ 7.8K ·

@SteveSandersonMS

Copy link
Copy Markdown
Contributor Author

Superseded by https://github.com/github/copilot-agent-runtime/pull/22049 after the SDK sources moved into that repository. All changes through 0fce9d4, including Node/Rust AHP handles and Rust owner-disconnect callback parity, are preserved under src/sdk in runtime commit 6e1d3112; final runtime PR head is 52cdb800. Monorepo path/provenance adaptations are included. Node 8/8 and Rust 9/9 real-AHP E2Es pass against both source and assembled candidate artifacts. Closing this PR without merging; the combined runtime PR remains a draft.

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