@theia/ai-copilot 1.76.0-next.4 → 1.76.0-next.42
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 +87 -14
- package/lib/browser/copilot-auth-dialog.d.ts.map +1 -1
- package/lib/browser/copilot-auth-dialog.js +19 -11
- package/lib/browser/copilot-auth-dialog.js.map +1 -1
- package/lib/browser/copilot-frontend-application-contribution.d.ts +21 -1
- package/lib/browser/copilot-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/copilot-frontend-application-contribution.js +129 -26
- 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 +6 -22
- 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 +44 -20
- package/lib/node/copilot-language-models-manager-impl.d.ts.map +1 -1
- package/lib/node/copilot-language-models-manager-impl.js +112 -65
- 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 +162 -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 +315 -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 +54 -0
- package/lib/node/copilot-sdk-mappers.d.ts.map +1 -0
- package/lib/node/copilot-sdk-mappers.js +158 -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 +168 -0
- package/lib/node/copilot-sdk-mappers.spec.js.map +1 -0
- package/lib/node/copilot-sdk-types.d.ts +208 -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 +20 -16
- package/src/browser/copilot-frontend-application-contribution.ts +144 -31
- package/src/common/copilot-auth-service.ts +28 -24
- package/src/common/copilot-language-models-manager.ts +6 -29
- 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 +188 -0
- package/src/node/copilot-language-models-manager-impl.ts +131 -84
- 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 +377 -0
- package/src/node/copilot-sdk-language-model.ts +330 -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 +190 -0
- package/src/node/copilot-sdk-mappers.ts +172 -0
- package/src/node/copilot-sdk-types.ts +290 -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,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The part of the Copilot SDK API this integration uses, mirrored by hand.
|
|
3
|
+
*
|
|
4
|
+
* Mirrored from `@github/copilot-sdk` 1.0.9 (protocol version 3), which the Copilot CLI 1.0.79 ships.
|
|
5
|
+
* The package is deliberately not a dependency: it depends on the CLI, a large proprietary binary that
|
|
6
|
+
* would end up in the tree and the lockfile of every application. The CLI is a prerequisite on the
|
|
7
|
+
* backend host instead, see `CopilotCliLocator`, and the SDK is loaded from it at runtime, see
|
|
8
|
+
* `CopilotSdkLoader`.
|
|
9
|
+
*
|
|
10
|
+
* Only what this integration passes to the SDK or reads from it is declared, so a drift shows up as a
|
|
11
|
+
* compile error here rather than at runtime. `scripts/copilot-sdk-mirror` checks the mirror against a
|
|
12
|
+
* released SDK and runs in CI on a schedule; update the version above along with the declarations.
|
|
13
|
+
*/
|
|
14
|
+
export interface ModelPolicy {
|
|
15
|
+
state: 'enabled' | 'disabled' | 'unconfigured';
|
|
16
|
+
}
|
|
17
|
+
/** A model as reported by {@link CopilotClient.listModels}. */
|
|
18
|
+
export interface ModelInfo {
|
|
19
|
+
/** Model identifier, for example `claude-sonnet-4.5`. */
|
|
20
|
+
id: string;
|
|
21
|
+
policy?: ModelPolicy;
|
|
22
|
+
}
|
|
23
|
+
/** The sections the runtime assembles its system prompt from. Unknown ids are a silent no-op there. */
|
|
24
|
+
export type SystemMessageSection = 'preamble' | 'identity' | 'tone' | 'tool_efficiency' | 'environment_context' | 'code_change_rules' | 'guidelines' | 'safety' | 'tool_instructions' | 'custom_instructions' | 'runtime_instructions' | 'last_instructions';
|
|
25
|
+
export type SectionTransformFn = (currentContent: string) => string | Promise<string>;
|
|
26
|
+
export type SectionOverrideAction = 'replace' | 'remove' | 'append' | 'prepend' | 'preserve' | SectionTransformFn;
|
|
27
|
+
export interface SectionOverride {
|
|
28
|
+
action: SectionOverrideAction;
|
|
29
|
+
content?: string;
|
|
30
|
+
}
|
|
31
|
+
/** The SDK foundation plus the given content. */
|
|
32
|
+
export interface SystemMessageAppendConfig {
|
|
33
|
+
mode?: 'append';
|
|
34
|
+
content?: string;
|
|
35
|
+
}
|
|
36
|
+
/** The given content as the entire system message. */
|
|
37
|
+
export interface SystemMessageReplaceConfig {
|
|
38
|
+
mode: 'replace';
|
|
39
|
+
content: string;
|
|
40
|
+
}
|
|
41
|
+
/** The SDK structure with section-level overrides, which is what this integration uses. */
|
|
42
|
+
export interface SystemMessageCustomizeConfig {
|
|
43
|
+
mode: 'customize';
|
|
44
|
+
sections?: Partial<Record<SystemMessageSection, SectionOverride>>;
|
|
45
|
+
content?: string;
|
|
46
|
+
}
|
|
47
|
+
export type SystemMessageConfig = SystemMessageAppendConfig | SystemMessageReplaceConfig | SystemMessageCustomizeConfig;
|
|
48
|
+
/** What the runtime tells a tool handler about its invocation. */
|
|
49
|
+
export interface ToolInvocation {
|
|
50
|
+
sessionId: string;
|
|
51
|
+
toolCallId: string;
|
|
52
|
+
toolName: string;
|
|
53
|
+
arguments: unknown;
|
|
54
|
+
}
|
|
55
|
+
export type ToolHandler = (args: unknown, invocation: ToolInvocation) => Promise<unknown> | unknown;
|
|
56
|
+
/** A tool declared to the runtime. `parameters` also accepts a Zod schema upstream. */
|
|
57
|
+
export interface Tool {
|
|
58
|
+
name: string;
|
|
59
|
+
description?: string;
|
|
60
|
+
parameters?: Record<string, unknown>;
|
|
61
|
+
handler?: ToolHandler;
|
|
62
|
+
/** When true, the tool runs without a permission prompt of the runtime. */
|
|
63
|
+
skipPermission?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A permission request of the runtime, upstream a union over the kind of operation with its own fields.
|
|
67
|
+
* Only `managedApprovalRequired` is read, which managed policy sets for a request it reserves for the
|
|
68
|
+
* user.
|
|
69
|
+
*/
|
|
70
|
+
export interface PermissionRequest {
|
|
71
|
+
readonly kind: string;
|
|
72
|
+
readonly managedApprovalRequired?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/** The decisions this integration can return. Upstream also has scopes that outlive a request. */
|
|
75
|
+
export type PermissionRequestResult = {
|
|
76
|
+
kind: 'approve-once';
|
|
77
|
+
} | {
|
|
78
|
+
kind: 'reject';
|
|
79
|
+
feedback?: string;
|
|
80
|
+
}
|
|
81
|
+
/** No user is available to confirm the request. */
|
|
82
|
+
| {
|
|
83
|
+
kind: 'user-not-available';
|
|
84
|
+
}
|
|
85
|
+
/** Leaves the request pending, so that another connected client can answer it. */
|
|
86
|
+
| {
|
|
87
|
+
kind: 'no-result';
|
|
88
|
+
};
|
|
89
|
+
export type PermissionHandler = (request: PermissionRequest, invocation: {
|
|
90
|
+
sessionId: string;
|
|
91
|
+
managedSettingsEnabled?: boolean;
|
|
92
|
+
}) => Promise<PermissionRequestResult> | PermissionRequestResult;
|
|
93
|
+
/** The envelope every session event comes in. */
|
|
94
|
+
export interface SessionEvent<T extends string, D> {
|
|
95
|
+
readonly type: T;
|
|
96
|
+
readonly data: D;
|
|
97
|
+
}
|
|
98
|
+
/** The session events this integration listens to, keyed by their type discriminator. */
|
|
99
|
+
export interface CopilotSessionEvents {
|
|
100
|
+
'assistant.message_delta': SessionEvent<'assistant.message_delta', {
|
|
101
|
+
readonly deltaContent: string;
|
|
102
|
+
}>;
|
|
103
|
+
'assistant.reasoning_delta': SessionEvent<'assistant.reasoning_delta', {
|
|
104
|
+
readonly deltaContent: string;
|
|
105
|
+
}>;
|
|
106
|
+
'assistant.message': SessionEvent<'assistant.message', {
|
|
107
|
+
readonly content: string;
|
|
108
|
+
readonly outputTokens?: number;
|
|
109
|
+
}>;
|
|
110
|
+
'assistant.usage': SessionEvent<'assistant.usage', {
|
|
111
|
+
readonly inputTokens?: number;
|
|
112
|
+
readonly outputTokens?: number;
|
|
113
|
+
}>;
|
|
114
|
+
/** Nothing of its payload is read, the event itself is the signal that the turn is over. */
|
|
115
|
+
'session.idle': SessionEvent<'session.idle', unknown>;
|
|
116
|
+
'session.error': SessionEvent<'session.error', {
|
|
117
|
+
readonly errorType: string;
|
|
118
|
+
readonly message: string;
|
|
119
|
+
readonly statusCode?: number;
|
|
120
|
+
readonly stack?: string;
|
|
121
|
+
}>;
|
|
122
|
+
}
|
|
123
|
+
export type CopilotSessionEventType = keyof CopilotSessionEvents;
|
|
124
|
+
/** The one attachment kind this integration produces: an inline image, from `MessageOptions['attachments']`. */
|
|
125
|
+
export interface BlobMessageAttachment {
|
|
126
|
+
type: 'blob';
|
|
127
|
+
data: string;
|
|
128
|
+
mimeType: string;
|
|
129
|
+
displayName?: string;
|
|
130
|
+
}
|
|
131
|
+
/** The options this integration passes to {@link CopilotSession.send}. */
|
|
132
|
+
export interface MessageOptions {
|
|
133
|
+
prompt: string;
|
|
134
|
+
attachments?: BlobMessageAttachment[];
|
|
135
|
+
}
|
|
136
|
+
/** A conversation with the runtime, upstream a class with resume, fork and sharing on top. */
|
|
137
|
+
export interface CopilotSession {
|
|
138
|
+
readonly sessionId: string;
|
|
139
|
+
/**
|
|
140
|
+
* Registers a handler for one type of event and returns the function that removes it again.
|
|
141
|
+
*/
|
|
142
|
+
on<K extends CopilotSessionEventType>(eventType: K, handler: (event: CopilotSessionEvents[K]) => void): () => void;
|
|
143
|
+
/** Sends a turn and resolves with the id of the message it created. */
|
|
144
|
+
send(options: MessageOptions): Promise<string>;
|
|
145
|
+
/** Stops the turn in flight. */
|
|
146
|
+
abort(): Promise<void>;
|
|
147
|
+
/** Releases the session in memory, leaving what it persisted in place. */
|
|
148
|
+
disconnect(): Promise<void>;
|
|
149
|
+
}
|
|
150
|
+
/** How the SDK reaches the runtime. This integration always spawns the CLI it located. */
|
|
151
|
+
export interface StdioRuntimeConnection {
|
|
152
|
+
readonly kind: 'stdio';
|
|
153
|
+
readonly path?: string;
|
|
154
|
+
readonly args?: readonly string[];
|
|
155
|
+
readonly env?: Record<string, string>;
|
|
156
|
+
}
|
|
157
|
+
export type RuntimeConnection = StdioRuntimeConnection;
|
|
158
|
+
/** The `RuntimeConnection` value of the SDK, of which only the stdio factory is used. */
|
|
159
|
+
export interface RuntimeConnectionFactory {
|
|
160
|
+
readonly forStdio: (options?: {
|
|
161
|
+
path?: string;
|
|
162
|
+
args?: readonly string[];
|
|
163
|
+
env?: Record<string, string>;
|
|
164
|
+
}) => StdioRuntimeConnection;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Selects the defaults of the runtime: `copilot-cli` brings the ambient behaviour of the CLI along,
|
|
168
|
+
* `empty` requires the application to opt into what it needs.
|
|
169
|
+
*/
|
|
170
|
+
export type CopilotClientMode = 'empty' | 'copilot-cli';
|
|
171
|
+
/** The client options this integration sets. */
|
|
172
|
+
export interface CopilotClientOptions {
|
|
173
|
+
connection?: RuntimeConnection;
|
|
174
|
+
mode?: CopilotClientMode;
|
|
175
|
+
/** Copilot home of the runtime, which becomes its `COPILOT_HOME`. Required in `empty` mode. */
|
|
176
|
+
baseDirectory?: string;
|
|
177
|
+
logLevel?: 'none' | 'error' | 'warning' | 'info' | 'debug' | 'all';
|
|
178
|
+
env?: Record<string, string | undefined>;
|
|
179
|
+
gitHubToken?: string;
|
|
180
|
+
/** When false, only an explicit token is used and no sign-in found on the host. */
|
|
181
|
+
useLoggedInUser?: boolean;
|
|
182
|
+
}
|
|
183
|
+
/** The session configuration this integration passes. */
|
|
184
|
+
export interface SessionConfig {
|
|
185
|
+
model?: string;
|
|
186
|
+
streaming?: boolean;
|
|
187
|
+
tools?: Tool[];
|
|
188
|
+
systemMessage?: SystemMessageConfig;
|
|
189
|
+
/**
|
|
190
|
+
* The tools to enable, as source-qualified patterns such as `custom:*` or `builtin:<name>`.
|
|
191
|
+
* Required in `empty` mode.
|
|
192
|
+
*/
|
|
193
|
+
availableTools?: string[];
|
|
194
|
+
onPermissionRequest?: PermissionHandler;
|
|
195
|
+
}
|
|
196
|
+
/** The runtime as seen by this integration, upstream a class with the full session and status API. */
|
|
197
|
+
export interface CopilotClient {
|
|
198
|
+
/** Starts the runtime and connects to it. */
|
|
199
|
+
start(): Promise<void>;
|
|
200
|
+
/** Stops the runtime and resolves with the errors its cleanup ran into, if any. */
|
|
201
|
+
stop(): Promise<Error[]>;
|
|
202
|
+
listModels(): Promise<ModelInfo[]>;
|
|
203
|
+
createSession(config: SessionConfig): Promise<CopilotSession>;
|
|
204
|
+
/** Removes a session and what it persisted in the Copilot home. */
|
|
205
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
206
|
+
}
|
|
207
|
+
export type CopilotClientConstructor = new (options?: CopilotClientOptions) => CopilotClient;
|
|
208
|
+
//# sourceMappingURL=copilot-sdk-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sdk-types.d.ts","sourceRoot":"","sources":["../../src/node/copilot-sdk-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// *****************************************************************************
|
|
3
|
-
// Copyright (C) 2026
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH and others.
|
|
4
4
|
//
|
|
5
5
|
// This program and the accompanying materials are made available under the
|
|
6
6
|
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -15,15 +15,4 @@
|
|
|
15
15
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
|
|
19
|
-
exports.CopilotOAuthConfig = Symbol('CopilotOAuthConfig');
|
|
20
|
-
/**
|
|
21
|
-
* Default OAuth configuration for the built-in Theia Copilot integration.
|
|
22
|
-
*/
|
|
23
|
-
exports.DEFAULT_COPILOT_OAUTH_CONFIG = {
|
|
24
|
-
clientId: 'Ov23liS2vINy9VOAweyv',
|
|
25
|
-
userAgent: 'Theia-Copilot/1.0.0',
|
|
26
|
-
keystoreService: 'theia-copilot-auth',
|
|
27
|
-
keystoreAccount: 'github-copilot'
|
|
28
|
-
};
|
|
29
|
-
//# sourceMappingURL=copilot-oauth-config.js.map
|
|
18
|
+
//# sourceMappingURL=copilot-sdk-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sdk-types.js","sourceRoot":"","sources":["../../src/node/copilot-sdk-types.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"}
|
package/lib/node/index.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export * from './copilot-auth-service-impl';
|
|
2
|
-
export * from './copilot-language-model';
|
|
3
2
|
export * from './copilot-language-models-manager-impl';
|
|
3
|
+
export * from './copilot-cli-auth-provider';
|
|
4
|
+
export * from './copilot-cli-locator';
|
|
5
|
+
export * from './copilot-credential-store';
|
|
6
|
+
export * from './copilot-runtime-env';
|
|
7
|
+
export * from './copilot-sdk-client-provider';
|
|
8
|
+
export * from './copilot-sdk-loader';
|
|
9
|
+
export * from './copilot-sdk-mappers';
|
|
10
|
+
export * from './copilot-sdk-language-model';
|
|
11
|
+
export * from './copilot-sdk-types';
|
|
4
12
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/node/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wCAAwC,CAAC;AACvD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC"}
|
package/lib/node/index.js
CHANGED
|
@@ -17,6 +17,14 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
const tslib_1 = require("tslib");
|
|
19
19
|
tslib_1.__exportStar(require("./copilot-auth-service-impl"), exports);
|
|
20
|
-
tslib_1.__exportStar(require("./copilot-language-model"), exports);
|
|
21
20
|
tslib_1.__exportStar(require("./copilot-language-models-manager-impl"), exports);
|
|
21
|
+
tslib_1.__exportStar(require("./copilot-cli-auth-provider"), exports);
|
|
22
|
+
tslib_1.__exportStar(require("./copilot-cli-locator"), exports);
|
|
23
|
+
tslib_1.__exportStar(require("./copilot-credential-store"), exports);
|
|
24
|
+
tslib_1.__exportStar(require("./copilot-runtime-env"), exports);
|
|
25
|
+
tslib_1.__exportStar(require("./copilot-sdk-client-provider"), exports);
|
|
26
|
+
tslib_1.__exportStar(require("./copilot-sdk-loader"), exports);
|
|
27
|
+
tslib_1.__exportStar(require("./copilot-sdk-mappers"), exports);
|
|
28
|
+
tslib_1.__exportStar(require("./copilot-sdk-language-model"), exports);
|
|
29
|
+
tslib_1.__exportStar(require("./copilot-sdk-types"), exports);
|
|
22
30
|
//# sourceMappingURL=index.js.map
|
package/lib/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,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,sEAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,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,sEAA4C;AAC5C,iFAAuD;AACvD,sEAA4C;AAC5C,gEAAsC;AACtC,qEAA2C;AAC3C,gEAAsC;AACtC,wEAA8C;AAC9C,+DAAqC;AACrC,gEAAsC;AACtC,uEAA6C;AAC7C,8DAAoC"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/ai-copilot",
|
|
3
|
-
"version": "1.76.0-next.
|
|
3
|
+
"version": "1.76.0-next.42+b0f9e63a6",
|
|
4
4
|
"description": "Theia - GitHub Copilot Integration",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@theia/ai-core": "1.76.0-next.
|
|
7
|
-
"@theia/
|
|
8
|
-
"@theia/core": "1.76.0-next.4+21b9b5342",
|
|
9
|
-
"openai": "^6.49.0",
|
|
6
|
+
"@theia/ai-core": "1.76.0-next.42+b0f9e63a6",
|
|
7
|
+
"@theia/core": "1.76.0-next.42+b0f9e63a6",
|
|
10
8
|
"tslib": "^2.8.1"
|
|
11
9
|
},
|
|
12
10
|
"publishConfig": {
|
|
@@ -48,5 +46,5 @@
|
|
|
48
46
|
"nyc": {
|
|
49
47
|
"extends": "../../configs/nyc.json"
|
|
50
48
|
},
|
|
51
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "b0f9e63a6d331135265869a341dce7c7f1eef158"
|
|
52
50
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import * as React from '@theia/core/shared/react';
|
|
18
18
|
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
19
|
-
import { DialogProps, DialogError } from '@theia/core/lib/browser/dialogs';
|
|
19
|
+
import { DialogProps, DialogError, Dialog } from '@theia/core/lib/browser/dialogs';
|
|
20
20
|
import { ReactDialog } from '@theia/core/lib/browser/dialogs/react-dialog';
|
|
21
21
|
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
22
22
|
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
|
@@ -68,28 +68,30 @@ export class CopilotAuthDialog extends ReactDialog<boolean> {
|
|
|
68
68
|
protected init(): void {
|
|
69
69
|
this.titleNode.textContent = this.props.title;
|
|
70
70
|
this.appendAcceptButton(nls.localize('theia/ai/copilot/auth/authorize', 'I have authorized'));
|
|
71
|
-
this.appendCloseButton(
|
|
71
|
+
this.appendCloseButton(Dialog.CANCEL);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
protected updateButtonStates(): void {
|
|
75
75
|
const isPolling = this.state === 'polling';
|
|
76
76
|
const isSuccess = this.state === 'success';
|
|
77
|
+
// Singleton dialog: button state survives close, so reset it on every render.
|
|
77
78
|
if (this.acceptButton) {
|
|
78
79
|
this.acceptButton.disabled = isPolling || isSuccess;
|
|
79
|
-
|
|
80
|
-
this.acceptButton.style.display = 'none';
|
|
81
|
-
}
|
|
80
|
+
this.acceptButton.style.display = isSuccess ? 'none' : '';
|
|
82
81
|
}
|
|
83
82
|
if (this.closeButton) {
|
|
84
|
-
|
|
85
|
-
this.closeButton.textContent = nls.localizeByDefault('Close');
|
|
86
|
-
}
|
|
83
|
+
this.closeButton.textContent = isSuccess ? nls.localizeByDefault('Close') : Dialog.CANCEL;
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
86
|
|
|
90
87
|
override async open(): Promise<boolean | undefined> {
|
|
91
88
|
this.initiateFlow();
|
|
92
|
-
|
|
89
|
+
const result = await super.open();
|
|
90
|
+
if (this.state !== 'success') {
|
|
91
|
+
// Leave no Copilot CLI process behind when the dialog is dismissed or retried.
|
|
92
|
+
await this.authService.cancelSignIn();
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
override update(): void {
|
|
@@ -100,9 +102,12 @@ export class CopilotAuthDialog extends ReactDialog<boolean> {
|
|
|
100
102
|
protected async initiateFlow(): Promise<void> {
|
|
101
103
|
try {
|
|
102
104
|
this.state = 'loading';
|
|
105
|
+
this.deviceCodeResponse = undefined;
|
|
106
|
+
this.errorMessage = undefined;
|
|
107
|
+
this.copied = false;
|
|
103
108
|
this.update();
|
|
104
109
|
|
|
105
|
-
this.deviceCodeResponse = await this.authService.
|
|
110
|
+
this.deviceCodeResponse = await this.authService.startSignIn(this.props.enterpriseUrl);
|
|
106
111
|
this.state = 'waiting';
|
|
107
112
|
this.update();
|
|
108
113
|
} catch (error) {
|
|
@@ -121,11 +126,7 @@ export class CopilotAuthDialog extends ReactDialog<boolean> {
|
|
|
121
126
|
this.update();
|
|
122
127
|
|
|
123
128
|
try {
|
|
124
|
-
const success = await this.authService.
|
|
125
|
-
this.deviceCodeResponse.device_code,
|
|
126
|
-
this.deviceCodeResponse.interval,
|
|
127
|
-
this.props.enterpriseUrl
|
|
128
|
-
);
|
|
129
|
+
const success = await this.authService.waitForSignIn();
|
|
129
130
|
|
|
130
131
|
if (success) {
|
|
131
132
|
this.state = 'success';
|
|
@@ -149,7 +150,10 @@ export class CopilotAuthDialog extends ReactDialog<boolean> {
|
|
|
149
150
|
|
|
150
151
|
protected override isValid(_value: boolean, _mode: DialogError): DialogError {
|
|
151
152
|
if (this.state === 'error') {
|
|
152
|
-
|
|
153
|
+
// The error is shown in the dialog body by renderError, where it can wrap. Returning only a
|
|
154
|
+
// failed result keeps the accept button disabled without repeating the (often long) message
|
|
155
|
+
// next to it, where it does not fit.
|
|
156
|
+
return { result: false, message: '' };
|
|
153
157
|
}
|
|
154
158
|
return '';
|
|
155
159
|
}
|
|
@@ -19,9 +19,12 @@ import { CommandService, nls, PreferenceService } from '@theia/core';
|
|
|
19
19
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
|
20
20
|
import { MessageService } from '@theia/core/lib/common/message-service';
|
|
21
21
|
import { CopilotAuthService, CopilotLanguageModelsManager, CopilotModelDescription, COPILOT_PROVIDER_ID } from '../common';
|
|
22
|
-
import { COPILOT_ENABLED_PREF,
|
|
22
|
+
import { COPILOT_ENABLED_PREF, COPILOT_ENTERPRISE_URL_PREF, COPILOT_EXECUTABLE_PATH_PREF, COPILOT_MODEL_OVERRIDES_PREF } from '../common/copilot-preferences';
|
|
23
23
|
import { AICorePreferences, PREFERENCE_NAME_MAX_RETRIES } from '@theia/ai-core/lib/common/ai-core-preferences';
|
|
24
24
|
import { CopilotCommands } from './copilot-command-contribution';
|
|
25
|
+
import { ModelDiscoveryStatusService } from '@theia/ai-core/lib/browser';
|
|
26
|
+
|
|
27
|
+
const COPILOT_PROVIDER_LABEL = 'GitHub Copilot';
|
|
25
28
|
|
|
26
29
|
@injectable()
|
|
27
30
|
export class CopilotFrontendApplicationContribution implements FrontendApplicationContribution {
|
|
@@ -44,29 +47,49 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
44
47
|
@inject(CommandService)
|
|
45
48
|
protected readonly commandService: CommandService;
|
|
46
49
|
|
|
50
|
+
@inject(ModelDiscoveryStatusService)
|
|
51
|
+
protected readonly discoveryStatus: ModelDiscoveryStatusService;
|
|
52
|
+
|
|
47
53
|
protected prevModels: string[] = [];
|
|
48
54
|
protected useAutoDiscovery = false;
|
|
49
55
|
|
|
50
56
|
onStart(): void {
|
|
51
57
|
this.preferenceService.ready.then(async () => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
this.discoveryStatus.registerProvider({
|
|
59
|
+
providerId: COPILOT_PROVIDER_ID,
|
|
60
|
+
label: COPILOT_PROVIDER_LABEL,
|
|
61
|
+
refresh: () => this.initializeModels()
|
|
62
|
+
});
|
|
63
|
+
// Before anything reaches for the CLI: the backend cannot read the preferences itself.
|
|
64
|
+
await this.updateExecutablePath();
|
|
55
65
|
if (this.isCopilotEnabled()) {
|
|
56
66
|
const authState = await this.authService.getAuthState();
|
|
57
67
|
if (authState.migrationRequired) {
|
|
58
|
-
this.
|
|
68
|
+
this.notifySignInRequired();
|
|
59
69
|
}
|
|
60
|
-
await this.initializeModels();
|
|
61
70
|
}
|
|
71
|
+
// Also when disabled: that is a state of its own on the provider's page, not the absence of one.
|
|
72
|
+
await this.initializeModels();
|
|
62
73
|
|
|
63
74
|
this.preferenceService.onPreferenceChanged(event => {
|
|
64
|
-
if (event.preferenceName ===
|
|
75
|
+
if (event.preferenceName === COPILOT_EXECUTABLE_PATH_PREF) {
|
|
76
|
+
this.updateExecutablePath().then(() => {
|
|
77
|
+
if (this.isCopilotEnabled() && this.useAutoDiscovery) {
|
|
78
|
+
// A CLI that could not be found before may be reachable now.
|
|
79
|
+
this.discoverAndRegisterModels();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
} else if (event.preferenceName === COPILOT_ENABLED_PREF) {
|
|
65
83
|
if (this.isCopilotEnabled()) {
|
|
66
84
|
this.initializeModels();
|
|
67
85
|
} else {
|
|
68
86
|
this.removeAllCopilotModels();
|
|
87
|
+
this.initializeModels();
|
|
69
88
|
}
|
|
89
|
+
} else if (event.preferenceName === COPILOT_ENTERPRISE_URL_PREF) {
|
|
90
|
+
// The domain is only read at sign-in time, so a change while signed in has no effect
|
|
91
|
+
// until the next sign-in. Let the user know instead of silently ignoring it.
|
|
92
|
+
this.notifyEnterpriseUrlChanged();
|
|
70
93
|
} else if (event.preferenceName === COPILOT_MODEL_OVERRIDES_PREF && this.isCopilotEnabled()) {
|
|
71
94
|
const newModels = this.preferenceService.get<string[]>(COPILOT_MODEL_OVERRIDES_PREF, []);
|
|
72
95
|
if (newModels.length > 0) {
|
|
@@ -77,15 +100,6 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
77
100
|
this.removeAllCopilotModels();
|
|
78
101
|
this.discoverAndRegisterModels();
|
|
79
102
|
}
|
|
80
|
-
} else if (event.preferenceName === COPILOT_ENTERPRISE_URL_PREF && this.isCopilotEnabled()) {
|
|
81
|
-
const url = this.preferenceService.get<string>(COPILOT_ENTERPRISE_URL_PREF);
|
|
82
|
-
this.manager.setEnterpriseUrl(url || undefined);
|
|
83
|
-
if (this.useAutoDiscovery) {
|
|
84
|
-
this.removeAllCopilotModels();
|
|
85
|
-
this.discoverAndRegisterModels();
|
|
86
|
-
} else {
|
|
87
|
-
this.manager.refreshModelsStatus();
|
|
88
|
-
}
|
|
89
103
|
}
|
|
90
104
|
});
|
|
91
105
|
|
|
@@ -95,6 +109,7 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
95
109
|
await this.discoverAndRegisterModels();
|
|
96
110
|
} else {
|
|
97
111
|
this.removeAllCopilotModels();
|
|
112
|
+
this.setSignInRequiredStatus();
|
|
98
113
|
}
|
|
99
114
|
}
|
|
100
115
|
});
|
|
@@ -111,9 +126,87 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
111
126
|
return this.preferenceService.get<boolean>(COPILOT_ENABLED_PREF, true);
|
|
112
127
|
}
|
|
113
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Hands the configured location of the Copilot CLI to the backend, which searches for it when
|
|
131
|
+
* none is configured.
|
|
132
|
+
*/
|
|
133
|
+
protected async updateExecutablePath(): Promise<void> {
|
|
134
|
+
const executablePath = this.preferenceService.get<string>(COPILOT_EXECUTABLE_PATH_PREF, '').trim();
|
|
135
|
+
await this.authService.setExecutablePath(executablePath || undefined);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Tells the user why they are signed out after an update, since the sign-in of the previous
|
|
140
|
+
* version cannot be carried over: it belonged to an OAuth application that is no longer used.
|
|
141
|
+
*/
|
|
142
|
+
protected async notifySignInRequired(): Promise<void> {
|
|
143
|
+
const signIn = nls.localize('theia/ai/copilot/commands/signIn', 'Sign in to GitHub Copilot');
|
|
144
|
+
const action = await this.messageService.info(
|
|
145
|
+
nls.localize('theia/ai/copilot/signInAgain',
|
|
146
|
+
'GitHub Copilot now signs in through the GitHub Copilot CLI. Your previous sign-in could not be carried over and has been '
|
|
147
|
+
+ 'removed, please sign in again to use Copilot models.'),
|
|
148
|
+
signIn
|
|
149
|
+
);
|
|
150
|
+
if (action === signIn) {
|
|
151
|
+
this.commandService.executeCommand(CopilotCommands.SIGN_IN.id);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Tells the user that a changed GitHub Copilot domain only takes effect on the next sign-in, since
|
|
157
|
+
* the domain is read when signing in and not while a session is already established.
|
|
158
|
+
*/
|
|
159
|
+
protected async notifyEnterpriseUrlChanged(): Promise<void> {
|
|
160
|
+
const authState = await this.authService.getAuthState();
|
|
161
|
+
if (!authState.isAuthenticated) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const signIn = nls.localize('theia/ai/copilot/commands/signIn', 'Sign in to GitHub Copilot');
|
|
165
|
+
const action = await this.messageService.info(
|
|
166
|
+
nls.localize('theia/ai/copilot/enterpriseUrlChanged',
|
|
167
|
+
'The GitHub Copilot domain changed. Sign in again for it to take effect.'),
|
|
168
|
+
signIn
|
|
169
|
+
);
|
|
170
|
+
if (action === signIn) {
|
|
171
|
+
this.commandService.executeCommand(CopilotCommands.SIGN_IN.id);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** The state of a provider whose credential is a sign-in that has not happened, with the way to fix it. */
|
|
176
|
+
protected setSignInRequiredStatus(): void {
|
|
177
|
+
this.discoveryStatus.updateStatus(COPILOT_PROVIDER_ID, {
|
|
178
|
+
state: 'no-credentials',
|
|
179
|
+
// What Copilot lacks is a sign-in, not an API key, so it says so rather than letting the
|
|
180
|
+
// state speak for it.
|
|
181
|
+
stateLabel: nls.localizeByDefault('Not signed in'),
|
|
182
|
+
message: nls.localize('theia/ai/copilot/discovery/signedOut',
|
|
183
|
+
'Not signed in to GitHub Copilot. Sign in to discover the models it offers.'),
|
|
184
|
+
action: { label: CopilotCommands.SIGN_IN.label!, commandId: CopilotCommands.SIGN_IN.id }
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
114
188
|
protected async initializeModels(): Promise<void> {
|
|
189
|
+
if (!this.isCopilotEnabled()) {
|
|
190
|
+
this.discoveryStatus.updateStatus(COPILOT_PROVIDER_ID, {
|
|
191
|
+
state: 'no-credentials',
|
|
192
|
+
stateLabel: nls.localizeByDefault('Disabled'),
|
|
193
|
+
message: nls.localize('theia/ai/copilot/discovery/disabled', 'The GitHub Copilot provider is disabled. Enable it to discover models.'),
|
|
194
|
+
action: undefined
|
|
195
|
+
});
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
115
198
|
const configuredModels = this.preferenceService.get<string[]>(COPILOT_MODEL_OVERRIDES_PREF, []);
|
|
116
199
|
if (configuredModels.length > 0) {
|
|
200
|
+
this.discoveryStatus.updateStatus(COPILOT_PROVIDER_ID, {
|
|
201
|
+
state: 'overridden',
|
|
202
|
+
stateLabel: undefined,
|
|
203
|
+
discovered: configuredModels.map(id => ({ id })),
|
|
204
|
+
message: nls.localize('theia/ai/copilot/discovery/overridden',
|
|
205
|
+
'The model list is configured manually. Clear the model overrides to discover the models from GitHub Copilot again.'),
|
|
206
|
+
lastFetch: undefined,
|
|
207
|
+
fromCache: false,
|
|
208
|
+
action: undefined
|
|
209
|
+
});
|
|
117
210
|
this.useAutoDiscovery = false;
|
|
118
211
|
this.manager.createOrUpdateLanguageModels(
|
|
119
212
|
...configuredModels.map((modelId: string) => this.createCopilotModelDescription(modelId))
|
|
@@ -126,7 +219,32 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
126
219
|
}
|
|
127
220
|
|
|
128
221
|
protected async discoverAndRegisterModels(): Promise<void> {
|
|
129
|
-
|
|
222
|
+
// Runs are queued rather than overlapped: startup, a key change and a manual refresh can all
|
|
223
|
+
// ask within a moment of each other, and two runs in flight would compute what to unregister
|
|
224
|
+
// from the same stale list and leave the registry disagreeing with the provider.
|
|
225
|
+
this.discovering = this.discovering.then(() => this.runDiscovery().catch(error => this.discoveryStatus.reportError(COPILOT_PROVIDER_ID, error)));
|
|
226
|
+
return this.discovering;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
protected discovering: Promise<void> = Promise.resolve();
|
|
230
|
+
|
|
231
|
+
protected async runDiscovery(): Promise<void> {
|
|
232
|
+
// Signing in is Copilot's equivalent of setting an API key, so a missing sign-in reads like a
|
|
233
|
+
// missing credential rather than like a failure: the CLI would answer the list call with an
|
|
234
|
+
// authorization error, which says the same thing in a way nobody can act on.
|
|
235
|
+
if (!(await this.authService.getAuthState()).isAuthenticated) {
|
|
236
|
+
this.setSignInRequiredStatus();
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
this.discoveryStatus.updateStatus(COPILOT_PROVIDER_ID, { state: 'fetching', stateLabel: undefined, message: undefined, action: undefined });
|
|
240
|
+
const { models, error } = await this.manager.fetchAvailableModels();
|
|
241
|
+
if (error) {
|
|
242
|
+
// The models of an earlier discovery stay registered; the manager already marks them
|
|
243
|
+
// unavailable, so they are visible as such rather than silently gone.
|
|
244
|
+
this.discoveryStatus.updateStatus(COPILOT_PROVIDER_ID, { state: 'error', stateLabel: undefined, message: error, action: undefined });
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const modelIds = models.map(model => model.id);
|
|
130
248
|
if (modelIds.length > 0) {
|
|
131
249
|
const modelsToRemove = this.prevModels.filter(m => !modelIds.includes(m));
|
|
132
250
|
if (modelsToRemove.length > 0) {
|
|
@@ -139,6 +257,15 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
139
257
|
);
|
|
140
258
|
this.prevModels = [...modelIds];
|
|
141
259
|
}
|
|
260
|
+
this.discoveryStatus.updateStatus(COPILOT_PROVIDER_ID, {
|
|
261
|
+
state: 'ready',
|
|
262
|
+
stateLabel: undefined,
|
|
263
|
+
discovered: models,
|
|
264
|
+
message: undefined,
|
|
265
|
+
lastFetch: Date.now(),
|
|
266
|
+
fromCache: false,
|
|
267
|
+
action: undefined
|
|
268
|
+
});
|
|
142
269
|
}
|
|
143
270
|
|
|
144
271
|
protected removeAllCopilotModels(): void {
|
|
@@ -171,18 +298,6 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
171
298
|
this.manager.createOrUpdateLanguageModels(...models.map((modelId: string) => this.createCopilotModelDescription(modelId)));
|
|
172
299
|
}
|
|
173
300
|
|
|
174
|
-
protected async notifyTokenMigration(): Promise<void> {
|
|
175
|
-
const signIn = nls.localize('theia/ai/copilot/commands/signIn', 'Sign in to GitHub Copilot');
|
|
176
|
-
const action = await this.messageService.info(
|
|
177
|
-
nls.localize('theia/ai/copilot/tokenMigration',
|
|
178
|
-
'Your GitHub Copilot session used an outdated authentication method and has been cleared. Please sign in again to access all available models.'),
|
|
179
|
-
signIn
|
|
180
|
-
);
|
|
181
|
-
if (action === signIn) {
|
|
182
|
-
this.commandService.executeCommand(CopilotCommands.SIGN_IN.id);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
301
|
protected createCopilotModelDescription(modelId: string): CopilotModelDescription {
|
|
187
302
|
const id = `${COPILOT_PROVIDER_ID}/${modelId}`;
|
|
188
303
|
const maxRetries = this.aiCorePreferences.get(PREFERENCE_NAME_MAX_RETRIES) ?? 3;
|
|
@@ -190,8 +305,6 @@ export class CopilotFrontendApplicationContribution implements FrontendApplicati
|
|
|
190
305
|
return {
|
|
191
306
|
id,
|
|
192
307
|
model: modelId,
|
|
193
|
-
enableStreaming: true,
|
|
194
|
-
supportsStructuredOutput: true,
|
|
195
308
|
maxRetries
|
|
196
309
|
};
|
|
197
310
|
}
|