@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
package/README.md
CHANGED
|
@@ -14,10 +14,9 @@ verified `github/copilot-cli` release assets when the SDK is published, so
|
|
|
14
14
|
starting the SDK performs no runtime download. Set `COPILOT_CLI_PATH` to use an
|
|
15
15
|
existing installation instead.
|
|
16
16
|
|
|
17
|
-
The checked-in
|
|
18
|
-
`
|
|
19
|
-
|
|
20
|
-
release's `SHA256SUMS.txt`.
|
|
17
|
+
The checked-in `copilotCliVersion` in `package.json` and compiled metadata in
|
|
18
|
+
`src/cliVersion.ts` use a development placeholder. The public SDK snapshot
|
|
19
|
+
replaces both with the CLI version published for that snapshot.
|
|
21
20
|
|
|
22
21
|
`npm run pack:release` builds the main package and all platform packages. Set
|
|
23
22
|
`COPILOT_CLI_DOWNLOAD_BASE_URL` to use a release mirror while packaging.
|
|
@@ -26,6 +25,12 @@ containing validated runtime npm package roots named for all eight platforms.
|
|
|
26
25
|
This keeps `COPILOT_CLI_USE_NPM_PACKAGE` false and embeds those runtime files in
|
|
27
26
|
the self-contained SDK platform packages.
|
|
28
27
|
|
|
28
|
+
In the runtime repository, packaging uses the prepared same-checkout runtime.
|
|
29
|
+
Set `COPILOT_SDK_RUNTIME_PLATFORMS` to the available target (for example,
|
|
30
|
+
`linux-x64`) for both `pack:release` and `verify:release-packages`. SDK CI checks
|
|
31
|
+
that target only; public release workflows leave this unset to package and
|
|
32
|
+
verify all eight platforms.
|
|
33
|
+
|
|
29
34
|
## Installation
|
|
30
35
|
|
|
31
36
|
```bash
|
|
@@ -118,6 +123,8 @@ new CopilotClient(options?: CopilotClientOptions)
|
|
|
118
123
|
- `mode?: "empty" | "copilot-cli"` - Defaulting strategy. Use `"empty"` for multi-user server mode; defaults to `"copilot-cli"`.
|
|
119
124
|
- `workingDirectory?: string` - Working directory for the runtime process (default: current process cwd).
|
|
120
125
|
- `baseDirectory?: string` - Base directory for Copilot data (session state, config, etc.). Sets `COPILOT_HOME` on the spawned runtime. When not set, the runtime defaults to `~/.copilot`. Ignored when connecting via `RuntimeConnection.forUri`.
|
|
126
|
+
- `extensionLaunchProvider?: ExtensionLaunchProvider` - Experimental connection-level resolver for extension launch profiles. The client installs the reverse-RPC handler and registers the provider during startup before sessions can be created.
|
|
127
|
+
- `installationConfirmationHandler?: InstallationConfirmationHandler` - Experimental connection-global human review for `installations.confirm`. Receives the typed request and independent request/connection cancellation signals, and returns an explicit decision. Does not enable installation capabilities.
|
|
121
128
|
- `logLevel?: "none" | "error" | "warning" | "info" | "debug" | "all"` - Log level. When omitted, the runtime uses its own default (currently `"info"`).
|
|
122
129
|
- `env?: Record<string, string | undefined>` - Environment variables for the runtime process. When omitted, inherits `process.env`.
|
|
123
130
|
- `gitHubToken?: string` - GitHub token for authentication. When provided, takes priority over other auth methods.
|
|
@@ -129,6 +136,49 @@ new CopilotClient(options?: CopilotClientOptions)
|
|
|
129
136
|
- `sessionIdleTimeoutSeconds?: number` - Server-wide idle timeout for sessions in seconds. Ignored when connecting via `RuntimeConnection.forUri`.
|
|
130
137
|
- `enableRemoteSessions?: boolean` - Enable Mission Control remote session support. Ignored when connecting via `RuntimeConnection.forUri`.
|
|
131
138
|
|
|
139
|
+
#### Installation confirmation (experimental)
|
|
140
|
+
|
|
141
|
+
All six SDKs (Node.js, Python, Go, .NET, Java and Rust) provide this receiver with the
|
|
142
|
+
same semantics: each review gets one cancellation token, concurrent reviews are
|
|
143
|
+
independent, and a decision returned after cancellation is never sent. Without a
|
|
144
|
+
configured handler, an `installations.confirm` request is refused, which the
|
|
145
|
+
runtime treats as no consent.
|
|
146
|
+
|
|
147
|
+
The installation confirmation handler receives the generated
|
|
148
|
+
`InstallationConfirmationRequest` and a `CancellationToken`. Match `operationId`
|
|
149
|
+
and `policySessionId` against the exact original action on this connection
|
|
150
|
+
before presenting the complete review. Refuse unknown operations or incomplete
|
|
151
|
+
reviews; missing legacy session metadata is not permission to use the current
|
|
152
|
+
session. Return `"confirm"`, `"decline"` or `"cancel"` only after an explicit
|
|
153
|
+
human decision. The SDK echoes the original challenge and fingerprint.
|
|
154
|
+
|
|
155
|
+
Concurrent reviews remain independent. The token is cancelled when the runtime
|
|
156
|
+
retires the request, including runtime-enforced expiry, or when the original
|
|
157
|
+
connection closes. Observe it to close pending UI. Late handler results cannot
|
|
158
|
+
approve a retired request. This incoming signal does not cancel outbound
|
|
159
|
+
installation or OAuth RPCs, and dropping those promises is not cancellation.
|
|
160
|
+
|
|
161
|
+
Use `client.rpc.mcp.prepareInstall` before `applyInstall`: preparation returns an
|
|
162
|
+
inert runtime-issued `operationId` and original expiry. Register that ID with its
|
|
163
|
+
captured session on this exact client before applying. Removal uses
|
|
164
|
+
`planUninstall` then `applyUninstall`; the returned `operationId` identifies the
|
|
165
|
+
operation, while `planHandle` is the one-use removal input. Never interchange them.
|
|
166
|
+
Use `client.rpc.mcp.installations.list` and `recover` for owned inventory.
|
|
167
|
+
Inspect or cancel uncertain work through `status` and `cancel` on the original
|
|
168
|
+
connection and operation ID, without selecting a replacement session or replaying apply.
|
|
169
|
+
|
|
170
|
+
Owned OAuth similarly uses `session.rpc.mcp.oauth.prepareLogin` to obtain
|
|
171
|
+
`loginId` before browser, network or cached-reconnect work. Retain that ID with
|
|
172
|
+
the original session and `expectedInstallationId` for `login` and `cancelLogin`.
|
|
173
|
+
Prepare freezes reauthentication and display options. Cancelling an incoming
|
|
174
|
+
confirmation or abandoning a login promise is not a substitute for `cancelLogin`.
|
|
175
|
+
Manual MCP OAuth retains its direct `login` path.
|
|
176
|
+
|
|
177
|
+
A matching runtime contract and available owned-lifecycle support are required.
|
|
178
|
+
Capability negotiation does not promise availability; preserve typed refusals
|
|
179
|
+
instead of falling back to raw configuration writes. Generated presence and
|
|
180
|
+
transport tests do not establish a working installer, live OAuth or restart safety.
|
|
181
|
+
|
|
132
182
|
#### Methods
|
|
133
183
|
|
|
134
184
|
##### `start(): Promise<void>`
|
|
@@ -157,6 +207,7 @@ Create a new conversation session.
|
|
|
157
207
|
- `systemMessage?: SystemMessageConfig` - System message customization (see below)
|
|
158
208
|
- `infiniteSessions?: InfiniteSessionConfig` - Configure automatic context compaction (see below)
|
|
159
209
|
- `workingDirectory?: string` - Working directory for the session (default: runtime process cwd).
|
|
210
|
+
- `refreshCustomInstructions?: boolean` - Invalidates the process-wide custom-instruction discovery cache before creating this session, so instruction-file edits made in the same runtime are read again. Defaults to `false` (cache reuse). Other sessions in this runtime may observe updated instructions on later turns or discovery. This does not watch files or enable disabled instruction loading. Available on `SessionConfig`, not `ResumeSessionConfig`.
|
|
160
211
|
- `enableSessionStore?: boolean` - Enables the cross-session store for search and retrieval across sessions. When unset in `"copilot-cli"` mode, the runtime default applies (enabled). In `"empty"` mode, defaults to disabled.
|
|
161
212
|
- `gitHubTokenProvider?: GitHubTokenProvider` - Acquires rotating, session-scoped GitHub tokens. Token results require a positive `expiresIn` value in seconds remaining when the callback completes; production tokens typically last eight hours. Cannot be combined with `gitHubToken`.
|
|
162
213
|
- `provider?: ProviderConfig` - Custom API provider configuration (BYOK - Bring Your Own Key). See [Custom Providers](#custom-providers) section.
|
|
@@ -294,6 +345,7 @@ Source is independent of delivery mode. Leaving it unset preserves the existing
|
|
|
294
345
|
##### `sendAndWait(options: MessageOptions, timeout?: number): Promise<AssistantMessageEvent | undefined>`
|
|
295
346
|
|
|
296
347
|
Send a message and wait until the session becomes idle.
|
|
348
|
+
Sub-agent events are still delivered to listeners, but do not complete the wait or supply its reply.
|
|
297
349
|
|
|
298
350
|
**Options:**
|
|
299
351
|
|
package/dist/cjs/cliVersion.js
CHANGED
|
@@ -22,7 +22,7 @@ __export(cliVersion_exports, {
|
|
|
22
22
|
COPILOT_CLI_VERSION: () => COPILOT_CLI_VERSION
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(cliVersion_exports);
|
|
25
|
-
const COPILOT_CLI_VERSION = "1.0.
|
|
25
|
+
const COPILOT_CLI_VERSION = "1.0.89";
|
|
26
26
|
const COPILOT_CLI_USE_NPM_PACKAGE = false;
|
|
27
27
|
// Annotate the CommonJS export names for ESM import in node:
|
|
28
28
|
0 && (module.exports = {
|
package/dist/cjs/client.js
CHANGED
|
@@ -44,6 +44,7 @@ var import_runtimeArtifacts = require("./runtimeArtifacts.js");
|
|
|
44
44
|
var import_cliVersion = require("./cliVersion.js");
|
|
45
45
|
var import_sessionFsProvider = require("./sessionFsProvider.js");
|
|
46
46
|
var import_copilotRequestHandler = require("./copilotRequestHandler.js");
|
|
47
|
+
var import_installationConfirmation = require("./installationConfirmation.js");
|
|
47
48
|
var import_telemetry = require("./telemetry.js");
|
|
48
49
|
var import_schema = require("./schema.js");
|
|
49
50
|
var import_toolSet = require("./toolSet.js");
|
|
@@ -226,6 +227,7 @@ class CopilotClient {
|
|
|
226
227
|
cliProcess = null;
|
|
227
228
|
ffiHost = null;
|
|
228
229
|
connection = null;
|
|
230
|
+
requestAdapter = null;
|
|
229
231
|
messageWriter = null;
|
|
230
232
|
connectionClosed = false;
|
|
231
233
|
socket = null;
|
|
@@ -263,6 +265,8 @@ class CopilotClient {
|
|
|
263
265
|
/** Connection-level session filesystem config, set via constructor option. */
|
|
264
266
|
sessionFsConfig = null;
|
|
265
267
|
requestHandler = null;
|
|
268
|
+
extensionLaunchProvider;
|
|
269
|
+
installationConfirmationHandler;
|
|
266
270
|
builtinPluginDirectories = [];
|
|
267
271
|
onGitHubTelemetry;
|
|
268
272
|
clientGlobalHandlers = {};
|
|
@@ -420,6 +424,8 @@ class CopilotClient {
|
|
|
420
424
|
this.onGetTraceContext = options.onGetTraceContext;
|
|
421
425
|
this.sessionFsConfig = options.sessionFs ?? null;
|
|
422
426
|
this.requestHandler = options.requestHandler ?? null;
|
|
427
|
+
this.extensionLaunchProvider = options.extensionLaunchProvider;
|
|
428
|
+
this.installationConfirmationHandler = options.installationConfirmationHandler;
|
|
423
429
|
this.onGitHubTelemetry = options.onGitHubTelemetry;
|
|
424
430
|
this.setupClientGlobalHandlers();
|
|
425
431
|
const connEnv = conn.kind === "stdio" || conn.kind === "tcp" ? conn.env : void 0;
|
|
@@ -522,14 +528,16 @@ class CopilotClient {
|
|
|
522
528
|
}
|
|
523
529
|
setupClientGlobalHandlers() {
|
|
524
530
|
const handlers = {};
|
|
531
|
+
handlers.extensionLaunchProvider = this.extensionLaunchProvider;
|
|
525
532
|
if (this.requestHandler) {
|
|
526
|
-
|
|
533
|
+
this.requestAdapter = (0, import_copilotRequestHandler.createCopilotRequestAdapter)(this.requestHandler, () => {
|
|
527
534
|
if (!this.connection) {
|
|
528
535
|
return void 0;
|
|
529
536
|
}
|
|
530
537
|
this._rpc ??= (0, import_rpc.createServerRpc)(this.connection);
|
|
531
538
|
return this._rpc;
|
|
532
539
|
});
|
|
540
|
+
handlers.llmInference = this.requestAdapter;
|
|
533
541
|
}
|
|
534
542
|
if (this.onGitHubTelemetry) {
|
|
535
543
|
const onGitHubTelemetry = this.onGitHubTelemetry;
|
|
@@ -634,6 +642,9 @@ class CopilotClient {
|
|
|
634
642
|
}
|
|
635
643
|
await this.connectToServer();
|
|
636
644
|
await this.verifyProtocolVersion();
|
|
645
|
+
if (this.extensionLaunchProvider) {
|
|
646
|
+
await this.rpc.registerExtensionLaunchProvider();
|
|
647
|
+
}
|
|
637
648
|
if (this.builtinPluginDirectories.length > 0) {
|
|
638
649
|
try {
|
|
639
650
|
await this.connection.sendRequest("plugins.builtin.set", {
|
|
@@ -722,6 +733,7 @@ class CopilotClient {
|
|
|
722
733
|
}
|
|
723
734
|
this.sessions.clear();
|
|
724
735
|
this.githubTokenProviders.clear();
|
|
736
|
+
this.requestAdapter?.cancelPending();
|
|
725
737
|
if (this.connection && !this.connectionClosed && (this.cliProcess || this.ffiHost) && !this.isExternalServer) {
|
|
726
738
|
const runtimeShutdownStart = Date.now();
|
|
727
739
|
const shutdownPromise = this.rpc.runtime.shutdown();
|
|
@@ -877,6 +889,7 @@ class CopilotClient {
|
|
|
877
889
|
}
|
|
878
890
|
this.sessions.clear();
|
|
879
891
|
this.githubTokenProviders.clear();
|
|
892
|
+
this.requestAdapter?.cancelPending();
|
|
880
893
|
if (this.messageWriter) {
|
|
881
894
|
this.messageWriter.suppressWriteErrors = true;
|
|
882
895
|
}
|
|
@@ -1227,6 +1240,7 @@ class CopilotClient {
|
|
|
1227
1240
|
includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
|
|
1228
1241
|
...this.onGitHubTelemetry != null ? { enableGitHubTelemetryForwarding: true } : {},
|
|
1229
1242
|
mcpServers: toWireMcpServers(config.mcpServers),
|
|
1243
|
+
...config.diagnostics !== void 0 ? { diagnostics: config.diagnostics } : {},
|
|
1230
1244
|
mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
|
|
1231
1245
|
authClientIdMetadataUrl: config.authClientIdMetadataUrl,
|
|
1232
1246
|
envValueMode: "direct",
|
|
@@ -1236,6 +1250,7 @@ class CopilotClient {
|
|
|
1236
1250
|
agent: config.agent,
|
|
1237
1251
|
configDir: config.configDirectory,
|
|
1238
1252
|
enableConfigDiscovery: config.enableConfigDiscovery,
|
|
1253
|
+
refreshCustomInstructions: config.refreshCustomInstructions,
|
|
1239
1254
|
skipEmbeddingRetrieval: config.skipEmbeddingRetrieval,
|
|
1240
1255
|
embeddingCacheStorage: config.embeddingCacheStorage,
|
|
1241
1256
|
organizationCustomInstructions: config.organizationCustomInstructions,
|
|
@@ -1328,10 +1343,11 @@ class CopilotClient {
|
|
|
1328
1343
|
return this.resumeSessionInternal(sessionId, config);
|
|
1329
1344
|
}
|
|
1330
1345
|
/** @internal */
|
|
1331
|
-
async resumeSessionForExtension(sessionId, config,
|
|
1332
|
-
return this.resumeSessionInternal(sessionId, config,
|
|
1346
|
+
async resumeSessionForExtension(sessionId, config, contributions = {}, extensionOptions) {
|
|
1347
|
+
return this.resumeSessionInternal(sessionId, config, contributions, extensionOptions);
|
|
1333
1348
|
}
|
|
1334
|
-
async resumeSessionInternal(sessionId, config,
|
|
1349
|
+
async resumeSessionInternal(sessionId, config, contributions = {}, extensionOptions) {
|
|
1350
|
+
const { workflows } = contributions;
|
|
1335
1351
|
if (config.gitHubToken !== void 0 && config.gitHubTokenProvider !== void 0) {
|
|
1336
1352
|
throw new Error("gitHubToken and gitHubTokenProvider are mutually exclusive");
|
|
1337
1353
|
}
|
|
@@ -1351,7 +1367,7 @@ class CopilotClient {
|
|
|
1351
1367
|
session.registerTools(config.tools);
|
|
1352
1368
|
session.registerCanvases(config.canvases);
|
|
1353
1369
|
session.registerCommands(config.commands);
|
|
1354
|
-
session.
|
|
1370
|
+
session.registerWorkflows(workflows);
|
|
1355
1371
|
const {
|
|
1356
1372
|
wireProvider: bearerWireProvider,
|
|
1357
1373
|
wireProviders: bearerWireProviders,
|
|
@@ -1432,7 +1448,7 @@ class CopilotClient {
|
|
|
1432
1448
|
})),
|
|
1433
1449
|
toolSearch: config.toolSearch,
|
|
1434
1450
|
canvases: config.canvases?.map((canvas) => canvas.declaration),
|
|
1435
|
-
|
|
1451
|
+
workflows: workflows?.map((workflow) => workflow.meta),
|
|
1436
1452
|
requestCanvasRenderer: config.requestCanvasRenderer,
|
|
1437
1453
|
requestExtensions: config.requestExtensions,
|
|
1438
1454
|
extensionSdkPath: config.extensionSdkPath,
|
|
@@ -1473,6 +1489,7 @@ class CopilotClient {
|
|
|
1473
1489
|
includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
|
|
1474
1490
|
...this.onGitHubTelemetry != null ? { enableGitHubTelemetryForwarding: true } : {},
|
|
1475
1491
|
mcpServers: toWireMcpServers(config.mcpServers),
|
|
1492
|
+
...config.diagnostics !== void 0 ? { diagnostics: config.diagnostics } : {},
|
|
1476
1493
|
mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
|
|
1477
1494
|
authClientIdMetadataUrl: config.authClientIdMetadataUrl,
|
|
1478
1495
|
envValueMode: "direct",
|
|
@@ -1893,6 +1910,9 @@ class CopilotClient {
|
|
|
1893
1910
|
if (this.options.mode === "empty") {
|
|
1894
1911
|
env.COPILOT_DISABLE_KEYTAR = "1";
|
|
1895
1912
|
}
|
|
1913
|
+
if (this.options.mode !== "empty") {
|
|
1914
|
+
env.COPILOT_RUNTIME_PROCESS_FILE_LOGGING = "1";
|
|
1915
|
+
}
|
|
1896
1916
|
if (this.options.telemetry) {
|
|
1897
1917
|
const t = this.options.telemetry;
|
|
1898
1918
|
env.COPILOT_OTEL_ENABLED = "true";
|
|
@@ -2267,6 +2287,16 @@ stderr: ${stderrOutput}` : ""}`
|
|
|
2267
2287
|
return session.clientSessionApis;
|
|
2268
2288
|
});
|
|
2269
2289
|
(0, import_rpc.registerClientGlobalApiHandlers)(this.connection, this.clientGlobalHandlers);
|
|
2290
|
+
if (this.installationConfirmationHandler) {
|
|
2291
|
+
const confirmation = (0, import_installationConfirmation.createInstallationConfirmationAdapter)(
|
|
2292
|
+
this.connection,
|
|
2293
|
+
this.installationConfirmationHandler
|
|
2294
|
+
);
|
|
2295
|
+
this.connection.onRequest(
|
|
2296
|
+
"installations.confirm",
|
|
2297
|
+
(params, token) => confirmation.confirm(params, token)
|
|
2298
|
+
);
|
|
2299
|
+
}
|
|
2270
2300
|
this.connection.onRequest(
|
|
2271
2301
|
"hooks.invoke",
|
|
2272
2302
|
async (params) => {
|
|
@@ -2285,6 +2315,7 @@ stderr: ${stderrOutput}` : ""}`
|
|
|
2285
2315
|
}
|
|
2286
2316
|
this.sessions.clear();
|
|
2287
2317
|
this.githubTokenProviders.clear();
|
|
2318
|
+
this.requestAdapter?.cancelPending();
|
|
2288
2319
|
};
|
|
2289
2320
|
this.connection.onClose(markDisconnected);
|
|
2290
2321
|
this.connection.onError(() => {
|
|
@@ -27,6 +27,7 @@ __export(copilotRequestHandler_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(copilotRequestHandler_exports);
|
|
28
28
|
const sharedTextDecoder = new TextDecoder("utf-8", { fatal: false });
|
|
29
29
|
const sharedTextEncoder = new TextEncoder();
|
|
30
|
+
const HTTP_RESPONSE_READ_AHEAD_BYTES = 32 * 1024;
|
|
30
31
|
const kBridge = /* @__PURE__ */ Symbol("copilotWebSocketResponseBridge");
|
|
31
32
|
const kCompletion = /* @__PURE__ */ Symbol("copilotWebSocketCompletion");
|
|
32
33
|
const kOpen = /* @__PURE__ */ Symbol("copilotWebSocketOpen");
|
|
@@ -265,7 +266,9 @@ function createCopilotRequestAdapter(handler, getServerRpc) {
|
|
|
265
266
|
const message = err instanceof Error ? err.message : String(err);
|
|
266
267
|
await finalize(exchange, 502, message);
|
|
267
268
|
} finally {
|
|
268
|
-
pending.
|
|
269
|
+
if (pending.get(exchange.requestId) === exchange) {
|
|
270
|
+
pending.delete(exchange.requestId);
|
|
271
|
+
}
|
|
269
272
|
}
|
|
270
273
|
}
|
|
271
274
|
return {
|
|
@@ -278,6 +281,13 @@ function createCopilotRequestAdapter(handler, getServerRpc) {
|
|
|
278
281
|
async httpRequestChunk(params) {
|
|
279
282
|
routeChunk(getOrCreate(params.requestId), params);
|
|
280
283
|
return {};
|
|
284
|
+
},
|
|
285
|
+
cancelPending() {
|
|
286
|
+
const exchanges = [...pending.values()];
|
|
287
|
+
pending.clear();
|
|
288
|
+
for (const exchange of exchanges) {
|
|
289
|
+
exchange.pushCancel("RPC connection closed");
|
|
290
|
+
}
|
|
281
291
|
}
|
|
282
292
|
};
|
|
283
293
|
}
|
|
@@ -526,30 +536,156 @@ async function drainAsync(stream) {
|
|
|
526
536
|
return out;
|
|
527
537
|
}
|
|
528
538
|
async function streamResponse(response, exchange) {
|
|
529
|
-
|
|
530
|
-
status: response.status,
|
|
531
|
-
statusText: response.statusText || void 0,
|
|
532
|
-
headers: headersToMultiMap(response.headers)
|
|
533
|
-
});
|
|
534
|
-
const body = response.body;
|
|
535
|
-
if (!body) {
|
|
536
|
-
await exchange.endResponse();
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
const reader = body.getReader();
|
|
539
|
+
const reader = response.body ? new HttpResponseReader(response.body, exchange.signal) : void 0;
|
|
540
540
|
try {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
541
|
+
await exchange.startResponse({
|
|
542
|
+
status: response.status,
|
|
543
|
+
statusText: response.statusText || void 0,
|
|
544
|
+
headers: headersToMultiMap(response.headers)
|
|
545
|
+
});
|
|
546
|
+
if (reader) {
|
|
547
|
+
for (; ; ) {
|
|
548
|
+
const chunk = await reader.nextChunk();
|
|
549
|
+
if (!chunk) {
|
|
550
|
+
break;
|
|
551
|
+
}
|
|
552
|
+
await exchange.writeResponse(chunk);
|
|
548
553
|
}
|
|
549
554
|
}
|
|
550
555
|
await exchange.endResponse();
|
|
551
556
|
} finally {
|
|
552
|
-
reader
|
|
557
|
+
await reader?.dispose();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
class HttpResponseReader {
|
|
561
|
+
#reader;
|
|
562
|
+
#signal;
|
|
563
|
+
#frames = [];
|
|
564
|
+
#pump;
|
|
565
|
+
#onAbort;
|
|
566
|
+
#queued = 0;
|
|
567
|
+
#done = false;
|
|
568
|
+
#cancelled = false;
|
|
569
|
+
#hasError = false;
|
|
570
|
+
#error;
|
|
571
|
+
#dataWaker;
|
|
572
|
+
#spaceWaker;
|
|
573
|
+
#cancelPromise;
|
|
574
|
+
constructor(body, signal) {
|
|
575
|
+
this.#reader = body.getReader();
|
|
576
|
+
this.#signal = signal;
|
|
577
|
+
this.#onAbort = () => {
|
|
578
|
+
void this.cancel(signal.reason);
|
|
579
|
+
};
|
|
580
|
+
signal.addEventListener("abort", this.#onAbort, { once: true });
|
|
581
|
+
this.#pump = this.#pumpSource();
|
|
582
|
+
if (signal.aborted) {
|
|
583
|
+
this.#onAbort();
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
async nextChunk() {
|
|
587
|
+
while (this.#frames.length === 0 && !this.#done && !this.#hasError) {
|
|
588
|
+
await new Promise((resolve) => {
|
|
589
|
+
this.#dataWaker = resolve;
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
if (this.#frames.length > 0) {
|
|
593
|
+
const chunk = this.#takeQueued();
|
|
594
|
+
this.#wakeSpace();
|
|
595
|
+
return chunk;
|
|
596
|
+
}
|
|
597
|
+
if (this.#hasError) {
|
|
598
|
+
this.#hasError = false;
|
|
599
|
+
throw this.#error;
|
|
600
|
+
}
|
|
601
|
+
return void 0;
|
|
602
|
+
}
|
|
603
|
+
#takeQueued() {
|
|
604
|
+
const frames = this.#frames;
|
|
605
|
+
const total = this.#queued;
|
|
606
|
+
this.#queued = 0;
|
|
607
|
+
if (frames.length === 1) {
|
|
608
|
+
return frames.pop();
|
|
609
|
+
}
|
|
610
|
+
const chunk = new Uint8Array(total);
|
|
611
|
+
let offset = 0;
|
|
612
|
+
for (const frame of frames) {
|
|
613
|
+
chunk.set(frame, offset);
|
|
614
|
+
offset += frame.byteLength;
|
|
615
|
+
}
|
|
616
|
+
frames.length = 0;
|
|
617
|
+
return chunk;
|
|
618
|
+
}
|
|
619
|
+
async dispose() {
|
|
620
|
+
this.#signal.removeEventListener("abort", this.#onAbort);
|
|
621
|
+
if (!this.#done) {
|
|
622
|
+
await this.cancel();
|
|
623
|
+
} else if (this.#cancelPromise) {
|
|
624
|
+
await this.#cancelPromise;
|
|
625
|
+
}
|
|
626
|
+
await this.#pump;
|
|
627
|
+
}
|
|
628
|
+
cancel(reason) {
|
|
629
|
+
if (this.#done) {
|
|
630
|
+
return Promise.resolve();
|
|
631
|
+
}
|
|
632
|
+
if (!this.#cancelPromise) {
|
|
633
|
+
this.#cancelled = true;
|
|
634
|
+
this.#done = true;
|
|
635
|
+
this.#hasError = true;
|
|
636
|
+
this.#error = reason instanceof Error ? reason : new Error("HTTP response body cancelled.");
|
|
637
|
+
this.#frames.length = 0;
|
|
638
|
+
this.#queued = 0;
|
|
639
|
+
this.#wakeData();
|
|
640
|
+
this.#wakeSpace();
|
|
641
|
+
this.#cancelPromise = this.#reader.cancel(reason).catch(() => void 0);
|
|
642
|
+
}
|
|
643
|
+
return this.#cancelPromise;
|
|
644
|
+
}
|
|
645
|
+
async #pumpSource() {
|
|
646
|
+
try {
|
|
647
|
+
while (!this.#cancelled) {
|
|
648
|
+
while (this.#queued >= HTTP_RESPONSE_READ_AHEAD_BYTES && !this.#cancelled) {
|
|
649
|
+
await new Promise((resolve) => {
|
|
650
|
+
this.#spaceWaker = resolve;
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
if (this.#cancelled) {
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
const { value, done } = await this.#reader.read();
|
|
657
|
+
if (done) {
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
if (value.byteLength > 0) {
|
|
661
|
+
this.#frames.push(value);
|
|
662
|
+
this.#queued += value.byteLength;
|
|
663
|
+
this.#wakeData();
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
667
|
+
}
|
|
668
|
+
} catch (error) {
|
|
669
|
+
if (!this.#cancelled) {
|
|
670
|
+
this.#hasError = true;
|
|
671
|
+
this.#error = error;
|
|
672
|
+
}
|
|
673
|
+
} finally {
|
|
674
|
+
this.#done = true;
|
|
675
|
+
this.#wakeData();
|
|
676
|
+
this.#wakeSpace();
|
|
677
|
+
this.#reader.releaseLock();
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
#wakeData() {
|
|
681
|
+
const waker = this.#dataWaker;
|
|
682
|
+
this.#dataWaker = void 0;
|
|
683
|
+
waker?.();
|
|
684
|
+
}
|
|
685
|
+
#wakeSpace() {
|
|
686
|
+
const waker = this.#spaceWaker;
|
|
687
|
+
this.#spaceWaker = void 0;
|
|
688
|
+
waker?.();
|
|
553
689
|
}
|
|
554
690
|
}
|
|
555
691
|
function headersToMultiMap(headers) {
|
package/dist/cjs/extension.js
CHANGED
|
@@ -20,17 +20,17 @@ var extension_exports = {};
|
|
|
20
20
|
__export(extension_exports, {
|
|
21
21
|
Canvas: () => import_canvas.Canvas,
|
|
22
22
|
CanvasError: () => import_canvas.CanvasError,
|
|
23
|
-
|
|
23
|
+
WorkflowResumeError: () => import_workflow.WorkflowResumeError,
|
|
24
24
|
createCanvas: () => import_canvas.createCanvas,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
defineWorkflow: () => import_workflow.defineWorkflow,
|
|
26
|
+
isWorkflowRunTerminal: () => import_workflow.isWorkflowRunTerminal,
|
|
27
27
|
joinSession: () => joinSession
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(extension_exports);
|
|
30
30
|
var import_client = require("./client.js");
|
|
31
31
|
var import_types = require("./types.js");
|
|
32
32
|
var import_canvas = require("./canvas.js");
|
|
33
|
-
var
|
|
33
|
+
var import_workflow = require("./workflow.js");
|
|
34
34
|
async function joinSession(config = {}) {
|
|
35
35
|
const sessionId = process.env.SESSION_ID;
|
|
36
36
|
if (!sessionId) {
|
|
@@ -41,7 +41,7 @@ async function joinSession(config = {}) {
|
|
|
41
41
|
const client = new import_client.CopilotClient({ _internalConnection: { kind: "parent-process" } });
|
|
42
42
|
const {
|
|
43
43
|
extensionSdkPath: _stripped,
|
|
44
|
-
|
|
44
|
+
workflows,
|
|
45
45
|
requestedEnvironmentVariables,
|
|
46
46
|
...rest
|
|
47
47
|
} = config;
|
|
@@ -53,7 +53,7 @@ async function joinSession(config = {}) {
|
|
|
53
53
|
onPermissionRequest: config.onPermissionRequest ?? import_types.defaultJoinSessionPermissionHandler,
|
|
54
54
|
suppressResumeEvent: config.suppressResumeEvent ?? true
|
|
55
55
|
},
|
|
56
|
-
|
|
56
|
+
{ workflows },
|
|
57
57
|
requestedEnvironmentVariables?.length ? { requestedEnvironmentVariables } : void 0
|
|
58
58
|
);
|
|
59
59
|
}
|
|
@@ -61,9 +61,9 @@ async function joinSession(config = {}) {
|
|
|
61
61
|
0 && (module.exports = {
|
|
62
62
|
Canvas,
|
|
63
63
|
CanvasError,
|
|
64
|
-
|
|
64
|
+
WorkflowResumeError,
|
|
65
65
|
createCanvas,
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
defineWorkflow,
|
|
67
|
+
isWorkflowRunTerminal,
|
|
68
68
|
joinSession
|
|
69
69
|
});
|