@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
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
PromptFragmentCustomizationService,
|
|
28
28
|
PromptService,
|
|
29
29
|
} from '@theia/ai-core/lib/common';
|
|
30
|
-
import { codicon, QuickInputService
|
|
30
|
+
import { codicon, QuickInputService } from '@theia/core/lib/browser';
|
|
31
31
|
import { URI } from '@theia/core/lib/common';
|
|
32
32
|
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
33
33
|
import * as React from '@theia/core/shared/react';
|
|
@@ -37,6 +37,7 @@ import { LanguageModelAliasRegistry, LanguageModelAlias } from '@theia/ai-core/l
|
|
|
37
37
|
import { AIVariableConfigurationWidget } from './variable-configuration-widget';
|
|
38
38
|
import { nls } from '@theia/core';
|
|
39
39
|
import { PromptVariantRenderer } from './template-settings-renderer';
|
|
40
|
+
import { AIListDetailConfigurationWidget } from './base/ai-list-detail-configuration-widget';
|
|
40
41
|
|
|
41
42
|
interface ParsedPrompt {
|
|
42
43
|
functions: string[];
|
|
@@ -45,7 +46,7 @@ interface ParsedPrompt {
|
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
@injectable()
|
|
48
|
-
export class AIAgentConfigurationWidget extends
|
|
49
|
+
export class AIAgentConfigurationWidget extends AIListDetailConfigurationWidget<Agent> {
|
|
49
50
|
|
|
50
51
|
static readonly ID = 'ai-agent-configuration-container-widget';
|
|
51
52
|
static readonly LABEL = nls.localize('theia/ai/core/agentConfiguration/label', 'Agents');
|
|
@@ -88,10 +89,13 @@ export class AIAgentConfigurationWidget extends ReactWidget {
|
|
|
88
89
|
this.title.label = AIAgentConfigurationWidget.LABEL;
|
|
89
90
|
this.title.closable = false;
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
94
|
-
|
|
92
|
+
Promise.all([
|
|
93
|
+
this.loadItems(),
|
|
94
|
+
this.languageModelRegistry.getLanguageModels().then(models => {
|
|
95
|
+
this.languageModels = models ?? [];
|
|
96
|
+
})
|
|
97
|
+
]).then(() => this.update());
|
|
98
|
+
|
|
95
99
|
this.languageModelAliasRegistry.ready.then(() => {
|
|
96
100
|
this.languageModelAliases = this.languageModelAliasRegistry.getAliases();
|
|
97
101
|
this.toDispose.push(this.languageModelAliasRegistry.onDidChange(() => {
|
|
@@ -99,132 +103,192 @@ export class AIAgentConfigurationWidget extends ReactWidget {
|
|
|
99
103
|
this.update();
|
|
100
104
|
}));
|
|
101
105
|
});
|
|
102
|
-
this.toDispose.push(this.languageModelRegistry.onChange(({ models }) => {
|
|
103
|
-
this.languageModelAliases = this.languageModelAliasRegistry.getAliases();
|
|
104
|
-
this.languageModels = models;
|
|
105
|
-
this.update();
|
|
106
|
-
}));
|
|
107
|
-
this.toDispose.push(this.promptService.onPromptsChange(() => this.updateParsedPromptParts()));
|
|
108
106
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
this.toDispose.pushAll([
|
|
108
|
+
this.languageModelRegistry.onChange(({ models }) => {
|
|
109
|
+
this.languageModelAliases = this.languageModelAliasRegistry.getAliases();
|
|
110
|
+
this.languageModels = models;
|
|
111
|
+
this.update();
|
|
112
|
+
}),
|
|
113
|
+
this.promptService.onPromptsChange(() => this.updateParsedPromptParts()),
|
|
114
|
+
this.promptFragmentCustomizationService.onDidChangePromptFragmentCustomization(() => {
|
|
115
|
+
this.updateParsedPromptParts();
|
|
116
|
+
}),
|
|
117
|
+
this.aiSettingsService.onDidChange(() => {
|
|
118
|
+
this.updateParsedPromptParts();
|
|
119
|
+
}),
|
|
120
|
+
this.aiConfigurationSelectionService.onDidAgentChange(() => {
|
|
121
|
+
this.selectedItem = this.aiConfigurationSelectionService.getActiveAgent();
|
|
122
|
+
this.updateParsedPromptParts();
|
|
123
|
+
}),
|
|
124
|
+
this.agentService.onDidChangeAgents(async () => {
|
|
125
|
+
await this.loadItems();
|
|
126
|
+
this.update();
|
|
127
|
+
})
|
|
128
|
+
]);
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.updateParsedPromptParts();
|
|
117
|
-
}));
|
|
130
|
+
this.updateParsedPromptParts();
|
|
131
|
+
}
|
|
118
132
|
|
|
119
|
-
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
protected async loadItems(): Promise<void> {
|
|
134
|
+
this.items = this.agentService.getAllAgents();
|
|
135
|
+
const activeAgent = this.aiConfigurationSelectionService.getActiveAgent();
|
|
136
|
+
if (activeAgent) {
|
|
137
|
+
this.selectedItem = activeAgent;
|
|
138
|
+
} else if (this.items.length > 0 && !this.selectedItem) {
|
|
139
|
+
this.selectedItem = this.items[0];
|
|
140
|
+
this.aiConfigurationSelectionService.setActiveAgent(this.items[0]);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
protected getItemId(agent: Agent): string {
|
|
145
|
+
return agent.id;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
protected getItemLabel(agent: Agent): string {
|
|
149
|
+
return agent.name;
|
|
150
|
+
}
|
|
123
151
|
|
|
124
|
-
|
|
152
|
+
protected override getEmptySelectionMessage(): string {
|
|
153
|
+
return nls.localize('theia/ai/core/agentConfiguration/selectAgentMessage', 'Please select an Agent first!');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
protected override handleItemSelect = (agent: Agent): void => {
|
|
157
|
+
this.selectedItem = agent;
|
|
158
|
+
this.aiConfigurationSelectionService.setActiveAgent(agent);
|
|
125
159
|
this.updateParsedPromptParts();
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
protected override renderItemPrefix(agent: Agent): React.ReactNode {
|
|
163
|
+
const enabled = this.agentService.isEnabled(agent.id);
|
|
164
|
+
return (
|
|
165
|
+
<span
|
|
166
|
+
className={
|
|
167
|
+
`agent-status-indicator ${enabled ? `agent-enabled ${codicon('circle-filled')}` : `agent-disabled ${codicon('circle')}`}`
|
|
168
|
+
}
|
|
169
|
+
title={enabled ? 'Enabled' : 'Disabled'}
|
|
170
|
+
>
|
|
171
|
+
</span>
|
|
172
|
+
);
|
|
126
173
|
}
|
|
127
174
|
|
|
128
|
-
protected
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (agent) {
|
|
132
|
-
this.parsedPromptParts = await this.parsePromptFragmentsForVariableAndFunction(agent);
|
|
133
|
-
} else {
|
|
134
|
-
this.parsedPromptParts = undefined;
|
|
175
|
+
protected override renderItemSuffix(agent: Agent): React.ReactNode {
|
|
176
|
+
if (!agent.tags?.length) {
|
|
177
|
+
return undefined;
|
|
135
178
|
}
|
|
136
|
-
|
|
137
|
-
this.update();
|
|
179
|
+
return <span>{agent.tags.map(tag => <span key={tag} className='agent-tag'>{tag}</span>)}</span>;
|
|
138
180
|
}
|
|
139
181
|
|
|
140
|
-
protected
|
|
141
|
-
return
|
|
142
|
-
<div className=
|
|
182
|
+
protected override renderList(): React.ReactNode {
|
|
183
|
+
return (
|
|
184
|
+
<div className="ai-configuration-list preferences-tree-widget theia-TreeContainer">
|
|
143
185
|
<ul>
|
|
144
|
-
{this.
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
return
|
|
148
|
-
|
|
149
|
-
|
|
186
|
+
{this.items.map(agent => {
|
|
187
|
+
const agentId = this.getItemId(agent);
|
|
188
|
+
const isSelected = this.selectedItem && this.getItemId(this.selectedItem) === agentId;
|
|
189
|
+
return (
|
|
190
|
+
<li
|
|
191
|
+
key={agentId}
|
|
192
|
+
className={`theia-TreeNode theia-CompositeTreeNode${isSelected ? ' theia-mod-selected' : ''} ${this.getItemClassName(agent)}`}
|
|
193
|
+
onClick={() => this.handleItemSelect(agent)}
|
|
194
|
+
>
|
|
195
|
+
{this.renderItemPrefix(agent)}
|
|
196
|
+
<span className="ai-configuration-list-item-label">{this.getItemLabel(agent)}</span>
|
|
197
|
+
{this.renderItemSuffix(agent)}
|
|
198
|
+
</li>
|
|
199
|
+
);
|
|
150
200
|
})}
|
|
151
201
|
</ul>
|
|
152
202
|
<div className='configuration-agents-add'>
|
|
153
203
|
<button
|
|
154
|
-
style={{ marginLeft: 0 }}
|
|
155
204
|
className='theia-button main'
|
|
156
205
|
onClick={() => this.addCustomAgent()}>
|
|
157
206
|
{nls.localize('theia/ai/core/agentConfiguration/addCustomAgent', 'Add Custom Agent')}
|
|
158
207
|
</button>
|
|
159
208
|
</div>
|
|
160
209
|
</div>
|
|
161
|
-
|
|
162
|
-
{this.renderAgentDetails()}
|
|
163
|
-
</div>
|
|
164
|
-
</div>;
|
|
210
|
+
);
|
|
165
211
|
}
|
|
166
212
|
|
|
167
|
-
protected
|
|
168
|
-
|
|
169
|
-
|
|
213
|
+
protected async updateParsedPromptParts(): Promise<void> {
|
|
214
|
+
this.isLoadingDetails = true;
|
|
215
|
+
const agent = this.aiConfigurationSelectionService.getActiveAgent();
|
|
216
|
+
if (agent) {
|
|
217
|
+
this.parsedPromptParts = await this.parsePromptFragmentsForVariableAndFunction(agent);
|
|
218
|
+
} else {
|
|
219
|
+
this.parsedPromptParts = undefined;
|
|
220
|
+
}
|
|
221
|
+
this.isLoadingDetails = false;
|
|
222
|
+
this.update();
|
|
170
223
|
}
|
|
171
224
|
|
|
172
|
-
protected
|
|
225
|
+
protected renderItemDetail(agent: Agent): React.ReactNode {
|
|
173
226
|
if (this.isLoadingDetails) {
|
|
174
|
-
return <div>{nls.
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const agent = this.aiConfigurationSelectionService.getActiveAgent();
|
|
178
|
-
if (!agent) {
|
|
179
|
-
return <div>{nls.localize('theia/ai/core/agentConfiguration/selectAgentMessage', 'Please select an Agent first!')}</div>;
|
|
227
|
+
return <div>{nls.localizeByDefault('Loading...')}</div>;
|
|
180
228
|
}
|
|
181
229
|
|
|
182
230
|
const enabled = this.agentService.isEnabled(agent.id);
|
|
183
231
|
|
|
184
232
|
if (!this.parsedPromptParts) {
|
|
185
233
|
this.updateParsedPromptParts();
|
|
186
|
-
return <div>{nls.
|
|
234
|
+
return <div>{nls.localizeByDefault('Loading...')}</div>;
|
|
187
235
|
}
|
|
188
236
|
|
|
189
237
|
const globalVariables = Array.from(new Set([...this.parsedPromptParts.globalVariables, ...agent.variables]));
|
|
190
238
|
const functions = Array.from(new Set([...this.parsedPromptParts.functions, ...agent.functions]));
|
|
191
239
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
240
|
+
const agentNameWithTags = <>
|
|
241
|
+
{agent.name}
|
|
242
|
+
{agent.tags?.length && <span>{agent.tags.map(tag => <span key={tag} className='agent-tag'>{tag}</span>)}</span>}
|
|
243
|
+
</>;
|
|
244
|
+
|
|
245
|
+
return <div key={agent.id}>
|
|
246
|
+
<div className='settings-section-title settings-section-category-title agent-title-with-toggle'>
|
|
247
|
+
<div className='agent-title-content'>
|
|
248
|
+
<div>
|
|
249
|
+
{agentNameWithTags}
|
|
250
|
+
<pre className='ai-id-label'>Id: {agent.id}</pre>
|
|
251
|
+
</div>
|
|
252
|
+
<label className='agent-enable-toggle' title={nls.localize('theia/ai/core/agentConfiguration/enableAgent', 'Enable Agent')}>
|
|
253
|
+
<div className='toggle-switch' onClick={this.toggleAgentEnabled}>
|
|
254
|
+
<input type="checkbox" checked={enabled} onChange={this.toggleAgentEnabled} />
|
|
255
|
+
<span className='toggle-slider'></span>
|
|
256
|
+
</div>
|
|
257
|
+
</label>
|
|
258
|
+
</div>
|
|
208
259
|
</div>
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
260
|
+
|
|
261
|
+
{agent.description && (
|
|
262
|
+
<div className="ai-agent-description">
|
|
263
|
+
{agent.description}
|
|
264
|
+
</div>
|
|
265
|
+
)}
|
|
266
|
+
{agent.prompts.length > 0 && (
|
|
267
|
+
<>
|
|
268
|
+
<div className="settings-section-subcategory-title ai-settings-section-subcategory-title">
|
|
269
|
+
{nls.localize('theia/ai/core/agentConfiguration/promptTemplates', 'Prompt Templates')}
|
|
270
|
+
</div>
|
|
271
|
+
<table className="ai-templates-table">
|
|
272
|
+
<thead>
|
|
273
|
+
<tr>
|
|
274
|
+
<th>{nls.localize('theia/ai/core/agentConfiguration/templateName', 'Template')}</th>
|
|
275
|
+
<th>{nls.localize('theia/ai/core/agentConfiguration/variant', 'Variant')}</th>
|
|
276
|
+
<th className="template-actions-header">{nls.localize('theia/ai/core/agentConfiguration/actions', 'Actions')}</th>
|
|
277
|
+
</tr>
|
|
278
|
+
</thead>
|
|
279
|
+
<tbody>
|
|
280
|
+
{agent.prompts.map(prompt => (
|
|
215
281
|
<PromptVariantRenderer
|
|
216
282
|
key={agent.id + '.' + prompt.id}
|
|
217
283
|
agentId={agent.id}
|
|
218
284
|
promptVariantSet={prompt}
|
|
219
285
|
promptService={this.promptService}
|
|
220
286
|
/>
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
})()}
|
|
227
|
-
</div>
|
|
287
|
+
))}
|
|
288
|
+
</tbody>
|
|
289
|
+
</table>
|
|
290
|
+
</>
|
|
291
|
+
)}
|
|
228
292
|
|
|
229
293
|
<div className='ai-lm-requirements'>
|
|
230
294
|
<LanguageModelRenderer
|
|
@@ -235,27 +299,43 @@ export class AIAgentConfigurationWidget extends ReactWidget {
|
|
|
235
299
|
languageModelAliases={this.languageModelAliases}
|
|
236
300
|
/>
|
|
237
301
|
</div>
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
<
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
<AgentSpecificVariables
|
|
248
|
-
promptVariables={this.parsedPromptParts.agentSpecificVariables}
|
|
249
|
-
agent={agent}
|
|
302
|
+
|
|
303
|
+
{globalVariables.length > 0 && (
|
|
304
|
+
<>
|
|
305
|
+
<div className="settings-section-subcategory-title">
|
|
306
|
+
{nls.localize('theia/ai/core/agentConfiguration/usedGlobalVariables', 'Used Global Variables')}
|
|
307
|
+
</div>
|
|
308
|
+
<AgentGlobalVariables
|
|
309
|
+
variables={globalVariables}
|
|
310
|
+
variableService={this.variableService}
|
|
250
311
|
/>
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
<
|
|
257
|
-
|
|
258
|
-
|
|
312
|
+
</>
|
|
313
|
+
)}
|
|
314
|
+
|
|
315
|
+
{this.parsedPromptParts.agentSpecificVariables.length > 0 && (
|
|
316
|
+
<>
|
|
317
|
+
<div className="settings-section-subcategory-title">
|
|
318
|
+
{nls.localize('theia/ai/core/agentConfiguration/usedAgentSpecificVariables', 'Used Agent-Specific Variables')}
|
|
319
|
+
</div>
|
|
320
|
+
<ul className='variable-references'>
|
|
321
|
+
<AgentSpecificVariables
|
|
322
|
+
promptVariables={this.parsedPromptParts.agentSpecificVariables}
|
|
323
|
+
agent={agent}
|
|
324
|
+
/>
|
|
325
|
+
</ul>
|
|
326
|
+
</>
|
|
327
|
+
)}
|
|
328
|
+
|
|
329
|
+
{functions.length > 0 && (
|
|
330
|
+
<>
|
|
331
|
+
<div className="settings-section-subcategory-title">
|
|
332
|
+
{nls.localize('theia/ai/core/agentConfiguration/usedFunctions', 'Used Functions')}
|
|
333
|
+
</div>
|
|
334
|
+
<ul className='function-references'>
|
|
335
|
+
<AgentFunctions functions={functions} />
|
|
336
|
+
</ul>
|
|
337
|
+
</>
|
|
338
|
+
)}
|
|
259
339
|
</div>;
|
|
260
340
|
}
|
|
261
341
|
|
|
@@ -282,12 +362,10 @@ export class AIAgentConfigurationWidget extends ReactWidget {
|
|
|
282
362
|
const variableMatches = matchVariablesRegEx(promptContent);
|
|
283
363
|
variableMatches.forEach(match => {
|
|
284
364
|
const variableId = match[1];
|
|
285
|
-
// skip comments
|
|
286
365
|
if (variableId.startsWith('!--')) {
|
|
287
366
|
return;
|
|
288
367
|
}
|
|
289
368
|
|
|
290
|
-
// Extract base variable ID without arguments
|
|
291
369
|
const baseVariableId = variableId.split(':')[0];
|
|
292
370
|
|
|
293
371
|
if (this.variableService.hasVariable(baseVariableId) &&
|
|
@@ -342,11 +420,6 @@ export class AIAgentConfigurationWidget extends ReactWidget {
|
|
|
342
420
|
quickPick.show();
|
|
343
421
|
}
|
|
344
422
|
|
|
345
|
-
protected setActiveAgent(agent: Agent): void {
|
|
346
|
-
this.aiConfigurationSelectionService.setActiveAgent(agent);
|
|
347
|
-
this.updateParsedPromptParts();
|
|
348
|
-
}
|
|
349
|
-
|
|
350
423
|
private toggleAgentEnabled = async () => {
|
|
351
424
|
const agent = this.aiConfigurationSelectionService.getActiveAgent();
|
|
352
425
|
if (!agent) {
|
|
@@ -364,19 +437,45 @@ export class AIAgentConfigurationWidget extends ReactWidget {
|
|
|
364
437
|
|
|
365
438
|
interface AgentGlobalVariablesProps {
|
|
366
439
|
variables: string[];
|
|
367
|
-
|
|
440
|
+
variableService: AIVariableService;
|
|
368
441
|
}
|
|
369
|
-
const AgentGlobalVariables = ({ variables: globalVariables,
|
|
442
|
+
const AgentGlobalVariables = ({ variables: globalVariables, variableService }: AgentGlobalVariablesProps) => {
|
|
370
443
|
if (globalVariables.length === 0) {
|
|
371
|
-
return
|
|
444
|
+
return <div className="ai-empty-state-content">
|
|
445
|
+
{nls.localizeByDefault('None')}
|
|
446
|
+
</div>;
|
|
372
447
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
448
|
+
|
|
449
|
+
const allVariables = variableService.getVariables();
|
|
450
|
+
const variableData = globalVariables.map(varId => {
|
|
451
|
+
const variable = allVariables.find(v => v.id === varId);
|
|
452
|
+
return {
|
|
453
|
+
id: varId,
|
|
454
|
+
name: variable?.name || varId,
|
|
455
|
+
description: variable?.description || ''
|
|
456
|
+
};
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
return (
|
|
460
|
+
<table className="ai-templates-table">
|
|
461
|
+
<thead>
|
|
462
|
+
<tr>
|
|
463
|
+
<th>{nls.localizeByDefault('Variable')}</th>
|
|
464
|
+
<th>{nls.localizeByDefault('Description')}</th>
|
|
465
|
+
</tr>
|
|
466
|
+
</thead>
|
|
467
|
+
<tbody>
|
|
468
|
+
{variableData.map(variable => (
|
|
469
|
+
<tr key={variable.id}>
|
|
470
|
+
<td className="ai-variable-name-cell">{variable.name}</td>
|
|
471
|
+
<td className="ai-variable-description-cell">
|
|
472
|
+
{variable.description || nls.localize('theia/ai/ide/agentConfiguration/noDescription', 'No description available')}
|
|
473
|
+
</td>
|
|
474
|
+
</tr>
|
|
475
|
+
))}
|
|
476
|
+
</tbody>
|
|
477
|
+
</table>
|
|
478
|
+
);
|
|
380
479
|
};
|
|
381
480
|
|
|
382
481
|
interface AgentFunctionsProps {
|
|
@@ -401,9 +500,11 @@ const AgentSpecificVariables = ({ promptVariables, agent }: AgentSpecificVariabl
|
|
|
401
500
|
const agentDefinedVariablesName = agent.agentSpecificVariables.map(v => v.name);
|
|
402
501
|
const variables = Array.from(new Set([...promptVariables, ...agentDefinedVariablesName]));
|
|
403
502
|
if (variables.length === 0) {
|
|
404
|
-
return
|
|
503
|
+
return <div className="ai-empty-state-content">
|
|
504
|
+
{nls.localizeByDefault('None')}
|
|
505
|
+
</div>;
|
|
405
506
|
}
|
|
406
|
-
return
|
|
507
|
+
return <div>
|
|
407
508
|
{variables.map(variableId =>
|
|
408
509
|
<AgentSpecificVariable
|
|
409
510
|
key={variableId}
|
|
@@ -411,7 +512,7 @@ const AgentSpecificVariables = ({ promptVariables, agent }: AgentSpecificVariabl
|
|
|
411
512
|
agent={agent}
|
|
412
513
|
promptVariables={promptVariables} />
|
|
413
514
|
)}
|
|
414
|
-
|
|
515
|
+
</div>;
|
|
415
516
|
};
|
|
416
517
|
interface AgentSpecificVariableProps {
|
|
417
518
|
variableId: string;
|
|
@@ -422,13 +523,33 @@ const AgentSpecificVariable = ({ variableId, agent, promptVariables }: AgentSpec
|
|
|
422
523
|
const agentDefinedVariable = agent.agentSpecificVariables.find(v => v.name === variableId);
|
|
423
524
|
const undeclared = agentDefinedVariable === undefined;
|
|
424
525
|
const notUsed = !promptVariables.includes(variableId) && agentDefinedVariable?.usedInPrompt === true;
|
|
425
|
-
return <
|
|
426
|
-
<div
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
526
|
+
return <div key={variableId} className="ai-agent-specific-variable-item">
|
|
527
|
+
<div className="ai-configuration-value-row">
|
|
528
|
+
<span className="ai-configuration-value-row-label">{nls.localizeByDefault('Name')}:</span>
|
|
529
|
+
<span className="ai-configuration-value-row-value">{variableId}</span>
|
|
530
|
+
</div>
|
|
531
|
+
{undeclared ? (
|
|
532
|
+
<div className="ai-configuration-value-row">
|
|
533
|
+
<span className="ai-configuration-value-row-label">{nls.localizeByDefault('Status')}:</span>
|
|
534
|
+
<span className="ai-configuration-value-row-value ai-configuration-warning-text">
|
|
535
|
+
{nls.localize('theia/ai/core/agentConfiguration/undeclared', 'Undeclared')}
|
|
536
|
+
</span>
|
|
537
|
+
</div>
|
|
538
|
+
) : (
|
|
539
|
+
<>
|
|
540
|
+
<div className="ai-configuration-value-row">
|
|
541
|
+
<span className="ai-configuration-value-row-label">{nls.localizeByDefault('Description')}:</span>
|
|
542
|
+
<span className="ai-configuration-value-row-value">{agentDefinedVariable.description}</span>
|
|
543
|
+
</div>
|
|
544
|
+
{notUsed && (
|
|
545
|
+
<div className="ai-configuration-value-row">
|
|
546
|
+
<span className="ai-configuration-value-row-label">{nls.localizeByDefault('Status')}:</span>
|
|
547
|
+
<span className="ai-configuration-value-row-value ai-configuration-warning-text">
|
|
548
|
+
{nls.localize('theia/ai/core/agentConfiguration/notUsedInPrompt', 'Not used in prompt')}
|
|
549
|
+
</span>
|
|
550
|
+
</div>
|
|
551
|
+
)}
|
|
552
|
+
</>
|
|
553
|
+
)}
|
|
554
|
+
</div>;
|
|
434
555
|
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 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
|
+
import * as React from '@theia/core/shared/react';
|
|
17
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
18
|
+
import { AIConfigurationBaseWidget } from './ai-configuration-base-widget';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Base class for AI configuration widgets that display items in a responsive card grid.
|
|
22
|
+
* This pattern is used by the MCP configuration widget.
|
|
23
|
+
*/
|
|
24
|
+
@injectable()
|
|
25
|
+
export abstract class AICardGridConfigurationWidget<T> extends AIConfigurationBaseWidget {
|
|
26
|
+
protected items: T[] = [];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get unique identifier for an item.
|
|
30
|
+
*/
|
|
31
|
+
protected abstract getItemId(item: T): string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Render a single card for an item.
|
|
35
|
+
*/
|
|
36
|
+
protected abstract renderCard(item: T): React.ReactNode;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Load items to display in the grid. Called during initialization.
|
|
40
|
+
*/
|
|
41
|
+
protected abstract loadItems(): Promise<void>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Optional: Render content before the card grid (e.g., header, controls).
|
|
45
|
+
*/
|
|
46
|
+
protected renderHeader(): React.ReactNode {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Optional: Render content after the card grid.
|
|
52
|
+
*/
|
|
53
|
+
protected renderFooter(): React.ReactNode {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected renderContent(): React.ReactNode {
|
|
58
|
+
return (
|
|
59
|
+
<div className="ai-card-grid-configuration-main">
|
|
60
|
+
{this.renderHeader()}
|
|
61
|
+
<div className="ai-configuration-card-grid">
|
|
62
|
+
{this.items.map(item => (
|
|
63
|
+
<div key={this.getItemId(item)} className="ai-configuration-card">
|
|
64
|
+
{this.renderCard(item)}
|
|
65
|
+
</div>
|
|
66
|
+
))}
|
|
67
|
+
</div>
|
|
68
|
+
{this.renderFooter()}
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 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
|
+
import * as React from '@theia/core/shared/react';
|
|
17
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
18
|
+
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Base class for all AI configuration widgets providing common structure and lifecycle management.
|
|
22
|
+
*/
|
|
23
|
+
@injectable()
|
|
24
|
+
export abstract class AIConfigurationBaseWidget extends ReactWidget {
|
|
25
|
+
/**
|
|
26
|
+
* Subclasses must implement this method to provide their specific content rendering.
|
|
27
|
+
*/
|
|
28
|
+
protected abstract renderContent(): React.ReactNode;
|
|
29
|
+
|
|
30
|
+
protected render(): React.ReactNode {
|
|
31
|
+
return (
|
|
32
|
+
<div className='ai-configuration-widget-content'>
|
|
33
|
+
{this.renderContent()}
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|