@github/copilot-sdk 1.0.0-beta.8 → 1.0.0
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 +25 -10
- package/dist/canvas.d.ts +26 -3
- package/dist/cjs/client.js +273 -42
- package/dist/cjs/extension.js +3 -1
- package/dist/cjs/generated/rpc.js +83 -17
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/session.js +34 -5
- package/dist/cjs/toolSet.js +107 -0
- package/dist/client.d.ts +17 -25
- package/dist/client.js +273 -42
- package/dist/extension.d.ts +1 -1
- package/dist/extension.js +3 -1
- package/dist/generated/rpc.d.ts +949 -303
- package/dist/generated/rpc.js +83 -17
- package/dist/generated/session-events.d.ts +267 -22
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -0
- package/dist/session.d.ts +9 -5
- package/dist/session.js +34 -5
- package/dist/toolSet.d.ts +75 -0
- package/dist/toolSet.js +82 -0
- package/dist/types.d.ts +306 -8
- package/docs/agent-author.md +31 -7
- package/docs/examples.md +26 -16
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC.
|
|
4
4
|
|
|
5
|
-
> **Note:** This SDK is in public preview and may change in breaking ways.
|
|
6
|
-
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
7
|
```bash
|
|
@@ -57,7 +55,7 @@ await session.disconnect();
|
|
|
57
55
|
await client.stop();
|
|
58
56
|
```
|
|
59
57
|
|
|
60
|
-
Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2
|
|
58
|
+
Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2+ / Node.js 20+):
|
|
61
59
|
|
|
62
60
|
```typescript
|
|
63
61
|
await using session = await client.createSession({
|
|
@@ -82,14 +80,20 @@ new CopilotClient(options?: CopilotClientOptions)
|
|
|
82
80
|
- `connection?: RuntimeConnection` - How to connect to the Copilot runtime. Construct via the factory functions on `RuntimeConnection`:
|
|
83
81
|
- `RuntimeConnection.forStdio({ path?, args? })` (default) — spawn the runtime and communicate over its stdin/stdout.
|
|
84
82
|
- `RuntimeConnection.forTcp({ port?, connectionToken?, path?, args? })` — spawn the runtime as a TCP server.
|
|
85
|
-
- `RuntimeConnection.forUri(url, { connectionToken? })` — connect to an already-running runtime (mutually exclusive with `gitHubToken`/`useLoggedInUser`).
|
|
86
|
-
- `
|
|
83
|
+
- `RuntimeConnection.forUri(url, { connectionToken? })` — connect to an already-running runtime (mutually exclusive with `gitHubToken`/`useLoggedInUser`). There is no top-level `cliUrl` shortcut; use this factory for URL-based connections.
|
|
84
|
+
- `mode?: "empty" | "copilot-cli"` - Defaulting strategy. Use `"empty"` for multi-user server mode; defaults to `"copilot-cli"`.
|
|
85
|
+
- `workingDirectory?: string` - Working directory for the runtime process (default: current process cwd).
|
|
87
86
|
- `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`.
|
|
88
|
-
- `logLevel?:
|
|
87
|
+
- `logLevel?: "none" | "error" | "warning" | "info" | "debug" | "all"` - Log level. When omitted, the runtime uses its own default (currently `"info"`).
|
|
88
|
+
- `env?: Record<string, string | undefined>` - Environment variables for the runtime process. When omitted, inherits `process.env`.
|
|
89
89
|
- `gitHubToken?: string` - GitHub token for authentication. When provided, takes priority over other auth methods.
|
|
90
90
|
- `useLoggedInUser?: boolean` - Whether to use logged-in user for authentication (default: true, but false when `gitHubToken` is provided). Cannot be used with `RuntimeConnection.forUri`.
|
|
91
|
+
- `onListModels?: () => Promise<ModelInfo[]> | ModelInfo[]` - Optional model-list provider, useful when using a custom provider.
|
|
91
92
|
- `telemetry?: TelemetryConfig` - OpenTelemetry configuration for the runtime process. Providing this object enables telemetry — no separate flag needed. See [Telemetry](#telemetry) below.
|
|
92
93
|
- `onGetTraceContext?: TraceContextProvider` - Advanced: callback for linking your application's own OpenTelemetry spans into the same distributed trace as the runtime's spans. Not needed for normal telemetry collection. See [Telemetry](#telemetry) below.
|
|
94
|
+
- `sessionFs?: SessionFsConfig` - Custom session filesystem provider.
|
|
95
|
+
- `sessionIdleTimeoutSeconds?: number` - Server-wide idle timeout for sessions in seconds. Ignored when connecting via `RuntimeConnection.forUri`.
|
|
96
|
+
- `enableRemoteSessions?: boolean` - Enable Mission Control remote session support. Ignored when connecting via `RuntimeConnection.forUri`.
|
|
93
97
|
|
|
94
98
|
#### Methods
|
|
95
99
|
|
|
@@ -163,7 +167,7 @@ Get the ID of the session currently displayed in the TUI. Only available when co
|
|
|
163
167
|
|
|
164
168
|
Request the TUI to switch to displaying the specified session. Only available in TUI+server mode.
|
|
165
169
|
|
|
166
|
-
##### `
|
|
170
|
+
##### `onLifecycle(eventType: SessionLifecycleEventType, handler): () => void`
|
|
167
171
|
|
|
168
172
|
Subscribe to a specific session lifecycle event type. Returns an unsubscribe function.
|
|
169
173
|
|
|
@@ -173,7 +177,7 @@ const unsubscribe = client.onLifecycle("session.foreground", (event) => {
|
|
|
173
177
|
});
|
|
174
178
|
```
|
|
175
179
|
|
|
176
|
-
##### `
|
|
180
|
+
##### `onLifecycle(handler: SessionLifecycleHandler): () => void`
|
|
177
181
|
|
|
178
182
|
Subscribe to all session lifecycle events. Returns an unsubscribe function.
|
|
179
183
|
|
|
@@ -957,7 +961,7 @@ const session = await client.createSession({
|
|
|
957
961
|
};
|
|
958
962
|
},
|
|
959
963
|
|
|
960
|
-
// Called after each tool execution
|
|
964
|
+
// Called after each successful tool execution
|
|
961
965
|
onPostToolUse: async (input, invocation) => {
|
|
962
966
|
console.log(`Tool ${input.toolName} completed`);
|
|
963
967
|
// Optionally modify the result or add context
|
|
@@ -966,6 +970,16 @@ const session = await client.createSession({
|
|
|
966
970
|
};
|
|
967
971
|
},
|
|
968
972
|
|
|
973
|
+
// Called after a tool execution whose result was "failure".
|
|
974
|
+
// onPostToolUse does NOT fire for failed tool calls — register this
|
|
975
|
+
// hook to observe them. Input includes `error` (the failure message
|
|
976
|
+
// extracted from the tool's result), not the full result object.
|
|
977
|
+
onPostToolUseFailure: async (input, invocation) => {
|
|
978
|
+
console.log(`Tool ${input.toolName} failed: ${input.error}`);
|
|
979
|
+
// Optionally append hidden guidance to the model.
|
|
980
|
+
return { additionalContext: "Suggest checking inputs and retrying." };
|
|
981
|
+
},
|
|
982
|
+
|
|
969
983
|
// Called when user submits a prompt
|
|
970
984
|
onUserPromptSubmitted: async (input, invocation) => {
|
|
971
985
|
console.log(`User prompt: ${input.prompt}`);
|
|
@@ -1001,7 +1015,8 @@ const session = await client.createSession({
|
|
|
1001
1015
|
**Available hooks:**
|
|
1002
1016
|
|
|
1003
1017
|
- `onPreToolUse` - Intercept tool calls before execution. Can allow/deny or modify arguments.
|
|
1004
|
-
- `onPostToolUse` - Process tool results after execution. Can modify results or add context.
|
|
1018
|
+
- `onPostToolUse` - Process tool results after **successful** execution. Can modify results or add context.
|
|
1019
|
+
- `onPostToolUseFailure` - Observe and append hidden guidance to the model after tool executions whose result was `"failure"`. Register this in addition to `onPostToolUse` to see failed tool calls.
|
|
1005
1020
|
- `onUserPromptSubmitted` - Intercept user prompts. Can modify the prompt before processing.
|
|
1006
1021
|
- `onSessionStart` - Run logic when a session starts or resumes.
|
|
1007
1022
|
- `onSessionEnd` - Cleanup or logging when session ends.
|
package/dist/canvas.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import type { CanvasJsonSchema, CanvasProviderCloseRequest, CanvasProviderInvokeActionRequest, CanvasProviderOpenRequest, CanvasProviderOpenResult } from "./generated/rpc.js";
|
|
2
|
-
export type { CanvasJsonSchema, CanvasHostContext } from "./generated/rpc.js";
|
|
2
|
+
export type { CanvasJsonSchema, CanvasHostContext, CanvasHostContextCapabilities, } from "./generated/rpc.js";
|
|
3
3
|
/**
|
|
4
4
|
* Extension-owned canvases declared via
|
|
5
5
|
* `joinSession({ canvases: [createCanvas({...})] })`.
|
|
6
6
|
*
|
|
7
7
|
* The runtime sends provider callbacks as `canvas.open`, `canvas.close`, and
|
|
8
|
-
* `canvas.
|
|
8
|
+
* `canvas.action.invoke` JSON-RPC requests via the codegen client session API
|
|
9
9
|
* pipeline. The SDK routes those requests by `canvasId` to the in-process
|
|
10
10
|
* handlers bound by `createCanvas`. Re-opening with an existing `instanceId`
|
|
11
11
|
* is how the host focuses an existing panel; reload is a renderer-only concern.
|
|
12
|
+
*
|
|
13
|
+
* @experimental Canvas types are part of an experimental wire-protocol surface
|
|
14
|
+
* and may change or be removed in future SDK or CLI releases.
|
|
12
15
|
*/
|
|
13
16
|
/**
|
|
14
17
|
* A single agent-callable action contributed by a canvas. The metadata
|
|
@@ -18,6 +21,9 @@ export type { CanvasJsonSchema, CanvasHostContext } from "./generated/rpc.js";
|
|
|
18
21
|
*
|
|
19
22
|
* Names MUST NOT start with `canvas.` — that prefix is reserved for
|
|
20
23
|
* lifecycle verbs.
|
|
24
|
+
*
|
|
25
|
+
* @experimental This type is part of an experimental wire-protocol surface
|
|
26
|
+
* and may change or be removed in future SDK or CLI releases.
|
|
21
27
|
*/
|
|
22
28
|
export interface CanvasAction {
|
|
23
29
|
/** Action identifier, unique within the canvas. */
|
|
@@ -32,6 +38,9 @@ export interface CanvasAction {
|
|
|
32
38
|
/**
|
|
33
39
|
* Declarative metadata for a single canvas, serialized over the wire on
|
|
34
40
|
* `session.create` / `session.resume`.
|
|
41
|
+
*
|
|
42
|
+
* @experimental This type is part of an experimental wire-protocol surface
|
|
43
|
+
* and may change or be removed in future SDK or CLI releases.
|
|
35
44
|
*/
|
|
36
45
|
export interface CanvasDeclaration {
|
|
37
46
|
/** Canvas id, unique within the declaring connection. */
|
|
@@ -45,7 +54,12 @@ export interface CanvasDeclaration {
|
|
|
45
54
|
/** Agent-invocable actions exposed via `invoke_canvas_action`. */
|
|
46
55
|
actions?: Omit<CanvasAction, "handler">[];
|
|
47
56
|
}
|
|
48
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Structured error returned from canvas handlers.
|
|
59
|
+
*
|
|
60
|
+
* @experimental This class is part of an experimental wire-protocol surface
|
|
61
|
+
* and may change or be removed in future SDK or CLI releases.
|
|
62
|
+
*/
|
|
49
63
|
export declare class CanvasError extends Error {
|
|
50
64
|
readonly code: string;
|
|
51
65
|
constructor(code: string, message: string);
|
|
@@ -55,6 +69,9 @@ export declare class CanvasError extends Error {
|
|
|
55
69
|
/**
|
|
56
70
|
* Options accepted by {@link createCanvas}. Combines the declarative
|
|
57
71
|
* {@link CanvasDeclaration} fields with the in-process handler closures.
|
|
72
|
+
*
|
|
73
|
+
* @experimental This interface is part of an experimental wire-protocol surface
|
|
74
|
+
* and may change or be removed in future SDK or CLI releases.
|
|
58
75
|
*/
|
|
59
76
|
export interface CanvasOptions {
|
|
60
77
|
/** @see CanvasDeclaration.id */
|
|
@@ -87,6 +104,9 @@ export interface CanvasOptions {
|
|
|
87
104
|
* ergonomics) where other SDKs (Rust, Python, Go, .NET) expose a single
|
|
88
105
|
* `CanvasHandler` per session that switches on `canvasId`. Both shapes target
|
|
89
106
|
* the same JSON-RPC wire protocol; the divergence is API ergonomics only.
|
|
107
|
+
*
|
|
108
|
+
* @experimental This class is part of an experimental wire-protocol surface
|
|
109
|
+
* and may change or be removed in future SDK or CLI releases.
|
|
90
110
|
*/
|
|
91
111
|
export declare class Canvas {
|
|
92
112
|
readonly declaration: CanvasDeclaration;
|
|
@@ -99,5 +119,8 @@ export declare class Canvas {
|
|
|
99
119
|
* `DefineTool`'s co-location ergonomics) where other SDKs (Rust, Python, Go,
|
|
100
120
|
* .NET) expose a single `CanvasHandler` per session that switches on
|
|
101
121
|
* `canvasId`. Both shapes target the same JSON-RPC wire protocol.
|
|
122
|
+
*
|
|
123
|
+
* @experimental This function is part of an experimental wire-protocol surface
|
|
124
|
+
* and may change or be removed in future SDK or CLI releases.
|
|
102
125
|
*/
|
|
103
126
|
export declare function createCanvas(options: CanvasOptions): Canvas;
|
package/dist/cjs/client.js
CHANGED
|
@@ -34,6 +34,7 @@ var import_sdkProtocolVersion = require("./sdkProtocolVersion.js");
|
|
|
34
34
|
var import_session = require("./session.js");
|
|
35
35
|
var import_sessionFsProvider = require("./sessionFsProvider.js");
|
|
36
36
|
var import_telemetry = require("./telemetry.js");
|
|
37
|
+
var import_toolSet = require("./toolSet.js");
|
|
37
38
|
var import_types = require("./types.js");
|
|
38
39
|
const import_meta = {};
|
|
39
40
|
const MIN_PROTOCOL_VERSION = 3;
|
|
@@ -67,6 +68,33 @@ function toWireCustomAgents(agents) {
|
|
|
67
68
|
return { ...rest, mcpServers: toWireMcpServers(mcpServers) };
|
|
68
69
|
});
|
|
69
70
|
}
|
|
71
|
+
function toWireLargeOutput(config) {
|
|
72
|
+
if (!config) return void 0;
|
|
73
|
+
const { outputDirectory, ...rest } = config;
|
|
74
|
+
const wire = { ...rest };
|
|
75
|
+
if (outputDirectory !== void 0) {
|
|
76
|
+
wire.outputDir = outputDirectory;
|
|
77
|
+
}
|
|
78
|
+
return wire;
|
|
79
|
+
}
|
|
80
|
+
function toolFilterListToArray(value) {
|
|
81
|
+
if (value === void 0) {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
return value instanceof import_toolSet.ToolSet ? value.toArray() : value;
|
|
85
|
+
}
|
|
86
|
+
function validateToolFilterList(field, list) {
|
|
87
|
+
if (!list) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
for (const entry of list) {
|
|
91
|
+
if (entry === "*") {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Invalid ${field} entry '*': there is no bare wildcard. Use one or more of \`new ToolSet().addBuiltIn('*')\`, \`.addMcp('*')\`, or \`.addCustom('*')\` to target a specific source.`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
70
98
|
function extractTransformCallbacks(systemMessage) {
|
|
71
99
|
if (!systemMessage || systemMessage.mode !== "customize" || !systemMessage.sections) {
|
|
72
100
|
return { wirePayload: systemMessage, transformCallbacks: void 0 };
|
|
@@ -249,8 +277,19 @@ class CopilotClient {
|
|
|
249
277
|
telemetry: options.telemetry,
|
|
250
278
|
baseDirectory: options.baseDirectory,
|
|
251
279
|
sessionIdleTimeoutSeconds: options.sessionIdleTimeoutSeconds ?? 0,
|
|
252
|
-
enableRemoteSessions: options.enableRemoteSessions ?? false
|
|
280
|
+
enableRemoteSessions: options.enableRemoteSessions ?? false,
|
|
281
|
+
mode: options.mode ?? "copilot-cli"
|
|
253
282
|
};
|
|
283
|
+
if (this.options.mode === "empty") {
|
|
284
|
+
const hasPersistence = this.options.baseDirectory !== void 0 || this.sessionFsConfig !== null || // External runtimes manage their own persistence layer; the SDK
|
|
285
|
+
// can't enforce it from here.
|
|
286
|
+
conn.kind === "uri" || conn.kind === "parent-process";
|
|
287
|
+
if (!hasPersistence) {
|
|
288
|
+
throw new Error(
|
|
289
|
+
"CopilotClient was created with mode: 'empty' but neither 'baseDirectory' nor 'sessionFs' was set. Empty mode requires an explicit per-session persistence location; pick one."
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
254
293
|
}
|
|
255
294
|
connectionExtraArgs = [];
|
|
256
295
|
/**
|
|
@@ -560,54 +599,190 @@ class CopilotClient {
|
|
|
560
599
|
* });
|
|
561
600
|
* ```
|
|
562
601
|
*/
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
602
|
+
/**
|
|
603
|
+
* Normalizes session-level tool filter options. Converts {@link ToolSet}
|
|
604
|
+
* instances to plain string arrays, rejects misuse (bare `"*"`) and the
|
|
605
|
+
* missing-availableTools case in `mode = "empty"`.
|
|
606
|
+
*
|
|
607
|
+
* The SDK always sends `toolFilterPrecedence: "excluded"` so callers can
|
|
608
|
+
* compose include + exclude lists naturally (e.g. "everything matching X
|
|
609
|
+
* except Y") regardless of mode. Allowlist-precedence is intentionally not
|
|
610
|
+
* exposed — it's available on the runtime side as a CLI-only concession to
|
|
611
|
+
* legacy behavior, but SDK consumers always get the composable semantics.
|
|
612
|
+
*
|
|
613
|
+
* @internal
|
|
614
|
+
*/
|
|
615
|
+
resolveToolFilterOptions(config) {
|
|
616
|
+
const availableTools = toolFilterListToArray(config.availableTools);
|
|
617
|
+
const excludedTools = toolFilterListToArray(config.excludedTools);
|
|
618
|
+
validateToolFilterList("availableTools", availableTools);
|
|
619
|
+
validateToolFilterList("excludedTools", excludedTools);
|
|
620
|
+
if (this.options.mode === "empty") {
|
|
621
|
+
if (availableTools === void 0) {
|
|
622
|
+
throw new Error(
|
|
623
|
+
"CopilotClient is in mode: 'empty' but the session config did not specify 'availableTools'. Empty mode requires every session to explicitly opt into the tools it wants \u2014 e.g. `new ToolSet().addBuiltIn(BuiltInTools.Isolated)`."
|
|
624
|
+
);
|
|
625
|
+
}
|
|
566
626
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
627
|
+
return { availableTools, excludedTools, toolFilterPrecedence: "excluded" };
|
|
628
|
+
}
|
|
629
|
+
/** Mode-specific defaults spread under the caller's config (app values win). */
|
|
630
|
+
configDefaultsForMode() {
|
|
631
|
+
if (this.options.mode === "empty") {
|
|
632
|
+
return {
|
|
633
|
+
enableSessionTelemetry: false,
|
|
634
|
+
mcpOAuthTokenStorage: "in-memory",
|
|
635
|
+
skipEmbeddingRetrieval: true,
|
|
636
|
+
embeddingCacheStorage: "in-memory",
|
|
637
|
+
enableOnDemandInstructionDiscovery: false,
|
|
638
|
+
enableFileHooks: false,
|
|
639
|
+
enableHostGitOperations: false,
|
|
640
|
+
enableSessionStore: false,
|
|
641
|
+
enableSkills: false
|
|
642
|
+
};
|
|
580
643
|
}
|
|
581
|
-
|
|
582
|
-
|
|
644
|
+
return {};
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Returns the systemMessage config to use, adjusted for the current mode.
|
|
648
|
+
* In empty mode we ensure the environment_context section is removed
|
|
649
|
+
* unless the app has already taken control of it. `append` (and
|
|
650
|
+
* unspecified) mode is promoted to `customize` so we can also strip
|
|
651
|
+
* environment_context; the caller's `content` is preserved verbatim
|
|
652
|
+
* because the runtime appends it as additional instructions in both
|
|
653
|
+
* customize and append modes.
|
|
654
|
+
*/
|
|
655
|
+
getSystemMessageConfigForMode(supplied) {
|
|
656
|
+
if (this.options.mode !== "empty") return supplied;
|
|
657
|
+
if (!supplied) {
|
|
658
|
+
return {
|
|
659
|
+
mode: "customize",
|
|
660
|
+
sections: { environment_context: { action: "remove" } }
|
|
661
|
+
};
|
|
583
662
|
}
|
|
584
|
-
|
|
585
|
-
|
|
663
|
+
switch (supplied.mode) {
|
|
664
|
+
case "replace":
|
|
665
|
+
return supplied;
|
|
666
|
+
case "customize":
|
|
667
|
+
if (supplied.sections?.environment_context) return supplied;
|
|
668
|
+
return {
|
|
669
|
+
...supplied,
|
|
670
|
+
sections: {
|
|
671
|
+
...supplied.sections,
|
|
672
|
+
environment_context: { action: "remove" }
|
|
673
|
+
}
|
|
674
|
+
};
|
|
675
|
+
case "append":
|
|
676
|
+
case void 0:
|
|
677
|
+
return {
|
|
678
|
+
mode: "customize",
|
|
679
|
+
content: supplied.content,
|
|
680
|
+
sections: { environment_context: { action: "remove" } }
|
|
681
|
+
};
|
|
586
682
|
}
|
|
587
|
-
|
|
588
|
-
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Mode-specific options applied via session.options.update after create/resume.
|
|
686
|
+
*
|
|
687
|
+
* In empty mode, defaults the four overridable feature flags to safe values
|
|
688
|
+
* (caller values from `config` win). `installedPlugins=[]` is unconditional
|
|
689
|
+
* in empty mode — apps that need custom plugins should switch modes.
|
|
690
|
+
*/
|
|
691
|
+
async updateSessionOptionsForMode(session, config) {
|
|
692
|
+
const patch = {};
|
|
693
|
+
if (this.options.mode === "empty") {
|
|
694
|
+
patch.skipCustomInstructions = config.skipCustomInstructions ?? true;
|
|
695
|
+
patch.customAgentsLocalOnly = config.customAgentsLocalOnly ?? true;
|
|
696
|
+
patch.coauthorEnabled = config.coauthorEnabled ?? false;
|
|
697
|
+
patch.manageScheduleEnabled = config.manageScheduleEnabled ?? false;
|
|
698
|
+
patch.installedPlugins = [];
|
|
699
|
+
} else {
|
|
700
|
+
if (config.skipCustomInstructions !== void 0)
|
|
701
|
+
patch.skipCustomInstructions = config.skipCustomInstructions;
|
|
702
|
+
if (config.customAgentsLocalOnly !== void 0)
|
|
703
|
+
patch.customAgentsLocalOnly = config.customAgentsLocalOnly;
|
|
704
|
+
if (config.coauthorEnabled !== void 0)
|
|
705
|
+
patch.coauthorEnabled = config.coauthorEnabled;
|
|
706
|
+
if (config.manageScheduleEnabled !== void 0)
|
|
707
|
+
patch.manageScheduleEnabled = config.manageScheduleEnabled;
|
|
708
|
+
}
|
|
709
|
+
if (Object.keys(patch).length === 0) {
|
|
710
|
+
return;
|
|
589
711
|
}
|
|
590
|
-
|
|
591
|
-
session.
|
|
712
|
+
try {
|
|
713
|
+
await session.rpc.options.update(patch);
|
|
714
|
+
} catch (e) {
|
|
715
|
+
try {
|
|
716
|
+
await session.disconnect();
|
|
717
|
+
} catch {
|
|
718
|
+
}
|
|
719
|
+
throw e;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
async createSession(config) {
|
|
723
|
+
if (!this.connection) {
|
|
724
|
+
await this.start();
|
|
592
725
|
}
|
|
726
|
+
config = { ...this.configDefaultsForMode(), ...config };
|
|
727
|
+
config.systemMessage = this.getSystemMessageConfigForMode(config.systemMessage);
|
|
728
|
+
const callerSessionId = config.sessionId;
|
|
729
|
+
const useServerGeneratedId = config.cloud != null && callerSessionId == null;
|
|
730
|
+
const localSessionId = useServerGeneratedId ? void 0 : callerSessionId ?? (0, import_node_crypto.randomUUID)();
|
|
593
731
|
const { wirePayload: wireSystemMessage, transformCallbacks } = extractTransformCallbacks(
|
|
594
732
|
config.systemMessage
|
|
595
733
|
);
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
734
|
+
const initializeSession = (sessionId) => {
|
|
735
|
+
const s = new import_session.CopilotSession(
|
|
736
|
+
sessionId,
|
|
737
|
+
this.connection,
|
|
738
|
+
void 0,
|
|
739
|
+
this.onGetTraceContext
|
|
740
|
+
);
|
|
741
|
+
s.registerTools(config.tools);
|
|
742
|
+
s.registerCanvases(config.canvases);
|
|
743
|
+
s.registerCommands(config.commands);
|
|
744
|
+
s.registerPermissionHandler(config.onPermissionRequest);
|
|
745
|
+
if (config.onUserInputRequest) {
|
|
746
|
+
s.registerUserInputHandler(config.onUserInputRequest);
|
|
747
|
+
}
|
|
748
|
+
if (config.onElicitationRequest) {
|
|
749
|
+
s.registerElicitationHandler(config.onElicitationRequest);
|
|
750
|
+
}
|
|
751
|
+
if (config.onExitPlanModeRequest) {
|
|
752
|
+
s.registerExitPlanModeHandler(config.onExitPlanModeRequest);
|
|
753
|
+
}
|
|
754
|
+
if (config.onAutoModeSwitchRequest) {
|
|
755
|
+
s.registerAutoModeSwitchHandler(config.onAutoModeSwitchRequest);
|
|
756
|
+
}
|
|
757
|
+
if (config.hooks) {
|
|
758
|
+
s.registerHooks(config.hooks);
|
|
759
|
+
}
|
|
760
|
+
if (transformCallbacks) {
|
|
761
|
+
s.registerTransformCallbacks(transformCallbacks);
|
|
762
|
+
}
|
|
763
|
+
if (config.onEvent) {
|
|
764
|
+
s.on(config.onEvent);
|
|
765
|
+
}
|
|
766
|
+
this.sessions.set(sessionId, s);
|
|
767
|
+
this.setupSessionFs(s, config);
|
|
768
|
+
return s;
|
|
769
|
+
};
|
|
770
|
+
let session;
|
|
771
|
+
let registeredId;
|
|
772
|
+
if (localSessionId !== void 0) {
|
|
773
|
+
session = initializeSession(localSessionId);
|
|
774
|
+
registeredId = localSessionId;
|
|
601
775
|
}
|
|
602
|
-
this.
|
|
603
|
-
this.setupSessionFs(session, config);
|
|
776
|
+
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
604
777
|
try {
|
|
605
778
|
const response = await this.connection.sendRequest("session.create", {
|
|
606
779
|
...await (0, import_telemetry.getTraceContext)(this.onGetTraceContext),
|
|
607
780
|
model: config.model,
|
|
608
|
-
sessionId,
|
|
781
|
+
sessionId: localSessionId,
|
|
609
782
|
clientName: config.clientName,
|
|
610
783
|
reasoningEffort: config.reasoningEffort,
|
|
784
|
+
reasoningSummary: config.reasoningSummary,
|
|
785
|
+
contextTier: config.contextTier,
|
|
611
786
|
tools: config.tools?.map((tool) => ({
|
|
612
787
|
name: tool.name,
|
|
613
788
|
description: tool.description,
|
|
@@ -618,20 +793,24 @@ class CopilotClient {
|
|
|
618
793
|
canvases: config.canvases?.map((canvas) => canvas.declaration),
|
|
619
794
|
requestCanvasRenderer: config.requestCanvasRenderer,
|
|
620
795
|
requestExtensions: config.requestExtensions,
|
|
796
|
+
extensionSdkPath: config.extensionSdkPath,
|
|
621
797
|
extensionInfo: config.extensionInfo,
|
|
622
798
|
commands: config.commands?.map((cmd) => ({
|
|
623
799
|
name: cmd.name,
|
|
624
800
|
description: cmd.description
|
|
625
801
|
})),
|
|
626
802
|
systemMessage: wireSystemMessage,
|
|
627
|
-
availableTools:
|
|
628
|
-
excludedTools:
|
|
803
|
+
availableTools: toolFilterOptions.availableTools,
|
|
804
|
+
excludedTools: toolFilterOptions.excludedTools,
|
|
805
|
+
toolFilterPrecedence: toolFilterOptions.toolFilterPrecedence,
|
|
629
806
|
provider: config.provider,
|
|
630
807
|
enableSessionTelemetry: config.enableSessionTelemetry,
|
|
631
808
|
modelCapabilities: config.modelCapabilities,
|
|
809
|
+
largeOutput: toWireLargeOutput(config.largeOutput),
|
|
632
810
|
requestPermission: !!config.onPermissionRequest,
|
|
633
811
|
requestUserInput: !!config.onUserInputRequest,
|
|
634
812
|
requestElicitation: !!config.onElicitationRequest,
|
|
813
|
+
...config.enableMcpApps ? { requestMcpApps: true } : {},
|
|
635
814
|
requestExitPlanMode: !!config.onExitPlanModeRequest,
|
|
636
815
|
requestAutoModeSwitch: !!config.onAutoModeSwitchRequest,
|
|
637
816
|
hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)),
|
|
@@ -639,13 +818,23 @@ class CopilotClient {
|
|
|
639
818
|
streaming: config.streaming,
|
|
640
819
|
includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
|
|
641
820
|
mcpServers: toWireMcpServers(config.mcpServers),
|
|
821
|
+
mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
|
|
642
822
|
envValueMode: "direct",
|
|
643
823
|
customAgents: toWireCustomAgents(config.customAgents),
|
|
644
824
|
defaultAgent: config.defaultAgent,
|
|
645
825
|
agent: config.agent,
|
|
646
|
-
configDir: config.
|
|
826
|
+
configDir: config.configDirectory,
|
|
647
827
|
enableConfigDiscovery: config.enableConfigDiscovery,
|
|
828
|
+
skipEmbeddingRetrieval: config.skipEmbeddingRetrieval,
|
|
829
|
+
embeddingCacheStorage: config.embeddingCacheStorage,
|
|
830
|
+
organizationCustomInstructions: config.organizationCustomInstructions,
|
|
831
|
+
enableOnDemandInstructionDiscovery: config.enableOnDemandInstructionDiscovery,
|
|
832
|
+
enableFileHooks: config.enableFileHooks,
|
|
833
|
+
enableHostGitOperations: config.enableHostGitOperations,
|
|
834
|
+
enableSessionStore: config.enableSessionStore,
|
|
835
|
+
enableSkills: config.enableSkills,
|
|
648
836
|
skillDirectories: config.skillDirectories,
|
|
837
|
+
pluginDirectories: config.pluginDirectories,
|
|
649
838
|
instructionDirectories: config.instructionDirectories,
|
|
650
839
|
disabledSkills: config.disabledSkills,
|
|
651
840
|
infiniteSessions: config.infiniteSessions,
|
|
@@ -653,11 +842,30 @@ class CopilotClient {
|
|
|
653
842
|
remoteSession: config.remoteSession,
|
|
654
843
|
cloud: config.cloud
|
|
655
844
|
});
|
|
656
|
-
const {
|
|
845
|
+
const {
|
|
846
|
+
sessionId: returnedSessionId,
|
|
847
|
+
workspacePath,
|
|
848
|
+
capabilities
|
|
849
|
+
} = response;
|
|
850
|
+
if (!returnedSessionId) {
|
|
851
|
+
throw new Error("session.create response did not include a sessionId");
|
|
852
|
+
}
|
|
853
|
+
if (localSessionId !== void 0 && localSessionId !== returnedSessionId) {
|
|
854
|
+
throw new Error(
|
|
855
|
+
`session.create returned sessionId ${returnedSessionId} but the caller requested ${localSessionId}`
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
if (session === void 0) {
|
|
859
|
+
session = initializeSession(returnedSessionId);
|
|
860
|
+
registeredId = returnedSessionId;
|
|
861
|
+
}
|
|
657
862
|
session["_workspacePath"] = workspacePath;
|
|
658
863
|
session.setCapabilities(capabilities);
|
|
864
|
+
await this.updateSessionOptionsForMode(session, config);
|
|
659
865
|
} catch (e) {
|
|
660
|
-
|
|
866
|
+
if (registeredId !== void 0) {
|
|
867
|
+
this.sessions.delete(registeredId);
|
|
868
|
+
}
|
|
661
869
|
throw e;
|
|
662
870
|
}
|
|
663
871
|
return session;
|
|
@@ -715,6 +923,8 @@ class CopilotClient {
|
|
|
715
923
|
if (config.hooks) {
|
|
716
924
|
session.registerHooks(config.hooks);
|
|
717
925
|
}
|
|
926
|
+
config = { ...this.configDefaultsForMode(), ...config };
|
|
927
|
+
config.systemMessage = this.getSystemMessageConfigForMode(config.systemMessage);
|
|
718
928
|
const { wirePayload: wireSystemMessage, transformCallbacks } = extractTransformCallbacks(
|
|
719
929
|
config.systemMessage
|
|
720
930
|
);
|
|
@@ -726,6 +936,7 @@ class CopilotClient {
|
|
|
726
936
|
}
|
|
727
937
|
this.sessions.set(sessionId, session);
|
|
728
938
|
this.setupSessionFs(session, config);
|
|
939
|
+
const toolFilterOptions = this.resolveToolFilterOptions(config);
|
|
729
940
|
try {
|
|
730
941
|
const response = await this.connection.sendRequest("session.resume", {
|
|
731
942
|
...await (0, import_telemetry.getTraceContext)(this.onGetTraceContext),
|
|
@@ -733,9 +944,12 @@ class CopilotClient {
|
|
|
733
944
|
clientName: config.clientName,
|
|
734
945
|
model: config.model,
|
|
735
946
|
reasoningEffort: config.reasoningEffort,
|
|
947
|
+
reasoningSummary: config.reasoningSummary,
|
|
948
|
+
contextTier: config.contextTier,
|
|
736
949
|
systemMessage: wireSystemMessage,
|
|
737
|
-
availableTools:
|
|
738
|
-
excludedTools:
|
|
950
|
+
availableTools: toolFilterOptions.availableTools,
|
|
951
|
+
excludedTools: toolFilterOptions.excludedTools,
|
|
952
|
+
toolFilterPrecedence: toolFilterOptions.toolFilterPrecedence,
|
|
739
953
|
enableSessionTelemetry: config.enableSessionTelemetry,
|
|
740
954
|
tools: config.tools?.map((tool) => ({
|
|
741
955
|
name: tool.name,
|
|
@@ -747,6 +961,7 @@ class CopilotClient {
|
|
|
747
961
|
canvases: config.canvases?.map((canvas) => canvas.declaration),
|
|
748
962
|
requestCanvasRenderer: config.requestCanvasRenderer,
|
|
749
963
|
requestExtensions: config.requestExtensions,
|
|
964
|
+
extensionSdkPath: config.extensionSdkPath,
|
|
750
965
|
extensionInfo: config.extensionInfo,
|
|
751
966
|
commands: config.commands?.map((cmd) => ({
|
|
752
967
|
name: cmd.name,
|
|
@@ -754,27 +969,39 @@ class CopilotClient {
|
|
|
754
969
|
})),
|
|
755
970
|
provider: config.provider,
|
|
756
971
|
modelCapabilities: config.modelCapabilities,
|
|
972
|
+
largeOutput: toWireLargeOutput(config.largeOutput),
|
|
757
973
|
requestPermission: config.onPermissionRequest !== import_types.defaultJoinSessionPermissionHandler,
|
|
758
974
|
requestUserInput: !!config.onUserInputRequest,
|
|
759
975
|
requestElicitation: !!config.onElicitationRequest,
|
|
976
|
+
...config.enableMcpApps ? { requestMcpApps: true } : {},
|
|
760
977
|
requestExitPlanMode: !!config.onExitPlanModeRequest,
|
|
761
978
|
requestAutoModeSwitch: !!config.onAutoModeSwitchRequest,
|
|
762
979
|
hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)),
|
|
763
980
|
workingDirectory: config.workingDirectory,
|
|
764
|
-
configDir: config.
|
|
981
|
+
configDir: config.configDirectory,
|
|
765
982
|
enableConfigDiscovery: config.enableConfigDiscovery,
|
|
983
|
+
skipEmbeddingRetrieval: config.skipEmbeddingRetrieval,
|
|
984
|
+
embeddingCacheStorage: config.embeddingCacheStorage,
|
|
985
|
+
organizationCustomInstructions: config.organizationCustomInstructions,
|
|
986
|
+
enableOnDemandInstructionDiscovery: config.enableOnDemandInstructionDiscovery,
|
|
987
|
+
enableFileHooks: config.enableFileHooks,
|
|
988
|
+
enableHostGitOperations: config.enableHostGitOperations,
|
|
989
|
+
enableSessionStore: config.enableSessionStore,
|
|
990
|
+
enableSkills: config.enableSkills,
|
|
766
991
|
streaming: config.streaming,
|
|
767
992
|
includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
|
|
768
993
|
mcpServers: toWireMcpServers(config.mcpServers),
|
|
994
|
+
mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
|
|
769
995
|
envValueMode: "direct",
|
|
770
996
|
customAgents: toWireCustomAgents(config.customAgents),
|
|
771
997
|
defaultAgent: config.defaultAgent,
|
|
772
998
|
agent: config.agent,
|
|
773
999
|
skillDirectories: config.skillDirectories,
|
|
1000
|
+
pluginDirectories: config.pluginDirectories,
|
|
774
1001
|
instructionDirectories: config.instructionDirectories,
|
|
775
1002
|
disabledSkills: config.disabledSkills,
|
|
776
1003
|
infiniteSessions: config.infiniteSessions,
|
|
777
|
-
|
|
1004
|
+
disableResume: config.suppressResumeEvent,
|
|
778
1005
|
continuePendingWork: config.continuePendingWork,
|
|
779
1006
|
gitHubToken: config.gitHubToken,
|
|
780
1007
|
remoteSession: config.remoteSession,
|
|
@@ -784,6 +1011,7 @@ class CopilotClient {
|
|
|
784
1011
|
session["_workspacePath"] = workspacePath;
|
|
785
1012
|
session.setCapabilities(capabilities);
|
|
786
1013
|
session.setOpenCanvases(openCanvases ?? []);
|
|
1014
|
+
await this.updateSessionOptionsForMode(session, config);
|
|
787
1015
|
} catch (e) {
|
|
788
1016
|
this.sessions.delete(sessionId);
|
|
789
1017
|
throw e;
|
|
@@ -1162,6 +1390,9 @@ class CopilotClient {
|
|
|
1162
1390
|
if (this.options.baseDirectory) {
|
|
1163
1391
|
envWithoutNodeDebug.COPILOT_HOME = this.options.baseDirectory;
|
|
1164
1392
|
}
|
|
1393
|
+
if (this.options.mode === "empty") {
|
|
1394
|
+
envWithoutNodeDebug.COPILOT_DISABLE_KEYTAR = "1";
|
|
1395
|
+
}
|
|
1165
1396
|
if (!this.resolvedCliPath) {
|
|
1166
1397
|
throw new Error(
|
|
1167
1398
|
"Path to Copilot CLI is required. Please supply it via `RuntimeConnection.forStdio({ path })` or `RuntimeConnection.forTcp({ path })`, set the COPILOT_CLI_PATH environment variable, or use `RuntimeConnection.forUri(...)` to connect to an already-running runtime."
|
package/dist/cjs/extension.js
CHANGED
|
@@ -35,8 +35,10 @@ async function joinSession(config = {}) {
|
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
const client = new import_client.CopilotClient({ _internalConnection: { kind: "parent-process" } });
|
|
38
|
+
const { extensionSdkPath: _stripped, ...rest } = config;
|
|
39
|
+
void _stripped;
|
|
38
40
|
return client.resumeSession(sessionId, {
|
|
39
|
-
...
|
|
41
|
+
...rest,
|
|
40
42
|
onPermissionRequest: config.onPermissionRequest ?? import_types.defaultJoinSessionPermissionHandler,
|
|
41
43
|
suppressResumeEvent: config.suppressResumeEvent ?? true
|
|
42
44
|
});
|