@github/copilot-sdk 1.0.17-preview.0 → 1.0.17-preview.10
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 +108 -0
- package/dist/canvas.d.ts +6 -1
- package/dist/cjs/cliVersion.js +1 -1
- package/dist/cjs/client.js +69 -4
- package/dist/cjs/extension.js +2 -0
- package/dist/cjs/generated/rpc.js +577 -251
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/runtimeArtifacts.js +1 -0
- package/dist/cjs/session.js +151 -2
- package/dist/cjs/sessionFsProvider.js +57 -0
- package/dist/cjs/types.js +5 -2
- package/dist/cliVersion.d.ts +1 -1
- package/dist/cliVersion.js +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.js +69 -4
- package/dist/extension.d.ts +1 -1
- package/dist/extension.js +2 -0
- package/dist/generated/rpc.d.ts +2250 -684
- package/dist/generated/rpc.js +577 -251
- package/dist/generated/session-events.d.ts +292 -11
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -0
- package/dist/runtimeArtifacts.js +1 -0
- package/dist/session.d.ts +52 -1
- package/dist/session.js +151 -2
- package/dist/sessionFsProvider.d.ts +9 -1
- package/dist/sessionFsProvider.js +56 -0
- package/dist/types.d.ts +159 -2
- package/dist/types.js +4 -2
- package/docs/agent-author.md +29 -2
- package/package.json +13 -12
package/dist/cjs/index.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
RuntimeConnection: () => import_types.RuntimeConnection,
|
|
33
33
|
SYSTEM_MESSAGE_SECTIONS: () => import_types2.SYSTEM_MESSAGE_SECTIONS,
|
|
34
34
|
SessionFsSqliteTransactionFailure: () => import_types2.SessionFsSqliteTransactionFailure,
|
|
35
|
+
SessionFsWriteFailure: () => import_types2.SessionFsWriteFailure,
|
|
35
36
|
ToolSet: () => import_toolSet.ToolSet,
|
|
36
37
|
WorkflowResumeError: () => import_workflow.WorkflowResumeError,
|
|
37
38
|
approveAll: () => import_types2.approveAll,
|
|
@@ -68,6 +69,7 @@ var import_types2 = require("./types.js");
|
|
|
68
69
|
RuntimeConnection,
|
|
69
70
|
SYSTEM_MESSAGE_SECTIONS,
|
|
70
71
|
SessionFsSqliteTransactionFailure,
|
|
72
|
+
SessionFsWriteFailure,
|
|
71
73
|
ToolSet,
|
|
72
74
|
WorkflowResumeError,
|
|
73
75
|
approveAll,
|
package/dist/cjs/session.js
CHANGED
|
@@ -38,6 +38,18 @@ function copyDefinedWorkflowAgentOption(source, target, key) {
|
|
|
38
38
|
target[key] = value;
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
function toToolDefinition(tool) {
|
|
42
|
+
return {
|
|
43
|
+
name: tool.name,
|
|
44
|
+
description: tool.description ?? "",
|
|
45
|
+
parameters: (0, import_schema.toJsonSchema)(tool.parameters),
|
|
46
|
+
overridesBuiltInTool: tool.overridesBuiltInTool,
|
|
47
|
+
skipPermission: tool.skipPermission,
|
|
48
|
+
defer: tool.defer,
|
|
49
|
+
metadata: tool.metadata,
|
|
50
|
+
isTerminal: tool.isTerminal
|
|
51
|
+
};
|
|
52
|
+
}
|
|
41
53
|
const workflowExecutionStore = new import_node_async_hooks.AsyncLocalStorage();
|
|
42
54
|
function throwIfWorkflowExecutionIsActive() {
|
|
43
55
|
if (workflowExecutionStore.getStore()?.active) {
|
|
@@ -258,6 +270,8 @@ class CopilotSession {
|
|
|
258
270
|
eventHandlers = /* @__PURE__ */ new Set();
|
|
259
271
|
typedEventHandlers = /* @__PURE__ */ new Map();
|
|
260
272
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
273
|
+
/** Settles once every earlier `setTools` call has finished. */
|
|
274
|
+
setToolsQueue = Promise.resolve();
|
|
261
275
|
pendingExternalTools = /* @__PURE__ */ new Map();
|
|
262
276
|
canvases = /* @__PURE__ */ new Map();
|
|
263
277
|
bearerTokenProviders = /* @__PURE__ */ new Map();
|
|
@@ -270,6 +284,7 @@ class CopilotSession {
|
|
|
270
284
|
elicitationHandler;
|
|
271
285
|
exitPlanModeHandler;
|
|
272
286
|
autoModeSwitchHandler;
|
|
287
|
+
skillProvider;
|
|
273
288
|
hooks;
|
|
274
289
|
transformCallbacks;
|
|
275
290
|
_rpc = null;
|
|
@@ -682,6 +697,7 @@ class CopilotSession {
|
|
|
682
697
|
this.elicitationHandler = void 0;
|
|
683
698
|
this.exitPlanModeHandler = void 0;
|
|
684
699
|
this.autoModeSwitchHandler = void 0;
|
|
700
|
+
this.skillProvider = void 0;
|
|
685
701
|
this.commandHandlers.clear();
|
|
686
702
|
this.canvases.clear();
|
|
687
703
|
this.workflows.clear();
|
|
@@ -1069,7 +1085,20 @@ class CopilotSession {
|
|
|
1069
1085
|
}
|
|
1070
1086
|
for (const tool of tools) {
|
|
1071
1087
|
if (tool.handler) {
|
|
1072
|
-
|
|
1088
|
+
const handler = tool.handler;
|
|
1089
|
+
if (tool.name === "apply_patch" && tool.overridesBuiltInTool && (0, import_schema.toJsonSchema)(tool.parameters)?.type === "string") {
|
|
1090
|
+
this.toolHandlers.set(tool.name, (args, invocation) => {
|
|
1091
|
+
if (typeof args === "string") {
|
|
1092
|
+
return handler(args, invocation);
|
|
1093
|
+
}
|
|
1094
|
+
if (typeof args === "object" && args !== null && "input" in args && typeof args.input === "string") {
|
|
1095
|
+
return handler(args.input, invocation);
|
|
1096
|
+
}
|
|
1097
|
+
throw new TypeError("apply_patch string override requires a string input");
|
|
1098
|
+
});
|
|
1099
|
+
} else {
|
|
1100
|
+
this.toolHandlers.set(tool.name, handler);
|
|
1101
|
+
}
|
|
1073
1102
|
}
|
|
1074
1103
|
}
|
|
1075
1104
|
}
|
|
@@ -1575,6 +1604,68 @@ class CopilotSession {
|
|
|
1575
1604
|
registerUserInputHandler(handler) {
|
|
1576
1605
|
this.userInputHandler = handler;
|
|
1577
1606
|
}
|
|
1607
|
+
/**
|
|
1608
|
+
* Registers the session's skill provider.
|
|
1609
|
+
*
|
|
1610
|
+
* @param provider - The skill provider, or undefined to remove it
|
|
1611
|
+
* @internal This method is typically called internally when creating a session.
|
|
1612
|
+
*/
|
|
1613
|
+
registerSkillProvider(provider) {
|
|
1614
|
+
this.skillProvider = provider;
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* Handles a `skillProvider.list` request from the runtime.
|
|
1618
|
+
*
|
|
1619
|
+
* @internal This method is for internal use by the SDK.
|
|
1620
|
+
*/
|
|
1621
|
+
async _handleSkillProviderList(token) {
|
|
1622
|
+
const provider = this.requireSkillProvider();
|
|
1623
|
+
return await this.callSkillProvider("listSkills", token, async (options) => ({
|
|
1624
|
+
skills: await provider.listSkills(options) ?? []
|
|
1625
|
+
}));
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Handles a `skillProvider.read` request from the runtime.
|
|
1629
|
+
*
|
|
1630
|
+
* @internal This method is for internal use by the SDK.
|
|
1631
|
+
*/
|
|
1632
|
+
async _handleSkillProviderRead(name, token) {
|
|
1633
|
+
const provider = this.requireSkillProvider();
|
|
1634
|
+
return await this.callSkillProvider("readSkill", token, async (options) => ({
|
|
1635
|
+
markdown: await provider.readSkill(name, options) ?? null
|
|
1636
|
+
}));
|
|
1637
|
+
}
|
|
1638
|
+
requireSkillProvider() {
|
|
1639
|
+
if (!this.skillProvider) {
|
|
1640
|
+
throw new Error(`No skill provider for session: ${this.sessionId}`);
|
|
1641
|
+
}
|
|
1642
|
+
return this.skillProvider;
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1645
|
+
* Runs a provider call with an abort signal tied to the runtime's request
|
|
1646
|
+
* cancellation. Failures are logged locally and reported generically.
|
|
1647
|
+
*/
|
|
1648
|
+
async callSkillProvider(operation, token, call) {
|
|
1649
|
+
const controller = new AbortController();
|
|
1650
|
+
const subscription = token?.onCancellationRequested(() => controller.abort());
|
|
1651
|
+
if (token?.isCancellationRequested) {
|
|
1652
|
+
controller.abort();
|
|
1653
|
+
}
|
|
1654
|
+
try {
|
|
1655
|
+
return await call({ signal: controller.signal });
|
|
1656
|
+
} catch (error) {
|
|
1657
|
+
if (controller.signal.aborted) {
|
|
1658
|
+
throw new import_node.ResponseError(-32800, `Skill provider ${operation} cancelled`);
|
|
1659
|
+
}
|
|
1660
|
+
console.error(`Skill provider ${operation} failed`, {
|
|
1661
|
+
sessionId: this.sessionId,
|
|
1662
|
+
error
|
|
1663
|
+
});
|
|
1664
|
+
throw skillProviderFailure(operation);
|
|
1665
|
+
} finally {
|
|
1666
|
+
subscription?.dispose();
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1578
1669
|
/**
|
|
1579
1670
|
* Registers hook handlers for session lifecycle events.
|
|
1580
1671
|
*
|
|
@@ -1664,7 +1755,9 @@ class CopilotSession {
|
|
|
1664
1755
|
sessionStart: this.hooks.onSessionStart,
|
|
1665
1756
|
sessionEnd: this.hooks.onSessionEnd,
|
|
1666
1757
|
errorOccurred: this.hooks.onErrorOccurred,
|
|
1667
|
-
agentStop: this.hooks.onAgentStop
|
|
1758
|
+
agentStop: this.hooks.onAgentStop,
|
|
1759
|
+
subagentStart: this.hooks.onSubagentStart,
|
|
1760
|
+
subagentStop: this.hooks.onSubagentStop
|
|
1668
1761
|
};
|
|
1669
1762
|
const handler = handlerMap[hookType];
|
|
1670
1763
|
if (!handler) {
|
|
@@ -1828,6 +1921,59 @@ class CopilotSession {
|
|
|
1828
1921
|
async setAutoTier(autoTier) {
|
|
1829
1922
|
return await this.rpc.model.switchAutoTier({ autoTier });
|
|
1830
1923
|
}
|
|
1924
|
+
/**
|
|
1925
|
+
* Replace the tools this client supplies to the session.
|
|
1926
|
+
*
|
|
1927
|
+
* `tools` becomes the complete set of tools this client implements,
|
|
1928
|
+
* replacing the ones it supplied when the session was created or resumed,
|
|
1929
|
+
* or in an earlier call. Built-in, MCP, and plugin tools, and tools other
|
|
1930
|
+
* connected clients supply, are unaffected. Pass an empty array to remove
|
|
1931
|
+
* all of this client's tools.
|
|
1932
|
+
*
|
|
1933
|
+
* Tools are defined the same way as for `createSession`: calls to tools
|
|
1934
|
+
* with a `handler` are dispatched to it, and tools without one are
|
|
1935
|
+
* declaration-only. Once the runtime accepts the replacement, every tool
|
|
1936
|
+
* call this session dispatches uses the new handlers; calls already
|
|
1937
|
+
* running finish on their original handlers. If the runtime rejects the
|
|
1938
|
+
* replacement, this rejects and the previous tools and handlers stay in
|
|
1939
|
+
* place. Concurrent calls on the same session are applied one at a time,
|
|
1940
|
+
* in the order they are made.
|
|
1941
|
+
*
|
|
1942
|
+
* The agent sees the new tools from its next model request, which can fall
|
|
1943
|
+
* within a turn in progress. A model request already in flight was made
|
|
1944
|
+
* with the previous tools, so the agent can still call a tool you removed.
|
|
1945
|
+
* This session doesn't answer that call, and it can stay pending until the
|
|
1946
|
+
* turn is aborted. If a running turn might still call a tool you remove,
|
|
1947
|
+
* replace tools while the session is idle.
|
|
1948
|
+
*
|
|
1949
|
+
* @param tools - The complete set of tools this client supplies
|
|
1950
|
+
*
|
|
1951
|
+
* @experimental Wraps the experimental `session.tools.set` RPC and may change
|
|
1952
|
+
* or be removed in a future release.
|
|
1953
|
+
*
|
|
1954
|
+
* @example
|
|
1955
|
+
* ```typescript
|
|
1956
|
+
* await session.setTools([
|
|
1957
|
+
* defineTool("search_issues", {
|
|
1958
|
+
* description: "Search the issues shown on the current page",
|
|
1959
|
+
* parameters: z.object({ query: z.string() }),
|
|
1960
|
+
* handler: async ({ query }) => searchIssues(query),
|
|
1961
|
+
* }),
|
|
1962
|
+
* ]);
|
|
1963
|
+
* ```
|
|
1964
|
+
*/
|
|
1965
|
+
async setTools(tools) {
|
|
1966
|
+
const definitions = tools.map(toToolDefinition);
|
|
1967
|
+
const replacement = this.setToolsQueue.then(async () => {
|
|
1968
|
+
await this.rpc.tools.set({ tools: definitions });
|
|
1969
|
+
this.registerTools(tools);
|
|
1970
|
+
});
|
|
1971
|
+
this.setToolsQueue = replacement.then(
|
|
1972
|
+
() => void 0,
|
|
1973
|
+
() => void 0
|
|
1974
|
+
);
|
|
1975
|
+
await replacement;
|
|
1976
|
+
}
|
|
1831
1977
|
/**
|
|
1832
1978
|
* Log a message to the session timeline.
|
|
1833
1979
|
* The message appears in the session event stream and is visible to SDK consumers
|
|
@@ -1873,6 +2019,9 @@ function toCanvasRpcError(error) {
|
|
|
1873
2019
|
const message = error instanceof Error ? error.message : String(error);
|
|
1874
2020
|
return new import_node.ResponseError(import_node.ErrorCodes.InternalError, message, { code, message });
|
|
1875
2021
|
}
|
|
2022
|
+
function skillProviderFailure(operation) {
|
|
2023
|
+
return new import_node.ResponseError(import_node.ErrorCodes.InternalError, `Skill provider ${operation} failed`);
|
|
2024
|
+
}
|
|
1876
2025
|
function strictJsonValidationError(context, category, message, path) {
|
|
1877
2026
|
return new import_node.ResponseError(import_node.ErrorCodes.InternalError, message, {
|
|
1878
2027
|
code: context.code,
|
|
@@ -19,9 +19,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var sessionFsProvider_exports = {};
|
|
20
20
|
__export(sessionFsProvider_exports, {
|
|
21
21
|
SessionFsSqliteTransactionFailure: () => SessionFsSqliteTransactionFailure,
|
|
22
|
+
SessionFsWriteFailure: () => SessionFsWriteFailure,
|
|
22
23
|
createSessionFsAdapter: () => createSessionFsAdapter
|
|
23
24
|
});
|
|
24
25
|
module.exports = __toCommonJS(sessionFsProvider_exports);
|
|
26
|
+
const MAX_BINARY_BYTES = (64 * 1024 * 1024 - 1024) / 4 * 3;
|
|
27
|
+
const MAX_BINARY_CONTENT_LENGTH = Math.ceil(MAX_BINARY_BYTES / 3) * 4;
|
|
25
28
|
class SessionFsSqliteTransactionFailure extends Error {
|
|
26
29
|
/** Failure classification reported to the runtime. */
|
|
27
30
|
errorClass;
|
|
@@ -31,6 +34,9 @@ class SessionFsSqliteTransactionFailure extends Error {
|
|
|
31
34
|
this.errorClass = errorClass;
|
|
32
35
|
}
|
|
33
36
|
}
|
|
37
|
+
class SessionFsWriteFailure extends Error {
|
|
38
|
+
writeChanged = true;
|
|
39
|
+
}
|
|
34
40
|
function normalizeSqliteParams(params) {
|
|
35
41
|
if (!params) {
|
|
36
42
|
return void 0;
|
|
@@ -53,10 +59,60 @@ function createSessionFsAdapter(provider) {
|
|
|
53
59
|
return { content: "", error: toSessionFsError(err) };
|
|
54
60
|
}
|
|
55
61
|
},
|
|
62
|
+
readFileBytes: async ({ path }) => {
|
|
63
|
+
if (!provider.readFileBytes) {
|
|
64
|
+
return {
|
|
65
|
+
content: "",
|
|
66
|
+
error: { code: "UNKNOWN", message: "Binary reads are not supported" }
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const bytes = await provider.readFileBytes(path);
|
|
71
|
+
if (bytes.length > MAX_BINARY_BYTES) {
|
|
72
|
+
return {
|
|
73
|
+
content: "",
|
|
74
|
+
error: {
|
|
75
|
+
code: "UNKNOWN",
|
|
76
|
+
message: "sessionFs.readFileBytes content exceeds the binary read limit"
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
content: Buffer.from(bytes).toString("base64")
|
|
82
|
+
};
|
|
83
|
+
} catch (err) {
|
|
84
|
+
return { content: "", error: toSessionFsError(err) };
|
|
85
|
+
}
|
|
86
|
+
},
|
|
56
87
|
writeFile: async ({ path, content, mode }) => {
|
|
57
88
|
try {
|
|
58
89
|
await provider.writeFile(path, content, mode);
|
|
59
90
|
return void 0;
|
|
91
|
+
} catch (err) {
|
|
92
|
+
const error = toSessionFsError(err);
|
|
93
|
+
return err instanceof SessionFsWriteFailure ? { ...error, writeChanged: true } : error;
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
writeFileBytes: async ({ path, content, mode }) => {
|
|
97
|
+
if (!provider.writeFileBytes) {
|
|
98
|
+
return { code: "UNKNOWN", message: "Binary writes are not supported" };
|
|
99
|
+
}
|
|
100
|
+
if (content.length > MAX_BINARY_CONTENT_LENGTH) {
|
|
101
|
+
return {
|
|
102
|
+
code: "UNKNOWN",
|
|
103
|
+
message: "sessionFs.writeFileBytes content exceeds the binary write limit"
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const bytes = Buffer.from(content, "base64");
|
|
107
|
+
if (bytes.toString("base64") !== content || bytes.length > MAX_BINARY_BYTES) {
|
|
108
|
+
return {
|
|
109
|
+
code: "UNKNOWN",
|
|
110
|
+
message: "invalid sessionFs.writeFileBytes base64 content"
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
await provider.writeFileBytes(path, bytes, mode);
|
|
115
|
+
return void 0;
|
|
60
116
|
} catch (err) {
|
|
61
117
|
return toSessionFsError(err);
|
|
62
118
|
}
|
|
@@ -194,5 +250,6 @@ function toSqliteTransactionError(err) {
|
|
|
194
250
|
// Annotate the CommonJS export names for ESM import in node:
|
|
195
251
|
0 && (module.exports = {
|
|
196
252
|
SessionFsSqliteTransactionFailure,
|
|
253
|
+
SessionFsWriteFailure,
|
|
197
254
|
createSessionFsAdapter
|
|
198
255
|
});
|
package/dist/cjs/types.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(types_exports, {
|
|
|
26
26
|
RuntimeConnection: () => RuntimeConnection,
|
|
27
27
|
SYSTEM_MESSAGE_SECTIONS: () => SYSTEM_MESSAGE_SECTIONS,
|
|
28
28
|
SessionFsSqliteTransactionFailure: () => import_sessionFsProvider2.SessionFsSqliteTransactionFailure,
|
|
29
|
+
SessionFsWriteFailure: () => import_sessionFsProvider3.SessionFsWriteFailure,
|
|
29
30
|
approveAll: () => approveAll,
|
|
30
31
|
convertMcpCallToolResult: () => convertMcpCallToolResult,
|
|
31
32
|
createAttributedPermissionResult: () => createAttributedPermissionResult,
|
|
@@ -37,6 +38,7 @@ __export(types_exports, {
|
|
|
37
38
|
module.exports = __toCommonJS(types_exports);
|
|
38
39
|
var import_sessionFsProvider = require("./sessionFsProvider.js");
|
|
39
40
|
var import_sessionFsProvider2 = require("./sessionFsProvider.js");
|
|
41
|
+
var import_sessionFsProvider3 = require("./sessionFsProvider.js");
|
|
40
42
|
var import_copilotRequestHandler = require("./copilotRequestHandler.js");
|
|
41
43
|
const RuntimeConnection = {
|
|
42
44
|
/**
|
|
@@ -138,10 +140,10 @@ const SYSTEM_MESSAGE_SECTIONS = {
|
|
|
138
140
|
tool_instructions: { description: "Per-tool usage instructions" },
|
|
139
141
|
custom_instructions: { description: "Repository and organization custom instructions" },
|
|
140
142
|
runtime_instructions: {
|
|
141
|
-
description: "Runtime-provided context and instructions
|
|
143
|
+
description: "Runtime-provided system-prompt context and instructions, such as system notifications, memories, workspace context, and content-exclusion policy. Mode-specific instructions can travel in transition messages instead."
|
|
142
144
|
},
|
|
143
145
|
last_instructions: {
|
|
144
|
-
description: "End-of-prompt instructions: parallel tool calling, persistence, task completion"
|
|
146
|
+
description: "End-of-prompt instructions: parallel tool calling, persistence, task completion, and configured subagent-model guidance when the task tool is available"
|
|
145
147
|
}
|
|
146
148
|
};
|
|
147
149
|
function isAttributedPermissionResult(result) {
|
|
@@ -182,6 +184,7 @@ const DisableBypassPermissionsModes = {
|
|
|
182
184
|
RuntimeConnection,
|
|
183
185
|
SYSTEM_MESSAGE_SECTIONS,
|
|
184
186
|
SessionFsSqliteTransactionFailure,
|
|
187
|
+
SessionFsWriteFailure,
|
|
185
188
|
approveAll,
|
|
186
189
|
convertMcpCallToolResult,
|
|
187
190
|
createAttributedPermissionResult,
|
package/dist/cliVersion.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const COPILOT_CLI_VERSION = "1.0.
|
|
1
|
+
export declare const COPILOT_CLI_VERSION = "1.0.93-4";
|
|
2
2
|
export declare const COPILOT_CLI_USE_NPM_PACKAGE = false;
|
package/dist/cliVersion.js
CHANGED
package/dist/client.d.ts
CHANGED
|
@@ -507,6 +507,7 @@ export declare class CopilotClient {
|
|
|
507
507
|
private handleUserInputRequest;
|
|
508
508
|
private handleExitPlanModeRequest;
|
|
509
509
|
private handleAutoModeSwitchRequest;
|
|
510
|
+
private resolveSkillProviderSession;
|
|
510
511
|
private handleHooksInvoke;
|
|
511
512
|
private handleSystemMessageTransform;
|
|
512
513
|
}
|
package/dist/client.js
CHANGED
|
@@ -32,6 +32,7 @@ import { ToolSet } from "./toolSet.js";
|
|
|
32
32
|
import { defaultJoinSessionPermissionHandler } from "./types.js";
|
|
33
33
|
const MIN_PROTOCOL_VERSION = 3;
|
|
34
34
|
const RUNTIME_SHUTDOWN_TIMEOUT_MS = 1e4;
|
|
35
|
+
const CLOUD_SESSION_CLEANUP_TIMEOUT_MS = 1e4;
|
|
35
36
|
function createMessageConnection(reader, writer) {
|
|
36
37
|
let dispatch;
|
|
37
38
|
let finishDrain;
|
|
@@ -560,6 +561,11 @@ class CopilotClient {
|
|
|
560
561
|
"SessionFsConfig declares capabilities.sqlite but the provider does not implement sqlite."
|
|
561
562
|
);
|
|
562
563
|
}
|
|
564
|
+
if (this.sessionFsConfig.capabilities?.binary && (!provider.readFileBytes || !provider.writeFileBytes)) {
|
|
565
|
+
throw new Error(
|
|
566
|
+
"SessionFsConfig declares capabilities.binary but the provider does not implement readFileBytes and writeFileBytes."
|
|
567
|
+
);
|
|
568
|
+
}
|
|
563
569
|
session.clientSessionApis.sessionFs = createSessionFsAdapter(provider);
|
|
564
570
|
}
|
|
565
571
|
setupClientGlobalHandlers() {
|
|
@@ -1178,6 +1184,9 @@ class CopilotClient {
|
|
|
1178
1184
|
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1179
1185
|
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1180
1186
|
}
|
|
1187
|
+
if (config.cloud != null && config.skillProvider) {
|
|
1188
|
+
throw new Error("Skill providers are not supported for cloud sessions.");
|
|
1189
|
+
}
|
|
1181
1190
|
if (!this.connection) {
|
|
1182
1191
|
await this.start();
|
|
1183
1192
|
}
|
|
@@ -1237,18 +1246,22 @@ class CopilotClient {
|
|
|
1237
1246
|
if (config.hooks) {
|
|
1238
1247
|
s.registerHooks(config.hooks);
|
|
1239
1248
|
}
|
|
1249
|
+
if (config.skillProvider) {
|
|
1250
|
+
s.registerSkillProvider(config.skillProvider);
|
|
1251
|
+
}
|
|
1240
1252
|
if (transformCallbacks) {
|
|
1241
1253
|
s.registerTransformCallbacks(transformCallbacks);
|
|
1242
1254
|
}
|
|
1243
1255
|
if (config.onEvent) {
|
|
1244
1256
|
s.on(config.onEvent);
|
|
1245
1257
|
}
|
|
1246
|
-
this.sessions.set(sessionId, s);
|
|
1247
1258
|
this.setupSessionFs(s, config);
|
|
1259
|
+
this.sessions.set(sessionId, s);
|
|
1248
1260
|
return s;
|
|
1249
1261
|
};
|
|
1250
1262
|
let session;
|
|
1251
1263
|
let registeredId;
|
|
1264
|
+
let uninitializedCloudSessionId;
|
|
1252
1265
|
if (localSessionId !== void 0) {
|
|
1253
1266
|
try {
|
|
1254
1267
|
session = initializeSession(localSessionId);
|
|
@@ -1342,6 +1355,7 @@ class CopilotClient {
|
|
|
1342
1355
|
enableSessionStore: config.enableSessionStore,
|
|
1343
1356
|
enableSkills: config.enableSkills,
|
|
1344
1357
|
skillDirectories: config.skillDirectories,
|
|
1358
|
+
...config.skillProvider ? { hasSkillProvider: true } : {},
|
|
1345
1359
|
pluginDirectories: config.pluginDirectories,
|
|
1346
1360
|
instructionDirectories: config.instructionDirectories,
|
|
1347
1361
|
disabledSkills: config.disabledSkills,
|
|
@@ -1371,7 +1385,9 @@ class CopilotClient {
|
|
|
1371
1385
|
);
|
|
1372
1386
|
}
|
|
1373
1387
|
if (session === void 0) {
|
|
1388
|
+
uninitializedCloudSessionId = returnedSessionId;
|
|
1374
1389
|
session = initializeSession(returnedSessionId);
|
|
1390
|
+
uninitializedCloudSessionId = void 0;
|
|
1375
1391
|
registeredId = returnedSessionId;
|
|
1376
1392
|
}
|
|
1377
1393
|
this.assignGitHubTokenProvider(gitHubTokenProviderRegistrationId, returnedSessionId);
|
|
@@ -1393,6 +1409,20 @@ class CopilotClient {
|
|
|
1393
1409
|
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1394
1410
|
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1395
1411
|
}
|
|
1412
|
+
if (uninitializedCloudSessionId !== void 0) {
|
|
1413
|
+
try {
|
|
1414
|
+
await withTimeout(
|
|
1415
|
+
this.deleteSession(uninitializedCloudSessionId),
|
|
1416
|
+
CLOUD_SESSION_CLEANUP_TIMEOUT_MS,
|
|
1417
|
+
`session.delete timed out after ${CLOUD_SESSION_CLEANUP_TIMEOUT_MS}ms`
|
|
1418
|
+
);
|
|
1419
|
+
} catch (cleanupError) {
|
|
1420
|
+
throw new AggregateError(
|
|
1421
|
+
[e, cleanupError],
|
|
1422
|
+
"Failed to initialize and delete cloud session"
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1396
1426
|
throw e;
|
|
1397
1427
|
}
|
|
1398
1428
|
for (const entry of this.hostHandoffs.values()) {
|
|
@@ -1479,6 +1509,9 @@ class CopilotClient {
|
|
|
1479
1509
|
if (config.hooks) {
|
|
1480
1510
|
session.registerHooks(config.hooks);
|
|
1481
1511
|
}
|
|
1512
|
+
if (config.skillProvider) {
|
|
1513
|
+
session.registerSkillProvider(config.skillProvider);
|
|
1514
|
+
}
|
|
1482
1515
|
const modeDefaults = this.configDefaultsForMode();
|
|
1483
1516
|
config = { ...modeDefaults, ...config };
|
|
1484
1517
|
config.customAgentsLocalOnly ??= modeDefaults.customAgentsLocalOnly;
|
|
@@ -1492,9 +1525,10 @@ class CopilotClient {
|
|
|
1492
1525
|
if (config.onEvent) {
|
|
1493
1526
|
session.on(config.onEvent);
|
|
1494
1527
|
}
|
|
1495
|
-
this.sessions.set(sessionId, session);
|
|
1496
|
-
this.setupSessionFs(session, config);
|
|
1497
1528
|
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
1529
|
+
this.setupSessionFs(session, config);
|
|
1530
|
+
const replacedSession = this.sessions.get(sessionId);
|
|
1531
|
+
this.sessions.set(sessionId, session);
|
|
1498
1532
|
const gitHubTokenProviderRegistrationId = this.registerGitHubTokenProvider(
|
|
1499
1533
|
config.gitHubTokenProvider,
|
|
1500
1534
|
sessionId
|
|
@@ -1587,6 +1621,7 @@ class CopilotClient {
|
|
|
1587
1621
|
defaultAgent: config.defaultAgent,
|
|
1588
1622
|
agent: config.agent,
|
|
1589
1623
|
skillDirectories: config.skillDirectories,
|
|
1624
|
+
...config.skillProvider ? { hasSkillProvider: true } : {},
|
|
1590
1625
|
pluginDirectories: config.pluginDirectories,
|
|
1591
1626
|
instructionDirectories: config.instructionDirectories,
|
|
1592
1627
|
disabledSkills: config.disabledSkills,
|
|
@@ -1631,7 +1666,13 @@ class CopilotClient {
|
|
|
1631
1666
|
this.commitGitHubTokenProvider(sessionId, gitHubTokenProviderRegistrationId);
|
|
1632
1667
|
} catch (e) {
|
|
1633
1668
|
session._markDisconnected();
|
|
1634
|
-
this.sessions.
|
|
1669
|
+
if (this.sessions.get(sessionId) === session) {
|
|
1670
|
+
if (replacedSession) {
|
|
1671
|
+
this.sessions.set(sessionId, replacedSession);
|
|
1672
|
+
} else {
|
|
1673
|
+
this.sessions.delete(sessionId);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1635
1676
|
if (gitHubTokenProviderRegistrationId !== void 0) {
|
|
1636
1677
|
this.githubTokenProviders.delete(gitHubTokenProviderRegistrationId);
|
|
1637
1678
|
}
|
|
@@ -2607,6 +2648,20 @@ stderr: ${stderrOutput}` : ""}`
|
|
|
2607
2648
|
return await this.handleHooksInvoke(params);
|
|
2608
2649
|
}
|
|
2609
2650
|
);
|
|
2651
|
+
this.connection.onRequest(
|
|
2652
|
+
"skillProvider.list",
|
|
2653
|
+
async (params, token) => await this.resolveSkillProviderSession(params)._handleSkillProviderList(token)
|
|
2654
|
+
);
|
|
2655
|
+
this.connection.onRequest(
|
|
2656
|
+
"skillProvider.read",
|
|
2657
|
+
async (params, token) => {
|
|
2658
|
+
const session = this.resolveSkillProviderSession(params);
|
|
2659
|
+
if (typeof params.name !== "string") {
|
|
2660
|
+
throw new Error("Invalid skillProvider.read payload");
|
|
2661
|
+
}
|
|
2662
|
+
return await session._handleSkillProviderRead(params.name, token);
|
|
2663
|
+
}
|
|
2664
|
+
);
|
|
2610
2665
|
const connection = this.connection;
|
|
2611
2666
|
const messageWriter = this.messageWriter;
|
|
2612
2667
|
const cliProcess = this.isExternalServer ? null : this.cliProcess;
|
|
@@ -2763,6 +2818,16 @@ stderr: ${stderrOutput}` : ""}`
|
|
|
2763
2818
|
});
|
|
2764
2819
|
return { response };
|
|
2765
2820
|
}
|
|
2821
|
+
resolveSkillProviderSession(params) {
|
|
2822
|
+
if (!params || typeof params.sessionId !== "string") {
|
|
2823
|
+
throw new Error("Invalid skillProvider payload");
|
|
2824
|
+
}
|
|
2825
|
+
const session = this.sessions.get(params.sessionId);
|
|
2826
|
+
if (!session) {
|
|
2827
|
+
throw new Error(`Session not found: ${params.sessionId}`);
|
|
2828
|
+
}
|
|
2829
|
+
return session;
|
|
2830
|
+
}
|
|
2766
2831
|
async handleHooksInvoke(params) {
|
|
2767
2832
|
if (!params || typeof params.sessionId !== "string" || typeof params.hookType !== "string") {
|
|
2768
2833
|
throw new Error("Invalid hooks invoke payload");
|
package/dist/extension.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { CopilotSession } from "./session.js";
|
|
|
2
2
|
import { type PermissionHandler, type ResumeSessionConfig } from "./types.js";
|
|
3
3
|
import type { WorkflowHandle } from "./workflow.js";
|
|
4
4
|
export { Canvas, CanvasError, createCanvas, type CanvasAction, type CanvasDeclaration, type CanvasHostContext, type CanvasJsonSchema, type CanvasOptions, } from "./canvas.js";
|
|
5
|
-
export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest" | "extensionSdkPath"> & {
|
|
5
|
+
export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest" | "extensionSdkPath" | "skillProvider"> & {
|
|
6
6
|
onPermissionRequest?: PermissionHandler;
|
|
7
7
|
/**
|
|
8
8
|
* Names of sensitive environment variables this extension needs, such as
|
package/dist/extension.js
CHANGED
|
@@ -22,11 +22,13 @@ async function joinSession(config = {}) {
|
|
|
22
22
|
const client = new CopilotClient({ _internalConnection: { kind: "parent-process" } });
|
|
23
23
|
const {
|
|
24
24
|
extensionSdkPath: _stripped,
|
|
25
|
+
skillProvider: _strippedSkillProvider,
|
|
25
26
|
workflows,
|
|
26
27
|
requestedEnvironmentVariables,
|
|
27
28
|
...rest
|
|
28
29
|
} = config;
|
|
29
30
|
void _stripped;
|
|
31
|
+
void _strippedSkillProvider;
|
|
30
32
|
return client.resumeSessionForExtension(
|
|
31
33
|
sessionId,
|
|
32
34
|
{
|