@theia/ai-ide 1.74.0-next.8 → 1.74.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 (96) hide show
  1. package/lib/browser/ai-allow-all-mode-chat-banner.d.ts +68 -0
  2. package/lib/browser/ai-allow-all-mode-chat-banner.d.ts.map +1 -0
  3. package/lib/browser/ai-allow-all-mode-chat-banner.js +184 -0
  4. package/lib/browser/ai-allow-all-mode-chat-banner.js.map +1 -0
  5. package/lib/browser/ai-allow-all-mode-chat-banner.spec.d.ts +2 -0
  6. package/lib/browser/ai-allow-all-mode-chat-banner.spec.d.ts.map +1 -0
  7. package/lib/browser/ai-allow-all-mode-chat-banner.spec.js +170 -0
  8. package/lib/browser/ai-allow-all-mode-chat-banner.spec.js.map +1 -0
  9. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +3 -4
  10. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +1 -1
  11. package/lib/browser/ai-configuration/tools-configuration-widget.js +17 -10
  12. package/lib/browser/ai-configuration/tools-configuration-widget.js.map +1 -1
  13. package/lib/browser/ai-first-perspective-contribution.d.ts +6 -0
  14. package/lib/browser/ai-first-perspective-contribution.d.ts.map +1 -0
  15. package/lib/browser/ai-first-perspective-contribution.js +50 -0
  16. package/lib/browser/ai-first-perspective-contribution.js.map +1 -0
  17. package/lib/browser/ai-sessions-view-contribution.d.ts +13 -0
  18. package/lib/browser/ai-sessions-view-contribution.d.ts.map +1 -0
  19. package/lib/browser/ai-sessions-view-contribution.js +69 -0
  20. package/lib/browser/ai-sessions-view-contribution.js.map +1 -0
  21. package/lib/browser/ai-sessions-widget.d.ts +27 -0
  22. package/lib/browser/ai-sessions-widget.d.ts.map +1 -0
  23. package/lib/browser/ai-sessions-widget.js +131 -0
  24. package/lib/browser/ai-sessions-widget.js.map +1 -0
  25. package/lib/browser/chat-session-item-action-contribution.js +2 -2
  26. package/lib/browser/chat-session-item-action-contribution.js.map +1 -1
  27. package/lib/browser/chat-session-item.d.ts +15 -0
  28. package/lib/browser/chat-session-item.d.ts.map +1 -1
  29. package/lib/browser/chat-session-item.js +39 -18
  30. package/lib/browser/chat-session-item.js.map +1 -1
  31. package/lib/browser/chat-session-list-components.d.ts +38 -0
  32. package/lib/browser/chat-session-list-components.d.ts.map +1 -0
  33. package/lib/browser/chat-session-list-components.js +87 -0
  34. package/lib/browser/chat-session-list-components.js.map +1 -0
  35. package/lib/browser/chat-session-list-service.d.ts +34 -0
  36. package/lib/browser/chat-session-list-service.d.ts.map +1 -0
  37. package/lib/browser/chat-session-list-service.js +251 -0
  38. package/lib/browser/chat-session-list-service.js.map +1 -0
  39. package/lib/browser/chat-session-list-service.spec.d.ts +2 -0
  40. package/lib/browser/chat-session-list-service.spec.d.ts.map +1 -0
  41. package/lib/browser/{chat-sessions-welcome-message-provider.spec.js → chat-session-list-service.spec.js} +133 -39
  42. package/lib/browser/chat-session-list-service.spec.js.map +1 -0
  43. package/lib/browser/chat-session-tooltip.d.ts +2 -2
  44. package/lib/browser/chat-session-tooltip.d.ts.map +1 -1
  45. package/lib/browser/chat-session-tooltip.js +33 -10
  46. package/lib/browser/chat-session-tooltip.js.map +1 -1
  47. package/lib/browser/chat-sessions-welcome-message-provider.d.ts +9 -35
  48. package/lib/browser/chat-sessions-welcome-message-provider.d.ts.map +1 -1
  49. package/lib/browser/chat-sessions-welcome-message-provider.js +51 -205
  50. package/lib/browser/chat-sessions-welcome-message-provider.js.map +1 -1
  51. package/lib/browser/context-file-validation-service-impl.spec.js +2 -2
  52. package/lib/browser/context-file-validation-service-impl.spec.js.map +1 -1
  53. package/lib/browser/frontend-module.d.ts.map +1 -1
  54. package/lib/browser/frontend-module.js +20 -0
  55. package/lib/browser/frontend-module.js.map +1 -1
  56. package/lib/browser/workspace-functions.d.ts +5 -6
  57. package/lib/browser/workspace-functions.d.ts.map +1 -1
  58. package/lib/browser/workspace-functions.js +24 -9
  59. package/lib/browser/workspace-functions.js.map +1 -1
  60. package/lib/browser/workspace-functions.spec.js +29 -29
  61. package/lib/browser/workspace-functions.spec.js.map +1 -1
  62. package/lib/browser/workspace-launch-provider.spec.js +3 -3
  63. package/lib/browser/workspace-launch-provider.spec.js.map +1 -1
  64. package/lib/browser/workspace-search-provider.d.ts.map +1 -1
  65. package/lib/browser/workspace-search-provider.js +28 -20
  66. package/lib/browser/workspace-search-provider.js.map +1 -1
  67. package/lib/browser/workspace-search-provider.spec.js +68 -0
  68. package/lib/browser/workspace-search-provider.spec.js.map +1 -1
  69. package/lib/browser/workspace-task-provider.spec.js +4 -4
  70. package/lib/browser/workspace-task-provider.spec.js.map +1 -1
  71. package/package.json +25 -25
  72. package/src/browser/ai-allow-all-mode-chat-banner.spec.ts +205 -0
  73. package/src/browser/ai-allow-all-mode-chat-banner.tsx +217 -0
  74. package/src/browser/ai-configuration/tools-configuration-widget.tsx +20 -13
  75. package/src/browser/ai-first-perspective-contribution.ts +48 -0
  76. package/src/browser/ai-sessions-view-contribution.ts +67 -0
  77. package/src/browser/ai-sessions-widget.tsx +151 -0
  78. package/src/browser/chat-session-item-action-contribution.ts +2 -2
  79. package/src/browser/chat-session-item.tsx +82 -27
  80. package/src/browser/chat-session-list-components.tsx +136 -0
  81. package/src/browser/{chat-sessions-welcome-message-provider.spec.ts → chat-session-list-service.spec.ts} +136 -30
  82. package/src/browser/chat-session-list-service.ts +261 -0
  83. package/src/browser/chat-session-tooltip.ts +31 -11
  84. package/src/browser/chat-sessions-welcome-message-provider.tsx +78 -268
  85. package/src/browser/context-file-validation-service-impl.spec.ts +3 -3
  86. package/src/browser/frontend-module.ts +23 -0
  87. package/src/browser/style/index.css +150 -3
  88. package/src/browser/workspace-functions.spec.ts +36 -37
  89. package/src/browser/workspace-functions.ts +8 -9
  90. package/src/browser/workspace-launch-provider.spec.ts +5 -5
  91. package/src/browser/workspace-search-provider.spec.ts +101 -0
  92. package/src/browser/workspace-search-provider.ts +34 -23
  93. package/src/browser/workspace-task-provider.spec.ts +6 -7
  94. package/lib/browser/chat-sessions-welcome-message-provider.spec.d.ts +0 -2
  95. package/lib/browser/chat-sessions-welcome-message-provider.spec.d.ts.map +0 -1
  96. package/lib/browser/chat-sessions-welcome-message-provider.spec.js.map +0 -1
