@github/copilot-sdk 1.0.24 → 1.0.25-preview.1

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
@@ -414,6 +414,16 @@ Initial acquisition runs during session creation or resume. Cancellation, provid
414
414
 
415
415
  ##### `resumeSession(sessionId: string, config?: ResumeSessionConfig): Promise<CopilotSession>`
416
416
 
417
+ Both create and resume accept experimental `autopilot: AutopilotOptions`, and
418
+ `session.rpc.options.update({ autopilot: ... })` patches the same policy.
419
+ `continuationEnabled` controls runtime-owned continuation, not the session mode;
420
+ it defaults to `true`. `maxContinues` limits continuations outside an active
421
+ objective: a non-negative integer, default five, with zero allowing none.
422
+ Updates and warm resumes preserve
423
+ omitted fields; `{}` changes nothing. The policy is not persisted, so re-supply
424
+ it on cold resume. Pause state, prompt overrides, and no-progress detection are
425
+ internal runtime controls, not SDK options.
426
+
417
427
  Resume an existing session. Returns the session with `workspacePath` populated if infinite sessions were enabled.
418
428
  `allowTranscriptRecovery` controls whether the runtime may repair a damaged transcript during
419
429
  resume. It defaults to `true` in all modes; set it to `false` to reject recovery.
@@ -533,7 +543,11 @@ Source is independent of delivery mode. Leaving it unset preserves the existing
533
543
 
534
544
  ##### `sendAndWait(options: MessageOptions, timeout?: number): Promise<AssistantMessageEvent | undefined>`
535
545
 
536
- Send a message and wait until the session becomes idle.
546
+ Send a message and wait for response completion: non-Autopilot `session.idle`,
547
+ or the request's root `session.autopilot_stopped` event in Autopilot.
548
+ The latter does not wait for attached shells to finish and does not stop them.
549
+ `session.idle` still means whole-session quiescence; neither `assistant.idle`
550
+ nor `session.task_complete` alone completes the wait.
537
551
  Sub-agent events are still delivered to listeners, but do not complete the wait or supply its reply.
538
552
 
539
553
  **Options:**
@@ -605,15 +619,25 @@ guarantee the schema plus conversation and tools fits the provider's budget.
605
619
 
606
620
  Structured waits select the last root-agent message whose `originatingMessageId`
607
621
  matches the ID returned by their send, then return at a non-autopilot
608
- `session.idle`. Other queued work can delay that idle, but cannot replace the
609
- selected result. The existing unformatted overload retains its session-wide
610
- behavior. `turnId` identifies an individual model/tool iteration, not the whole
622
+ `session.idle` or a root `session.autopilot_stopped` whose `requestId` matches
623
+ that original send ID. Automatic continuation messages do not change ownership.
624
+ An absent or different `requestId` cannot complete a correlated wait.
625
+ Other queued work can delay idle, but cannot replace the selected result.
626
+ Unformatted waits also isolate their replies and accept idle only after their
627
+ own request starts. Both forms ignore child-agent events and `session.error`
628
+ events whose `originatingMessageId` belongs to another request. A matching error
629
+ fails its own wait even before a user message is emitted. Errors without an ID
630
+ retain legacy handling: unformatted waits treat them as session-wide, while
631
+ structured waits require their request to have started. Older hosts that omit
632
+ error IDs cannot provide concurrent request-error isolation.
633
+ `turnId` identifies an individual model/tool iteration, not the whole
611
634
  run; telemetry interaction IDs are not unique run identifiers.
612
635
 
613
636
  For event-driven consumption with `send`, subscribe before sending and collect
614
637
  root `assistant.message` events whose `data.originatingMessageId` matches the ID
615
638
  returned by `send`; events may arrive before that acknowledgement. Wait for
616
- `session.idle`, then parse the last matching message without tool requests.
639
+ non-autopilot `session.idle`, or the matching `session.autopilot_stopped`, then
640
+ parse the last matching message without tool requests.
617
641
  An earlier response may be superseded by a stop-hook correction. Handle
618
642
  `session.error` and aborted idle events rather than returning a partial result.
619
643
 
