@github/copilot-sdk 1.0.8 → 1.0.9-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 +18 -1
- package/dist/cjs/client.js +9 -0
- package/dist/cjs/extension.js +21 -6
- package/dist/cjs/factory.js +123 -0
- package/dist/cjs/generated/rpc.js +376 -11
- package/dist/cjs/index.js +11 -2
- package/dist/cjs/session.js +598 -3
- package/dist/cjs/sessionFsProvider.js +43 -0
- package/dist/cjs/types.js +3 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +9 -0
- package/dist/extension.d.ts +11 -2
- package/dist/extension.js +22 -6
- package/dist/factory.d.ts +273 -0
- package/dist/factory.js +96 -0
- package/dist/generated/rpc.d.ts +2445 -228
- package/dist/generated/rpc.js +376 -11
- package/dist/generated/session-events.d.ts +260 -6
- package/dist/index.d.ts +4 -2
- package/dist/index.js +7 -1
- package/dist/session.d.ts +21 -0
- package/dist/session.js +602 -3
- package/dist/sessionFsProvider.d.ts +38 -2
- package/dist/sessionFsProvider.js +42 -0
- package/dist/types.d.ts +95 -10
- package/dist/types.js +2 -0
- package/docs/extensions.md +1 -0
- package/docs/factories.md +240 -0
- package/docs/factory-patterns.md +194 -0
- package/package.json +2 -2
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
|
|
@@ -751,7 +757,7 @@ The SDK supports custom OpenAI-compatible API providers (BYOK - Bring Your Own K
|
|
|
751
757
|
- `apiKey?: string` - API key (optional for local providers like Ollama)
|
|
752
758
|
- `bearerToken?: string` - Bearer token for authentication (takes precedence over apiKey)
|
|
753
759
|
- `wireApi?: "completions" | "responses"` - API format for OpenAI/Azure (default: "completions")
|
|
754
|
-
- `azure?.apiVersion?: string` - Azure API version
|
|
760
|
+
- `azure?.apiVersion?: string` - Azure API version; when omitted, the runtime uses the GA versionless `v1` route
|
|
755
761
|
|
|
756
762
|
**Example with Ollama:**
|
|
757
763
|
|
|
@@ -1058,6 +1064,16 @@ const session = await client.createSession({
|
|
|
1058
1064
|
errorHandling: "retry", // "retry", "skip", or "abort"
|
|
1059
1065
|
};
|
|
1060
1066
|
},
|
|
1067
|
+
|
|
1068
|
+
// Called when the top-level agent naturally stops
|
|
1069
|
+
onAgentStop: async (input, invocation) => {
|
|
1070
|
+
if (!input.stopHookActive && needsMoreWork()) {
|
|
1071
|
+
return {
|
|
1072
|
+
decision: "block",
|
|
1073
|
+
reason: "Run the final validation and fix any failures.",
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
},
|
|
1061
1077
|
},
|
|
1062
1078
|
});
|
|
1063
1079
|
```
|
|
@@ -1071,6 +1087,7 @@ const session = await client.createSession({
|
|
|
1071
1087
|
- `onSessionStart` - Run logic when a session starts or resumes.
|
|
1072
1088
|
- `onSessionEnd` - Cleanup or logging when session ends.
|
|
1073
1089
|
- `onErrorOccurred` - Handle errors with retry/skip/abort strategies.
|
|
1090
|
+
- `onAgentStop` - Observe natural top-level agent completion. Return `{ decision: "block", reason }` to request another turn; use `stopHookActive` to avoid repeated blocks.
|
|
1074
1091
|
|
|
1075
1092
|
## Error Handling
|
|
1076
1093
|
|
package/dist/cjs/client.js
CHANGED
|
@@ -1203,6 +1203,13 @@ class CopilotClient {
|
|
|
1203
1203
|
* ```
|
|
1204
1204
|
*/
|
|
1205
1205
|
async resumeSession(sessionId, config) {
|
|
1206
|
+
return this.resumeSessionInternal(sessionId, config);
|
|
1207
|
+
}
|
|
1208
|
+
/** @internal */
|
|
1209
|
+
async resumeSessionForExtension(sessionId, config, factories) {
|
|
1210
|
+
return this.resumeSessionInternal(sessionId, config, factories);
|
|
1211
|
+
}
|
|
1212
|
+
async resumeSessionInternal(sessionId, config, factories) {
|
|
1206
1213
|
if (!this.connection) {
|
|
1207
1214
|
await this.start();
|
|
1208
1215
|
}
|
|
@@ -1216,6 +1223,7 @@ class CopilotClient {
|
|
|
1216
1223
|
session.registerTools(config.tools);
|
|
1217
1224
|
session.registerCanvases(config.canvases);
|
|
1218
1225
|
session.registerCommands(config.commands);
|
|
1226
|
+
session.registerFactories(factories);
|
|
1219
1227
|
const {
|
|
1220
1228
|
wireProvider: bearerWireProvider,
|
|
1221
1229
|
wireProviders: bearerWireProviders,
|
|
@@ -1282,6 +1290,7 @@ class CopilotClient {
|
|
|
1282
1290
|
})),
|
|
1283
1291
|
toolSearch: config.toolSearch,
|
|
1284
1292
|
canvases: config.canvases?.map((canvas) => canvas.declaration),
|
|
1293
|
+
factories: factories?.map((factory) => factory.meta),
|
|
1285
1294
|
requestCanvasRenderer: config.requestCanvasRenderer,
|
|
1286
1295
|
requestExtensions: config.requestExtensions,
|
|
1287
1296
|
extensionSdkPath: config.extensionSdkPath,
|
package/dist/cjs/extension.js
CHANGED
|
@@ -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 {
|
|
42
|
+
const {
|
|
43
|
+
extensionSdkPath: _stripped,
|
|
44
|
+
factories,
|
|
45
|
+
...rest
|
|
46
|
+
} = config;
|
|
39
47
|
void _stripped;
|
|
40
|
-
return client.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
+
});
|