@theia/ai-ide 1.64.0-next.28 → 1.64.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 (152) hide show
  1. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts +5 -2
  2. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +1 -1
  3. package/lib/browser/ai-configuration/agent-configuration-widget.js +15 -1
  4. package/lib/browser/ai-configuration/agent-configuration-widget.js.map +1 -1
  5. package/lib/browser/ai-configuration/ai-configuration-service.d.ts +6 -1
  6. package/lib/browser/ai-configuration/ai-configuration-service.d.ts.map +1 -1
  7. package/lib/browser/ai-configuration/ai-configuration-service.js +10 -1
  8. package/lib/browser/ai-configuration/ai-configuration-service.js.map +1 -1
  9. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts +2 -0
  10. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts.map +1 -1
  11. package/lib/browser/ai-configuration/ai-configuration-widget.js +7 -1
  12. package/lib/browser/ai-configuration/ai-configuration-widget.js.map +1 -1
  13. package/lib/browser/ai-configuration/language-model-renderer.d.ts +4 -2
  14. package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -1
  15. package/lib/browser/ai-configuration/language-model-renderer.js +49 -71
  16. package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -1
  17. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts +41 -0
  18. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts.map +1 -0
  19. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js +225 -0
  20. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js.map +1 -0
  21. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts +7 -3
  22. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts.map +1 -1
  23. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +35 -13
  24. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +1 -1
  25. package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +1 -1
  26. package/lib/browser/ai-configuration/template-settings-renderer.js +11 -6
  27. package/lib/browser/ai-configuration/template-settings-renderer.js.map +1 -1
  28. package/lib/browser/ai-ide-activation-service.d.ts +18 -0
  29. package/lib/browser/ai-ide-activation-service.d.ts.map +1 -0
  30. package/lib/browser/ai-ide-activation-service.js +72 -0
  31. package/lib/browser/ai-ide-activation-service.js.map +1 -0
  32. package/lib/browser/ai-ide-preferences.d.ts +4 -0
  33. package/lib/browser/ai-ide-preferences.d.ts.map +1 -0
  34. package/lib/browser/ai-ide-preferences.js +43 -0
  35. package/lib/browser/ai-ide-preferences.js.map +1 -0
  36. package/lib/browser/app-tester-chat-agent.d.ts +3 -6
  37. package/lib/browser/app-tester-chat-agent.d.ts.map +1 -1
  38. package/lib/browser/app-tester-chat-agent.js +6 -71
  39. package/lib/browser/app-tester-chat-agent.js.map +1 -1
  40. package/lib/browser/app-tester-prompt-template.d.ts +6 -0
  41. package/lib/browser/app-tester-prompt-template.d.ts.map +1 -0
  42. package/lib/browser/app-tester-prompt-template.js +79 -0
  43. package/lib/browser/app-tester-prompt-template.js.map +1 -0
  44. package/lib/browser/architect-agent.js +1 -1
  45. package/lib/browser/architect-agent.js.map +1 -1
  46. package/lib/browser/coder-agent.js +1 -1
  47. package/lib/browser/coder-agent.js.map +1 -1
  48. package/lib/browser/context-functions.d.ts.map +1 -1
  49. package/lib/browser/context-functions.js +12 -0
  50. package/lib/browser/context-functions.js.map +1 -1
  51. package/lib/browser/context-functions.spec.d.ts +2 -0
  52. package/lib/browser/context-functions.spec.d.ts.map +1 -0
  53. package/lib/browser/context-functions.spec.js +93 -0
  54. package/lib/browser/context-functions.spec.js.map +1 -0
  55. package/lib/browser/file-changeset-function.spec.d.ts +2 -0
  56. package/lib/browser/file-changeset-function.spec.d.ts.map +1 -0
  57. package/lib/browser/file-changeset-function.spec.js +45 -0
  58. package/lib/browser/file-changeset-function.spec.js.map +1 -0
  59. package/lib/browser/file-changeset-functions.d.ts +13 -3
  60. package/lib/browser/file-changeset-functions.d.ts.map +1 -1
  61. package/lib/browser/file-changeset-functions.js +100 -29
  62. package/lib/browser/file-changeset-functions.js.map +1 -1
  63. package/lib/browser/file-changeset-functions.spec.d.ts +2 -0
  64. package/lib/browser/file-changeset-functions.spec.d.ts.map +1 -0
  65. package/lib/browser/file-changeset-functions.spec.js +161 -0
  66. package/lib/browser/file-changeset-functions.spec.js.map +1 -0
  67. package/lib/browser/frontend-module.d.ts.map +1 -1
  68. package/lib/browser/frontend-module.js +20 -0
  69. package/lib/browser/frontend-module.js.map +1 -1
  70. package/lib/browser/ide-chat-welcome-message-provider.js +2 -2
  71. package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
  72. package/lib/browser/test/tool-provider-cancellation-test-util.spec.d.ts +2 -0
  73. package/lib/browser/test/tool-provider-cancellation-test-util.spec.d.ts.map +1 -0
  74. package/lib/browser/test/tool-provider-cancellation-test-util.spec.js +52 -0
  75. package/lib/browser/test/tool-provider-cancellation-test-util.spec.js.map +1 -0
  76. package/lib/browser/workspace-functions.d.ts +3 -3
  77. package/lib/browser/workspace-functions.d.ts.map +1 -1
  78. package/lib/browser/workspace-functions.js +79 -28
  79. package/lib/browser/workspace-functions.js.map +1 -1
  80. package/lib/browser/workspace-functions.spec.d.ts +2 -0
  81. package/lib/browser/workspace-functions.spec.d.ts.map +1 -0
  82. package/lib/browser/workspace-functions.spec.js +161 -0
  83. package/lib/browser/workspace-functions.spec.js.map +1 -0
  84. package/lib/browser/workspace-launch-provider.d.ts +24 -0
  85. package/lib/browser/workspace-launch-provider.d.ts.map +1 -0
  86. package/lib/browser/workspace-launch-provider.js +216 -0
  87. package/lib/browser/workspace-launch-provider.js.map +1 -0
  88. package/lib/browser/workspace-launch-provider.spec.d.ts +2 -0
  89. package/lib/browser/workspace-launch-provider.spec.d.ts.map +1 -0
  90. package/lib/browser/workspace-launch-provider.spec.js +245 -0
  91. package/lib/browser/workspace-launch-provider.spec.js.map +1 -0
  92. package/lib/browser/workspace-search-provider.d.ts.map +1 -1
  93. package/lib/browser/workspace-search-provider.js +9 -0
  94. package/lib/browser/workspace-search-provider.js.map +1 -1
  95. package/lib/browser/workspace-search-provider.spec.js +59 -203
  96. package/lib/browser/workspace-search-provider.spec.js.map +1 -1
  97. package/lib/browser/workspace-task-provider.d.ts.map +1 -1
  98. package/lib/browser/workspace-task-provider.js +8 -1
  99. package/lib/browser/workspace-task-provider.js.map +1 -1
  100. package/lib/browser/workspace-task-provider.spec.d.ts +2 -0
  101. package/lib/browser/workspace-task-provider.spec.d.ts.map +1 -0
  102. package/lib/browser/workspace-task-provider.spec.js +109 -0
  103. package/lib/browser/workspace-task-provider.spec.js.map +1 -0
  104. package/lib/common/architect-prompt-template.d.ts.map +1 -1
  105. package/lib/common/architect-prompt-template.js +11 -0
  106. package/lib/common/architect-prompt-template.js.map +1 -1
  107. package/lib/common/command-chat-agents.js +1 -1
  108. package/lib/common/command-chat-agents.js.map +1 -1
  109. package/lib/common/orchestrator-chat-agent.js +1 -1
  110. package/lib/common/orchestrator-chat-agent.js.map +1 -1
  111. package/lib/common/universal-chat-agent.js +1 -1
  112. package/lib/common/universal-chat-agent.js.map +1 -1
  113. package/lib/common/workspace-functions.d.ts +3 -0
  114. package/lib/common/workspace-functions.d.ts.map +1 -1
  115. package/lib/common/workspace-functions.js +4 -1
  116. package/lib/common/workspace-functions.js.map +1 -1
  117. package/package.json +18 -17
  118. package/src/browser/ai-configuration/agent-configuration-widget.tsx +18 -2
  119. package/src/browser/ai-configuration/ai-configuration-service.ts +14 -1
  120. package/src/browser/ai-configuration/ai-configuration-widget.tsx +7 -1
  121. package/src/browser/ai-configuration/language-model-renderer.tsx +87 -59
  122. package/src/browser/ai-configuration/model-aliases-configuration-widget.tsx +279 -0
  123. package/src/browser/ai-configuration/prompt-fragments-configuration-widget.tsx +43 -13
  124. package/src/browser/ai-configuration/template-settings-renderer.tsx +11 -7
  125. package/src/browser/ai-ide-activation-service.ts +65 -0
  126. package/src/browser/ai-ide-preferences.ts +44 -0
  127. package/src/browser/app-tester-chat-agent.ts +5 -73
  128. package/src/browser/app-tester-prompt-template.ts +81 -0
  129. package/src/browser/architect-agent.ts +1 -1
  130. package/src/browser/coder-agent.ts +1 -1
  131. package/src/browser/context-functions.spec.ts +102 -0
  132. package/src/browser/context-functions.ts +11 -0
  133. package/src/browser/file-changeset-function.spec.ts +52 -0
  134. package/src/browser/file-changeset-functions.spec.ts +212 -0
  135. package/src/browser/file-changeset-functions.ts +102 -25
  136. package/src/browser/frontend-module.ts +29 -1
  137. package/src/browser/ide-chat-welcome-message-provider.tsx +4 -4
  138. package/src/browser/style/index.css +111 -6
  139. package/src/browser/test/tool-provider-cancellation-test-util.spec.ts +60 -0
  140. package/src/browser/workspace-functions.spec.ts +199 -0
  141. package/src/browser/workspace-functions.ts +105 -32
  142. package/src/browser/workspace-launch-provider.spec.ts +320 -0
  143. package/src/browser/workspace-launch-provider.ts +231 -0
  144. package/src/browser/workspace-search-provider.spec.ts +79 -229
  145. package/src/browser/workspace-search-provider.ts +10 -1
  146. package/src/browser/workspace-task-provider.spec.ts +125 -0
  147. package/src/browser/workspace-task-provider.ts +7 -2
  148. package/src/common/architect-prompt-template.ts +11 -0
  149. package/src/common/command-chat-agents.ts +1 -1
  150. package/src/common/orchestrator-chat-agent.ts +1 -1
  151. package/src/common/universal-chat-agent.ts +1 -1
  152. package/src/common/workspace-functions.ts +3 -0