@@ -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.101";
25
+ const COPILOT_CLI_VERSION = "1.0.102-1";
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 = {
@@ -620,6 +620,16 @@ class CopilotClient {
620
620
  handlers.gitHubToken = {
621
621
  getToken: (params) => this.acquireGitHubToken(params)
622
622
  };
623
+ handlers.uiThread = {
624
+ run: async ({ actionId }) => {
625
+ const connection = this.connectionConfig;
626
+ const host = this.ffiHost;
627
+ if (connection.kind !== "inprocess" || !connection.runOnUiThread || !host) {
628
+ throw new Error("No in-process runOnUiThread handler is configured.");
629
+ }
630
+ await connection.runOnUiThread(() => host.runUiAction(actionId));
631
+ }
632
+ };
623
633
  this.clientGlobalHandlers = handlers;
624
634
  }
625
635
  async acquireGitHubToken(params) {
@@ -1358,6 +1368,7 @@ class CopilotClient {
1358
1368
  enableCitations: config.enableCitations,
1359
1369
  enableFileChangeTracking: config.enableFileChangeTracking,
1360
1370
  sessionLimits: config.sessionLimits,
1371
+ autopilot: config.autopilot,
1361
1372
  modelCapabilities: config.modelCapabilities,
1362
1373
  largeOutput: toWireLargeOutput(config.largeOutput),
1363
1374
  requestPermission: !!config.onPermissionRequest,
@@ -1605,6 +1616,7 @@ class CopilotClient {
1605
1616
  enableCitations: config.enableCitations,
1606
1617
  enableFileChangeTracking: config.enableFileChangeTracking,
1607
1618
  sessionLimits: config.sessionLimits,
1619
+ autopilot: config.autopilot,
1608
1620
  tools: config.tools?.map((tool) => ({
1609
1621
  name: tool.name,
1610
1622
  description: tool.description,
@@ -2555,6 +2567,9 @@ stderr: ${this.stderrBuffer.trim().slice(-8192) || "(empty)"}`
2555
2567
  );
2556
2568
  this.attachConnectionHandlers();
2557
2569
  this.connection.listen();
2570
+ this.ffiHost.configureUiThread(
2571
+ this.connectionConfig.kind === "inprocess" && this.connectionConfig.runOnUiThread !== void 0
2572
+ );
2558
2573
  }
2559
2574
  static getNapiPrebuildsFolder(entrypoint) {
2560
2575
  const arch = process.arch;
@@ -80,6 +80,15 @@ function loadLibrary(libraryPath) {
80
80
  "size_t"
81
81
  ]),
82
82
  connectionClose: lib.func(`${SYMBOL_PREFIX}connection_close`, "bool", ["uint32"]),
83
+ connectionSetUiThreadHandler: lib.func(
84
+ `${SYMBOL_PREFIX}connection_set_ui_thread_handler`,
85
+ "bool",
86
+ ["uint32", "bool"]
87
+ ),
88
+ connectionRunUiAction: lib.func(`${SYMBOL_PREFIX}connection_run_ui_action`, "bool", [
89
+ "uint32",
90
+ "uint32"
91
+ ]),
83
92
  outboundCallbackType
84
93
  };
85
94
  loadedLibraryPath = libraryPath;
@@ -230,6 +239,21 @@ class FfiRuntimeHost {
230
239
  throw new Error("Failed to write a frame to the in-process runtime connection.");
231
240
  }
232
241
  }
242
+ configureUiThread(enabled) {
243
+ if (this.disposed || !this.lib.connectionSetUiThreadHandler(this.connectionId, enabled)) {
244
+ throw new Error("Failed to configure the in-process UI dispatcher.");
245
+ }
246
+ }
247
+ runUiAction(actionId) {
248
+ if (!Number.isInteger(actionId) || actionId < 0 || actionId > 4294967295) {
249
+ throw new RangeError("UI action ID must be an unsigned 32-bit integer.");
250
+ }
251
+ if (this.disposed || !this.lib.connectionRunUiAction(this.connectionId, actionId)) {
252
+ throw new Error(
253
+ "Native UI action is retired, already executed, or not running on the process main thread."
254
+ );
255
+ }
256
+ }
233
257
  /**
234
258
  * Native outbound (server→client) callback. koffi delivers it on the JS event loop
235
259
  * via a threadsafe function, so the frame is decoded and written straight to
@@ -4812,6 +4812,11 @@ function registerClientGlobalApiHandlers(connection, handlers) {
4812
4812
  if (!handler) throw new Error("No gitHubToken client-global handler registered");
4813
4813
  return handler.getToken(params);
4814
4814
  });
4815
+ connection.onRequest("uiThread.run", async (params) => {
4816
+ const handler = handlers.uiThread;
4817
+ if (!handler) throw new Error("No uiThread client-global handler registered");
4818
+ return handler.run(params);
4819
+ });
4815
4820
  connection.onRequest("installations.confirm", async (params) => {
4816
4821
  const handler = handlers.installations;
4817
4822
  if (!handler) throw new Error("No installations client-global handler registered");
@@ -574,28 +574,72 @@ class CopilotSession {
574
574
  resolveOutcome = resolve;
575
575
  });
576
576
  let lastAssistantMessage;
577
- const unsubscribe = this.on((event) => {
577
+ let messageId;
578
+ let requestStarted = false;
579
+ let admitted = false;
580
+ const buffered = [];
581
+ const observe = (event) => {
578
582
  if (event.agentId) return;
579
- if (event.type === "assistant.message") {
583
+ if (event.type === "user.message" && event.data.messageId === messageId) {
584
+ requestStarted = true;
585
+ } else if (event.type === "session.warning" && event.data.warningType === "policy_blocked" && event.data.originatingMessageId === messageId) {
586
+ requestStarted = true;
587
+ } else if (event.type === "assistant.message" && (event.data.originatingMessageId === messageId || !event.data.originatingMessageId && requestStarted)) {
580
588
  lastAssistantMessage = event;
581
- } else if (event.type === "session.idle" && event.data.mode !== "autopilot") {
582
- resolveOutcome({ kind: "idle" });
583
- } else if (event.type === "session.error") {
589
+ if (event.data.originatingMessageId === messageId) requestStarted = true;
590
+ } else if (event.type === "session.idle" && requestStarted && event.data.mode !== "autopilot") {
591
+ resolveOutcome(
592
+ event.data.aborted ? {
593
+ kind: "error",
594
+ error: new Error("The requested run was aborted before completion.")
595
+ } : { kind: "idle", message: lastAssistantMessage }
596
+ );
597
+ } else if (event.type === "session.autopilot_stopped" && messageId && event.data.requestId === messageId) {
598
+ if (event.data.reason === "error") {
599
+ resolveOutcome({
600
+ kind: "error",
601
+ error: new Error("Autopilot request failed")
602
+ });
603
+ } else if (event.data.reason === "aborted") {
604
+ resolveOutcome({
605
+ kind: "error",
606
+ error: new Error("The requested run was aborted before completion.")
607
+ });
608
+ } else {
609
+ resolveOutcome({ kind: "idle", message: lastAssistantMessage });
610
+ }
611
+ } else if (event.type === "session.error" && (!event.data.originatingMessageId || event.data.originatingMessageId === messageId)) {
584
612
  const error = new Error(event.data.message);
585
613
  error.stack = event.data.stack;
586
614
  resolveOutcome({ kind: "error", error });
587
615
  }
616
+ };
617
+ const unsubscribe = this.on((event) => {
618
+ if (event.agentId || event.type !== "assistant.message" && event.type !== "user.message" && event.type !== "session.warning" && event.type !== "session.idle" && event.type !== "session.autopilot_stopped" && event.type !== "session.error") {
619
+ return;
620
+ }
621
+ if (!admitted) buffered.push(event);
622
+ else observe(event);
588
623
  });
589
- const fail = (error) => resolveOutcome({ kind: "error", error });
624
+ const fail = (error) => {
625
+ if (!admitted) buffered.push(error);
626
+ else resolveOutcome({ kind: "error", error });
627
+ };
590
628
  this.pendingResponseWaits.add(fail);
591
629
  let timeoutId;
592
630
  try {
593
- await this.send(options);
631
+ messageId = await this.send(options);
632
+ admitted = true;
633
+ for (const event of buffered) {
634
+ if (event instanceof Error) fail(event);
635
+ else observe(event);
636
+ }
637
+ buffered.length = 0;
594
638
  const timeoutPromise = new Promise((_, reject) => {
595
639
  timeoutId = setTimeout(
596
640
  () => reject(
597
641
  new Error(
598
- `Timeout after ${effectiveTimeout}ms waiting for session.idle`
642
+ `Timeout after ${effectiveTimeout}ms waiting for response completion`
599
643
  )
600
644
  ),
601
645
  effectiveTimeout
@@ -605,12 +649,13 @@ class CopilotSession {
605
649
  if (outcome.kind === "error") {
606
650
  throw outcome.error;
607
651
  }
608
- return lastAssistantMessage;
652
+ return outcome.message;
609
653
  } finally {
610
654
  if (timeoutId !== void 0) {
611
655
  clearTimeout(timeoutId);
612
656
  }
613
657
  unsubscribe();
658
+ buffered.length = 0;
614
659
  this.pendingResponseWaits.delete(fail);
615
660
  }
616
661
  }
@@ -634,8 +679,10 @@ class CopilotSession {
634
679
  } else if (event.type === "assistant.message" && event.data.originatingMessageId === messageId) {
635
680
  consumed = true;
636
681
  lastMessage = event.data.toolRequests?.length ? void 0 : event;
637
- } else if (consumed && event.type === "session.idle" && event.data.mode !== "autopilot") {
638
- if (event.data.aborted) {
682
+ } else if (consumed && event.type === "session.idle" && event.data.mode !== "autopilot" || event.type === "session.autopilot_stopped" && event.data.requestId === messageId) {
683
+ if (event.type === "session.autopilot_stopped" && event.data.reason === "error") {
684
+ fail(new Error("Autopilot request failed"));
685
+ } else if (event.type === "session.idle" && event.data.aborted || event.type === "session.autopilot_stopped" && event.data.reason === "aborted") {
639
686
  fail(
640
687
  new Error(
641
688
  "The requested run was aborted before a structured result was completed."
@@ -644,14 +691,14 @@ class CopilotSession {
644
691
  } else {
645
692
  resolveOutcome({ kind: "idle", message: lastMessage });
646
693
  }
647
- } else if (consumed && event.type === "session.error") {
694
+ } else if (event.type === "session.error" && (event.data.originatingMessageId ? event.data.originatingMessageId === messageId : consumed)) {
648
695
  const error = new Error(event.data.message);
649
696
  error.stack = event.data.stack;
650
697
  fail(error);
651
698
  }
652
699
  };
653
700
  const unsubscribe = this.on((event) => {
654
- if (event.type !== "user.message" && event.type !== "assistant.message" && event.type !== "session.idle" && event.type !== "session.error") {
701
+ if (event.type !== "user.message" && event.type !== "assistant.message" && event.type !== "session.idle" && event.type !== "session.autopilot_stopped" && event.type !== "session.error") {
655
702
  return;
656
703
  }
657
704
  if (messageId === void 0) {
package/dist/cjs/types.js CHANGED
@@ -77,8 +77,8 @@ const RuntimeConnection = {
77
77
  * corresponding environment variables on the host process instead. See
78
78
  * https://github.com/github/copilot-sdk/issues/1934.
79
79
  */
80
- forInProcess() {
81
- return { kind: "inprocess" };
80
+ forInProcess(options = {}) {
81
+ return { kind: "inprocess", ...options };
82
82
  }
83
83
  };
84
84
  function convertMcpCallToolResult(callResult) {
@@ -1,2 +1,2 @@
1
- export declare const COPILOT_CLI_VERSION = "1.0.101";
1
+ export declare const COPILOT_CLI_VERSION = "1.0.102-1";
2
2
  export declare const COPILOT_CLI_USE_NPM_PACKAGE = false;
@@ -1,4 +1,4 @@
1
- const COPILOT_CLI_VERSION = "1.0.101";
1
+ const COPILOT_CLI_VERSION = "1.0.102-1";
2
2
  const COPILOT_CLI_USE_NPM_PACKAGE = false;
3
3
  export {
4
4
  COPILOT_CLI_USE_NPM_PACKAGE,
package/dist/client.js CHANGED
@@ -600,6 +600,16 @@ class CopilotClient {
600
600
  handlers.gitHubToken = {
601
601
  getToken: (params) => this.acquireGitHubToken(params)
602
602
  };
603
+ handlers.uiThread = {
604
+ run: async ({ actionId }) => {
605
+ const connection = this.connectionConfig;
606
+ const host = this.ffiHost;
607
+ if (connection.kind !== "inprocess" || !connection.runOnUiThread || !host) {
608
+ throw new Error("No in-process runOnUiThread handler is configured.");
609
+ }
610
+ await connection.runOnUiThread(() => host.runUiAction(actionId));
611
+ }
612
+ };
603
613
  this.clientGlobalHandlers = handlers;
604
614
  }
605
615
  async acquireGitHubToken(params) {
@@ -1338,6 +1348,7 @@ class CopilotClient {
1338
1348
  enableCitations: config.enableCitations,
1339
1349
  enableFileChangeTracking: config.enableFileChangeTracking,
1340
1350
  sessionLimits: config.sessionLimits,
1351
+ autopilot: config.autopilot,
1341
1352
  modelCapabilities: config.modelCapabilities,
1342
1353
  largeOutput: toWireLargeOutput(config.largeOutput),
1343
1354
  requestPermission: !!config.onPermissionRequest,
@@ -1585,6 +1596,7 @@ class CopilotClient {
1585
1596
  enableCitations: config.enableCitations,
1586
1597
  enableFileChangeTracking: config.enableFileChangeTracking,
1587
1598
  sessionLimits: config.sessionLimits,
1599
+ autopilot: config.autopilot,
1588
1600
  tools: config.tools?.map((tool) => ({
1589
1601
  name: tool.name,
1590
1602
  description: tool.description,
@@ -2535,6 +2547,9 @@ stderr: ${this.stderrBuffer.trim().slice(-8192) || "(empty)"}`
2535
2547
  );
2536
2548
  this.attachConnectionHandlers();
2537
2549
  this.connection.listen();
2550
+ this.ffiHost.configureUiThread(
2551
+ this.connectionConfig.kind === "inprocess" && this.connectionConfig.runOnUiThread !== void 0
2552
+ );
2538
2553
  }
2539
2554
  static getNapiPrebuildsFolder(entrypoint) {
2540
2555
  const arch = process.arch;
@@ -26,6 +26,8 @@ export declare class FfiRuntimeHost {
26
26
  /** Starts the in-process Rust runtime and opens the FFI JSON-RPC connection. */
27
27
  start(): Promise<void>;
28
28
  private writeFrame;
29
+ configureUiThread(enabled: boolean): void;
30
+ runUiAction(actionId: number): void;
29
31
  /**
30
32
  * Native outbound (server→client) callback. koffi delivers it on the JS event loop
31
33
  * via a threadsafe function, so the frame is decoded and written straight to
@@ -47,6 +47,15 @@ function loadLibrary(libraryPath) {
47
47
  "size_t"
48
48
  ]),
49
49
  connectionClose: lib.func(`${SYMBOL_PREFIX}connection_close`, "bool", ["uint32"]),
50
+ connectionSetUiThreadHandler: lib.func(
51
+ `${SYMBOL_PREFIX}connection_set_ui_thread_handler`,
52
+ "bool",
53
+ ["uint32", "bool"]
54
+ ),
55
+ connectionRunUiAction: lib.func(`${SYMBOL_PREFIX}connection_run_ui_action`, "bool", [
56
+ "uint32",
57
+ "uint32"
58
+ ]),
50
59
  outboundCallbackType
51
60
  };
52
61
  loadedLibraryPath = libraryPath;
@@ -197,6 +206,21 @@ class FfiRuntimeHost {
197
206
  throw new Error("Failed to write a frame to the in-process runtime connection.");
198
207
  }
199
208
  }
209
+ configureUiThread(enabled) {
210
+ if (this.disposed || !this.lib.connectionSetUiThreadHandler(this.connectionId, enabled)) {
211
+ throw new Error("Failed to configure the in-process UI dispatcher.");
212
+ }
213
+ }
214
+ runUiAction(actionId) {
215
+ if (!Number.isInteger(actionId) || actionId < 0 || actionId > 4294967295) {
216
+ throw new RangeError("UI action ID must be an unsigned 32-bit integer.");
217
+ }
218
+ if (this.disposed || !this.lib.connectionRunUiAction(this.connectionId, actionId)) {
219
+ throw new Error(
220
+ "Native UI action is retired, already executed, or not running on the process main thread."
221
+ );
222
+ }
223
+ }
200
224
  /**
201
225
  * Native outbound (server→client) callback. koffi delivers it on the JS event loop
202
226
  * via a threadsafe function, so the frame is decoded and written straight to
@@ -3884,6 +3884,18 @@ export type OptionsUpdateToolFilterPrecedence =
3884
3884
  "available"
3885
3885
  /** A tool is enabled if and only if it matches the allowlist (or the allowlist is unset) AND it does not match the denylist. Makes 'all except X' expressible by combining the two lists. */
3886
3886
  | "excluded";
3887
+ /**
3888
+ * Memory injection mode. Defaults to system-prompt.
3889
+ *
3890
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
3891
+ * via the `definition` "MemoryMode".
3892
+ */
3893
+ /** @experimental */
3894
+ export type MemoryMode =
3895
+ /** Include memories in the system prompt (default). */
3896
+ "system-prompt"
3897
+ /** Include memories in user messages. */
3898
+ | "user-prompt";
3887
3899
  /**
3888
3900
  * Per-source context-window attribution, or null if the session has not yet been initialized (no system prompt or tool metadata cached).
3889
3901
  *
@@ -8244,6 +8256,17 @@ export interface AutopilotObjectiveState {
8244
8256
  creditCountNanoAiu: string;
8245
8257
  creditLimit?: AutopilotObjectiveCreditLimit;
8246
8258
  }
8259
+ /** @experimental */
8260
+ export interface AutopilotOptions {
8261
+ /**
8262
+ * Enable runtime-owned automatic continuation while in Autopilot mode. Defaults to true for SDK sessions; does not change the session mode.
8263
+ */
8264
+ continuationEnabled?: boolean;
8265
+ /**
8266
+ * Maximum automatic continuations outside an active objective. Zero allows none; defaults to five. Omitted values preserve the current limit on update or warm resume.
8267
+ */
8268
+ maxContinues?: number;
8269
+ }
8247
8270
  /**
8248
8271
  * Billing information for a server-advertised routing preference.
8249
8272
  *
@@ -18436,6 +18459,12 @@ export interface MemoryConfiguration {
18436
18459
  * Whether memory is enabled for the session.
18437
18460
  */
18438
18461
  enabled: boolean;
18462
+ /**
18463
+ * Memory injection mode: system-prompt (default) includes memories in the system prompt; user-prompt includes them in user messages.
18464
+ *
18465
+ * @experimental
18466
+ */
18467
+ mode?: MemoryMode;
18439
18468
  }
18440
18469
  /**
18441
18470
  * Per-source attribution breakdown for the session's current context window, or null if uninitialized.
@@ -26304,6 +26333,7 @@ export interface SessionOpenOptions {
26304
26333
  maxInlineBinaryBytes?: number;
26305
26334
  modelCapabilitiesOverrides?: ModelCapabilitiesOverride;
26306
26335
  sessionLimits?: SessionLimitsConfig;
26336
+ autopilot?: AutopilotOptions;
26307
26337
  /**
26308
26338
  * Runtime context discriminator for agent filtering.
26309
26339
  */
@@ -28153,6 +28183,7 @@ export interface SessionUpdateOptionsParams {
28153
28183
  * Optional session limits. Pass null to clear the session limits.
28154
28184
  */
28155
28185
  sessionLimits?: SessionLimitsConfig | null;
28186
+ autopilot?: AutopilotOptions;
28156
28187
  }
28157
28188
  /**
28158
28189
  * Indicates whether the session options patch was applied successfully.
@@ -28750,7 +28781,7 @@ export interface SlashCommandTimelineEntry {
28750
28781
  remediation?: RemediationAction;
28751
28782
  }
28752
28783
  /**
28753
- * Slash-command invocation result that submits an agent prompt, with display prompt, optional mode, optional user-facing notice, and settings-change flag.
28784
+ * Slash-command invocation result that submits an agent prompt, with display prompt, optional mode, optional user-facing notice, settings-change flag, and opaque reservation finalization token.
28754
28785
  *
28755
28786
  * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
28756
28787
  * via the `definition` "SlashCommandAgentPromptResult".
@@ -28778,6 +28809,10 @@ export interface SlashCommandAgentPromptResult {
28778
28809
  * True when the invocation mutated user runtime settings; consumers caching settings should refresh
28779
28810
  */
28780
28811
  runtimeSettingsChanged?: boolean;
28812
+ /**
28813
+ * Opaque token used to finalize this invocation's objective prompt reservation
28814
+ */
28815
+ reservationToken?: string;
28781
28816
  }
28782
28817
  /**
28783
28818
  * Slash-command invocation result indicating completion, with optional message and settings-change flag.
@@ -30657,6 +30692,19 @@ export interface UIRegisterDirectAutoModeSwitchHandlerResult {
30657
30692
  */
30658
30693
  handle: string;
30659
30694
  }
30695
+ /**
30696
+ * Identifies one runtime-owned native action for an in-process SDK UI dispatcher.
30697
+ *
30698
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
30699
+ * via the `definition` "UiThreadRunRequest".
30700
+ */
30701
+ /** @experimental */
30702
+ export interface UiThreadRunRequest {
30703
+ /**
30704
+ * Opaque, one-shot action identifier scoped to the receiving native connection. Execute only through the synchronous native UI-action entry point.
30705
+ */
30706
+ actionId: number;
30707
+ }
30660
30708
  /**
30661
30709
  * Opaque handle previously returned by `registerDirectAutoModeSwitchHandler` to release.
30662
30710
  *
@@ -37337,6 +37385,16 @@ export interface GitHubTokenHandler {
37337
37385
  */
37338
37386
  getToken(params: GitHubTokenAcquireRequest): Promise<GitHubTokenAcquireResult>;
37339
37387
  }
37388
+ /** Handler for `uiThread` client global API methods. */
37389
+ /** @experimental */
37390
+ export interface UiThreadHandler {
37391
+ /**
37392
+ * Schedules a runtime-owned native action through an in-process SDK host's runOnUiThread callback. The SDK supplies an action that enters the native C ABI synchronously; the host executes it exactly once on its UI thread (the process main thread on macOS) and completes only after it returns. Never sent to out-of-process clients.
37393
+ *
37394
+ * @param params Identifies one runtime-owned native action for an in-process SDK UI dispatcher.
37395
+ */
37396
+ run(params: UiThreadRunRequest): Promise<void>;
37397
+ }
37340
37398
  /** Handler for `installations` client global API methods. */
37341
37399
  /** @experimental */
37342
37400
  export interface InstallationsHandler {
@@ -37356,6 +37414,7 @@ export interface ClientGlobalApiHandlers {
37356
37414
  llmInference?: LlmInferenceHandler;
37357
37415
  gitHubTelemetry?: GitHubTelemetryHandler;
37358
37416
  gitHubToken?: GitHubTokenHandler;
37417
+ uiThread?: UiThreadHandler;
37359
37418
  installations?: InstallationsHandler;
37360
37419
  }
37361
37420
  /**
@@ -4784,6 +4784,11 @@ function registerClientGlobalApiHandlers(connection, handlers) {
4784
4784
  if (!handler) throw new Error("No gitHubToken client-global handler registered");
4785
4785
  return handler.getToken(params);
4786
4786
  });
4787
+ connection.onRequest("uiThread.run", async (params) => {
4788
+ const handler = handlers.uiThread;
4789
+ if (!handler) throw new Error("No uiThread client-global handler registered");
4790
+ return handler.run(params);
4791
+ });
4787
4792
  connection.onRequest("installations.confirm", async (params) => {
4788
4793
  const handler = handlers.installations;
4789
4794
  if (!handler) throw new Error("No installations client-global handler registered");
@@ -9,7 +9,7 @@ export type JsonValue = null | boolean | number | string | JsonValue[] | {
9
9
  /**
10
10
  * Union of all session event variants emitted by the Copilot CLI runtime.
11
11
  */
12
- export type SessionEvent = StartEvent | ResumeEvent | RemoteSteerableChangedEvent | ErrorEvent | IdleEvent | TitleChangedEvent | ScheduleCreatedEvent | ScheduleCancelledEvent | ScheduleRearmedEvent | AutopilotObjectiveChangedEvent | InfoEvent | IndexedSearchEvent | WarningEvent | ModelChangeEvent | ModelDeselectedEvent | AutoTierRecommendationEvent | AutoTierSwitchFailedEvent | ModeChangedEvent | ModeNoticeDeliveredEvent | SessionLimitsChangedEvent | PermissionsChangedEvent | PlanChangedEvent | TodosChangedEvent | WorkspaceFileChangedEvent | HandoffEvent | TruncationEvent | SnapshotRewindEvent | ShutdownEvent | UsageCheckpointEvent | ProviderQuotaObservationEvent | ContextChangedEvent | UsageInfoEvent | ContextClearedEvent | CompactionStartEvent | CompactionCompleteEvent | TaskCompleteEvent | CompletionReceiptEvent | FusionRouteStartedEvent | FusionRouteFailedEvent | FusionResolvedEvent | FusionCompletedEvent | PermissionRecoveryEvent | UserMessageEvent | PendingMessagesModifiedEvent | AssistantTurnStartEvent | AssistantIntentEvent | AssistantFusionPhaseStartedEvent | AssistantFusionPhaseActivityEvent | AssistantFusionPhaseCompletedEvent | AssistantFusionPhaseFailedEvent | AssistantServerToolProgressEvent | AssistantReasoningEvent | AssistantReasoningDeltaEvent | AssistantToolCallDeltaEvent | AssistantStreamingDeltaEvent | AssistantMessageEvent | AssistantMessageStartEvent | AssistantMessageDeltaEvent | AssistantTurnEndEvent | AssistantIdleEvent | AssistantUsageEvent | ModelCallFailureEvent | ModelCallFinishedEvent | AbortEvent | ToolUserRequestedEvent | ToolExecutionStartEvent | ToolExecutionPartialResultEvent | ToolShellOutputEvent | ToolExecutionProgressEvent | ToolExecutionCompleteEvent | ToolSearchActivatedEvent | SkillInvokedEvent | SubagentStartedEvent | SubagentConfiguredEvent | SubagentCompletedEvent | SubagentFailedEvent | SubagentSelectedEvent | SubagentDeselectedEvent | HookStartEvent | HookEndEvent | HookProgressEvent | BinaryAssetEvent | SystemMessageEvent | SystemNotificationEvent | PermissionRequestedEvent | PermissionCompletedEvent | PermissionCarriedForwardEvent | PermissionMessageAuthorizationEvent | PermissionMessageAuthorizationReadEvent | PermissionMessageAuthorizationDegradedEvent | PermissionAssentDetectedEvent | PermissionContextualAuthorizationEvent | UserInputRequestedEvent | UserInputCompletedEvent | ElicitationRequestedEvent | ElicitationCompletedEvent | SamplingRequestedEvent | SamplingCompletedEvent | McpOauthRequiredEvent | McpOauthCompletedEvent | McpOauthRecoveryCompletedEvent | McpHeadersRefreshRequiredEvent | McpHeadersRefreshCompletedEvent | CustomNotificationEvent | UIEphemeralQueryEvent | ExternalToolRequestedEvent | ExternalToolCompletedEvent | CommandQueuedEvent | CommandExecuteEvent | CommandCompletedEvent | AutoModeSwitchRequestedEvent | AutoModeSwitchCompletedEvent | SessionLimitsExhaustedRequestedEvent | SessionLimitsExhaustedCompletedEvent | AutoModeResolvedEvent | ManagedPluginProgressEvent | ManagedSettingsResolvedEvent | ManagedSettingsEnforcedEvent | CommandsChangedEvent | CapabilitiesChangedEvent | ExitPlanModeRequestedEvent | ExitPlanModeCompletedEvent | HumanResponseRecordedEvent | ToolsUpdatedEvent | BackgroundTasksChangedEvent | WorkflowRunUpdatedEvent | WorkflowRunStartedEvent | WorkflowRunSettledEvent | SkillsLoadedEvent | CustomAgentsUpdatedEvent | McpServersLoadedEvent | McpServerStatusChangedEvent | McpServerToolsLoadedEvent | McpServerRemovedEvent | McpServerNeedsReconnectEvent | McpToolsListChangedEvent | McpResourcesListChangedEvent | McpPromptsListChangedEvent | ExtensionsLoadedEvent | CanvasOpenedEvent | CanvasRegistryChangedEvent | CanvasClosedEvent | CanvasUnavailableEvent | CanvasRecordedEvent | CanvasRemovedEvent | ExtensionsAttachmentsPushedEvent | McpAppToolCallCompleteEvent;
12
+ export type SessionEvent = StartEvent | ResumeEvent | RemoteSteerableChangedEvent | ErrorEvent | IdleEvent | AutopilotStoppedEvent | TitleChangedEvent | ScheduleCreatedEvent | ScheduleCancelledEvent | ScheduleRearmedEvent | AutopilotObjectiveChangedEvent | InfoEvent | IndexedSearchEvent | WarningEvent | ModelChangeEvent | ModelDeselectedEvent | AutoTierRecommendationEvent | AutoTierSwitchFailedEvent | ModeChangedEvent | ModeNoticeDeliveredEvent | SessionLimitsChangedEvent | PermissionsChangedEvent | PlanChangedEvent | TodosChangedEvent | WorkspaceFileChangedEvent | HandoffEvent | TruncationEvent | SnapshotRewindEvent | ShutdownEvent | UsageCheckpointEvent | ProviderQuotaObservationEvent | ContextChangedEvent | UsageInfoEvent | ContextClearedEvent | CompactionStartEvent | CompactionCompleteEvent | TaskCompleteEvent | CompletionReceiptEvent | FusionRouteStartedEvent | FusionRouteFailedEvent | FusionResolvedEvent | FusionCompletedEvent | PermissionRecoveryEvent | UserMessageEvent | PendingMessagesModifiedEvent | AssistantTurnStartEvent | AssistantIntentEvent | AssistantFusionPhaseStartedEvent | AssistantFusionPhaseActivityEvent | AssistantFusionPhaseCompletedEvent | AssistantFusionPhaseFailedEvent | AssistantServerToolProgressEvent | AssistantReasoningEvent | AssistantReasoningDeltaEvent | AssistantToolCallDeltaEvent | AssistantStreamingDeltaEvent | AssistantMessageEvent | AssistantMessageStartEvent | AssistantMessageDeltaEvent | AssistantTurnEndEvent | AssistantIdleEvent | AssistantUsageEvent | ModelCallFailureEvent | ModelCallFinishedEvent | AbortEvent | ToolUserRequestedEvent | ToolExecutionStartEvent | ToolExecutionPartialResultEvent | ToolShellOutputEvent | ToolExecutionProgressEvent | ToolExecutionCompleteEvent | ToolSearchActivatedEvent | SkillInvokedEvent | SubagentStartedEvent | SubagentConfiguredEvent | SubagentCompletedEvent | SubagentFailedEvent | SubagentSelectedEvent | SubagentDeselectedEvent | HookStartEvent | HookEndEvent | HookProgressEvent | BinaryAssetEvent | SystemMessageEvent | SystemNotificationEvent | PermissionRequestedEvent | PermissionCompletedEvent | PermissionCarriedForwardEvent | PermissionMessageAuthorizationEvent | PermissionMessageAuthorizationReadEvent | PermissionMessageAuthorizationDegradedEvent | PermissionAssentDetectedEvent | PermissionContextualAuthorizationEvent | UserInputRequestedEvent | UserInputCompletedEvent | ElicitationRequestedEvent | ElicitationCompletedEvent | SamplingRequestedEvent | SamplingCompletedEvent | McpOauthRequiredEvent | McpOauthCompletedEvent | McpOauthRecoveryCompletedEvent | McpHeadersRefreshRequiredEvent | McpHeadersRefreshCompletedEvent | CustomNotificationEvent | UIEphemeralQueryEvent | ExternalToolRequestedEvent | ExternalToolCompletedEvent | CommandQueuedEvent | CommandExecuteEvent | CommandCompletedEvent | AutoModeSwitchRequestedEvent | AutoModeSwitchCompletedEvent | SessionLimitsExhaustedRequestedEvent | SessionLimitsExhaustedCompletedEvent | AutoModeResolvedEvent | ManagedPluginProgressEvent | ManagedSettingsResolvedEvent | ManagedSettingsEnforcedEvent | CommandsChangedEvent | CapabilitiesChangedEvent | ExitPlanModeRequestedEvent | ExitPlanModeCompletedEvent | HumanResponseRecordedEvent | ToolsUpdatedEvent | BackgroundTasksChangedEvent | WorkflowRunUpdatedEvent | WorkflowRunStartedEvent | WorkflowRunSettledEvent | SkillsLoadedEvent | CustomAgentsUpdatedEvent | McpServersLoadedEvent | McpServerStatusChangedEvent | McpServerToolsLoadedEvent | McpServerRemovedEvent | McpServerNeedsReconnectEvent | McpToolsListChangedEvent | McpResourcesListChangedEvent | McpPromptsListChangedEvent | ExtensionsLoadedEvent | CanvasOpenedEvent | CanvasRegistryChangedEvent | CanvasClosedEvent | CanvasUnavailableEvent | CanvasRecordedEvent | CanvasRemovedEvent | ExtensionsAttachmentsPushedEvent | McpAppToolCallCompleteEvent;
13
13
  /**
14
14
  * Extensible routing preference for the virtual `auto` model. New identifiers must be advertised and enabled by the provider. `fast` is an integrator-only latency preset.
15
15
  */
@@ -1969,6 +1969,10 @@ export interface ErrorData {
1969
1969
  * Human-readable error message
1970
1970
  */
1971
1971
  message: string;
1972
+ /**
1973
+ * Original root user-message ID of the failed request, including failures before user.message is emitted. Absent for session-wide errors or legacy hosts.
1974
+ */
1975
+ originatingMessageId?: string;
1972
1976
  /**
1973
1977
  * GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs
1974
1978
  */
@@ -2039,6 +2043,49 @@ export interface IdleData {
2039
2043
  aborted?: boolean;
2040
2044
  mode?: SessionMode;
2041
2045
  }
2046
+ /**
2047
+ * Session event "session.autopilot_stopped". The runtime has stopped continuing one Autopilot request. Attached background work may remain active; this is not session-wide idle.
2048
+ */
2049
+ export interface AutopilotStoppedEvent {
2050
+ /**
2051
+ * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events.
2052
+ */
2053
+ agentId?: string;
2054
+ data: AutopilotStoppedData;
2055
+ /**
2056
+ * Always true for events that are transient and not persisted to the session event log on disk.
2057
+ */
2058
+ ephemeral: true;
2059
+ /**
2060
+ * Unique event identifier (UUID v4), generated when the event is emitted
2061
+ */
2062
+ id: string;
2063
+ /**
2064
+ * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event.
2065
+ */
2066
+ parentId: string | null;
2067
+ /**
2068
+ * ISO 8601 timestamp when the event was created
2069
+ */
2070
+ timestamp: string;
2071
+ /**
2072
+ * Type discriminator. Always "session.autopilot_stopped".
2073
+ */
2074
+ type: "session.autopilot_stopped";
2075
+ }
2076
+ /**
2077
+ * The runtime has stopped continuing one Autopilot request. Attached background work may remain active; this is not session-wide idle.
2078
+ */
2079
+ export interface AutopilotStoppedData {
2080
+ /**
2081
+ * The terminal policy reason, such as task_complete, aborted, error, or background_timeout.
2082
+ */
2083
+ reason: string;
2084
+ /**
2085
+ * Original root user message ID for this request, absent when no root request is available.
2086
+ */
2087
+ requestId?: string;
2088
+ }
2042
2089
  /**
2043
2090
  * Session event "session.title_changed". Session title change payload containing the new display title
2044
2091
  */
@@ -2392,6 +2439,10 @@ export interface WarningData {
2392
2439
  * Human-readable warning message for display in the timeline
2393
2440
  */
2394
2441
  message: string;
2442
+ /**
2443
+ * Logical ID returned by session.send for the request this warning concerns. Set for policy-blocked prompts, which do not emit a user.message event.
2444
+ */
2445
+ originatingMessageId?: string;
2395
2446
  remediation?: RemediationAction;
2396
2447
  /**
2397
2448
  * Optional URL associated with this warning that the user can open in a browser
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * JSON-RPC based SDK for programmatic control of GitHub Copilot CLI
5
5
  */
6
6
  export { CopilotClient } from "./client.js";
7
- export type { HostLocalServerOptions, HostGitHubEnvironmentOptions, ModelGetReasoningSummariesRequest, ModelGetReasoningSummariesResult, SandboxConfig, } from "./generated/rpc.js";
7
+ export type { HostLocalServerOptions, HostGitHubEnvironmentOptions, ModelGetReasoningSummariesRequest, ModelGetReasoningSummariesResult, SandboxConfig, AutopilotOptions, } from "./generated/rpc.js";
8
8
  export { AhpHost, type AhpHostExit, type AhpHostOptions, type AhpSessionCreateRequest, type AhpSessionResumeRequest, } from "./host.js";
9
9
  export { DisableBypassPermissionsModes, RuntimeConnection } from "./types.js";
10
10
  export { BuiltInTools, ToolSet } from "./toolSet.js";
package/dist/session.d.ts CHANGED
@@ -144,10 +144,12 @@ export declare class CopilotSession {
144
144
  send(prompt: string): Promise<string>;
145
145
  send(options: MessageOptions): Promise<string>;
146
146
  /**
147
- * Sends a message to this session and waits until the session becomes idle.
147
+ * Sends a message and waits for its response to complete.
148
148
  *
149
149
  * This is a convenience method that combines {@link send} with waiting for
150
- * the `session.idle` event. Use this when you want to block until the
150
+ * non-Autopilot `session.idle` or the request-correlated `session.autopilot_stopped`
151
+ * event. Autopilot completion does not wait for or stop attached shells.
152
+ * Use this when you want to block until the
151
153
  * assistant has finished processing the message.
152
154
  *
153
155
  * Events are still delivered to handlers registered via {@link on} while waiting.
@@ -158,9 +160,10 @@ export declare class CopilotSession {
158
160
  *
159
161
  * @param options - The message options including the prompt and optional attachments
160
162
  * @param timeout - Timeout in milliseconds (default: 60000). Controls how long to wait; does not abort in-flight agent work.
161
- * @returns A promise that resolves with the final assistant message when the session becomes idle,
163
+ * @returns A promise that resolves with the final assistant message on completion,
162
164
  * or undefined if no assistant message was received
163
- * @throws Error if the timeout is reached before the session becomes idle
165
+ * @throws Error if the run is aborted before completion
166
+ * @throws Error if the timeout is reached before response completion
164
167
  * @throws Error if the session has been disconnected or the connection fails
165
168
  *
166
169
  * @example
package/dist/session.js CHANGED
@@ -556,28 +556,72 @@ class CopilotSession {
556
556
  resolveOutcome = resolve;
557
557
  });
558
558
  let lastAssistantMessage;
559
- const unsubscribe = this.on((event) => {
559
+ let messageId;
560
+ let requestStarted = false;
561
+ let admitted = false;
562
+ const buffered = [];
563
+ const observe = (event) => {
560
564
  if (event.agentId) return;
561
- if (event.type === "assistant.message") {
565
+ if (event.type === "user.message" && event.data.messageId === messageId) {
566
+ requestStarted = true;
567
+ } else if (event.type === "session.warning" && event.data.warningType === "policy_blocked" && event.data.originatingMessageId === messageId) {
568
+ requestStarted = true;
569
+ } else if (event.type === "assistant.message" && (event.data.originatingMessageId === messageId || !event.data.originatingMessageId && requestStarted)) {
562
570
  lastAssistantMessage = event;
563
- } else if (event.type === "session.idle" && event.data.mode !== "autopilot") {
564
- resolveOutcome({ kind: "idle" });
565
- } else if (event.type === "session.error") {
571
+ if (event.data.originatingMessageId === messageId) requestStarted = true;
572
+ } else if (event.type === "session.idle" && requestStarted && event.data.mode !== "autopilot") {
573
+ resolveOutcome(
574
+ event.data.aborted ? {
575
+ kind: "error",
576
+ error: new Error("The requested run was aborted before completion.")
577
+ } : { kind: "idle", message: lastAssistantMessage }
578
+ );
579
+ } else if (event.type === "session.autopilot_stopped" && messageId && event.data.requestId === messageId) {
580
+ if (event.data.reason === "error") {
581
+ resolveOutcome({
582
+ kind: "error",
583
+ error: new Error("Autopilot request failed")
584
+ });
585
+ } else if (event.data.reason === "aborted") {
586
+ resolveOutcome({
587
+ kind: "error",
588
+ error: new Error("The requested run was aborted before completion.")
589
+ });
590
+ } else {
591
+ resolveOutcome({ kind: "idle", message: lastAssistantMessage });
592
+ }
593
+ } else if (event.type === "session.error" && (!event.data.originatingMessageId || event.data.originatingMessageId === messageId)) {
566
594
  const error = new Error(event.data.message);
567
595
  error.stack = event.data.stack;
568
596
  resolveOutcome({ kind: "error", error });
569
597
  }
598
+ };
599
+ const unsubscribe = this.on((event) => {
600
+ if (event.agentId || event.type !== "assistant.message" && event.type !== "user.message" && event.type !== "session.warning" && event.type !== "session.idle" && event.type !== "session.autopilot_stopped" && event.type !== "session.error") {
601
+ return;
602
+ }
603
+ if (!admitted) buffered.push(event);
604
+ else observe(event);
570
605
  });
571
- const fail = (error) => resolveOutcome({ kind: "error", error });
606
+ const fail = (error) => {
607
+ if (!admitted) buffered.push(error);
608
+ else resolveOutcome({ kind: "error", error });
609
+ };
572
610
  this.pendingResponseWaits.add(fail);
573
611
  let timeoutId;
574
612
  try {
575
- await this.send(options);
613
+ messageId = await this.send(options);
614
+ admitted = true;
615
+ for (const event of buffered) {
616
+ if (event instanceof Error) fail(event);
617
+ else observe(event);
618
+ }
619
+ buffered.length = 0;
576
620
  const timeoutPromise = new Promise((_, reject) => {
577
621
  timeoutId = setTimeout(
578
622
  () => reject(
579
623
  new Error(
580
- `Timeout after ${effectiveTimeout}ms waiting for session.idle`
624
+ `Timeout after ${effectiveTimeout}ms waiting for response completion`
581
625
  )
582
626
  ),
583
627
  effectiveTimeout
@@ -587,12 +631,13 @@ class CopilotSession {
587
631
  if (outcome.kind === "error") {
588
632
  throw outcome.error;
589
633
  }
590
- return lastAssistantMessage;
634
+ return outcome.message;
591
635
  } finally {
592
636
  if (timeoutId !== void 0) {
593
637
  clearTimeout(timeoutId);
594
638
  }
595
639
  unsubscribe();
640
+ buffered.length = 0;
596
641
  this.pendingResponseWaits.delete(fail);
597
642
  }
598
643
  }
@@ -616,8 +661,10 @@ class CopilotSession {
616
661
  } else if (event.type === "assistant.message" && event.data.originatingMessageId === messageId) {
617
662
  consumed = true;
618
663
  lastMessage = event.data.toolRequests?.length ? void 0 : event;
619
- } else if (consumed && event.type === "session.idle" && event.data.mode !== "autopilot") {
620
- if (event.data.aborted) {
664
+ } else if (consumed && event.type === "session.idle" && event.data.mode !== "autopilot" || event.type === "session.autopilot_stopped" && event.data.requestId === messageId) {
665
+ if (event.type === "session.autopilot_stopped" && event.data.reason === "error") {
666
+ fail(new Error("Autopilot request failed"));
667
+ } else if (event.type === "session.idle" && event.data.aborted || event.type === "session.autopilot_stopped" && event.data.reason === "aborted") {
621
668
  fail(
622
669
  new Error(
623
670
  "The requested run was aborted before a structured result was completed."
@@ -626,14 +673,14 @@ class CopilotSession {
626
673
  } else {
627
674
  resolveOutcome({ kind: "idle", message: lastMessage });
628
675
  }
629
- } else if (consumed && event.type === "session.error") {
676
+ } else if (event.type === "session.error" && (event.data.originatingMessageId ? event.data.originatingMessageId === messageId : consumed)) {
630
677
  const error = new Error(event.data.message);
631
678
  error.stack = event.data.stack;
632
679
  fail(error);
633
680
  }
634
681
  };
635
682
  const unsubscribe = this.on((event) => {
636
- if (event.type !== "user.message" && event.type !== "assistant.message" && event.type !== "session.idle" && event.type !== "session.error") {
683
+ if (event.type !== "user.message" && event.type !== "assistant.message" && event.type !== "session.idle" && event.type !== "session.autopilot_stopped" && event.type !== "session.error") {
637
684
  return;
638
685
  }
639
686
  if (messageId === void 0) {
package/dist/types.d.ts CHANGED
@@ -9,9 +9,10 @@ export type { InstallationConfirmationHandler } from "./installationConfirmation
9
9
  import type { AgentModelPolicy, AttachmentExtensionContext as GeneratedExtensionContextAttachment, AutoTier, PermissionRequest as GeneratedPermissionRequest, PermissionRequestedData as GeneratedPermissionRequestedData, PermissionRequestedEvent as GeneratedPermissionRequestedEvent, ReasoningSummary, SessionLimitsConfig, SessionEvent as GeneratedSessionEvent } from "./generated/session-events.js";
10
10
  import type { CopilotSession } from "./session.js";
11
11
  import type { JsonValue } from "./workflow.js";
12
- import type { ExtensionLaunchProviderHandler as GeneratedExtensionLaunchProvider, GitHubTokenAcquireRequest, GitHubTokenAcquireResult, GitHubTelemetryNotification, ModelBillingTokenPrices, DiagnosticsConfiguration, OpenCanvasInstance, ProtocolExternalToolNamespace, RemoteSessionMode, CurrentToolMetadata, SandboxConfig } from "./generated/rpc.js";
12
+ import type { ExtensionLaunchProviderHandler as GeneratedExtensionLaunchProvider, AutopilotOptions, GitHubTokenAcquireRequest, GitHubTokenAcquireResult, GitHubTelemetryNotification, ModelBillingTokenPrices, DiagnosticsConfiguration, OpenCanvasInstance, ProtocolExternalToolNamespace, RemoteSessionMode, CurrentToolMetadata, SandboxConfig } from "./generated/rpc.js";
13
13
  import type { ToolSet } from "./toolSet.js";
14
14
  export type { RemoteSessionMode } from "./generated/rpc.js";
15
+ export type { AutopilotOptions } from "./generated/rpc.js";
15
16
  export type { CurrentToolMetadata } from "./generated/rpc.js";
16
17
  export type { SandboxConfig, SandboxConfigSource } from "./generated/rpc.js";
17
18
  export type { AuthIdentityMetadata, AuthInfoType, ConnectorAccountRequest, ConnectorAvailability, ConnectorCapabilities, ConnectorCatalogEntry, ConnectorCatalogResult, ConnectorCatalogStatus, ConnectorConnectRequest, ConnectorConnectResult, ConnectorContinueRequest, ConnectorDisconnectResult, ConnectorMcpStatus, ConnectorReconcileRequest, ConnectorRuntimeStatus, ConnectorSessionAccount, ConnectorSessionAccountResult, ConnectorStatus, ExtensionLaunchProfile, ExtensionLaunchProviderResolveRequest, ExtensionLaunchProviderResolveResult, GitHubTokenAcquireReason, GitHubTokenAcquireResult, GitHubTelemetryNotification, GitHubTelemetryEvent, GitHubTelemetryClientInfo, InstallationConfirmationRequest, InstallationConfirmationResponse, InstallationDecision, InstallationReview, McpInstallationReview, } from "./generated/rpc.js";
@@ -140,6 +141,19 @@ export interface StdioRuntimeConnection extends ChildProcessRuntimeConnection {
140
141
  */
141
142
  export interface InProcessRuntimeConnection {
142
143
  readonly kind: "inprocess";
144
+ /**
145
+ * Schedule the supplied native action exactly once on the host's UI thread
146
+ * (the process main thread on macOS), completing only after it returns.
147
+ * The action can block while native UI is open. No authentication data crosses
148
+ * this callback. Other in-process clients can share this process-wide capability.
149
+ *
150
+ * Required for OneAuth interactive authentication on macOS. This general-purpose
151
+ * scheduler may also be used for other runtime-owned native UI operations.
152
+ * Temporary OneAuth workaround; this API may be removed if no longer needed.
153
+ * See https://github.com/github/copilot-agent-runtime/issues/27032.
154
+ * @experimental
155
+ */
156
+ readonly runOnUiThread?: (action: () => void) => void | Promise<void>;
143
157
  }
144
158
  /**
145
159
  * Spawns a runtime child process that listens on a TCP socket and connects to it.
@@ -209,7 +223,7 @@ export declare const RuntimeConnection: {
209
223
  * corresponding environment variables on the host process instead. See
210
224
  * https://github.com/github/copilot-sdk/issues/1934.
211
225
  */
212
- readonly forInProcess: () => InProcessRuntimeConnection;
226
+ readonly forInProcess: (options?: Pick<InProcessRuntimeConnection, "runOnUiThread">) => InProcessRuntimeConnection;
213
227
  };
214
228
  /**
215
229
  * Controls SDK defaults for ambient features.
@@ -1738,6 +1752,12 @@ export interface MemoryConfiguration {
1738
1752
  * Whether the memory feature is enabled for this session.
1739
1753
  */
1740
1754
  enabled: boolean;
1755
+ /**
1756
+ * "system-prompt" (default) places memories in the system prompt.
1757
+ * "user-prompt" places memories in generated user-role messages.
1758
+ * @experimental This option may change or be removed in a future release.
1759
+ */
1760
+ mode?: "system-prompt" | "user-prompt";
1741
1761
  }
1742
1762
  /**
1743
1763
  * Configuration for handling large tool outputs.
@@ -2307,6 +2327,14 @@ export interface SessionConfigBase {
2307
2327
  * @experimental
2308
2328
  */
2309
2329
  sessionLimits?: SessionLimitsConfig;
2330
+ /**
2331
+ * Autopilot policy. Omitted fields preserve resident values on warm resume;
2332
+ * new sessions default to continuation enabled and at most five continuations.
2333
+ * Does not change the session mode. Re-supply on cold resume.
2334
+ *
2335
+ * @experimental
2336
+ */
2337
+ autopilot?: AutopilotOptions;
2310
2338
  /**
2311
2339
  * When true, the runtime skips loading custom-instruction sources
2312
2340
  * (e.g. `.github/copilot-instructions.md`, `AGENTS.md`, `CLAUDE.md`).
package/dist/types.js CHANGED
@@ -44,8 +44,8 @@ const RuntimeConnection = {
44
44
  * corresponding environment variables on the host process instead. See
45
45
  * https://github.com/github/copilot-sdk/issues/1934.
46
46
  */
47
- forInProcess() {
48
- return { kind: "inprocess" };
47
+ forInProcess(options = {}) {
48
+ return { kind: "inprocess", ...options };
49
49
  }
50
50
  };
51
51
  function convertMcpCallToolResult(callResult) {
package/package.json CHANGED
@@ -5,8 +5,8 @@
5
5
  "url": "https://github.com/github/copilot-agent-runtime.git",
6
6
  "directory": "src/sdk/nodejs"
7
7
  },
8
- "version": "1.0.24",
9
- "copilotCliVersion": "1.0.101",
8
+ "version": "1.0.25-preview.1",
9
+ "copilotCliVersion": "1.0.102-1",
10
10
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
11
11
  "main": "./dist/cjs/index.js",
12
12
  "types": "./dist/index.d.ts",
@@ -114,18 +114,18 @@
114
114
  "README.md"
115
115
  ],
116
116
  "copilotRuntime": {
117
- "sourceSha": "01c5befcd0b26b1b4b0a7fce219cf441b8ae2ae1",
118
- "version": "1.0.101",
117
+ "sourceSha": "638eca2df1797ed37da09ddd23ba37d298f45ffd",
118
+ "version": "1.0.102-1",
119
119
  "visibility": "public"
120
120
  },
121
121
  "optionalDependencies": {
122
- "@github/copilot-sdk-darwin-arm64": "1.0.24",
123
- "@github/copilot-sdk-darwin-x64": "1.0.24",
124
- "@github/copilot-sdk-linux-arm64": "1.0.24",
125
- "@github/copilot-sdk-linux-x64": "1.0.24",
126
- "@github/copilot-sdk-linuxmusl-arm64": "1.0.24",
127
- "@github/copilot-sdk-linuxmusl-x64": "1.0.24",
128
- "@github/copilot-sdk-win32-arm64": "1.0.24",
129
- "@github/copilot-sdk-win32-x64": "1.0.24"
122
+ "@github/copilot-sdk-darwin-arm64": "1.0.25-preview.1",
123
+ "@github/copilot-sdk-darwin-x64": "1.0.25-preview.1",
124
+ "@github/copilot-sdk-linux-arm64": "1.0.25-preview.1",
125
+ "@github/copilot-sdk-linux-x64": "1.0.25-preview.1",
126
+ "@github/copilot-sdk-linuxmusl-arm64": "1.0.25-preview.1",
127
+ "@github/copilot-sdk-linuxmusl-x64": "1.0.25-preview.1",
128
+ "@github/copilot-sdk-win32-arm64": "1.0.25-preview.1",
129
+ "@github/copilot-sdk-win32-x64": "1.0.25-preview.1"
130
130
  }
131
131
  }