Skip to content
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
e2f57e0
Add LLM inference callback support to Node SDK
Jun 15, 2026
9f854f8
feat: register llm inference handler globally on the SDK client
SteveSandersonMS Jun 15, 2026
8e305b5
test: assert /models catalog request now intercepts in callback
SteveSandersonMS Jun 15, 2026
e18edeb
feat: streaming LLM inference callback (httpStreamStart + e2e)
SteveSandersonMS Jun 15, 2026
6bcfd60
test: e2e for LLM inference callback error mapping
SteveSandersonMS Jun 15, 2026
6457cdc
refactor(llm-callback): drop inferred request metadata field
SteveSandersonMS Jun 15, 2026
d3eb4f5
feat(llm-callback): collapse to a single onLlmRequest with chunked body
SteveSandersonMS Jun 15, 2026
b95e6fa
feat(llm-callback): surface req.signal and propagate cancellation
SteveSandersonMS Jun 16, 2026
a5366e7
test(llm-callback): cover consumer-initiated cancellation
SteveSandersonMS Jun 16, 2026
510ce96
Add WebSocket transport to the LLM inference provider
SteveSandersonMS Jun 16, 2026
c241268
Add LlmRequestHandler base class for SDK consumers
SteveSandersonMS Jun 16, 2026
cb814e1
Harden LLM inference SDK adapter + WS handler; add unit tests
SteveSandersonMS Jun 16, 2026
8d5343b
Add SDK e2e asserting sessionId reaches the LLM callback (CAPI + BYOK)
SteveSandersonMS Jun 16, 2026
5325bd4
Port LLM inference callbacks to the .NET SDK
SteveSandersonMS Jun 16, 2026
f99182f
Collapse LLM inference callback public API to LlmRequestHandler
SteveSandersonMS Jun 16, 2026
c70adeb
Refine LLM inference callback handlers
SteveSandersonMS Jun 16, 2026
7484511
Add Python SDK support for LLM inference callbacks
SteveSandersonMS Jun 19, 2026
69a7f05
Add Go SDK support for LLM inference callbacks
SteveSandersonMS Jun 19, 2026
c9d5b40
Add Rust SDK support for LLM inference callbacks
SteveSandersonMS Jun 22, 2026
f74d396
Java SDK: LLM inference callbacks
SteveSandersonMS Jun 22, 2026
d44886c
Simplify .NET LLM inference callbacks
SteveSandersonMS Jun 22, 2026
f00fb0e
Further simplify .NET LLM inference callbacks
SteveSandersonMS Jun 22, 2026
a4ca676
Rename public .NET callback types to Copilot* prefix
SteveSandersonMS Jun 22, 2026
82e7c9a
Simplify and rename Node SDK LLM callbacks to CopilotRequestHandler
SteveSandersonMS Jun 22, 2026
d653322
Fix .NET WebSocket upgrade deadlock and add WS e2e test
SteveSandersonMS Jun 22, 2026
2c100ff
Regenerate C#/Node codegen against published runtime 1.0.64-1
SteveSandersonMS Jun 22, 2026
692eb2c
Add cancel + error e2e coverage for CopilotRequestHandler (Node + .NET)
SteveSandersonMS Jun 22, 2026
328e715
Simplify and rename Go SDK LLM callbacks to CopilotRequestHandler
SteveSandersonMS Jun 22, 2026
da91eaf
Simplify and rename Java SDK LLM callbacks to CopilotRequestHandler
SteveSandersonMS Jun 22, 2026
a607520
Simplify and rename Python SDK LLM callbacks to CopilotRequestHandler
SteveSandersonMS Jun 22, 2026
979d27a
Simplify and rename Rust SDK LLM callbacks to CopilotRequestHandler
SteveSandersonMS Jun 22, 2026
bd9379c
Fix net472 test build: restore direct compile of SDK polyfills
SteveSandersonMS Jun 22, 2026
cc0ce37
Apply nightly rustfmt import consolidation to Rust handler
SteveSandersonMS Jun 22, 2026
8d35395
Fix Go lint: avoid deprecated http.ProtocolError in cancel/error e2e
SteveSandersonMS Jun 22, 2026
4b9c8e6
Fix rustdoc redundant explicit link in request_handler doc comment
SteveSandersonMS Jun 22, 2026
ed7b121
Fix CopilotRequestHandler frame-ordering race in .NET adapter
SteveSandersonMS Jun 22, 2026
29de529
Fix CopilotRequestHandler frame-ordering race in Go adapter
SteveSandersonMS Jun 22, 2026
072d7af
Harden CopilotRequestHandler against frame-ordering race in Java adapter
SteveSandersonMS Jun 22, 2026
b0ac997
Harden CopilotRequestHandler against frame-ordering race in Node adapter
SteveSandersonMS Jun 22, 2026
c74e538
Harden CopilotRequestHandler against frame-ordering race in Python ad…
SteveSandersonMS Jun 22, 2026
32f4164
Harden CopilotRequestHandler against frame-ordering race in Rust adapter
SteveSandersonMS Jun 22, 2026
7d425ff
Go: thread WebSocket binary flag, fix body close and ErrorCode naming
SteveSandersonMS Jun 22, 2026
eeea347
Rust: rename send_http to send_request and document open_websocket re…
SteveSandersonMS Jun 22, 2026
171bb96
Java: rename sendHttp to sendRequest, drop deprecated/unsafe test calls
SteveSandersonMS Jun 22, 2026
a5e7373
Address PR review comments in Python SDK
SteveSandersonMS Jun 22, 2026
6180a8a
Dispose TcpListener probe in .NET e2e GetFreePort helper
SteveSandersonMS Jun 22, 2026
2b06cd3
Terminate runtime immediately after runtime.shutdown completes
SteveSandersonMS Jun 22, 2026
1c911fa
Rename WebSocket handler: forwarding is now the default base
SteveSandersonMS Jun 22, 2026
9f2a649
Python: rename open_web_socket to open_websocket to match Rust
SteveSandersonMS Jun 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions dotnet/src/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ public sealed partial class CopilotClient : IDisposable, IAsyncDisposable
private List<ModelInfo>? _modelsCache;
private ServerRpc? _serverRpc;

