@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
@@ -1169,7 +1169,7 @@
1169
1169
  display: flex;
1170
1170
  align-items: center;
1171
1171
  gap: var(--theia-ui-padding);
1172
- padding: var(--theia-ui-padding) calc(var(--theia-ui-padding) * 2);
1172
+ padding: var(--theia-ui-padding);
1173
1173
  border-radius: 3px;
1174
1174
  cursor: pointer;
1175
1175
  outline: none;
@@ -1187,13 +1187,20 @@
1187
1187
  }
1188
1188
 
1189
1189
  .theia-chat-session-item-icon-col {
1190
- position: relative;
1191
1190
  display: inline-flex;
1192
1191
  align-items: center;
1193
1192
  gap: calc(var(--theia-ui-padding) / 2);
1194
1193
  flex-shrink: 0;
1195
1194
  }
1196
1195
 
1196
+ /* Positioning context for the unread/attention badges so they anchor to the status icon itself
1197
+ rather than to the whole column (which now also holds the expand toggle to the left). */
1198
+ .theia-chat-session-item-status-icon {
1199
+ position: relative;
1200
+ display: inline-flex;
1201
+ align-items: center;
1202
+ }
1203
+
1197
1204
  .theia-chat-session-item-unread-dot,
1198
1205
  .theia-chat-session-item-attention-dot {
1199
1206
  position: absolute;
@@ -1244,11 +1251,57 @@
1244
1251
  foreground so they stay readable on the highlighted background. */
1245
1252
  .theia-chat-session-item:focus .theia-chat-session-item-agent-icon,
1246
1253
  .theia-chat-session-item:focus .theia-chat-session-item-archive-icon,
1254
+ .theia-chat-session-item:focus .theia-chat-session-item-expand-icon,
1247
1255
  .theia-chat-session-item:focus-within .theia-chat-session-item-agent-icon,
1248
- .theia-chat-session-item:focus-within .theia-chat-session-item-archive-icon {
1256
+ .theia-chat-session-item:focus-within .theia-chat-session-item-archive-icon,
1257
+ .theia-chat-session-item:focus-within .theia-chat-session-item-expand-icon {
1249
1258
  color: inherit;
1250
1259
  }
1251
1260
 
1261
+ /* Expand/collapse toggle shown next to the agent icon on parent sessions.
1262
+ Non-parent rows render a same-sized placeholder so agent icons stay aligned. */
1263
+ .theia-chat-session-item-expand-icon {
1264
+ display: inline-flex;
1265
+ align-items: center;
1266
+ justify-content: center;
1267
+ box-sizing: content-box;
1268
+ width: var(--theia-ui-font-size0);
1269
+ padding: calc(var(--theia-ui-padding) / 2);
1270
+ border-radius: 3px;
1271
+ color: var(--theia-descriptionForeground);
1272
+ font-size: var(--theia-ui-font-size0);
1273
+ outline: none;
1274
+ }
1275
+
1276
+ .theia-chat-session-item-expand-icon:not(.theia-chat-session-item-expand-placeholder) {
1277
+ cursor: pointer;
1278
+ }
1279
+
1280
+ .theia-chat-session-item-expand-icon:not(.theia-chat-session-item-expand-placeholder):hover {
1281
+ color: var(--theia-icon-foreground);
1282
+ background-color: var(--theia-toolbar-hoverBackground, var(--theia-list-hoverBackground));
1283
+ }
1284
+
1285
+ /* Only show a focus ring for keyboard focus, not on pointer clicks. */
1286
+ .theia-chat-session-item-expand-icon:focus-visible {
1287
+ outline: 1px solid var(--theia-focusBorder);
1288
+ }
1289
+
1290
+ /* The placeholder only reserves layout space and must not be interactive. */
1291
+ .theia-chat-session-item-expand-placeholder {
1292
+ visibility: hidden;
1293
+ pointer-events: none;
1294
+ }
1295
+
1296
+ /* Child session indentation */
1297
+ .theia-chat-session-item-child {
1298
+ padding-left: calc(var(--tree-indent, 0px) + var(--theia-ui-padding) * 3);
1299
+ }
1300
+
1301
+ .theia-chat-session-item-child .theia-chat-session-item-content {
1302
+ font-size: calc(var(--theia-ui-font-size1) * 0.95);
1303
+ }
1304
+
1252
1305
  .theia-chat-session-item-content {
1253
1306
  flex: 1;
1254
1307
  min-width: 0;
@@ -2170,3 +2223,97 @@
2170
2223
  outline: 2px solid var(--theia-focusBorder);
2171
2224
  outline-offset: -2px;
2172
2225
  }
2226
+
2227
+ /* AI Sessions View */
2228
+ .ai-sessions-view {
2229
+ display: flex;
2230
+ flex-direction: column;
2231
+ height: 100%;
2232
+ }
2233
+
2234
+ .ai-sessions-view-content {
2235
+ flex: 1;
2236
+ overflow-y: auto;
2237
+ padding: var(--theia-ui-padding) 0;
2238
+ }
2239
+
2240
+ .ai-sessions-view-empty {
2241
+ display: flex;
2242
+ flex-direction: column;
2243
+ align-items: center;
2244
+ justify-content: center;
2245
+ height: 100%;
2246
+ color: var(--theia-descriptionForeground);
2247
+ gap: var(--theia-ui-padding);
2248
+ }
2249
+
2250
+ .ai-sessions-view-empty .codicon {
2251
+ font-size: calc(var(--theia-ui-font-size1) * 2.5);
2252
+ opacity: 0.5;
2253
+ }
2254
+
2255
+ /* Persistent banner strip rendered above the AI chat content when an AI session
2256
+ * override (e.g. --session-preference) is active. */
2257
+ .chat-banner-host {
2258
+ flex: none;
2259
+ width: 100%;
2260
+ }
2261
+
2262
+ .chat-banner-host:empty {
2263
+ display: none;
2264
+ }
2265
+
2266
+ .theia-ai-allow-all-mode-strip {
2267
+ display: flex;
2268
+ align-items: center;
2269
+ justify-content: center;
2270
+ gap: calc(var(--theia-ui-padding) * 0.75);
2271
+ padding: calc(var(--theia-ui-padding) * 0.6) calc(var(--theia-ui-padding) * 1.5);
2272
+ background-color: var(--theia-inputValidation-warningBackground);
2273
+ font-size: var(--theia-ui-font-size1);
2274
+ line-height: 1.4;
2275
+ white-space: nowrap;
2276
+ overflow: hidden;
2277
+ text-overflow: ellipsis;
2278
+ cursor: default;
2279
+ }
2280
+
2281
+ .theia-ai-allow-all-mode-strip.is-allow-all {
2282
+ background-color: var(--theia-inputValidation-errorBackground);
2283
+ }
2284
+
2285
+ .theia-ai-allow-all-mode-strip-icon {
2286
+ flex: none;
2287
+ }
2288
+
2289
+ .theia-ai-allow-all-mode-strip.is-allow-all .theia-ai-allow-all-mode-strip-icon {
2290
+ color: var(--theia-errorForeground);
2291
+ }
2292
+
2293
+ .theia-ai-allow-all-mode-strip-title {
2294
+ font-weight: 600;
2295
+ }
2296
+
2297
+ .theia-ai-allow-all-mode-strip-dismiss {
2298
+ flex: none;
2299
+ margin-left: calc(var(--theia-ui-padding) * 0.5);
2300
+ padding: 2px;
2301
+ background: transparent;
2302
+ border: none;
2303
+ border-radius: 3px;
2304
+ color: inherit;
2305
+ opacity: 0.7;
2306
+ font: inherit;
2307
+ line-height: 1;
2308
+ cursor: pointer;
2309
+ }
2310
+
2311
+ .theia-ai-allow-all-mode-strip-dismiss:hover {
2312
+ opacity: 1;
2313
+ background-color: var(--theia-toolbar-hoverBackground);
2314
+ }
2315
+
2316
+ .theia-ai-allow-all-mode-strip-dismiss:focus {
2317
+ outline: 1px solid var(--theia-focusBorder);
2318
+ outline-offset: -1px;
2319
+ }
@@ -29,8 +29,7 @@ import {
29
29
  WorkspaceFunctionScope,
30
30
  FindFilesByPattern
31
31
  } from './workspace-functions';
32
- import { ToolInvocationContext } from '@theia/ai-core';
33
- import { TrustAwarePreferenceReader } from '@theia/ai-core/lib/browser/trust-aware-preference-reader';
32
+ import { AiConfigurationService, ToolInvocationContext } from '@theia/ai-core';
34
33
  import { Container } from '@theia/core/shared/inversify';
35
34
  import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
36
35
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
@@ -78,11 +77,11 @@ const makeRipgrepLikeSearchService = (filesByRoot: Record<string, string[]>) =>
78
77
  });
