@theia/ai-openai 1.46.0-next.241
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 +50 -0
- package/lib/browser/openai-frontend-application-contribution.d.ts +18 -0
- package/lib/browser/openai-frontend-application-contribution.d.ts.map +1 -0
- package/lib/browser/openai-frontend-application-contribution.js +143 -0
- package/lib/browser/openai-frontend-application-contribution.js.map +1 -0
- package/lib/browser/openai-frontend-module.d.ts +4 -0
- package/lib/browser/openai-frontend-module.d.ts.map +1 -0
- package/lib/browser/openai-frontend-module.js +32 -0
- package/lib/browser/openai-frontend-module.js.map +1 -0
- package/lib/browser/openai-preferences.d.ts +6 -0
- package/lib/browser/openai-preferences.d.ts.map +1 -0
- package/lib/browser/openai-preferences.js +84 -0
- package/lib/browser/openai-preferences.js.map +1 -0
- package/lib/common/index.d.ts +2 -0
- package/lib/common/index.d.ts.map +1 -0
- package/lib/common/index.js +20 -0
- package/lib/common/index.js.map +1 -0
- package/lib/common/openai-language-models-manager.d.ts +37 -0
- package/lib/common/openai-language-models-manager.d.ts.map +1 -0
- package/lib/common/openai-language-models-manager.js +21 -0
- package/lib/common/openai-language-models-manager.js.map +1 -0
- package/lib/node/openai-backend-module.d.ts +5 -0
- package/lib/node/openai-backend-module.d.ts.map +1 -0
- package/lib/node/openai-backend-module.js +29 -0
- package/lib/node/openai-backend-module.js.map +1 -0
- package/lib/node/openai-language-model.d.ts +36 -0
- package/lib/node/openai-language-model.d.ts.map +1 -0
- package/lib/node/openai-language-model.js +210 -0
- package/lib/node/openai-language-model.js.map +1 -0
- package/lib/node/openai-language-models-manager-impl.d.ts +11 -0
- package/lib/node/openai-language-models-manager-impl.d.ts.map +1 -0
- package/lib/node/openai-language-models-manager-impl.js +80 -0
- package/lib/node/openai-language-models-manager-impl.js.map +1 -0
- package/lib/package.spec.d.ts +1 -0
- package/lib/package.spec.d.ts.map +1 -0
- package/lib/package.spec.js +26 -0
- package/lib/package.spec.js.map +1 -0
- package/package.json +54 -0
- package/src/browser/openai-frontend-application-contribution.ts +162 -0
- package/src/browser/openai-frontend-module.ts +31 -0
- package/src/browser/openai-preferences.ts +84 -0
- package/src/common/index.ts +16 -0
- package/src/common/openai-language-models-manager.ts +49 -0
- package/src/node/openai-backend-module.ts +30 -0
- package/src/node/openai-language-model.ts +234 -0
- package/src/node/openai-language-models-manager-impl.ts +85 -0
- package/src/package.spec.ts +28 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2024 EclipseSource GmbH.
|
|
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.OpenAiModel = exports.OpenAiModelIdentifier = void 0;
|
|
19
|
+
const openai_1 = require("openai");
|
|
20
|
+
exports.OpenAiModelIdentifier = Symbol('OpenAiModelIdentifier');
|
|
21
|
+
function toOpenAIMessage(message) {
|
|
22
|
+
return {
|
|
23
|
+
role: toOpenAiRole(message),
|
|
24
|
+
content: message.query || ''
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function toOpenAiRole(message) {
|
|
28
|
+
switch (message.actor) {
|
|
29
|
+
case 'system':
|
|
30
|
+
return 'system';
|
|
31
|
+
case 'ai':
|
|
32
|
+
return 'assistant';
|
|
33
|
+
default:
|
|
34
|
+
return 'user';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
class OpenAiModel {
|
|
38
|
+
/**
|
|
39
|
+
* @param id the unique id for this language model. It will be used to identify the model in the UI.
|
|
40
|
+
* @param model the model id as it is used by the OpenAI API
|
|
41
|
+
* @param enableStreaming whether the streaming API shall be used
|
|
42
|
+
* @param apiKey a function that returns the API key to use for this model, called on each request
|
|
43
|
+
* @param url the OpenAI API compatible endpoint where the model is hosted. If not provided the default OpenAI endpoint will be used.
|
|
44
|
+
* @param defaultRequestSettings optional default settings for requests made using this model.
|
|
45
|
+
*/
|
|
46
|
+
constructor(id, model, enableStreaming, apiKey, url, defaultRequestSettings) {
|
|
47
|
+
this.id = id;
|
|
48
|
+
this.model = model;
|
|
49
|
+
this.enableStreaming = enableStreaming;
|
|
50
|
+
this.apiKey = apiKey;
|
|
51
|
+
this.url = url;
|
|
52
|
+
this.defaultRequestSettings = defaultRequestSettings;
|
|
53
|
+
}
|
|
54
|
+
getSettings(request) {
|
|
55
|
+
const settings = request.settings ? request.settings : this.defaultRequestSettings;
|
|
56
|
+
if (!settings) {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
return settings;
|
|
60
|
+
}
|
|
61
|
+
async request(request, cancellationToken) {
|
|
62
|
+
var _a;
|
|
63
|
+
const settings = this.getSettings(request);
|
|
64
|
+
const openai = this.initializeOpenAi();
|
|
65
|
+
if (this.isNonStreamingModel(this.model)) {
|
|
66
|
+
return this.handleNonStreamingRequest(openai, request);
|
|
67
|
+
}
|
|
68
|
+
if (((_a = request.response_format) === null || _a === void 0 ? void 0 : _a.type) === 'json_schema' && this.supportsStructuredOutput()) {
|
|
69
|
+
return this.handleStructuredOutputRequest(openai, request);
|
|
70
|
+
}
|
|
71
|
+
let runner;
|
|
72
|
+
const tools = this.createTools(request);
|
|
73
|
+
if (tools) {
|
|
74
|
+
runner = openai.beta.chat.completions.runTools({
|
|
75
|
+
model: this.model,
|
|
76
|
+
messages: request.messages.map(toOpenAIMessage),
|
|
77
|
+
stream: true,
|
|
78
|
+
tools: tools,
|
|
79
|
+
tool_choice: 'auto',
|
|
80
|
+
...settings
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
runner = openai.beta.chat.completions.stream({
|
|
85
|
+
model: this.model,
|
|
86
|
+
messages: request.messages.map(toOpenAIMessage),
|
|
87
|
+
stream: true,
|
|
88
|
+
...settings
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
cancellationToken === null || cancellationToken === void 0 ? void 0 : cancellationToken.onCancellationRequested(() => {
|
|
92
|
+
runner.abort();
|
|
93
|
+
});
|
|
94
|
+
let runnerEnd = false;
|
|
95
|
+
let resolve;
|
|
96
|
+
runner.on('error', error => {
|
|
97
|
+
console.error('Error in OpenAI chat completion stream:', error);
|
|
98
|
+
runnerEnd = true;
|
|
99
|
+
resolve({ content: error.message });
|
|
100
|
+
});
|
|
101
|
+
// we need to also listen for the emitted errors, as otherwise any error actually thrown by the API will not be caught
|
|
102
|
+
runner.emitted('error').then(error => {
|
|
103
|
+
console.error('Error in OpenAI chat completion stream:', error);
|
|
104
|
+
runnerEnd = true;
|
|
105
|
+
resolve({ content: error.message });
|
|
106
|
+
});
|
|
107
|
+
runner.emitted('abort').then(() => {
|
|
108
|
+
// do nothing, as the abort event is only emitted when the runner is aborted by us
|
|
109
|
+
});
|
|
110
|
+
runner.on('message', message => {
|
|
111
|
+
if (message.role === 'tool') {
|
|
112
|
+
resolve({ tool_calls: [{ id: message.tool_call_id, finished: true, result: this.getCompletionContent(message) }] });
|
|
113
|
+
}
|
|
114
|
+
console.debug('Received Open AI message', JSON.stringify(message));
|
|
115
|
+
});
|
|
116
|
+
runner.once('end', () => {
|
|
117
|
+
runnerEnd = true;
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
+
resolve(runner.finalChatCompletion);
|
|
120
|
+
});
|
|
121
|
+
const asyncIterator = {
|
|
122
|
+
async *[Symbol.asyncIterator]() {
|
|
123
|
+
runner.on('chunk', chunk => {
|
|
124
|
+
var _a, _b;
|
|
125
|
+
if ((_a = chunk.choices[0]) === null || _a === void 0 ? void 0 : _a.delta) {
|
|
126
|
+
resolve({ ...(_b = chunk.choices[0]) === null || _b === void 0 ? void 0 : _b.delta });
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
while (!runnerEnd) {
|
|
130
|
+
const promise = new Promise((res, rej) => {
|
|
131
|
+
resolve = res;
|
|
132
|
+
});
|
|
133
|
+
yield promise;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
return { stream: asyncIterator };
|
|
138
|
+
}
|
|
139
|
+
async handleNonStreamingRequest(openai, request) {
|
|
140
|
+
var _a;
|
|
141
|
+
const settings = this.getSettings(request);
|
|
142
|
+
const response = await openai.chat.completions.create({
|
|
143
|
+
model: this.model,
|
|
144
|
+
messages: request.messages.map(toOpenAIMessage),
|
|
145
|
+
...settings
|
|
146
|
+
});
|
|
147
|
+
const message = response.choices[0].message;
|
|
148
|
+
return {
|
|
149
|
+
text: (_a = message.content) !== null && _a !== void 0 ? _a : ''
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
isNonStreamingModel(_model) {
|
|
153
|
+
return !this.enableStreaming;
|
|
154
|
+
}
|
|
155
|
+
supportsStructuredOutput() {
|
|
156
|
+
// see https://platform.openai.com/docs/models/gpt-4o
|
|
157
|
+
return [
|
|
158
|
+
'gpt-4o',
|
|
159
|
+
'gpt-4o-2024-08-06',
|
|
160
|
+
'gpt-4o-mini'
|
|
161
|
+
].includes(this.model);
|
|
162
|
+
}
|
|
163
|
+
async handleStructuredOutputRequest(openai, request) {
|
|
164
|
+
var _a;
|
|
165
|
+
const settings = this.getSettings(request);
|
|
166
|
+
// TODO implement tool support for structured output (parse() seems to require different tool format)
|
|
167
|
+
const result = await openai.beta.chat.completions.parse({
|
|
168
|
+
model: this.model,
|
|
169
|
+
messages: request.messages.map(toOpenAIMessage),
|
|
170
|
+
response_format: request.response_format,
|
|
171
|
+
...settings
|
|
172
|
+
});
|
|
173
|
+
const message = result.choices[0].message;
|
|
174
|
+
if (message.refusal || message.parsed === undefined) {
|
|
175
|
+
console.error('Error in OpenAI chat completion stream:', JSON.stringify(message));
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
content: (_a = message.content) !== null && _a !== void 0 ? _a : '',
|
|
179
|
+
parsed: message.parsed
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
getCompletionContent(message) {
|
|
183
|
+
if (Array.isArray(message.content)) {
|
|
184
|
+
return message.content.join('');
|
|
185
|
+
}
|
|
186
|
+
return message.content;
|
|
187
|
+
}
|
|
188
|
+
createTools(request) {
|
|
189
|
+
var _a;
|
|
190
|
+
return (_a = request.tools) === null || _a === void 0 ? void 0 : _a.map(tool => ({
|
|
191
|
+
type: 'function',
|
|
192
|
+
function: {
|
|
193
|
+
name: tool.name,
|
|
194
|
+
description: tool.description,
|
|
195
|
+
parameters: tool.parameters,
|
|
196
|
+
function: (args_string) => tool.handler(args_string)
|
|
197
|
+
}
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
initializeOpenAi() {
|
|
201
|
+
const apiKey = this.apiKey();
|
|
202
|
+
if (!apiKey && !(this.url)) {
|
|
203
|
+
throw new Error('Please provide OPENAI_API_KEY in preferences or via environment variable');
|
|
204
|
+
}
|
|
205
|
+
// We need to hand over "some" key, even if a custom url is not key protected as otherwise the OpenAI client will throw an error
|
|
206
|
+
return new openai_1.default({ apiKey: apiKey !== null && apiKey !== void 0 ? apiKey : 'no-key', baseURL: this.url });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.OpenAiModel = OpenAiModel;
|
|
210
|
+
//# sourceMappingURL=openai-language-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-language-model.js","sourceRoot":"","sources":["../../src/node/openai-language-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LanguageModelRegistry } from '@theia/ai-core';
|
|
2
|
+
import { OpenAiLanguageModelsManager, OpenAiModelDescription } from '../common';
|
|
3
|
+
export declare class OpenAiLanguageModelsManagerImpl implements OpenAiLanguageModelsManager {
|
|
4
|
+
protected _apiKey: string | undefined;
|
|
5
|
+
protected readonly languageModelRegistry: LanguageModelRegistry;
|
|
6
|
+
get apiKey(): string | undefined;
|
|
7
|
+
createOrUpdateLanguageModels(...modelDescriptions: OpenAiModelDescription[]): Promise<void>;
|
|
8
|
+
removeLanguageModels(...modelIds: string[]): void;
|
|
9
|
+
setApiKey(apiKey: string | undefined): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=openai-language-models-manager-impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-language-models-manager-impl.d.ts","sourceRoot":"","sources":["../../src/node/openai-language-models-manager-impl.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEhF,qBACa,+BAAgC,YAAW,2BAA2B;IAE/E,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAGtC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;IAEhE,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAE/B;IAIK,4BAA4B,CAAC,GAAG,iBAAiB,EAAE,sBAAsB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCjG,oBAAoB,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAIjD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAO9C"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2024 EclipseSource GmbH.
|
|
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.OpenAiLanguageModelsManagerImpl = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const ai_core_1 = require("@theia/ai-core");
|
|
21
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
22
|
+
const openai_language_model_1 = require("./openai-language-model");
|
|
23
|
+
let OpenAiLanguageModelsManagerImpl = class OpenAiLanguageModelsManagerImpl {
|
|
24
|
+
get apiKey() {
|
|
25
|
+
var _a;
|
|
26
|
+
return (_a = this._apiKey) !== null && _a !== void 0 ? _a : process.env.OPENAI_API_KEY;
|
|
27
|
+
}
|
|
28
|
+
// Triggered from frontend. In case you want to use the models on the backend
|
|
29
|
+
// without a frontend then call this yourself
|
|
30
|
+
async createOrUpdateLanguageModels(...modelDescriptions) {
|
|
31
|
+
for (const modelDescription of modelDescriptions) {
|
|
32
|
+
const model = await this.languageModelRegistry.getLanguageModel(modelDescription.id);
|
|
33
|
+
const apiKeyProvider = () => {
|
|
34
|
+
if (modelDescription.apiKey === true) {
|
|
35
|
+
return this.apiKey;
|
|
36
|
+
}
|
|
37
|
+
if (modelDescription.apiKey) {
|
|
38
|
+
return modelDescription.apiKey;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
};
|
|
42
|
+
if (model) {
|
|
43
|
+
if (!(model instanceof openai_language_model_1.OpenAiModel)) {
|
|
44
|
+
console.warn(`OpenAI: model ${modelDescription.id} is not an OpenAI model`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
model.model = modelDescription.model;
|
|
48
|
+
model.enableStreaming = modelDescription.enableStreaming;
|
|
49
|
+
model.url = modelDescription.url;
|
|
50
|
+
model.apiKey = apiKeyProvider;
|
|
51
|
+
model.defaultRequestSettings = modelDescription.defaultRequestSettings;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.languageModelRegistry.addLanguageModels([
|
|
55
|
+
new openai_language_model_1.OpenAiModel(modelDescription.id, modelDescription.model, modelDescription.enableStreaming, apiKeyProvider, modelDescription.url, modelDescription.defaultRequestSettings)
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
removeLanguageModels(...modelIds) {
|
|
61
|
+
this.languageModelRegistry.removeLanguageModels(modelIds);
|
|
62
|
+
}
|
|
63
|
+
setApiKey(apiKey) {
|
|
64
|
+
if (apiKey) {
|
|
65
|
+
this._apiKey = apiKey;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
this._apiKey = undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
exports.OpenAiLanguageModelsManagerImpl = OpenAiLanguageModelsManagerImpl;
|
|
73
|
+
tslib_1.__decorate([
|
|
74
|
+
(0, inversify_1.inject)(ai_core_1.LanguageModelRegistry),
|
|
75
|
+
tslib_1.__metadata("design:type", Object)
|
|
76
|
+
], OpenAiLanguageModelsManagerImpl.prototype, "languageModelRegistry", void 0);
|
|
77
|
+
exports.OpenAiLanguageModelsManagerImpl = OpenAiLanguageModelsManagerImpl = tslib_1.__decorate([
|
|
78
|
+
(0, inversify_1.injectable)()
|
|
79
|
+
], OpenAiLanguageModelsManagerImpl);
|
|
80
|
+
//# sourceMappingURL=openai-language-models-manager-impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-language-models-manager-impl.js","sourceRoot":"","sources":["../../src/node/openai-language-models-manager-impl.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,4CAAuD;AACvD,4DAAkE;AAClE,mEAAsD;AAI/C,IAAM,+BAA+B,GAArC,MAAM,+BAA+B;IAOxC,IAAI,MAAM;;QACN,OAAO,MAAA,IAAI,CAAC,OAAO,mCAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACtD,CAAC;IAED,6EAA6E;IAC7E,6CAA6C;IAC7C,KAAK,CAAC,4BAA4B,CAAC,GAAG,iBAA2C;QAC7E,KAAK,MAAM,gBAAgB,IAAI,iBAAiB,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrF,MAAM,cAAc,GAAG,GAAG,EAAE;gBACxB,IAAI,gBAAgB,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;oBACnC,OAAO,IAAI,CAAC,MAAM,CAAC;gBACvB,CAAC;gBACD,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;oBAC1B,OAAO,gBAAgB,CAAC,MAAM,CAAC;gBACnC,CAAC;gBACD,OAAO,SAAS,CAAC;YACrB,CAAC,CAAC;YAEF,IAAI,KAAK,EAAE,CAAC;gBACR,IAAI,CAAC,CAAC,KAAK,YAAY,mCAAW,CAAC,EAAE,CAAC;oBAClC,OAAO,CAAC,IAAI,CAAC,iBAAiB,gBAAgB,CAAC,EAAE,yBAAyB,CAAC,CAAC;oBAC5E,SAAS;gBACb,CAAC;gBACD,KAAK,CAAC,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC;gBACrC,KAAK,CAAC,eAAe,GAAG,gBAAgB,CAAC,eAAe,CAAC;gBACzD,KAAK,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC;gBACjC,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC;gBAC9B,KAAK,CAAC,sBAAsB,GAAG,gBAAgB,CAAC,sBAAsB,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,CAAC;oBACzC,IAAI,mCAAW,CACX,gBAAgB,CAAC,EAAE,EACnB,gBAAgB,CAAC,KAAK,EACtB,gBAAgB,CAAC,eAAe,EAChC,cAAc,EACd,gBAAgB,CAAC,GAAG,EACpB,gBAAgB,CAAC,sBAAsB,CAC1C;iBACJ,CAAC,CAAC;YACP,CAAC;QACL,CAAC;IACL,CAAC;IAED,oBAAoB,CAAC,GAAG,QAAkB;QACtC,IAAI,CAAC,qBAAqB,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED,SAAS,CAAC,MAA0B;QAChC,IAAI,MAAM,EAAE,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QAC1B,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QAC7B,CAAC;IACL,CAAC;CACJ,CAAA;AA9DY,0EAA+B;AAKrB;IADlB,IAAA,kBAAM,EAAC,+BAAqB,CAAC;;8EACkC;0CALvD,+BAA+B;IAD3C,IAAA,sBAAU,GAAE;GACA,+BAA+B,CA8D3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=package.spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.spec.d.ts","sourceRoot":"","sources":["../src/package.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 EclipseSource GmbH and others.
|
|
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
|
+
/* note: this bogus test file is required so that
|
|
17
|
+
we are able to run mocha unit tests on this
|
|
18
|
+
package, without having any actual unit tests in it.
|
|
19
|
+
This way a coverage report will be generated,
|
|
20
|
+
showing 0% coverage, instead of no report.
|
|
21
|
+
This file can be removed once we have real unit
|
|
22
|
+
tests in place. */
|
|
23
|
+
describe('ai-openai package', () => {
|
|
24
|
+
it('support code coverage statistics', () => true);
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=package.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.spec.js","sourceRoot":"","sources":["../src/package.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;;;;;;qBAMqB;AAErB,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAE/B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@theia/ai-openai",
|
|
3
|
+
"version": "1.46.0-next.241+4295c1a8c",
|
|
4
|
+
"description": "Theia - OpenAI Integration",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@theia/ai-core": "1.46.0-next.241+4295c1a8c",
|
|
7
|
+
"@theia/core": "1.46.0-next.241+4295c1a8c",
|
|
8
|
+
"@theia/filesystem": "1.46.0-next.241+4295c1a8c",
|
|
9
|
+
"@theia/workspace": "1.46.0-next.241+4295c1a8c",
|
|
10
|
+
"minimatch": "^5.1.0",
|
|
11
|
+
"openai": "^4.55.7",
|
|
12
|
+
"tslib": "^2.6.2"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"theiaExtensions": [
|
|
18
|
+
{
|
|
19
|
+
"frontend": "lib/browser/openai-frontend-module",
|
|
20
|
+
"backend": "lib/node/openai-backend-module"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"theia-extension"
|
|
25
|
+
],
|
|
26
|
+
"license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/eclipse-theia/theia.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/eclipse-theia/theia/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/eclipse-theia/theia",
|
|
35
|
+
"files": [
|
|
36
|
+
"lib",
|
|
37
|
+
"src"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "theiaext build",
|
|
41
|
+
"clean": "theiaext clean",
|
|
42
|
+
"compile": "theiaext compile",
|
|
43
|
+
"lint": "theiaext lint",
|
|
44
|
+
"test": "theiaext test",
|
|
45
|
+
"watch": "theiaext watch"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@theia/ext-scripts": "1.56.0"
|
|
49
|
+
},
|
|
50
|
+
"nyc": {
|
|
51
|
+
"extends": "../../configs/nyc.json"
|
|
52
|
+
},
|
|
53
|
+
"gitHead": "4295c1a8c8b5d23471f274265c798bac9e6baecc"
|
|
54
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 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 { FrontendApplicationContribution, PreferenceService } from '@theia/core/lib/browser';
|
|
18
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { OpenAiLanguageModelsManager, OpenAiModelDescription } from '../common';
|
|
20
|
+
import { API_KEY_PREF, CUSTOM_ENDPOINTS_PREF, MODELS_PREF } from './openai-preferences';
|
|
21
|
+
import { PREFERENCE_NAME_REQUEST_SETTINGS, RequestSetting } from '@theia/ai-core/lib/browser/ai-core-preferences';
|
|
22
|
+
|
|
23
|
+
const OPENAI_PROVIDER_ID = 'openai';
|
|
24
|
+
|
|
25
|
+
@injectable()
|
|
26
|
+
export class OpenAiFrontendApplicationContribution implements FrontendApplicationContribution {
|
|
27
|
+
|
|
28
|
+
@inject(PreferenceService)
|
|
29
|
+
protected preferenceService: PreferenceService;
|
|
30
|
+
|
|
31
|
+
@inject(OpenAiLanguageModelsManager)
|
|
32
|
+
protected manager: OpenAiLanguageModelsManager;
|
|
33
|
+
|
|
34
|
+
protected prevModels: string[] = [];
|
|
35
|
+
protected prevCustomModels: Partial<OpenAiModelDescription>[] = [];
|
|
36
|
+
|
|
37
|
+
onStart(): void {
|
|
38
|
+
this.preferenceService.ready.then(() => {
|
|
39
|
+
const apiKey = this.preferenceService.get<string>(API_KEY_PREF, undefined);
|
|
40
|
+
this.manager.setApiKey(apiKey);
|
|
41
|
+
|
|
42
|
+
const models = this.preferenceService.get<string[]>(MODELS_PREF, []);
|
|
43
|
+
const requestSettings = this.getRequestSettingsPref();
|
|
44
|
+
this.manager.createOrUpdateLanguageModels(...models.map(modelId => this.createOpenAIModelDescription(modelId, requestSettings)));
|
|
45
|
+
this.prevModels = [...models];
|
|
46
|
+
|
|
47
|
+
const customModels = this.preferenceService.get<Partial<OpenAiModelDescription>[]>(CUSTOM_ENDPOINTS_PREF, []);
|
|
48
|
+
this.manager.createOrUpdateLanguageModels(...this.createCustomModelDescriptionsFromPreferences(customModels, this.getRequestSettingsPref()));
|
|
49
|
+
this.prevCustomModels = [...customModels];
|
|
50
|
+
|
|
51
|
+
this.preferenceService.onPreferenceChanged(event => {
|
|
52
|
+
if (event.preferenceName === API_KEY_PREF) {
|
|
53
|
+
this.manager.setApiKey(event.newValue);
|
|
54
|
+
} else if (event.preferenceName === MODELS_PREF) {
|
|
55
|
+
this.handleModelChanges(event.newValue as string[]);
|
|
56
|
+
} else if (event.preferenceName === CUSTOM_ENDPOINTS_PREF) {
|
|
57
|
+
this.handleCustomModelChanges(event.newValue as Partial<OpenAiModelDescription>[]);
|
|
58
|
+
} else if (event.preferenceName === PREFERENCE_NAME_REQUEST_SETTINGS) {
|
|
59
|
+
this.handleRequestSettingsChanges(event.newValue as RequestSetting[]);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
protected handleModelChanges(newModels: string[]): void {
|
|
66
|
+
const oldModels = new Set(this.prevModels);
|
|
67
|
+
const updatedModels = new Set(newModels);
|
|
68
|
+
|
|
69
|
+
const modelsToRemove = [...oldModels].filter(model => !updatedModels.has(model));
|
|
70
|
+
const modelsToAdd = [...updatedModels].filter(model => !oldModels.has(model));
|
|
71
|
+
|
|
72
|
+
this.manager.removeLanguageModels(...modelsToRemove.map(model => `openai/${model}`));
|
|
73
|
+
const requestSettings = this.getRequestSettingsPref();
|
|
74
|
+
this.manager.createOrUpdateLanguageModels(...modelsToAdd.map(modelId => this.createOpenAIModelDescription(modelId, requestSettings)));
|
|
75
|
+
this.prevModels = newModels;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private getRequestSettingsPref(): RequestSetting[] {
|
|
79
|
+
return this.preferenceService.get<RequestSetting[]>(PREFERENCE_NAME_REQUEST_SETTINGS, []);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
protected handleCustomModelChanges(newCustomModels: Partial<OpenAiModelDescription>[]): void {
|
|
83
|
+
const requestSettings = this.getRequestSettingsPref();
|
|
84
|
+
const oldModels = this.createCustomModelDescriptionsFromPreferences(this.prevCustomModels, requestSettings);
|
|
85
|
+
const newModels = this.createCustomModelDescriptionsFromPreferences(newCustomModels, requestSettings);
|
|
86
|
+
|
|
87
|
+
const modelsToRemove = oldModels.filter(model => !newModels.some(newModel => newModel.id === model.id));
|
|
88
|
+
const modelsToAddOrUpdate = newModels.filter(newModel =>
|
|
89
|
+
!oldModels.some(model =>
|
|
90
|
+
model.id === newModel.id &&
|
|
91
|
+
model.model === newModel.model &&
|
|
92
|
+
model.url === newModel.url &&
|
|
93
|
+
model.apiKey === newModel.apiKey &&
|
|
94
|
+
model.enableStreaming === newModel.enableStreaming));
|
|
95
|
+
|
|
96
|
+
this.manager.removeLanguageModels(...modelsToRemove.map(model => model.id));
|
|
97
|
+
this.manager.createOrUpdateLanguageModels(...modelsToAddOrUpdate);
|
|
98
|
+
this.prevCustomModels = [...newCustomModels];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected handleRequestSettingsChanges(newSettings: RequestSetting[]): void {
|
|
102
|
+
const models = this.preferenceService.get<string[]>(MODELS_PREF, []);
|
|
103
|
+
this.manager.createOrUpdateLanguageModels(...models.map(modelId => this.createOpenAIModelDescription(modelId, newSettings)));
|
|
104
|
+
|
|
105
|
+
const customModels = this.preferenceService.get<Partial<OpenAiModelDescription>[]>(CUSTOM_ENDPOINTS_PREF, []);
|
|
106
|
+
this.manager.createOrUpdateLanguageModels(...this.createCustomModelDescriptionsFromPreferences(customModels, newSettings));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
protected createOpenAIModelDescription(modelId: string, requestSettings: RequestSetting[]): OpenAiModelDescription {
|
|
110
|
+
const id = `${OPENAI_PROVIDER_ID}/${modelId}`;
|
|
111
|
+
const modelRequestSetting = this.getMatchingRequestSetting(modelId, OPENAI_PROVIDER_ID, requestSettings);
|
|
112
|
+
return {
|
|
113
|
+
id: id,
|
|
114
|
+
model: modelId,
|
|
115
|
+
apiKey: true,
|
|
116
|
+
enableStreaming: !openAIModelsWithDisabledStreaming.includes(modelId),
|
|
117
|
+
defaultRequestSettings: modelRequestSetting?.requestSettings
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
protected createCustomModelDescriptionsFromPreferences(
|
|
122
|
+
preferences: Partial<OpenAiModelDescription>[],
|
|
123
|
+
requestSettings: RequestSetting[]
|
|
124
|
+
): OpenAiModelDescription[] {
|
|
125
|
+
return preferences.reduce((acc, pref) => {
|
|
126
|
+
if (!pref.model || !pref.url || typeof pref.model !== 'string' || typeof pref.url !== 'string') {
|
|
127
|
+
return acc;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const modelRequestSetting = this.getMatchingRequestSetting(pref.model, OPENAI_PROVIDER_ID, requestSettings);
|
|
131
|
+
|
|
132
|
+
return [
|
|
133
|
+
...acc,
|
|
134
|
+
{
|
|
135
|
+
id: pref.id && typeof pref.id === 'string' ? pref.id : pref.model,
|
|
136
|
+
model: pref.model,
|
|
137
|
+
url: pref.url,
|
|
138
|
+
apiKey: typeof pref.apiKey === 'string' || pref.apiKey === true ? pref.apiKey : undefined,
|
|
139
|
+
enableStreaming: pref.enableStreaming ?? true,
|
|
140
|
+
defaultRequestSettings: modelRequestSetting?.requestSettings
|
|
141
|
+
}
|
|
142
|
+
];
|
|
143
|
+
}, []);
|
|
144
|
+
}
|
|
145
|
+
protected getMatchingRequestSetting(
|
|
146
|
+
modelId: string,
|
|
147
|
+
providerId: string,
|
|
148
|
+
requestSettings: RequestSetting[]
|
|
149
|
+
): RequestSetting | undefined {
|
|
150
|
+
const matchingSettings = requestSettings.filter(
|
|
151
|
+
setting => (!setting.providerId || setting.providerId === providerId) && setting.modelId === modelId
|
|
152
|
+
);
|
|
153
|
+
if (matchingSettings.length > 1) {
|
|
154
|
+
console.warn(
|
|
155
|
+
`Multiple entries found for provider "${providerId}" and model "${modelId}". Using the first match.`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
return matchingSettings[0];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const openAIModelsWithDisabledStreaming = ['o1-preview'];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 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 { ContainerModule } from '@theia/core/shared/inversify';
|
|
18
|
+
import { OpenAiPreferencesSchema } from './openai-preferences';
|
|
19
|
+
import { FrontendApplicationContribution, PreferenceContribution, RemoteConnectionProvider, ServiceConnectionProvider } from '@theia/core/lib/browser';
|
|
20
|
+
import { OpenAiFrontendApplicationContribution } from './openai-frontend-application-contribution';
|
|
21
|
+
import { OPENAI_LANGUAGE_MODELS_MANAGER_PATH, OpenAiLanguageModelsManager } from '../common';
|
|
22
|
+
|
|
23
|
+
export default new ContainerModule(bind => {
|
|
24
|
+
bind(PreferenceContribution).toConstantValue({ schema: OpenAiPreferencesSchema });
|
|
25
|
+
bind(OpenAiFrontendApplicationContribution).toSelf().inSingletonScope();
|
|
26
|
+
bind(FrontendApplicationContribution).toService(OpenAiFrontendApplicationContribution);
|
|
27
|
+
bind(OpenAiLanguageModelsManager).toDynamicValue(ctx => {
|
|
28
|
+
const provider = ctx.container.get<ServiceConnectionProvider>(RemoteConnectionProvider);
|
|
29
|
+
return provider.createProxy<OpenAiLanguageModelsManager>(OPENAI_LANGUAGE_MODELS_MANAGER_PATH);
|
|
30
|
+
}).inSingletonScope();
|
|
31
|
+
});
|