@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.
Files changed (150) hide show
  1. package/README.md +86 -14
  2. package/lib/browser/copilot-auth-dialog.d.ts.map +1 -1
  3. package/lib/browser/copilot-auth-dialog.js +12 -4
  4. package/lib/browser/copilot-auth-dialog.js.map +1 -1
  5. package/lib/browser/copilot-frontend-application-contribution.d.ts +15 -1
  6. package/lib/browser/copilot-frontend-application-contribution.d.ts.map +1 -1
  7. package/lib/browser/copilot-frontend-application-contribution.js +52 -24
  8. package/lib/browser/copilot-frontend-application-contribution.js.map +1 -1
  9. package/lib/common/copilot-auth-service.d.ts +27 -24
  10. package/lib/common/copilot-auth-service.d.ts.map +1 -1
  11. package/lib/common/copilot-language-models-manager.d.ts +3 -21
  12. package/lib/common/copilot-language-models-manager.d.ts.map +1 -1
  13. package/lib/common/copilot-language-models-manager.js +1 -13
  14. package/lib/common/copilot-language-models-manager.js.map +1 -1
  15. package/lib/common/copilot-preferences.d.ts +1 -0
  16. package/lib/common/copilot-preferences.d.ts.map +1 -1
  17. package/lib/common/copilot-preferences.js +24 -6
  18. package/lib/common/copilot-preferences.js.map +1 -1
  19. package/lib/common/index.d.ts +0 -1
  20. package/lib/common/index.d.ts.map +1 -1
  21. package/lib/common/index.js +0 -1
  22. package/lib/common/index.js.map +1 -1
  23. package/lib/node/copilot-auth-service-impl.d.ts +25 -16
  24. package/lib/node/copilot-auth-service-impl.d.ts.map +1 -1
  25. package/lib/node/copilot-auth-service-impl.js +67 -183
  26. package/lib/node/copilot-auth-service-impl.js.map +1 -1
  27. package/lib/node/copilot-auth-service-impl.spec.js +104 -168
  28. package/lib/node/copilot-auth-service-impl.spec.js.map +1 -1
  29. package/lib/node/copilot-backend-module.d.ts.map +1 -1
  30. package/lib/node/copilot-backend-module.js +10 -2
  31. package/lib/node/copilot-backend-module.js.map +1 -1
  32. package/lib/node/copilot-cli-auth-provider.d.ts +146 -0
  33. package/lib/node/copilot-cli-auth-provider.d.ts.map +1 -0
  34. package/lib/node/copilot-cli-auth-provider.js +430 -0
  35. package/lib/node/copilot-cli-auth-provider.js.map +1 -0
  36. package/lib/node/copilot-cli-auth-provider.spec.d.ts +2 -0
  37. package/lib/node/copilot-cli-auth-provider.spec.d.ts.map +1 -0
  38. package/lib/node/copilot-cli-auth-provider.spec.js +249 -0
  39. package/lib/node/copilot-cli-auth-provider.spec.js.map +1 -0
  40. package/lib/node/copilot-cli-locator.d.ts +120 -0
  41. package/lib/node/copilot-cli-locator.d.ts.map +1 -0
  42. package/lib/node/copilot-cli-locator.js +348 -0
  43. package/lib/node/copilot-cli-locator.js.map +1 -0
  44. package/lib/node/copilot-cli-locator.spec.d.ts +2 -0
  45. package/lib/node/copilot-cli-locator.spec.d.ts.map +1 -0
  46. package/lib/node/copilot-cli-locator.spec.js +327 -0
  47. package/lib/node/copilot-cli-locator.spec.js.map +1 -0
  48. package/lib/node/copilot-credential-store.d.ts +45 -0
  49. package/lib/node/copilot-credential-store.d.ts.map +1 -0
  50. package/lib/node/copilot-credential-store.js +96 -0
  51. package/lib/node/copilot-credential-store.js.map +1 -0
  52. package/lib/node/copilot-credential-store.spec.d.ts +2 -0
  53. package/lib/node/copilot-credential-store.spec.d.ts.map +1 -0
  54. package/lib/node/copilot-credential-store.spec.js +93 -0
  55. package/lib/node/copilot-credential-store.spec.js.map +1 -0
  56. package/lib/node/copilot-language-models-manager-impl.d.ts +20 -18
  57. package/lib/node/copilot-language-models-manager-impl.d.ts.map +1 -1
  58. package/lib/node/copilot-language-models-manager-impl.js +39 -67
  59. package/lib/node/copilot-language-models-manager-impl.js.map +1 -1
  60. package/lib/node/copilot-language-models-manager-impl.spec.d.ts +2 -0
  61. package/lib/node/copilot-language-models-manager-impl.spec.d.ts.map +1 -0
  62. package/lib/node/copilot-language-models-manager-impl.spec.js +119 -0
  63. package/lib/node/copilot-language-models-manager-impl.spec.js.map +1 -0
  64. package/lib/node/copilot-runtime-env.d.ts +20 -0
  65. package/lib/node/copilot-runtime-env.d.ts.map +1 -0
  66. package/lib/node/copilot-runtime-env.js +49 -0
  67. package/lib/node/copilot-runtime-env.js.map +1 -0
  68. package/lib/node/copilot-sdk-client-provider.d.ts +103 -0
  69. package/lib/node/copilot-sdk-client-provider.d.ts.map +1 -0
  70. package/lib/node/copilot-sdk-client-provider.js +247 -0
  71. package/lib/node/copilot-sdk-client-provider.js.map +1 -0
  72. package/lib/node/copilot-sdk-client-provider.spec.d.ts +2 -0
  73. package/lib/node/copilot-sdk-client-provider.spec.d.ts.map +1 -0
  74. package/lib/node/copilot-sdk-client-provider.spec.js +215 -0
  75. package/lib/node/copilot-sdk-client-provider.spec.js.map +1 -0
  76. package/lib/node/copilot-sdk-language-model.d.ts +85 -0
  77. package/lib/node/copilot-sdk-language-model.d.ts.map +1 -0
  78. package/lib/node/copilot-sdk-language-model.js +301 -0
  79. package/lib/node/copilot-sdk-language-model.js.map +1 -0
  80. package/lib/node/copilot-sdk-language-model.spec.d.ts +2 -0
  81. package/lib/node/copilot-sdk-language-model.spec.d.ts.map +1 -0
  82. package/lib/node/copilot-sdk-language-model.spec.js +302 -0
  83. package/lib/node/copilot-sdk-language-model.spec.js.map +1 -0
  84. package/lib/node/copilot-sdk-loader.d.ts +57 -0
  85. package/lib/node/copilot-sdk-loader.d.ts.map +1 -0
  86. package/lib/node/copilot-sdk-loader.js +133 -0
  87. package/lib/node/copilot-sdk-loader.js.map +1 -0
  88. package/lib/node/copilot-sdk-loader.spec.d.ts +2 -0
  89. package/lib/node/copilot-sdk-loader.spec.d.ts.map +1 -0
  90. package/lib/node/copilot-sdk-loader.spec.js +113 -0
  91. package/lib/node/copilot-sdk-loader.spec.js.map +1 -0
  92. package/lib/node/copilot-sdk-mappers.d.ts +49 -0
  93. package/lib/node/copilot-sdk-mappers.d.ts.map +1 -0
  94. package/lib/node/copilot-sdk-mappers.js +147 -0
  95. package/lib/node/copilot-sdk-mappers.js.map +1 -0
  96. package/lib/node/copilot-sdk-mappers.spec.d.ts +2 -0
  97. package/lib/node/copilot-sdk-mappers.spec.d.ts.map +1 -0
  98. package/lib/node/copilot-sdk-mappers.spec.js +133 -0
  99. package/lib/node/copilot-sdk-mappers.spec.js.map +1 -0
  100. package/lib/node/copilot-sdk-types.d.ts +198 -0
  101. package/lib/node/copilot-sdk-types.d.ts.map +1 -0
  102. package/lib/{common/copilot-oauth-config.js → node/copilot-sdk-types.js} +2 -13
  103. package/lib/node/copilot-sdk-types.js.map +1 -0
  104. package/lib/node/index.d.ts +9 -1
  105. package/lib/node/index.d.ts.map +1 -1
  106. package/lib/node/index.js +9 -1
  107. package/lib/node/index.js.map +1 -1
  108. package/package.json +4 -6
  109. package/src/browser/copilot-auth-dialog.tsx +12 -8
  110. package/src/browser/copilot-frontend-application-contribution.ts +62 -29
  111. package/src/common/copilot-auth-service.ts +28 -24
  112. package/src/common/copilot-language-models-manager.ts +3 -28
  113. package/src/common/copilot-preferences.ts +24 -5
  114. package/src/common/index.ts +0 -1
  115. package/src/node/copilot-auth-service-impl.spec.ts +122 -207
  116. package/src/node/copilot-auth-service-impl.ts +63 -218
  117. package/src/node/copilot-backend-module.ts +11 -2
  118. package/src/node/copilot-cli-auth-provider.spec.ts +315 -0
  119. package/src/node/copilot-cli-auth-provider.ts +444 -0
  120. package/src/node/copilot-cli-locator.spec.ts +386 -0
  121. package/src/node/copilot-cli-locator.ts +363 -0
  122. package/src/node/copilot-credential-store.spec.ts +106 -0
  123. package/src/node/copilot-credential-store.ts +99 -0
  124. package/src/node/copilot-language-models-manager-impl.spec.ts +137 -0
  125. package/src/node/copilot-language-models-manager-impl.ts +51 -85
  126. package/src/node/copilot-runtime-env.ts +46 -0
  127. package/src/node/copilot-sdk-client-provider.spec.ts +253 -0
  128. package/src/node/copilot-sdk-client-provider.ts +241 -0
  129. package/src/node/copilot-sdk-language-model.spec.ts +363 -0
  130. package/src/node/copilot-sdk-language-model.ts +329 -0
  131. package/src/node/copilot-sdk-loader.spec.ts +126 -0
  132. package/src/node/copilot-sdk-loader.ts +142 -0
  133. package/src/node/copilot-sdk-mappers.spec.ts +151 -0
  134. package/src/node/copilot-sdk-mappers.ts +161 -0
  135. package/src/node/copilot-sdk-types.ts +276 -0
  136. package/src/node/index.ts +9 -1
  137. package/lib/common/copilot-oauth-config.d.ts +0 -33
  138. package/lib/common/copilot-oauth-config.d.ts.map +0 -1
  139. package/lib/common/copilot-oauth-config.js.map +0 -1
  140. package/lib/node/copilot-language-model.d.ts +0 -34
  141. package/lib/node/copilot-language-model.d.ts.map +0 -1
  142. package/lib/node/copilot-language-model.js +0 -236
  143. package/lib/node/copilot-language-model.js.map +0 -1
  144. package/lib/node/copilot-language-model.spec.d.ts +0 -2
  145. package/lib/node/copilot-language-model.spec.d.ts.map +0 -1
  146. package/lib/node/copilot-language-model.spec.js +0 -89
  147. package/lib/node/copilot-language-model.spec.js.map +0 -1
  148. package/src/common/copilot-oauth-config.ts +0 -55
  149. package/src/node/copilot-language-model.spec.ts +0 -106
  150. package/src/node/copilot-language-model.ts +0 -273