79
78
  });
80
79
 
81
- const makeTrustAwareReader = (overrides: { [pref: string]: unknown } = {}): TrustAwarePreferenceReader => ({
80
+ const makeTrustAwareReader = (overrides: { [pref: string]: unknown } = {}): AiConfigurationService => ({
82
81
  get: <T>(name: string, fallback?: T) => (name in overrides ? overrides[name] as T : fallback),
83
82
  ready: Promise.resolve(),
84
83
  onDidChangeTrust: () => ({ dispose: () => { /* noop */ } })
85
- } as unknown as TrustAwarePreferenceReader);
84
+ } as unknown as AiConfigurationService);
86
85
 
87
86
  const makeEnvVariablesServer = (homeDirUri: string = 'file:///home/test'): EnvVariablesServer => ({
88
87
  getHomeDirUri: async () => homeDirUri,
@@ -171,7 +170,7 @@ describe('Workspace Functions Cancellation Tests', () => {
171
170
  container.bind(MonacoWorkspace).toConstantValue(mockMonacoWorkspace);
172
171
  container.bind(ProblemManager).toConstantValue(mockProblemManager);
173
172
  container.bind(MonacoTextModelService).toConstantValue(mockMonacoTextModelService);
174
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
173
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
175
174
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
176
175
  container.bind(FileSearchService).toConstantValue(makeFileSearchService());
177
176
  container.bind(WorkspaceFunctionScope).toSelf();
@@ -294,7 +293,7 @@ describe('FileContentFunction.getArgumentsShortLabel', () => {
294
293
  container.bind(FileService).toConstantValue(mockFileService);
295
294
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
296
295
  container.bind(MonacoWorkspace).toConstantValue(mockMonacoWorkspace);
297
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
296
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
298
297
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
299
298
  container.bind(WorkspaceFunctionScope).toSelf();
300
299
  container.bind(FileContentFunction).toSelf();
@@ -412,7 +411,7 @@ describe('FileContentFunction handler', () => {
412
411
  container.bind(FileService).toConstantValue(mockFileService);
413
412
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
414
413
  container.bind(MonacoWorkspace).toConstantValue(mockMonacoWorkspace);
415
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
414
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
416
415
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
417
416
  container.bind(WorkspaceFunctionScope).toSelf();
418
417
  container.bind(FileContentFunction).toSelf();
@@ -776,7 +775,7 @@ describe('FindFilesByPattern.getArgumentsShortLabel', () => {
776
775
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
777
776
  container.bind(FileService).toConstantValue(mockFileService);
778
777
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
779
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
778
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
780
779
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
781
780
  container.bind(FileSearchService).toConstantValue(makeFileSearchService());
782
781
  container.bind(WorkspaceFunctionScope).toSelf();
@@ -852,14 +851,14 @@ describe('FindFilesByPattern.findFiles', () => {
852
851
  (name === 'ai-features.workspaceFunctions.allowedExternalPaths' ? (allowedExternal as unknown as T) : fallback),
853
852
  ready: Promise.resolve(),
854
853
  onDidChangeTrust: () => ({ dispose: () => { /* noop */ } })
855
- } as unknown as TrustAwarePreferenceReader;
854
+ } as unknown as AiConfigurationService;
856
855
 
857
856
  fileSearchService = makeFileSearchService(async () => searchResults);
858
857
 
859
858
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
860
859
  container.bind(FileService).toConstantValue(mockFileService);
861
860
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
862
- container.bind(TrustAwarePreferenceReader).toConstantValue(trustAwareReader);
861
+ container.bind(AiConfigurationService).toConstantValue(trustAwareReader);
863
862
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
864
863
  container.bind(FileSearchService).toConstantValue(fileSearchService);
865
864
  container.bind(WorkspaceFunctionScope).toSelf();
@@ -996,7 +995,7 @@ describe('WorkspaceFunctionScope gitignore caching', () => {
996
995
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
997
996
  container.bind(FileService).toConstantValue(mockFileService);
998
997
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
999
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
998
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1000
999
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1001
1000
  container.bind(WorkspaceFunctionScope).toSelf();
1002
1001
 
@@ -1065,7 +1064,7 @@ describe('GetWorkspaceFileList resolves the target directory once', () => {
1065
1064
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1066
1065
  container.bind(FileService).toConstantValue(mockFileService);
1067
1066
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
1068
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1067
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1069
1068
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1070
1069
  container.bind(WorkspaceFunctionScope).toSelf();
1071
1070
  container.bind(GetWorkspaceFileList).toSelf();
@@ -1128,7 +1127,7 @@ describe('GetWorkspaceDirectoryStructure preserves empty folders', () => {
1128
1127
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1129
1128
  container.bind(FileService).toConstantValue(mockFileService);
1130
1129
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
1131
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1130
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1132
1131
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1133
1132
  container.bind(WorkspaceFunctionScope).toSelf();
1134
1133
  container.bind(GetWorkspaceDirectoryStructure).toSelf();
@@ -1194,13 +1193,13 @@ describe('FileContentFunction external paths', () => {
1194
1193
  get: <T>(_name: string, fallback?: T) => (trustedScopeOnly ? fallback : (allowedPaths as unknown as T)),
1195
1194
  ready: Promise.resolve(),
1196
1195
  onDidChangeTrust: () => ({ dispose: () => { /* noop */ } })
1197
- } as unknown as TrustAwarePreferenceReader;
1196
+ } as unknown as AiConfigurationService;
1198
1197
 
1199
1198
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1200
1199
  container.bind(FileService).toConstantValue(mockFileService);
1201
1200
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
1202
1201
  container.bind(MonacoWorkspace).toConstantValue(mockMonacoWorkspace);
1203
- container.bind(TrustAwarePreferenceReader).toConstantValue(trustAwareReader);
1202
+ container.bind(AiConfigurationService).toConstantValue(trustAwareReader);
1204
1203
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer('file:///home/test'));
1205
1204
  container.bind(WorkspaceFunctionScope).toSelf();
1206
1205
  container.bind(FileContentFunction).toSelf();
@@ -1362,12 +1361,12 @@ describe('GetWorkspaceFileList / GetWorkspaceDirectoryStructure with external pa
1362
1361
  get: <T>(_name: string, _fallback?: T) => allowedPaths as unknown as T,
1363
1362
  ready: Promise.resolve(),
1364
1363
  onDidChangeTrust: () => ({ dispose: () => { /* noop */ } })
1365
- } as unknown as TrustAwarePreferenceReader;
1364
+ } as unknown as AiConfigurationService;
1366
1365
 
1367
1366
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1368
1367
  container.bind(FileService).toConstantValue(mockFileService);
1369
1368
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
1370
- container.bind(TrustAwarePreferenceReader).toConstantValue(trustAwareReader);
1369
+ container.bind(AiConfigurationService).toConstantValue(trustAwareReader);
1371
1370
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1372
1371
  container.bind(WorkspaceFunctionScope).toSelf();
1373
1372
  container.bind(GetWorkspaceFileList).toSelf();
@@ -1452,12 +1451,12 @@ describe('FindFilesByPattern with searchRoot', () => {
1452
1451
  get: <T>(_name: string, _fallback?: T) => allowedPaths as unknown as T,
1453
1452
  ready: Promise.resolve(),
1454
1453
  onDidChangeTrust: () => ({ dispose: () => { /* noop */ } })
1455
- } as unknown as TrustAwarePreferenceReader;
1454
+ } as unknown as AiConfigurationService;
1456
1455
 
1457
1456
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1458
1457
  container.bind(FileService).toConstantValue(mockFileService);
1459
1458
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
1460
- container.bind(TrustAwarePreferenceReader).toConstantValue(trustAwareReader);
1459
+ container.bind(AiConfigurationService).toConstantValue(trustAwareReader);
1461
1460
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1462
1461
  container.bind(FileSearchService).toConstantValue(makeRipgrepLikeSearchService(FILES_BY_ROOT));
1463
1462
  container.bind(WorkspaceFunctionScope).toSelf();
@@ -1547,13 +1546,13 @@ describe('WorkspaceFunctionScope path-traversal hardening', () => {
1547
1546
  get: <T>(name: string, fallback?: T) => trustAwareGet<T>(name, fallback),
1548
1547
  get ready(): Promise<void> { return trustReady; },
1549
1548
  onDidChangeTrust: () => ({ dispose: () => { /* noop */ } })
1550
- } as unknown as TrustAwarePreferenceReader;
1549
+ } as unknown as AiConfigurationService;
1551
1550
 
1552
1551
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1553
1552
  container.bind(FileService).toConstantValue(mockFileService);
1554
1553
  container.bind(PreferenceService).toConstantValue(mockPreferenceService);
1555
1554
  container.bind(MonacoWorkspace).toConstantValue(mockMonacoWorkspace);
1556
- container.bind(TrustAwarePreferenceReader).toConstantValue(trustAwareReader);
1555
+ container.bind(AiConfigurationService).toConstantValue(trustAwareReader);
1557
1556
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer('file:///home/test'));
1558
1557
  container.bind(WorkspaceFunctionScope).toSelf();
1559
1558
  container.bind(FileContentFunction).toSelf();
@@ -1617,9 +1616,9 @@ describe('WorkspaceFunctionScope path-traversal hardening', () => {
1617
1616
  expect(parsed.error).to.include('not allowed');
1618
1617
  });
1619
1618
 
1620
- // Item 7 — getAllowedExternalUris must await TrustAwarePreferenceReader.ready
1619
+ // Item 7 — getAllowedExternalUris must await AiConfigurationService.ready
1621
1620
  // so that preference reads see the resolved trust state.
1622
- it('awaits TrustAwarePreferenceReader.ready before reading the allow-list', async () => {
1621
+ it('awaits AiConfigurationService.ready before reading the allow-list', async () => {
1623
1622
  let preferenceVisible = false;
1624
1623
  let resolveReady: () => void = () => { /* noop */ };
1625
1624
  trustReady = new Promise<void>(r => { resolveReady = r; });
@@ -1727,7 +1726,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1727
1726
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1728
1727
  container.bind(FileService).toConstantValue({} as FileService);
1729
1728
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1730
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1729
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1731
1730
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1732
1731
  container.bind(WorkspaceFunctionScope).toSelf();
1733
1732
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -1750,7 +1749,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1750
1749
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1751
1750
  container.bind(FileService).toConstantValue({} as FileService);
1752
1751
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1753
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1752
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1754
1753
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1755
1754
  container.bind(WorkspaceFunctionScope).toSelf();
1756
1755
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -1774,7 +1773,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1774
1773
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1775
1774
  container.bind(FileService).toConstantValue({} as FileService);
1776
1775
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1777
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1776
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1778
1777
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1779
1778
  container.bind(WorkspaceFunctionScope).toSelf();
1780
1779
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -1797,7 +1796,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1797
1796
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1798
1797
  container.bind(FileService).toConstantValue({} as FileService);
1799
1798
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1800
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1799
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1801
1800
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1802
1801
  container.bind(WorkspaceFunctionScope).toSelf();
1803
1802
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -1819,7 +1818,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1819
1818
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1820
1819
  container.bind(FileService).toConstantValue({} as FileService);
1821
1820
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1822
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1821
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1823
1822
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1824
1823
  container.bind(WorkspaceFunctionScope).toSelf();
1825
1824
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -1840,7 +1839,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1840
1839
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1841
1840
  container.bind(FileService).toConstantValue({} as FileService);
1842
1841
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1843
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1842
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1844
1843
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1845
1844
  container.bind(WorkspaceFunctionScope).toSelf();
1846
1845
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -1859,7 +1858,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1859
1858
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1860
1859
  container.bind(FileService).toConstantValue({} as FileService);
1861
1860
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1862
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1861
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1863
1862
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1864
1863
  container.bind(WorkspaceFunctionScope).toSelf();
1865
1864
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -1881,7 +1880,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
1881
1880
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
1882
1881
  container.bind(FileService).toConstantValue({} as FileService);
1883
1882
  container.bind(PreferenceService).toConstantValue({ get: () => false });
1884
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
1883
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
1885
1884
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
1886
1885
  container.bind(WorkspaceFunctionScope).toSelf();
1887
1886
  return container.get(WorkspaceFunctionScope);
@@ -2053,7 +2052,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
2053
2052
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceServiceA);
2054
2053
  container.bind(FileService).toConstantValue({} as FileService);
2055
2054
  container.bind(PreferenceService).toConstantValue({ get: () => false });
2056
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
2055
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
2057
2056
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
2058
2057
  container.bind(WorkspaceFunctionScope).toSelf();
2059
2058
  const scopeA = container.get(WorkspaceFunctionScope);
@@ -2072,7 +2071,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
2072
2071
  container2.bind(WorkspaceService).toConstantValue(mockWorkspaceServiceB);
2073
2072
  container2.bind(FileService).toConstantValue({} as FileService);
2074
2073
  container2.bind(PreferenceService).toConstantValue({ get: () => false });
2075
- container2.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
2074
+ container2.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
2076
2075
  container2.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
2077
2076
  container2.bind(WorkspaceFunctionScope).toSelf();
2078
2077
  const scopeB = container2.get(WorkspaceFunctionScope);
@@ -2100,7 +2099,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
2100
2099
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
2101
2100
  container.bind(FileService).toConstantValue({} as FileService);
2102
2101
  container.bind(PreferenceService).toConstantValue({ get: () => false });
2103
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
2102
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
2104
2103
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
2105
2104
  container.bind(WorkspaceFunctionScope).toSelf();
2106
2105
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -2127,7 +2126,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
2127
2126
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
2128
2127
  container.bind(FileService).toConstantValue({} as FileService);
2129
2128
  container.bind(PreferenceService).toConstantValue({ get: () => false });
2130
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
2129
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
2131
2130
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
2132
2131
  container.bind(WorkspaceFunctionScope).toSelf();
2133
2132
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -2151,7 +2150,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
2151
2150
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
2152
2151
  container.bind(FileService).toConstantValue({} as FileService);
2153
2152
  container.bind(PreferenceService).toConstantValue({ get: () => false });
2154
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
2153
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
2155
2154
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
2156
2155
  container.bind(WorkspaceFunctionScope).toSelf();
2157
2156
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -2175,7 +2174,7 @@ describe('WorkspaceFunctionScope Multi-Root Tests', () => {
2175
2174
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
2176
2175
  container.bind(FileService).toConstantValue({} as FileService);
2177
2176
  container.bind(PreferenceService).toConstantValue({ get: () => false });
2178
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
2177
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
2179
2178
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
2180
2179
  container.bind(WorkspaceFunctionScope).toSelf();
2181
2180
  workspaceScope = container.get(WorkspaceFunctionScope);
@@ -13,8 +13,7 @@
13
13
  //
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
- import { ToolInvocationContext, ToolProvider, ToolRequest } from '@theia/ai-core';
17
- import { TrustAwarePreferenceReader } from '@theia/ai-core/lib/browser/trust-aware-preference-reader';
16
+ import { AiConfigurationService, ToolInvocationContext, ToolProvider, ToolRequest } from '@theia/ai-core';
18
17
  import { CancellationToken, Disposable, OS, PreferenceService, URI, Path } from '@theia/core';
19
18
  import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
20
19
  import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
@@ -54,8 +53,8 @@ export class WorkspaceFunctionScope {
54
53
  @inject(PreferenceService)
55
54
  protected readonly preferences: PreferenceService;
56
55
 
57
- @inject(TrustAwarePreferenceReader)
58
- protected readonly trustAwarePreferences: TrustAwarePreferenceReader;
56
+ @inject(AiConfigurationService)
57
+ protected readonly aiConfiguration: AiConfigurationService;
59
58
 
60
59
  @inject(EnvVariablesServer)
61
60
  protected readonly envVariablesServer: EnvVariablesServer;
@@ -379,15 +378,15 @@ export class WorkspaceFunctionScope {
379
378
 
380
379
  /**
381
380
  * Resolves the configured external allow-list to URIs. Reads via the
382
- * trust-aware preference reader so workspace-scoped overrides are dropped
383
- * when the workspace is untrusted. Awaits the reader's `ready` promise so
384
- * that the trust state is resolved before the first preference read.
381
+ * trust-aware {@link AiConfigurationService} so workspace-scoped overrides are
382
+ * dropped when the workspace is untrusted. Awaits the service's `ready` promise
383
+ * so that the trust state is resolved before the first preference read.
385
384
  * Non-string entries, blanks, and entries that don't parse to a `file://`
386
385
  * URI are filtered out; URIs are returned in normalized form.
387
386
  */
388
387
  async getAllowedExternalUris(resourceUri?: string): Promise<URI[]> {
389
- await this.trustAwarePreferences.ready;
390
- const raw = this.trustAwarePreferences.get<string[]>(ALLOWED_EXTERNAL_PATHS_PREF, [], resourceUri) ?? [];
388
+ await this.aiConfiguration.ready;
389
+ const raw = this.aiConfiguration.get<string[]>(ALLOWED_EXTERNAL_PATHS_PREF, [], resourceUri) ?? [];
391
390
  const result: URI[] = [];
392
391
  for (const entry of raw) {
393
392
  if (typeof entry !== 'string') {
@@ -35,16 +35,16 @@ import { DebugConfiguration } from '@theia/debug/lib/common/debug-common';
35
35
  import { DebugCompound } from '@theia/debug/lib/common/debug-compound';
36
36
  import { DebugSession } from '@theia/debug/lib/browser/debug-session';
37
37
  import { WorkspaceFunctionScope } from './workspace-functions';
38
- import { TrustAwarePreferenceReader } from '@theia/ai-core/lib/browser/trust-aware-preference-reader';
38
+ import { AiConfigurationService } from '@theia/ai-core';
39
39
  import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
40
40
  import { WorkspaceService } from '@theia/workspace/lib/browser';
41
41
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
42
42
 
43
- const makeTrustAwareReader = (): TrustAwarePreferenceReader => ({
43
+ const makeTrustAwareReader = (): AiConfigurationService => ({
44
44
  get: <T>(_name: string, fallback?: T) => fallback,
45
45
  ready: Promise.resolve(),
46
46
  onDidChangeTrust: () => ({ dispose: () => { } })
47
- } as unknown as TrustAwarePreferenceReader);
47
+ } as unknown as AiConfigurationService);
48
48
 
49
49
  const makeEnvVariablesServer = (): EnvVariablesServer => ({
50
50
  getHomeDirUri: async () => 'file:///home/test',
@@ -88,7 +88,7 @@ describe('Launch Management Tool Providers', () => {
88
88
  container.bind(WorkspaceService).toConstantValue(mockWorkspaceService);
89
89
  container.bind(FileService).toConstantValue({} as FileService);
90
90
  container.bind(PreferenceService).toConstantValue({ get: () => false } as unknown as PreferenceService);
91
- container.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
91
+ container.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
92
92
  container.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
93
93
  container.bind(WorkspaceFunctionScope).toSelf();
94
94
 
@@ -396,7 +396,7 @@ describe('Launch Management Tool Providers', () => {
396
396
  multiRootContainer.bind(WorkspaceService).toConstantValue(multiRootWorkspaceService);
397
397
  multiRootContainer.bind(FileService).toConstantValue({} as FileService);
398
398
  multiRootContainer.bind(PreferenceService).toConstantValue({ get: () => false } as unknown as PreferenceService);
399
- multiRootContainer.bind(TrustAwarePreferenceReader).toConstantValue(makeTrustAwareReader());
399
+ multiRootContainer.bind(AiConfigurationService).toConstantValue(makeTrustAwareReader());
400
400
  multiRootContainer.bind(EnvVariablesServer).toConstantValue(makeEnvVariablesServer());
401
401
  multiRootContainer.bind(WorkspaceFunctionScope).toSelf();
402
402