@github/copilot-sdk 1.0.29-preview.8 → 1.0.29-preview.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -286,7 +286,7 @@ new CopilotClient(options?: CopilotClientOptions)
286
286
  - `RuntimeConnection.forStdio({ path?, args?, env? })` (default) — spawn the runtime and communicate over its stdin/stdout.
287
287
  - `RuntimeConnection.forTcp({ port?, connectionToken?, path?, args?, env? })` — spawn the runtime as a TCP server.
288
288
  - `RuntimeConnection.forUri(url, { connectionToken? })` — connect to an already-running runtime (mutually exclusive with `gitHubToken`/`useLoggedInUser`). There is no top-level `cliUrl` shortcut; use this factory for URL-based connections.
289
- - `RuntimeConnection.forInProcess()` — host the runtime in-process over its native C ABI (FFI). **Experimental.** Because the runtime shares this process, `env`, `telemetry`, and `workingDirectory` are rejected with this transport; set them on the host process instead.
289
+ - `RuntimeConnection.forInProcess()` — host the runtime in-process over its native C ABI (FFI). **Experimental.** Client-level `env`, `telemetry`, and `workingDirectory` are rejected; use supported typed options and configure working directories per session.
290
290
  - The child-process transports (`forStdio`/`forTcp`) also accept a per-connection `env`. Set it there or via the top-level `env` option — not both (setting both throws).
291
291
  - Managed child-process connections materialize the bundled `copilot-runtime` and adjacent `runtime.node`, then launch the wrapper by default. An explicit connection `path` or `COPILOT_CLI_PATH` overrides the bundled runtime.
292
292
  - `mode?: "empty" | "copilot-cli"` - Defaulting strategy. Use `"empty"` for multi-user server mode; defaults to `"copilot-cli"`.
