@theia/ai-ide 1.63.0-next.52 → 1.63.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.
Files changed (46) hide show
  1. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +1 -1
  2. package/lib/browser/ai-configuration/agent-configuration-widget.js +7 -2
  3. package/lib/browser/ai-configuration/agent-configuration-widget.js.map +1 -1
  4. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js +1 -1
  5. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js.map +1 -1
  6. package/lib/browser/ai-configuration/mcp-configuration-widget.d.ts +4 -1
  7. package/lib/browser/ai-configuration/mcp-configuration-widget.d.ts.map +1 -1
  8. package/lib/browser/ai-configuration/mcp-configuration-widget.js +59 -11
  9. package/lib/browser/ai-configuration/mcp-configuration-widget.js.map +1 -1
  10. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts.map +1 -1
  11. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +1 -3
  12. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +1 -1
  13. package/lib/browser/ai-configuration/template-settings-renderer.js +1 -1
  14. package/lib/browser/ai-configuration/template-settings-renderer.js.map +1 -1
  15. package/lib/browser/app-tester-chat-agent.d.ts +5 -3
  16. package/lib/browser/app-tester-chat-agent.d.ts.map +1 -1
  17. package/lib/browser/app-tester-chat-agent.js +41 -31
  18. package/lib/browser/app-tester-chat-agent.js.map +1 -1
  19. package/lib/browser/architect-agent.d.ts.map +1 -1
  20. package/lib/browser/architect-agent.js +2 -2
  21. package/lib/browser/architect-agent.js.map +1 -1
  22. package/lib/browser/summarize-session-command-contribution.d.ts +2 -0
  23. package/lib/browser/summarize-session-command-contribution.d.ts.map +1 -1
  24. package/lib/browser/summarize-session-command-contribution.js +9 -4
  25. package/lib/browser/summarize-session-command-contribution.js.map +1 -1
  26. package/lib/common/architect-prompt-template.d.ts +4 -3
  27. package/lib/common/architect-prompt-template.d.ts.map +1 -1
  28. package/lib/common/architect-prompt-template.js +43 -38
  29. package/lib/common/architect-prompt-template.js.map +1 -1
  30. package/lib/common/coder-replace-prompt-template.d.ts +4 -4
  31. package/lib/common/coder-replace-prompt-template.d.ts.map +1 -1
  32. package/lib/common/coder-replace-prompt-template.js +6 -6
  33. package/lib/common/coder-replace-prompt-template.js.map +1 -1
  34. package/lib/common/universal-chat-agent.js +2 -2
  35. package/package.json +17 -17
  36. package/src/browser/ai-configuration/agent-configuration-widget.tsx +7 -5
  37. package/src/browser/ai-configuration/ai-configuration-view-contribution.ts +1 -1
  38. package/src/browser/ai-configuration/mcp-configuration-widget.tsx +82 -14
  39. package/src/browser/ai-configuration/prompt-fragments-configuration-widget.tsx +1 -3
  40. package/src/browser/ai-configuration/template-settings-renderer.tsx +1 -1
  41. package/src/browser/app-tester-chat-agent.ts +43 -33
  42. package/src/browser/architect-agent.ts +3 -3
  43. package/src/browser/summarize-session-command-contribution.ts +8 -4
  44. package/src/common/architect-prompt-template.ts +43 -37
  45. package/src/common/coder-replace-prompt-template.ts +6 -6
  46. package/src/common/universal-chat-agent.ts +2 -2
@@ -60,7 +60,7 @@ export class AIAgentConfigurationViewContribution extends AIViewContribution<AIC
60
60
  tooltip: nls.localize('theia/ai-ide/open-agent-settings-tooltip', 'Open Agent settings...'),
61
61
  group: 'ai-settings',
62
62
  priority: 2,
63
- isVisible: widget => widget instanceof ChatViewWidget
63
+ isVisible: widget => this.activationService.isActive && widget instanceof ChatViewWidget
64
64
  });
65
65
  }
66
66
  }
@@ -18,7 +18,14 @@ import { ReactWidget } from '@theia/core/lib/browser';
18
18
  import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
19
19
  import * as React from '@theia/core/shared/react';
20
20
  import { HoverService } from '@theia/core/lib/browser/hover-service';
21
- import { MCPFrontendNotificationService, MCPFrontendService, MCPServerDescription, MCPServerStatus } from '@theia/ai-mcp/lib/common/mcp-server-manager';
21
+ import {
22
+ isLocalMCPServerDescription,
23
+ isRemoteMCPServerDescription,
24
+ MCPFrontendNotificationService,
25
+ MCPFrontendService,
26
+ MCPServerDescription,
27
+ MCPServerStatus
28
+ } from '@theia/ai-mcp/lib/common/mcp-server-manager';
22
29
  import { MessageService, nls } from '@theia/core';
23
30
  import { PROMPT_VARIABLE } from '@theia/ai-core/lib/common/prompt-variable-contribution';
