-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathextension.ts
More file actions
143 lines (135 loc) · 4.87 KB
/
Copy pathextension.ts
File metadata and controls
143 lines (135 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
import { CopilotClient } from "./client.js";
import type { CopilotSession } from "./session.js";
import {
defaultJoinSessionPermissionHandler,
type PermissionHandler,
type ResumeSessionConfig,
} from "./types.js";
import type { FactoryHandle } from "./factory.js";
export {
Canvas,
CanvasError,
createCanvas,
type CanvasAction,
type CanvasDeclaration,
type CanvasHostContext,
type CanvasJsonSchema,
type CanvasOptions,
} from "./canvas.js";
export type JoinSessionConfig = Omit<
ResumeSessionConfig,
"onPermissionRequest" | "extensionSdkPath"
> & {
onPermissionRequest?: PermissionHandler;
/**
* Names of sensitive environment variables this extension needs, such as
* `"GITHUB_TOKEN"`.
*
* The Copilot CLI strips sensitive variables from every extension process
* before it starts, so an extension that needs one must ask for it by name.
* The CLI prompts the user with the extension's name and the exact list of
* variables requested. On approval the granted values are written into this
* process's `process.env` before {@link joinSession} resolves, so they are
* readable afterwards. On denial the join rejects and the extension does not
* load, so its tools never reach the model.
*
* An approval is remembered against the exact set of names the user saw, so
* asking for an additional variable later prompts again. Names that are unset
* or that the CLI does not filter from extensions are not prompted for. An
* empty list means the same as omitting the option: nothing is requested.
*
* Requires a Copilot CLI that supports extension environment access; older
* CLIs ignore the request and grant nothing.
*
* @example
* ```typescript
* const session = await joinSession({
* requestedEnvironmentVariables: ["GITHUB_TOKEN"],
* });
* const token = process.env.GITHUB_TOKEN;
* ```
*/
requestedEnvironmentVariables?: string[];
/**
* Factory handles to register when the extension joins the session.
*
* @experimental Part of the experimental Agent Factories surface and may
* change or be removed in future SDK or CLI releases.
*/
factories?: FactoryHandle[];
};
export type { ExtensionInfo, FactoryLimits, FactoryMeta } from "./types.js";
export {
defineFactory,
FactoryResumeError,
isFactoryRunTerminal,
type RunOptions,
type ResumeOptions,
type FactoryResumeErrorCode,
type SessionFactoryApi,
type FactoryAgentOptions,
type FactoryContext,
type FactoryDefinition,
type FactoryHandle,
type FactoryJsonSchema,
type JsonValue,
type FactoryPipelineStage,
type FactoryStepOptions,
type FactoryRunResult,
type FactoryRunStatus,
type FactoryRunSummary,
type FactoryRunDetail,
type FactoryProgressPage,
type FactoryProgressLine,
type FactoryPhaseObservation,
type FactoryPhaseStatus,
type FactoryAgentSummary,
} from "./factory.js";
/**
* Joins the current foreground session.
*
* @param config - Configuration to add to the session
* @returns A promise that resolves with the joined session
*
* @example
* ```typescript
* import { joinSession } from "@github/copilot-sdk/extension";
*
* const session = await joinSession({ tools: [myTool] });
* ```
*/
export async function joinSession(config: JoinSessionConfig = {}): Promise<CopilotSession> {
const sessionId = process.env.SESSION_ID;
if (!sessionId) {
throw new Error(
"joinSession() is intended for extensions running as child processes of the Copilot CLI."
);
}
const client = new CopilotClient({ _internalConnection: { kind: "parent-process" } });
// Strip `extensionSdkPath` at runtime even though `JoinSessionConfig` omits it
// at the type level — untyped (JS) callers can still slip it through, and
// honoring it here would be misleading since the extension subprocess has
// already been forked by the host with the SDK the host chose.
const {
extensionSdkPath: _stripped,
factories,
requestedEnvironmentVariables,
...rest
} = config as JoinSessionConfig & {
extensionSdkPath?: string;
};
void _stripped;
return client.resumeSessionForExtension(
sessionId,
{
...rest,
onPermissionRequest: config.onPermissionRequest ?? defaultJoinSessionPermissionHandler,
suppressResumeEvent: config.suppressResumeEvent ?? true,
},
factories,
requestedEnvironmentVariables?.length ? { requestedEnvironmentVariables } : undefined
);
}