@@ -421,6 +421,20 @@ Create a new conversation session.
421
421
  - `hooks?: SessionHooks` - Hook handlers for session lifecycle events. See [Session Hooks](#session-hooks) section.
422
422
  - `skillProvider?: SkillProvider` - **Experimental.** Serves skills from host storage instead of skill directories. Not persisted; pass it again on resume. See [Skill providers](#skill-providers-experimental).
423
423
 
424
+ <!-- docs-validate: strict -->
425
+ <!-- docs-validate: hidden -->
426
+ ```typescript
427
+ declare function acquireTokenForHost(host: string): Promise<string>;
428
+
429
+ const session = await client.createSession({
430
+ gitHubTokenProvider: async ({ host }) => ({
431
+ kind: "token",
432
+ accessToken: await acquireTokenForHost(host),
433
+ expiresIn: 8 * 60 * 60,
434
+ }),
435
+ });
436
+ ```
437
+ <!-- /docs-validate: hidden -->
424
438
  ```typescript
425
439
  const session = await client.createSession({
426
440
  gitHubTokenProvider: async ({ host }) => ({
@@ -495,6 +509,7 @@ Request the TUI to switch to displaying the specified session. Only available in
495
509
 
496
510
  Subscribe to a specific session lifecycle event type. Returns an unsubscribe function.
497
511
 
512
+ <!-- docs-validate: strict -->
498
513
  ```typescript
499
514
  const unsubscribe = client.onLifecycle("session.foreground", (event) => {
500
515
  console.log(`Session ${event.sessionId} is now in foreground`);
@@ -505,6 +520,7 @@ const unsubscribe = client.onLifecycle("session.foreground", (event) => {
505
520
 
506
521
  Subscribe to all session lifecycle events. Returns an unsubscribe function.
507
522
 
523
+ <!-- docs-validate: strict -->
508
524
  ```typescript
509
525
  const unsubscribe = client.onLifecycle((event) => {
510
526
  console.log(`${event.type}: ${event.sessionId}`);
@@ -552,12 +568,32 @@ Returns the message ID.
552
568
 
553
569
  Use `source: "system"` for automated messages from your application:
554
570
 
571
+ <!-- docs-validate: strict -->
572
+ <!-- docs-validate: hidden -->
573
+ ```typescript
574
+ import type { CopilotSession } from "@github/copilot-sdk";
575
+
576
+ declare const session: CopilotSession;
577
+
578
+ await session.send({ prompt: "Context updated", source: "system" });
579
+ ```
580
+ <!-- /docs-validate: hidden -->
555
581
  ```typescript
556
582
  await session.send({ prompt: "Context updated", source: "system" });
557
583
  ```
558
584
 
559
585
  For a message from another agent, use its trusted sender ID:
560
586
 
587
+ <!-- docs-validate: strict -->
588
+ <!-- docs-validate: hidden -->
589
+ ```typescript
590
+ import type { CopilotSession } from "@github/copilot-sdk";
591
+
592
+ declare const session: CopilotSession;
593
+
594
+ await session.send({ prompt: "Review complete", source: "agent-reviewer-id" });
595
+ ```
596
+ <!-- /docs-validate: hidden -->
561
597
  ```typescript
562
598
  await session.send({ prompt: "Review complete", source: "agent-reviewer-id" });
563
599
  ```
@@ -590,6 +626,23 @@ Pass a raw JSON Schema or a Zod schema as `responseSchema` to `send` or
590
626
  `sendAndWait`. As with custom tool parameters, the SDK converts Zod schemas to
591
627
  JSON Schema before sending them:
592
628
 
629
+ <!-- docs-validate: strict -->
630
+ <!-- docs-validate: hidden -->
631
+ ```typescript
632
+ import type { CopilotSession } from "@github/copilot-sdk";
633
+
634
+ declare const session: CopilotSession;
635
+
636
+ import { z } from "zod";
637
+
638
+ const answerSchema = z.object({ answer: z.number().int() });
639
+ const message = await session.sendAndWait({
640
+ prompt: "What is 19 + 23?",
641
+ responseSchema: answerSchema,
642
+ });
643
+ console.log(message?.data.content); // JSON text
644
+ ```
645
+ <!-- /docs-validate: hidden -->
593
646
  ```typescript
594
647
  import { z } from "zod";
595
648
 
@@ -603,6 +656,20 @@ console.log(message?.data.content); // JSON text
603
656
 
604
657
  For a typed result, pass the Zod schema as the **second argument** instead:
605
658
 
659
+ <!-- docs-validate: strict -->
660
+ <!-- docs-validate: hidden -->
661
+ ```typescript
662
+ import type { CopilotSession } from "@github/copilot-sdk";
663
+
664
+ declare const session: CopilotSession;
665
+ import { z } from "zod";
666
+
667
+ const answerSchema = z.object({ answer: z.number().int() });
668
+
669
+ const answer = await session.sendAndWait("What is 19 + 23?", answerSchema);
670
+ console.log(answer.answer); // number; TResult is inferred from answerSchema
671
+ ```
672
+ <!-- /docs-validate: hidden -->
606
673
  ```typescript
607
674
  const answer = await session.sendAndWait("What is 19 + 23?", answerSchema);
608
675
  console.log(answer.answer); // number; TResult is inferred from answerSchema
@@ -675,6 +742,28 @@ native `output_config.format` endpoint.
675
742
 
676
743
  Subscribe to a specific event type. The handler receives properly typed events.
677
744
 
745
+ <!-- docs-validate: strict -->
746
+ <!-- docs-validate: hidden -->
747
+ ```typescript
748
+ import type { CopilotSession } from "@github/copilot-sdk";
749
+
750
+ declare const session: CopilotSession;
751
+
752
+ // Listen for specific event types with full type inference
753
+ session.on("assistant.message", (event) => {
754
+ console.log(event.data.content); // TypeScript knows about event.data.content
755
+ });
756
+
757
+ session.on("session.idle", () => {
758
+ console.log("Session is idle");
759
+ });
760
+
761
+ // Listen to streaming events
762
+ session.on("assistant.message_delta", (event) => {
763
+ process.stdout.write(event.data.deltaContent);
764
+ });
765
+ ```
766
+ <!-- /docs-validate: hidden -->
678
767
  ```typescript
679
768
  // Listen for specific event types with full type inference
680
769
  session.on("assistant.message", (event) => {
@@ -695,6 +784,22 @@ session.on("assistant.message_delta", (event) => {
695
784
 
696
785
  Subscribe to all session events. Returns an unsubscribe function.
697
786
 
787
+ <!-- docs-validate: strict -->
788
+ <!-- docs-validate: hidden -->
789
+ ```typescript
790
+ import type { CopilotSession } from "@github/copilot-sdk";
791
+
792
+ declare const session: CopilotSession;
793
+
794
+ const unsubscribe = session.on((event) => {
795
+ // Handle any event type
796
+ console.log(event.type, event);
797
+ });
798
+
799
+ // Later...
800
+ unsubscribe();
801
+ ```
802
+ <!-- /docs-validate: hidden -->
698
803
  ```typescript
699
804
  const unsubscribe = session.on((event) => {
700
805
  // Handle any event type
@@ -722,6 +827,19 @@ The runtime does not apply the preference immediately. It records the request an
722
827
 
723
828
  Watch for the outcome through the `session.model_change` event on success or the ephemeral `session.auto_tier_switch_failed` event on failure. A failed activation leaves the incumbent effective tier unchanged. Read the authoritative state at any time with `session.rpc.model.getCurrent()`.
724
829
 
830
+ <!-- docs-validate: strict -->
831
+ <!-- docs-validate: hidden -->
832
+ ```typescript
833
+ import type { CopilotSession } from "@github/copilot-sdk";
834
+
835
+ declare const session: CopilotSession;
836
+
837
+ const result = await session.setAutoTier("intelligence");
838
+ if (result.status === "pending") {
839
+ // Accepted, but not yet in effect.
840
+ }
841
+ ```
842
+ <!-- /docs-validate: hidden -->
725
843
  ```typescript
726
844
  const result = await session.setAutoTier("intelligence");
727
845
  if (result.status === "pending") {
@@ -735,6 +853,23 @@ See [Auto tier persistence](../docs/features/session-persistence.md#auto-tier-pe
735
853
 
736
854
  Read the current model's reasoning-summary presentation policy without changing session state. Call `session.rpc.model.list()` first to load the model catalog; otherwise the result may have `ready: false`. The request and result types are exported from `@github/copilot-sdk`.
737
855
 
856
+ <!-- docs-validate: strict -->
857
+ <!-- docs-validate: hidden -->
858
+ ```typescript
859
+ import type { CopilotSession } from "@github/copilot-sdk";
860
+
861
+ declare const session: CopilotSession;
862
+
863
+ import type {
864
+ ModelGetReasoningSummariesRequest,
865
+ ModelGetReasoningSummariesResult,
866
+ } from "@github/copilot-sdk";
867
+
868
+ const presentation: ModelGetReasoningSummariesRequest = { summariesVisible: false };
869
+ const policy: ModelGetReasoningSummariesResult =
870
+ await session.rpc.model.getReasoningSummaries(presentation);
871
+ ```
872
+ <!-- /docs-validate: hidden -->
738
873
  ```typescript
739
874
  import type {
740
875
  ModelGetReasoningSummariesRequest,
@@ -754,6 +889,26 @@ Replace the tools this client supplies to the session, together with the handler
754
889
 
755
890
  Once the runtime accepts the replacement, every tool call this session dispatches uses the new handlers; calls already running finish on their original handlers. If the runtime rejects it, the promise rejects and the previous tools and handlers stay in place. Concurrent calls are applied one at a time, in call order.
756
891
 
892
+ <!-- docs-validate: strict -->
893
+ <!-- docs-validate: hidden -->
894
+ ```typescript
895
+ import type { CopilotSession } from "@github/copilot-sdk";
896
+
897
+ declare const session: CopilotSession;
898
+ import { defineTool } from "@github/copilot-sdk";
899
+ import { z } from "zod";
900
+
901
+ declare function searchIssues(query: string): Promise<string>;
902
+
903
+ await session.setTools([
904
+ defineTool("search_issues", {
905
+ description: "Search the issues shown on the current page",
906
+ parameters: z.object({ query: z.string() }),
907
+ handler: async ({ query }) => searchIssues(query),
908
+ }),
909
+ ]);
910
+ ```
911
+ <!-- /docs-validate: hidden -->
757
912
  ```typescript
758
913
  await session.setTools([
759
914
  defineTool("search_issues", {
@@ -782,6 +937,18 @@ Disconnect the session and free resources. Session data on disk is preserved for
782
937
 
783
938
  Host capabilities reported when the session was created or resumed. Use this to check feature support before calling capability-gated APIs.
784
939
 
940
+ <!-- docs-validate: strict -->
941
+ <!-- docs-validate: hidden -->
942
+ ```typescript
943
+ import type { CopilotSession } from "@github/copilot-sdk";
944
+
945
+ declare const session: CopilotSession;
946
+
947
+ if (session.capabilities.ui?.elicitation) {
948
+ const ok = await session.ui.confirm("Deploy?");
949
+ }
950
+ ```
951
+ <!-- /docs-validate: hidden -->
785
952
  ```typescript
786
953
  if (session.capabilities.ui?.elicitation) {
787
954
  const ok = await session.ui.confirm("Deploy?");
@@ -1427,7 +1594,7 @@ console.log(session.workspacePath);
1427
1594
  // => ~/.copilot/session-state/{sessionId}/
1428
1595
 
1429
1596
  // Custom thresholds
1430
- const session = await client.createSession({
1597
+ const tuned = await client.createSession({
1431
1598
  model: "gpt-5",
1432
1599
  infiniteSessions: {
1433
1600
  enabled: true,
@@ -1437,7 +1604,7 @@ const session = await client.createSession({
1437
1604
  });
1438
1605
 
1439
1606
  // Disable infinite sessions
1440
- const session = await client.createSession({
1607
+ const disabled = await client.createSession({
1441
1608
  model: "gpt-5",
1442
1609
  infiniteSessions: { enabled: false },
1443
1610
  });
@@ -1475,13 +1642,13 @@ const disabled = await client.createSession({
1475
1642
  <!-- /docs-validate: hidden -->
1476
1643
  ```typescript
1477
1644
  // Enable memory for a session
1478
- const session = await client.createSession({
1645
+ const enabled = await client.createSession({
1479
1646
  model: "gpt-5",
1480
1647
  memory: { enabled: true },
1481
1648
  });
1482
1649
 
1483
1650
  // Disable memory for a session
1484
- const session = await client.createSession({
1651
+ const disabled = await client.createSession({
1485
1652
  model: "gpt-5",
1486
1653
  memory: { enabled: false },
1487
1654
  });
@@ -22,7 +22,7 @@ __export(cliVersion_exports, {
22
22
  COPILOT_CLI_VERSION: () => COPILOT_CLI_VERSION
23
23
  });
24
24
  module.exports = __toCommonJS(cliVersion_exports);
25
- const COPILOT_CLI_VERSION = "1.0.106-9";
25
+ const COPILOT_CLI_VERSION = "1.0.106-10";
26
26
  const COPILOT_CLI_USE_NPM_PACKAGE = false;
27
27
  // Annotate the CommonJS export names for ESM import in node:
28
28
  0 && (module.exports = {
@@ -301,6 +301,10 @@ function getNodeExecPath() {
301
301
  function getBundledRuntimePath() {
302
302
  return (0, import_runtimeArtifacts.ensureRuntimeBundle)(import_cliVersion.COPILOT_CLI_VERSION);
303
303
  }
304
+ async function getSpawnableBundledRuntimePath() {
305
+ const runtimePath = await getBundledRuntimePath();
306
+ return process.platform === "win32" ? import_node_path.win32.toNamespacedPath(runtimePath) : runtimePath;
307
+ }
304
308
  class TeardownResilientStreamMessageWriter extends import_node.StreamMessageWriter {
305
309
  suppressWriteErrors = false;
306
310
  constructor(writable) {
@@ -466,19 +470,22 @@ class CopilotClient {
466
470
  */
467
471
  constructor(options = {}) {
468
472
  const conn = options._internalConnection ?? options.connection ?? CopilotClient.resolveDefaultConnection();
473
+ if ((conn.kind === "uri" || conn.kind === "parent-process") && options.internalTestOptions !== void 0) {
474
+ throw new Error("internalTestOptions requires a runtime owned by this client");
475
+ }
469
476
  if (conn.kind === "uri" && (options.gitHubToken !== void 0 || options.useLoggedInUser !== void 0)) {
470
477
  throw new Error(
471
478
  "gitHubToken and useLoggedInUser cannot be used with RuntimeConnection.forUri (external server manages its own auth)"
472
479
  );
473
480
  }
474
- if (conn.kind === "inprocess" && options.workingDirectory !== void 0) {
481
+ if (conn.kind === "inprocess" && options.env !== void 0) {
475
482
  throw new Error(
476
- "workingDirectory is not supported with RuntimeConnection.forInProcess(): the in-process transport hosts the runtime in this process, so honoring it would require mutating the shared process-global cwd. Change the host process's working directory before constructing the client instead."
483
+ "env is not supported with RuntimeConnection.forInProcess(): environment variables belong to the shared host process. Use typed client/session options or a child-process transport."
477
484
  );
478
485
  }
479
- if (conn.kind === "inprocess" && options.env !== void 0) {
486
+ if (conn.kind === "inprocess" && options.workingDirectory !== void 0) {
480
487
  throw new Error(
481
- "env is not supported with RuntimeConnection.forInProcess(): the in-process transport loads the native runtime into the shared host process, whose single environment block cannot carry per-client values. Set the variables on the host process environment instead."
488
+ "workingDirectory is not supported with RuntimeConnection.forInProcess(): the in-process transport hosts the runtime in this process, so honoring it would require mutating the shared process-global cwd. Set SessionConfig.workingDirectory instead."
482
489
  );
483
490
  }
484
491
  if (conn.kind === "inprocess" && options.telemetry !== void 0) {
@@ -544,6 +551,7 @@ class CopilotClient {
544
551
  const connArgs = conn.kind === "stdio" || conn.kind === "tcp" ? conn.args ?? [] : [];
545
552
  this.connectionExtraArgs = [...connArgs];
546
553
  this.options = {
554
+ internalTestOptions: options.internalTestOptions,
547
555
  entra: options.entra ? { ...options.entra, tokenProvider: options.entra.tokenProvider } : void 0,
548
556
  workingDirectory: options.workingDirectory ?? process.cwd(),
549
557
  logLevel: options.logLevel,
@@ -1164,7 +1172,7 @@ class CopilotClient {
1164
1172
  * // Session with model and tools
1165
1173
  * const session = await client.createSession({
1166
1174
  * onPermissionRequest: approveAll,
1167
- * model: "gpt-4",
1175
+ * model: "gpt-5.4",
1168
1176
  * tools: [{
1169
1177
  * name: "get_weather",
1170
1178
  * description: "Get weather for a location",
@@ -2429,15 +2437,40 @@ class CopilotClient {
2429
2437
  };
2430
2438
  }
2431
2439
  /**
2432
- * Builds the environment for the spawned runtime child process (stdio/TCP): applies
2433
- * the auth token, connection token, `COPILOT_HOME`, keychain setting, and telemetry
2434
- * variables on top of the effective env. Not used by the in-process (FFI) transport,
2435
- * whose worker inherits the host process's ambient environment
2436
- * (see {@link CopilotClient.startInProcessFfi}).
2440
+ * Builds runtime configuration for child processes and the per-host FFI snapshot.
2441
+ * Typed auth, home, keychain, and telemetry options override the effective env.
2437
2442
  */
2438
2443
  buildRuntimeEnv() {
2439
- const env = { ...this.resolvedEnv };
2444
+ const env = process.platform === "win32" ? Object.fromEntries(
2445
+ Object.entries(this.resolvedEnv).map(([key, value]) => [
2446
+ key.toUpperCase(),
2447
+ value
2448
+ ])
2449
+ ) : { ...this.resolvedEnv };
2440
2450
  delete env.NODE_DEBUG;
2451
+ const test = this.options.internalTestOptions;
2452
+ if (test) {
2453
+ const overrides = {
2454
+ COPILOT_API_URL: test.copilotApiUrl,
2455
+ COPILOT_DEBUG_GITHUB_API_URL: test.githubApiUrl,
2456
+ HTTP_PROXY: test.proxyUrl,
2457
+ HTTPS_PROXY: test.proxyUrl,
2458
+ http_proxy: test.proxyUrl,
2459
+ https_proxy: test.proxyUrl,
2460
+ NO_PROXY: test.noProxy,
2461
+ no_proxy: test.noProxy,
2462
+ NODE_EXTRA_CA_CERTS: test.caCertificatePath,
2463
+ SSL_CERT_FILE: test.caCertificatePath,
2464
+ REQUESTS_CA_BUNDLE: test.caCertificatePath,
2465
+ CURL_CA_BUNDLE: test.caCertificatePath,
2466
+ GIT_SSL_CAINFO: test.caCertificatePath
2467
+ };
2468
+ for (const [key, value] of Object.entries(overrides)) {
2469
+ if (value !== void 0) {
2470
+ env[process.platform === "win32" ? key.toUpperCase() : key] = value;
2471
+ }
2472
+ }
2473
+ }
2441
2474
  if (this.options.gitHubToken) {
2442
2475
  env.COPILOT_SDK_AUTH_TOKEN = this.options.gitHubToken;
2443
2476
  }
@@ -2446,6 +2479,9 @@ class CopilotClient {
2446
2479
  }
2447
2480
  if (this.options.baseDirectory) {
2448
2481
  env.COPILOT_HOME = this.options.baseDirectory;
2482
+ if (this.connectionConfig.kind === "inprocess") {
2483
+ env.COPILOT_CACHE_HOME = (0, import_node_path.join)(this.options.baseDirectory, "cache");
2484
+ }
2449
2485
  }
2450
2486
  if (this.options.mode === "empty") {
2451
2487
  env.COPILOT_DISABLE_KEYTAR = "1";
@@ -2472,7 +2508,7 @@ class CopilotClient {
2472
2508
  * Start the CLI server process
2473
2509
  */
2474
2510
  async startCLIServer() {
2475
- this.resolvedCliPath ??= await getBundledRuntimePath();
2511
+ this.resolvedCliPath ??= await getSpawnableBundledRuntimePath();
2476
2512
  return new Promise((resolve2, reject) => {
2477
2513
  this.stderrBuffer = "";
2478
2514
  const args = [...this.connectionExtraArgs, "--headless", "--no-auto-update"];
@@ -2510,6 +2546,22 @@ class CopilotClient {
2510
2546
  `Copilot CLI not found at ${this.resolvedCliPath}. Set COPILOT_CLI_PATH to use a custom installation.`
2511
2547
  );
2512
2548
  }
2549
+ const workingDirectory = this.options.workingDirectory;
2550
+ let workingDirectoryProblem;
2551
+ try {
2552
+ workingDirectoryProblem = (0, import_node_fs.statSync)(workingDirectory).isDirectory() ? void 0 : "does not exist or is not a directory";
2553
+ if (!workingDirectoryProblem) {
2554
+ (0, import_node_fs.accessSync)(workingDirectory, import_node_fs.constants.X_OK);
2555
+ }
2556
+ } catch (error) {
2557
+ const code = error.code;
2558
+ workingDirectoryProblem = code === "ENOENT" || code === "ENOTDIR" ? "does not exist or is not a directory" : `cannot be entered: ${error instanceof Error ? error.message : String(error)}`;
2559
+ }
2560
+ if (workingDirectoryProblem) {
2561
+ throw new Error(
2562
+ `Working directory ${workingDirectory} ${workingDirectoryProblem}.`
2563
+ );
2564
+ }
2513
2565
  const stdioConfig = this.connectionConfig.kind === "stdio" ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"];
2514
2566
  const isJsFile = this.resolvedCliPath.endsWith(".js");
2515
2567
  if (isJsFile) {
@@ -2661,16 +2713,7 @@ stderr: ${this.stderrBuffer.trim().slice(-8192) || "(empty)"}`
2661
2713
  runtimeLibrary = (0, import_node_path.join)((0, import_node_path.dirname)(bundledRuntimePath), "runtime.node");
2662
2714
  }
2663
2715
  const { FfiRuntimeHost } = await import("./ffiRuntimeHost.js");
2664
- const environment = {};
2665
- if (this.options.gitHubToken) {
2666
- environment.COPILOT_SDK_AUTH_TOKEN = this.options.gitHubToken;
2667
- }
2668
- if (this.options.baseDirectory) {
2669
- environment.COPILOT_HOME = this.options.baseDirectory;
2670
- }
2671
- if (this.options.mode === "empty") {
2672
- environment.COPILOT_DISABLE_KEYTAR = "1";
2673
- }
2716
+ const environment = this.buildRuntimeEnv();
2674
2717
  const args = [];
2675
2718
  if (this.options.logLevel) {
2676
2719
  args.push("--log-level", this.options.logLevel);
@@ -2628,7 +2628,7 @@ function createSessionRpc(connection, sessionId) {
2628
2628
  /** @experimental */
2629
2629
  login: {
2630
2630
  /**
2631
- * Begin an interactive login flow for a provider kind (dispatch is kind-only) and return its opaque flow id and first step.
2631
+ * Begin an interactive login flow for a provider kind, optionally selecting how to authorize (`method`: `web` by default, or `device-code`), and return its opaque flow id and first step.
2632
2632
  *
2633
2633
  * @param params Begin an interactive login flow for a provider kind, optionally reusing a cached base identity or explicitly requesting provider account selection.
2634
2634
  *
@@ -2640,7 +2640,7 @@ function createSessionRpc(connection, sessionId) {
2640
2640
  *
2641
2641
  * @param params Advance an in-flight login flow, optionally fulfilling an input-required step.
2642
2642
  *
2643
- * @returns One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra).
2643
+ * @returns One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra). A device-code flow surfaces its one-time code as `device-code`; the consumer shows the code, may open the verification URI, and calls advance, which resolves once the user has authorized the device.
2644
2644
  */
2645
2645
  advance: async (params) => connection.sendRequest("session.accounts.login.advance", { ...params, sessionId }),
2646
2646
  /**
@@ -4500,6 +4500,12 @@ function createSessionRpc(connection, sessionId) {
4500
4500
  * @returns Indicates whether an in-progress background compaction was cancelled.
4501
4501
  */
4502
4502
  cancelBackgroundCompaction: async () => connection.sendRequest("session.history.cancelBackgroundCompaction", { sessionId }),
4503
+ /**
4504
+ * Replaces this local session's compaction settings: the model, prompt and reasoning effort its automatic and manual compactions use. Each call replaces all three: an omitted field returns to its default. Settings are held in memory only, so re-apply them after resuming the session in a new process. A change applies to compactions that start afterwards, except that automatic compactions keep the model the running turn already chose for them until that turn ends; a compaction already in progress may still pick up a new reasoning effort. Rejects on a remote session.
4505
+ *
4506
+ * @param params Compaction settings for this session. Each call replaces the previous settings: an omitted field returns to its default. Settings live in memory until the session ends; re-apply them after resuming a session in a new process.
4507
+ */
4508
+ setCompactionConfig: async (params) => connection.sendRequest("session.history.setCompactionConfig", { ...params, sessionId }),
4503
4509
  /**
4504
4510
  * Aborts any in-progress manual compaction on a local session.
4505
4511
  *
@@ -4837,6 +4843,15 @@ function createInternalSessionRpc(connection, sessionId) {
4837
4843
  }
4838
4844
  },
4839
4845
  /** @experimental */
4846
+ canvasSource: {
4847
+ /**
4848
+ * Closes a canvas through its original session source. Requires the privately admitted in-process CLI host.
4849
+ *
4850
+ * @param params Closes a canvas through its original owned or attached session namespace.
4851
+ */
4852
+ close: async (params) => connection.sendRequest("session.canvasSource.close", { ...params, sessionId })
4853
+ },
4854
+ /** @experimental */
4840
4855
  workflow: {
4841
4856
  /**
4842
4857
  * Internal tool-originated dynamic workflow invocation.
@@ -1177,6 +1177,13 @@ class CopilotSession {
1177
1177
  } else if (typeof rawResult === "string") {
1178
1178
  result = rawResult;
1179
1179
  } else if (isToolResultObject(rawResult)) {
1180
+ try {
1181
+ JSON.stringify(rawResult.toolTelemetry);
1182
+ } catch (error) {
1183
+ const message = error instanceof Error ? error.message : String(error);
1184
+ throw new Error(`failed to serialize tool telemetry: ${message}`);
1185
+ }
1186
+ JSON.stringify(rawResult);
1180
1187
  result = rawResult;
1181
1188
  } else {
1182
1189
  result = JSON.stringify(rawResult);
package/dist/cjs/types.js CHANGED
@@ -71,11 +71,9 @@ const RuntimeConnection = {
71
71
  /**
72
72
  * Host the runtime in-process over the native runtime library's C ABI (FFI).
73
73
  *
74
- * @experimental Per-client options lowered to environment variables (`env`,
75
- * `telemetry`, `gitHubToken`, `baseDirectory`) are **not** honored in-process;
76
- * the worker inherits the host process's ambient environment. Set the
77
- * corresponding environment variables on the host process instead. See
78
- * https://github.com/github/copilot-sdk/issues/1934.
74
+ * @experimental Runtime configuration from `gitHubToken` and
75
+ * `baseDirectory` is scoped to this host, not the process environment.
76
+ * Client-level `env`, `telemetry` and `workingDirectory` are unsupported.
79
77
  */
80
78
  forInProcess(options = {}) {
81
79
  return { kind: "inprocess", ...options };
@@ -1,2 +1,2 @@
1
- export declare const COPILOT_CLI_VERSION = "1.0.106-9";
1
+ export declare const COPILOT_CLI_VERSION = "1.0.106-10";
2
2
  export declare const COPILOT_CLI_USE_NPM_PACKAGE = false;
@@ -1,4 +1,4 @@
1
- const COPILOT_CLI_VERSION = "1.0.106-9";
1
+ const COPILOT_CLI_VERSION = "1.0.106-10";
2
2
  const COPILOT_CLI_USE_NPM_PACKAGE = false;
3
3
  export {
4
4
  COPILOT_CLI_USE_NPM_PACKAGE,
package/dist/client.d.ts CHANGED
@@ -474,11 +474,8 @@ export declare class CopilotClient {
474
474
  */
475
475
  onLifecycle(handler: SessionLifecycleHandler): () => void;
476
476
  /**
477
- * Builds the environment for the spawned runtime child process (stdio/TCP): applies
478
- * the auth token, connection token, `COPILOT_HOME`, keychain setting, and telemetry
479
- * variables on top of the effective env. Not used by the in-process (FFI) transport,
480
- * whose worker inherits the host process's ambient environment
481
- * (see {@link CopilotClient.startInProcessFfi}).
477
+ * Builds runtime configuration for child processes and the per-host FFI snapshot.
478
+ * Typed auth, home, keychain, and telemetry options override the effective env.
482
479
  */
483
480
  private buildRuntimeEnv;
484
481
  /**