@github/copilot-sdk 1.0.15-unstable.35395657398.gad69ee1 → 1.0.15
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 +56 -4
- package/dist/cjs/cliVersion.js +1 -1
- package/dist/cjs/client.js +37 -6
- package/dist/cjs/copilotRequestHandler.js +156 -20
- package/dist/cjs/extension.js +9 -9
- package/dist/cjs/generated/rpc.js +582 -111
- package/dist/cjs/index.js +7 -7
- package/dist/cjs/installationConfirmation.js +98 -0
- package/dist/cjs/session.js +122 -135
- package/dist/cjs/{factory.js → workflow.js} +33 -33
- package/dist/cliVersion.d.ts +1 -1
- package/dist/cliVersion.js +1 -1
- package/dist/client.d.ts +3 -0
- package/dist/client.js +39 -6
- package/dist/copilotRequestHandler.js +156 -20
- package/dist/extension.d.ts +6 -6
- package/dist/extension.js +9 -9
- package/dist/generated/rpc.d.ts +16537 -12361
- package/dist/generated/rpc.js +582 -111
- package/dist/generated/session-events.d.ts +780 -120
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/installationConfirmation.d.ts +19 -0
- package/dist/installationConfirmation.js +77 -0
- package/dist/session.d.ts +10 -16
- package/dist/session.js +126 -139
- package/dist/types.d.ts +46 -69
- package/dist/workflow.d.ts +367 -0
- package/dist/{factory.js → workflow.js} +25 -25
- package/docs/extensions.md +1 -1
- package/docs/workflows.md +255 -0
- package/package.json +11 -10
- package/dist/factory.d.ts +0 -327
- package/docs/factories.md +0 -296
- package/docs/factory-patterns.md +0 -194
|
@@ -16,26 +16,26 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var
|
|
20
|
-
__export(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
26
|
});
|
|
27
|
-
module.exports = __toCommonJS(
|
|
28
|
-
const
|
|
27
|
+
module.exports = __toCommonJS(workflow_exports);
|
|
28
|
+
const WORKFLOW_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
29
29
|
"completed",
|
|
30
30
|
"halted",
|
|
31
31
|
"paused",
|
|
32
32
|
"cancelled",
|
|
33
33
|
"error"
|
|
34
34
|
]);
|
|
35
|
-
function
|
|
36
|
-
return
|
|
35
|
+
function isWorkflowRunTerminal(status) {
|
|
36
|
+
return WORKFLOW_TERMINAL_STATUSES.has(status);
|
|
37
37
|
}
|
|
38
|
-
const
|
|
38
|
+
const WORKFLOW_AGENT_OPTION_KEYS = [
|
|
39
39
|
"label",
|
|
40
40
|
"schema",
|
|
41
41
|
"model",
|
|
@@ -43,16 +43,16 @@ const FACTORY_AGENT_OPTION_KEYS = [
|
|
|
43
43
|
"contextTier",
|
|
44
44
|
"agent"
|
|
45
45
|
];
|
|
46
|
-
class
|
|
46
|
+
class WorkflowResumeError extends Error {
|
|
47
47
|
constructor(code, message) {
|
|
48
48
|
super(message);
|
|
49
49
|
this.code = code;
|
|
50
|
-
this.name = "
|
|
50
|
+
this.name = "WorkflowResumeError";
|
|
51
51
|
}
|
|
52
52
|
code;
|
|
53
53
|
}
|
|
54
|
-
const
|
|
55
|
-
const
|
|
54
|
+
const workflowHandles = /* @__PURE__ */ new WeakMap();
|
|
55
|
+
const MAX_WORKFLOW_TIMEOUT_SECONDS = 2147483647e-3;
|
|
56
56
|
const NANO_AIU_PER_AIU = 1e9;
|
|
57
57
|
function deepFreeze(value) {
|
|
58
58
|
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
@@ -71,24 +71,24 @@ function validateLimits(meta) {
|
|
|
71
71
|
for (const field of ["maxConcurrentSubagents", "maxTotalSubagents"]) {
|
|
72
72
|
const value = limits[field];
|
|
73
73
|
if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) {
|
|
74
|
-
throw new Error(`
|
|
74
|
+
throw new Error(`Workflow limit "${field}" must be a positive integer`);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
if (limits.timeoutSeconds !== void 0 && (!Number.isFinite(limits.timeoutSeconds) || limits.timeoutSeconds <= 0)) {
|
|
78
78
|
throw new Error(
|
|
79
|
-
'
|
|
79
|
+
'Workflow limit "timeoutSeconds" must be a positive, finite number of seconds'
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
|
-
if (limits.timeoutSeconds !== void 0 && limits.timeoutSeconds >
|
|
82
|
+
if (limits.timeoutSeconds !== void 0 && limits.timeoutSeconds > MAX_WORKFLOW_TIMEOUT_SECONDS) {
|
|
83
83
|
throw new Error(
|
|
84
|
-
`
|
|
84
|
+
`Workflow limit "timeoutSeconds" must not exceed ${MAX_WORKFLOW_TIMEOUT_SECONDS} seconds`
|
|
85
85
|
);
|
|
86
86
|
}
|
|
87
87
|
if (limits.maxAiCredits !== void 0) {
|
|
88
88
|
const maxNanoAiu = Math.round(limits.maxAiCredits * NANO_AIU_PER_AIU);
|
|
89
89
|
if (!Number.isFinite(limits.maxAiCredits) || limits.maxAiCredits <= 0 || !Number.isSafeInteger(maxNanoAiu) || maxNanoAiu < 1) {
|
|
90
90
|
throw new Error(
|
|
91
|
-
'
|
|
91
|
+
'Workflow limit "maxAiCredits" must be a positive, finite number that rounds to a safe positive integer nano-AIU ceiling'
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -97,15 +97,15 @@ function validatePhases(meta) {
|
|
|
97
97
|
const titles = /* @__PURE__ */ new Set();
|
|
98
98
|
for (const phase of meta.phases) {
|
|
99
99
|
if (phase.title.trim().length === 0) {
|
|
100
|
-
throw new Error("
|
|
100
|
+
throw new Error("Workflow phase titles must not be empty");
|
|
101
101
|
}
|
|
102
102
|
if (titles.has(phase.title)) {
|
|
103
|
-
throw new Error(`
|
|
103
|
+
throw new Error(`Workflow phase title "${phase.title}" is declared more than once`);
|
|
104
104
|
}
|
|
105
105
|
titles.add(phase.title);
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
-
function
|
|
108
|
+
function defineWorkflow(definition) {
|
|
109
109
|
const meta = deepFreeze(structuredClone(definition.meta));
|
|
110
110
|
validateLimits(meta);
|
|
111
111
|
validatePhases(meta);
|
|
@@ -114,21 +114,21 @@ function defineFactory(definition) {
|
|
|
114
114
|
run: definition.run
|
|
115
115
|
};
|
|
116
116
|
const handle = Object.freeze({ meta });
|
|
117
|
-
|
|
117
|
+
workflowHandles.set(handle, stored);
|
|
118
118
|
return handle;
|
|
119
119
|
}
|
|
120
|
-
function
|
|
121
|
-
const definition =
|
|
120
|
+
function getWorkflowDefinition(handle) {
|
|
121
|
+
const definition = workflowHandles.get(handle);
|
|
122
122
|
if (!definition) {
|
|
123
|
-
throw new Error("Invalid
|
|
123
|
+
throw new Error("Invalid workflow handle");
|
|
124
124
|
}
|
|
125
125
|
return definition;
|
|
126
126
|
}
|
|
127
127
|
// Annotate the CommonJS export names for ESM import in node:
|
|
128
128
|
0 && (module.exports = {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
WORKFLOW_AGENT_OPTION_KEYS,
|
|
130
|
+
WorkflowResumeError,
|
|
131
|
+
defineWorkflow,
|
|
132
|
+
getWorkflowDefinition,
|
|
133
|
+
isWorkflowRunTerminal
|
|
134
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";
|
|
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,8 @@ 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?;
|
|
46
|
+
private installationConfirmationHandler?;
|
|
44
47
|
private builtinPluginDirectories;
|
|
45
48
|
private onGitHubTelemetry?;
|
|
46
49
|
private clientGlobalHandlers;
|
package/dist/client.js
CHANGED
|
@@ -22,6 +22,9 @@ import { ensureRuntimeBundle } from "./runtimeArtifacts.js";
|
|
|
22
22
|
import { COPILOT_CLI_VERSION } from "./cliVersion.js";
|
|
23
23
|
import { createSessionFsAdapter } from "./sessionFsProvider.js";
|
|
24
24
|
import { createCopilotRequestAdapter } from "./copilotRequestHandler.js";
|
|
25
|
+
import {
|
|
26
|
+
createInstallationConfirmationAdapter
|
|
27
|
+
} from "./installationConfirmation.js";
|
|
25
28
|
import { getTraceContext } from "./telemetry.js";
|
|
26
29
|
import { toJsonSchema } from "./schema.js";
|
|
27
30
|
import { ToolSet } from "./toolSet.js";
|
|
@@ -204,6 +207,7 @@ class CopilotClient {
|
|
|
204
207
|
cliProcess = null;
|
|
205
208
|
ffiHost = null;
|
|
206
209
|
connection = null;
|
|
210
|
+
requestAdapter = null;
|
|
207
211
|
messageWriter = null;
|
|
208
212
|
connectionClosed = false;
|
|
209
213
|
socket = null;
|
|
@@ -241,6 +245,8 @@ class CopilotClient {
|
|
|
241
245
|
/** Connection-level session filesystem config, set via constructor option. */
|
|
242
246
|
sessionFsConfig = null;
|
|
243
247
|
requestHandler = null;
|
|
248
|
+
extensionLaunchProvider;
|
|
249
|
+
installationConfirmationHandler;
|
|
244
250
|
builtinPluginDirectories = [];
|
|
245
251
|
onGitHubTelemetry;
|
|
246
252
|
clientGlobalHandlers = {};
|
|
@@ -398,6 +404,8 @@ class CopilotClient {
|
|
|
398
404
|
this.onGetTraceContext = options.onGetTraceContext;
|
|
399
405
|
this.sessionFsConfig = options.sessionFs ?? null;
|
|
400
406
|
this.requestHandler = options.requestHandler ?? null;
|
|
407
|
+
this.extensionLaunchProvider = options.extensionLaunchProvider;
|
|
408
|
+
this.installationConfirmationHandler = options.installationConfirmationHandler;
|
|
401
409
|
this.onGitHubTelemetry = options.onGitHubTelemetry;
|
|
402
410
|
this.setupClientGlobalHandlers();
|
|
403
411
|
const connEnv = conn.kind === "stdio" || conn.kind === "tcp" ? conn.env : void 0;
|
|
@@ -500,14 +508,16 @@ class CopilotClient {
|
|
|
500
508
|
}
|
|
501
509
|
setupClientGlobalHandlers() {
|
|
502
510
|
const handlers = {};
|
|
511
|
+
handlers.extensionLaunchProvider = this.extensionLaunchProvider;
|
|
503
512
|
if (this.requestHandler) {
|
|
504
|
-
|
|
513
|
+
this.requestAdapter = createCopilotRequestAdapter(this.requestHandler, () => {
|
|
505
514
|
if (!this.connection) {
|
|
506
515
|
return void 0;
|
|
507
516
|
}
|
|
508
517
|
this._rpc ??= createServerRpc(this.connection);
|
|
509
518
|
return this._rpc;
|
|
510
519
|
});
|
|
520
|
+
handlers.llmInference = this.requestAdapter;
|
|
511
521
|
}
|
|
512
522
|
if (this.onGitHubTelemetry) {
|
|
513
523
|
const onGitHubTelemetry = this.onGitHubTelemetry;
|
|
@@ -612,6 +622,9 @@ class CopilotClient {
|
|
|
612
622
|
}
|
|
613
623
|
await this.connectToServer();
|
|
614
624
|
await this.verifyProtocolVersion();
|
|
625
|
+
if (this.extensionLaunchProvider) {
|
|
626
|
+
await this.rpc.registerExtensionLaunchProvider();
|
|
627
|
+
}
|
|
615
628
|
if (this.builtinPluginDirectories.length > 0) {
|
|
616
629
|
try {
|
|
617
630
|
await this.connection.sendRequest("plugins.builtin.set", {
|
|
@@ -700,6 +713,7 @@ class CopilotClient {
|
|
|
700
713
|
}
|
|
701
714
|
this.sessions.clear();
|
|
702
715
|
this.githubTokenProviders.clear();
|
|
716
|
+
this.requestAdapter?.cancelPending();
|
|
703
717
|
if (this.connection && !this.connectionClosed && (this.cliProcess || this.ffiHost) && !this.isExternalServer) {
|
|
704
718
|
const runtimeShutdownStart = Date.now();
|
|
705
719
|
const shutdownPromise = this.rpc.runtime.shutdown();
|
|
@@ -855,6 +869,7 @@ class CopilotClient {
|
|
|
855
869
|
}
|
|
856
870
|
this.sessions.clear();
|
|
857
871
|
this.githubTokenProviders.clear();
|
|
872
|
+
this.requestAdapter?.cancelPending();
|
|
858
873
|
if (this.messageWriter) {
|
|
859
874
|
this.messageWriter.suppressWriteErrors = true;
|
|
860
875
|
}
|
|
@@ -1205,6 +1220,7 @@ class CopilotClient {
|
|
|
1205
1220
|
includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
|
|
1206
1221
|
...this.onGitHubTelemetry != null ? { enableGitHubTelemetryForwarding: true } : {},
|
|
1207
1222
|
mcpServers: toWireMcpServers(config.mcpServers),
|
|
1223
|
+
...config.diagnostics !== void 0 ? { diagnostics: config.diagnostics } : {},
|
|
1208
1224
|
mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
|
|
1209
1225
|
authClientIdMetadataUrl: config.authClientIdMetadataUrl,
|
|
1210
1226
|
envValueMode: "direct",
|
|
@@ -1214,6 +1230,7 @@ class CopilotClient {
|
|
|
1214
1230
|
agent: config.agent,
|
|
1215
1231
|
configDir: config.configDirectory,
|
|
1216
1232
|
enableConfigDiscovery: config.enableConfigDiscovery,
|
|
1233
|
+
refreshCustomInstructions: config.refreshCustomInstructions,
|
|
1217
1234
|
skipEmbeddingRetrieval: config.skipEmbeddingRetrieval,
|
|
1218
1235
|
embeddingCacheStorage: config.embeddingCacheStorage,
|
|
1219
1236
|
organizationCustomInstructions: config.organizationCustomInstructions,
|
|
@@ -1306,10 +1323,11 @@ class CopilotClient {
|
|
|
1306
1323
|
return this.resumeSessionInternal(sessionId, config);
|
|
1307
1324
|
}
|
|
1308
1325
|
/** @internal */
|
|
1309
|
-
async resumeSessionForExtension(sessionId, config,
|
|
1310
|
-
return this.resumeSessionInternal(sessionId, config,
|
|
1326
|
+
async resumeSessionForExtension(sessionId, config, contributions = {}, extensionOptions) {
|
|
1327
|
+
return this.resumeSessionInternal(sessionId, config, contributions, extensionOptions);
|
|
1311
1328
|
}
|
|
1312
|
-
async resumeSessionInternal(sessionId, config,
|
|
1329
|
+
async resumeSessionInternal(sessionId, config, contributions = {}, extensionOptions) {
|
|
1330
|
+
const { workflows } = contributions;
|
|
1313
1331
|
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1314
1332
|
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1315
1333
|
}
|
|
@@ -1329,7 +1347,7 @@ class CopilotClient {
|
|
|
1329
1347
|
session.registerTools(config.tools);
|
|
1330
1348
|
session.registerCanvases(config.canvases);
|
|
1331
1349
|
session.registerCommands(config.commands);
|
|
1332
|
-
session.
|
|
1350
|
+
session.registerWorkflows(workflows);
|
|
1333
1351
|
const {
|
|
1334
1352
|
wireProvider: bearerWireProvider,
|
|
1335
1353
|
wireProviders: bearerWireProviders,
|
|
@@ -1410,7 +1428,7 @@ class CopilotClient {
|
|
|
1410
1428
|
})),
|
|
1411
1429
|
toolSearch: config.toolSearch,
|
|
1412
1430
|
canvases: config.canvases?.map((canvas) => canvas.declaration),
|
|
1413
|
-
|
|
1431
|
+
workflows: workflows?.map((workflow) => workflow.meta),
|
|
1414
1432
|
requestCanvasRenderer: config.requestCanvasRenderer,
|
|
1415
1433
|
requestExtensions: config.requestExtensions,
|
|
1416
1434
|
extensionSdkPath: config.extensionSdkPath,
|
|
@@ -1451,6 +1469,7 @@ class CopilotClient {
|
|
|
1451
1469
|
includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
|
|
1452
1470
|
...this.onGitHubTelemetry != null ? { enableGitHubTelemetryForwarding: true } : {},
|
|
1453
1471
|
mcpServers: toWireMcpServers(config.mcpServers),
|
|
1472
|
+
...config.diagnostics !== void 0 ? { diagnostics: config.diagnostics } : {},
|
|
1454
1473
|
mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
|
|
1455
1474
|
authClientIdMetadataUrl: config.authClientIdMetadataUrl,
|
|
1456
1475
|
envValueMode: "direct",
|
|
@@ -1871,6 +1890,9 @@ class CopilotClient {
|
|
|
1871
1890
|
if (this.options.mode === "empty") {
|
|
1872
1891
|
env.COPILOT_DISABLE_KEYTAR = "1";
|
|
1873
1892
|
}
|
|
1893
|
+
if (this.options.mode !== "empty") {
|
|
1894
|
+
env.COPILOT_RUNTIME_PROCESS_FILE_LOGGING = "1";
|
|
1895
|
+
}
|
|
1874
1896
|
if (this.options.telemetry) {
|
|
1875
1897
|
const t = this.options.telemetry;
|
|
1876
1898
|
env.COPILOT_OTEL_ENABLED = "true";
|
|
@@ -2245,6 +2267,16 @@ stderr: ${stderrOutput}` : ""}`
|
|
|
2245
2267
|
return session.clientSessionApis;
|
|
2246
2268
|
});
|
|
2247
2269
|
registerClientGlobalApiHandlers(this.connection, this.clientGlobalHandlers);
|
|
2270
|
+
if (this.installationConfirmationHandler) {
|
|
2271
|
+
const confirmation = createInstallationConfirmationAdapter(
|
|
2272
|
+
this.connection,
|
|
2273
|
+
this.installationConfirmationHandler
|
|
2274
|
+
);
|
|
2275
|
+
this.connection.onRequest(
|
|
2276
|
+
"installations.confirm",
|
|
2277
|
+
(params, token) => confirmation.confirm(params, token)
|
|
2278
|
+
);
|
|
2279
|
+
}
|
|
2248
2280
|
this.connection.onRequest(
|
|
2249
2281
|
"hooks.invoke",
|
|
2250
2282
|
async (params) => {
|
|
@@ -2263,6 +2295,7 @@ stderr: ${stderrOutput}` : ""}`
|
|
|
2263
2295
|
}
|
|
2264
2296
|
this.sessions.clear();
|
|
2265
2297
|
this.githubTokenProviders.clear();
|
|
2298
|
+
this.requestAdapter?.cancelPending();
|
|
2266
2299
|
};
|
|
2267
2300
|
this.connection.onClose(markDisconnected);
|
|
2268
2301
|
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,6 +1,6 @@
|
|
|
1
1
|
import type { CopilotSession } from "./session.js";
|
|
2
2
|
import { type PermissionHandler, type ResumeSessionConfig } from "./types.js";
|
|
3
|
-
import type {
|
|
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
5
|
export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest" | "extensionSdkPath"> & {
|
|
6
6
|
onPermissionRequest?: PermissionHandler;
|
|
@@ -34,15 +34,15 @@ export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest"
|
|
|
34
34
|
*/
|
|
35
35
|
requestedEnvironmentVariables?: string[];
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* Workflow handles to register when the extension joins the session.
|
|
38
38
|
*
|
|
39
|
-
* @experimental Part of the experimental
|
|
39
|
+
* @experimental Part of the experimental Dynamic Workflows surface and may
|
|
40
40
|
* change or be removed in future SDK or CLI releases.
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
workflows?: WorkflowHandle[];
|
|
43
43
|
};
|
|
44
|
-
export type { ExtensionInfo
|
|
45
|
-
export {
|
|
44
|
+
export type { ExtensionInfo } from "./types.js";
|
|
45
|
+
export { defineWorkflow, WorkflowResumeError, isWorkflowRunTerminal, type WorkflowRunOptions, type WorkflowResumeOptions, type WorkflowLimitOverrides, type WorkflowResumeErrorCode, type SessionWorkflowApi, type WorkflowAgentOptions, type WorkflowContext, type WorkflowDefinition, type WorkflowHandle, type JsonValue, 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
46
|
/**
|
|
47
47
|
* Joins the current foreground session.
|
|
48
48
|
*
|
package/dist/extension.js
CHANGED
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
createCanvas
|
|
9
9
|
} from "./canvas.js";
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from "./
|
|
11
|
+
defineWorkflow,
|
|
12
|
+
WorkflowResumeError,
|
|
13
|
+
isWorkflowRunTerminal
|
|
14
|
+
} from "./workflow.js";
|
|
15
15
|
async function joinSession(config = {}) {
|
|
16
16
|
const sessionId = process.env.SESSION_ID;
|
|
17
17
|
if (!sessionId) {
|
|
@@ -22,7 +22,7 @@ async function joinSession(config = {}) {
|
|
|
22
22
|
const client = new CopilotClient({ _internalConnection: { kind: "parent-process" } });
|
|
23
23
|
const {
|
|
24
24
|
extensionSdkPath: _stripped,
|
|
25
|
-
|
|
25
|
+
workflows,
|
|
26
26
|
requestedEnvironmentVariables,
|
|
27
27
|
...rest
|
|
28
28
|
} = config;
|
|
@@ -34,16 +34,16 @@ async function joinSession(config = {}) {
|
|
|
34
34
|
onPermissionRequest: config.onPermissionRequest ?? defaultJoinSessionPermissionHandler,
|
|
35
35
|
suppressResumeEvent: config.suppressResumeEvent ?? true
|
|
36
36
|
},
|
|
37
|
-
|
|
37
|
+
{ workflows },
|
|
38
38
|
requestedEnvironmentVariables?.length ? { requestedEnvironmentVariables } : void 0
|
|
39
39
|
);
|
|
40
40
|
}
|
|
41
41
|
export {
|
|
42
42
|
Canvas,
|
|
43
43
|
CanvasError,
|
|
44
|
-
|
|
44
|
+
WorkflowResumeError,
|
|
45
45
|
createCanvas,
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
defineWorkflow,
|
|
47
|
+
isWorkflowRunTerminal,
|
|
48
48
|
joinSession
|
|
49
49
|
};
|