@github/copilot-sdk 1.0.9-preview.0 → 1.0.9-preview.2

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
@@ -71,6 +71,12 @@ await using session = await client.createSession({
71
71
  // session is automatically disconnected when leaving scope
72
72
  ```
73
73
 
74
+ When targeting MCP tools configured through `mcpServers`, remember the runtime
75
+ tool name is `<server-key>-<tool-name>`. For `availableTools` and
76
+ `excludedTools`, prefer `new ToolSet().addMcp("<server-key>-<tool-name>")` or
77
+ the raw `mcp:<server-key>-<tool-name>` form. For `customAgents[].tools` and
78
+ `defaultAgent.excludedTools`, use `<server-key>-<tool-name>` directly.
79
+
74
80
  ## API Reference
75
81
 
76
82
  ### CopilotClient
@@ -129,6 +135,7 @@ Create a new conversation session.
129
135
  - `tools?: Tool[]` - Custom tools exposed to the CLI. Tools without `handler` are declaration-only and must be resolved via pending tool-call RPCs.
130
136
  - `systemMessage?: SystemMessageConfig` - System message customization (see below)
131
137
  - `infiniteSessions?: InfiniteSessionConfig` - Configure automatic context compaction (see below)
138
+ - `enableSessionStore?: boolean` - Enables the cross-session store for search and retrieval across sessions. When unset in `"copilot-cli"` mode, the runtime default applies (enabled). In `"empty"` mode, defaults to disabled.
132
139
  - `provider?: ProviderConfig` - Custom API provider configuration (BYOK - Bring Your Own Key). See [Custom Providers](#custom-providers) section.
133
140
  - `onPermissionRequest?: PermissionHandler` - Optional handler called before each tool execution to approve or deny it. When omitted, permission requests are emitted as events and left pending for manual resolution. Use `approveAll` to allow everything, or provide a custom function for fine-grained control. See [Permission Handling](#permission-handling) section.
134
141
  - `onUserInputRequest?: UserInputHandler` - Handler for user input requests from the agent. Enables the `ask_user` tool. See [User Input Requests](#user-input-requests) section.
@@ -520,9 +520,6 @@ class CopilotClient {
520
520
  }
521
521
  setupClientGlobalHandlers() {
522
522
  const handlers = {};
523
- handlers.hooks = {
524
- invoke: async (params) => await this.handleHooksInvoke(params)
525
- };
526
523
  if (this.requestHandler) {
527
524
  handlers.llmInference = (0, import_copilotRequestHandler.createCopilotRequestAdapter)(this.requestHandler, () => {
528
525
  if (!this.connection) {
@@ -917,7 +914,8 @@ class CopilotClient {
917
914
  enableHostGitOperations: false,
918
915
  enableSessionStore: false,
919
916
  enableSkills: false,
920
- memory: { enabled: false }
917
+ memory: { enabled: false },
918
+ customAgentsLocalOnly: true
921
919
  };
922
920
  }
923
921
  return {};
@@ -1002,7 +1000,9 @@ class CopilotClient {
1002
1000
  if (!this.connection) {
1003
1001
  await this.start();
1004
1002
  }
1005
- config = { ...this.configDefaultsForMode(), ...config };
1003
+ const modeDefaults = this.configDefaultsForMode();
1004
+ config = { ...modeDefaults, ...config };
1005
+ config.customAgentsLocalOnly ??= modeDefaults.customAgentsLocalOnly;
1006
1006
  config.systemMessage = this.getSystemMessageConfigForMode(config.systemMessage);
1007
1007
  const callerSessionId = config.sessionId;
1008
1008
  const useServerGeneratedId = config.cloud != null && callerSessionId == null;
@@ -1120,6 +1120,7 @@ class CopilotClient {
1120
1120
  mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
1121
1121
  envValueMode: "direct",
1122
1122
  customAgents: toWireCustomAgents(config.customAgents),
1123
+ customAgentsLocalOnly: config.customAgentsLocalOnly,
1123
1124
  defaultAgent: config.defaultAgent,
1124
1125
  agent: config.agent,
1125
1126
  configDir: config.configDirectory,
@@ -1203,6 +1204,13 @@ class CopilotClient {
1203
1204
  * ```
1204
1205
  */
1205
1206
  async resumeSession(sessionId, config) {
1207
+ return this.resumeSessionInternal(sessionId, config);
1208
+ }
1209
+ /** @internal */
1210
+ async resumeSessionForExtension(sessionId, config, factories) {
1211
+ return this.resumeSessionInternal(sessionId, config, factories);
1212
+ }
1213
+ async resumeSessionInternal(sessionId, config, factories) {
1206
1214
  if (!this.connection) {
1207
1215
  await this.start();
1208
1216
  }
@@ -1216,6 +1224,7 @@ class CopilotClient {
1216
1224
  session.registerTools(config.tools);
1217
1225
  session.registerCanvases(config.canvases);
1218
1226
  session.registerCommands(config.commands);
1227
+ session.registerFactories(factories);
1219
1228
  const {
1220
1229
  wireProvider: bearerWireProvider,
1221
1230
  wireProviders: bearerWireProviders,
@@ -1240,7 +1249,9 @@ class CopilotClient {
1240
1249
  if (config.hooks) {
1241
1250
  session.registerHooks(config.hooks);
1242
1251
  }
1243
- config = { ...this.configDefaultsForMode(), ...config };
1252
+ const modeDefaults = this.configDefaultsForMode();
1253
+ config = { ...modeDefaults, ...config };
1254
+ config.customAgentsLocalOnly ??= modeDefaults.customAgentsLocalOnly;
1244
1255
  config.systemMessage = this.getSystemMessageConfigForMode(config.systemMessage);
1245
1256
  const { wirePayload: wireSystemMessage, transformCallbacks } = extractTransformCallbacks(
1246
1257
  config.systemMessage
@@ -1282,6 +1293,7 @@ class CopilotClient {
1282
1293
  })),
1283
1294
  toolSearch: config.toolSearch,
1284
1295
  canvases: config.canvases?.map((canvas) => canvas.declaration),
1296
+ factories: factories?.map((factory) => factory.meta),
1285
1297
  requestCanvasRenderer: config.requestCanvasRenderer,
1286
1298
  requestExtensions: config.requestExtensions,
1287
1299
  extensionSdkPath: config.extensionSdkPath,
@@ -1322,6 +1334,7 @@ class CopilotClient {
1322
1334
  mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
1323
1335
  envValueMode: "direct",
1324
1336
  customAgents: toWireCustomAgents(config.customAgents),
1337
+ customAgentsLocalOnly: config.customAgentsLocalOnly,
1325
1338
  defaultAgent: config.defaultAgent,
1326
1339
  agent: config.agent,
1327
1340
  skillDirectories: config.skillDirectories,
@@ -2079,6 +2092,12 @@ stderr: ${stderrOutput}`
2079
2092
  return session.clientSessionApis;
2080
2093
  });
2081
2094
  (0, import_rpc.registerClientGlobalApiHandlers)(this.connection, this.clientGlobalHandlers);
2095
+ this.connection.onRequest(
2096
+ "hooks.invoke",
2097
+ async (params) => {
2098
+ return await this.handleHooksInvoke(params);
2099
+ }
2100
+ );
2082
2101
  this.connection.onClose(() => {
2083
2102
  this.state = "disconnected";
2084
2103
  });
@@ -20,13 +20,17 @@ var extension_exports = {};
20
20
  __export(extension_exports, {
21
21
  Canvas: () => import_canvas.Canvas,
22
22
  CanvasError: () => import_canvas.CanvasError,
23
+ FactoryResumeError: () => import_factory.FactoryResumeError,
23
24
  createCanvas: () => import_canvas.createCanvas,
25
+ defineFactory: () => import_factory.defineFactory,
26
+ isFactoryRunTerminal: () => import_factory.isFactoryRunTerminal,
24
27
  joinSession: () => joinSession
25
28
  });
26
29
  module.exports = __toCommonJS(extension_exports);
27
30
  var import_client = require("./client.js");
28
31
  var import_types = require("./types.js");
29
32
  var import_canvas = require("./canvas.js");
33
+ var import_factory = require("./factory.js");
30
34
  async function joinSession(config = {}) {
31
35
  const sessionId = process.env.SESSION_ID;
32
36
  if (!sessionId) {
@@ -35,18 +39,29 @@ async function joinSession(config = {}) {
35
39
  );
36
40
  }
37
41
  const client = new import_client.CopilotClient({ _internalConnection: { kind: "parent-process" } });
38
- const { extensionSdkPath: _stripped, ...rest } = config;
42
+ const {
43
+ extensionSdkPath: _stripped,
44
+ factories,
45
+ ...rest
46
+ } = config;
39
47
  void _stripped;
40
- return client.resumeSession(sessionId, {
41
- ...rest,
42
- onPermissionRequest: config.onPermissionRequest ?? import_types.defaultJoinSessionPermissionHandler,
43
- suppressResumeEvent: config.suppressResumeEvent ?? true
44
- });
48
+ return client.resumeSessionForExtension(
49
+ sessionId,
50
+ {
51
+ ...rest,
52
+ onPermissionRequest: config.onPermissionRequest ?? import_types.defaultJoinSessionPermissionHandler,
53
+ suppressResumeEvent: config.suppressResumeEvent ?? true
54
+ },
55
+ factories
56
+ );
45
57
  }
46
58
  // Annotate the CommonJS export names for ESM import in node:
47
59
  0 && (module.exports = {
48
60
  Canvas,
49
61
  CanvasError,
62
+ FactoryResumeError,
50
63
  createCanvas,
64
+ defineFactory,
65
+ isFactoryRunTerminal,
51
66
  joinSession
52
67
  });
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var factory_exports = {};
20
+ __export(factory_exports, {
21
+ FactoryResumeError: () => FactoryResumeError,
22
+ defineFactory: () => defineFactory,
23
+ getFactoryDefinition: () => getFactoryDefinition,
24
+ isFactoryRunTerminal: () => isFactoryRunTerminal
25
+ });
26
+ module.exports = __toCommonJS(factory_exports);
27
+ const FACTORY_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
28
+ "completed",
29
+ "halted",
30
+ "cancelled",
31
+ "error"
32
+ ]);
33
+ function isFactoryRunTerminal(status) {
34
+ return FACTORY_TERMINAL_STATUSES.has(status);
35
+ }
36
+ class FactoryResumeError extends Error {
37
+ constructor(code, message) {
38
+ super(message);
39
+ this.code = code;
40
+ this.name = "FactoryResumeError";
41
+ }
42
+ code;
43
+ }
44
+ const factoryHandles = /* @__PURE__ */ new WeakMap();
45
+ const MAX_FACTORY_TIMEOUT_SECONDS = 2147483647e-3;
46
+ const NANO_AIU_PER_AIU = 1e9;
47
+ function deepFreeze(value) {
48
+ if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
49
+ Object.freeze(value);
50
+ for (const nested of Object.values(value)) {
51
+ deepFreeze(nested);
52
+ }
53
+ }
54
+ return value;
55
+ }
56
+ function validateLimits(meta) {
57
+ const limits = meta.limits;
58
+ if (!limits) {
59
+ return;
60
+ }
61
+ for (const field of ["maxConcurrentSubagents", "maxTotalSubagents"]) {
62
+ const value = limits[field];
63
+ if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) {
64
+ throw new Error(`Factory limit "${field}" must be a positive integer`);
65
+ }
66
+ }
67
+ if (limits.timeoutSeconds !== void 0 && (!Number.isFinite(limits.timeoutSeconds) || limits.timeoutSeconds <= 0)) {
68
+ throw new Error(
69
+ 'Factory limit "timeoutSeconds" must be a positive, finite number of seconds'
70
+ );
71
+ }
72
+ if (limits.timeoutSeconds !== void 0 && limits.timeoutSeconds > MAX_FACTORY_TIMEOUT_SECONDS) {
73
+ throw new Error(
74
+ `Factory limit "timeoutSeconds" must not exceed ${MAX_FACTORY_TIMEOUT_SECONDS} seconds`
75
+ );
76
+ }
77
+ if (limits.maxAiCredits !== void 0) {
78
+ const maxNanoAiu = Math.round(limits.maxAiCredits * NANO_AIU_PER_AIU);
79
+ if (!Number.isFinite(limits.maxAiCredits) || limits.maxAiCredits <= 0 || !Number.isSafeInteger(maxNanoAiu) || maxNanoAiu < 1) {
80
+ throw new Error(
81
+ 'Factory limit "maxAiCredits" must be a positive, finite number that rounds to a safe positive integer nano-AIU ceiling'
82
+ );
83
+ }
84
+ }
85
+ }
86
+ function validatePhases(meta) {
87
+ const titles = /* @__PURE__ */ new Set();
88
+ for (const phase of meta.phases) {
89
+ if (phase.title.trim().length === 0) {
90
+ throw new Error("Factory phase titles must not be empty");
91
+ }
92
+ if (titles.has(phase.title)) {
93
+ throw new Error(`Factory phase title "${phase.title}" is declared more than once`);
94
+ }
95
+ titles.add(phase.title);
96
+ }
97
+ }
98
+ function defineFactory(definition) {
99
+ const meta = deepFreeze(structuredClone(definition.meta));
100
+ validateLimits(meta);
101
+ validatePhases(meta);
102
+ const stored = {
103
+ meta,
104
+ run: definition.run
105
+ };
106
+ const handle = Object.freeze({ meta });
107
+ factoryHandles.set(handle, stored);
108
+ return handle;
109
+ }
110
+ function getFactoryDefinition(handle) {
111
+ const definition = factoryHandles.get(handle);
112
+ if (!definition) {
113
+ throw new Error("Invalid factory handle");
114
+ }
115
+ return definition;
116
+ }
117
+ // Annotate the CommonJS export names for ESM import in node:
118
+ 0 && (module.exports = {
119
+ FactoryResumeError,
120
+ defineFactory,
121
+ getFactoryDefinition,
122
+ isFactoryRunTerminal
123
+ });
@@ -2582,11 +2582,6 @@ function registerClientSessionApiHandlers(connection, getHandlers) {
2582
2582
  });
2583
2583
  }
2584
2584
  function registerClientGlobalApiHandlers(connection, handlers) {
2585
- connection.onRequest("hooks.invoke", async (params) => {
2586
- const handler = handlers.hooks;
2587
- if (!handler) throw new Error("No hooks client-global handler registered");
2588
- return handler.invoke(params);
2589
- });
2590
2585
  connection.onRequest("llmInference.httpRequestStart", async (params) => {
2591
2586
  const handler = handlers.llmInference;
2592
2587
  if (!handler) throw new Error("No llmInference client-global handler registered");
package/dist/cjs/index.js CHANGED
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  CopilotWebSocketCloseStatus: () => import_types2.CopilotWebSocketCloseStatus,
28
28
  CopilotWebSocketForwarder: () => import_types2.CopilotWebSocketForwarder,
29
29
  CopilotWebSocketHandler: () => import_types2.CopilotWebSocketHandler,
30
+ FactoryResumeError: () => import_factory.FactoryResumeError,
30
31
  RuntimeConnection: () => import_types.RuntimeConnection,
31
32
  SYSTEM_MESSAGE_SECTIONS: () => import_types2.SYSTEM_MESSAGE_SECTIONS,
32
33
  SessionFsSqliteTransactionFailure: () => import_types2.SessionFsSqliteTransactionFailure,
@@ -35,13 +36,16 @@ __export(index_exports, {
35
36
  convertMcpCallToolResult: () => import_types2.convertMcpCallToolResult,
36
37
  createCanvas: () => import_canvas.createCanvas,
37
38
  createSessionFsAdapter: () => import_types2.createSessionFsAdapter,
38
- defineTool: () => import_types2.defineTool
39
+ defineFactory: () => import_factory.defineFactory,
40
+ defineTool: () => import_types2.defineTool,
41
+ isFactoryRunTerminal: () => import_factory.isFactoryRunTerminal
39
42
  });
40
43
  module.exports = __toCommonJS(index_exports);
41
44
  var import_client = require("./client.js");
42
45
  var import_types = require("./types.js");
43
46
  var import_toolSet = require("./toolSet.js");
44
47
  var import_session = require("./session.js");
48
+ var import_factory = require("./factory.js");
45
49
  var import_canvas = require("./canvas.js");
46
50
  var import_types2 = require("./types.js");
47
51
  // Annotate the CommonJS export names for ESM import in node:
@@ -55,6 +59,7 @@ var import_types2 = require("./types.js");
55
59
  CopilotWebSocketCloseStatus,
56
60
  CopilotWebSocketForwarder,
57
61
  CopilotWebSocketHandler,
62
+ FactoryResumeError,
58
63
  RuntimeConnection,
59
64
  SYSTEM_MESSAGE_SECTIONS,
60
65
  SessionFsSqliteTransactionFailure,
@@ -63,5 +68,7 @@ var import_types2 = require("./types.js");
63
68
  convertMcpCallToolResult,
64
69
  createCanvas,
65
70
  createSessionFsAdapter,
66
- defineTool
71
+ defineFactory,
72
+ defineTool,
73
+ isFactoryRunTerminal
67
74
  });