@github/copilot-sdk 1.0.29-preview.2 → 1.0.29-preview.3

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
@@ -813,6 +813,38 @@ See `SessionEvent` type in the source for full details.
813
813
 
814
814
  The SDK supports image attachments via the `attachments` parameter. You can attach images by providing their file path, or by passing base64-encoded data directly using a blob attachment:
815
815
 
816
+ <!-- docs-validate: strict -->
817
+ <!-- docs-validate: hidden -->
818
+ ```typescript
819
+ import type { CopilotSession } from "@github/copilot-sdk";
820
+
821
+ declare const session: CopilotSession;
822
+ declare const base64ImageData: string;
823
+
824
+ // File attachment — runtime reads from disk
825
+ await session.send({
826
+ prompt: "What's in this image?",
827
+ attachments: [
828
+ {
829
+ type: "file",
830
+ path: "/path/to/image.jpg",
831
+ },
832
+ ],
833
+ });
834
+
835
+ // Blob attachment — provide base64 data directly
836
+ await session.send({
837
+ prompt: "What's in this image?",
838
+ attachments: [
839
+ {
840
+ type: "blob",
841
+ data: base64ImageData,
842
+ mimeType: "image/png",
843
+ },
844
+ ],
845
+ });
846
+ ```
847
+ <!-- /docs-validate: hidden -->
816
848
  ```typescript
817
849
  // File attachment — runtime reads from disk
818
850
  await session.send({
@@ -840,6 +872,16 @@ await session.send({
840
872
 
841
873
  Supported image formats are PNG, JPEG, WebP, and GIF. Images in other formats, such as BMP or TIFF, are not sent to the model. The agent's `view` tool can also read images directly from the filesystem, so you can also ask questions like:
842
874
 
875
+ <!-- docs-validate: strict -->
876
+ <!-- docs-validate: hidden -->
877
+ ```typescript
878
+ import type { CopilotSession } from "@github/copilot-sdk";
879
+
880
+ declare const session: CopilotSession;
881
+
882
+ await session.send({ prompt: "What does the most recent jpg in this directory portray?" });
883
+ ```
884
+ <!-- /docs-validate: hidden -->
843
885
  ```typescript
844
886
  await session.send({ prompt: "What does the most recent jpg in this directory portray?" });
845
887
  ```
@@ -848,6 +890,51 @@ await session.send({ prompt: "What does the most recent jpg in this directory po
848
890
 
849
891
  Enable streaming to receive assistant response chunks as they're generated:
850
892
 
893
+ <!-- docs-validate: strict -->
894
+ <!-- docs-validate: hidden -->
895
+ ```typescript
896
+ import { approveAll } from "@github/copilot-sdk";
897
+
898
+ const session = await client.createSession({
899
+ model: "gpt-5",
900
+ streaming: true,
901
+ onPermissionRequest: approveAll,
902
+ });
903
+
904
+ // Wait for completion using typed event handlers
905
+ const done = new Promise<void>((resolve) => {
906
+ session.on("assistant.message_delta", (event) => {
907
+ // Streaming message chunk - print incrementally
908
+ process.stdout.write(event.data.deltaContent);
909
+ });
910
+
911
+ session.on("assistant.reasoning_delta", (event) => {
912
+ // Streaming reasoning chunk (if model supports reasoning)
913
+ process.stdout.write(event.data.deltaContent);
914
+ });
915
+
916
+ session.on("assistant.message", (event) => {
917
+ // Final message - complete content
918
+ console.log("\n--- Final message ---");
919
+ console.log(event.data.content);
920
+ });
921
+
922
+ session.on("assistant.reasoning", (event) => {
923
+ // Final reasoning content (if model supports reasoning)
924
+ console.log("--- Reasoning ---");
925
+ console.log(event.data.content);
926
+ });
927
+
928
+ session.on("session.idle", () => {
929
+ // Session finished processing
930
+ resolve();
931
+ });
932
+ });
933
+
934
+ await session.send({ prompt: "Tell me a short story" });
935
+ await done; // Wait for streaming to complete
936
+ ```
937
+ <!-- /docs-validate: hidden -->
851
938
  ```typescript