@@ -0,0 +1,320 @@
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
+
17
+ import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
18
+ let disableJSDOM = enableJSDOM();
19
+ import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
20
+ FrontendApplicationConfigProvider.set({});
21
+
22
+ import { expect } from 'chai';
23
+ import { Container } from '@theia/core/shared/inversify';
24
+ import {
25
+ LaunchListProvider,
26
+ LaunchRunnerProvider,
27
+ LaunchStopProvider,
28
+ } from './workspace-launch-provider';
29
+ import { DebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager';
30
+ import { DebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
31
+ import { DebugSessionOptions } from '@theia/debug/lib/browser/debug-session-options';
32
+ import { DebugConfiguration } from '@theia/debug/lib/common/debug-common';
33
+ import { DebugCompound } from '@theia/debug/lib/common/debug-compound';
34
+ import { DebugSession } from '@theia/debug/lib/browser/debug-session';
35
+
36
+ disableJSDOM();
37
+
38
+ describe('Launch Management Tool Providers', () => {
39
+ let container: Container;
40
+ let launchListProvider: LaunchListProvider;
41
+ let launchRunnerProvider: LaunchRunnerProvider;
42
+ let launchStopProvider: LaunchStopProvider;
43
+ let mockDebugConfigurationManager: Partial<DebugConfigurationManager>;
44
+ let mockDebugSessionManager: Partial<DebugSessionManager>;
45
+
46
+ before(() => {
47
+ disableJSDOM = enableJSDOM();
48
+ });
49
+
50
+ after(() => {
51
+ disableJSDOM();
52
+ });
53
+
54
+ beforeEach(() => {
55
+ container = new Container();
56
+
57
+ const mockConfigs = createMockConfigurations();
58
+
59
+ mockDebugConfigurationManager = {
60
+ load: () => Promise.resolve(),
61
+ get all(): IterableIterator<DebugSessionOptions> {
62
+ function* configIterator(): IterableIterator<DebugSessionOptions> {
63
+ for (const config of mockConfigs) {
64
+ yield config;
65
+ }
66
+ }
67
+ return configIterator();
68
+ },
69
+ };
70
+
71
+ mockDebugSessionManager = {
72
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
+ start: async (options: DebugSessionOptions | string): Promise<any> => {
74
+ if (
75
+ typeof options === 'string' ||
76
+ DebugSessionOptions.isCompound(options)
77
+ ) {
78
+ return true;
79
+ }
80
+ return {
81
+ id: 'test-session-id',
82
+ configuration: { name: 'Test Config' },
83
+ } as DebugSession;
84
+ },
85
+ terminateSession: () => Promise.resolve(),
86
+ currentSession: undefined,
87
+ sessions: [],
88
+ };
89
+
90
+ container
91
+ .bind(DebugConfigurationManager)
92
+ .toConstantValue(
93
+ mockDebugConfigurationManager as DebugConfigurationManager
94
+ );
95
+ container
96
+ .bind(DebugSessionManager)
97
+ .toConstantValue(mockDebugSessionManager as DebugSessionManager);
98
+
99
+ launchListProvider = container.resolve(LaunchListProvider);
100
+ launchRunnerProvider = container.resolve(LaunchRunnerProvider);
101
+ launchStopProvider = container.resolve(LaunchStopProvider);
102
+ });
103
+
104
+ function createMockConfigurations(): DebugSessionOptions[] {
105
+ const config1: DebugConfiguration = {
106
+ name: 'Node.js Debug',
107
+ type: 'node',
108
+ request: 'launch',
109
+ program: '${workspaceFolder}/app.js',
110
+ };
111
+
112
+ const config2: DebugConfiguration = {
113
+ name: 'Python Debug',
114
+ type: 'python',
115
+ request: 'launch',
116
+ program: '${workspaceFolder}/main.py',
117
+ };
118
+
119
+ const compound: DebugCompound = {
120
+ name: 'Launch All',
121
+ configurations: ['Node.js Debug', 'Python Debug'],
122
+ };
123
+
124
+ return [
125
+ {
126
+ name: 'Node.js Debug',
127
+ configuration: config1,
128
+ workspaceFolderUri: '/workspace',
129
+ },
130
+ {
131
+ name: 'Python Debug',
132
+ configuration: config2,
133
+ workspaceFolderUri: '/workspace',
134
+ },
135
+ { name: 'Launch All', compound, workspaceFolderUri: '/workspace' },
136
+ ];
137
+ }
138
+
139
+ describe('LaunchListProvider', () => {
140
+ it('should provide the correct tool metadata', () => {
141
+ const tool = launchListProvider.getTool();
142
+ expect(tool.id).to.equal('listLaunchConfigurations');
143
+ expect(tool.name).to.equal('listLaunchConfigurations');
144
+ expect(tool.description).to.contain(
145
+ 'Lists available launch configurations'
146
+ );
147
+ expect(tool.parameters.required).to.deep.equal(['filter']);
148
+ });
149
+
150
+ it('should list all configurations without filter', async () => {
151
+ const tool = launchListProvider.getTool();
152
+ const result = await tool.handler('{"filter":""}');
153
+ expect(result).to.be.a('string');
154
+ const configurations = JSON.parse(result as string);
155
+
156
+ expect(configurations).to.be.an('array');
157
+ expect(configurations).to.have.lengthOf(3);
158
+ expect(configurations).to.include('Node.js Debug');
159
+ expect(configurations).to.include('Python Debug');
160
+ expect(configurations).to.include('Launch All');
161
+ });
162
+
163
+ it('should filter configurations by name', async () => {
164
+ const tool = launchListProvider.getTool();
165
+ const result = await tool.handler('{"filter":"Node"}');
166
+ expect(result).to.be.a('string');
167
+ const configurations = JSON.parse(result as string);
168
+
169
+ expect(configurations).to.be.an('array');
170
+ expect(configurations).to.have.lengthOf(1);
171
+ expect(configurations).to.include('Node.js Debug');
172
+ });
173
+
174
+ it('should handle case-insensitive filtering', async () => {
175
+ const tool = launchListProvider.getTool();
176
+ const result = await tool.handler('{"filter":"python"}');
177
+ expect(result).to.be.a('string');
178
+ const configurations = JSON.parse(result as string);
179
+
180
+ expect(configurations).to.be.an('array');
181
+ expect(configurations).to.have.lengthOf(1);
182
+ expect(configurations).to.include('Python Debug');
183
+ });
184
+ });
185
+
186
+ describe('LaunchRunnerProvider', () => {
187
+ it('should provide the correct tool metadata', () => {
188
+ const tool = launchRunnerProvider.getTool();
189
+ expect(tool.id).to.equal('runLaunchConfiguration');
190
+ expect(tool.name).to.equal('runLaunchConfiguration');
191
+ expect(tool.description).to.contain(
192
+ 'Executes a specified launch configuration'
193
+ );
194
+ expect(tool.parameters.required).to.deep.equal([
195
+ 'configurationName',
196
+ ]);
197
+ });
198
+
199
+ it('should start a valid configuration', async () => {
200
+ const tool = launchRunnerProvider.getTool();
201
+ const result = await tool.handler(
202
+ '{"configurationName":"Node.js Debug"}'
203
+ );
204
+
205
+ expect(result).to.be.a('string');
206
+ expect(result).to.contain('Node.js Debug');
207
+ expect(result).to.contain('started with session ID');
208
+ });
209
+
210
+ it('should handle unknown configuration', async () => {
211
+ const tool = launchRunnerProvider.getTool();
212
+ const result = await tool.handler(
213
+ '{"configurationName":"Unknown Config"}'
214
+ );
215
+
216
+ expect(result).to.be.a('string');
217
+ expect(result).to.contain('Did not find a launch configuration');
218
+ expect(result).to.contain('Unknown Config');
219
+ });
220
+
221
+ it('should handle compound configurations', async () => {
222
+ const tool = launchRunnerProvider.getTool();
223
+ const result = await tool.handler(
224
+ '{"configurationName":"Launch All"}'
225
+ );
226
+
227
+ expect(result).to.be.a('string');
228
+ expect(result).to.contain('Compound launch configuration');
229
+ expect(result).to.contain('Launch All');
230
+ expect(result).to.contain('started successfully');
231
+ });
232
+ });
233
+
234
+ describe('LaunchStopProvider', () => {
235
+ it('should provide the correct tool metadata', () => {
236
+ const tool = launchStopProvider.getTool();
237
+ expect(tool.id).to.equal('stopLaunchConfiguration');
238
+ expect(tool.name).to.equal('stopLaunchConfiguration');
239
+ expect(tool.description).to.contain(
240
+ 'Stops an active launch configuration'
241
+ );
242
+ expect(tool.parameters.required).to.deep.equal([]);
243
+ });
244
+
245
+ it('should stop current session when no configuration name provided', async () => {
246
+ (
247
+ mockDebugSessionManager as { currentSession: unknown }
248
+ ).currentSession = {
249
+ id: 'current-session',
250
+ configuration: { name: 'Current Config' },
251
+ };
252
+
253
+ const tool = launchStopProvider.getTool();
254
+ const result = await tool.handler('{}');
255
+
256
+ expect(result).to.be.a('string');
257
+ expect(result).to.contain(
258
+ 'Successfully stopped current debug session'
259
+ );
260
+ expect(result).to.contain('Current Config');
261
+ });
262
+
263
+ it('should handle no active session', async () => {
264
+ (
265
+ mockDebugSessionManager as { currentSession: unknown }
266
+ ).currentSession = undefined;
267
+
268
+ const tool = launchStopProvider.getTool();
269
+ const result = await tool.handler('{}');
270
+
271
+ expect(result).to.be.a('string');
272
+ expect(result).to.contain('No active debug session to stop');
273
+ });
274
+
275
+ it('should stop specific session by name', async () => {
276
+ Object.defineProperty(mockDebugSessionManager, 'sessions', {
277
+ value: [
278
+ {
279
+ id: 'session-1',
280
+ configuration: { name: 'Node.js Debug' },
281
+ },
282
+ {
283
+ id: 'session-2',
284
+ configuration: { name: 'Python Debug' },
285
+ },
286
+ ],
287
+ writable: true,
288
+ configurable: true,
289
+ });
290
+
291
+ const tool = launchStopProvider.getTool();
292
+ const result = await tool.handler(
293
+ '{"configurationName":"Node.js Debug"}'
294
+ );
295
+
296
+ expect(result).to.be.a('string');
297
+ expect(result).to.contain(
298
+ 'Successfully stopped launch configuration'
299
+ );
300
+ expect(result).to.contain('Node.js Debug');
301
+ });
302
+
303
+ it('should handle session not found by name', async () => {
304
+ Object.defineProperty(mockDebugSessionManager, 'sessions', {
305
+ value: [],
306
+ writable: true,
307
+ configurable: true,
308
+ });
309
+
310
+ const tool = launchStopProvider.getTool();
311
+ const result = await tool.handler(
312
+ '{"configurationName":"Unknown Config"}'
313
+ );
314
+
315
+ expect(result).to.be.a('string');
316
+ expect(result).to.contain('No active session found');
317
+ expect(result).to.contain('Unknown Config');
318
+ });
319
+ });
320
+ });
@@ -0,0 +1,231 @@
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
+
17
+ import { ToolProvider, ToolRequest } from '@theia/ai-core';
18
+ import { inject, injectable } from '@theia/core/shared/inversify';
19
+ import { DebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager';
20
+ import { DebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
21
+ import { DebugSessionOptions } from '@theia/debug/lib/browser/debug-session-options';
22
+ import { DebugSession } from '@theia/debug/lib/browser/debug-session';
23
+ import { MutableChatRequestModel } from '@theia/ai-chat';
24
+ import { CancellationToken } from '@theia/core';
25
+ import {
26
+ LIST_LAUNCH_CONFIGURATIONS_FUNCTION_ID,
27
+ RUN_LAUNCH_CONFIGURATION_FUNCTION_ID,
28
+ STOP_LAUNCH_CONFIGURATION_FUNCTION_ID
29
+ } from '../common/workspace-functions';
30
+
31
+ @injectable()
32
+ export class LaunchListProvider implements ToolProvider {
33
+
34
+ @inject(DebugConfigurationManager)
35
+ protected readonly debugConfigurationManager: DebugConfigurationManager;
36
+
37
+ getTool(): ToolRequest {
38
+ return {
39
+ id: LIST_LAUNCH_CONFIGURATIONS_FUNCTION_ID,
40
+ name: LIST_LAUNCH_CONFIGURATIONS_FUNCTION_ID,
41
+ description: 'Lists available launch configurations in the workspace. Launch configurations can be filtered by name.',
42
+ parameters: {
43
+ type: 'object',
44
+ properties: {
45
+ filter: {
46
+ type: 'string',
47
+ description: 'Filter to apply on launch configuration names (empty string to retrieve all configurations).'
48
+ }
49
+ },
50
+ required: ['filter']
51
+ },
52
+ handler: async (argString: string) => {
53
+ const filterArgs: { filter: string } = JSON.parse(argString);
54
+ const configurations = await this.getAvailableLaunchConfigurations(filterArgs.filter);
55
+ return JSON.stringify(configurations);
56
+ }
57
+ };
58
+ }
59
+
60
+ private async getAvailableLaunchConfigurations(filter: string = ''): Promise<string[]> {
61
+ await this.debugConfigurationManager.load();
62
+ const configurations: string[] = [];
63
+
64
+ for (const options of this.debugConfigurationManager.all) {
65
+ const name = this.getDisplayName(options);
66
+ if (name.toLowerCase().includes(filter.toLowerCase())) {
67
+ configurations.push(name);
68
+ }
69
+ }
70
+
71
+ return configurations;
72
+ }
73
+
74
+ private getDisplayName(options: DebugSessionOptions): string {
75
+ if (DebugSessionOptions.isConfiguration(options)) {
76
+ return options.configuration.name;
77
+ } else if (DebugSessionOptions.isCompound(options)) {
78
+ return options.compound.name;
79
+ }
80
+ return 'Unnamed Configuration';
81
+ }
82
+ }
83
+
84
+ @injectable()
85
+ export class LaunchRunnerProvider implements ToolProvider {
86
+
87
+ @inject(DebugConfigurationManager)
88
+ protected readonly debugConfigurationManager: DebugConfigurationManager;
89
+
90
+ @inject(DebugSessionManager)
91
+ protected readonly debugSessionManager: DebugSessionManager;
92
+
93
+ getTool(): ToolRequest {
94
+ return {
95
+ id: RUN_LAUNCH_CONFIGURATION_FUNCTION_ID,
96
+ name: RUN_LAUNCH_CONFIGURATION_FUNCTION_ID,
97
+ description: 'Executes a specified launch configuration to start debugging.',
98
+ parameters: {
99
+ type: 'object',
100
+ properties: {
101
+ configurationName: {
102
+ type: 'string',
103
+ description: 'The name of the launch configuration to execute.'
104
+ }
105
+ },
106
+ required: ['configurationName']
107
+ },
108
+ handler: async (argString: string, ctx: MutableChatRequestModel) => this.handleRunLaunchConfiguration(argString, ctx?.response?.cancellationToken)
109
+ };
110
+ }
111
+
112
+ private async handleRunLaunchConfiguration(argString: string, cancellationToken?: CancellationToken): Promise<string> {
113
+ try {
114
+ const args: { configurationName: string } = JSON.parse(argString);
115
+
116
+ await this.debugConfigurationManager.load();
117
+
118
+ const options = this.findConfigurationByName(args.configurationName);
119
+ if (!options) {
120
+ return `Did not find a launch configuration for the name: '${args.configurationName}'`;
121
+ }
122
+
123
+ const session = await this.debugSessionManager.start(options);
124
+
125
+ if (!session) {
126
+ return `Failed to start launch configuration '${args.configurationName}'`;
127
+ }
128
+
129
+ if (cancellationToken && typeof session !== 'boolean') {
130
+ cancellationToken.onCancellationRequested(() => {
131
+ this.debugSessionManager.terminateSession(session);
132
+ });
133
+ }
134
+
135
+ const sessionInfo = typeof session === 'boolean'
136
+ ? `Compound launch configuration '${args.configurationName}' started successfully`
137
+ : `Launch configuration '${args.configurationName}' started with session ID: ${session.id}`;
138
+
139
+ return sessionInfo;
140
+
141
+ } catch (error) {
142
+ return JSON.stringify({
143
+ success: false,
144
+ message: error instanceof Error ? error.message : 'Failed to run launch configuration'
145
+ });
146
+ }
147
+ }
148
+
149
+ private findConfigurationByName(name: string): DebugSessionOptions | undefined {
150
+ for (const options of this.debugConfigurationManager.all) {
151
+ const displayName = this.getDisplayName(options);
152
+ if (displayName === name) {
153
+ return options;
154
+ }
155
+ }
156
+ return undefined;
157
+ }
158
+
159
+ private getDisplayName(options: DebugSessionOptions): string {
160
+ if (DebugSessionOptions.isConfiguration(options)) {
161
+ return options.configuration.name;
162
+ } else if (DebugSessionOptions.isCompound(options)) {
163
+ return options.compound.name;
164
+ }
165
+ return 'Unnamed Configuration';
166
+ }
167
+ }
168
+
169
+ @injectable()
170
+ export class LaunchStopProvider implements ToolProvider {
171
+
172
+ @inject(DebugSessionManager)
173
+ protected readonly debugSessionManager: DebugSessionManager;
174
+
175
+ getTool(): ToolRequest {
176
+ return {
177
+ id: STOP_LAUNCH_CONFIGURATION_FUNCTION_ID,
178
+ name: STOP_LAUNCH_CONFIGURATION_FUNCTION_ID,
179
+ description: 'Stops an active launch configuration or debug session.',
180
+ parameters: {
181
+ type: 'object',
182
+ properties: {
183
+ configurationName: {
184
+ type: 'string',
185
+ description: 'The name of the launch configuration to stop. If not provided, stops the current active session.'
186
+ }
187
+ },
188
+ required: []
189
+ },
190
+ handler: async (argString: string) => this.handleStopLaunchConfiguration(argString)
191
+ };
192
+ }
193
+
194
+ private async handleStopLaunchConfiguration(argString: string): Promise<string> {
195
+ try {
196
+ const args: { configurationName?: string } = JSON.parse(argString);
197
+
198
+ if (args.configurationName) {
199
+ // Find and stop specific session by configuration name
200
+ const session = this.findSessionByConfigurationName(args.configurationName);
201
+ if (!session) {
202
+ return `No active session found for launch configuration: '${args.configurationName}'`;
203
+ }
204
+
205
+ await this.debugSessionManager.terminateSession(session);
206
+ return `Successfully stopped launch configuration: '${args.configurationName}'`;
207
+ } else {
208
+ // Stop current active session
209
+ const currentSession = this.debugSessionManager.currentSession;
210
+ if (!currentSession) {
211
+ return 'No active debug session to stop';
212
+ }
213
+
214
+ await this.debugSessionManager.terminateSession(currentSession);
215
+ return `Successfully stopped current debug session: '${currentSession.configuration.name}'`;
216
+ }
217
+
218
+ } catch (error) {
219
+ return JSON.stringify({
220
+ success: false,
221
+ message: error instanceof Error ? error.message : 'Failed to stop launch configuration'
222
+ });
223
+ }
224
+ }
225
+
226
+ private findSessionByConfigurationName(configurationName: string): DebugSession | undefined {
227
+ return this.debugSessionManager.sessions.find(
228
+ session => session.configuration.name === configurationName
229
+ );
230
+ }
231
+ }