@theia/ai-openai 1.72.0-next.52 → 1.72.0
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/lib/browser/openai-frontend-application-contribution.d.ts +1 -0
- package/lib/browser/openai-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/openai-frontend-application-contribution.js +7 -45
- package/lib/browser/openai-frontend-application-contribution.js.map +1 -1
- package/lib/common/openai-language-models-manager.d.ts +19 -41
- package/lib/common/openai-language-models-manager.d.ts.map +1 -1
- package/lib/common/openai-preferences.d.ts.map +1 -1
- package/lib/common/openai-preferences.js +4 -6
- package/lib/common/openai-preferences.js.map +1 -1
- package/lib/node/openai-language-model.d.ts +2 -1
- package/lib/node/openai-language-model.d.ts.map +1 -1
- package/lib/node/openai-language-model.js +2 -1
- package/lib/node/openai-language-model.js.map +1 -1
- package/lib/node/openai-language-models-manager-impl.d.ts +17 -2
- package/lib/node/openai-language-models-manager-impl.d.ts.map +1 -1
- package/lib/node/openai-language-models-manager-impl.js +25 -7
- package/lib/node/openai-language-models-manager-impl.js.map +1 -1
- package/lib/node/openai-model-defaults.d.ts +17 -0
- package/lib/node/openai-model-defaults.d.ts.map +1 -0
- package/lib/node/openai-model-defaults.js +65 -0
- package/lib/node/openai-model-defaults.js.map +1 -0
- package/lib/node/openai-model-defaults.spec.d.ts +2 -0
- package/lib/node/openai-model-defaults.spec.d.ts.map +1 -0
- package/lib/node/openai-model-defaults.spec.js +127 -0
- package/lib/node/openai-model-defaults.spec.js.map +1 -0
- package/package.json +7 -7
- package/src/browser/openai-frontend-application-contribution.ts +7 -51
- package/src/common/openai-language-models-manager.ts +19 -41
- package/src/common/openai-preferences.ts +4 -6
- package/src/node/openai-language-model.ts +2 -1
- package/src/node/openai-language-models-manager-impl.ts +40 -12
- package/src/node/openai-model-defaults.spec.ts +141 -0
- package/src/node/openai-model-defaults.ts +82 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 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.getOpenAiModelDefaults = getOpenAiModelDefaults;
|
|
19
|
+
const GPT5_REASONING_SUPPORT = {
|
|
20
|
+
supportedLevels: ['off', 'minimal', 'low', 'medium', 'high', 'auto'],
|
|
21
|
+
defaultLevel: 'auto'
|
|
22
|
+
};
|
|
23
|
+
const O_SERIES_REASONING_SUPPORT = {
|
|
24
|
+
supportedLevels: ['off', 'low', 'medium', 'high', 'auto'],
|
|
25
|
+
defaultLevel: 'auto'
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* First matching prefix wins, so more specific prefixes must come before broader ones
|
|
29
|
+
* (e.g. `gpt-5.4-mini` before `gpt-5.4`). Snapshots inherit their family value
|
|
30
|
+
* (e.g. `gpt-4o-2024-08-06` matches `gpt-4o`).
|
|
31
|
+
*/
|
|
32
|
+
const OPENAI_MODEL_FAMILIES = [
|
|
33
|
+
['gpt-5.5', { contextWindow: 1_050_000, reasoningSupport: GPT5_REASONING_SUPPORT }],
|
|
34
|
+
['gpt-5.4-mini', { contextWindow: 400_000, reasoningSupport: GPT5_REASONING_SUPPORT }],
|
|
35
|
+
['gpt-5.4-nano', { contextWindow: 400_000, reasoningSupport: GPT5_REASONING_SUPPORT }],
|
|
36
|
+
['gpt-5.4', { contextWindow: 1_050_000, reasoningSupport: GPT5_REASONING_SUPPORT }],
|
|
37
|
+
['gpt-5', { contextWindow: 400_000, reasoningSupport: GPT5_REASONING_SUPPORT }],
|
|
38
|
+
['gpt-4.1', { contextWindow: 1_047_576 }],
|
|
39
|
+
// gpt-4o-2024-05-13 predates structured output support; later snapshots support it.
|
|
40
|
+
['gpt-4o-2024-05-13', { contextWindow: 128_000, supportsStructuredOutput: false }],
|
|
41
|
+
['gpt-4o', { contextWindow: 128_000 }],
|
|
42
|
+
['gpt-4-turbo', { contextWindow: 128_000, supportsStructuredOutput: false }],
|
|
43
|
+
['gpt-4-32k', { contextWindow: 32_768, supportsStructuredOutput: false }],
|
|
44
|
+
['gpt-4', { contextWindow: 8_192, supportsStructuredOutput: false }],
|
|
45
|
+
['gpt-3.5', { contextWindow: 16_385, supportsStructuredOutput: false }],
|
|
46
|
+
['o4', { contextWindow: 200_000, reasoningSupport: O_SERIES_REASONING_SUPPORT }],
|
|
47
|
+
['o3', { contextWindow: 200_000, reasoningSupport: O_SERIES_REASONING_SUPPORT }],
|
|
48
|
+
['o1-preview', {
|
|
49
|
+
contextWindow: 128_000,
|
|
50
|
+
reasoningSupport: O_SERIES_REASONING_SUPPORT,
|
|
51
|
+
developerMessageSettings: 'user',
|
|
52
|
+
supportsStructuredOutput: false
|
|
53
|
+
}],
|
|
54
|
+
['o1-mini', {
|
|
55
|
+
contextWindow: 128_000,
|
|
56
|
+
reasoningSupport: O_SERIES_REASONING_SUPPORT,
|
|
57
|
+
developerMessageSettings: 'user',
|
|
58
|
+
supportsStructuredOutput: false
|
|
59
|
+
}],
|
|
60
|
+
['o1', { contextWindow: 200_000, reasoningSupport: O_SERIES_REASONING_SUPPORT }],
|
|
61
|
+
];
|
|
62
|
+
function getOpenAiModelDefaults(model) {
|
|
63
|
+
return OPENAI_MODEL_FAMILIES.find(([prefix]) => model.startsWith(prefix))?.[1] ?? {};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=openai-model-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-model-defaults.js","sourceRoot":"","sources":["../../src/node/openai-model-defaults.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-model-defaults.spec.d.ts","sourceRoot":"","sources":["../../src/node/openai-model-defaults.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 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
|
+
const chai_1 = require("chai");
|
|
19
|
+
const openai_model_defaults_1 = require("./openai-model-defaults");
|
|
20
|
+
describe('getOpenAiModelDefaults', () => {
|
|
21
|
+
it('returns empty defaults for unknown models', () => {
|
|
22
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)('totally-made-up-model')).to.deep.equal({});
|
|
23
|
+
});
|
|
24
|
+
describe('GPT-5.5', () => {
|
|
25
|
+
it('matches base and pro at 1,050,000 with GPT-5 reasoning', () => {
|
|
26
|
+
for (const id of ['gpt-5.5', 'gpt-5.5-pro']) {
|
|
27
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)(id);
|
|
28
|
+
(0, chai_1.expect)(d.contextWindow, id).to.equal(1_050_000);
|
|
29
|
+
(0, chai_1.expect)(d.reasoningSupport?.supportedLevels, id).to.include('minimal');
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('GPT-5.4', () => {
|
|
34
|
+
it('matches base and pro at 1,050,000', () => {
|
|
35
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-5.4').contextWindow).to.equal(1_050_000);
|
|
36
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-5.4-pro').contextWindow).to.equal(1_050_000);
|
|
37
|
+
});
|
|
38
|
+
it('matches mini and nano at 400,000 (specific prefix wins over `gpt-5.4`)', () => {
|
|
39
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-5.4-mini').contextWindow).to.equal(400_000);
|
|
40
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-5.4-nano').contextWindow).to.equal(400_000);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('GPT-5', () => {
|
|
44
|
+
it('matches base, pro, mini, nano, codex at 400,000', () => {
|
|
45
|
+
for (const id of ['gpt-5', 'gpt-5-pro', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-codex']) {
|
|
46
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)(id).contextWindow, id).to.equal(400_000);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
it('exposes GPT-5 reasoning support (incl. `minimal`)', () => {
|
|
50
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-5');
|
|
51
|
+
(0, chai_1.expect)(d.reasoningSupport?.supportedLevels).to.include('minimal');
|
|
52
|
+
(0, chai_1.expect)(d.reasoningSupport?.defaultLevel).to.equal('auto');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('GPT-4.1', () => {
|
|
56
|
+
it('matches the family at 1,047,576 with no reasoning', () => {
|
|
57
|
+
for (const id of ['gpt-4.1', 'gpt-4.1-mini', 'gpt-4.1-nano']) {
|
|
58
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)(id);
|
|
59
|
+
(0, chai_1.expect)(d.contextWindow, id).to.equal(1_047_576);
|
|
60
|
+
(0, chai_1.expect)(d.reasoningSupport, id).to.equal(undefined);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe('GPT-4o', () => {
|
|
65
|
+
it('matches base, mini, and most snapshots at 128,000 with structured output enabled', () => {
|
|
66
|
+
for (const id of ['gpt-4o', 'gpt-4o-mini', 'gpt-4o-2024-08-06']) {
|
|
67
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)(id);
|
|
68
|
+
(0, chai_1.expect)(d.contextWindow, id).to.equal(128_000);
|
|
69
|
+
(0, chai_1.expect)(d.supportsStructuredOutput, id).to.equal(undefined); // default true at the manager
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
it('flags the gpt-4o-2024-05-13 snapshot as not supporting structured output', () => {
|
|
73
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-4o-2024-05-13');
|
|
74
|
+
(0, chai_1.expect)(d.contextWindow).to.equal(128_000);
|
|
75
|
+
(0, chai_1.expect)(d.supportsStructuredOutput).to.equal(false);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe('GPT-4 turbo / 32k / base', () => {
|
|
79
|
+
it('matches gpt-4-turbo at 128,000 (no structured output)', () => {
|
|
80
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-4-turbo-2024-04-09');
|
|
81
|
+
(0, chai_1.expect)(d.contextWindow).to.equal(128_000);
|
|
82
|
+
(0, chai_1.expect)(d.supportsStructuredOutput).to.equal(false);
|
|
83
|
+
});
|
|
84
|
+
it('matches gpt-4-32k at 32,768 (no structured output)', () => {
|
|
85
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-4-32k');
|
|
86
|
+
(0, chai_1.expect)(d.contextWindow).to.equal(32_768);
|
|
87
|
+
(0, chai_1.expect)(d.supportsStructuredOutput).to.equal(false);
|
|
88
|
+
});
|
|
89
|
+
it('falls back to gpt-4 (8,192) for the base model', () => {
|
|
90
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)('gpt-4-0613');
|
|
91
|
+
(0, chai_1.expect)(d.contextWindow).to.equal(8_192);
|
|
92
|
+
(0, chai_1.expect)(d.supportsStructuredOutput).to.equal(false);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe('GPT-3.5', () => {
|
|
96
|
+
it('matches gpt-3.5-turbo and snapshots at 16,385 (no structured output)', () => {
|
|
97
|
+
for (const id of ['gpt-3.5-turbo', 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-0125']) {
|
|
98
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)(id);
|
|
99
|
+
(0, chai_1.expect)(d.contextWindow, id).to.equal(16_385);
|
|
100
|
+
(0, chai_1.expect)(d.supportsStructuredOutput, id).to.equal(false);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('o-series', () => {
|
|
105
|
+
it('matches o4 and o3 families at 200,000 with o-series reasoning', () => {
|
|
106
|
+
for (const id of ['o4-mini', 'o3', 'o3-mini', 'o3-pro']) {
|
|
107
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)(id);
|
|
108
|
+
(0, chai_1.expect)(d.contextWindow, id).to.equal(200_000);
|
|
109
|
+
(0, chai_1.expect)(d.reasoningSupport?.supportedLevels, id).to.not.include('minimal');
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
it('matches o1 / o1-pro at 200,000', () => {
|
|
113
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)('o1').contextWindow).to.equal(200_000);
|
|
114
|
+
(0, chai_1.expect)((0, openai_model_defaults_1.getOpenAiModelDefaults)('o1-pro').contextWindow).to.equal(200_000);
|
|
115
|
+
});
|
|
116
|
+
it('matches o1-preview / o1-mini at 128,000 with the legacy "user" role and no structured output', () => {
|
|
117
|
+
for (const id of ['o1-preview', 'o1-mini']) {
|
|
118
|
+
const d = (0, openai_model_defaults_1.getOpenAiModelDefaults)(id);
|
|
119
|
+
(0, chai_1.expect)(d.contextWindow, id).to.equal(128_000);
|
|
120
|
+
(0, chai_1.expect)(d.developerMessageSettings, id).to.equal('user');
|
|
121
|
+
(0, chai_1.expect)(d.supportsStructuredOutput, id).to.equal(false);
|
|
122
|
+
(0, chai_1.expect)(d.reasoningSupport, id).to.not.equal(undefined);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=openai-model-defaults.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-model-defaults.spec.js","sourceRoot":"","sources":["../../src/node/openai-model-defaults.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/ai-openai",
|
|
3
|
-
"version": "1.72.0
|
|
3
|
+
"version": "1.72.0",
|
|
4
4
|
"description": "Theia - OpenAI Integration",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@theia/ai-core": "1.72.0
|
|
7
|
-
"@theia/core": "1.72.0
|
|
8
|
-
"@theia/filesystem": "1.72.0
|
|
9
|
-
"@theia/workspace": "1.72.0
|
|
6
|
+
"@theia/ai-core": "1.72.0",
|
|
7
|
+
"@theia/core": "1.72.0",
|
|
8
|
+
"@theia/filesystem": "1.72.0",
|
|
9
|
+
"@theia/workspace": "1.72.0",
|
|
10
10
|
"openai": "^6.35.0",
|
|
11
11
|
"tslib": "^2.8.1"
|
|
12
12
|
},
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"watch": "theiaext watch"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@theia/ext-scripts": "1.
|
|
47
|
+
"@theia/ext-scripts": "1.72.0"
|
|
48
48
|
},
|
|
49
49
|
"nyc": {
|
|
50
50
|
"extends": "../../configs/nyc.json"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "5bc20bc672aa732fb7e05234cf63c1b514868896"
|
|
53
53
|
}
|
|
@@ -121,6 +121,7 @@ export class OpenAiFrontendApplicationContribution implements FrontendApplicatio
|
|
|
121
121
|
this.manager.createOrUpdateLanguageModels(...this.createCustomModelDescriptionsFromPreferences(customModels));
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/** Per-model capabilities are resolved by the backend from the model id; see `openai-model-defaults.ts`. */
|
|
124
125
|
protected createOpenAIModelDescription(modelId: string): OpenAiModelDescription {
|
|
125
126
|
const id = `${OPENAI_PROVIDER_ID}/${modelId}`;
|
|
126
127
|
const maxRetries = this.aiCorePreferences.get(PREFERENCE_NAME_MAX_RETRIES) ?? 3;
|
|
@@ -130,12 +131,8 @@ export class OpenAiFrontendApplicationContribution implements FrontendApplicatio
|
|
|
130
131
|
model: modelId,
|
|
131
132
|
apiKey: true,
|
|
132
133
|
apiVersion: true,
|
|
133
|
-
developerMessageSettings: openAIModelsNotSupportingDeveloperMessages.includes(modelId) ? 'user' : 'developer',
|
|
134
|
-
enableStreaming: !openAIModelsWithDisabledStreaming.includes(modelId),
|
|
135
|
-
supportsStructuredOutput: !openAIModelsWithoutStructuredOutput.includes(modelId),
|
|
136
134
|
maxRetries: maxRetries,
|
|
137
|
-
useResponseApi: useResponseApi
|
|
138
|
-
reasoningSupport: reasoningSupportFor(modelId)
|
|
135
|
+
useResponseApi: useResponseApi
|
|
139
136
|
};
|
|
140
137
|
}
|
|
141
138
|
|
|
@@ -147,13 +144,6 @@ export class OpenAiFrontendApplicationContribution implements FrontendApplicatio
|
|
|
147
144
|
if (!pref.model || !pref.url || typeof pref.model !== 'string' || typeof pref.url !== 'string') {
|
|
148
145
|
return acc;
|
|
149
146
|
}
|
|
150
|
-
// Default to the model-name heuristic so reasoning-capable GPT-5 / o-series models exposed via
|
|
151
|
-
// a custom endpoint still get the selector. Users can override via `reasoningSupport`
|
|
152
|
-
// (set to `null` to disable, or to a full `ReasoningSupport` object to customize).
|
|
153
|
-
const reasoningSupport: ReasoningSupport | undefined = 'reasoningSupport' in pref
|
|
154
|
-
? (isReasoningSupport(pref.reasoningSupport) ? pref.reasoningSupport : undefined)
|
|
155
|
-
: reasoningSupportFor(pref.model);
|
|
156
|
-
|
|
157
147
|
return [
|
|
158
148
|
...acc,
|
|
159
149
|
{
|
|
@@ -163,12 +153,12 @@ export class OpenAiFrontendApplicationContribution implements FrontendApplicatio
|
|
|
163
153
|
deployment: typeof pref.deployment === 'string' && pref.deployment ? pref.deployment : undefined,
|
|
164
154
|
apiKey: typeof pref.apiKey === 'string' || pref.apiKey === true ? pref.apiKey : undefined,
|
|
165
155
|
apiVersion: typeof pref.apiVersion === 'string' || pref.apiVersion === true ? pref.apiVersion : undefined,
|
|
166
|
-
developerMessageSettings: pref.developerMessageSettings
|
|
167
|
-
supportsStructuredOutput: pref.supportsStructuredOutput
|
|
168
|
-
enableStreaming: pref.enableStreaming
|
|
156
|
+
developerMessageSettings: pref.developerMessageSettings,
|
|
157
|
+
supportsStructuredOutput: pref.supportsStructuredOutput,
|
|
158
|
+
enableStreaming: pref.enableStreaming,
|
|
169
159
|
maxRetries: pref.maxRetries ?? maxRetries,
|
|
170
160
|
useResponseApi: pref.useResponseApi ?? false,
|
|
171
|
-
reasoningSupport
|
|
161
|
+
reasoningSupport: isReasoningSupport(pref.reasoningSupport) ? pref.reasoningSupport : undefined
|
|
172
162
|
}
|
|
173
163
|
];
|
|
174
164
|
}, []);
|
|
@@ -179,12 +169,7 @@ function isReasoningSupport(value: unknown): value is ReasoningSupport {
|
|
|
179
169
|
return !!value && typeof value === 'object' && Array.isArray((value as ReasoningSupport).supportedLevels);
|
|
180
170
|
}
|
|
181
171
|
|
|
182
|
-
/**
|
|
183
|
-
* Structural equality for {@link ReasoningSupport}. Used by {@link handleCustomModelChanges} to avoid
|
|
184
|
-
* needless model re-creation when the user supplies an explicit `reasoningSupport` object via
|
|
185
|
-
* preferences — each JSON deserialization yields a fresh object reference, so a `===` check would
|
|
186
|
-
* always report a change even when the contents are identical.
|
|
187
|
-
*/
|
|
172
|
+
/** Structural equality — preference reads yield fresh objects, so identity comparison would always report a change. */
|
|
188
173
|
function reasoningSupportEquals(a: ReasoningSupport | undefined, b: ReasoningSupport | undefined): boolean {
|
|
189
174
|
if (a === b) {
|
|
190
175
|
return true;
|
|
@@ -196,32 +181,3 @@ function reasoningSupportEquals(a: ReasoningSupport | undefined, b: ReasoningSup
|
|
|
196
181
|
&& a.supportedLevels.length === b.supportedLevels.length
|
|
197
182
|
&& a.supportedLevels.every((level, index) => level === b.supportedLevels[index]);
|
|
198
183
|
}
|
|
199
|
-
|
|
200
|
-
const openAIModelsWithDisabledStreaming: string[] = [];
|
|
201
|
-
const openAIModelsNotSupportingDeveloperMessages = ['o1-preview', 'o1-mini'];
|
|
202
|
-
const openAIModelsWithoutStructuredOutput = ['o1-preview', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo', 'o1-mini', 'gpt-4o-2024-05-13'];
|
|
203
|
-
|
|
204
|
-
/** GPT-5 family: supports `minimal` in addition to `low | medium | high`. */
|
|
205
|
-
const GPT5_REASONING = /^gpt-5(?:\.|-|$)/i;
|
|
206
|
-
/** o-series reasoning models (o1, o3, o4): `low | medium | high`. */
|
|
207
|
-
const O_SERIES_REASONING = /^o[134](?:-|$)/i;
|
|
208
|
-
|
|
209
|
-
const GPT5_REASONING_SUPPORT: ReasoningSupport = {
|
|
210
|
-
supportedLevels: ['off', 'minimal', 'low', 'medium', 'high', 'auto'],
|
|
211
|
-
defaultLevel: 'auto'
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
const O_SERIES_REASONING_SUPPORT: ReasoningSupport = {
|
|
215
|
-
supportedLevels: ['off', 'low', 'medium', 'high', 'auto'],
|
|
216
|
-
defaultLevel: 'auto'
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
function reasoningSupportFor(modelId: string): ReasoningSupport | undefined {
|
|
220
|
-
if (GPT5_REASONING.test(modelId)) {
|
|
221
|
-
return GPT5_REASONING_SUPPORT;
|
|
222
|
-
}
|
|
223
|
-
if (O_SERIES_REASONING.test(modelId)) {
|
|
224
|
-
return O_SERIES_REASONING_SUPPORT;
|
|
225
|
-
}
|
|
226
|
-
return undefined;
|
|
227
|
-
}
|
|
@@ -21,56 +21,34 @@ export const OpenAiLanguageModelsManager = Symbol('OpenAiLanguageModelsManager')
|
|
|
21
21
|
export const OPENAI_PROVIDER_ID = 'openai';
|
|
22
22
|
|
|
23
23
|
export interface OpenAiModelDescription {
|
|
24
|
-
/**
|
|
25
|
-
* The identifier of the model which will be shown in the UI.
|
|
26
|
-
*/
|
|
24
|
+
/** The identifier of the model which will be shown in the UI. */
|
|
27
25
|
id: string;
|
|
28
|
-
/**
|
|
29
|
-
* The model ID as used by the OpenAI API.
|
|
30
|
-
*/
|
|
26
|
+
/** The model ID as used by the OpenAI API. */
|
|
31
27
|
model: string;
|
|
32
|
-
/**
|
|
33
|
-
* The OpenAI API compatible endpoint where the model is hosted. If not provided the default OpenAI endpoint will be used.
|
|
34
|
-
*/
|
|
28
|
+
/** The OpenAI API compatible endpoint where the model is hosted. If not provided the default OpenAI endpoint will be used. */
|
|
35
29
|
url?: string;
|
|
36
|
-
/**
|
|
37
|
-
* The key for the model. If 'true' is provided the global OpenAI API key will be used.
|
|
38
|
-
*/
|
|
30
|
+
/** The key for the model. If `true` is provided the global OpenAI API key will be used. */
|
|
39
31
|
apiKey: string | true | undefined;
|
|
40
|
-
/**
|
|
41
|
-
* The version for the api. If 'true' is provided the global OpenAI version will be used.
|
|
42
|
-
*/
|
|
32
|
+
/** The version for the api. If `true` is provided the global OpenAI version will be used. */
|
|
43
33
|
apiVersion: string | true | undefined;
|
|
44
|
-
/**
|
|
45
|
-
* Optional deployment name for Azure OpenAI.
|
|
46
|
-
*/
|
|
34
|
+
/** Optional deployment name for Azure OpenAI. */
|
|
47
35
|
deployment?: string;
|
|
48
|
-
/**
|
|
49
|
-
* Indicate whether the streaming API shall be used.
|
|
50
|
-
*/
|
|
51
|
-
enableStreaming: boolean;
|
|
52
|
-
/**
|
|
53
|
-
* Property to configure the developer message of the model. Setting this property to 'user', 'system', or 'developer' will use that string as the role for the system message.
|
|
54
|
-
* Setting it to 'mergeWithFollowingUserMessage' will prefix the following user message with the system message or convert the system message to user if the following message
|
|
55
|
-
* is not a user message. 'skip' will remove the system message altogether.
|
|
56
|
-
* Defaults to 'developer'.
|
|
57
|
-
*/
|
|
58
|
-
developerMessageSettings?: 'user' | 'system' | 'developer' | 'mergeWithFollowingUserMessage' | 'skip';
|
|
59
|
-
/**
|
|
60
|
-
* Flag to configure whether the OpenAPI model supports structured output. Default is `true`.
|
|
61
|
-
*/
|
|
62
|
-
supportsStructuredOutput: boolean;
|
|
63
|
-
/**
|
|
64
|
-
* Maximum number of retry attempts when a request fails. Default is 3.
|
|
65
|
-
*/
|
|
36
|
+
/** Maximum number of retry attempts when a request fails. Default is 3. */
|
|
66
37
|
maxRetries: number;
|
|
38
|
+
/** Use the newer OpenAI Response API instead of the Chat Completion API. Default is `false`. */
|
|
39
|
+
useResponseApi?: boolean;
|
|
40
|
+
/** Indicate whether the streaming API shall be used. Defaults from the model id when unset. */
|
|
41
|
+
enableStreaming?: boolean;
|
|
67
42
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
43
|
+
* Configures how system messages are handled. `'user' | 'system' | 'developer'` use that role for
|
|
44
|
+
* the system message; `'mergeWithFollowingUserMessage'` prepends the system message to the next
|
|
45
|
+
* user message (creating one when needed); `'skip'` removes system messages. Defaults from the
|
|
46
|
+
* model id when unset (typically `'developer'`).
|
|
71
47
|
*/
|
|
72
|
-
|
|
73
|
-
/**
|
|
48
|
+
developerMessageSettings?: 'user' | 'system' | 'developer' | 'mergeWithFollowingUserMessage' | 'skip';
|
|
49
|
+
/** Whether the model supports structured output (`response_format` JSON schemas). Defaults from the model id when unset. */
|
|
50
|
+
supportsStructuredOutput?: boolean;
|
|
51
|
+
/** When set, the UI exposes a reasoning selector. Defaults from the model id when unset. */
|
|
74
52
|
reasoningSupport?: ReasoningSupport;
|
|
75
53
|
}
|
|
76
54
|
export interface OpenAiLanguageModelsManager {
|
|
@@ -86,9 +86,8 @@ Best effort is made to convert non-conformant schemas, but errors are still poss
|
|
|
86
86
|
\n\
|
|
87
87
|
- specify `useResponseApi: true` to use the newer OpenAI Response API instead of the Chat Completion API (requires compatible endpoint).\
|
|
88
88
|
\n\
|
|
89
|
-
- specify `reasoningSupport` to opt in to the chat reasoning selector.
|
|
90
|
-
`
|
|
91
|
-
`["off", "low", "medium", "high", "auto"]`) and an optional `defaultLevel` to customize.\
|
|
89
|
+
- specify `reasoningSupport` to opt in to the chat reasoning selector. Provide an object with\
|
|
90
|
+
`supportedLevels` (e.g. `["off", "low", "medium", "high", "auto"]`) and an optional `defaultLevel`.\
|
|
92
91
|
\n\
|
|
93
92
|
Refer to [our documentation](https://theia-ide.org/docs/user_ai/#openai-compatible-models-eg-via-vllm) for more information.'),
|
|
94
93
|
default: [],
|
|
@@ -148,10 +147,9 @@ Best effort is made to convert non-conformant schemas, but errors are still poss
|
|
|
148
147
|
+ 'Note: Will automatically fall back to Chat Completions API when tools are used.'),
|
|
149
148
|
},
|
|
150
149
|
reasoningSupport: {
|
|
151
|
-
type:
|
|
150
|
+
type: 'object',
|
|
152
151
|
title: nls.localize('theia/ai/openai/customEndpoints/reasoningSupport/title',
|
|
153
|
-
'Declares the model\'s reasoning capabilities. When set the chat shows a reasoning selector'
|
|
154
|
-
+ ' for this model. Set to `null` to disable. Inferred from the model name by default.'),
|
|
152
|
+
'Declares the model\'s reasoning capabilities. When set the chat shows a reasoning selector for this model.'),
|
|
155
153
|
properties: {
|
|
156
154
|
supportedLevels: {
|
|
157
155
|
type: 'array',
|
|
@@ -106,7 +106,8 @@ export class OpenAiModel implements LanguageModel {
|
|
|
106
106
|
public maxRetries: number = 3,
|
|
107
107
|
public useResponseApi: boolean = false,
|
|
108
108
|
public proxy?: string,
|
|
109
|
-
public reasoningSupport?: ReasoningSupport
|
|
109
|
+
public reasoningSupport?: ReasoningSupport,
|
|
110
|
+
public maxInputTokens?: number
|
|
110
111
|
) { }
|
|
111
112
|
|
|
112
113
|
/** Reasoning-level translation lives in {@link openAiReasoningFor}. */
|
|
@@ -14,13 +14,22 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { LanguageModelRegistry, LanguageModelStatus } from '@theia/ai-core';
|
|
17
|
+
import { LanguageModelRegistry, LanguageModelStatus, ReasoningSupport } from '@theia/ai-core';
|
|
18
18
|
import { getProxyUrl } from '@theia/ai-core/lib/node';
|
|
19
19
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
20
|
-
import { OpenAiModel, OpenAiModelUtils } from './openai-language-model';
|
|
20
|
+
import { DeveloperMessageSettings, OpenAiModel, OpenAiModelUtils } from './openai-language-model';
|
|
21
21
|
import { OpenAiResponseApiUtils } from './openai-response-api-utils';
|
|
22
|
+
import { getOpenAiModelDefaults } from './openai-model-defaults';
|
|
22
23
|
import { OpenAiLanguageModelsManager, OpenAiModelDescription } from '../common';
|
|
23
24
|
|
|
25
|
+
interface ResolvedModelMetadata {
|
|
26
|
+
maxInputTokens?: number;
|
|
27
|
+
reasoningSupport?: ReasoningSupport;
|
|
28
|
+
developerMessageSettings: DeveloperMessageSettings;
|
|
29
|
+
enableStreaming: boolean;
|
|
30
|
+
supportsStructuredOutput: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
@injectable()
|
|
25
34
|
export class OpenAiLanguageModelsManagerImpl implements OpenAiLanguageModelsManager {
|
|
26
35
|
|
|
@@ -46,7 +55,7 @@ export class OpenAiLanguageModelsManagerImpl implements OpenAiLanguageModelsMana
|
|
|
46
55
|
}
|
|
47
56
|
|
|
48
57
|
protected calculateStatus(modelDescription: OpenAiModelDescription, effectiveApiKey: string | undefined): LanguageModelStatus {
|
|
49
|
-
//
|
|
58
|
+
// Custom models (with `url`) are always marked ready since their API key requirements are unknown.
|
|
50
59
|
if (modelDescription.url) {
|
|
51
60
|
return { status: 'ready' };
|
|
52
61
|
}
|
|
@@ -80,8 +89,8 @@ export class OpenAiLanguageModelsManagerImpl implements OpenAiLanguageModelsMana
|
|
|
80
89
|
};
|
|
81
90
|
const proxyUrl = getProxyUrl(modelDescription.url ?? 'https://api.openai.com', this._proxyUrl);
|
|
82
91
|
|
|
83
|
-
// Determine the effective API key for status
|
|
84
92
|
const status = this.calculateStatus(modelDescription, apiKeyProvider());
|
|
93
|
+
const metadata = this.resolveMetadata(modelDescription);
|
|
85
94
|
|
|
86
95
|
if (model) {
|
|
87
96
|
if (!(model instanceof OpenAiModel)) {
|
|
@@ -90,18 +99,19 @@ export class OpenAiLanguageModelsManagerImpl implements OpenAiLanguageModelsMana
|
|
|
90
99
|
}
|
|
91
100
|
await this.languageModelRegistry.patchLanguageModel<OpenAiModel>(modelDescription.id, {
|
|
92
101
|
model: modelDescription.model,
|
|
93
|
-
enableStreaming:
|
|
102
|
+
enableStreaming: metadata.enableStreaming,
|
|
94
103
|
url: modelDescription.url,
|
|
95
104
|
apiKey: apiKeyProvider,
|
|
96
105
|
apiVersion: apiVersionProvider,
|
|
97
106
|
deployment: modelDescription.deployment,
|
|
98
|
-
developerMessageSettings:
|
|
99
|
-
supportsStructuredOutput:
|
|
107
|
+
developerMessageSettings: metadata.developerMessageSettings,
|
|
108
|
+
supportsStructuredOutput: metadata.supportsStructuredOutput,
|
|
100
109
|
status,
|
|
101
110
|
maxRetries: modelDescription.maxRetries,
|
|
102
111
|
useResponseApi: modelDescription.useResponseApi ?? false,
|
|
103
112
|
proxy: proxyUrl,
|
|
104
|
-
reasoningSupport:
|
|
113
|
+
reasoningSupport: metadata.reasoningSupport,
|
|
114
|
+
maxInputTokens: metadata.maxInputTokens
|
|
105
115
|
});
|
|
106
116
|
} else {
|
|
107
117
|
this.languageModelRegistry.addLanguageModels([
|
|
@@ -109,25 +119,43 @@ export class OpenAiLanguageModelsManagerImpl implements OpenAiLanguageModelsMana
|
|
|
109
119
|
modelDescription.id,
|
|
110
120
|
modelDescription.model,
|
|
111
121
|
status,
|
|
112
|
-
|
|
122
|
+
metadata.enableStreaming,
|
|
113
123
|
apiKeyProvider,
|
|
114
124
|
apiVersionProvider,
|
|
115
|
-
|
|
125
|
+
metadata.supportsStructuredOutput,
|
|
116
126
|
modelDescription.url,
|
|
117
127
|
modelDescription.deployment,
|
|
118
128
|
this.openAiModelUtils,
|
|
119
129
|
this.responseApiUtils,
|
|
120
|
-
|
|
130
|
+
metadata.developerMessageSettings,
|
|
121
131
|
modelDescription.maxRetries,
|
|
122
132
|
modelDescription.useResponseApi ?? false,
|
|
123
133
|
proxyUrl,
|
|
124
|
-
|
|
134
|
+
metadata.reasoningSupport,
|
|
135
|
+
metadata.maxInputTokens
|
|
125
136
|
)
|
|
126
137
|
]);
|
|
127
138
|
}
|
|
128
139
|
}
|
|
129
140
|
}
|
|
130
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Merges description overrides with model-id-based defaults from {@link getOpenAiModelDefaults}.
|
|
144
|
+
* Description fields win, allowing custom-endpoint preferences to override capabilities for
|
|
145
|
+
* non-OpenAI models. Custom endpoints (with a `url`) skip the context window lookup since we
|
|
146
|
+
* don't know which model is actually behind the endpoint.
|
|
147
|
+
*/
|
|
148
|
+
protected resolveMetadata(description: OpenAiModelDescription): ResolvedModelMetadata {
|
|
149
|
+
const defaults = getOpenAiModelDefaults(description.model);
|
|
150
|
+
return {
|
|
151
|
+
maxInputTokens: description.url ? undefined : defaults.contextWindow,
|
|
152
|
+
reasoningSupport: description.reasoningSupport ?? defaults.reasoningSupport,
|
|
153
|
+
developerMessageSettings: description.developerMessageSettings ?? defaults.developerMessageSettings ?? 'developer',
|
|
154
|
+
enableStreaming: description.enableStreaming ?? defaults.supportsStreaming ?? true,
|
|
155
|
+
supportsStructuredOutput: description.supportsStructuredOutput ?? defaults.supportsStructuredOutput ?? true
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
131
159
|
removeLanguageModels(...modelIds: string[]): void {
|
|
132
160
|
this.languageModelRegistry.removeLanguageModels(modelIds);
|
|
133
161
|
}
|