@@ -15,6 +15,7 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { expect } from 'chai';
18
+ import * as sinon from 'sinon';
18
19
  import { CancellationTokenSource, PreferenceService } from '@theia/core';
19
20
  import { WorkspaceSearchProvider } from './workspace-search-provider';
20
21
  import { ToolInvocationContext } from '@theia/ai-core';
@@ -100,4 +101,104 @@ describe('Workspace Search Provider Cancellation Tests', () => {
100
101
  expect(jsonResponse.error).to.equal('Operation cancelled by user');
101
102
  });
102
103
 
104
+ it('should normalize a string fileExtensions argument into an include array without hanging', async () => {
105
+ let capturedOptions: SearchInWorkspaceOptions | undefined;
106
+ // Rebind the search service so it records the options and immediately completes the search.
107
+ container.rebind(SearchInWorkspaceService).toConstantValue({
108
+ searchWithCallback: async (
109
+ query: string,
110
+ rootUris: string[],
111
+ callbacks: SearchInWorkspaceCallbacks,
112
+ options: SearchInWorkspaceOptions
113
+ ) => {
114
+ capturedOptions = options;
115
+ callbacks.onDone?.(1);
116
+ return 1;
117
+ },
118
+ cancel: () => { }
119
+ } as unknown as SearchInWorkspaceService);
120
+
121
+ const searchProvider = container.get(WorkspaceSearchProvider);
122
+ const handler = searchProvider.getTool().handler;
123
+ // The model may emit fileExtensions as a bare string instead of an array.
124
+ const result = await handler(
125
+ JSON.stringify({ query: 'deleteSession', useRegExp: false, fileExtensions: 'spec.ts' }),
126
+ mockCtx
127
+ );
128
+
129
+ const jsonResponse = JSON.parse(result as string);
130
+ expect(jsonResponse.error).to.equal(undefined);
131
+ expect(capturedOptions?.include).to.deep.equal(['**/*.spec.ts']);
132
+ });
133
+
134
+ it('should time out instead of hanging when the search never reports completion', async () => {
135
+ // Reproduces the original hang: the backend returns a search id but onDone is never called,
136
+ // and previously the search could also never report an id at all.
137
+ container.rebind(SearchInWorkspaceService).toConstantValue({
138
+ searchWithCallback: () => new Promise<number>(() => { /* never resolves: no id, no onDone */ }),
139
+ cancel: () => { }
140
+ } as unknown as SearchInWorkspaceService);
141
+
142
+ const searchProvider = container.get(WorkspaceSearchProvider);
143
+ const handler = searchProvider.getTool().handler;
144
+
145
+ const clock = sinon.useFakeTimers();
146
+ try {
147
+ const resultPromise = handler(
148
+ JSON.stringify({ query: 'deleteSession', useRegExp: false }),
149
+ mockCtx
150
+ );
151
+ await clock.tickAsync(30000);
152
+ const jsonResponse = JSON.parse(await resultPromise as string);
153
+ expect(jsonResponse.error).to.equal('Search timed out after 30 seconds');
154
+ } finally {
155
+ clock.restore();
156
+ }
157
+ });
158
+
159
+ it('should return an error (not hang) when search setup fails', async () => {
160
+ // An empty workspace makes determineSearchRoots throw; the error must surface as a result.
161
+ container.rebind(WorkspaceFunctionScope).toConstantValue({
162
+ getRootMapping: () => new Map()
163
+ } as unknown as WorkspaceFunctionScope);
164
+
165
+ const searchProvider = container.get(WorkspaceSearchProvider);
166
+ const handler = searchProvider.getTool().handler;
167
+ const result = await handler(
168
+ JSON.stringify({ query: 'deleteSession', useRegExp: false }),
169
+ mockCtx
170
+ );
171
+
172
+ const jsonResponse = JSON.parse(result as string);
173
+ expect(jsonResponse.error).to.equal('No workspace has been opened yet');
174
+ });
175
+
176
+ it('should accept an array fileExtensions argument', async () => {
177
+ let capturedOptions: SearchInWorkspaceOptions | undefined;
178
+ container.rebind(SearchInWorkspaceService).toConstantValue({
179
+ searchWithCallback: async (
180
+ query: string,
181
+ rootUris: string[],
182
+ callbacks: SearchInWorkspaceCallbacks,
183
+ options: SearchInWorkspaceOptions
184
+ ) => {
185
+ capturedOptions = options;
186
+ callbacks.onDone?.(1);
187
+ return 1;
188
+ },
189
+ cancel: () => { }
190
+ } as unknown as SearchInWorkspaceService);
191
+
192
+ const searchProvider = container.get(WorkspaceSearchProvider);
193
+ const handler = searchProvider.getTool().handler;
194
+ const result = await handler(
195
+ JSON.stringify({ query: 'deleteSession', useRegExp: false, fileExtensions: ['ts', 'js'] }),
196
+ mockCtx
197
+ );
198
+
199
+ const jsonResponse = JSON.parse(result as string);
200
+ expect(jsonResponse.error).to.equal(undefined);
201
+ expect(capturedOptions?.include).to.deep.equal(['**/*.ts', '**/*.js']);
202
+ });
203
+
103
204
  });