@@ -1,273 +0,0 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2026 EclipseSource GmbH.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import {
18
- ImageContent,
19
- formatToolCallContentForModel,
20
- LanguageModel,
21
- LanguageModelMessage,
22
- LanguageModelParsedResponse,
23
- LanguageModelRequest,
24
- LanguageModelResponse,
25
- LanguageModelStatus,
26
- LanguageModelTextResponse,
27
- UserRequest
28
- } from '@theia/ai-core';
29
- import { CancellationToken } from '@theia/core';
30
- import OpenAI from 'openai';
31
- import { RunnableToolFunctionWithoutParse } from 'openai/lib/RunnableFunction';
32
- import { ChatCompletionAssistantMessageParam, ChatCompletionMessageParam } from 'openai/resources';
33
- import { StreamingAsyncIterator } from '@theia/ai-openai/lib/node/openai-streaming-iterator';
34
- import { COPILOT_PROVIDER_ID, getCopilotApiBaseUrl } from '../common';
35
- import type { RunnerOptions } from 'openai/lib/AbstractChatCompletionRunner';
36
- import type { ChatCompletionStream } from 'openai/lib/ChatCompletionStream';
37
-
38
- /**
39
- * Language model implementation for GitHub Copilot.
40
- * Uses the OpenAI SDK to communicate with the Copilot API.
41
- */
42
- export class CopilotLanguageModel implements LanguageModel {
43
-
44
- protected runnerOptions: RunnerOptions = {
45
- maxChatCompletions: 100
46
- };
47
-
48
- constructor(
49
- public readonly id: string,
50
- public model: string,
51
- public status: LanguageModelStatus,
52
- public enableStreaming: boolean,
53
- public supportsStructuredOutput: boolean,
54
- public maxRetries: number,
55
- protected readonly accessTokenProvider: () => Promise<string | undefined>,
56
- protected readonly enterpriseUrlProvider: () => string | undefined,
57
- protected readonly userAgentProvider: () => string,
58
- ) { }
59
-
60
- protected getSettings(request: LanguageModelRequest): Record<string, unknown> {
61
- return request.settings ?? {};
62
- }
63
-
64
- async request(request: UserRequest, cancellationToken?: CancellationToken): Promise<LanguageModelResponse> {
65
- const openai = await this.initializeCopilotClient();
66
-
67
- if (request.response_format?.type === 'json_schema' && this.supportsStructuredOutput) {
68
- return this.handleStructuredOutputRequest(openai, request);
69
- }
70
-
71
- const settings = this.getSettings(request);
72
-
73
- if (!this.enableStreaming || (typeof settings.stream === 'boolean' && !settings.stream)) {
74
- return this.handleNonStreamingRequest(openai, request);
75
- }
76
-
77
- if (cancellationToken?.isCancellationRequested) {
78
- return { text: '' };
79
- }
80
-
81
- if (this.id.startsWith(`${COPILOT_PROVIDER_ID}/`)) {
82
- settings['stream_options'] = { include_usage: true };
83
- }
84
-
85
- let runner: ChatCompletionStream;
86
- const tools = this.createTools(request);
87
-
88
- if (tools) {
89
- runner = openai.chat.completions.runTools({
90
- model: this.model,
91
- messages: this.processMessages(request.messages),
92
- stream: true,
93
- tools: tools,
94
- tool_choice: 'auto',
95
- ...settings
96
- }, {
97
- ...this.runnerOptions,
98
- maxRetries: this.maxRetries
99
- });
100
- } else {
101
- runner = openai.chat.completions.stream({
102
- model: this.model,
103
- messages: this.processMessages(request.messages),
104
- stream: true,
105
- ...settings
106
- });
107
- }
108
-
109
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
- return { stream: new StreamingAsyncIterator(runner as any, cancellationToken) };
111
- }
112
-
113
- protected async handleNonStreamingRequest(openai: OpenAI, request: UserRequest): Promise<LanguageModelTextResponse> {
114
- const settings = this.getSettings(request);
115
- const response = await openai.chat.completions.create({
116
- model: this.model,
117
- messages: this.processMessages(request.messages),
118
- ...settings
119
- });
120
-
121
- const message = response.choices[0].message;
122
-
123
- return {
124
- text: message.content ?? '',
125
- usage: response.usage ? {
126
- input_tokens: response.usage.prompt_tokens,
127
- output_tokens: response.usage.completion_tokens,
128
- } : undefined
129
- };
130
- }
131
-
132
- protected async handleStructuredOutputRequest(openai: OpenAI, request: UserRequest): Promise<LanguageModelParsedResponse> {
133
- const settings = this.getSettings(request);
134
- const result = await openai.chat.completions.parse({
135
- model: this.model,
136
- messages: this.processMessages(request.messages),
137
- response_format: request.response_format,
138
- ...settings
139
- });
140
-
141
- const message = result.choices[0].message;
142
- if (message.refusal || message.parsed === undefined) {
143
- console.error('Error in Copilot chat completion:', JSON.stringify(message));
144
- }
145
-
146
- return {
147
- content: message.content ?? '',
148
- parsed: message.parsed,
149
- usage: result.usage ? {
150
- input_tokens: result.usage.prompt_tokens,
151
- output_tokens: result.usage.completion_tokens,
152
- } : undefined
153
- };
154
- }
155
-
156
- protected createTools(request: LanguageModelRequest): RunnableToolFunctionWithoutParse[] | undefined {
157
- return request.tools?.map(tool => ({
158
- type: 'function',
159
- function: {
160
- name: tool.name,
161
- description: tool.description,
162
- parameters: tool.parameters,
163
- function: (args_string: string) => tool.handler(args_string)
164
- }
165
- } as RunnableToolFunctionWithoutParse));
166
- }
167
-
168
- protected async initializeCopilotClient(): Promise<OpenAI> {
169
- const accessToken = await this.accessTokenProvider();
170
- if (!accessToken) {
171
- throw new Error('Not authenticated with GitHub Copilot. Please sign in first.');
172
- }
173
-
174
- const baseURL = getCopilotApiBaseUrl(this.enterpriseUrlProvider());
175
-
176
- return new OpenAI({
177
- apiKey: accessToken,
178
- baseURL,
179
- defaultHeaders: {
180
- 'User-Agent': this.userAgentProvider(),
181
- 'Openai-Intent': 'conversation-edits',
182
- 'X-Initiator': 'user'
183
- }
184
- });
185
- }
186
-
187
- protected processMessages(messages: LanguageModelMessage[]): ChatCompletionMessageParam[] {
188
- const converted = messages.filter(m => m.type !== 'thinking' && m.type !== 'compaction').map(m => this.toOpenAIMessage(m));
189
- return this.mergeConsecutiveAssistantMessages(converted);
190
- }
191
-
192
- protected mergeConsecutiveAssistantMessages(messages: ChatCompletionMessageParam[]): ChatCompletionMessageParam[] {
193
- const result: ChatCompletionMessageParam[] = [];
194
- for (const message of messages) {
195
- const previous = result[result.length - 1];
196
- if (previous?.role === 'assistant' && message.role === 'assistant') {
197
- const merged: ChatCompletionAssistantMessageParam = { ...previous, role: 'assistant' };
198
-
199
- const previousContent = typeof previous.content === 'string' ? previous.content : undefined;
200
- const nextContent = typeof message.content === 'string' ? message.content : undefined;
201
- if (previousContent !== undefined && nextContent !== undefined) {
202
- merged.content = `${previousContent}\n${nextContent}`;
203
- } else if (nextContent !== undefined) {
204
- merged.content = nextContent;
205
- } else if (previousContent !== undefined) {
206
- merged.content = previousContent;
207
- }
208
-
209
- const toolCalls = [...(previous.tool_calls ?? []), ...(message.tool_calls ?? [])];
210
- if (toolCalls.length > 0) {
211
- merged.tool_calls = toolCalls;
212
- }
213
-
214
- result[result.length - 1] = merged;
215
- } else {
216
- result.push(message);
217
- }
218
- }
219
- return result;
220
- }
221
-
222
- protected toOpenAIMessage(message: LanguageModelMessage): ChatCompletionMessageParam {
223
- if (LanguageModelMessage.isTextMessage(message)) {
224
- return {
225
- role: this.toOpenAiRole(message),
226
- content: message.text
227
- };
228
- }
229
- if (LanguageModelMessage.isToolUseMessage(message)) {
230
- return {
231
- role: 'assistant',
232
- tool_calls: [{
233
- id: message.id,
234
- function: {
235
- name: message.name,
236
- arguments: JSON.stringify(message.input)
237
- },
238
- type: 'function'
239
- }]
240
- };
241
- }
242
- if (LanguageModelMessage.isToolResultMessage(message)) {
243
- return {
244
- role: 'tool',
245
- tool_call_id: message.tool_use_id,
246
- content: typeof message.content === 'string' ? message.content : formatToolCallContentForModel(message.content)
247
- };
248
- }
249
- if (LanguageModelMessage.isImageMessage(message) && message.actor === 'user') {
250
- return {
251
- role: 'user',
252
- content: [{
253
- type: 'image_url',
254
- image_url: {
255
- url: ImageContent.isBase64(message.image)
256
- ? `data:${message.image.mimeType};base64,${message.image.base64data}`
257
- : message.image.url
258
- }
259
- }]
260
- };
261
- }
262
- throw new Error(`Unknown message type: '${JSON.stringify(message)}'`);
263
- }
264
-
265
- protected toOpenAiRole(message: LanguageModelMessage): 'developer' | 'user' | 'assistant' | 'system' {
266
- if (message.actor === 'system') {
267
- return 'developer';
268
- } else if (message.actor === 'ai') {
269
- return 'assistant';
270
- }
271
- return 'user';
272
- }
273
- }