@theia/ai-ide 1.67.0-next.59 → 1.67.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/address-pr-review-command-contribution.d.ts +9 -0
- package/lib/browser/address-pr-review-command-contribution.d.ts.map +1 -0
- package/lib/browser/address-pr-review-command-contribution.js +176 -0
- package/lib/browser/address-pr-review-command-contribution.js.map +1 -0
- package/lib/browser/ai-configuration/agent-configuration-widget.d.ts +12 -6
- package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js +158 -106
- package/lib/browser/ai-configuration/agent-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts +32 -0
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js +55 -0
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js.map +1 -0
- package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts +14 -0
- package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/base/ai-configuration-base-widget.js +35 -0
- package/lib/browser/ai-configuration/base/ai-configuration-base-widget.js.map +1 -0
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts +23 -0
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js +60 -0
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js.map +1 -0
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts +56 -0
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js +96 -0
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js.map +1 -0
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts +45 -0
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js +66 -0
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js.map +1 -0
- package/lib/browser/ai-configuration/components/configuration-section.d.ts +13 -0
- package/lib/browser/ai-configuration/components/configuration-section.d.ts.map +1 -0
- package/lib/browser/ai-configuration/components/configuration-section.js +28 -0
- package/lib/browser/ai-configuration/components/configuration-section.js.map +1 -0
- package/lib/browser/ai-configuration/components/empty-state.d.ts +11 -0
- package/lib/browser/ai-configuration/components/empty-state.d.ts.map +1 -0
- package/lib/browser/ai-configuration/components/empty-state.js +26 -0
- package/lib/browser/ai-configuration/components/empty-state.js.map +1 -0
- package/lib/browser/ai-configuration/components/expandable-section.d.ts +14 -0
- package/lib/browser/ai-configuration/components/expandable-section.d.ts.map +1 -0
- package/lib/browser/ai-configuration/components/expandable-section.js +31 -0
- package/lib/browser/ai-configuration/components/expandable-section.js.map +1 -0
- package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -1
- package/lib/browser/ai-configuration/language-model-renderer.js +23 -22
- package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -1
- package/lib/browser/ai-configuration/mcp-configuration-widget.d.ts +0 -1
- package/lib/browser/ai-configuration/mcp-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/mcp-configuration-widget.js +88 -82
- package/lib/browser/ai-configuration/mcp-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts +8 -22
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.js +49 -78
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +10 -10
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.js +11 -11
- package/lib/browser/ai-configuration/template-settings-renderer.js.map +1 -1
- package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts +7 -8
- package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/token-usage-configuration-widget.js +93 -79
- package/lib/browser/ai-configuration/token-usage-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +12 -7
- package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/tools-configuration-widget.js +45 -37
- package/lib/browser/ai-configuration/tools-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/variable-configuration-widget.d.ts +8 -4
- package/lib/browser/ai-configuration/variable-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/variable-configuration-widget.js +61 -28
- package/lib/browser/ai-configuration/variable-configuration-widget.js.map +1 -1
- package/lib/browser/analyze-gh-ticket-command-contribution.d.ts +9 -0
- package/lib/browser/analyze-gh-ticket-command-contribution.d.ts.map +1 -0
- package/lib/browser/analyze-gh-ticket-command-contribution.js +172 -0
- package/lib/browser/analyze-gh-ticket-command-contribution.js.map +1 -0
- package/lib/browser/default-chat-agent-recommendation-service.d.ts +5 -0
- package/lib/browser/default-chat-agent-recommendation-service.d.ts.map +1 -0
- package/lib/browser/default-chat-agent-recommendation-service.js +47 -0
- package/lib/browser/default-chat-agent-recommendation-service.js.map +1 -0
- package/lib/browser/frontend-module.d.ts.map +1 -1
- package/lib/browser/frontend-module.js +9 -3
- package/lib/browser/frontend-module.js.map +1 -1
- package/lib/browser/ide-chat-welcome-message-provider.d.ts +36 -0
- package/lib/browser/ide-chat-welcome-message-provider.d.ts.map +1 -1
- package/lib/browser/ide-chat-welcome-message-provider.js +204 -1
- package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
- package/lib/browser/implement-gh-ticket-command-contribution.d.ts +9 -0
- package/lib/browser/implement-gh-ticket-command-contribution.d.ts.map +1 -0
- package/lib/browser/implement-gh-ticket-command-contribution.js +156 -0
- package/lib/browser/implement-gh-ticket-command-contribution.js.map +1 -0
- package/package.json +21 -21
- package/src/browser/address-pr-review-command-contribution.ts +180 -0
- package/src/browser/ai-configuration/agent-configuration-widget.tsx +258 -137
- package/src/browser/ai-configuration/base/ai-card-grid-configuration-widget.tsx +72 -0
- package/src/browser/ai-configuration/base/ai-configuration-base-widget.tsx +37 -0
- package/src/browser/ai-configuration/base/ai-hierarchical-configuration-widget.tsx +51 -0
- package/src/browser/ai-configuration/base/ai-list-detail-configuration-widget.tsx +140 -0
- package/src/browser/ai-configuration/base/ai-table-configuration-widget.tsx +107 -0
- package/src/browser/ai-configuration/components/configuration-section.tsx +37 -0
- package/src/browser/ai-configuration/components/empty-state.tsx +30 -0
- package/src/browser/ai-configuration/components/expandable-section.tsx +51 -0
- package/src/browser/ai-configuration/language-model-renderer.tsx +68 -63
- package/src/browser/ai-configuration/mcp-configuration-widget.tsx +82 -87
- package/src/browser/ai-configuration/model-aliases-configuration-widget.tsx +93 -107
- package/src/browser/ai-configuration/prompt-fragments-configuration-widget.tsx +10 -10
- package/src/browser/ai-configuration/template-settings-renderer.tsx +25 -29
- package/src/browser/ai-configuration/token-usage-configuration-widget.tsx +131 -131
- package/src/browser/ai-configuration/tools-configuration-widget.tsx +70 -61
- package/src/browser/ai-configuration/variable-configuration-widget.tsx +95 -45
- package/src/browser/analyze-gh-ticket-command-contribution.ts +176 -0
- package/src/browser/default-chat-agent-recommendation-service.ts +43 -0
- package/src/browser/frontend-module.ts +12 -7
- package/src/browser/ide-chat-welcome-message-provider.tsx +300 -2
- package/src/browser/implement-gh-ticket-command-contribution.ts +160 -0
- package/src/browser/style/ai-configuration-base.css +90 -0
- package/src/browser/style/ai-configuration-cards.css +60 -0
- package/src/browser/style/ai-configuration-hierarchical.css +61 -0
- package/src/browser/style/ai-configuration-list-detail.css +88 -0
- package/src/browser/style/ai-configuration-table.css +73 -0
- package/src/browser/style/index.css +596 -261
- package/src/browser/style/widgets/mcp-configuration.css +253 -0
- package/src/browser/style/widgets/model-aliases-configuration.css +74 -0
|
@@ -33,7 +33,7 @@ import { PROMPT_VARIABLE } from '@theia/ai-core/lib/common/prompt-variable-contr
|
|
|
33
33
|
export class AIMCPConfigurationWidget extends ReactWidget {
|
|
34
34
|
|
|
35
35
|
static readonly ID = 'ai-mcp-configuration-container-widget';
|
|
36
|
-
static readonly LABEL = nls.
|
|
36
|
+
static readonly LABEL = nls.localizeByDefault('MCP Servers');
|
|
37
37
|
|
|
38
38
|
protected servers: MCPServerDescription[] = [];
|
|
39
39
|
protected expandedTools: Record<string, boolean> = {};
|
|
@@ -147,10 +147,44 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
protected renderServerHeader(server: MCPServerDescription): React.ReactNode {
|
|
150
|
+
const isStoppable = server.status === MCPServerStatus.Running
|
|
151
|
+
|| server.status === MCPServerStatus.Connected
|
|
152
|
+
|| server.status === MCPServerStatus.Starting
|
|
153
|
+
|| server.status === MCPServerStatus.Connecting;
|
|
154
|
+
const isStartable = server.status === MCPServerStatus.NotRunning
|
|
155
|
+
|| server.status === MCPServerStatus.NotConnected
|
|
156
|
+
|| server.status === MCPServerStatus.Errored;
|
|
157
|
+
|
|
158
|
+
const isRemote = isRemoteMCPServerDescription(server);
|
|
159
|
+
const startIcon = isRemote ? 'plug' : 'play';
|
|
160
|
+
const stopIcon = isRemote ? 'debug-disconnect' : 'close';
|
|
161
|
+
const startLabel = isRemote
|
|
162
|
+
? nls.localize('theia/ai/mcpConfiguration/connectServer', 'Connect')
|
|
163
|
+
: nls.localizeByDefault('Start Server');
|
|
164
|
+
const stopLabel = isRemote
|
|
165
|
+
? nls.localizeByDefault('Disconnect')
|
|
166
|
+
: nls.localizeByDefault('Stop Server');
|
|
167
|
+
|
|
150
168
|
return (
|
|
151
169
|
<div className="mcp-server-header">
|
|
152
170
|
<div className="mcp-server-name">{server.name}</div>
|
|
153
|
-
|
|
171
|
+
<div className="mcp-server-header-controls">
|
|
172
|
+
{this.renderStatusBadge(server)}
|
|
173
|
+
{isStartable && (
|
|
174
|
+
<button
|
|
175
|
+
className={`mcp-action-button codicon codicon-${startIcon}`}
|
|
176
|
+
onClick={() => this.handleStartServer(server.name)}
|
|
177
|
+
title={startLabel}
|
|
178
|
+
/>
|
|
179
|
+
)}
|
|
180
|
+
{isStoppable && (
|
|
181
|
+
<button
|
|
182
|
+
className={`mcp-action-button codicon codicon-${stopIcon}`}
|
|
183
|
+
onClick={() => this.handleStopServer(server.name)}
|
|
184
|
+
title={stopLabel}
|
|
185
|
+
/>
|
|
186
|
+
)}
|
|
187
|
+
</div>
|
|
154
188
|
</div>
|
|
155
189
|
);
|
|
156
190
|
}
|
|
@@ -160,9 +194,9 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
160
194
|
return;
|
|
161
195
|
}
|
|
162
196
|
return (
|
|
163
|
-
<div className="mcp-
|
|
164
|
-
<span className="mcp-
|
|
165
|
-
<code className="mcp-
|
|
197
|
+
<div className="mcp-property-row">
|
|
198
|
+
<span className="mcp-property-label">{nls.localizeByDefault('Command')}:</span>
|
|
199
|
+
<code className="mcp-property-value">{server.command}</code>
|
|
166
200
|
</div>
|
|
167
201
|
);
|
|
168
202
|
}
|
|
@@ -172,9 +206,9 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
172
206
|
return;
|
|
173
207
|
}
|
|
174
208
|
return (
|
|
175
|
-
<div className="mcp-
|
|
176
|
-
<span className="mcp-
|
|
177
|
-
<code className="mcp-
|
|
209
|
+
<div className="mcp-property-row">
|
|
210
|
+
<span className="mcp-property-label">{nls.localize('theia/ai/mcpConfiguration/arguments', 'Arguments')}:</span>
|
|
211
|
+
<code className="mcp-property-value">{server.args.join(' ')}</code>
|
|
178
212
|
</div>
|
|
179
213
|
);
|
|
180
214
|
}
|
|
@@ -184,12 +218,12 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
184
218
|
return;
|
|
185
219
|
}
|
|
186
220
|
return (
|
|
187
|
-
<div className="mcp-
|
|
188
|
-
<span className="mcp-
|
|
189
|
-
<div className="mcp-
|
|
221
|
+
<div className="mcp-property-row">
|
|
222
|
+
<span className="mcp-property-label">{nls.localize('theia/ai/mcpConfiguration/environmentVariables', 'Environment Variables')}:</span>
|
|
223
|
+
<div className="mcp-property-value">
|
|
190
224
|
{Object.entries(server.env).map(([key, value]) => (
|
|
191
|
-
<div key={key}>
|
|
192
|
-
{key}={key.toLowerCase().includes('token') ? '******' : String(value)}
|
|
225
|
+
<div key={key} className="mcp-env-entry">
|
|
226
|
+
<code>{key}={key.toLowerCase().includes('token') ? '******' : String(value)}</code>
|
|
193
227
|
</div>
|
|
194
228
|
))}
|
|
195
229
|
</div>
|
|
@@ -202,9 +236,9 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
202
236
|
return;
|
|
203
237
|
}
|
|
204
238
|
return (
|
|
205
|
-
<div className="mcp-
|
|
206
|
-
<span className="mcp-
|
|
207
|
-
<code className="mcp-
|
|
239
|
+
<div className="mcp-property-row">
|
|
240
|
+
<span className="mcp-property-label">{nls.localize('theia/ai/mcpConfiguration/serverUrl', 'Server URL')}:</span>
|
|
241
|
+
<code className="mcp-property-value">{server.serverUrl}</code>
|
|
208
242
|
</div>
|
|
209
243
|
);
|
|
210
244
|
}
|
|
@@ -214,9 +248,9 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
214
248
|
return;
|
|
215
249
|
}
|
|
216
250
|
return (
|
|
217
|
-
<div className="mcp-
|
|
218
|
-
<span className="mcp-
|
|
219
|
-
<code className="mcp-
|
|
251
|
+
<div className="mcp-property-row">
|
|
252
|
+
<span className="mcp-property-label">{nls.localize('theia/ai/mcpConfiguration/serverAuthTokenHeader', 'Auth Header Name')}:</span>
|
|
253
|
+
<code className="mcp-property-value">{server.serverAuthTokenHeader}</code>
|
|
220
254
|
</div>
|
|
221
255
|
);
|
|
222
256
|
}
|
|
@@ -226,9 +260,9 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
226
260
|
return;
|
|
227
261
|
}
|
|
228
262
|
return (
|
|
229
|
-
<div className="mcp-
|
|
230
|
-
<span className="mcp-
|
|
231
|
-
<code className="mcp-
|
|
263
|
+
<div className="mcp-property-row">
|
|
264
|
+
<span className="mcp-property-label">{nls.localize('theia/ai/mcpConfiguration/serverAuthToken', 'Auth Token')}:</span>
|
|
265
|
+
<code className="mcp-property-value">******</code>
|
|
232
266
|
</div>
|
|
233
267
|
);
|
|
234
268
|
}
|
|
@@ -238,29 +272,27 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
238
272
|
return;
|
|
239
273
|
}
|
|
240
274
|
return (
|
|
241
|
-
<div className="mcp-
|
|
242
|
-
<span className="mcp-
|
|
243
|
-
<div className="mcp-
|
|
275
|
+
<div className="mcp-property-row">
|
|
276
|
+
<span className="mcp-property-label">{nls.localize('theia/ai/mcpConfiguration/headers', 'Headers')}:</span>
|
|
277
|
+
<div className="mcp-property-value">
|
|
244
278
|
{Object.entries(server.headers).map(([key, value]) => (
|
|
245
|
-
<div key={key}>
|
|
246
|
-
{key}={(key.toLowerCase().includes('token') || key.toLowerCase().includes('authorization')) ? '******' : String(value)}
|
|
279
|
+
<div key={key} className="mcp-env-entry">
|
|
280
|
+
<code>{key}={(key.toLowerCase().includes('token') || key.toLowerCase().includes('authorization')) ? '******' : String(value)}</code>
|
|
247
281
|
</div>
|
|
248
282
|
))}
|
|
249
283
|
</div>
|
|
250
|
-
|
|
251
284
|
</div>
|
|
252
285
|
);
|
|
253
286
|
}
|
|
254
287
|
|
|
255
288
|
protected renderAutostartSection(server: MCPServerDescription): React.ReactNode {
|
|
256
289
|
return (
|
|
257
|
-
<div className="mcp-
|
|
258
|
-
<span className="mcp-
|
|
290
|
+
<div className="mcp-property-row">
|
|
291
|
+
<span className="mcp-property-label">{nls.localize('theia/ai/mcpConfiguration/autostart', 'Autostart')}:</span>
|
|
259
292
|
<span className="mcp-autostart-badge" style={{
|
|
260
|
-
backgroundColor: server.autostart ? 'var(--theia-successBackground)' : 'var(--theia-errorBackground)',
|
|
261
293
|
color: server.autostart ? 'var(--theia-successForeground)' : 'var(--theia-errorForeground)',
|
|
262
294
|
}}>
|
|
263
|
-
{server.autostart ? nls.
|
|
295
|
+
{server.autostart ? nls.localizeByDefault('Enabled') : nls.localizeByDefault('Disabled')}
|
|
264
296
|
</span>
|
|
265
297
|
</div>
|
|
266
298
|
);
|
|
@@ -273,20 +305,16 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
273
305
|
const isToolsExpanded = this.expandedTools[server.name] || false;
|
|
274
306
|
return (
|
|
275
307
|
<div className="mcp-tools-section">
|
|
276
|
-
<div
|
|
277
|
-
<div className="mcp-toggle-indicator"
|
|
278
|
-
<span
|
|
279
|
-
display: 'inline-block',
|
|
280
|
-
transition: 'transform 0.2s ease',
|
|
281
|
-
fontSize: '12px'
|
|
282
|
-
}}>
|
|
308
|
+
<div className="mcp-tools-header" onClick={() => this.toggleTools(server.name)}>
|
|
309
|
+
<div className="mcp-toggle-indicator">
|
|
310
|
+
<span className="mcp-toggle-icon">
|
|
283
311
|
{isToolsExpanded ? '▼' : '►'}
|
|
284
312
|
</span>
|
|
285
313
|
</div>
|
|
286
|
-
<div
|
|
314
|
+
<div className="mcp-tools-label-container">
|
|
287
315
|
<span className="mcp-section-label">{nls.localize('theia/ai/mcpConfiguration/tools', 'Tools: ')}</span>
|
|
288
316
|
</div>
|
|
289
|
-
<div
|
|
317
|
+
<div className="mcp-tools-actions">
|
|
290
318
|
{this.renderButton(
|
|
291
319
|
<i className="codicon codicon-versions"></i>,
|
|
292
320
|
nls.localize('theia/ai/mcpConfiguration/copyAllList', 'Copy all (list of all tools)'),
|
|
@@ -327,11 +355,11 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
327
355
|
{isToolsExpanded && (
|
|
328
356
|
<div className="mcp-tools-list">
|
|
329
357
|
{server.tools.map(tool => (
|
|
330
|
-
<div key={tool.name}
|
|
331
|
-
<div
|
|
358
|
+
<div key={tool.name} className="mcp-tool-item">
|
|
359
|
+
<div className="mcp-tool-content">
|
|
332
360
|
<strong>{tool.name}:</strong> {tool.description}
|
|
333
361
|
</div>
|
|
334
|
-
<div
|
|
362
|
+
<div className="mcp-tool-actions">
|
|
335
363
|
{this.renderButton(
|
|
336
364
|
<i className="codicon codicon-copy"></i>,
|
|
337
365
|
nls.localize('theia/ai/mcpConfiguration/copyForPrompt', 'Copy tool (for chat or prompt template)'),
|
|
@@ -357,53 +385,21 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
357
385
|
this.update();
|
|
358
386
|
}
|
|
359
387
|
|
|
360
|
-
protected renderServerControls(server: MCPServerDescription): React.ReactNode {
|
|
361
|
-
const isStoppable = server.status === MCPServerStatus.Running
|
|
362
|
-
|| server.status === MCPServerStatus.Connected
|
|
363
|
-
|| server.status === MCPServerStatus.Starting
|
|
364
|
-
|| server.status === MCPServerStatus.Connecting;
|
|
365
|
-
const isStartable = server.status === MCPServerStatus.NotRunning
|
|
366
|
-
|| server.status === MCPServerStatus.NotConnected
|
|
367
|
-
|| server.status === MCPServerStatus.Errored;
|
|
368
|
-
|
|
369
|
-
const startLabel = isRemoteMCPServerDescription(server)
|
|
370
|
-
? nls.localize('theia/ai/mcpConfiguration/connectServer', 'Connnect')
|
|
371
|
-
: nls.localize('theia/ai/mcpConfiguration/startServer', 'Start Server');
|
|
372
|
-
const stopLabel = isRemoteMCPServerDescription(server)
|
|
373
|
-
? nls.localize('theia/ai/mcpConfiguration/disconnectServer', 'Disconnnect')
|
|
374
|
-
: nls.localize('theia/ai/mcpConfiguration/stopServer', 'Stop Server');
|
|
375
|
-
return (
|
|
376
|
-
<div className="mcp-server-controls">
|
|
377
|
-
{isStartable && this.renderButton(
|
|
378
|
-
<><i className="codicon codicon-play"></i> {startLabel}</>,
|
|
379
|
-
startLabel,
|
|
380
|
-
() => this.handleStartServer(server.name),
|
|
381
|
-
'mcp-server-button play-button'
|
|
382
|
-
)}
|
|
383
|
-
{isStoppable && this.renderButton(
|
|
384
|
-
<><i className="codicon codicon-close"></i> {stopLabel}</>,
|
|
385
|
-
stopLabel,
|
|
386
|
-
() => this.handleStopServer(server.name),
|
|
387
|
-
'mcp-server-button stop-button'
|
|
388
|
-
)}
|
|
389
|
-
</div>
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
388
|
protected renderServerCard(server: MCPServerDescription): React.ReactNode {
|
|
394
389
|
return (
|
|
395
390
|
<div key={server.name} className="mcp-server-card">
|
|
396
391
|
{this.renderServerHeader(server)}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
392
|
+
<div className="mcp-server-content">
|
|
393
|
+
{this.renderCommandSection(server)}
|
|
394
|
+
{this.renderArgumentsSection(server)}
|
|
395
|
+
{this.renderEnvironmentSection(server)}
|
|
396
|
+
{this.renderServerUrlSection(server)}
|
|
397
|
+
{this.renderServerAuthTokenHeaderSection(server)}
|
|
398
|
+
{this.renderServerAuthTokenSection(server)}
|
|
399
|
+
{this.renderServerHeadersSection(server)}
|
|
400
|
+
{this.renderAutostartSection(server)}
|
|
401
|
+
</div>
|
|
405
402
|
{this.renderToolsSection(server)}
|
|
406
|
-
{this.renderServerControls(server)}
|
|
407
403
|
</div>
|
|
408
404
|
);
|
|
409
405
|
}
|
|
@@ -419,7 +415,6 @@ export class AIMCPConfigurationWidget extends ReactWidget {
|
|
|
419
415
|
|
|
420
416
|
return (
|
|
421
417
|
<div className="mcp-configuration-container">
|
|
422
|
-
<h2 className="mcp-configuration-title">{nls.localize('theia/ai/mcpConfiguration/serverConfigurations', 'MCP Server Configurations')}</h2>
|
|
423
418
|
{this.servers.map(server => this.renderServerCard(server))}
|
|
424
419
|
</div>
|
|
425
420
|
);
|
|
@@ -15,20 +15,15 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
import * as React from '@theia/core/shared/react';
|
|
17
17
|
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
18
|
-
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
|
19
18
|
import { LanguageModelAliasRegistry, LanguageModelAlias } from '@theia/ai-core/lib/common/language-model-alias';
|
|
20
19
|
import { FrontendLanguageModelRegistry, LanguageModel, LanguageModelRegistry, LanguageModelRequirement } from '@theia/ai-core/lib/common/language-model';
|
|
21
20
|
import { nls } from '@theia/core/lib/common/nls';
|
|
22
|
-
import { AIConfigurationSelectionService } from './ai-configuration-service';
|
|
23
21
|
import { AgentService, AISettingsService } from '@theia/ai-core';
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
languageModelAliasRegistry: LanguageModelAliasRegistry;
|
|
27
|
-
languageModelRegistry: LanguageModelRegistry;
|
|
28
|
-
}
|
|
22
|
+
import { AIListDetailConfigurationWidget } from './base/ai-list-detail-configuration-widget';
|
|
23
|
+
import { ConfigurationSection } from './components/configuration-section';
|
|
29
24
|
|
|
30
25
|
@injectable()
|
|
31
|
-
export class ModelAliasesConfigurationWidget extends
|
|
26
|
+
export class ModelAliasesConfigurationWidget extends AIListDetailConfigurationWidget<LanguageModelAlias> {
|
|
32
27
|
static readonly ID = 'ai-model-aliases-configuration-widget';
|
|
33
28
|
static readonly LABEL = nls.localize('theia/ai/core/modelAliasesConfiguration/label', 'Model Aliases');
|
|
34
29
|
|
|
@@ -36,22 +31,13 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
36
31
|
protected readonly languageModelAliasRegistry: LanguageModelAliasRegistry;
|
|
37
32
|
@inject(LanguageModelRegistry)
|
|
38
33
|
protected readonly languageModelRegistry: FrontendLanguageModelRegistry;
|
|
39
|
-
@inject(AIConfigurationSelectionService)
|
|
40
|
-
protected readonly aiConfigurationSelectionService: AIConfigurationSelectionService;
|
|
41
34
|
@inject(AISettingsService)
|
|
42
35
|
protected readonly aiSettingsService: AISettingsService;
|
|
43
36
|
@inject(AgentService)
|
|
44
37
|
protected readonly agentService: AgentService;
|
|
45
38
|
|
|
46
|
-
protected aliases: LanguageModelAlias[] = [];
|
|
47
39
|
protected languageModels: LanguageModel[] = [];
|
|
48
|
-
/**
|
|
49
|
-
* Map from alias ID to a list of agent IDs that have a language model requirement for that alias.
|
|
50
|
-
*/
|
|
51
40
|
protected matchingAgentIdsForAliasMap: Map<string, string[]> = new Map();
|
|
52
|
-
/**
|
|
53
|
-
* Map from alias ID to the resolved LanguageModel (what the alias currently evaluates to).
|
|
54
|
-
*/
|
|
55
41
|
protected resolvedModelForAlias: Map<string, LanguageModel | undefined> = new Map();
|
|
56
42
|
|
|
57
43
|
@postConstruct()
|
|
@@ -60,43 +46,45 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
60
46
|
this.title.label = ModelAliasesConfigurationWidget.LABEL;
|
|
61
47
|
this.title.closable = false;
|
|
62
48
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
Promise.all([
|
|
50
|
+
this.loadItems(),
|
|
51
|
+
this.loadLanguageModels()
|
|
52
|
+
]).then(() => this.update());
|
|
67
53
|
|
|
68
54
|
this.languageModelAliasRegistry.ready.then(() =>
|
|
69
55
|
this.toDispose.push(this.languageModelAliasRegistry.onDidChange(async () => {
|
|
70
|
-
await this.
|
|
56
|
+
await this.loadItems();
|
|
71
57
|
this.update();
|
|
72
58
|
}))
|
|
73
59
|
);
|
|
74
60
|
|
|
75
61
|
this.toDispose.pushAll([
|
|
76
62
|
this.languageModelRegistry.onChange(async () => {
|
|
77
|
-
await this.
|
|
63
|
+
await this.loadItems();
|
|
78
64
|
await this.loadLanguageModels();
|
|
79
65
|
this.update();
|
|
80
66
|
}),
|
|
81
67
|
this.aiSettingsService.onDidChange(async () => {
|
|
82
68
|
await this.loadMatchingAgentIdsForAllAliases();
|
|
83
69
|
this.update();
|
|
84
|
-
})
|
|
85
|
-
this.aiConfigurationSelectionService.onDidAliasChange(() => this.update())
|
|
70
|
+
})
|
|
86
71
|
]);
|
|
87
72
|
}
|
|
88
73
|
|
|
89
|
-
protected async
|
|
74
|
+
protected override async loadItems(): Promise<void> {
|
|
90
75
|
await this.languageModelAliasRegistry.ready;
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
76
|
+
this.items = this.languageModelAliasRegistry.getAliases();
|
|
77
|
+
|
|
78
|
+
// Set initial selection
|
|
79
|
+
if (this.items.length > 0 && !this.selectedItem) {
|
|
80
|
+
this.selectedItem = this.items[0];
|
|
95
81
|
}
|
|
82
|
+
|
|
96
83
|
await this.loadMatchingAgentIdsForAllAliases();
|
|
84
|
+
|
|
97
85
|
// Resolve evaluated models for each alias
|
|
98
86
|
this.resolvedModelForAlias = new Map();
|
|
99
|
-
for (const alias of this.
|
|
87
|
+
for (const alias of this.items) {
|
|
100
88
|
const model = await this.languageModelRegistry.getReadyLanguageModel(alias.id);
|
|
101
89
|
this.resolvedModelForAlias.set(alias.id, model);
|
|
102
90
|
}
|
|
@@ -106,23 +94,18 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
106
94
|
this.languageModels = await this.languageModelRegistry.getLanguageModels();
|
|
107
95
|
}
|
|
108
96
|
|
|
109
|
-
/**
|
|
110
|
-
* Loads a map from alias ID to a list of agent IDs that have a language model requirement for that alias.
|
|
111
|
-
*/
|
|
112
97
|
protected async loadMatchingAgentIdsForAllAliases(): Promise<void> {
|
|
113
98
|
const agents = this.agentService.getAllAgents();
|
|
114
99
|
const aliasMap: Map<string, string[]> = new Map();
|
|
115
|
-
for (const alias of this.
|
|
100
|
+
for (const alias of this.items) {
|
|
116
101
|
const matchingAgentIds: string[] = [];
|
|
117
102
|
for (const agent of agents) {
|
|
118
103
|
const requirementSetting = await this.aiSettingsService.getAgentSettings(agent.id);
|
|
119
104
|
if (requirementSetting?.languageModelRequirements) {
|
|
120
|
-
// requirement is set via settings, check if it is this alias
|
|
121
105
|
if (requirementSetting?.languageModelRequirements?.find(e => e.identifier === alias.id)) {
|
|
122
106
|
matchingAgentIds.push(agent.id);
|
|
123
107
|
}
|
|
124
108
|
} else {
|
|
125
|
-
// requirement is NOT set via settings, check if this alias is the default for this agent
|
|
126
109
|
if (agent.languageModelRequirements.some((req: LanguageModelRequirement) => req.identifier === alias.id)) {
|
|
127
110
|
matchingAgentIds.push(agent.id);
|
|
128
111
|
}
|
|
@@ -133,6 +116,18 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
133
116
|
this.matchingAgentIdsForAliasMap = aliasMap;
|
|
134
117
|
}
|
|
135
118
|
|
|
119
|
+
protected override getItemId(item: LanguageModelAlias): string {
|
|
120
|
+
return item.id;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
protected override getItemLabel(item: LanguageModelAlias): string {
|
|
124
|
+
return item.id;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
protected override getEmptySelectionMessage(): string {
|
|
128
|
+
return nls.localize('theia/ai/core/modelAliasesConfiguration/selectAlias', 'Please select a Model Alias.');
|
|
129
|
+
}
|
|
130
|
+
|
|
136
131
|
protected handleAliasSelectedModelIdChange = (alias: LanguageModelAlias, event: React.ChangeEvent<HTMLSelectElement>): void => {
|
|
137
132
|
const newModelId = event.target.value || undefined;
|
|
138
133
|
const updatedAlias: LanguageModelAlias = {
|
|
@@ -144,50 +139,28 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
144
139
|
});
|
|
145
140
|
};
|
|
146
141
|
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
const selectedAlias = this.aliases.find(alias => alias.id === selectedAliasId);
|
|
150
|
-
return (
|
|
151
|
-
<div className="model-alias-configuration-main">
|
|
152
|
-
<div className="model-alias-configuration-list preferences-tree-widget theia-TreeContainer ai-model-alias-list">
|
|
153
|
-
<ul>
|
|
154
|
-
{this.aliases.map(alias => (
|
|
155
|
-
<li
|
|
156
|
-
key={alias.id}
|
|
157
|
-
className={`theia-TreeNode theia-CompositeTreeNode${alias.id === selectedAliasId ? ' theia-mod-selected' : ''}`}
|
|
158
|
-
onClick={() => this.aiConfigurationSelectionService.setSelectedAliasId(alias.id)}
|
|
159
|
-
>
|
|
160
|
-
<span>{alias.id}</span>
|
|
161
|
-
</li>
|
|
162
|
-
))}
|
|
163
|
-
</ul>
|
|
164
|
-
</div>
|
|
165
|
-
<div className="model-alias-configuration-panel preferences-editor-widget">
|
|
166
|
-
{selectedAlias ? this.renderAliasDetail(selectedAlias, this.languageModels) : (
|
|
167
|
-
<div>
|
|
168
|
-
{nls.localize('theia/ai/core/modelAliasesConfiguration/selectAlias', 'Please select a Model Alias.')}
|
|
169
|
-
</div>
|
|
170
|
-
)}
|
|
171
|
-
</div>
|
|
172
|
-
</div>
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
protected renderAliasDetail(alias: LanguageModelAlias, languageModels: LanguageModel[]): React.ReactNode {
|
|
177
|
-
const availableModelIds = languageModels.map(m => m.id);
|
|
142
|
+
protected override renderItemDetail(alias: LanguageModelAlias): React.ReactNode {
|
|
143
|
+
const availableModelIds = this.languageModels.map(m => m.id);
|
|
178
144
|
const selectedModelId = alias.selectedModelId ?? '';
|
|
179
145
|
const isInvalidModel = !!selectedModelId && !availableModelIds.includes(alias.selectedModelId ?? '');
|
|
180
146
|
const agentIds = this.matchingAgentIdsForAliasMap.get(alias.id) || [];
|
|
181
147
|
const agents = this.agentService.getAllAgents().filter(agent => agentIds.includes(agent.id));
|
|
182
148
|
const resolvedModel = this.resolvedModelForAlias.get(alias.id);
|
|
149
|
+
|
|
183
150
|
return (
|
|
184
151
|
<div>
|
|
185
|
-
<div className="settings-section-title settings-section-category-title
|
|
186
|
-
|
|
152
|
+
<div className="settings-section-title settings-section-category-title">
|
|
153
|
+
{alias.id}
|
|
187
154
|
</div>
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
<
|
|
155
|
+
|
|
156
|
+
{alias.description && (
|
|
157
|
+
<div className="ai-alias-detail-description">{alias.description}</div>
|
|
158
|
+
)}
|
|
159
|
+
|
|
160
|
+
<ConfigurationSection
|
|
161
|
+
title={nls.localize('theia/ai/core/modelAliasesConfiguration/selectedModelId', 'Selected Model')}
|
|
162
|
+
className="ai-alias-selected-model-section"
|
|
163
|
+
>
|
|
191
164
|
<select
|
|
192
165
|
className={`theia-select template-variant-selector ${isInvalidModel ? 'error' : ''}`}
|
|
193
166
|
value={isInvalidModel ? 'invalid' : selectedModelId}
|
|
@@ -201,7 +174,7 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
201
174
|
<option value="" className='ai-language-model-item-ready'>
|
|
202
175
|
{nls.localize('theia/ai/core/modelAliasesConfiguration/defaultList', '[Default list]')}
|
|
203
176
|
</option>
|
|
204
|
-
{[...languageModels]
|
|
177
|
+
{[...this.languageModels]
|
|
205
178
|
.sort((a, b) => (a.name ?? a.id).localeCompare(b.name ?? b.id))
|
|
206
179
|
.map(model => {
|
|
207
180
|
const isNotReady = model.status.status !== 'ready';
|
|
@@ -218,32 +191,41 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
218
191
|
}
|
|
219
192
|
)}
|
|
220
193
|
</select>
|
|
221
|
-
</
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
194
|
+
</ConfigurationSection>
|
|
195
|
+
|
|
196
|
+
{alias.selectedModelId === undefined && (
|
|
197
|
+
<>
|
|
198
|
+
<ConfigurationSection
|
|
199
|
+
title={nls.localize('theia/ai/core/modelAliasesConfiguration/priorityList', 'Priority List')}
|
|
200
|
+
className="ai-alias-defaults-section"
|
|
201
|
+
>
|
|
202
|
+
<ol>
|
|
203
|
+
{alias.defaultModelIds.map(modelId => {
|
|
204
|
+
const model = this.languageModels.find(m => m.id === modelId);
|
|
205
|
+
const isReady = model?.status.status === 'ready';
|
|
206
|
+
return (
|
|
207
|
+
<li key={modelId}>
|
|
208
|
+
{isReady ? (
|
|
209
|
+
<span className={modelId === resolvedModel?.id ? 'ai-alias-priority-item-resolved' : 'ai-alias-priority-item-ready'}>
|
|
210
|
+
{modelId} <span className="ai-model-status-ready"
|
|
211
|
+
title={nls.localize('theia/ai/core/modelAliasesConfiguration/modelReadyTooltip', 'Ready')}>✓</span>
|
|
212
|
+
</span>
|
|
213
|
+
) : (
|
|
214
|
+
<span className="ai-model-default-not-ready">
|
|
215
|
+
{modelId} <span className="ai-model-status-not-ready"
|
|
216
|
+
title={nls.localize('theia/ai/core/modelAliasesConfiguration/modelNotReadyTooltip', 'Not ready')}>✗</span>
|
|
217
|
+
</span>
|
|
218
|
+
)}
|
|
219
|
+
</li>
|
|
220
|
+
);
|
|
221
|
+
})}
|
|
222
|
+
</ol>
|
|
223
|
+
</ConfigurationSection>
|
|
224
|
+
|
|
225
|
+
<ConfigurationSection
|
|
226
|
+
title={nls.localize('theia/ai/core/modelAliasesConfiguration/evaluatesTo', 'Evaluates to')}
|
|
227
|
+
className="ai-alias-evaluates-to-section"
|
|
228
|
+
>
|
|
247
229
|
{resolvedModel ? (
|
|
248
230
|
<span className="ai-alias-evaluates-to-value">
|
|
249
231
|
{resolvedModel.name ?? resolvedModel.id}
|
|
@@ -260,24 +242,28 @@ export class ModelAliasesConfigurationWidget extends ReactWidget {
|
|
|
260
242
|
{nls.localize('theia/ai/core/modelAliasesConfiguration/noResolvedModel', 'No model ready for this alias.')}
|
|
261
243
|
</span>
|
|
262
244
|
)}
|
|
263
|
-
</
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
245
|
+
</ConfigurationSection>
|
|
246
|
+
</>
|
|
247
|
+
)}
|
|
248
|
+
|
|
249
|
+
<ConfigurationSection
|
|
250
|
+
title={nls.localize('theia/ai/core/modelAliasesConfiguration/agents', 'Agents using this Alias')}
|
|
251
|
+
className="ai-alias-agents-section"
|
|
252
|
+
>
|
|
267
253
|
<ul>
|
|
268
254
|
{agents.length > 0 ? (
|
|
269
255
|
agents.map(agent => (
|
|
270
256
|
<li key={agent.id}>
|
|
271
257
|
<span>{agent.name}</span>
|
|
272
|
-
{agent.id !== agent.name && <span className="ai-alias-agent-id">({agent.id})</span>}
|
|
258
|
+
{agent.id !== agent.name && <span className="ai-alias-agent-id"> ({agent.id})</span>}
|
|
273
259
|
</li>
|
|
274
260
|
))
|
|
275
261
|
) : (
|
|
276
262
|
<span>{nls.localize('theia/ai/core/modelAliasesConfiguration/noAgents', 'No agents use this alias.')}</span>
|
|
277
263
|
)}
|
|
278
264
|
</ul>
|
|
279
|
-
</
|
|
280
|
-
</div
|
|
265
|
+
</ConfigurationSection>
|
|
266
|
+
</div>
|
|
281
267
|
);
|
|
282
268
|
}
|
|
283
269
|
}
|