@theia/ai-copilot 1.75.0 → 1.76.0-next.10
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 +86 -14
- package/lib/browser/copilot-auth-dialog.d.ts.map +1 -1
- package/lib/browser/copilot-auth-dialog.js +12 -4
- package/lib/browser/copilot-auth-dialog.js.map +1 -1
- package/lib/browser/copilot-frontend-application-contribution.d.ts +15 -1
- package/lib/browser/copilot-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/copilot-frontend-application-contribution.js +52 -24
- package/lib/browser/copilot-frontend-application-contribution.js.map +1 -1
- package/lib/common/copilot-auth-service.d.ts +27 -24
- package/lib/common/copilot-auth-service.d.ts.map +1 -1
- package/lib/common/copilot-language-models-manager.d.ts +3 -21
- package/lib/common/copilot-language-models-manager.d.ts.map +1 -1
- package/lib/common/copilot-language-models-manager.js +1 -13
- package/lib/common/copilot-language-models-manager.js.map +1 -1
- package/lib/common/copilot-preferences.d.ts +1 -0
- package/lib/common/copilot-preferences.d.ts.map +1 -1
- package/lib/common/copilot-preferences.js +24 -6
- package/lib/common/copilot-preferences.js.map +1 -1
- package/lib/common/index.d.ts +0 -1
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +0 -1
- package/lib/common/index.js.map +1 -1
- package/lib/node/copilot-auth-service-impl.d.ts +25 -16
- package/lib/node/copilot-auth-service-impl.d.ts.map +1 -1
- package/lib/node/copilot-auth-service-impl.js +67 -183
- package/lib/node/copilot-auth-service-impl.js.map +1 -1
- package/lib/node/copilot-auth-service-impl.spec.js +104 -168
- package/lib/node/copilot-auth-service-impl.spec.js.map +1 -1
- package/lib/node/copilot-backend-module.d.ts.map +1 -1
- package/lib/node/copilot-backend-module.js +10 -2
- package/lib/node/copilot-backend-module.js.map +1 -1
- package/lib/node/copilot-cli-auth-provider.d.ts +146 -0
- package/lib/node/copilot-cli-auth-provider.d.ts.map +1 -0
- package/lib/node/copilot-cli-auth-provider.js +430 -0
- package/lib/node/copilot-cli-auth-provider.js.map +1 -0
- package/lib/node/copilot-cli-auth-provider.spec.d.ts +2 -0
- package/lib/node/copilot-cli-auth-provider.spec.d.ts.map +1 -0
- package/lib/node/copilot-cli-auth-provider.spec.js +249 -0
- package/lib/node/copilot-cli-auth-provider.spec.js.map +1 -0
- package/lib/node/copilot-cli-locator.d.ts +120 -0
- package/lib/node/copilot-cli-locator.d.ts.map +1 -0
- package/lib/node/copilot-cli-locator.js +348 -0
- package/lib/node/copilot-cli-locator.js.map +1 -0
- package/lib/node/copilot-cli-locator.spec.d.ts +2 -0
- package/lib/node/copilot-cli-locator.spec.d.ts.map +1 -0
- package/lib/node/copilot-cli-locator.spec.js +327 -0
- package/lib/node/copilot-cli-locator.spec.js.map +1 -0
- package/lib/node/copilot-credential-store.d.ts +45 -0
- package/lib/node/copilot-credential-store.d.ts.map +1 -0
- package/lib/node/copilot-credential-store.js +96 -0
- package/lib/node/copilot-credential-store.js.map +1 -0
- package/lib/node/copilot-credential-store.spec.d.ts +2 -0
- package/lib/node/copilot-credential-store.spec.d.ts.map +1 -0
- package/lib/node/copilot-credential-store.spec.js +93 -0
- package/lib/node/copilot-credential-store.spec.js.map +1 -0
- package/lib/node/copilot-language-models-manager-impl.d.ts +20 -18
- package/lib/node/copilot-language-models-manager-impl.d.ts.map +1 -1
- package/lib/node/copilot-language-models-manager-impl.js +39 -67
- package/lib/node/copilot-language-models-manager-impl.js.map +1 -1
- package/lib/node/copilot-language-models-manager-impl.spec.d.ts +2 -0
- package/lib/node/copilot-language-models-manager-impl.spec.d.ts.map +1 -0
- package/lib/node/copilot-language-models-manager-impl.spec.js +119 -0
- package/lib/node/copilot-language-models-manager-impl.spec.js.map +1 -0
- package/lib/node/copilot-runtime-env.d.ts +20 -0
- package/lib/node/copilot-runtime-env.d.ts.map +1 -0
- package/lib/node/copilot-runtime-env.js +49 -0
- package/lib/node/copilot-runtime-env.js.map +1 -0
- package/lib/node/copilot-sdk-client-provider.d.ts +103 -0
- package/lib/node/copilot-sdk-client-provider.d.ts.map +1 -0
- package/lib/node/copilot-sdk-client-provider.js +247 -0
- package/lib/node/copilot-sdk-client-provider.js.map +1 -0
- package/lib/node/copilot-sdk-client-provider.spec.d.ts +2 -0
- package/lib/node/copilot-sdk-client-provider.spec.d.ts.map +1 -0
- package/lib/node/copilot-sdk-client-provider.spec.js +215 -0
- package/lib/node/copilot-sdk-client-provider.spec.js.map +1 -0
- package/lib/node/copilot-sdk-language-model.d.ts +85 -0
- package/lib/node/copilot-sdk-language-model.d.ts.map +1 -0
- package/lib/node/copilot-sdk-language-model.js +301 -0
- package/lib/node/copilot-sdk-language-model.js.map +1 -0
- package/lib/node/copilot-sdk-language-model.spec.d.ts +2 -0
- package/lib/node/copilot-sdk-language-model.spec.d.ts.map +1 -0
- package/lib/node/copilot-sdk-language-model.spec.js +302 -0
- package/lib/node/copilot-sdk-language-model.spec.js.map +1 -0
- package/lib/node/copilot-sdk-loader.d.ts +57 -0
- package/lib/node/copilot-sdk-loader.d.ts.map +1 -0
- package/lib/node/copilot-sdk-loader.js +133 -0
- package/lib/node/copilot-sdk-loader.js.map +1 -0
- package/lib/node/copilot-sdk-loader.spec.d.ts +2 -0
- package/lib/node/copilot-sdk-loader.spec.d.ts.map +1 -0
- package/lib/node/copilot-sdk-loader.spec.js +113 -0
- package/lib/node/copilot-sdk-loader.spec.js.map +1 -0
- package/lib/node/copilot-sdk-mappers.d.ts +49 -0
- package/lib/node/copilot-sdk-mappers.d.ts.map +1 -0
- package/lib/node/copilot-sdk-mappers.js +147 -0
- package/lib/node/copilot-sdk-mappers.js.map +1 -0
- package/lib/node/copilot-sdk-mappers.spec.d.ts +2 -0
- package/lib/node/copilot-sdk-mappers.spec.d.ts.map +1 -0
- package/lib/node/copilot-sdk-mappers.spec.js +133 -0
- package/lib/node/copilot-sdk-mappers.spec.js.map +1 -0
- package/lib/node/copilot-sdk-types.d.ts +198 -0
- package/lib/node/copilot-sdk-types.d.ts.map +1 -0
- package/lib/{common/copilot-oauth-config.js → node/copilot-sdk-types.js} +2 -13
- package/lib/node/copilot-sdk-types.js.map +1 -0
- package/lib/node/index.d.ts +9 -1
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +9 -1
- package/lib/node/index.js.map +1 -1
- package/package.json +4 -6
- package/src/browser/copilot-auth-dialog.tsx +12 -8
- package/src/browser/copilot-frontend-application-contribution.ts +62 -29
- package/src/common/copilot-auth-service.ts +28 -24
- package/src/common/copilot-language-models-manager.ts +3 -28
- package/src/common/copilot-preferences.ts +24 -5
- package/src/common/index.ts +0 -1
- package/src/node/copilot-auth-service-impl.spec.ts +122 -207
- package/src/node/copilot-auth-service-impl.ts +63 -218
- package/src/node/copilot-backend-module.ts +11 -2
- package/src/node/copilot-cli-auth-provider.spec.ts +315 -0
- package/src/node/copilot-cli-auth-provider.ts +444 -0
- package/src/node/copilot-cli-locator.spec.ts +386 -0
- package/src/node/copilot-cli-locator.ts +363 -0
- package/src/node/copilot-credential-store.spec.ts +106 -0
- package/src/node/copilot-credential-store.ts +99 -0
- package/src/node/copilot-language-models-manager-impl.spec.ts +137 -0
- package/src/node/copilot-language-models-manager-impl.ts +51 -85
- package/src/node/copilot-runtime-env.ts +46 -0
- package/src/node/copilot-sdk-client-provider.spec.ts +253 -0
- package/src/node/copilot-sdk-client-provider.ts +241 -0
- package/src/node/copilot-sdk-language-model.spec.ts +363 -0
- package/src/node/copilot-sdk-language-model.ts +329 -0
- package/src/node/copilot-sdk-loader.spec.ts +126 -0
- package/src/node/copilot-sdk-loader.ts +142 -0
- package/src/node/copilot-sdk-mappers.spec.ts +151 -0
- package/src/node/copilot-sdk-mappers.ts +161 -0
- package/src/node/copilot-sdk-types.ts +276 -0
- package/src/node/index.ts +9 -1
- package/lib/common/copilot-oauth-config.d.ts +0 -33
- package/lib/common/copilot-oauth-config.d.ts.map +0 -1
- package/lib/common/copilot-oauth-config.js.map +0 -1
- package/lib/node/copilot-language-model.d.ts +0 -34
- package/lib/node/copilot-language-model.d.ts.map +0 -1
- package/lib/node/copilot-language-model.js +0 -236
- package/lib/node/copilot-language-model.js.map +0 -1
- package/lib/node/copilot-language-model.spec.d.ts +0 -2
- package/lib/node/copilot-language-model.spec.d.ts.map +0 -1
- package/lib/node/copilot-language-model.spec.js +0 -89
- package/lib/node/copilot-language-model.spec.js.map +0 -1
- package/src/common/copilot-oauth-config.ts +0 -55
- package/src/node/copilot-language-model.spec.ts +0 -106
- package/src/node/copilot-language-model.ts +0 -273
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH and others.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.CopilotSdkClientProvider = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const fs_1 = require("fs");
|
|
21
|
+
const path_1 = require("path");
|
|
22
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
23
|
+
const core_1 = require("@theia/core");
|
|
24
|
+
const env_variables_1 = require("@theia/core/lib/common/env-variables");
|
|
25
|
+
const file_uri_1 = require("@theia/core/lib/common/file-uri");
|
|
26
|
+
const copilot_credential_store_1 = require("./copilot-credential-store");
|
|
27
|
+
const copilot_cli_locator_1 = require("./copilot-cli-locator");
|
|
28
|
+
const copilot_runtime_env_1 = require("./copilot-runtime-env");
|
|
29
|
+
const copilot_sdk_loader_1 = require("./copilot-sdk-loader");
|
|
30
|
+
const copilot_sdk_mappers_1 = require("./copilot-sdk-mappers");
|
|
31
|
+
/**
|
|
32
|
+
* Manages the lifecycle of a {@link CopilotClient}, which spawns and talks to the
|
|
33
|
+
* official Copilot CLI over JSON-RPC.
|
|
34
|
+
*
|
|
35
|
+
* The runtime is given the token this application holds, and nothing else: credentials the CLI could
|
|
36
|
+
* otherwise pick up on its own, from the environment or from the sign-in of the GitHub CLI, are not a
|
|
37
|
+
* sign-in of this application and are deliberately kept out of reach. The token is established by
|
|
38
|
+
* {@link CopilotCliAuthProvider} and kept in {@link CopilotCredentialStore}.
|
|
39
|
+
*
|
|
40
|
+
* A single client is started lazily and shared for the lifetime of the (connection-scoped) backend
|
|
41
|
+
* container. It is recreated when the host configuration changes.
|
|
42
|
+
*
|
|
43
|
+
* Note: this provider is bound in the per-connection container, so each frontend connection runs
|
|
44
|
+
* its own CLI process, authenticated with the credentials of the backend host. This is not suitable
|
|
45
|
+
* for multi-user backend deployments, where every connected frontend would share a single identity.
|
|
46
|
+
*/
|
|
47
|
+
let CopilotSdkClientProvider = class CopilotSdkClientProvider {
|
|
48
|
+
/**
|
|
49
|
+
* Returns a started {@link CopilotClient}, creating (or recreating, if the
|
|
50
|
+
* configuration changed) one on demand.
|
|
51
|
+
*/
|
|
52
|
+
async getClient() {
|
|
53
|
+
const credentials = await this.credentialStore.get();
|
|
54
|
+
if (!credentials) {
|
|
55
|
+
throw new Error(core_1.nls.localize('theia/ai/copilot/notSignedInSignInFirst', 'Not signed in to GitHub Copilot. Please sign in first.'));
|
|
56
|
+
}
|
|
57
|
+
const configKey = this.getConfigKey(credentials);
|
|
58
|
+
if (this.clientPromise && this.clientConfigKey === configKey) {
|
|
59
|
+
return this.clientPromise;
|
|
60
|
+
}
|
|
61
|
+
// First use or changed credentials: (re)create the client. Capture the
|
|
62
|
+
// previous client and assign synchronously so concurrent callers share
|
|
63
|
+
// the same promise instead of spawning multiple CLI processes.
|
|
64
|
+
const previous = this.clientPromise;
|
|
65
|
+
this.clientConfigKey = configKey;
|
|
66
|
+
this.clientPromise = this.recreate(configKey, credentials, previous);
|
|
67
|
+
return this.clientPromise;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Lists the model IDs available to the authenticated user via the Copilot CLI.
|
|
71
|
+
* Because the CLI runs under an entitled identity, this returns the full current model lineup
|
|
72
|
+
* rather than the baseline set that the direct REST API exposes to an unentitled OAuth app.
|
|
73
|
+
*/
|
|
74
|
+
async listModelIds() {
|
|
75
|
+
const client = await this.getClient();
|
|
76
|
+
try {
|
|
77
|
+
const models = await client.listModels();
|
|
78
|
+
return (0, copilot_sdk_mappers_1.selectSdkModelIds)(models);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
throw this.enrichEntitlementError(error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Replaces the bare authorization failure of the Copilot runtime with an explanation of the
|
|
86
|
+
* possible causes, because the runtime only reports that the feature is not authorized.
|
|
87
|
+
*/
|
|
88
|
+
enrichEntitlementError(error) {
|
|
89
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
90
|
+
if (!message.includes('not authorized to use this Copilot feature') && !message.includes('Access denied by policy settings')) {
|
|
91
|
+
return error;
|
|
92
|
+
}
|
|
93
|
+
return new Error(core_1.nls.localize('theia/ai/copilot/notAuthorized', 'GitHub Copilot rejected the request as not authorized for this account. Either the account has no Copilot subscription, or '
|
|
94
|
+
+ 'access has to be enabled by an administrator through an organization or enterprise policy. Signing out and in again also '
|
|
95
|
+
+ 'renews credentials that were revoked. GitHub reports requests sent to an API host that does not match the subscription the '
|
|
96
|
+
+ 'same way, so as a last resort the host can be set explicitly with the `COPILOT_API_URL` environment variable of the backend. '
|
|
97
|
+
+ 'Reported by the Copilot runtime: {0}', message));
|
|
98
|
+
}
|
|
99
|
+
getConfigKey(credentials) {
|
|
100
|
+
return `${credentials.enterpriseUrl ?? ''}|${credentials.token}`;
|
|
101
|
+
}
|
|
102
|
+
async recreate(configKey, credentials, previous) {
|
|
103
|
+
if (previous) {
|
|
104
|
+
try {
|
|
105
|
+
const previousClient = await previous;
|
|
106
|
+
await previousClient.stop();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
this.logger.warn('Copilot SDK: failed to stop previous client:', error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const sdk = await this.sdkLoader.load();
|
|
113
|
+
const client = new sdk.CopilotClient(this.createClientOptions(sdk, credentials, await this.cliLocator.resolve(), await this.getCopilotHome()));
|
|
114
|
+
try {
|
|
115
|
+
await client.start();
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
// Don't cache a failed start, otherwise every later call replays the rejection.
|
|
119
|
+
if (this.clientConfigKey === configKey) {
|
|
120
|
+
this.clientPromise = undefined;
|
|
121
|
+
this.clientConfigKey = undefined;
|
|
122
|
+
}
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
return client;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Builds the options of the {@link CopilotClient}.
|
|
129
|
+
*
|
|
130
|
+
* The token of this application is passed explicitly and the resolution of a logged-in user is
|
|
131
|
+
* switched off, so that the runtime cannot fall back to credentials this application does not own.
|
|
132
|
+
*
|
|
133
|
+
* The CLI is passed explicitly as well, see {@link CopilotCliLocator}: the SDK would otherwise look
|
|
134
|
+
* for the JavaScript entry point of a platform package installed next to itself and spawn it with
|
|
135
|
+
* `process.execPath`, which is the Electron binary rather than Node.js in an Electron application.
|
|
136
|
+
*
|
|
137
|
+
* The runtime is configured in `empty` mode rather than in the `copilot-cli` mode the SDK defaults
|
|
138
|
+
* to. That mode brings the ambient behaviour of the CLI along, which the SDK documents as unsuitable
|
|
139
|
+
* for an application serving requests on a backend: instructions and skills found on the host,
|
|
140
|
+
* session and memory stores, host git operations and plugins. Theia drives the conversation itself
|
|
141
|
+
* and declares the tools of each request, so none of that applies, and `empty` mode additionally
|
|
142
|
+
* keeps the runtime away from the system keychain. Its two requirements are met here, a persistence
|
|
143
|
+
* location ({@link getCopilotHome}) and an explicit tool list per session.
|
|
144
|
+
*/
|
|
145
|
+
createClientOptions(sdk, credentials, cliPath, baseDirectory) {
|
|
146
|
+
return {
|
|
147
|
+
connection: sdk.RuntimeConnection.forStdio({ path: cliPath }),
|
|
148
|
+
mode: 'empty',
|
|
149
|
+
baseDirectory,
|
|
150
|
+
gitHubToken: credentials.token,
|
|
151
|
+
useLoggedInUser: false,
|
|
152
|
+
logLevel: 'error',
|
|
153
|
+
env: this.createRuntimeEnv(credentials)
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The Copilot home the runtime is pointed at, below the configuration directory of Theia.
|
|
158
|
+
*
|
|
159
|
+
* Requests are served in sessions that the runtime persists in its home, and the default home is
|
|
160
|
+
* the one the user's own Copilot CLI uses. Prompts sent from Theia would end up listed among the
|
|
161
|
+
* conversations the user started themselves, so this application keeps its own.
|
|
162
|
+
*/
|
|
163
|
+
async getCopilotHome() {
|
|
164
|
+
const configDirectory = file_uri_1.FileUri.fsPath(new core_1.URI(await this.envVariablesServer.getConfigDirUri()));
|
|
165
|
+
const home = (0, path_1.join)(configDirectory, 'copilot');
|
|
166
|
+
await fs_1.promises.mkdir(home, { recursive: true });
|
|
167
|
+
return home;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns the environment for the runtime process.
|
|
171
|
+
*
|
|
172
|
+
* Tokens from the environment are removed: the runtime accepts them even when a token is passed
|
|
173
|
+
* explicitly, and they are not a sign-in of this application. The GitHub host is taken from the
|
|
174
|
+
* credentials, so that the runtime always talks to the deployment that was signed in to.
|
|
175
|
+
*
|
|
176
|
+
* The Copilot API endpoint is deliberately not set: the runtime resolves the one belonging to the
|
|
177
|
+
* subscription from the token, including for Business and Enterprise seats. The environment of the
|
|
178
|
+
* backend is inherited as-is, so an operator can still override it with `COPILOT_API_URL` should
|
|
179
|
+
* that resolution ever fail for a deployment.
|
|
180
|
+
*/
|
|
181
|
+
createRuntimeEnv(credentials) {
|
|
182
|
+
return {
|
|
183
|
+
...copilot_runtime_env_1.CopilotRuntimeEnv.withoutTokens(process.env),
|
|
184
|
+
...(credentials.enterpriseUrl ? { COPILOT_GH_HOST: credentials.enterpriseUrl } : {})
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Stops and clears the current client. Safe to call when no client exists.
|
|
189
|
+
*/
|
|
190
|
+
async reset() {
|
|
191
|
+
const previous = this.clientPromise;
|
|
192
|
+
this.clientPromise = undefined;
|
|
193
|
+
this.clientConfigKey = undefined;
|
|
194
|
+
if (previous) {
|
|
195
|
+
try {
|
|
196
|
+
const client = await previous;
|
|
197
|
+
await client.stop();
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
this.logger.warn('Copilot SDK: failed to stop client during reset:', error);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Stops the CLI when the container this provider lives in goes away, which happens when the
|
|
206
|
+
* frontend connection it belongs to is closed.
|
|
207
|
+
*
|
|
208
|
+
* A closing connection unbinds its container, and unbinding runs `@preDestroy` rather than
|
|
209
|
+
* `dispose`. Without this hook the CLI of every closed connection would keep running for the rest
|
|
210
|
+
* of the lifetime of the backend.
|
|
211
|
+
*/
|
|
212
|
+
async stop() {
|
|
213
|
+
await this.reset();
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
exports.CopilotSdkClientProvider = CopilotSdkClientProvider;
|
|
217
|
+
tslib_1.__decorate([
|
|
218
|
+
(0, inversify_1.inject)(copilot_credential_store_1.CopilotCredentialStore),
|
|
219
|
+
tslib_1.__metadata("design:type", copilot_credential_store_1.CopilotCredentialStore)
|
|
220
|
+
], CopilotSdkClientProvider.prototype, "credentialStore", void 0);
|
|
221
|
+
tslib_1.__decorate([
|
|
222
|
+
(0, inversify_1.inject)(copilot_cli_locator_1.CopilotCliLocator),
|
|
223
|
+
tslib_1.__metadata("design:type", copilot_cli_locator_1.CopilotCliLocator)
|
|
224
|
+
], CopilotSdkClientProvider.prototype, "cliLocator", void 0);
|
|
225
|
+
tslib_1.__decorate([
|
|
226
|
+
(0, inversify_1.inject)(copilot_sdk_loader_1.CopilotSdkLoader),
|
|
227
|
+
tslib_1.__metadata("design:type", copilot_sdk_loader_1.CopilotSdkLoader)
|
|
228
|
+
], CopilotSdkClientProvider.prototype, "sdkLoader", void 0);
|
|
229
|
+
tslib_1.__decorate([
|
|
230
|
+
(0, inversify_1.inject)(env_variables_1.EnvVariablesServer),
|
|
231
|
+
tslib_1.__metadata("design:type", Object)
|
|
232
|
+
], CopilotSdkClientProvider.prototype, "envVariablesServer", void 0);
|
|
233
|
+
tslib_1.__decorate([
|
|
234
|
+
(0, inversify_1.inject)(core_1.ILogger),
|
|
235
|
+
(0, inversify_1.named)('ai-copilot:CopilotSdkClientProvider'),
|
|
236
|
+
tslib_1.__metadata("design:type", Object)
|
|
237
|
+
], CopilotSdkClientProvider.prototype, "logger", void 0);
|
|
238
|
+
tslib_1.__decorate([
|
|
239
|
+
(0, inversify_1.preDestroy)(),
|
|
240
|
+
tslib_1.__metadata("design:type", Function),
|
|
241
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
242
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
243
|
+
], CopilotSdkClientProvider.prototype, "stop", null);
|
|
244
|
+
exports.CopilotSdkClientProvider = CopilotSdkClientProvider = tslib_1.__decorate([
|
|
245
|
+
(0, inversify_1.injectable)()
|
|
246
|
+
], CopilotSdkClientProvider);
|
|
247
|
+
//# sourceMappingURL=copilot-sdk-client-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sdk-client-provider.js","sourceRoot":"","sources":["../../src/node/copilot-sdk-client-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sdk-client-provider.spec.d.ts","sourceRoot":"","sources":["../../src/node/copilot-sdk-client-provider.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH and others.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const chai_1 = require("chai");
|
|
19
|
+
const fs_1 = require("fs");
|
|
20
|
+
const os = require("os");
|
|
21
|
+
const path_1 = require("path");
|
|
22
|
+
const mock_logger_1 = require("@theia/core/lib/common/test/mock-logger");
|
|
23
|
+
const file_uri_1 = require("@theia/core/lib/common/file-uri");
|
|
24
|
+
const copilot_sdk_client_provider_1 = require("./copilot-sdk-client-provider");
|
|
25
|
+
/** The SDK as the provider uses it: a client constructor and the stdio connection factory. */
|
|
26
|
+
function sdkStub() {
|
|
27
|
+
const started = [];
|
|
28
|
+
const stopped = [];
|
|
29
|
+
class StubClient {
|
|
30
|
+
constructor(options) {
|
|
31
|
+
this.options = options;
|
|
32
|
+
}
|
|
33
|
+
async start() {
|
|
34
|
+
started.push(String(this.options?.gitHubToken));
|
|
35
|
+
}
|
|
36
|
+
async stop() {
|
|
37
|
+
stopped.push(String(this.options?.gitHubToken));
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
async listModels() {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
api: {
|
|
46
|
+
CopilotClient: StubClient,
|
|
47
|
+
RuntimeConnection: { forStdio: (options) => ({ kind: 'stdio', ...options }) }
|
|
48
|
+
},
|
|
49
|
+
started,
|
|
50
|
+
stopped
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
class TestableCopilotSdkClientProvider extends copilot_sdk_client_provider_1.CopilotSdkClientProvider {
|
|
54
|
+
constructor(sdk, configDirectory, cli = (0, path_1.join)('/opt', 'copilot', 'copilot')) {
|
|
55
|
+
super();
|
|
56
|
+
this.credentials = { token: 'gho_first' };
|
|
57
|
+
Object.assign(this, {
|
|
58
|
+
logger: new mock_logger_1.MockLogger(),
|
|
59
|
+
credentialStore: { get: async () => this.credentials },
|
|
60
|
+
cliLocator: { resolve: async () => cli },
|
|
61
|
+
sdkLoader: { load: async () => sdk },
|
|
62
|
+
envVariablesServer: { getConfigDirUri: async () => file_uri_1.FileUri.create(configDirectory).toString() }
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
callCreateRuntimeEnv(credentials) {
|
|
66
|
+
return this.createRuntimeEnv(credentials);
|
|
67
|
+
}
|
|
68
|
+
callEnrichEntitlementError(error) {
|
|
69
|
+
return this.enrichEntitlementError(error);
|
|
70
|
+
}
|
|
71
|
+
clientOptions(client) {
|
|
72
|
+
return client.options;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
describe('CopilotSdkClientProvider - client options', () => {
|
|
76
|
+
let configDirectory;
|
|
77
|
+
let sdk;
|
|
78
|
+
beforeEach(async () => {
|
|
79
|
+
configDirectory = await fs_1.promises.mkdtemp((0, path_1.join)(os.tmpdir(), 'theia-copilot-config-'));
|
|
80
|
+
sdk = sdkStub();
|
|
81
|
+
});
|
|
82
|
+
afterEach(async () => {
|
|
83
|
+
await fs_1.promises.rm(configDirectory, { recursive: true, force: true });
|
|
84
|
+
});
|
|
85
|
+
it('should hand the located CLI and the token of this application to the runtime', async () => {
|
|
86
|
+
const provider = new TestableCopilotSdkClientProvider(sdk.api, configDirectory);
|
|
87
|
+
const options = provider.clientOptions(await provider.getClient());
|
|
88
|
+
(0, chai_1.expect)(options?.connection).to.deep.equal({ kind: 'stdio', path: (0, path_1.join)('/opt', 'copilot', 'copilot') });
|
|
89
|
+
(0, chai_1.expect)(options?.gitHubToken).to.equal('gho_first');
|
|
90
|
+
// Nothing the runtime finds on the host may make it appear signed in.
|
|
91
|
+
(0, chai_1.expect)(options?.useLoggedInUser).to.be.false;
|
|
92
|
+
});
|
|
93
|
+
it('should keep the runtime out of the ambient behaviour of the CLI', async () => {
|
|
94
|
+
const provider = new TestableCopilotSdkClientProvider(sdk.api, configDirectory);
|
|
95
|
+
const options = provider.clientOptions(await provider.getClient());
|
|
96
|
+
(0, chai_1.expect)(options?.mode).to.equal('empty');
|
|
97
|
+
});
|
|
98
|
+
it('should point the runtime at a Copilot home of the application and create it', async () => {
|
|
99
|
+
const provider = new TestableCopilotSdkClientProvider(sdk.api, configDirectory);
|
|
100
|
+
const options = provider.clientOptions(await provider.getClient());
|
|
101
|
+
const home = (0, path_1.join)(configDirectory, 'copilot');
|
|
102
|
+
// Compared without case, because the URI of the configuration directory lowercases the drive
|
|
103
|
+
// letter on Windows, which addresses the same location.
|
|
104
|
+
(0, chai_1.expect)(options?.baseDirectory?.toLowerCase()).to.equal(home.toLowerCase());
|
|
105
|
+
(0, chai_1.expect)((await fs_1.promises.stat(home)).isDirectory()).to.be.true;
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('CopilotSdkClientProvider - runtime environment', () => {
|
|
109
|
+
const provider = new TestableCopilotSdkClientProvider(sdkStub().api, os.tmpdir());
|
|
110
|
+
it('should remove tokens of the environment, which are not a sign-in of this application', () => {
|
|
111
|
+
const previous = { ...process.env };
|
|
112
|
+
try {
|
|
113
|
+
process.env.GITHUB_TOKEN = 'gho_environment';
|
|
114
|
+
process.env.GH_TOKEN = 'gho_environment';
|
|
115
|
+
process.env.COPILOT_GITHUB_TOKEN = 'gho_environment';
|
|
116
|
+
const env = provider.callCreateRuntimeEnv({ token: 'gho_ours' });
|
|
117
|
+
(0, chai_1.expect)(env.GITHUB_TOKEN).to.be.undefined;
|
|
118
|
+
(0, chai_1.expect)(env.GH_TOKEN).to.be.undefined;
|
|
119
|
+
(0, chai_1.expect)(env.COPILOT_GITHUB_TOKEN).to.be.undefined;
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
process.env = previous;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
it('should remove a token variable whatever its case, since Windows ignores it', () => {
|
|
126
|
+
const previous = { ...process.env };
|
|
127
|
+
try {
|
|
128
|
+
process.env.Gh_Token = 'gho_environment';
|
|
129
|
+
const env = provider.callCreateRuntimeEnv({ token: 'gho_ours' });
|
|
130
|
+
(0, chai_1.expect)(Object.keys(env).some(name => name.toLowerCase() === 'gh_token')).to.be.false;
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
process.env = previous;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
it('should point the runtime at the deployment that was signed in to', () => {
|
|
137
|
+
const env = provider.callCreateRuntimeEnv({ token: 'gho_ours', enterpriseUrl: 'company.ghe.com' });
|
|
138
|
+
(0, chai_1.expect)(env.COPILOT_GH_HOST).to.equal('company.ghe.com');
|
|
139
|
+
});
|
|
140
|
+
it('should leave the host alone for a sign-in against GitHub.com', () => {
|
|
141
|
+
(0, chai_1.expect)(provider.callCreateRuntimeEnv({ token: 'gho_ours' })).to.not.have.property('COPILOT_GH_HOST');
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe('CopilotSdkClientProvider - lifecycle', () => {
|
|
145
|
+
let configDirectory;
|
|
146
|
+
let sdk;
|
|
147
|
+
let provider;
|
|
148
|
+
beforeEach(async () => {
|
|
149
|
+
configDirectory = await fs_1.promises.mkdtemp((0, path_1.join)(os.tmpdir(), 'theia-copilot-config-'));
|
|
150
|
+
sdk = sdkStub();
|
|
151
|
+
provider = new TestableCopilotSdkClientProvider(sdk.api, configDirectory);
|
|
152
|
+
});
|
|
153
|
+
afterEach(async () => {
|
|
154
|
+
await fs_1.promises.rm(configDirectory, { recursive: true, force: true });
|
|
155
|
+
});
|
|
156
|
+
it('should reject when the application is not signed in', async () => {
|
|
157
|
+
provider.credentials = undefined;
|
|
158
|
+
try {
|
|
159
|
+
await provider.getClient();
|
|
160
|
+
chai_1.expect.fail('should have rejected');
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
(0, chai_1.expect)(String(error)).to.contain('sign in');
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
it('should start one CLI and share it, also for concurrent callers', async () => {
|
|
167
|
+
const [first, second] = await Promise.all([provider.getClient(), provider.getClient()]);
|
|
168
|
+
(0, chai_1.expect)(first).to.equal(second);
|
|
169
|
+
(0, chai_1.expect)(await provider.getClient()).to.equal(first);
|
|
170
|
+
(0, chai_1.expect)(sdk.started).to.deep.equal(['gho_first']);
|
|
171
|
+
});
|
|
172
|
+
it('should replace the client when the credentials changed, stopping the previous one', async () => {
|
|
173
|
+
const first = await provider.getClient();
|
|
174
|
+
provider.credentials = { token: 'gho_second' };
|
|
175
|
+
const second = await provider.getClient();
|
|
176
|
+
(0, chai_1.expect)(second).to.not.equal(first);
|
|
177
|
+
(0, chai_1.expect)(sdk.started).to.deep.equal(['gho_first', 'gho_second']);
|
|
178
|
+
(0, chai_1.expect)(sdk.stopped).to.deep.equal(['gho_first']);
|
|
179
|
+
});
|
|
180
|
+
it('should stop the CLI on reset and start a new one afterwards', async () => {
|
|
181
|
+
await provider.getClient();
|
|
182
|
+
await provider.reset();
|
|
183
|
+
(0, chai_1.expect)(sdk.stopped).to.deep.equal(['gho_first']);
|
|
184
|
+
await provider.getClient();
|
|
185
|
+
(0, chai_1.expect)(sdk.started).to.deep.equal(['gho_first', 'gho_first']);
|
|
186
|
+
});
|
|
187
|
+
it('should not cache a client whose runtime failed to start', async () => {
|
|
188
|
+
const failing = sdkStub();
|
|
189
|
+
failing.api.CopilotClient = class {
|
|
190
|
+
async start() {
|
|
191
|
+
throw new Error('runtime did not come up');
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const other = new TestableCopilotSdkClientProvider(failing.api, configDirectory);
|
|
195
|
+
await other.getClient().catch(() => { });
|
|
196
|
+
// A cached rejection would keep replaying instead of trying again.
|
|
197
|
+
await other.getClient().catch(error => (0, chai_1.expect)(String(error)).to.contain('did not come up'));
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
describe('CopilotSdkClientProvider - entitlement errors', () => {
|
|
201
|
+
const provider = new TestableCopilotSdkClientProvider(sdkStub().api, os.tmpdir());
|
|
202
|
+
it('should explain what an authorization failure of the runtime can mean', () => {
|
|
203
|
+
const enriched = provider.callEnrichEntitlementError(new Error('user is not authorized to use this Copilot feature'));
|
|
204
|
+
(0, chai_1.expect)(String(enriched)).to.contain('subscription');
|
|
205
|
+
(0, chai_1.expect)(String(enriched)).to.contain('not authorized to use this Copilot feature');
|
|
206
|
+
});
|
|
207
|
+
it('should explain a policy rejection the same way', () => {
|
|
208
|
+
(0, chai_1.expect)(String(provider.callEnrichEntitlementError(new Error('Access denied by policy settings')))).to.contain('administrator');
|
|
209
|
+
});
|
|
210
|
+
it('should pass an unrelated failure through unchanged', () => {
|
|
211
|
+
const error = new Error('socket hang up');
|
|
212
|
+
(0, chai_1.expect)(provider.callEnrichEntitlementError(error)).to.equal(error);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=copilot-sdk-client-provider.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sdk-client-provider.spec.js","sourceRoot":"","sources":["../../src/node/copilot-sdk-client-provider.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,+BAA8B;AAC9B,2BAAoC;AACpC,yBAAyB;AACzB,+BAA4B;AAC5B,yEAAqE;AACrE,8DAA0D;AAE1D,+EAAyE;AAYzE,8FAA8F;AAC9F,SAAS,OAAO;IACZ,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,UAAU;QACZ,YAAqB,OAA8B;YAA9B,YAAO,GAAP,OAAO,CAAuB;QAAI,CAAC;QACxD,KAAK,CAAC,KAAK;YACP,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,CAAC,IAAI;YACN,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;YAChD,OAAO,EAAE,CAAC;QACd,CAAC;QACD,KAAK,CAAC,UAAU;YACZ,OAAO,EAAE,CAAC;QACd,CAAC;KACJ;IACD,OAAO;QACH,GAAG,EAAE;YACD,aAAa,EAAE,UAA8E;YAC7F,iBAAiB,EAAE,EAAE,QAAQ,EAAE,CAAC,OAAyB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE;SAClG;QACD,OAAO;QACP,OAAO;KACV,CAAC;AACN,CAAC;AAED,MAAM,gCAAiC,SAAQ,sDAAwB;IAInE,YAAY,GAAmB,EAAE,eAAuB,EAAE,GAAG,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC;QAC9F,KAAK,EAAE,CAAC;QAHZ,gBAAW,GAAmC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QAIjE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;YAChB,MAAM,EAAE,IAAI,wBAAU,EAAE;YACxB,eAAe,EAAE,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE;YACtD,UAAU,EAAE,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE;YACxC,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE;YACpC,kBAAkB,EAAE,EAAE,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,kBAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,EAAE;SAClG,CAAC,CAAC;IACP,CAAC;IAED,oBAAoB,CAAC,WAA+B;QAChD,OAAO,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAED,0BAA0B,CAAC,KAAc;QACrC,OAAO,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,aAAa,CAAC,MAAqB;QAC/B,OAAQ,MAAwD,CAAC,OAAO,CAAC;IAC7E,CAAC;CACJ;AAED,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IAEvD,IAAI,eAAuB,CAAC;IAC5B,IAAI,GAA+B,CAAC;IAEpC,UAAU,CAAC,KAAK,IAAI,EAAE;QAClB,eAAe,GAAG,MAAM,aAAE,CAAC,OAAO,CAAC,IAAA,WAAI,EAAC,EAAE,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;QAC/E,GAAG,GAAG,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,aAAE,CAAC,EAAE,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,QAAQ,GAAG,IAAI,gCAAgC,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QACnE,IAAA,aAAM,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAA,WAAI,EAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;QACvG,IAAA,aAAM,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACnD,sEAAsE;QACtE,IAAA,aAAM,EAAC,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,QAAQ,GAAG,IAAI,gCAAgC,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QACnE,IAAA,aAAM,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,QAAQ,GAAG,IAAI,gCAAgC,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,IAAA,WAAI,EAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QAC9C,6FAA6F;QAC7F,wDAAwD;QACxD,IAAA,aAAM,EAAC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3E,IAAA,aAAM,EAAC,CAAC,MAAM,aAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC3D,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAE5D,MAAM,QAAQ,GAAG,IAAI,gCAAgC,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAElF,EAAE,CAAC,sFAAsF,EAAE,GAAG,EAAE;QAC5F,MAAM,QAAQ,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACpC,IAAI,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,iBAAiB,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,iBAAiB,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,iBAAiB,CAAC;YACrD,MAAM,GAAG,GAAG,QAAQ,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YACjE,IAAA,aAAM,EAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC;YACzC,IAAA,aAAM,EAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC;YACrC,IAAA,aAAM,EAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC;QACrD,CAAC;gBAAS,CAAC;YACP,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC;QAC3B,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QAClF,MAAM,QAAQ,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACpC,IAAI,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,iBAAiB,CAAC;YACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YACjE,IAAA,aAAM,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACzF,CAAC;gBAAS,CAAC;YACP,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC;QAC3B,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QACxE,MAAM,GAAG,GAAG,QAAQ,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACnG,IAAA,aAAM,EAAC,GAAG,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACpE,IAAA,aAAM,EAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IACzG,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IAElD,IAAI,eAAuB,CAAC;IAC5B,IAAI,GAA+B,CAAC;IACpC,IAAI,QAA0C,CAAC;IAE/C,UAAU,CAAC,KAAK,IAAI,EAAE;QAClB,eAAe,GAAG,MAAM,aAAE,CAAC,OAAO,CAAC,IAAA,WAAI,EAAC,EAAE,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;QAC/E,GAAG,GAAG,OAAO,EAAE,CAAC;QAChB,QAAQ,GAAG,IAAI,gCAAgC,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,aAAE,CAAC,EAAE,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACjE,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC;YACD,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC3B,aAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAA,aAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACxF,IAAA,aAAM,EAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAA,aAAM,EAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnD,IAAA,aAAM,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;QACzC,QAAQ,CAAC,WAAW,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,IAAA,aAAM,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;QAC/D,IAAA,aAAM,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QACvB,IAAA,aAAM,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QACjD,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC3B,IAAA,aAAM,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG;YACxB,KAAK,CAAC,KAAK;gBACP,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;YAC/C,CAAC;SACkC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,gCAAgC,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QACjF,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAkB,CAAC,CAAC,CAAC;QACxD,mEAAmE;QACnE,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAA,aAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAE3D,MAAM,QAAQ,GAAG,IAAI,gCAAgC,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAElF,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC5E,MAAM,QAAQ,GAAG,QAAQ,CAAC,0BAA0B,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC;QACtH,IAAA,aAAM,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpD,IAAA,aAAM,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACtD,IAAA,aAAM,EAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAC,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACnI,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC1D,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC1C,IAAA,aAAM,EAAC,QAAQ,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { LanguageModel, LanguageModelResponse, LanguageModelStatus, LanguageModelStreamResponsePart, ToolRequest, UserRequest } from '@theia/ai-core';
|
|
2
|
+
import { CancellationToken, ILogger } from '@theia/core';
|
|
3
|
+
import type { CopilotClient, CopilotSession, PermissionHandler, Tool } from './copilot-sdk-types';
|
|
4
|
+
/**
|
|
5
|
+
* Answers the permission requests of the CLI for the tools of a request.
|
|
6
|
+
*
|
|
7
|
+
* Only Theia's own tools are declared to the CLI, and those are gated by Theia's tool confirmation
|
|
8
|
+
* already, so a second confirmation by the CLI would ask the user the same question twice. This is
|
|
9
|
+
* the behaviour of the SDK's own `approveAll`, which cannot be used here because it is not imported
|
|
10
|
+
* at runtime.
|
|
11
|
+
*
|
|
12
|
+
* A request that managed policy reserves for an explicit decision is not approved on the user's
|
|
13
|
+
* behalf but denied as unconfirmable. Leaving it unanswered is what the SDK's `no-result` does, and
|
|
14
|
+
* it is only correct when another client is connected that can answer it; here it would leave the
|
|
15
|
+
* turn pending until the request is cancelled.
|
|
16
|
+
*/
|
|
17
|
+
export declare const approveTheiaTools: PermissionHandler;
|
|
18
|
+
/**
|
|
19
|
+
* Collects the stream parts produced by the session events and by the tool handlers, and hands them
|
|
20
|
+
* to the consuming generator as they arrive.
|
|
21
|
+
*
|
|
22
|
+
* A buffer is needed because the parts originate from callbacks rather than from a stream we can
|
|
23
|
+
* await, and because the tool handlers of a turn run while its response is still being produced.
|
|
24
|
+
*/
|
|
25
|
+
export declare class CopilotStreamSink {
|
|
26
|
+
protected readonly queue: LanguageModelStreamResponsePart[];
|
|
27
|
+
protected readonly flushWaiters: Array<() => void>;
|
|
28
|
+
protected notify: (() => void) | undefined;
|
|
29
|
+
protected done: boolean;
|
|
30
|
+
protected failure: unknown;
|
|
31
|
+
push(part: LanguageModelStreamResponsePart): void;
|
|
32
|
+
/**
|
|
33
|
+
* Resolves once everything pushed so far has been taken by the consumer.
|
|
34
|
+
*
|
|
35
|
+
* Needed because a tool call has to be reported before the tool runs: the caller creates the
|
|
36
|
+
* record of the call from the stream, and the tool handler then completes that record. Handing the
|
|
37
|
+
* part over and invoking the handler in the same turn would leave the handler with nothing to
|
|
38
|
+
* complete.
|
|
39
|
+
*/
|
|
40
|
+
flush(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Ends the stream. A given error is raised to the consumer once the buffered parts are drained.
|
|
43
|
+
*/
|
|
44
|
+
finish(error?: unknown): void;
|
|
45
|
+
drain(): AsyncIterable<LanguageModelStreamResponsePart>;
|
|
46
|
+
protected wake(): void;
|
|
47
|
+
protected releaseFlushWaiters(): void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Language model implementation for GitHub Copilot backed by the official Copilot
|
|
51
|
+
* CLI via `@github/copilot-sdk`.
|
|
52
|
+
*
|
|
53
|
+
* The CLI is an agent that owns the tool-calling loop, whereas Theia's language model contract
|
|
54
|
+
* expects the caller to drive it. The two are reconciled by handing the tools of the request to the
|
|
55
|
+
* CLI as custom tools whose handlers delegate back to Theia, and by reporting every invocation as a
|
|
56
|
+
* tool call part, so that the conversation and its tool calls are recorded and rendered as usual.
|
|
57
|
+
* None of the CLI's own tools are exposed, so only what Theia provides can run.
|
|
58
|
+
*
|
|
59
|
+
* Structured output is not supported on this path.
|
|
60
|
+
*/
|
|
61
|
+
export declare class CopilotSdkLanguageModel implements LanguageModel {
|
|
62
|
+
readonly id: string;
|
|
63
|
+
model: string;
|
|
64
|
+
status: LanguageModelStatus;
|
|
65
|
+
maxRetries: number;
|
|
66
|
+
protected readonly clientProvider: () => Promise<CopilotClient>;
|
|
67
|
+
protected readonly logger: ILogger;
|
|
68
|
+
constructor(id: string, model: string, status: LanguageModelStatus, maxRetries: number, clientProvider: () => Promise<CopilotClient>, logger: ILogger);
|
|
69
|
+
request(request: UserRequest, cancellationToken?: CancellationToken): Promise<LanguageModelResponse>;
|
|
70
|
+
/**
|
|
71
|
+
* Maps the tools of the request onto tools of the CLI, reporting each invocation to the stream.
|
|
72
|
+
*/
|
|
73
|
+
protected createTools(tools: ToolRequest[], sink: CopilotStreamSink): Tool[];
|
|
74
|
+
protected delay(ms: number): Promise<void>;
|
|
75
|
+
protected streamResponse(client: CopilotClient, session: CopilotSession, prompt: string, sink: CopilotStreamSink, cancellationToken?: CancellationToken): AsyncIterable<LanguageModelStreamResponsePart>;
|
|
76
|
+
/**
|
|
77
|
+
* Ends the session of a request and removes what it persisted.
|
|
78
|
+
*
|
|
79
|
+
* Disconnecting only releases the session in memory and keeps it stored for a later resumption,
|
|
80
|
+
* which Theia never does: it drives the conversation itself and starts a fresh session per
|
|
81
|
+
* request. Without the deletion, every request would leave a session behind in the Copilot home.
|
|
82
|
+
*/
|
|
83
|
+
protected discardSession(client: CopilotClient, session: CopilotSession): Promise<void>;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=copilot-sdk-language-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sdk-language-model.d.ts","sourceRoot":"","sources":["../../src/node/copilot-sdk-language-model.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEH,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,+BAA+B,EAC/B,WAAW,EACX,WAAW,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAGlG;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBAK/B,CAAC;AAOF;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAE1B,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,+BAA+B,EAAE,CAAM;IACjE,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACxD,SAAS,CAAC,MAAM,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3C,SAAS,CAAC,IAAI,UAAS;IACvB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAE3B,IAAI,CAAC,IAAI,EAAE,+BAA+B,GAAG,IAAI;IAKjD;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAQtB,KAAK,IAAI,aAAa,CAAC,+BAA+B,CAAC;IAkB9D,SAAS,CAAC,IAAI,IAAI,IAAI;IAMtB,SAAS,CAAC,mBAAmB,IAAI,IAAI;CAMxC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAwB,YAAW,aAAa;aAGrC,EAAE,EAAE,MAAM;IACnB,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,mBAAmB;IAC3B,UAAU,EAAE,MAAM;IACzB,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC;IAC/D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;gBALlB,EAAE,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,MAAM,EACN,cAAc,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,EAC5C,MAAM,EAAE,OAAO;IAGhC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA2B1G;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,iBAAiB,GAAG,IAAI,EAAE;IA4C5E,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAIzB,cAAc,CAC3B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,EACvB,iBAAiB,CAAC,EAAE,iBAAiB,GACtC,aAAa,CAAC,+BAA+B,CAAC;IAsEjD;;;;;;OAMG;cACa,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAYhG"}
|