852
939
  const session = await client.createSession({
853
940
  model: "gpt-5",
@@ -1807,6 +1894,7 @@ const session = await client.createSession({
1807
1894
  // request.question - The question to ask
1808
1895
  // request.choices - Optional array of choices for multiple choice
1809
1896
  // request.allowFreeform - Whether freeform input is allowed (default: true)
1897
+ // request.requestId - Runtime ID of the pending request (absent on older runtimes)
1810
1898
 
1811
1899
  console.log(`Agent asks: ${request.question}`);
1812
1900
  if (request.choices) {
@@ -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-3";
25
+ const COPILOT_CLI_VERSION = "1.0.106-4";
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 = {
@@ -3033,7 +3033,8 @@ stderr: ${stderrOutput}` : ""}`
3033
3033
  const result = await session._handleUserInputRequest({
3034
3034
  question: params.question,
3035
3035
  choices: params.choices,
3036
- allowFreeform: params.allowFreeform
3036
+ allowFreeform: params.allowFreeform,
3037
+ requestId: params.requestId
3037
3038
  });
3038
3039
  return result;
3039
3040
  }
@@ -3049,7 +3050,8 @@ stderr: ${stderrOutput}` : ""}`
3049
3050
  summary: params.summary,
3050
3051
  planContent: params.planContent,
3051
3052
  actions: params.actions,
3052
- recommendedAction: params.recommendedAction
3053
+ recommendedAction: params.recommendedAction,
3054
+ requestId: params.requestId
3053
3055
  });
3054
3056
  }
3055
3057
  async handleAutoModeSwitchRequest(params) {
@@ -151,13 +151,16 @@ class CopilotWebSocketForwarder extends CopilotWebSocketHandler {
151
151
  });
152
152
  }
153
153
  async close(status = CopilotWebSocketCloseStatus.normalClosure) {
154
+ const upstream = this.#upstream;
155
+ this.#upstream = null;
156
+ const completion = super.close(status);
154
157
  try {
155
- if (this.#upstream?.readyState === WebSocket.OPEN || this.#upstream?.readyState === WebSocket.CONNECTING) {
156
- this.#upstream?.close();
158
+ if (upstream?.readyState === WebSocket.OPEN || upstream?.readyState === WebSocket.CONNECTING) {
159
+ upstream.close();
157
160
  }
158
161
  } catch {
159
162
  }
160
- await super.close(status);
163
+ await completion;
161
164
  }
162
165
  async [Symbol.asyncDispose]() {
163
166
  try {
@@ -841,9 +841,17 @@ function createServerRpc(connection) {
841
841
  *
842
842
  * @param params A bounded catalog search. Both the query length and the result count are capped by the schema so a caller cannot request an unbounded scan.
843
843
  *
844
- * @returns Outcome of a catalog.search call: either bounded inert candidates, or one typed refusal. Never a partial success.
844
+ * @returns Outcome of catalog.search or catalog.recommend: either bounded inert candidates, or one typed refusal. Never a partial success.
845
845
  */
846
846
  search: async (params) => connection.sendRequest("catalog.search", params),
847
+ /**
848
+ * Requests the initial page of at most ten official-product recommendations for a complete task and product, bound to an existing attached local session. Requires catalog-recommend, catalog-search-session-bound and catalog-search-credential-required. Uses the selected GitHub.com user credential on the fixed Agent Finder recommendations route; successful capability negotiation does not establish service acceptance. Returns the existing inert catalog candidates and retained install references with the typed catalog refusal union. No anonymous retry, unfiltered search fallback or continuation is performed. Server-owned product approvals establish provenance, not task suitability. Read-only: nothing is installed, configured or persisted.
849
+ *
850
+ * @param params Initial-page official-product recommendations for a complete task. The runtime fixes recommendationPolicy to official-product and pageSize to 10; callers cannot override the policy, request pagination or fall back to search.
851
+ *
852
+ * @returns Outcome of catalog.search or catalog.recommend: either bounded inert candidates, or one typed refusal. Never a partial success.
853
+ */
854
+ recommend: async (params) => connection.sendRequest("catalog.recommend", params),
847
855
  /**
848
856
  * Retrieves one saved feed by its opaque ID, optionally filtered by trust tier. Requires catalog-feeds and catalog-search-credential-required, and uses the same authority, credential policy, optional session binding and candidate projection as catalog.search, so available entries are the same inert candidates, with the same installability, handles and display metadata, and install through the same confirmed flows. Entries keep the feed's order; an entry the runtime cannot present is returned as unavailable with a reason rather than failing the feed. No anonymous retry. Read-only: nothing is installed, configured, or persisted.
849
857
  *
@@ -1587,6 +1587,7 @@ class CopilotSession {
1587
1587
  assertWorkflowResult(result);
1588
1588
  return { result };
1589
1589
  } finally {
1590
+ controller.abort(new DOMException("Workflow run has settled", "AbortError"));
1590
1591
  try {
1591
1592
  await progress.close();
1592
1593
  } finally {
@@ -1,2 +1,2 @@
1
- export declare const COPILOT_CLI_VERSION = "1.0.106-3";
1
+ export declare const COPILOT_CLI_VERSION = "1.0.106-4";
2
2
  export declare const COPILOT_CLI_USE_NPM_PACKAGE = false;
@@ -1,4 +1,4 @@
1
- const COPILOT_CLI_VERSION = "1.0.106-3";
1
+ const COPILOT_CLI_VERSION = "1.0.106-4";
2
2
  const COPILOT_CLI_USE_NPM_PACKAGE = false;
3
3
  export {
4
4
  COPILOT_CLI_USE_NPM_PACKAGE,
package/dist/client.js CHANGED
@@ -3015,7 +3015,8 @@ stderr: ${stderrOutput}` : ""}`
3015
3015
  const result = await session._handleUserInputRequest({
3016
3016
  question: params.question,
3017
3017
  choices: params.choices,
3018
- allowFreeform: params.allowFreeform
3018
+ allowFreeform: params.allowFreeform,
3019
+ requestId: params.requestId
3019
3020
  });
3020
3021
  return result;
3021
3022
  }
@@ -3031,7 +3032,8 @@ stderr: ${stderrOutput}` : ""}`
3031
3032
  summary: params.summary,
3032
3033
  planContent: params.planContent,
3033
3034
  actions: params.actions,
3034
- recommendedAction: params.recommendedAction
3035
+ recommendedAction: params.recommendedAction,
3036
+ requestId: params.requestId
3035
3037
  });
3036
3038
  }
3037
3039
  async handleAutoModeSwitchRequest(params) {
@@ -124,13 +124,16 @@ class CopilotWebSocketForwarder extends CopilotWebSocketHandler {
124
124
  });
125
125
  }
126
126
  async close(status = CopilotWebSocketCloseStatus.normalClosure) {
127
+ const upstream = this.#upstream;
128
+ this.#upstream = null;
129
+ const completion = super.close(status);
127
130
  try {
128
- if (this.#upstream?.readyState === WebSocket.OPEN || this.#upstream?.readyState === WebSocket.CONNECTING) {
129
- this.#upstream?.close();
131
+ if (upstream?.readyState === WebSocket.OPEN || upstream?.readyState === WebSocket.CONNECTING) {
132
+ upstream.close();
130
133
  }
131
134
  } catch {
132
135
  }
133
- await super.close(status);
136
+ await completion;
134
137
  }
135
138
  async [Symbol.asyncDispose]() {
136
139
  try {
@@ -1081,6 +1081,8 @@ export type CatalogCapability =
1081
1081
  | "catalog-search-credential-required"
1082
1082
  /** Captures the exact existing native session, account, host and connection for authenticated catalogue search, selection and planning. Requires catalog-search-credential-required; does not grant installation or create a session. */
1083
1083
  | "catalog-search-session-bound"
1084
+ /** Understands initial-page official-product recommendations for a full task and product with fixed pageSize 10. Requires session-bound, credential-required catalogue support. No anonymous retry, broad-search fallback or continuation. Authentication uses the selected GitHub.com user credential; successful capability negotiation does not establish service acceptance. */
1085
+ | "catalog-recommend"
1084
1086
  /** Understands effect-free preparation, exact human-confirmed apply and owned removal for fully resolved personal remote MCP choices without supplied inputs or configured secrets. Advertised only when the real producer and lower owned admission are linked; requires original connection and bound session authority for new work. */
1085
1087
  | "mcp-confirmed-remote-installation"
1086
1088
  /** Extends mcp-confirmed-remote-installation to declared non-secret header and URL values and receipt-owned header secrets for personal remote MCP choices. Requires mcp-confirmed-remote-installation and bound session authority. Secret values are written only to the reviewed backend after confirmation and are never returned; package and stdio choices remain unsupported. Advertised only when owned secret effects and owned secret activation are linked. */
@@ -1211,6 +1213,8 @@ export type CatalogInvalidRequestField =
1211
1213
  "policySessionId"
1212
1214
  /** The search query was empty or longer than permitted. */
1213
1215
  | "query"
1216
+ /** The requested recommendation product was missing, blank or longer than permitted. */
1217
+ | "product"
1214
1218
  /** The requested result count fell outside its permitted range. */
1215
1219
  | "limit"
1216
1220
  /** The requested candidate kinds were empty or contained a duplicate. */
@@ -1714,7 +1718,7 @@ export type CatalogSearchTotalCountRelation =
1714
1718
  /** No exact/full-query or lower-bound guarantee is available. */
1715
1719
  "unknown";
1716
1720
  /**
1717
- * Outcome of a catalog.search call: either bounded inert candidates, or one typed refusal. Never a partial success.
1721
+ * Outcome of catalog.search or catalog.recommend: either bounded inert candidates, or one typed refusal. Never a partial success.
1718
1722
  *
1719
1723
  * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
1720
1724
  * via the `definition` "CatalogSearchResult".
@@ -11509,6 +11513,31 @@ export interface CatalogPolicyRejectedError {
11509
11513
  */
11510
11514
  message: string;
11511
11515
  }
11516
+ /**
11517
+ * Initial-page official-product recommendations for a complete task. The runtime fixes recommendationPolicy to official-product and pageSize to 10; callers cannot override the policy, request pagination or fall back to search.
11518
+ *
11519
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
11520
+ * via the `definition` "CatalogRecommendRequest".
11521
+ */
11522
+ /** @experimental */
11523
+ export interface CatalogRecommendRequest {
11524
+ /**
11525
+ * Required contract, including catalog-recommend, catalog-search-session-bound and catalog-search-credential-required.
11526
+ */
11527
+ contract: CatalogClientContract;
11528
+ /**
11529
+ * Existing attached local session whose account, host and connection own the candidate references. Never creates or resumes a session.
11530
+ */
11531
+ policySessionId: string;
11532
+ /**
11533
+ * Full original task, including action, account, output and host requirements. Forwarded without trimming or rewriting and excluded from telemetry.
11534
+ */
11535
+ query: string;
11536
+ /**
11537
+ * Requested product. Agent Finder resolves aliases and applies its versioned official-product approvals before limiting results.
11538
+ */
11539
+ product: string;
11540
+ }
11512
11541
  /**
11513
11542
  * A computed Skill install plan. Nothing has been applied.
11514
11543
  *
@@ -38814,9 +38843,17 @@ export declare function createServerRpc(connection: MessageConnection): {
38814
38843
  *
38815
38844
  * @param params A bounded catalog search. Both the query length and the result count are capped by the schema so a caller cannot request an unbounded scan.
38816
38845
  *
38817
- * @returns Outcome of a catalog.search call: either bounded inert candidates, or one typed refusal. Never a partial success.
38846
+ * @returns Outcome of catalog.search or catalog.recommend: either bounded inert candidates, or one typed refusal. Never a partial success.
38818
38847
  */
38819
38848
  search: (params: CatalogSearchRequest) => Promise<CatalogSearchResult>;
38849
+ /**
38850
+ * Requests the initial page of at most ten official-product recommendations for a complete task and product, bound to an existing attached local session. Requires catalog-recommend, catalog-search-session-bound and catalog-search-credential-required. Uses the selected GitHub.com user credential on the fixed Agent Finder recommendations route; successful capability negotiation does not establish service acceptance. Returns the existing inert catalog candidates and retained install references with the typed catalog refusal union. No anonymous retry, unfiltered search fallback or continuation is performed. Server-owned product approvals establish provenance, not task suitability. Read-only: nothing is installed, configured or persisted.
38851
+ *
38852
+ * @param params Initial-page official-product recommendations for a complete task. The runtime fixes recommendationPolicy to official-product and pageSize to 10; callers cannot override the policy, request pagination or fall back to search.
38853
+ *
38854
+ * @returns Outcome of catalog.search or catalog.recommend: either bounded inert candidates, or one typed refusal. Never a partial success.
38855
+ */
38856
+ recommend: (params: CatalogRecommendRequest) => Promise<CatalogSearchResult>;
38820
38857
  /**
38821
38858
  * Retrieves one saved feed by its opaque ID, optionally filtered by trust tier. Requires catalog-feeds and catalog-search-credential-required, and uses the same authority, credential policy, optional session binding and candidate projection as catalog.search, so available entries are the same inert candidates, with the same installability, handles and display metadata, and install through the same confirmed flows. Entries keep the feed's order; an entry the runtime cannot present is returned as unavailable with a reason rather than failing the feed. No anonymous retry. Read-only: nothing is installed, configured, or persisted.
38822
38859
  *
@@ -813,9 +813,17 @@ function createServerRpc(connection) {
813
813
  *
814
814
  * @param params A bounded catalog search. Both the query length and the result count are capped by the schema so a caller cannot request an unbounded scan.
815
815
  *
816
- * @returns Outcome of a catalog.search call: either bounded inert candidates, or one typed refusal. Never a partial success.
816
+ * @returns Outcome of catalog.search or catalog.recommend: either bounded inert candidates, or one typed refusal. Never a partial success.
817
817
  */
818
818
  search: async (params) => connection.sendRequest("catalog.search", params),
819
+ /**
820
+ * Requests the initial page of at most ten official-product recommendations for a complete task and product, bound to an existing attached local session. Requires catalog-recommend, catalog-search-session-bound and catalog-search-credential-required. Uses the selected GitHub.com user credential on the fixed Agent Finder recommendations route; successful capability negotiation does not establish service acceptance. Returns the existing inert catalog candidates and retained install references with the typed catalog refusal union. No anonymous retry, unfiltered search fallback or continuation is performed. Server-owned product approvals establish provenance, not task suitability. Read-only: nothing is installed, configured or persisted.
821
+ *
822
+ * @param params Initial-page official-product recommendations for a complete task. The runtime fixes recommendationPolicy to official-product and pageSize to 10; callers cannot override the policy, request pagination or fall back to search.
823
+ *
824
+ * @returns Outcome of catalog.search or catalog.recommend: either bounded inert candidates, or one typed refusal. Never a partial success.
825
+ */
826
+ recommend: async (params) => connection.sendRequest("catalog.recommend", params),
819
827
  /**
820
828
  * Retrieves one saved feed by its opaque ID, optionally filtered by trust tier. Requires catalog-feeds and catalog-search-credential-required, and uses the same authority, credential policy, optional session binding and candidate projection as catalog.search, so available entries are the same inert candidates, with the same installability, handles and display metadata, and install through the same confirmed flows. Entries keep the feed's order; an entry the runtime cannot present is returned as unavailable with a reason rather than failing the feed. No anonymous retry. Read-only: nothing is installed, configured, or persisted.
821
829
  *
package/dist/session.js CHANGED
@@ -1574,6 +1574,7 @@ class CopilotSession {
1574
1574
  assertWorkflowResult(result);
1575
1575
  return { result };
1576
1576
  } finally {
1577
+ controller.abort(new DOMException("Workflow run has settled", "AbortError"));
1577
1578
  try {
1578
1579
  await progress.close();
1579
1580
  } finally {
package/dist/types.d.ts CHANGED
@@ -1192,6 +1192,12 @@ export interface UserInputRequest {
1192
1192
  * @default true
1193
1193
  */
1194
1194
  allowFreeform?: boolean;
1195
+ /**
1196
+ * Runtime ID of the pending `user_input.requested` request. Pass it as `requestId`
1197
+ * to answer this exact request through the session's UI RPCs. Absent when the
1198
+ * runtime predates this field.
1199
+ */
1200
+ requestId?: string;
1195
1201
  }
1196
1202
  /**
1197
1203
  * Response to a user input request
@@ -1224,6 +1230,12 @@ export interface ExitPlanModeRequest {
1224
1230
  actions: string[];
1225
1231
  /** The action recommended by the runtime. */
1226
1232
  recommendedAction: string;
1233
+ /**
1234
+ * Runtime ID of the pending `exit_plan_mode.requested` request. Pass it as
1235
+ * `requestId` to answer this exact request through the session's UI RPCs. Absent
1236
+ * when the runtime predates this field.
1237
+ */
1238
+ requestId?: string;
1227
1239
  }
1228
1240
  /**
1229
1241
  * Response to an exit-plan-mode request.
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.29-preview.2",
9
- "copilotCliVersion": "1.0.106-3",
8
+ "version": "1.0.29-preview.3",
9
+ "copilotCliVersion": "1.0.106-4",
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",
@@ -115,18 +115,18 @@
115
115
  "README.md"
116
116
  ],
117
117
  "copilotRuntime": {
118
- "sourceSha": "70ffdab66d4c7eb84302789a8536c02d955da3ed",
119
- "version": "1.0.106-3",
118
+ "sourceSha": "54bae76dc3ced5344dc60a365e81a06c787fda53",
119
+ "version": "1.0.106-4",
120
120
  "visibility": "public"
121
121
  },
122
122
  "optionalDependencies": {
123
- "@github/copilot-sdk-darwin-arm64": "1.0.29-preview.2",
124
- "@github/copilot-sdk-darwin-x64": "1.0.29-preview.2",
125
- "@github/copilot-sdk-linux-arm64": "1.0.29-preview.2",
126
- "@github/copilot-sdk-linux-x64": "1.0.29-preview.2",
127
- "@github/copilot-sdk-linuxmusl-arm64": "1.0.29-preview.2",
128
- "@github/copilot-sdk-linuxmusl-x64": "1.0.29-preview.2",
129
- "@github/copilot-sdk-win32-arm64": "1.0.29-preview.2",
130
- "@github/copilot-sdk-win32-x64": "1.0.29-preview.2"
123
+ "@github/copilot-sdk-darwin-arm64": "1.0.29-preview.3",
124
+ "@github/copilot-sdk-darwin-x64": "1.0.29-preview.3",
125
+ "@github/copilot-sdk-linux-arm64": "1.0.29-preview.3",
126
+ "@github/copilot-sdk-linux-x64": "1.0.29-preview.3",
127
+ "@github/copilot-sdk-linuxmusl-arm64": "1.0.29-preview.3",
128
+ "@github/copilot-sdk-linuxmusl-x64": "1.0.29-preview.3",
129
+ "@github/copilot-sdk-win32-arm64": "1.0.29-preview.3",
130
+ "@github/copilot-sdk-win32-x64": "1.0.29-preview.3"
131
131
  }
132
132
  }