/// <summary>
/// Client-global RPC handlers (e.g. the LLM inference provider adapter),
/// built once at construction when the corresponding option is configured and
/// registered on every connection. Null when no client-global API is enabled.
/// </summary>
private readonly ClientGlobalApiHandlers? _clientGlobalApis;

private sealed record LifecycleSubscription(Type EventType, Action<SessionLifecycleEvent> Handler);

/// <summary>
Expand Down Expand Up @@ -165,6 +172,8 @@ public CopilotClient(CopilotClientOptions? options = null)
_logger = _options.Logger ?? NullLogger.Instance;
_onListModels = _options.OnListModels;

_clientGlobalApis = BuildClientGlobalApis();

// Empty mode: validate at construction time that the app supplied a
// per-session persistence location. The runtime is mode-agnostic, so
// without this check it would silently fall back to ~/.copilot, which
Expand Down Expand Up @@ -276,6 +285,8 @@ async Task<Connection> StartCoreAsync(CancellationToken ct)
sessionFsTimestamp);
}

await ConfigureLlmInferenceAsync(ct);

LoggingHelpers.LogTiming(_logger, LogLevel.Debug, null,
"CopilotClient.StartAsync complete. Elapsed={Elapsed}",
startTimestamp);
Expand Down Expand Up @@ -1678,6 +1689,39 @@ await Rpc.SessionFs.SetProviderAsync(
cancellationToken: cancellationToken);
}

/// <summary>
/// Builds the client-global RPC handler bag at construction time. Currently
/// only the LLM inference provider adapter is registered; returns null when no
/// client-global API is configured so the registration is skipped entirely.
/// </summary>
private ClientGlobalApiHandlers? BuildClientGlobalApis()
{
var handler = _options.RequestHandler;
if (handler is null)
{
return null;
}

return new ClientGlobalApiHandlers
{
LlmInference = new LlmInferenceAdapter(handler, () => _serverRpc),
};
}

/// <summary>
/// Tells the runtime to route its outbound model-layer requests through this
/// client's LLM inference provider. No-op when interception is not configured.
/// </summary>
private async Task ConfigureLlmInferenceAsync(CancellationToken cancellationToken)
{
if (_clientGlobalApis?.LlmInference is null)
{
return;
}

await Rpc.LlmInference.SetProviderAsync(cancellationToken);
}

private void ConfigureSessionFsHandlers(CopilotSession session, Func<CopilotSession, SessionFsProvider>? createSessionFsHandler)
{
if (_options.SessionFs is null)
Expand Down Expand Up @@ -2072,6 +2116,10 @@ private async Task<Connection> ConnectToServerAsync(Process? cliProcess, string?
var session = GetSession(sessionId) ?? throw new ArgumentException($"Unknown session {sessionId}");
return session.ClientSessionApis;
});
if (_clientGlobalApis is not null)
{
ClientGlobalApiRegistration.RegisterClientGlobalApiHandlers(rpc, _clientGlobalApis);
}
rpc.StartListening();
LoggingHelpers.LogTiming(_logger, LogLevel.Debug, null,
"CopilotClient.ConnectToServerAsync transport setup complete. Elapsed={Elapsed}",
Expand Down
Loading
Loading