@github/copilot-sdk 1.0.14 → 1.0.15-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 +116 -11
- package/dist/cjs/cliVersion.js +1 -1
- package/dist/cjs/client.js +24 -17
- package/dist/cjs/copilotRequestHandler.js +156 -20
- package/dist/cjs/extension.js +12 -1
- package/dist/cjs/generated/rpc.js +349 -8
- package/dist/cjs/index.js +9 -2
- package/dist/cjs/schema.js +40 -0
- package/dist/cjs/session.js +625 -3
- package/dist/cjs/workflow.js +134 -0
- package/dist/cliVersion.d.ts +1 -1
- package/dist/cliVersion.js +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.js +22 -15
- package/dist/copilotRequestHandler.js +156 -20
- package/dist/extension.d.ts +22 -8
- package/dist/extension.js +13 -1
- package/dist/generated/rpc.d.ts +2824 -315
- package/dist/generated/rpc.js +349 -8
- package/dist/generated/session-events.d.ts +565 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +5 -1
- package/dist/schema.d.ts +4 -0
- package/dist/schema.js +14 -0
- package/dist/session.d.ts +26 -3
- package/dist/session.js +630 -3
- package/dist/types.d.ts +37 -5
- package/dist/workflow.d.ts +364 -0
- package/dist/workflow.js +106 -0
- package/docs/extensions.md +1 -0
- package/docs/workflows.md +257 -0
- package/package.json +17 -14
|
@@ -0,0 +1,134 @@
|
|
|
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 workflow_exports = {};
|
|
20
|
+
__export(workflow_exports, {
|
|
21
|
+
WORKFLOW_AGENT_OPTION_KEYS: () => WORKFLOW_AGENT_OPTION_KEYS,
|
|
22
|
+
WorkflowResumeError: () => WorkflowResumeError,
|
|
23
|
+
defineWorkflow: () => defineWorkflow,
|
|
24
|
+
getWorkflowDefinition: () => getWorkflowDefinition,
|
|
25
|
+
isWorkflowRunTerminal: () => isWorkflowRunTerminal
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(workflow_exports);
|
|
28
|
+
const WORKFLOW_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
29
|
+
"completed",
|
|
30
|
+
"halted",
|
|
31
|
+
"paused",
|
|
32
|
+
"cancelled",
|
|
33
|
+
"error"
|
|
34
|
+
]);
|
|
35
|
+
function isWorkflowRunTerminal(status) {
|
|
36
|
+
return WORKFLOW_TERMINAL_STATUSES.has(status);
|
|
37
|
+
}
|
|
38
|
+
const WORKFLOW_AGENT_OPTION_KEYS = [
|
|
39
|
+
"label",
|
|
40
|
+
"schema",
|
|
41
|
+
"model",
|
|
42
|
+
"reasoningEffort",
|
|
43
|
+
"contextTier",
|
|
44
|
+
"agent"
|
|
45
|
+
];
|
|
46
|
+
class WorkflowResumeError extends Error {
|
|
47
|
+
constructor(code, message) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.code = code;
|
|
50
|
+
this.name = "WorkflowResumeError";
|
|
51
|
+
}
|
|
52
|
+
code;
|
|
53
|
+
}
|
|
54
|
+
const workflowHandles = /* @__PURE__ */ new WeakMap();
|
|
55
|
+
const MAX_WORKFLOW_TIMEOUT_SECONDS = 2147483647e-3;
|
|
56
|
+
const NANO_AIU_PER_AIU = 1e9;
|
|
57
|
+
function deepFreeze(value) {
|
|
58
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
59
|
+
Object.freeze(value);
|
|
60
|
+
for (const nested of Object.values(value)) {
|
|
61
|
+
deepFreeze(nested);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
function validateLimits(meta) {
|
|
67
|
+
const limits = meta.limits;
|
|
68
|
+
if (!limits) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
for (const field of ["maxConcurrentSubagents", "maxTotalSubagents"]) {
|
|
72
|
+
const value = limits[field];
|
|
73
|
+
if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) {
|
|
74
|
+
throw new Error(`Workflow limit "${field}" must be a positive integer`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (limits.timeoutSeconds !== void 0 && (!Number.isFinite(limits.timeoutSeconds) || limits.timeoutSeconds <= 0)) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
'Workflow limit "timeoutSeconds" must be a positive, finite number of seconds'
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (limits.timeoutSeconds !== void 0 && limits.timeoutSeconds > MAX_WORKFLOW_TIMEOUT_SECONDS) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`Workflow limit "timeoutSeconds" must not exceed ${MAX_WORKFLOW_TIMEOUT_SECONDS} seconds`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
if (limits.maxAiCredits !== void 0) {
|
|
88
|
+
const maxNanoAiu = Math.round(limits.maxAiCredits * NANO_AIU_PER_AIU);
|
|
89
|
+
if (!Number.isFinite(limits.maxAiCredits) || limits.maxAiCredits <= 0 || !Number.isSafeInteger(maxNanoAiu) || maxNanoAiu < 1) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
'Workflow limit "maxAiCredits" must be a positive, finite number that rounds to a safe positive integer nano-AIU ceiling'
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function validatePhases(meta) {
|
|
97
|
+
const titles = /* @__PURE__ */ new Set();
|
|
98
|
+
for (const phase of meta.phases) {
|
|
99
|
+
if (phase.title.trim().length === 0) {
|
|
100
|
+
throw new Error("Workflow phase titles must not be empty");
|
|
101
|
+
}
|
|
102
|
+
if (titles.has(phase.title)) {
|
|
103
|
+
throw new Error(`Workflow phase title "${phase.title}" is declared more than once`);
|
|
104
|
+
}
|
|
105
|
+
titles.add(phase.title);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function defineWorkflow(definition) {
|
|
109
|
+
const meta = deepFreeze(structuredClone(definition.meta));
|
|
110
|
+
validateLimits(meta);
|
|
111
|
+
validatePhases(meta);
|
|
112
|
+
const stored = {
|
|
113
|
+
meta,
|
|
114
|
+
run: definition.run
|
|
115
|
+
};
|
|
116
|
+
const handle = Object.freeze({ meta });
|
|
117
|
+
workflowHandles.set(handle, stored);
|
|
118
|
+
return handle;
|
|
119
|
+
}
|
|
120
|
+
function getWorkflowDefinition(handle) {
|
|
121
|
+
const definition = workflowHandles.get(handle);
|
|
122
|
+
if (!definition) {
|
|
123
|
+
throw new Error("Invalid workflow handle");
|
|
124
|
+
}
|
|
125
|
+
return definition;
|
|
126
|
+
}
|
|
127
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
128
|
+
0 && (module.exports = {
|
|
129
|
+
WORKFLOW_AGENT_OPTION_KEYS,
|
|
130
|
+
WorkflowResumeError,
|
|
131
|
+
defineWorkflow,
|
|
132
|
+
getWorkflowDefinition,
|
|
133
|
+
isWorkflowRunTerminal
|
|
134
|
+
});
|
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.89-0";
|
|
2
2
|
export declare const COPILOT_CLI_USE_NPM_PACKAGE = false;
|
package/dist/cliVersion.js
CHANGED
package/dist/client.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare class CopilotClient {
|
|
|
6
6
|
private cliProcess;
|
|
7
7
|
private ffiHost;
|
|
8
8
|
private connection;
|
|
9
|
+
private requestAdapter;
|
|
9
10
|
private messageWriter;
|
|
10
11
|
private connectionClosed;
|
|
11
12
|
private socket;
|
|
@@ -41,6 +42,7 @@ export declare class CopilotClient {
|
|
|
41
42
|
/** Connection-level session filesystem config, set via constructor option. */
|
|
42
43
|
private sessionFsConfig;
|
|
43
44
|
private requestHandler;
|
|
45
|
+
private extensionLaunchProvider?;
|
|
44
46
|
private builtinPluginDirectories;
|
|
45
47
|
private onGitHubTelemetry?;
|
|
46
48
|
private clientGlobalHandlers;
|
package/dist/client.js
CHANGED
|
@@ -23,13 +23,11 @@ import { COPILOT_CLI_VERSION } from "./cliVersion.js";
|
|
|
23
23
|
import { createSessionFsAdapter } from "./sessionFsProvider.js";
|
|
24
24
|
import { createCopilotRequestAdapter } from "./copilotRequestHandler.js";
|
|
25
25
|
import { getTraceContext } from "./telemetry.js";
|
|
26
|
+
import { toJsonSchema } from "./schema.js";
|
|
26
27
|
import { ToolSet } from "./toolSet.js";
|
|
27
28
|
import { defaultJoinSessionPermissionHandler } from "./types.js";
|
|
28
29
|
const MIN_PROTOCOL_VERSION = 3;
|
|
29
30
|
const RUNTIME_SHUTDOWN_TIMEOUT_MS = 1e4;
|
|
30
|
-
function isZodSchema(value) {
|
|
31
|
-
return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function";
|
|
32
|
-
}
|
|
33
31
|
async function withTimeout(promise, timeoutMs, message) {
|
|
34
32
|
let timeout;
|
|
35
33
|
try {
|
|
@@ -74,13 +72,6 @@ async function waitForChildExit(child, timeoutMs) {
|
|
|
74
72
|
}
|
|
75
73
|
});
|
|
76
74
|
}
|
|
77
|
-
function toJsonSchema(parameters) {
|
|
78
|
-
if (!parameters) return void 0;
|
|
79
|
-
if (isZodSchema(parameters)) {
|
|
80
|
-
return parameters.toJSONSchema();
|
|
81
|
-
}
|
|
82
|
-
return parameters;
|
|
83
|
-
}
|
|
84
75
|
const DEFAULT_PROVIDER_NAME = "default";
|
|
85
76
|
function extractBearerTokenProviders(provider, providers) {
|
|
86
77
|
const callbacks = /* @__PURE__ */ new Map();
|
|
@@ -213,6 +204,7 @@ class CopilotClient {
|
|
|
213
204
|
cliProcess = null;
|
|
214
205
|
ffiHost = null;
|
|
215
206
|
connection = null;
|
|
207
|
+
requestAdapter = null;
|
|
216
208
|
messageWriter = null;
|
|
217
209
|
connectionClosed = false;
|
|
218
210
|
socket = null;
|
|
@@ -250,6 +242,7 @@ class CopilotClient {
|
|
|
250
242
|
/** Connection-level session filesystem config, set via constructor option. */
|
|
251
243
|
sessionFsConfig = null;
|
|
252
244
|
requestHandler = null;
|
|
245
|
+
extensionLaunchProvider;
|
|
253
246
|
builtinPluginDirectories = [];
|
|
254
247
|
onGitHubTelemetry;
|
|
255
248
|
clientGlobalHandlers = {};
|
|
@@ -407,6 +400,7 @@ class CopilotClient {
|
|
|
407
400
|
this.onGetTraceContext = options.onGetTraceContext;
|
|
408
401
|
this.sessionFsConfig = options.sessionFs ?? null;
|
|
409
402
|
this.requestHandler = options.requestHandler ?? null;
|
|
403
|
+
this.extensionLaunchProvider = options.extensionLaunchProvider;
|
|
410
404
|
this.onGitHubTelemetry = options.onGitHubTelemetry;
|
|
411
405
|
this.setupClientGlobalHandlers();
|
|
412
406
|
const connEnv = conn.kind === "stdio" || conn.kind === "tcp" ? conn.env : void 0;
|
|
@@ -509,14 +503,16 @@ class CopilotClient {
|
|
|
509
503
|
}
|
|
510
504
|
setupClientGlobalHandlers() {
|
|
511
505
|
const handlers = {};
|
|
506
|
+
handlers.extensionLaunchProvider = this.extensionLaunchProvider;
|
|
512
507
|
if (this.requestHandler) {
|
|
513
|
-
|
|
508
|
+
this.requestAdapter = createCopilotRequestAdapter(this.requestHandler, () => {
|
|
514
509
|
if (!this.connection) {
|
|
515
510
|
return void 0;
|
|
516
511
|
}
|
|
517
512
|
this._rpc ??= createServerRpc(this.connection);
|
|
518
513
|
return this._rpc;
|
|
519
514
|
});
|
|
515
|
+
handlers.llmInference = this.requestAdapter;
|
|
520
516
|
}
|
|
521
517
|
if (this.onGitHubTelemetry) {
|
|
522
518
|
const onGitHubTelemetry = this.onGitHubTelemetry;
|
|
@@ -621,6 +617,9 @@ class CopilotClient {
|
|
|
621
617
|
}
|
|
622
618
|
await this.connectToServer();
|
|
623
619
|
await this.verifyProtocolVersion();
|
|
620
|
+
if (this.extensionLaunchProvider) {
|
|
621
|
+
await this.rpc.registerExtensionLaunchProvider();
|
|
622
|
+
}
|
|
624
623
|
if (this.builtinPluginDirectories.length > 0) {
|
|
625
624
|
try {
|
|
626
625
|
await this.connection.sendRequest("plugins.builtin.set", {
|
|
@@ -709,6 +708,7 @@ class CopilotClient {
|
|
|
709
708
|
}
|
|
710
709
|
this.sessions.clear();
|
|
711
710
|
this.githubTokenProviders.clear();
|
|
711
|
+
this.requestAdapter?.cancelPending();
|
|
712
712
|
if (this.connection && !this.connectionClosed && (this.cliProcess || this.ffiHost) && !this.isExternalServer) {
|
|
713
713
|
const runtimeShutdownStart = Date.now();
|
|
714
714
|
const shutdownPromise = this.rpc.runtime.shutdown();
|
|
@@ -864,6 +864,7 @@ class CopilotClient {
|
|
|
864
864
|
}
|
|
865
865
|
this.sessions.clear();
|
|
866
866
|
this.githubTokenProviders.clear();
|
|
867
|
+
this.requestAdapter?.cancelPending();
|
|
867
868
|
if (this.messageWriter) {
|
|
868
869
|
this.messageWriter.suppressWriteErrors = true;
|
|
869
870
|
}
|
|
@@ -1314,11 +1315,14 @@ class CopilotClient {
|
|
|
1314
1315
|
async resumeSession(sessionId, config) {
|
|
1315
1316
|
return this.resumeSessionInternal(sessionId, config);
|
|
1316
1317
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
return this.resumeSessionInternal(sessionId, config, factories, extensionOptions);
|
|
1318
|
+
async resumeSessionForExtension(sessionId, config, contributions = {}, extensionOptions) {
|
|
1319
|
+
return this.resumeSessionInternal(sessionId, config, contributions, extensionOptions);
|
|
1320
1320
|
}
|
|
1321
|
-
async resumeSessionInternal(sessionId, config,
|
|
1321
|
+
async resumeSessionInternal(sessionId, config, contributions = {}, extensionOptions) {
|
|
1322
|
+
const { factories, workflows } = Array.isArray(contributions) ? { factories: contributions, workflows: void 0 } : contributions;
|
|
1323
|
+
if (factories !== void 0 && workflows !== void 0) {
|
|
1324
|
+
throw new Error("Session configuration cannot include both factories and workflows");
|
|
1325
|
+
}
|
|
1322
1326
|
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1323
1327
|
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1324
1328
|
}
|
|
@@ -1339,6 +1343,7 @@ class CopilotClient {
|
|
|
1339
1343
|
session.registerCanvases(config.canvases);
|
|
1340
1344
|
session.registerCommands(config.commands);
|
|
1341
1345
|
session.registerFactories(factories);
|
|
1346
|
+
session.registerWorkflows(workflows);
|
|
1342
1347
|
const {
|
|
1343
1348
|
wireProvider: bearerWireProvider,
|
|
1344
1349
|
wireProviders: bearerWireProviders,
|
|
@@ -1420,6 +1425,7 @@ class CopilotClient {
|
|
|
1420
1425
|
toolSearch: config.toolSearch,
|
|
1421
1426
|
canvases: config.canvases?.map((canvas) => canvas.declaration),
|
|
1422
1427
|
factories: factories?.map((factory) => factory.meta),
|
|
1428
|
+
workflows: workflows?.map((workflow) => workflow.meta),
|
|
1423
1429
|
requestCanvasRenderer: config.requestCanvasRenderer,
|
|
1424
1430
|
requestExtensions: config.requestExtensions,
|
|
1425
1431
|
extensionSdkPath: config.extensionSdkPath,
|
|
@@ -2272,6 +2278,7 @@ stderr: ${stderrOutput}` : ""}`
|
|
|
2272
2278
|
}
|
|
2273
2279
|
this.sessions.clear();
|
|
2274
2280
|
this.githubTokenProviders.clear();
|
|
2281
|
+
this.requestAdapter?.cancelPending();
|
|
2275
2282
|
};
|
|
2276
2283
|
this.connection.onClose(markDisconnected);
|
|
2277
2284
|
this.connection.onError(() => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const sharedTextDecoder = new TextDecoder("utf-8", { fatal: false });
|
|
2
2
|
const sharedTextEncoder = new TextEncoder();
|
|
3
|
+
const HTTP_RESPONSE_READ_AHEAD_BYTES = 32 * 1024;
|
|
3
4
|
const kBridge = /* @__PURE__ */ Symbol("copilotWebSocketResponseBridge");
|
|
4
5
|
const kCompletion = /* @__PURE__ */ Symbol("copilotWebSocketCompletion");
|
|
5
6
|
const kOpen = /* @__PURE__ */ Symbol("copilotWebSocketOpen");
|
|
@@ -238,7 +239,9 @@ function createCopilotRequestAdapter(handler, getServerRpc) {
|
|
|
238
239
|
const message = err instanceof Error ? err.message : String(err);
|
|
239
240
|
await finalize(exchange, 502, message);
|
|
240
241
|
} finally {
|
|
241
|
-
pending.
|
|
242
|
+
if (pending.get(exchange.requestId) === exchange) {
|
|
243
|
+
pending.delete(exchange.requestId);
|
|
244
|
+
}
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
247
|
return {
|
|
@@ -251,6 +254,13 @@ function createCopilotRequestAdapter(handler, getServerRpc) {
|
|
|
251
254
|
async httpRequestChunk(params) {
|
|
252
255
|
routeChunk(getOrCreate(params.requestId), params);
|
|
253
256
|
return {};
|
|
257
|
+
},
|
|
258
|
+
cancelPending() {
|
|
259
|
+
const exchanges = [...pending.values()];
|
|
260
|
+
pending.clear();
|
|
261
|
+
for (const exchange of exchanges) {
|
|
262
|
+
exchange.pushCancel("RPC connection closed");
|
|
263
|
+
}
|
|
254
264
|
}
|
|
255
265
|
};
|
|
256
266
|
}
|
|
@@ -499,30 +509,156 @@ async function drainAsync(stream) {
|
|
|
499
509
|
return out;
|
|
500
510
|
}
|
|
501
511
|
async function streamResponse(response, exchange) {
|
|
502
|
-
|
|
503
|
-
status: response.status,
|
|
504
|
-
statusText: response.statusText || void 0,
|
|
505
|
-
headers: headersToMultiMap(response.headers)
|
|
506
|
-
});
|
|
507
|
-
const body = response.body;
|
|
508
|
-
if (!body) {
|
|
509
|
-
await exchange.endResponse();
|
|
510
|
-
return;
|
|
511
|
-
}
|
|
512
|
-
const reader = body.getReader();
|
|
512
|
+
const reader = response.body ? new HttpResponseReader(response.body, exchange.signal) : void 0;
|
|
513
513
|
try {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
514
|
+
await exchange.startResponse({
|
|
515
|
+
status: response.status,
|
|
516
|
+
statusText: response.statusText || void 0,
|
|
517
|
+
headers: headersToMultiMap(response.headers)
|
|
518
|
+
});
|
|
519
|
+
if (reader) {
|
|
520
|
+
for (; ; ) {
|
|
521
|
+
const chunk = await reader.nextChunk();
|
|
522
|
+
if (!chunk) {
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
await exchange.writeResponse(chunk);
|
|
521
526
|
}
|
|
522
527
|
}
|
|
523
528
|
await exchange.endResponse();
|
|
524
529
|
} finally {
|
|
525
|
-
reader
|
|
530
|
+
await reader?.dispose();
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
class HttpResponseReader {
|
|
534
|
+
#reader;
|
|
535
|
+
#signal;
|
|
536
|
+
#frames = [];
|
|
537
|
+
#pump;
|
|
538
|
+
#onAbort;
|
|
539
|
+
#queued = 0;
|
|
540
|
+
#done = false;
|
|
541
|
+
#cancelled = false;
|
|
542
|
+
#hasError = false;
|
|
543
|
+
#error;
|
|
544
|
+
#dataWaker;
|
|
545
|
+
#spaceWaker;
|
|
546
|
+
#cancelPromise;
|
|
547
|
+
constructor(body, signal) {
|
|
548
|
+
this.#reader = body.getReader();
|
|
549
|
+
this.#signal = signal;
|
|
550
|
+
this.#onAbort = () => {
|
|
551
|
+
void this.cancel(signal.reason);
|
|
552
|
+
};
|
|
553
|
+
signal.addEventListener("abort", this.#onAbort, { once: true });
|
|
554
|
+
this.#pump = this.#pumpSource();
|
|
555
|
+
if (signal.aborted) {
|
|
556
|
+
this.#onAbort();
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
async nextChunk() {
|
|
560
|
+
while (this.#frames.length === 0 && !this.#done && !this.#hasError) {
|
|
561
|
+
await new Promise((resolve) => {
|
|
562
|
+
this.#dataWaker = resolve;
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
if (this.#frames.length > 0) {
|
|
566
|
+
const chunk = this.#takeQueued();
|
|
567
|
+
this.#wakeSpace();
|
|
568
|
+
return chunk;
|
|
569
|
+
}
|
|
570
|
+
if (this.#hasError) {
|
|
571
|
+
this.#hasError = false;
|
|
572
|
+
throw this.#error;
|
|
573
|
+
}
|
|
574
|
+
return void 0;
|
|
575
|
+
}
|
|
576
|
+
#takeQueued() {
|
|
577
|
+
const frames = this.#frames;
|
|
578
|
+
const total = this.#queued;
|
|
579
|
+
this.#queued = 0;
|
|
580
|
+
if (frames.length === 1) {
|
|
581
|
+
return frames.pop();
|
|
582
|
+
}
|
|
583
|
+
const chunk = new Uint8Array(total);
|
|
584
|
+
let offset = 0;
|
|
585
|
+
for (const frame of frames) {
|
|
586
|
+
chunk.set(frame, offset);
|
|
587
|
+
offset += frame.byteLength;
|
|
588
|
+
}
|
|
589
|
+
frames.length = 0;
|
|
590
|
+
return chunk;
|
|
591
|
+
}
|
|
592
|
+
async dispose() {
|
|
593
|
+
this.#signal.removeEventListener("abort", this.#onAbort);
|
|
594
|
+
if (!this.#done) {
|
|
595
|
+
await this.cancel();
|
|
596
|
+
} else if (this.#cancelPromise) {
|
|
597
|
+
await this.#cancelPromise;
|
|
598
|
+
}
|
|
599
|
+
await this.#pump;
|
|
600
|
+
}
|
|
601
|
+
cancel(reason) {
|
|
602
|
+
if (this.#done) {
|
|
603
|
+
return Promise.resolve();
|
|
604
|
+
}
|
|
605
|
+
if (!this.#cancelPromise) {
|
|
606
|
+
this.#cancelled = true;
|
|
607
|
+
this.#done = true;
|
|
608
|
+
this.#hasError = true;
|
|
609
|
+
this.#error = reason instanceof Error ? reason : new Error("HTTP response body cancelled.");
|
|
610
|
+
this.#frames.length = 0;
|
|
611
|
+
this.#queued = 0;
|
|
612
|
+
this.#wakeData();
|
|
613
|
+
this.#wakeSpace();
|
|
614
|
+
this.#cancelPromise = this.#reader.cancel(reason).catch(() => void 0);
|
|
615
|
+
}
|
|
616
|
+
return this.#cancelPromise;
|
|
617
|
+
}
|
|
618
|
+
async #pumpSource() {
|
|
619
|
+
try {
|
|
620
|
+
while (!this.#cancelled) {
|
|
621
|
+
while (this.#queued >= HTTP_RESPONSE_READ_AHEAD_BYTES && !this.#cancelled) {
|
|
622
|
+
await new Promise((resolve) => {
|
|
623
|
+
this.#spaceWaker = resolve;
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
if (this.#cancelled) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
const { value, done } = await this.#reader.read();
|
|
630
|
+
if (done) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
if (value.byteLength > 0) {
|
|
634
|
+
this.#frames.push(value);
|
|
635
|
+
this.#queued += value.byteLength;
|
|
636
|
+
this.#wakeData();
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
640
|
+
}
|
|
641
|
+
} catch (error) {
|
|
642
|
+
if (!this.#cancelled) {
|
|
643
|
+
this.#hasError = true;
|
|
644
|
+
this.#error = error;
|
|
645
|
+
}
|
|
646
|
+
} finally {
|
|
647
|
+
this.#done = true;
|
|
648
|
+
this.#wakeData();
|
|
649
|
+
this.#wakeSpace();
|
|
650
|
+
this.#reader.releaseLock();
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
#wakeData() {
|
|
654
|
+
const waker = this.#dataWaker;
|
|
655
|
+
this.#dataWaker = void 0;
|
|
656
|
+
waker?.();
|
|
657
|
+
}
|
|
658
|
+
#wakeSpace() {
|
|
659
|
+
const waker = this.#spaceWaker;
|
|
660
|
+
this.#spaceWaker = void 0;
|
|
661
|
+
waker?.();
|
|
526
662
|
}
|
|
527
663
|
}
|
|
528
664
|
function headersToMultiMap(headers) {
|
package/dist/extension.d.ts
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
import type { CopilotSession } from "./session.js";
|
|
2
2
|
import { type PermissionHandler, type ResumeSessionConfig } from "./types.js";
|
|
3
3
|
import type { FactoryHandle } from "./factory.js";
|
|
4
|
+
import type { WorkflowHandle } from "./workflow.js";
|
|
4
5
|
export { Canvas, CanvasError, createCanvas, type CanvasAction, type CanvasDeclaration, type CanvasHostContext, type CanvasJsonSchema, type CanvasOptions, } from "./canvas.js";
|
|
6
|
+
type JoinSessionContributionConfig = {
|
|
7
|
+
/**
|
|
8
|
+
* Factory handles to register when the extension joins the session.
|
|
9
|
+
*
|
|
10
|
+
* @experimental Part of the experimental Agent Factories surface and may
|
|
11
|
+
* change or be removed in future SDK or CLI releases.
|
|
12
|
+
*/
|
|
13
|
+
factories?: FactoryHandle[];
|
|
14
|
+
workflows?: never;
|
|
15
|
+
} | {
|
|
16
|
+
factories?: never;
|
|
17
|
+
/**
|
|
18
|
+
* Workflow handles to register when the extension joins the session.
|
|
19
|
+
*
|
|
20
|
+
* @experimental Part of the experimental Dynamic Workflows surface and may
|
|
21
|
+
* change or be removed in future SDK or CLI releases.
|
|
22
|
+
*/
|
|
23
|
+
workflows?: WorkflowHandle[];
|
|
24
|
+
};
|
|
5
25
|
export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest" | "extensionSdkPath"> & {
|
|
6
26
|
onPermissionRequest?: PermissionHandler;
|
|
7
27
|
/**
|
|
@@ -33,16 +53,10 @@ export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest"
|
|
|
33
53
|
* ```
|
|
34
54
|
*/
|
|
35
55
|
requestedEnvironmentVariables?: string[];
|
|
36
|
-
|
|
37
|
-
* Factory handles to register when the extension joins the session.
|
|
38
|
-
*
|
|
39
|
-
* @experimental Part of the experimental Agent Factories surface and may
|
|
40
|
-
* change or be removed in future SDK or CLI releases.
|
|
41
|
-
*/
|
|
42
|
-
factories?: FactoryHandle[];
|
|
43
|
-
};
|
|
56
|
+
} & JoinSessionContributionConfig;
|
|
44
57
|
export type { ExtensionInfo, FactoryLimits, FactoryMeta } from "./types.js";
|
|
45
58
|
export { defineFactory, FactoryResumeError, isFactoryRunTerminal, type RunOptions, type ResumeOptions, type FactoryResumeErrorCode, type SessionFactoryApi, type FactoryAgentOptions, type FactoryContext, type FactoryDefinition, type FactoryHandle, type FactoryJsonSchema, type JsonValue, type FactoryPipelineStage, type FactoryStepOptions, type FactoryRunResult, type FactoryRunStatus, type FactoryRunSummary, type FactoryListRunsOptions, type FactoryRunsPage, type FactoryRunDetail, type FactoryProgressPage, type FactoryProgressLine, type FactoryPhaseObservation, type FactoryPhaseStatus, type FactoryAgentSummary, } from "./factory.js";
|
|
59
|
+
export { defineWorkflow, WorkflowResumeError, isWorkflowRunTerminal, type WorkflowRunOptions, type WorkflowResumeOptions, type WorkflowLimitOverrides, type WorkflowResumeErrorCode, type SessionWorkflowApi, type WorkflowAgentOptions, type WorkflowContext, type WorkflowDefinition, type WorkflowHandle, type WorkflowJsonSchema, type WorkflowLimits, type WorkflowMeta, type WorkflowPipelineStage, type WorkflowStepOptions, type WorkflowRunResult, type WorkflowRunStatus, type WorkflowRunSummary, type WorkflowListRunsOptions, type WorkflowRunsPage, type WorkflowRunDetail, type WorkflowProgressPage, type WorkflowProgressLine, type WorkflowPhaseObservation, type WorkflowPhaseStatus, type WorkflowAgentSummary, } from "./workflow.js";
|
|
46
60
|
/**
|
|
47
61
|
* Joins the current foreground session.
|
|
48
62
|
*
|
package/dist/extension.js
CHANGED
|
@@ -12,6 +12,11 @@ import {
|
|
|
12
12
|
FactoryResumeError,
|
|
13
13
|
isFactoryRunTerminal
|
|
14
14
|
} from "./factory.js";
|
|
15
|
+
import {
|
|
16
|
+
defineWorkflow,
|
|
17
|
+
WorkflowResumeError,
|
|
18
|
+
isWorkflowRunTerminal
|
|
19
|
+
} from "./workflow.js";
|
|
15
20
|
async function joinSession(config = {}) {
|
|
16
21
|
const sessionId = process.env.SESSION_ID;
|
|
17
22
|
if (!sessionId) {
|
|
@@ -23,10 +28,14 @@ async function joinSession(config = {}) {
|
|
|
23
28
|
const {
|
|
24
29
|
extensionSdkPath: _stripped,
|
|
25
30
|
factories,
|
|
31
|
+
workflows,
|
|
26
32
|
requestedEnvironmentVariables,
|
|
27
33
|
...rest
|
|
28
34
|
} = config;
|
|
29
35
|
void _stripped;
|
|
36
|
+
if (factories !== void 0 && workflows !== void 0) {
|
|
37
|
+
throw new Error("joinSession cannot register both factories and workflows");
|
|
38
|
+
}
|
|
30
39
|
return client.resumeSessionForExtension(
|
|
31
40
|
sessionId,
|
|
32
41
|
{
|
|
@@ -34,7 +43,7 @@ async function joinSession(config = {}) {
|
|
|
34
43
|
onPermissionRequest: config.onPermissionRequest ?? defaultJoinSessionPermissionHandler,
|
|
35
44
|
suppressResumeEvent: config.suppressResumeEvent ?? true
|
|
36
45
|
},
|
|
37
|
-
factories,
|
|
46
|
+
{ factories, workflows },
|
|
38
47
|
requestedEnvironmentVariables?.length ? { requestedEnvironmentVariables } : void 0
|
|
39
48
|
);
|
|
40
49
|
}
|
|
@@ -42,8 +51,11 @@ export {
|
|
|
42
51
|
Canvas,
|
|
43
52
|
CanvasError,
|
|
44
53
|
FactoryResumeError,
|
|
54
|
+
WorkflowResumeError,
|
|
45
55
|
createCanvas,
|
|
46
56
|
defineFactory,
|
|
57
|
+
defineWorkflow,
|
|
47
58
|
isFactoryRunTerminal,
|
|
59
|
+
isWorkflowRunTerminal,
|
|
48
60
|
joinSession
|
|
49
61
|
};
|