24
31
 
@@ -67,12 +74,15 @@ export class AIMCPConfigurationWidget extends ReactWidget {
67
74
  }
68
75
  switch (status) {
69
76
  case MCPServerStatus.Running:
77
+ case MCPServerStatus.Connected:
70
78
  return { bg: 'var(--theia-successBackground)', fg: 'var(--theia-successForeground)' };
71
79
  case MCPServerStatus.Starting:
80
+ case MCPServerStatus.Connecting:
72
81
  return { bg: 'var(--theia-warningBackground)', fg: 'var(--theia-warningForeground)' };
73
82
  case MCPServerStatus.Errored:
74
83
  return { bg: 'var(--theia-errorBackground)', fg: 'var(--theia-errorForeground)' };
75
84
  case MCPServerStatus.NotRunning:
85
+ case MCPServerStatus.NotConnected:
76
86
  default:
77
87
  return { bg: 'var(--theia-inputValidation-infoBackground)', fg: 'var(--theia-inputValidation-infoForeground)' };
78
88
  }
@@ -106,10 +116,14 @@ export class AIMCPConfigurationWidget extends ReactWidget {
106
116
  );
107
117
  }
108
118
 
109
- protected renderStatusBadge(status?: MCPServerStatus, error?: string): React.ReactNode {
110
- const colors = this.getStatusColor(status);
111
- const displayStatus = status || MCPServerStatus.NotRunning;
119
+ protected renderStatusBadge(server: MCPServerDescription): React.ReactNode {
120
+ const colors = this.getStatusColor(server.status);
121
+ let displayStatus = server.status;
122
+ if (!displayStatus) {
123
+ displayStatus = isRemoteMCPServerDescription(server) ? MCPServerStatus.NotConnected : MCPServerStatus.NotRunning;
124
+ }
112
125
  const spanRef = React.createRef<HTMLSpanElement>();
126
+ const error = server.error;
113
127
  return (
114
128
  <div className="mcp-status-container">
115
129
  <span className="mcp-status-badge" style={{
@@ -136,12 +150,15 @@ export class AIMCPConfigurationWidget extends ReactWidget {
136
150
  return (
137
151
  <div className="mcp-server-header">
138
152
  <div className="mcp-server-name">{server.name}</div>
139
- {this.renderStatusBadge(server.status, server.error)}
153
+ {this.renderStatusBadge(server)}
140
154
  </div>
141
155
  );
142
156
  }
143
157
 
144
158
  protected renderCommandSection(server: MCPServerDescription): React.ReactNode {
159
+ if (!isLocalMCPServerDescription(server)) {
160
+ return;
161
+ }
145
162
  return (
146
163
  <div className="mcp-server-section">
147
164
  <span className="mcp-section-label">{nls.localize('theia/ai/mcpConfiguration/command', 'Command: ')}</span>
@@ -151,7 +168,7 @@ export class AIMCPConfigurationWidget extends ReactWidget {
151
168
  }
152
169
 
153
170
  protected renderArgumentsSection(server: MCPServerDescription): React.ReactNode {
154
- if (!server.args || server.args.length === 0) {
171
+ if (!isLocalMCPServerDescription(server) || !server.args || server.args.length === 0) {
155
172
  return;
156
173
  }
157
174
  return (
@@ -163,7 +180,7 @@ export class AIMCPConfigurationWidget extends ReactWidget {
163
180
  }
164
181
 
165
182
  protected renderEnvironmentSection(server: MCPServerDescription): React.ReactNode {
166
- if (!server.env || Object.keys(server.env).length === 0) {
183
+ if (!isLocalMCPServerDescription(server) || !server.env || Object.keys(server.env).length === 0) {
167
184
  return;
168
185
  }
169
186
  return (
@@ -172,7 +189,7 @@ export class AIMCPConfigurationWidget extends ReactWidget {
172
189
  <div className="mcp-env-block">
173
190
  {Object.entries(server.env).map(([key, value]) => (
174
191
  <div key={key}>
175
- {key}={key.toLowerCase().includes('token') ? '******' : value}
192
+ {key}={key.toLowerCase().includes('token') ? '******' : String(value)}
176
193
  </div>
177
194
  ))}
178
195
  </div>
@@ -180,6 +197,42 @@ export class AIMCPConfigurationWidget extends ReactWidget {
180
197
  );
181
198
  }
182
199
 
200
+ protected renderServerUrlSection(server: MCPServerDescription): React.ReactNode {
201
+ if (!isRemoteMCPServerDescription(server)) {
202
+ return;
203
+ }
204
+ return (
205
+ <div className="mcp-server-section">
206
+ <span className="mcp-section-label">{nls.localize('theia/ai/mcpConfiguration/serverUrl', 'Server URL: ')}</span>
207
+ <code className="mcp-code-block">{server.serverUrl}</code>
208
+ </div>
209
+ );
210
+ }
211
+
212
+ protected renderServerAuthTokenHeaderSection(server: MCPServerDescription): React.ReactNode {
213
+ if (!isRemoteMCPServerDescription(server) || !server.serverAuthTokenHeader) {
214
+ return;
215
+ }
216
+ return (
217
+ <div className="mcp-server-section">
218
+ <span className="mcp-section-label">{nls.localize('theia/ai/mcpConfiguration/serverAuthTokenHeader', 'Authentication Header Name: ')}</span>
219
+ <code className="mcp-code-block">{server.serverAuthTokenHeader}</code>
220
+ </div>
221
+ );
222
+ }
223
+
224
+ protected renderServerAuthTokenSection(server: MCPServerDescription): React.ReactNode {
225
+ if (!isRemoteMCPServerDescription(server) || !server.serverAuthToken) {
226
+ return;
227
+ }
228
+ return (
229
+ <div className="mcp-server-section">
230
+ <span className="mcp-section-label">{nls.localize('theia/ai/mcpConfiguration/serverAuthToken', 'Authentication Token: ')}</span>
231
+ <code className="mcp-code-block">******</code>
232
+ </div>
233
+ );
234
+ }
235
+
183
236
  protected renderAutostartSection(server: MCPServerDescription): React.ReactNode {
184
237
  return (
185
238
  <div className="mcp-server-section">
@@ -286,19 +339,31 @@ export class AIMCPConfigurationWidget extends ReactWidget {
286
339
  }
287
340
 
288
341
  protected renderServerControls(server: MCPServerDescription): React.ReactNode {
289
- const isStoppable = server.status === MCPServerStatus.Running || server.status === MCPServerStatus.Starting;
290
- const isStartable = server.status === MCPServerStatus.NotRunning || server.status === MCPServerStatus.Errored;
342
+ const isStoppable = server.status === MCPServerStatus.Running
343
+ || server.status === MCPServerStatus.Connected
344
+ || server.status === MCPServerStatus.Starting
345
+ || server.status === MCPServerStatus.Connecting;
346
+ const isStartable = server.status === MCPServerStatus.NotRunning
347
+ || server.status === MCPServerStatus.NotConnected
348
+ || server.status === MCPServerStatus.Errored;
349
+
350
+ const startLabel = isRemoteMCPServerDescription(server)
351
+ ? nls.localize('theia/ai/mcpConfiguration/connectServer', 'Connnect')
352
+ : nls.localize('theia/ai/mcpConfiguration/startServer', 'Start Server');
353
+ const stopLabel = isRemoteMCPServerDescription(server)
354
+ ? nls.localize('theia/ai/mcpConfiguration/disconnectServer', 'Disconnnect')
355
+ : nls.localize('theia/ai/mcpConfiguration/stopServer', 'Stop Server');
291
356
  return (
292
357
  <div className="mcp-server-controls">
293
358
  {isStartable && this.renderButton(
294
- <><i className="codicon codicon-play"></i> {nls.localize('theia/ai/mcpConfiguration/startServer', 'Start Server')}</>,
295
- nls.localize('theia/ai/mcpConfiguration/startServer', 'Start Server'),
359
+ <><i className="codicon codicon-play"></i> {startLabel}</>,
360
+ startLabel,
296
361
  () => this.handleStartServer(server.name),
297
362
  'mcp-server-button play-button'
298
363
  )}
299
364
  {isStoppable && this.renderButton(
300
- <><i className="codicon codicon-close"></i> {nls.localize('theia/ai/mcpConfiguration/stopServer', 'Stop Server')}</>,
301
- nls.localize('theia/ai/mcpConfiguration/stopServer', 'Stop Server'),
365
+ <><i className="codicon codicon-close"></i> {stopLabel}</>,
366
+ stopLabel,
302
367
  () => this.handleStopServer(server.name),
303
368
  'mcp-server-button stop-button'
304
369
  )}
@@ -313,6 +378,9 @@ export class AIMCPConfigurationWidget extends ReactWidget {
313
378
  {this.renderCommandSection(server)}
314
379
  {this.renderArgumentsSection(server)}
315
380
  {this.renderEnvironmentSection(server)}
381
+ {this.renderServerUrlSection(server)}
382
+ {this.renderServerAuthTokenHeaderSection(server)}
383
+ {this.renderServerAuthTokenSection(server)}
316
384
  {this.renderAutostartSection(server)}
317
385
  {this.renderToolsSection(server)}
318
386
  {this.renderServerControls(server)}
@@ -346,9 +346,7 @@ export class AIPromptFragmentsConfigurationWidget extends ReactWidget {
346
346
 
347
347
  const shouldReset = await dialog.open();
348
348
  if (shouldReset) {
349
- this.promptFragmentMap.forEach(fragments => {
350
- this.promptService.resetToBuiltIn(fragments[0].id);
351
- });
349
+ this.promptService.resetAllToBuiltIn();
352
350
  }
353
351
  };
354
352
 
@@ -77,7 +77,7 @@ export const PromptVariantRenderer: React.FC<PromptVariantRendererProps> = ({
77
77
  >
78
78
  {isInvalidVariant && (
79
79
  <option value="invalid" disabled>
80
- {nls.localize('theia/ai/core/templateSettings/unavailableVariant', 'The selected variant is no longer available')}
80
+ {nls.localize('theia/ai/core/templateSettings/unavailableVariant', 'Selected variant not available, default will be used')}
81
81
  </option>
82
82
  )}
83
83
  {variantIds.map(variantId => (
@@ -26,7 +26,22 @@ import { inject, injectable } from '@theia/core/shared/inversify';
26
26
  import { MCP_SERVERS_PREF } from '@theia/ai-mcp/lib/browser/mcp-preferences';
27
27
  import { PreferenceScope, PreferenceService } from '@theia/core/lib/browser';
28
28
 
29
- export const EXPECTED_MCP_SERVER_NAME = 'playwright';
29
+ export const REQUIRED_MCP_SERVERS: MCPServerDescription[] = [
30
+ {
31
+ name: 'playwright',
32
+ command: 'npx',
33
+ args: ['-y', '@playwright/mcp@latest'],
34
+ autostart: false,
35
+ env: {},
36
+ },
37
+ {
38
+ name: 'playwright-visual',
39
+ command: 'npx',
40
+ args: ['-y', '@playwright/mcp@latest', '--vision'],
41
+ autostart: false,
42
+ env: {},
43
+ }
44
+ ];
30
45
 
31
46
  // Prompt templates
32
47
  export const appTesterTemplate: BasePromptFragment = {
@@ -45,7 +60,8 @@ Your role is to inspect the application for user-specified test scenarios throug
45
60
  4. Help fix issues when needed
46
61
 
47
62
  ## Available Playwright Testing Tools
48
- You have access to these powerful automation tools: {{prompt:mcp_${EXPECTED_MCP_SERVER_NAME}_tools}}
63
+ You have access to these powerful automation tools:
64
+ ${REQUIRED_MCP_SERVERS.map(server => `{{prompt:mcp_${server.name}_tools}}`)}
49
65
 
50
66
  ## Workflow Approach
51
67
  1. **Understand Requirements**: Ask the user to clearly define what needs to be tested
@@ -86,30 +102,29 @@ export class AppTesterChatAgent extends AbstractStreamParsingChatAgent {
86
102
  + 'It can automate testing workflows and provide detailed feedback on application functionality.');
87
103
 
88
104
  override iconClass: string = 'codicon codicon-beaker';
89
- protected override systemPromptId: string = 'app-tester-prompt';
90
- override prompts = [{ id: 'app-tester-prompt', defaultVariant: appTesterTemplate, variants: [appTesterTemplateVariant] }];
105
+ protected override systemPromptId: string = 'app-tester-system';
106
+ override prompts = [{ id: 'app-tester-system', defaultVariant: appTesterTemplate, variants: [appTesterTemplateVariant] }];
91
107
 
92
108
  /**
93
109
  * Override invoke to check if the Playwright MCP server is running, and if not, ask the user if it should be started.
94
110
  */
95
111
  override async invoke(request: MutableChatRequestModel): Promise<void> {
96
112
  try {
97
- const startedServers = await this.mcpService.getStartedServers();
98
- if (!startedServers.includes(EXPECTED_MCP_SERVER_NAME)) {
113
+ if (await this.requiresStartingServers()) {
99
114
  // Ask the user if they want to start the server
100
115
  request.response.response.addContent(new QuestionResponseContentImpl(
101
- 'The Playwright MCP server is not running. Would you like to start it now? This may install the Playwright MCP server.',
116
+ 'The Playwright MCP servers are not running. Would you like to start them now? This may install the Playwright MCP servers.',
102
117
  [
103
- { text: 'Yes, start the server', value: 'yes' },
118
+ { text: 'Yes, start the servers', value: 'yes' },
104
119
  { text: 'No, cancel', value: 'no' }
105
120
  ],
106
121
  request,
107
122
  async selectedOption => {
108
123
  if (selectedOption.value === 'yes') {
109
124
  // Show progress
110
- const progress = request.response.addProgressMessage({ content: 'Starting Playwright MCP server.', show: 'whileIncomplete' });
125
+ const progress = request.response.addProgressMessage({ content: 'Starting Playwright MCP servers.', show: 'whileIncomplete' });
111
126
  try {
112
- await this.startPlaywrightMCPServer();
127
+ await this.startServers();
113
128
  // Remove progress, continue with normal flow
114
129
  request.response.updateProgressMessage({ ...progress, show: 'whileIncomplete', status: 'completed' });
115
130
  await super.invoke(request);
@@ -121,7 +136,7 @@ export class AppTesterChatAgent extends AbstractStreamParsingChatAgent {
121
136
  }
122
137
  } else {
123
138
  // Continue without starting the server
124
- request.response.response.addContent(new MarkdownChatResponseContentImpl('Please setup the MCP server.'));
139
+ request.response.response.addContent(new MarkdownChatResponseContentImpl('Please setup the MCP servers.'));
125
140
  request.response.complete();
126
141
  }
127
142
  }
@@ -139,39 +154,34 @@ export class AppTesterChatAgent extends AbstractStreamParsingChatAgent {
139
154
  }
140
155
  }
141
156
 
157
+ protected async requiresStartingServers(): Promise<boolean> {
158
+ const allStarted = await Promise.all(REQUIRED_MCP_SERVERS.map(server => this.mcpService.isServerStarted(server.name)));
159
+ return allStarted.some(started => !started);
160
+ }
161
+
162
+ protected async startServers(): Promise<void> {
163
+ await Promise.all(REQUIRED_MCP_SERVERS.map(server => this.ensureServerStarted(server)));
164
+
165
+ }
166
+
142
167
  /**
143
168
  * Starts the Playwright MCP server if it doesn't exist or isn't running.
144
169
  *
145
170
  * @returns A promise that resolves when the server is started
146
171
  */
147
- async startPlaywrightMCPServer(): Promise<void> {
172
+ async ensureServerStarted(server: MCPServerDescription): Promise<void> {
148
173
  try {
149
- const startedServers = await this.mcpService.getStartedServers();
150
- if (startedServers.includes(EXPECTED_MCP_SERVER_NAME)) {
174
+ if ((await this.mcpService.isServerStarted(server.name))) {
151
175
  return;
152
176
  }
153
-
154
- const mcpServer: MCPServerDescription = {
155
- name: EXPECTED_MCP_SERVER_NAME,
156
- command: 'npx',
157
- args: ['-y', '@playwright/mcp@latest'],
158
- autostart: false,
159
- env: {},
160
- };
161
-
162
- const availableServers = await this.mcpService.getServerNames();
163
- if (!availableServers.includes(EXPECTED_MCP_SERVER_NAME)) {
177
+ if (!(await this.mcpService.hasServer(server.name))) {
164
178
  const currentServers = this.preferenceService.get<Record<string, MCPServerDescription>>(MCP_SERVERS_PREF, {});
165
- await this.preferenceService.set(MCP_SERVERS_PREF, {
166
- ...currentServers,
167
- mcpServer
168
- }, PreferenceScope.User);
169
-
170
- await this.mcpService.addOrUpdateServer(mcpServer);
179
+ await this.preferenceService.set(MCP_SERVERS_PREF, { ...currentServers, server }, PreferenceScope.User);
180
+ await this.mcpService.addOrUpdateServer(server);
171
181
  }
172
- await this.mcpService.startServer(EXPECTED_MCP_SERVER_NAME);
182
+ await this.mcpService.startServer(server.name);
173
183
  } catch (error) {
174
- this.logger.error(`Error starting Playwright MCP server: ${error}`);
184
+ this.logger.error(`Error starting MCP server ${server.name}: ${error}`);
175
185
  throw error;
176
186
  }
177
187
  }
@@ -16,7 +16,7 @@
16
16
  import { AbstractStreamParsingChatAgent, ChatRequestModel, ChatService, ChatSession, MutableChatModel, MutableChatRequestModel } from '@theia/ai-chat/lib/common';
17
17
  import { LanguageModelRequirement } from '@theia/ai-core';
18
18
  import { inject, injectable } from '@theia/core/shared/inversify';
19
- import { architectVariants } from '../common/architect-prompt-template';
19
+ import { architectSystemVariants, architectTaskSummaryVariants } from '../common/architect-prompt-template';
20
20
  import { FILE_CONTENT_FUNCTION_ID, GET_WORKSPACE_FILE_LIST_FUNCTION_ID } from '../common/workspace-functions';
21
21
  import { nls } from '@theia/core';
22
22
  import { MarkdownStringImpl } from '@theia/core/lib/common/markdown-rendering';
@@ -38,9 +38,9 @@ export class ArchitectAgent extends AbstractStreamParsingChatAgent {
38
38
  'An AI assistant integrated into Theia IDE, designed to assist software developers. This agent can access the users workspace, it can get a list of all available files \
39
39
  and folders and retrieve their content. It cannot modify files. It can therefore answer questions about the current project, project files and source code in the \
40
40
  workspace, such as how to build the project, where to put source code, where to find specific code or configurations, etc.');
41
- override prompts = [architectVariants];
41
+ override prompts = [architectSystemVariants, architectTaskSummaryVariants];
42
42
  override functions = [GET_WORKSPACE_FILE_LIST_FUNCTION_ID, FILE_CONTENT_FUNCTION_ID];
43
- protected override systemPromptId: string | undefined = architectVariants.id;
43
+ protected override systemPromptId: string | undefined = architectSystemVariants.id;
44
44
 
45
45
  override async invoke(request: MutableChatRequestModel): Promise<void> {
46
46
  await super.invoke(request);
@@ -26,6 +26,7 @@ import { FILE_VARIABLE } from '@theia/ai-core/lib/browser/file-variable-contribu
26
26
  import { AIVariableResolutionRequest } from '@theia/ai-core';
27
27
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
28
28
  import { WorkspaceService } from '@theia/workspace/lib/browser';
29
+ import { AICommandHandlerFactory } from '@theia/ai-core/lib/browser';
29
30
 
30
31
  @injectable()
31
32
  export class SummarizeSessionCommandContribution implements CommandContribution {
@@ -50,8 +51,11 @@ export class SummarizeSessionCommandContribution implements CommandContribution
50
51
  @inject(WorkspaceService)
51
52
  protected readonly wsService: WorkspaceService;
52
53
 
54
+ @inject(AICommandHandlerFactory)
55
+ protected readonly commandHandlerFactory: AICommandHandlerFactory;
56
+
53
57
  registerCommands(registry: CommandRegistry): void {
54
- registry.registerCommand(AI_UPDATE_TASK_CONTEXT_COMMAND, {
58
+ registry.registerCommand(AI_UPDATE_TASK_CONTEXT_COMMAND, this.commandHandlerFactory({
55
59
  execute: async () => {
56
60
  const activeSession = this.chatService.getActiveSession();
57
61
 
@@ -68,9 +72,9 @@ export class SummarizeSessionCommandContribution implements CommandContribution
68
72
  await this.taskContextService.update(activeSession, ARCHITECT_TASK_SUMMARY_UPDATE_PROMPT_TEMPLATE_ID);
69
73
  }
70
74
  }
71
- });
75
+ }));
72
76
 
73
- registry.registerCommand(AI_SUMMARIZE_SESSION_AS_TASK_FOR_CODER, {
77
+ registry.registerCommand(AI_SUMMARIZE_SESSION_AS_TASK_FOR_CODER, this.commandHandlerFactory({
74
78
  execute: async () => {
75
79
  const activeSession = this.chatService.getActiveSession();
76
80
 
@@ -104,6 +108,6 @@ export class SummarizeSessionCommandContribution implements CommandContribution
104
108
  newSession.model.context.addVariables(summaryVariable);
105
109
  }
106
110
  }
107
- });
111
+ }));
108
112
  }
109
113
  }
@@ -16,10 +16,10 @@ import {
16
16
  import { CONTEXT_FILES_VARIABLE_ID, TASK_CONTEXT_SUMMARY_VARIABLE_ID } from './context-variables';
17
17
  import { UPDATE_CONTEXT_FILES_FUNCTION_ID } from './context-functions';
18
18
 
19
- export const ARCHITECT_TASK_SUMMARY_PROMPT_TEMPLATE_ID = 'architect-task-summary';
20
- export const ARCHITECT_TASK_SUMMARY_UPDATE_PROMPT_TEMPLATE_ID = 'architect-update-task-summary';
19
+ export const ARCHITECT_TASK_SUMMARY_PROMPT_TEMPLATE_ID = 'architect-tasksummary-create';
20
+ export const ARCHITECT_TASK_SUMMARY_UPDATE_PROMPT_TEMPLATE_ID = 'architect-tasksummary-update';
21
21
 
22
- export const architectVariants = <PromptVariantSet>{
22
+ export const architectSystemVariants = <PromptVariantSet>{
23
23
  id: 'architect-system',
24
24
  defaultVariant: {
25
25
  id: 'architect-system-default',
@@ -28,69 +28,73 @@ Made improvements or adaptations to this prompt template? We'd love for you to s
28
28
  https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
29
29
  # Instructions
30
30
 
31
- You are an AI assistant integrated into Theia IDE, designed to assist software developers. You can't change any files, but you can navigate and read the users workspace using \
32
- the provided functions. Therefore describe and explain the details or procedures necessary to achieve the desired outcome. If file changes are necessary to help the user, be \
31
+ You are an AI assistant integrated into Theia IDE, designed to assist software developers. You can only change the files added to the context, but you can navigate and read the
32
+ users workspace using the provided functions.\
33
+ Therefore describe and explain the details or procedures necessary to achieve the desired outcome. If file changes are necessary to help the user, be \
33
34
  aware that there is another agent called 'Coder' that can suggest file changes. In this case you can create a description on what to do and tell the user to ask '@Coder' to \
34
35
  implement the change plan. If you refer to files, always mention the workspace-relative path.\
35
36
 
36
- Use the following functions to interact with the workspace files as needed:
37
- - **~{${GET_WORKSPACE_DIRECTORY_STRUCTURE_FUNCTION_ID}}**: Returns the complete directory structure.
38
- - **~{${GET_WORKSPACE_FILE_LIST_FUNCTION_ID}}**: Lists files and directories in a specific directory.
39
- - **~{${FILE_CONTENT_FUNCTION_ID}}**: Retrieves the content of a specific file.
40
-
41
- ### Workspace Navigation Guidelines
37
+ ## Context Retrieval
38
+ Use the following functions to interact with the workspace files if you require context:
39
+ - **~{${GET_WORKSPACE_DIRECTORY_STRUCTURE_FUNCTION_ID}}**
40
+ - **~{${GET_WORKSPACE_FILE_LIST_FUNCTION_ID}}**
41
+ - **~{${FILE_CONTENT_FUNCTION_ID}}**
42
+ - **~{${SEARCH_IN_WORKSPACE_FUNCTION_ID}}**
42
43
 
43
- 1. **Start at the Root**: For general questions (e.g., "How to build the project"), check root-level documentation files or setup files before browsing subdirectories.
44
- 2. **Confirm Paths**: Always verify paths by listing directories or files as you navigate. Avoid assumptions based on user input alone.
45
- 3. **Navigate Step-by-Step**: Move into subdirectories only as needed, confirming each directory level.
44
+ Remember file locations that are relevant for completing your tasks using **~{${UPDATE_CONTEXT_FILES_FUNCTION_ID}}**
45
+ Only add files that are really relevant to look at later. Only add files that are really relevant to look at later.
46
46
 
47
+ ## File Validation
48
+ Use the following function to retrieve a list of problems in a file if the user requests fixes in a given file: **~{${GET_FILE_DIAGNOSTICS_ID}}**
47
49
  ## Additional Context
48
50
  The following files have been provided for additional context. Some of them may also be referred to by the user (e.g. "this file" or "the attachment"). \
49
51
  Always look at the relevant files to understand your task using the function ~{${FILE_CONTENT_FUNCTION_ID}}
50
52
  {{${CONTEXT_FILES_VARIABLE_ID}}}
51
53
 
52
54
  {{prompt:project-info}}
55
+
56
+ {{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}
53
57
  `
54
58
  },
55
59
  variants: [
56
60
  {
57
- id: 'architect-system-next',
61
+ id: 'architect-system-simple',
58
62
  template: `{{!-- This prompt is licensed under the MIT License (https://opensource.org/license/mit).
59
63
  Made improvements or adaptations to this prompt template? We'd love for you to share it with the community! Contribute back here:
60
64
  https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
61
65
  # Instructions
62
-
63
- You are an AI assistant integrated into Theia IDE, designed to assist software developers. You can only change the files added to the context, but you can navigate and read the
64
- users workspace using the provided functions.\
65
- Therefore describe and explain the details or procedures necessary to achieve the desired outcome. If file changes are necessary to help the user, be \
66
+
67
+ You are an AI assistant integrated into Theia IDE, designed to assist software developers. You can't change any files, but you can navigate and read the users workspace using \
68
+ the provided functions. Therefore describe and explain the details or procedures necessary to achieve the desired outcome. If file changes are necessary to help the user, be \
66
69
  aware that there is another agent called 'Coder' that can suggest file changes. In this case you can create a description on what to do and tell the user to ask '@Coder' to \
67
70
  implement the change plan. If you refer to files, always mention the workspace-relative path.\
71
+
72
+ Use the following functions to interact with the workspace files as needed:
73
+ - **~{${GET_WORKSPACE_DIRECTORY_STRUCTURE_FUNCTION_ID}}**: Returns the complete directory structure.
74
+ - **~{${GET_WORKSPACE_FILE_LIST_FUNCTION_ID}}**: Lists files and directories in a specific directory.
75
+ - **~{${FILE_CONTENT_FUNCTION_ID}}**: Retrieves the content of a specific file.
76
+
77
+ ### Workspace Navigation Guidelines
68
78
 
69
- ## Context Retrieval
70
- Use the following functions to interact with the workspace files if you require context:
71
- - **~{${GET_WORKSPACE_DIRECTORY_STRUCTURE_FUNCTION_ID}}**
72
- - **~{${GET_WORKSPACE_FILE_LIST_FUNCTION_ID}}**
73
- - **~{${FILE_CONTENT_FUNCTION_ID}}**
74
- - **~{${SEARCH_IN_WORKSPACE_FUNCTION_ID}}**
75
-
76
- Remember file locations that are relevant for completing your tasks using **~{${UPDATE_CONTEXT_FILES_FUNCTION_ID}}**
77
- Only add files that are really relevant to look at later. Only add files that are really relevant to look at later.
79
+ 1. **Start at the Root**: For general questions (e.g., "How to build the project"), check root-level documentation files or setup files before browsing subdirectories.
80
+ 2. **Confirm Paths**: Always verify paths by listing directories or files as you navigate. Avoid assumptions based on user input alone.
81
+ 3. **Navigate Step-by-Step**: Move into subdirectories only as needed, confirming each directory level.
78
82
 
79
- ## File Validation
80
- Use the following function to retrieve a list of problems in a file if the user requests fixes in a given file: **~{${GET_FILE_DIAGNOSTICS_ID}}**
81
83
  ## Additional Context
82
84
  The following files have been provided for additional context. Some of them may also be referred to by the user (e.g. "this file" or "the attachment"). \
83
85
  Always look at the relevant files to understand your task using the function ~{${FILE_CONTENT_FUNCTION_ID}}
84
86
  {{${CONTEXT_FILES_VARIABLE_ID}}}
85
87
 
86
88
  {{prompt:project-info}}
87
-
88
- {{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}
89
89
  `
90
- },
91
- {
92
- id: ARCHITECT_TASK_SUMMARY_PROMPT_TEMPLATE_ID,
93
- template: `{{!-- This prompt is licensed under the MIT License (https://opensource.org/license/mit).
90
+ }]
91
+ };
92
+
93
+ export const architectTaskSummaryVariants = <PromptVariantSet>{
94
+ id: 'architect-tasksummary',
95
+ defaultVariant: {
96
+ id: ARCHITECT_TASK_SUMMARY_PROMPT_TEMPLATE_ID,
97
+ template: `{{!-- This prompt is licensed under the MIT License (https://opensource.org/license/mit).
94
98
  Made improvements or adaptations to this prompt template? We'd love for you to share it with the community! Contribute back here:
95
99
  https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
96
100
 
@@ -217,7 +221,9 @@ Use the following format, but only include the sections that were discussed in t
217
221
  **Next Steps:**
218
222
  - [Immediate action items, who should act next.]
219
223
  `
220
- },
224
+ },
225
+ variants: [
226
+
221
227
  {
222
228
  id: ARCHITECT_TASK_SUMMARY_UPDATE_PROMPT_TEMPLATE_ID,
223
229
  template: `{{!-- This prompt is licensed under the MIT License (https://opensource.org/license/mit).
@@ -31,11 +31,11 @@ import {
31
31
  GET_PROPOSED_CHANGES_ID
32
32
  } from './file-changeset-function-ids';
33
33
 
34
- export const CODER_SYSTEM_PROMPT_ID = 'coder-prompt';
34
+ export const CODER_SYSTEM_PROMPT_ID = 'coder-system';
35
35
 
36
- export const CODER_SIMPLE_EDIT_TEMPLATE_ID = 'coder-simple-edit';
37
- export const CODER_EDIT_TEMPLATE_ID = 'coder-edit';
38
- export const CODER_AGENT_MODE_TEMPLATE_ID = 'coder-agent-mode';
36
+ export const CODER_SIMPLE_EDIT_TEMPLATE_ID = 'coder-system-simple-edit';
37
+ export const CODER_EDIT_TEMPLATE_ID = 'coder-system-edit';
38
+ export const CODER_AGENT_MODE_TEMPLATE_ID = 'coder-system-agent-mode';
39
39
 
40
40
  export function getCoderAgentModePromptTemplate(): BasePromptFragment {
41
41
  return {
@@ -219,7 +219,7 @@ You have previously proposed changes for the following files. Some suggestions m
219
219
  {{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}
220
220
 
221
221
  ## Final Instruction
222
- - Your task is to propose changes to be reviewed by the user
222
+ - Your task is to propose changes to be reviewed by the user. Always do so using the functions described above.
223
223
  - Tasks such as building or liniting run on the workspace state, the user has to accept the changes beforehand
224
224
  - Do not run a build or any error checking before the users asks you to
225
225
  - Focus on the task that the user described
@@ -277,7 +277,7 @@ You have previously proposed changes for the following files. Some suggestions m
277
277
  {{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}
278
278
 
279
279
  ## Final Instruction
280
- - Your task is to propose changes to be reviewed by the user
280
+ - Your task is to propose changes to be reviewed by the user. Always do so using the functions described above.
281
281
  - Tasks such as building or liniting run on the workspace state, the user has to accept the changes beforehand
282
282
  - Do not run a build or any error checking before the users asks you to
283
283
  - Focus on the task that the user described
@@ -35,6 +35,6 @@ export class UniversalChatAgent extends AbstractStreamParsingChatAgent {
35
35
  + 'questions the user might ask. The universal agent currently does not have any context by default, i.e. it cannot '
36
36
  + 'access the current user context or the workspace.');
37
37
 
38
- override prompts = [{ id: 'universal-prompt', defaultVariant: universalTemplate, variants: [universalTemplateVariant] }];
39
- protected override systemPromptId: string = 'universal-prompt';
38
+ override prompts = [{ id: 'universal-system', defaultVariant: universalTemplate, variants: [universalTemplateVariant] }];
39
+ protected override systemPromptId: string = 'universal-system';
40
40
  }