@@ -117,7 +117,12 @@ export class WorkspaceSearchProvider implements ToolProvider {
117
117
 
118
118
  private async handleSearch(argString: string, cancellationToken?: CancellationToken): Promise<string> {
119
119
  try {
120
- const args: { query: string, useRegExp: boolean, fileExtensions?: string[], subDirectoryPath?: string } = JSON.parse(argString);
120
+ const args: { query: string, useRegExp: boolean, fileExtensions?: string[] | string, subDirectoryPath?: string } = JSON.parse(argString);
121
+
122
+ if (cancellationToken?.isCancellationRequested) {
123
+ return JSON.stringify({ error: 'Operation cancelled by user' });
124
+ }
125
+
121
126
  const results: SearchInWorkspaceResult[] = [];
122
127
  let expectedSearchId: number | undefined;
123
128
  let searchCompleted = false;
@@ -128,11 +133,28 @@ export class WorkspaceSearchProvider implements ToolProvider {
128
133
  searchCompleted = true;
129
134
  }
130
135
  });
131
- if (cancellationToken?.isCancellationRequested) {
132
- return JSON.stringify({ error: 'Operation cancelled by user' });
136
+
137
+ // Use one more than our actual maximum. this way we can determine if we have more results than our maximum and warn the user
138
+ const maxResultsForTheiaAPI = this.preferenceService.get<number>(SEARCH_IN_WORKSPACE_MAX_RESULTS_PREF, 30) + 1;
139
+ const options: SearchInWorkspaceOptions = {
140
+ useRegExp: args.useRegExp,
141
+ matchCase: false,
142
+ matchWholeWord: false,
143
+ maxResults: maxResultsForTheiaAPI,
144
+ };
145
+
146
+ // The model may supply fileExtensions as a single string instead of an array; normalize to an array so that `.map` never throws.
147
+ const fileExtensions = args.fileExtensions === undefined ? undefined
148
+ : Array.isArray(args.fileExtensions) ? args.fileExtensions
149
+ : [args.fileExtensions];
150
+ if (fileExtensions && fileExtensions.length > 0) {
151
+ options.include = fileExtensions.map(ext => `**/*.${ext}`);
133
152
  }
134
153
 
135
- const searchPromise = new Promise<SearchInWorkspaceResult[]>(async (resolve, reject) => {
154
+ // Resolve the search roots before starting the search so that any error is reported through the outer try/catch.
155
+ const rootUris = await this.determineSearchRoots(args.subDirectoryPath);
156
+
157
+ const searchPromise = new Promise<SearchInWorkspaceResult[]>((resolve, reject) => {
136
158
  const callbacks: SearchInWorkspaceCallbacks = {
137
159
  onResult: (id, result) => {
138
160
  if (expectedSearchId !== undefined && id !== expectedSearchId) {
@@ -163,26 +185,13 @@ export class WorkspaceSearchProvider implements ToolProvider {
163
185
  }
164
186
  };
165
187
 
166
- // Use one more than our actual maximum. this way we can determine if we have more results than our maximum and warn the user
167
- const maxResultsForTheiaAPI = this.preferenceService.get<number>(SEARCH_IN_WORKSPACE_MAX_RESULTS_PREF, 30) + 1;
168
- const options: SearchInWorkspaceOptions = {
169
- useRegExp: args.useRegExp,
170
- matchCase: false,
171
- matchWholeWord: false,
172
- maxResults: maxResultsForTheiaAPI,
173
- };
174
-
175
- if (args.fileExtensions && args.fileExtensions.length > 0) {
176
- options.include = args.fileExtensions.map(ext => `**/*.${ext}`);
177
- }
178
-
179
- await this.determineSearchRoots(args.subDirectoryPath)
180
- .then(rootUris => this.searchService.searchWithCallback(args.query, rootUris, callbacks, options))
188
+ this.searchService.searchWithCallback(args.query, rootUris, callbacks, options)
181
189
  .then(id => {
182
190
  expectedSearchId = id;
183
- cancellationToken?.onCancellationRequested(() => {
191
+ // Handle cancellation that was requested before the search id became available.
192
+ if (cancellationToken?.isCancellationRequested && !searchCompleted) {
184
193
  this.searchService.cancel(id);
185
- });
194
+ }
186
195
  })
187
196
  .catch(err => {
188
197
  searchCompleted = true;
@@ -192,8 +201,10 @@ export class WorkspaceSearchProvider implements ToolProvider {
192
201
 
193
202
  const timeoutPromise = new Promise<SearchInWorkspaceResult[]>((_, reject) => {
194
203
  setTimeout(() => {
195
- if (expectedSearchId !== undefined && !searchCompleted) {
196
- this.searchService.cancel(expectedSearchId);
204
+ if (!searchCompleted) {
205
+ if (expectedSearchId !== undefined) {
206
+ this.searchService.cancel(expectedSearchId);
207
+ }
197
208
  searchCompleted = true;
198
209
  reject(new Error('Search timed out after 30 seconds'));
199
210
  }
@@ -18,23 +18,22 @@ import { expect } from 'chai';
18
18
  import { CancellationTokenSource, PreferenceService } from '@theia/core';
19
19
  import URI from '@theia/core/lib/common/uri';
20
20
  import { GLOBAL_SCOPE_TOKEN, TaskListProvider, TaskRunnerProvider, WORKSPACE_SCOPE_TOKEN } from './workspace-task-provider';
21
- import { ToolInvocationContext } from '@theia/ai-core';
21
+ import { AiConfigurationService, ToolInvocationContext } from '@theia/ai-core';
22
22
  import { Container } from '@theia/core/shared/inversify';
23
23
  import { TaskService } from '@theia/task/lib/browser/task-service';
24
24
  import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service';
25
25
  import { TaskConfiguration, TaskInfo, TaskScope } from '@theia/task/lib/common';
26
26
  import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
27
27
  import { WorkspaceFunctionScope } from './workspace-functions';
28
- import { TrustAwarePreferenceReader } from '@theia/ai-core/lib/browser/trust-aware-preference-reader';
29
28
  import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
30
29
  import { WorkspaceService } from '@theia/workspace/lib/browser';
31
30
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
32
31
 
33
- const makeTrustAwareReader = (): TrustAwarePreferenceReader => ({
32
+ const makeTrustAwareReader = (): AiConfigurationService => ({
34
33
  get: <T>(_name: string, fallback?: T) => fallback,
35
34
  ready: Promise.resolve(),
36
35
  onDidChangeTrust: () => ({ dispose: () => { } })
37
- } as unknown as TrustAwarePreferenceReader);
36
+ } as unknown as AiConfigurationService);
38
37
 
39
38
  const makeEnvVariablesServer = (): EnvVariablesServer => ({
40
39
  getHomeDirUri: async () => 'file:///home/test',
@@ -129,7 +128,7 @@ describe('Workspace Task Provider Cancellation Tests', () => {
129
128
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
130
129
  container.bind(FileService).toConstantValue({} as FileService);
131
130
  container.bind(PreferenceService).toConstantValue({ get: () => false } as unknown as PreferenceService);
132
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
131
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
133
132
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
134
133
  container.bind(WorkspaceFunctionScope).toSelf();
135
134
  container.bind(TaskListProvider).toSelf();
@@ -362,7 +361,7 @@ describe('Workspace Task Provider Cancellation Tests', () => {
362
361
  multiRootContainer.bind(WorkspaceService).toConstantValue(multiRootWorkspaceService);
363
362
  multiRootContainer.bind(FileService).toConstantValue({} as FileService);
364
363
  multiRootContainer.bind(PreferenceService).toConstantValue({ get: () => false } as unknown as PreferenceService);
365
- multiRootContainer.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
364
+ multiRootContainer.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
366
365
  multiRootContainer.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
367
366
  multiRootContainer.bind(WorkspaceFunctionScope).toSelf();
368
367
  multiRootContainer.bind(TaskRunnerProvider).toSelf();
@@ -409,7 +408,7 @@ describe('Workspace Task Provider Cancellation Tests', () => {
409
408
  multiRootContainer.bind(WorkspaceService).toConstantValue(multiRootWorkspaceService);
410
409
  multiRootContainer.bind(FileService).toConstantValue({} as FileService);
411
410
  multiRootContainer.bind(PreferenceService).toConstantValue({ get: () => false } as unknown as PreferenceService);
412
- multiRootContainer.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
411
+ multiRootContainer.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
413
412
  multiRootContainer.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
414
413
  multiRootContainer.bind(WorkspaceFunctionScope).toSelf();
415
414
  multiRootContainer.bind(TaskRunnerProvider).toSelf();
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=chat-sessions-welcome-message-provider.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-sessions-welcome-message-provider.spec.d.ts","sourceRoot":"","sources":["../../src/browser/chat-sessions-welcome-message-provider.spec.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-sessions-welcome-message-provider.spec.js","sourceRoot":"","sources":["../../src/browser/chat-sessions-welcome-message-provider.spec.ts"],"names":[],"mappings":"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"}