@github/copilot-sdk 1.0.29-preview.1 → 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
@@ -218,6 +218,7 @@ npm start
218
218
 
219
219
  ## Quick Start
220
220
 
221
+ <!-- docs-validate: strict -->
221
222
  ```typescript
222
223
  import { CopilotClient, approveAll } from "@github/copilot-sdk";
223
224
 
@@ -252,7 +253,10 @@ await client.stop();
252
253
 
253
254
  Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2+ / Node.js 20+):
254
255
 
256
+ <!-- docs-validate: strict -->
255
257
  ```typescript
258
+ import { approveAll } from "@github/copilot-sdk";
259
+
256
260
  await using session = await client.createSession({
257
261
  model: "gpt-5",
258
262
  onPermissionRequest: approveAll,
@@ -809,6 +813,38 @@ See `SessionEvent` type in the source for full details.
809
813
 
810
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:
811
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 -->
812
848
  ```typescript
813
849
  // File attachment — runtime reads from disk
814
850
  await session.send({
@@ -836,6 +872,16 @@ await session.send({
836
872
 
837
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:
838
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 -->
839
885
  ```typescript
840
886
  await session.send({ prompt: "What does the most recent jpg in this directory portray?" });
841
887
  ```
@@ -844,6 +890,51 @@ await session.send({ prompt: "What does the most recent jpg in this directory po
844
890
 
845
891
  Enable streaming to receive assistant response chunks as they're generated:
846
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 -->
847
938
  ```typescript
848
939
  const session = await client.createSession({
849
940
  model: "gpt-5",
@@ -897,7 +988,10 @@ Note: `assistant.message` and `assistant.reasoning` (final events) are always se
897
988
 
898
989
  ### Manual Server Control
899
990
 
991
+ <!-- docs-validate: strict -->
900
992
  ```typescript
993
+ import { CopilotClient } from "@github/copilot-sdk";
994
+
901
995
  const client = new CopilotClient({});
902
996
 
903
997
  // Start manually
@@ -913,6 +1007,31 @@ await client.stop();
913
1007
 
914
1008
  You can let the CLI call back into your process when the model needs capabilities you own. Use `defineTool` with Zod schemas for type-safe tool definitions:
915
1009
 
1010
+ <!-- docs-validate: strict -->
1011
+ <!-- docs-validate: hidden -->
1012
+ ```ts
1013
+ import { z } from "zod";
1014
+ import { defineTool } from "@github/copilot-sdk";
1015
+
1016
+ declare function fetchIssue(id: string): Promise<string>;
1017
+
1018
+ const session = await client.createSession({
1019
+ model: "gpt-5",
1020
+ tools: [
1021
+ defineTool("lookup_issue", {
1022
+ description: "Fetch issue details from our tracker",
1023
+ parameters: z.object({
1024
+ id: z.string().describe("Issue identifier"),
1025
+ }),
1026
+ handler: async ({ id }) => {
1027
+ const issue = await fetchIssue(id);
1028
+ return issue;
1029
+ },
1030
+ }),
1031
+ ],
1032
+ });
1033
+ ```
1034
+ <!-- /docs-validate: hidden -->
916
1035
  ```ts
917
1036
  import { z } from "zod";
918
1037
  import { CopilotClient, defineTool } from "@github/copilot-sdk";
@@ -940,6 +1059,22 @@ When Copilot invokes `lookup_issue`, the client automatically runs your handler
940
1059
 
941
1060
  If you register a tool with the same name as a built-in CLI tool (e.g. `edit_file`, `read_file`), the SDK will throw an error unless you explicitly opt in by setting `overridesBuiltInTool: true`. This flag signals that you intend to replace the built-in tool with your custom implementation.
942
1061
 
1062
+ <!-- docs-validate: strict -->
1063
+ <!-- docs-validate: hidden -->
1064
+ ```ts
1065
+ import { z } from "zod";
1066
+ import { defineTool } from "@github/copilot-sdk";
1067
+
1068
+ defineTool("edit_file", {
1069
+ description: "Custom file editor with project-specific validation",
1070
+ parameters: z.object({ path: z.string(), content: z.string() }),
1071
+ overridesBuiltInTool: true,
1072
+ handler: async ({ path, content }) => {
1073
+ /* your logic */
1074
+ },
1075
+ });
1076
+ ```
1077
+ <!-- /docs-validate: hidden -->
943
1078
  ```ts
944
1079
  defineTool("edit_file", {
945
1080
  description: "Custom file editor with project-specific validation",
@@ -956,6 +1091,19 @@ An `apply_patch` override can declare a string schema. The model sees a required
956
1091
  dispatching to any SDK. Both a Zod-inferred Node handler and
957
1092
  `invocation.arguments` receive the patch text as a string:
958
1093
 
1094
+ <!-- docs-validate: strict -->
1095
+ <!-- docs-validate: hidden -->
1096
+ ```ts
1097
+ import { z } from "zod";
1098
+ import { defineTool } from "@github/copilot-sdk";
1099
+
1100
+ defineTool("apply_patch", {
1101
+ parameters: z.string(),
1102
+ overridesBuiltInTool: true,
1103
+ handler: (patch) => patch.trim(),
1104
+ });
1105
+ ```
1106
+ <!-- /docs-validate: hidden -->
959
1107
  ```ts
960
1108
  defineTool("apply_patch", {
961
1109
  parameters: z.string(),
@@ -971,6 +1119,22 @@ use an object schema if references are needed.
971
1119
 
972
1120
  Set `skipPermission: true` on a tool definition to allow it to execute without triggering a permission prompt:
973
1121
 
1122
+ <!-- docs-validate: strict -->
1123
+ <!-- docs-validate: hidden -->
1124
+ ```ts
1125
+ import { z } from "zod";
1126
+ import { defineTool } from "@github/copilot-sdk";
1127
+
1128
+ defineTool("safe_lookup", {
1129
+ description: "A read-only lookup that needs no confirmation",
1130
+ parameters: z.object({ id: z.string() }),
1131
+ skipPermission: true,
1132
+ handler: async ({ id }) => {
1133
+ /* your logic */
1134
+ },
1135
+ });
1136
+ ```
1137
+ <!-- /docs-validate: hidden -->
974
1138
  ```ts
975
1139
  defineTool("safe_lookup", {
976
1140
  description: "A read-only lookup that needs no confirmation",
@@ -986,6 +1150,22 @@ defineTool("safe_lookup", {
986
1150
 
987
1151
  Set `defer` to control whether a tool may be loaded lazily via tool search rather than always pre-loaded. Use `"auto"` to allow the tool to be deferred and surfaced through tool search, or `"never"` to force it to always be pre-loaded. Defaults to `"auto"`.
988
1152
 
1153
+ <!-- docs-validate: strict -->
1154
+ <!-- docs-validate: hidden -->
1155
+ ```ts
1156
+ import { z } from "zod";
1157
+ import { defineTool } from "@github/copilot-sdk";
1158
+
1159
+ defineTool("lookup_issue", {
1160
+ description: "Fetch issue details",
1161
+ parameters: z.object({ id: z.string() }),
1162
+ defer: "auto",
1163
+ handler: async ({ id }) => {
1164
+ /* your logic */
1165
+ },
1166
+ });
1167
+ ```
1168
+ <!-- /docs-validate: hidden -->
989
1169
  ```ts
990
1170
  defineTool("lookup_issue", {
991
1171
  description: "Fetch issue details",
@@ -1001,6 +1181,26 @@ defineTool("lookup_issue", {
1001
1181
 
1002
1182
  Register slash commands so that users of the CLI's TUI can invoke custom actions via `/commandName`. Each command has a `name`, optional `description`, and a `handler` called when the user executes it.
1003
1183
 
1184
+ <!-- docs-validate: strict -->
1185
+ <!-- docs-validate: hidden -->
1186
+ ```ts
1187
+ import { approveAll } from "@github/copilot-sdk";
1188
+
1189
+ const session = await client.createSession({
1190
+ onPermissionRequest: approveAll,
1191
+ commands: [
1192
+ {
1193
+ name: "deploy",
1194
+ description: "Deploy the app to production",
1195
+ handler: async ({ commandName, args }) => {
1196
+ console.log(`Deploying with args: ${args}`);
1197
+ // Do work here — any thrown error is reported back to the CLI
1198
+ },
1199
+ },
1200
+ ],
1201
+ });
1202
+ ```
1203
+ <!-- /docs-validate: hidden -->
1004
1204
  ```ts
1005
1205
  const session = await client.createSession({
1006
1206
  onPermissionRequest: approveAll,
@@ -1027,6 +1227,44 @@ When the session has elicitation support — either from the CLI's TUI or from a
1027
1227
 
1028
1228
  > **Capability check:** Elicitation is only available when at least one connected participant advertises support. Always check `session.capabilities.ui?.elicitation` before calling UI methods — this property updates automatically as participants join and leave.
1029
1229
 
1230
+ <!-- docs-validate: strict -->
1231
+ <!-- docs-validate: hidden -->
1232
+ ```ts
1233
+ import { approveAll } from "@github/copilot-sdk";
1234
+
1235
+ const session = await client.createSession({ onPermissionRequest: approveAll });
1236
+
1237
+ if (session.capabilities.ui?.elicitation) {
1238
+ // Confirm dialog — returns boolean
1239
+ const ok = await session.ui.confirm("Deploy to production?");
1240
+
1241
+ // Selection dialog — returns selected value or null
1242
+ const env = await session.ui.select("Pick environment", ["production", "staging", "dev"]);
1243
+
1244
+ // Text input — returns string or null
1245
+ const name = await session.ui.input("Project name:", {
1246
+ title: "Name",
1247
+ minLength: 1,
1248
+ maxLength: 50,
1249
+ });
1250
+
1251
+ // Generic elicitation with full schema control
1252
+ const result = await session.ui.elicitation({
1253
+ message: "Configure deployment",
1254
+ requestedSchema: {
1255
+ type: "object",
1256
+ properties: {
1257
+ region: { type: "string", enum: ["us-east", "eu-west"] },
1258
+ dryRun: { type: "boolean", default: true },
1259
+ },
1260
+ required: ["region"],
1261
+ },
1262
+ });
1263
+ // result.action: "accept" | "decline" | "cancel"
1264
+ // result.content: { region: "us-east", dryRun: true } (when accepted)
1265
+ }
1266
+ ```
1267
+ <!-- /docs-validate: hidden -->
1030
1268
  ```ts
1031
1269
  const session = await client.createSession({ onPermissionRequest: approveAll });
1032
1270
 
@@ -1067,6 +1305,7 @@ All UI methods throw if elicitation is not supported by the host.
1067
1305
 
1068
1306
  Control the system prompt using `systemMessage` in session config:
1069
1307
 
1308
+ <!-- docs-validate: strict -->
1070
1309
  ```typescript
1071
1310
  const session = await client.createSession({
1072
1311
  model: "gpt-5",
@@ -1087,6 +1326,7 @@ The SDK auto-injects environment context, tool instructions, and security guardr
1087
1326
 
1088
1327
  Use `mode: "customize"` to selectively override individual sections of the prompt while preserving the rest:
1089
1328
 
1329
+ <!-- docs-validate: strict -->
1090
1330
  ```typescript
1091
1331
  import { SYSTEM_MESSAGE_SECTIONS } from "@github/copilot-sdk";
1092
1332
  import type { SectionOverride, SystemMessageSection } from "@github/copilot-sdk";
@@ -1134,6 +1374,7 @@ Unknown section IDs are handled gracefully: content from `replace`/`append`/`pre
1134
1374
 
1135
1375
  For full control (removes all guardrails), use `mode: "replace"`:
1136
1376
 
1377
+ <!-- docs-validate: strict -->
1137
1378
  ```typescript
1138
1379
  const session = await client.createSession({
1139
1380
  model: "gpt-5",
@@ -1148,6 +1389,33 @@ const session = await client.createSession({
1148
1389
 
1149
1390
  By default, sessions use **infinite sessions** which automatically manage context window limits through background compaction and persist state to a workspace directory.
1150
1391
 
1392
+ <!-- docs-validate: strict -->
1393
+ <!-- docs-validate: hidden -->
1394
+ ```typescript
1395
+ // Default: infinite sessions enabled with default thresholds
1396
+ const session = await client.createSession({ model: "gpt-5" });
1397
+
1398
+ // Access the workspace path for checkpoints and files
1399
+ console.log(session.workspacePath);
1400
+ // => ~/.copilot/session-state/{sessionId}/
1401
+
1402
+ // Custom thresholds
1403
+ const tuned = await client.createSession({
1404
+ model: "gpt-5",
1405
+ infiniteSessions: {
1406
+ enabled: true,
1407
+ backgroundCompactionThreshold: 0.8, // Start compacting at 80% context usage
1408
+ bufferExhaustionThreshold: 0.95, // Block at 95% until compaction completes
1409
+ },
1410
+ });
1411
+
1412
+ // Disable infinite sessions
1413
+ const disabled = await client.createSession({
1414
+ model: "gpt-5",
1415
+ infiniteSessions: { enabled: false },
1416
+ });
1417
+ ```
1418
+ <!-- /docs-validate: hidden -->
1151
1419
  ```typescript
1152
1420
  // Default: infinite sessions enabled with default thresholds
1153
1421
  const session = await client.createSession({ model: "gpt-5" });
@@ -1187,6 +1455,22 @@ SDK leaves `memory` unset so the runtime applies its own default, while `"empty"
1187
1455
  defaults `memory` to disabled unless you set it explicitly.
1188
1456
  For more background, see [About GitHub Copilot Memory](https://docs.github.com/en/copilot/concepts/agents/copilot-memory).
1189
1457
 
1458
+ <!-- docs-validate: strict -->
1459
+ <!-- docs-validate: hidden -->
1460
+ ```typescript
1461
+ // Enable memory for a session
1462
+ const enabled = await client.createSession({
1463
+ model: "gpt-5",
1464
+ memory: { enabled: true },
1465
+ });
1466
+
1467
+ // Disable memory for a session
1468
+ const disabled = await client.createSession({
1469
+ model: "gpt-5",
1470
+ memory: { enabled: false },
1471
+ });
1472
+ ```
1473
+ <!-- /docs-validate: hidden -->
1190
1474
  ```typescript
1191
1475
  // Enable memory for a session
1192
1476
  const session = await client.createSession({
@@ -1207,6 +1491,29 @@ A skill provider serves skills from your own storage, such as a database, instea
1207
1491
  files on disk. Provider skills join the session's skill catalog and load on demand through the
1208
1492
  `skill` tool, just like file-based skills.
1209
1493
 
1494
+ <!-- docs-validate: strict -->
1495
+ <!-- docs-validate: hidden -->
1496
+ ```typescript
1497
+ import { approveAll } from "@github/copilot-sdk";
1498
+ import type { SkillProvider } from "@github/copilot-sdk";
1499
+
1500
+ declare const db: {
1501
+ findSkill(name: string, options: { signal: AbortSignal }): Promise<{ markdown: string } | undefined>;
1502
+ };
1503
+
1504
+ const skillProvider: SkillProvider = {
1505
+ listSkills: async () => [
1506
+ { name: "release-notes", description: "Writes release notes in the team's format." },
1507
+ ],
1508
+ readSkill: async (name, { signal }) => (await db.findSkill(name, { signal }))?.markdown ?? null,
1509
+ };
1510
+
1511
+ const session = await client.createSession({
1512
+ onPermissionRequest: approveAll,
1513
+ skillProvider,
1514
+ });
1515
+ ```
1516
+ <!-- /docs-validate: hidden -->
1210
1517
  ```typescript
1211
1518
  import type { SkillProvider } from "@github/copilot-sdk";
1212
1519
 
@@ -1260,6 +1567,7 @@ See [Supporting files](../docs/features/skills.md#supporting-files-experimental)
1260
1567
 
1261
1568
  ### Multiple Sessions
1262
1569
 
1570
+ <!-- docs-validate: strict -->
1263
1571
  ```typescript
1264
1572
  const session1 = await client.createSession({ model: "gpt-5" });
1265
1573
  const session2 = await client.createSession({ model: "claude-sonnet-4.5" });
@@ -1271,6 +1579,7 @@ await session2.sendAndWait({ prompt: "Hello from session 2" });
1271
1579
 
1272
1580
  ### Custom Session IDs
1273
1581
 
1582
+ <!-- docs-validate: strict -->
1274
1583
  ```typescript
1275
1584
  const session = await client.createSession({
1276
1585
  sessionId: "my-custom-session-id",
@@ -1280,6 +1589,25 @@ const session = await client.createSession({
1280
1589
 
1281
1590
  ### File Attachments
1282
1591
 
1592
+ <!-- docs-validate: strict -->
1593
+ <!-- docs-validate: hidden -->
1594
+ ```typescript
1595
+ import { approveAll } from "@github/copilot-sdk";
1596
+
1597
+ const session = await client.createSession({ onPermissionRequest: approveAll });
1598
+
1599
+ await session.send({
1600
+ prompt: "Analyze this file",
1601
+ attachments: [
1602
+ {
1603
+ type: "file",
1604
+ path: "/path/to/file.js",
1605
+ displayName: "My File",
1606
+ },
1607
+ ],
1608
+ });
1609
+ ```
1610
+ <!-- /docs-validate: hidden -->
1283
1611
  ```typescript
1284
1612
  await session.send({
1285
1613
  prompt: "Analyze this file",
@@ -1308,6 +1636,7 @@ The SDK supports custom OpenAI-compatible API providers (BYOK - Bring Your Own K
1308
1636
 
1309
1637
  **Example with Ollama:**
1310
1638
 
1639
+ <!-- docs-validate: strict -->
1311
1640
  ```typescript
1312
1641
  const session = await client.createSession({
1313
1642
  model: "deepseek-coder-v2:16b", // Required when using custom provider
@@ -1323,6 +1652,7 @@ await session.sendAndWait({ prompt: "Hello!" });
1323
1652
 
1324
1653
  **Example with custom OpenAI-compatible API:**
1325
1654
 
1655
+ <!-- docs-validate: strict -->
1326
1656
  ```typescript
1327
1657
  const session = await client.createSession({
1328
1658
  model: "gpt-4",
@@ -1336,6 +1666,7 @@ const session = await client.createSession({
1336
1666
 
1337
1667
  **Example with Azure OpenAI:**
1338
1668
 
1669
+ <!-- docs-validate: strict -->
1339
1670
  ```typescript
1340
1671
  const session = await client.createSession({
1341
1672
  model: "gpt-4",
@@ -1360,7 +1691,10 @@ const session = await client.createSession({
1360
1691
 
1361
1692
  The SDK supports OpenTelemetry for distributed tracing. Provide a `telemetry` config to enable trace export from the CLI process — this is all most users need:
1362
1693
 
1694
+ <!-- docs-validate: strict -->
1363
1695
  ```typescript
1696
+ import { CopilotClient } from "@github/copilot-sdk";
1697
+
1364
1698
  const client = new CopilotClient({
1365
1699
  telemetry: {
1366
1700
  otlpEndpoint: "http://localhost:4318",
@@ -1552,6 +1886,7 @@ To let a specific custom tool bypass the permission prompt entirely, set `skipPe
1552
1886
 
1553
1887
  Enable the legacy question-and-answer `ask_user` tool by providing an `onUserInputRequest` handler:
1554
1888
 
1889
+ <!-- docs-validate: strict -->
1555
1890
  ```typescript
1556
1891
  const session = await client.createSession({
1557
1892
  model: "gpt-5",
@@ -1559,6 +1894,7 @@ const session = await client.createSession({
1559
1894
  // request.question - The question to ask
1560
1895
  // request.choices - Optional array of choices for multiple choice
1561
1896
  // request.allowFreeform - Whether freeform input is allowed (default: true)
1897
+ // request.requestId - Runtime ID of the pending request (absent on older runtimes)
1562
1898
 
1563
1899
  console.log(`Agent asks: ${request.question}`);
1564
1900
  if (request.choices) {
@@ -1578,7 +1914,10 @@ const session = await client.createSession({
1578
1914
 
1579
1915
  Register an `onElicitationRequest` handler to let your client act as an elicitation provider — presenting form-based UI dialogs on behalf of the agent. When provided, the server notifies your client whenever a tool or MCP server needs structured user input.
1580
1916
 
1917
+ <!-- docs-validate: strict -->
1581
1918
  ```typescript
1919
+ import { approveAll } from "@github/copilot-sdk";
1920
+
1582
1921
  const session = await client.createSession({
1583
1922
  model: "gpt-5",
1584
1923
  onPermissionRequest: approveAll,
@@ -1619,6 +1958,100 @@ In multi-client scenarios:
1619
1958
 
1620
1959
  Hook into session lifecycle events by providing handlers in the `hooks` configuration:
1621
1960
 
1961
+ <!-- docs-validate: strict -->
1962
+ <!-- docs-validate: hidden -->
1963
+ ```typescript
1964
+ declare function needsMoreWork(): boolean;
1965
+
1966
+ const session = await client.createSession({
1967
+ model: "gpt-5",
1968
+ hooks: {
1969
+ // Called before each tool execution
1970
+ onPreToolUse: async (input, invocation) => {
1971
+ console.log(`About to run tool: ${input.toolName}`);
1972
+ // Return permission decision and optionally modify args
1973
+ return {
1974
+ permissionDecision: "allow", // "allow", "deny", or "ask"
1975
+ modifiedArgs: input.toolArgs, // Optionally modify tool arguments
1976
+ additionalContext: "Extra context for the model",
1977
+ };
1978
+ },
1979
+
1980
+ // Called after each successful tool execution
1981
+ onPostToolUse: async (input, invocation) => {
1982
+ console.log(`Tool ${input.toolName} completed`);
1983
+ // Optionally modify the result or add context
1984
+ return {
1985
+ additionalContext: "Post-execution notes",
1986
+ };
1987
+ },
1988
+
1989
+ // Called after a tool execution whose result was "failure".
1990
+ // onPostToolUse does NOT fire for failed tool calls — register this
1991
+ // hook to observe them. Input includes `error` (the failure message
1992
+ // extracted from the tool's result), not the full result object.
1993
+ onPostToolUseFailure: async (input, invocation) => {
1994
+ console.log(`Tool ${input.toolName} failed: ${input.error}`);
1995
+ // Optionally append hidden guidance to the model.
1996
+ return { additionalContext: "Suggest checking inputs and retrying." };
1997
+ },
1998
+
1999
+ // Called when user submits a prompt
2000
+ onUserPromptSubmitted: async (input, invocation) => {
2001
+ console.log(`User prompt: ${input.prompt}`);
2002
+ return {
2003
+ modifiedPrompt: input.prompt, // Optionally modify the prompt
2004
+ };
2005
+ },
2006
+
2007
+ // Called when session starts
2008
+ onSessionStart: async (input, invocation) => {
2009
+ console.log(`Session started from: ${input.source}`); // "startup", "resume", "new"
2010
+ return {
2011
+ additionalContext: "Session initialization context",
2012
+ };
2013
+ },
2014
+
2015
+ // Called when session ends
2016
+ onSessionEnd: async (input, invocation) => {
2017
+ console.log(`Session ended: ${input.reason}`);
2018
+ },
2019
+
2020
+ // Called when an error occurs
2021
+ onErrorOccurred: async (input, invocation) => {
2022
+ console.error(`Error in ${input.errorContext}: ${input.error}`);
2023
+ return {
2024
+ errorHandling: "retry", // "retry", "skip", or "abort"
2025
+ };
2026
+ },
2027
+
2028
+ // Called when the top-level agent naturally stops
2029
+ onAgentStop: async (input, invocation) => {
2030
+ if (!input.stopHookActive && needsMoreWork()) {
2031
+ return {
2032
+ decision: "block",
2033
+ reason: "Run the final validation and fix any failures.",
2034
+ };
2035
+ }
2036
+ },
2037
+
2038
+ // Called before a sub-agent's first turn (the input identifies the parent session)
2039
+ onSubagentStart: (input, invocation) => {
2040
+ console.log(`Starting ${input.agentDisplayName ?? input.agentName}`);
2041
+ return { additionalContext: "Check the requested file before reporting back." };
2042
+ },
2043
+
2044
+ // Called when a sub-agent completes a turn
2045
+ onSubagentStop: (input, invocation) => {
2046
+ console.log(`${input.agentName} replied: ${input.response}`);
2047
+ // Return { decision: "block", reason: "Continue checking the file." }
2048
+ // to request another child turn instead.
2049
+ return { modifiedResponse: `Reviewed: ${input.response}` };
2050
+ },
2051
+ },
2052
+ });
2053
+ ```
2054
+ <!-- /docs-validate: hidden -->
1622
2055
  ```typescript
1623
2056
  const session = await client.createSession({
1624
2057
  model: "gpt-5",
@@ -1724,12 +2157,13 @@ const session = await client.createSession({
1724
2157
 
1725
2158
  ## Error Handling
1726
2159
 
2160
+ <!-- docs-validate: strict -->
1727
2161
  ```typescript
1728
2162
  try {
1729
- const session = await client.createSession();
2163
+ const session = await client.createSession({});
1730
2164
  await session.send({ prompt: "Hello" });
1731
2165
  } catch (error) {
1732
- console.error("Error:", error.message);
2166
+ console.error("Error:", error instanceof Error ? error.message : error);
1733
2167
  }
1734
2168
  ```
1735
2169
 
@@ -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-2";
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 = {