@theia/ai-ide 1.67.0-next.3 → 1.67.0-next.56

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 (306) hide show
  1. package/README.md +1 -0
  2. package/package.json +21 -21
  3. package/src/browser/ai-configuration/agent-configuration-widget.tsx +3 -3
  4. package/src/browser/context-file-validation-service-impl.spec.ts +405 -0
  5. package/src/browser/context-file-validation-service-impl.ts +120 -0
  6. package/src/browser/context-functions.spec.ts +155 -1
  7. package/src/browser/context-functions.ts +40 -6
  8. package/src/browser/file-changeset-functions.spec.ts +13 -13
  9. package/src/browser/file-changeset-functions.ts +9 -9
  10. package/src/browser/frontend-module.ts +12 -4
  11. package/src/browser/ide-chat-welcome-message-provider.tsx +64 -70
  12. package/src/browser/remember-command-contribution.ts +105 -0
  13. package/src/browser/workspace-functions.ts +68 -1
  14. package/src/common/ai-ide-preferences.ts +1 -1
  15. package/src/common/coder-replace-prompt-template.ts +8 -9
  16. package/src/common/command-prompt-template.ts +5 -5
  17. package/src/common/file-changeset-function-ids.ts +15 -1
  18. package/src/common/orchestrator-chat-agent.ts +2 -2
  19. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts +0 -41
  20. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +0 -1
  21. package/lib/browser/ai-configuration/agent-configuration-widget.js +0 -333
  22. package/lib/browser/ai-configuration/agent-configuration-widget.js.map +0 -1
  23. package/lib/browser/ai-configuration/ai-configuration-service.d.ts +0 -18
  24. package/lib/browser/ai-configuration/ai-configuration-service.d.ts.map +0 -1
  25. package/lib/browser/ai-configuration/ai-configuration-service.js +0 -53
  26. package/lib/browser/ai-configuration/ai-configuration-service.js.map +0 -1
  27. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts +0 -14
  28. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts.map +0 -1
  29. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js +0 -67
  30. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js.map +0 -1
  31. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts +0 -29
  32. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts.map +0 -1
  33. package/lib/browser/ai-configuration/ai-configuration-widget.js +0 -118
  34. package/lib/browser/ai-configuration/ai-configuration-widget.js.map +0 -1
  35. package/lib/browser/ai-configuration/language-model-renderer.d.ts +0 -13
  36. package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +0 -1
  37. package/lib/browser/ai-configuration/language-model-renderer.js +0 -104
  38. package/lib/browser/ai-configuration/language-model-renderer.js.map +0 -1
  39. package/lib/browser/ai-configuration/mcp-configuration-widget.d.ts +0 -43
  40. package/lib/browser/ai-configuration/mcp-configuration-widget.d.ts.map +0 -1
  41. package/lib/browser/ai-configuration/mcp-configuration-widget.js +0 -302
  42. package/lib/browser/ai-configuration/mcp-configuration-widget.js.map +0 -1
  43. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts +0 -41
  44. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts.map +0 -1
  45. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js +0 -226
  46. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js.map +0 -1
  47. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts +0 -141
  48. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts.map +0 -1
  49. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +0 -508
  50. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +0 -1
  51. package/lib/browser/ai-configuration/template-settings-renderer.d.ts +0 -10
  52. package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +0 -1
  53. package/lib/browser/ai-configuration/template-settings-renderer.js +0 -48
  54. package/lib/browser/ai-configuration/template-settings-renderer.js.map +0 -1
  55. package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts +0 -22
  56. package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts.map +0 -1
  57. package/lib/browser/ai-configuration/token-usage-configuration-widget.js +0 -156
  58. package/lib/browser/ai-configuration/token-usage-configuration-widget.js.map +0 -1
  59. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +0 -30
  60. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +0 -1
  61. package/lib/browser/ai-configuration/tools-configuration-widget.js +0 -150
  62. package/lib/browser/ai-configuration/tools-configuration-widget.js.map +0 -1
  63. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts +0 -19
  64. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts.map +0 -1
  65. package/lib/browser/ai-configuration/variable-configuration-widget.js +0 -99
  66. package/lib/browser/ai-configuration/variable-configuration-widget.js.map +0 -1
  67. package/lib/browser/ai-ide-activation-service.d.ts +0 -18
  68. package/lib/browser/ai-ide-activation-service.d.ts.map +0 -1
  69. package/lib/browser/ai-ide-activation-service.js +0 -71
  70. package/lib/browser/ai-ide-activation-service.js.map +0 -1
  71. package/lib/browser/ai-terminal-functions.d.ts +0 -13
  72. package/lib/browser/ai-terminal-functions.d.ts.map +0 -1
  73. package/lib/browser/ai-terminal-functions.js +0 -114
  74. package/lib/browser/ai-terminal-functions.js.map +0 -1
  75. package/lib/browser/app-tester-chat-agent.d.ts +0 -35
  76. package/lib/browser/app-tester-chat-agent.d.ts.map +0 -1
  77. package/lib/browser/app-tester-chat-agent.js +0 -142
  78. package/lib/browser/app-tester-chat-agent.js.map +0 -1
  79. package/lib/browser/app-tester-chat-functions.d.ts +0 -25
  80. package/lib/browser/app-tester-chat-functions.d.ts.map +0 -1
  81. package/lib/browser/app-tester-chat-functions.js +0 -170
  82. package/lib/browser/app-tester-chat-functions.js.map +0 -1
  83. package/lib/browser/app-tester-prompt-template.d.ts +0 -6
  84. package/lib/browser/app-tester-prompt-template.d.ts.map +0 -1
  85. package/lib/browser/app-tester-prompt-template.js +0 -83
  86. package/lib/browser/app-tester-prompt-template.js.map +0 -1
  87. package/lib/browser/architect-agent.d.ts +0 -15
  88. package/lib/browser/architect-agent.d.ts.map +0 -1
  89. package/lib/browser/architect-agent.js +0 -68
  90. package/lib/browser/architect-agent.js.map +0 -1
  91. package/lib/browser/coder-agent.d.ts +0 -15
  92. package/lib/browser/coder-agent.d.ts.map +0 -1
  93. package/lib/browser/coder-agent.js +0 -81
  94. package/lib/browser/coder-agent.js.map +0 -1
  95. package/lib/browser/context-functions.d.ts +0 -14
  96. package/lib/browser/context-functions.d.ts.map +0 -1
  97. package/lib/browser/context-functions.js +0 -130
  98. package/lib/browser/context-functions.js.map +0 -1
  99. package/lib/browser/context-functions.spec.d.ts +0 -2
  100. package/lib/browser/context-functions.spec.d.ts.map +0 -1
  101. package/lib/browser/context-functions.spec.js +0 -93
  102. package/lib/browser/context-functions.spec.js.map +0 -1
  103. package/lib/browser/file-changeset-function.spec.d.ts +0 -2
  104. package/lib/browser/file-changeset-function.spec.d.ts.map +0 -1
  105. package/lib/browser/file-changeset-function.spec.js +0 -45
  106. package/lib/browser/file-changeset-function.spec.js.map +0 -1
  107. package/lib/browser/file-changeset-functions.d.ts +0 -87
  108. package/lib/browser/file-changeset-functions.d.ts.map +0 -1
  109. package/lib/browser/file-changeset-functions.js +0 -645
  110. package/lib/browser/file-changeset-functions.js.map +0 -1
  111. package/lib/browser/file-changeset-functions.spec.d.ts +0 -2
  112. package/lib/browser/file-changeset-functions.spec.d.ts.map +0 -1
  113. package/lib/browser/file-changeset-functions.spec.js +0 -179
  114. package/lib/browser/file-changeset-functions.spec.js.map +0 -1
  115. package/lib/browser/frontend-module.d.ts +0 -5
  116. package/lib/browser/frontend-module.d.ts.map +0 -1
  117. package/lib/browser/frontend-module.js +0 -214
  118. package/lib/browser/frontend-module.js.map +0 -1
  119. package/lib/browser/github-chat-agent.d.ts +0 -48
  120. package/lib/browser/github-chat-agent.d.ts.map +0 -1
  121. package/lib/browser/github-chat-agent.js +0 -222
  122. package/lib/browser/github-chat-agent.js.map +0 -1
  123. package/lib/browser/github-prompt-template.d.ts +0 -6
  124. package/lib/browser/github-prompt-template.d.ts.map +0 -1
  125. package/lib/browser/github-prompt-template.js +0 -53
  126. package/lib/browser/github-prompt-template.js.map +0 -1
  127. package/lib/browser/github-repo-variable-contribution.d.ts +0 -15
  128. package/lib/browser/github-repo-variable-contribution.d.ts.map +0 -1
  129. package/lib/browser/github-repo-variable-contribution.js +0 -82
  130. package/lib/browser/github-repo-variable-contribution.js.map +0 -1
  131. package/lib/browser/ide-chat-welcome-message-provider.d.ts +0 -11
  132. package/lib/browser/ide-chat-welcome-message-provider.d.ts.map +0 -1
  133. package/lib/browser/ide-chat-welcome-message-provider.js +0 -142
  134. package/lib/browser/ide-chat-welcome-message-provider.js.map +0 -1
  135. package/lib/browser/project-info-agent.d.ts +0 -13
  136. package/lib/browser/project-info-agent.d.ts.map +0 -1
  137. package/lib/browser/project-info-agent.js +0 -45
  138. package/lib/browser/project-info-agent.js.map +0 -1
  139. package/lib/browser/summarize-session-command-contribution.d.ts +0 -19
  140. package/lib/browser/summarize-session-command-contribution.d.ts.map +0 -1
  141. package/lib/browser/summarize-session-command-contribution.js +0 -118
  142. package/lib/browser/summarize-session-command-contribution.js.map +0 -1
  143. package/lib/browser/task-background-summary-variable.d.ts +0 -9
  144. package/lib/browser/task-background-summary-variable.d.ts.map +0 -1
  145. package/lib/browser/task-background-summary-variable.js +0 -60
  146. package/lib/browser/task-background-summary-variable.js.map +0 -1
  147. package/lib/browser/task-context-agent.d.ts +0 -13
  148. package/lib/browser/task-context-agent.d.ts.map +0 -1
  149. package/lib/browser/task-context-agent.js +0 -45
  150. package/lib/browser/task-context-agent.js.map +0 -1
  151. package/lib/browser/task-context-file-storage-service.d.ts +0 -40
  152. package/lib/browser/task-context-file-storage-service.d.ts.map +0 -1
  153. package/lib/browser/task-context-file-storage-service.js +0 -232
  154. package/lib/browser/task-context-file-storage-service.js.map +0 -1
  155. package/lib/browser/template-preference-contribution.d.ts +0 -17
  156. package/lib/browser/template-preference-contribution.d.ts.map +0 -1
  157. package/lib/browser/template-preference-contribution.js +0 -94
  158. package/lib/browser/template-preference-contribution.js.map +0 -1
  159. package/lib/browser/test/tool-provider-cancellation-test-util.spec.d.ts +0 -2
  160. package/lib/browser/test/tool-provider-cancellation-test-util.spec.d.ts.map +0 -1
  161. package/lib/browser/test/tool-provider-cancellation-test-util.spec.js +0 -52
  162. package/lib/browser/test/tool-provider-cancellation-test-util.spec.js.map +0 -1
  163. package/lib/browser/workspace-functions.d.ts +0 -75
  164. package/lib/browser/workspace-functions.d.ts.map +0 -1
  165. package/lib/browser/workspace-functions.js +0 -641
  166. package/lib/browser/workspace-functions.js.map +0 -1
  167. package/lib/browser/workspace-functions.spec.d.ts +0 -2
  168. package/lib/browser/workspace-functions.spec.d.ts.map +0 -1
  169. package/lib/browser/workspace-functions.spec.js +0 -161
  170. package/lib/browser/workspace-functions.spec.js.map +0 -1
  171. package/lib/browser/workspace-launch-provider.d.ts +0 -24
  172. package/lib/browser/workspace-launch-provider.d.ts.map +0 -1
  173. package/lib/browser/workspace-launch-provider.js +0 -216
  174. package/lib/browser/workspace-launch-provider.js.map +0 -1
  175. package/lib/browser/workspace-launch-provider.spec.d.ts +0 -2
  176. package/lib/browser/workspace-launch-provider.spec.d.ts.map +0 -1
  177. package/lib/browser/workspace-launch-provider.spec.js +0 -245
  178. package/lib/browser/workspace-launch-provider.spec.js.map +0 -1
  179. package/lib/browser/workspace-search-provider.d.ts +0 -15
  180. package/lib/browser/workspace-search-provider.d.ts.map +0 -1
  181. package/lib/browser/workspace-search-provider.js +0 -204
  182. package/lib/browser/workspace-search-provider.js.map +0 -1
  183. package/lib/browser/workspace-search-provider.spec.d.ts +0 -2
  184. package/lib/browser/workspace-search-provider.spec.d.ts.map +0 -1
  185. package/lib/browser/workspace-search-provider.spec.js +0 -82
  186. package/lib/browser/workspace-search-provider.spec.js.map +0 -1
  187. package/lib/browser/workspace-task-provider.d.ts +0 -15
  188. package/lib/browser/workspace-task-provider.d.ts.map +0 -1
  189. package/lib/browser/workspace-task-provider.js +0 -138
  190. package/lib/browser/workspace-task-provider.js.map +0 -1
  191. package/lib/browser/workspace-task-provider.spec.d.ts +0 -2
  192. package/lib/browser/workspace-task-provider.spec.d.ts.map +0 -1
  193. package/lib/browser/workspace-task-provider.spec.js +0 -109
  194. package/lib/browser/workspace-task-provider.spec.js.map +0 -1
  195. package/lib/common/ai-configuration-preferences.d.ts +0 -8
  196. package/lib/common/ai-configuration-preferences.d.ts.map +0 -1
  197. package/lib/common/ai-configuration-preferences.js +0 -41
  198. package/lib/common/ai-configuration-preferences.js.map +0 -1
  199. package/lib/common/ai-ide-preferences.d.ts +0 -5
  200. package/lib/common/ai-ide-preferences.d.ts.map +0 -1
  201. package/lib/common/ai-ide-preferences.js +0 -53
  202. package/lib/common/ai-ide-preferences.js.map +0 -1
  203. package/lib/common/ai-terminal-functions.d.ts +0 -2
  204. package/lib/common/ai-terminal-functions.d.ts.map +0 -1
  205. package/lib/common/ai-terminal-functions.js +0 -20
  206. package/lib/common/ai-terminal-functions.js.map +0 -1
  207. package/lib/common/app-tester-chat-functions.d.ts +0 -5
  208. package/lib/common/app-tester-chat-functions.d.ts.map +0 -1
  209. package/lib/common/app-tester-chat-functions.js +0 -23
  210. package/lib/common/app-tester-chat-functions.js.map +0 -1
  211. package/lib/common/architect-prompt-template.d.ts +0 -3
  212. package/lib/common/architect-prompt-template.d.ts.map +0 -1
  213. package/lib/common/architect-prompt-template.js +0 -81
  214. package/lib/common/architect-prompt-template.js.map +0 -1
  215. package/lib/common/browser-automation-protocol.d.ts +0 -15
  216. package/lib/common/browser-automation-protocol.d.ts.map +0 -1
  217. package/lib/common/browser-automation-protocol.js +0 -22
  218. package/lib/common/browser-automation-protocol.js.map +0 -1
  219. package/lib/common/coder-replace-prompt-template.d.ts +0 -11
  220. package/lib/common/coder-replace-prompt-template.d.ts.map +0 -1
  221. package/lib/common/coder-replace-prompt-template.js +0 -295
  222. package/lib/common/coder-replace-prompt-template.js.map +0 -1
  223. package/lib/common/command-chat-agents.d.ts +0 -36
  224. package/lib/common/command-chat-agents.d.ts.map +0 -1
  225. package/lib/common/command-chat-agents.js +0 -122
  226. package/lib/common/command-chat-agents.js.map +0 -1
  227. package/lib/common/command-prompt-template.d.ts +0 -3
  228. package/lib/common/command-prompt-template.d.ts.map +0 -1
  229. package/lib/common/command-prompt-template.js +0 -226
  230. package/lib/common/command-prompt-template.js.map +0 -1
  231. package/lib/common/context-files-variable.d.ts +0 -9
  232. package/lib/common/context-files-variable.d.ts.map +0 -1
  233. package/lib/common/context-files-variable.js +0 -52
  234. package/lib/common/context-files-variable.js.map +0 -1
  235. package/lib/common/context-functions.d.ts +0 -4
  236. package/lib/common/context-functions.d.ts.map +0 -1
  237. package/lib/common/context-functions.js +0 -22
  238. package/lib/common/context-functions.js.map +0 -1
  239. package/lib/common/context-variables.d.ts +0 -3
  240. package/lib/common/context-variables.d.ts.map +0 -1
  241. package/lib/common/context-variables.js +0 -21
  242. package/lib/common/context-variables.js.map +0 -1
  243. package/lib/common/file-changeset-function-ids.d.ts +0 -8
  244. package/lib/common/file-changeset-function-ids.d.ts.map +0 -1
  245. package/lib/common/file-changeset-function-ids.js +0 -26
  246. package/lib/common/file-changeset-function-ids.js.map +0 -1
  247. package/lib/common/github-repo-protocol.d.ts +0 -15
  248. package/lib/common/github-repo-protocol.d.ts.map +0 -1
  249. package/lib/common/github-repo-protocol.js +0 -21
  250. package/lib/common/github-repo-protocol.js.map +0 -1
  251. package/lib/common/orchestrator-chat-agent.d.ts +0 -36
  252. package/lib/common/orchestrator-chat-agent.d.ts.map +0 -1
  253. package/lib/common/orchestrator-chat-agent.js +0 -167
  254. package/lib/common/orchestrator-chat-agent.js.map +0 -1
  255. package/lib/common/orchestrator-prompt-template.d.ts +0 -3
  256. package/lib/common/orchestrator-prompt-template.d.ts.map +0 -1
  257. package/lib/common/orchestrator-prompt-template.js +0 -55
  258. package/lib/common/orchestrator-prompt-template.js.map +0 -1
  259. package/lib/common/project-info-prompt-template.d.ts +0 -6
  260. package/lib/common/project-info-prompt-template.d.ts.map +0 -1
  261. package/lib/common/project-info-prompt-template.js +0 -145
  262. package/lib/common/project-info-prompt-template.js.map +0 -1
  263. package/lib/common/summarize-session-commands.d.ts +0 -4
  264. package/lib/common/summarize-session-commands.d.ts.map +0 -1
  265. package/lib/common/summarize-session-commands.js +0 -28
  266. package/lib/common/summarize-session-commands.js.map +0 -1
  267. package/lib/common/task-context-prompt-template.d.ts +0 -8
  268. package/lib/common/task-context-prompt-template.d.ts.map +0 -1
  269. package/lib/common/task-context-prompt-template.js +0 -217
  270. package/lib/common/task-context-prompt-template.js.map +0 -1
  271. package/lib/common/universal-chat-agent.d.ts +0 -17
  272. package/lib/common/universal-chat-agent.d.ts.map +0 -1
  273. package/lib/common/universal-chat-agent.js +0 -47
  274. package/lib/common/universal-chat-agent.js.map +0 -1
  275. package/lib/common/universal-prompt-template.d.ts +0 -4
  276. package/lib/common/universal-prompt-template.d.ts.map +0 -1
  277. package/lib/common/universal-prompt-template.js +0 -32
  278. package/lib/common/universal-prompt-template.js.map +0 -1
  279. package/lib/common/workspace-functions.d.ts +0 -12
  280. package/lib/common/workspace-functions.d.ts.map +0 -1
  281. package/lib/common/workspace-functions.js +0 -30
  282. package/lib/common/workspace-functions.js.map +0 -1
  283. package/lib/common/workspace-preferences.d.ts +0 -10
  284. package/lib/common/workspace-preferences.d.ts.map +0 -1
  285. package/lib/common/workspace-preferences.js +0 -89
  286. package/lib/common/workspace-preferences.js.map +0 -1
  287. package/lib/common/workspace-search-provider-util.d.ts +0 -17
  288. package/lib/common/workspace-search-provider-util.d.ts.map +0 -1
  289. package/lib/common/workspace-search-provider-util.js +0 -51
  290. package/lib/common/workspace-search-provider-util.js.map +0 -1
  291. package/lib/node/app-tester-agent/browser-automation-impl.d.ts +0 -18
  292. package/lib/node/app-tester-agent/browser-automation-impl.d.ts.map +0 -1
  293. package/lib/node/app-tester-agent/browser-automation-impl.js +0 -96
  294. package/lib/node/app-tester-agent/browser-automation-impl.js.map +0 -1
  295. package/lib/node/backend-module.d.ts +0 -4
  296. package/lib/node/backend-module.d.ts.map +0 -1
  297. package/lib/node/backend-module.js +0 -45
  298. package/lib/node/backend-module.js.map +0 -1
  299. package/lib/node/github-repo-service-impl.d.ts +0 -7
  300. package/lib/node/github-repo-service-impl.d.ts.map +0 -1
  301. package/lib/node/github-repo-service-impl.js +0 -86
  302. package/lib/node/github-repo-service-impl.js.map +0 -1
  303. package/lib/package.spec.d.ts +0 -1
  304. package/lib/package.spec.d.ts.map +0 -1
  305. package/lib/package.spec.js +0 -26
  306. package/lib/package.spec.js.map +0 -1
@@ -22,7 +22,8 @@ import { ListChatContext, ResolveChatContext, AddFileToChatContext } from './con
22
22
  import { CancellationTokenSource } from '@theia/core';
23
23
  import { ChatContextManager, MutableChatModel, MutableChatRequestModel, MutableChatResponseModel } from '@theia/ai-chat';
24
24
  import { fail } from 'assert';
25
- import { ResolvedAIContextVariable } from '@theia/ai-core';
25
+ import { AIVariableResolutionRequest, ResolvedAIContextVariable } from '@theia/ai-core';
26
+ import { ContextFileValidationService, FileValidationState } from '@theia/ai-chat/lib/browser/context-file-validation-service';
26
27
  disableJSDOM();
27
28
 
28
29
  describe('Context Functions Cancellation Tests', () => {
@@ -100,3 +101,156 @@ describe('Context Functions Cancellation Tests', () => {
100
101
  expect(jsonResponse.error).to.equal('Operation cancelled by user');
101
102
  });
102
103
  });
104
+
105
+ describe('AddFileToChatContext Validation Tests', () => {
106
+ let mockCtx: Partial<MutableChatRequestModel>;
107
+ let addedFiles: AIVariableResolutionRequest[];
108
+
109
+ before(() => {
110
+ disableJSDOM = enableJSDOM();
111
+ });
112
+ after(() => {
113
+ disableJSDOM();
114
+ });
115
+
116
+ beforeEach(() => {
117
+ addedFiles = [];
118
+ const context: Partial<ChatContextManager> = {
119
+ addVariables: (...vars: AIVariableResolutionRequest[]) => {
120
+ addedFiles.push(...vars);
121
+ },
122
+ getVariables: () => []
123
+ };
124
+ mockCtx = {
125
+ response: {
126
+ cancellationToken: new CancellationTokenSource().token
127
+ } as MutableChatResponseModel,
128
+ context: {
129
+ variables: []
130
+ },
131
+ session: {
132
+ context
133
+ } as MutableChatModel
134
+ };
135
+ });
136
+
137
+ it('should add valid files to context', async () => {
138
+ const mockValidationService: ContextFileValidationService = {
139
+ validateFile: async () => ({ state: FileValidationState.VALID })
140
+ };
141
+
142
+ const addFileToChatContext = new AddFileToChatContext();
143
+ (addFileToChatContext as unknown as { validationService: ContextFileValidationService }).validationService = mockValidationService;
144
+
145
+ const result = await addFileToChatContext.getTool().handler(
146
+ '{"filesToAdd":["/valid/file1.ts","/valid/file2.ts"]}',
147
+ mockCtx
148
+ );
149
+
150
+ if (typeof result !== 'string') {
151
+ fail(`Wrong tool call result type: ${result}`);
152
+ }
153
+
154
+ const jsonResponse = JSON.parse(result);
155
+ expect(jsonResponse.added).to.have.lengthOf(2);
156
+ expect(jsonResponse.added).to.include('/valid/file1.ts');
157
+ expect(jsonResponse.added).to.include('/valid/file2.ts');
158
+ expect(jsonResponse.rejected).to.have.lengthOf(0);
159
+ expect(jsonResponse.summary.totalRequested).to.equal(2);
160
+ expect(jsonResponse.summary.added).to.equal(2);
161
+ expect(jsonResponse.summary.rejected).to.equal(0);
162
+ expect(addedFiles).to.have.lengthOf(2);
163
+ });
164
+
165
+ it('should reject non-existent files', async () => {
166
+ const mockValidationService: ContextFileValidationService = {
167
+ validateFile: async file => {
168
+ if (file === '/nonexistent/file.ts') {
169
+ return {
170
+ state: FileValidationState.INVALID_NOT_FOUND,
171
+ message: 'File does not exist'
172
+ };
173
+ }
174
+ return { state: FileValidationState.VALID };
175
+ }
176
+ };
177
+
178
+ const addFileToChatContext = new AddFileToChatContext();
179
+ (addFileToChatContext as unknown as { validationService: ContextFileValidationService }).validationService = mockValidationService;
180
+
181
+ const result = await addFileToChatContext.getTool().handler(
182
+ '{"filesToAdd":["/valid/file.ts","/nonexistent/file.ts"]}',
183
+ mockCtx
184
+ );
185
+
186
+ if (typeof result !== 'string') {
187
+ fail(`Wrong tool call result type: ${result}`);
188
+ }
189
+
190
+ const jsonResponse = JSON.parse(result);
191
+ expect(jsonResponse.added).to.have.lengthOf(1);
192
+ expect(jsonResponse.added).to.include('/valid/file.ts');
193
+ expect(jsonResponse.rejected).to.have.lengthOf(1);
194
+ expect(jsonResponse.rejected[0].file).to.equal('/nonexistent/file.ts');
195
+ expect(jsonResponse.rejected[0].reason).to.equal('File does not exist');
196
+ expect(jsonResponse.rejected[0].state).to.equal(FileValidationState.INVALID_NOT_FOUND);
197
+ expect(jsonResponse.summary.totalRequested).to.equal(2);
198
+ expect(jsonResponse.summary.added).to.equal(1);
199
+ expect(jsonResponse.summary.rejected).to.equal(1);
200
+ expect(addedFiles).to.have.lengthOf(1);
201
+ });
202
+
203
+ it('should reject files in secondary workspace roots', async () => {
204
+ const mockValidationService: ContextFileValidationService = {
205
+ validateFile: async file => {
206
+ if (file === '/secondary/root/file.ts') {
207
+ return {
208
+ state: FileValidationState.INVALID_SECONDARY,
209
+ message: 'File is in a secondary workspace root. AI agents can only access files in the first workspace root.'
210
+ };
211
+ }
212
+ return { state: FileValidationState.VALID };
213
+ }
214
+ };
215
+
216
+ const addFileToChatContext = new AddFileToChatContext();
217
+ (addFileToChatContext as unknown as { validationService: ContextFileValidationService }).validationService = mockValidationService;
218
+
219
+ const result = await addFileToChatContext.getTool().handler(
220
+ '{"filesToAdd":["/secondary/root/file.ts"]}',
221
+ mockCtx
222
+ );
223
+
224
+ if (typeof result !== 'string') {
225
+ fail(`Wrong tool call result type: ${result}`);
226
+ }
227
+
228
+ const jsonResponse = JSON.parse(result);
229
+ expect(jsonResponse.added).to.have.lengthOf(0);
230
+ expect(jsonResponse.rejected).to.have.lengthOf(1);
231
+ expect(jsonResponse.rejected[0].file).to.equal('/secondary/root/file.ts');
232
+ expect(jsonResponse.rejected[0].state).to.equal(FileValidationState.INVALID_SECONDARY);
233
+ expect(addedFiles).to.have.lengthOf(0);
234
+ });
235
+
236
+ it('should add all files when validation service is not available', async () => {
237
+ const addFileToChatContext = new AddFileToChatContext();
238
+
239
+ const result = await addFileToChatContext.getTool().handler(
240
+ '{"filesToAdd":["/file1.ts","/file2.ts"]}',
241
+ mockCtx
242
+ );
243
+
244
+ if (typeof result !== 'string') {
245
+ fail(`Wrong tool call result type: ${result}`);
246
+ }
247
+
248
+ const jsonResponse = JSON.parse(result);
249
+ expect(jsonResponse.added).to.have.lengthOf(2);
250
+ expect(jsonResponse.rejected).to.have.lengthOf(0);
251
+ expect(jsonResponse.summary.totalRequested).to.equal(2);
252
+ expect(jsonResponse.summary.added).to.equal(2);
253
+ expect(jsonResponse.summary.rejected).to.equal(0);
254
+ expect(addedFiles).to.have.lengthOf(2);
255
+ });
256
+ });
@@ -16,9 +16,10 @@
16
16
 
17
17
  import { MutableChatRequestModel } from '@theia/ai-chat';
18
18
  import { ToolProvider, ToolRequest } from '@theia/ai-core';
19
- import { injectable } from '@theia/core/shared/inversify';
19
+ import { inject, injectable, optional } from '@theia/core/shared/inversify';
20
20
  import { LIST_CHAT_CONTEXT_FUNCTION_ID, RESOLVE_CHAT_CONTEXT_FUNCTION_ID, UPDATE_CONTEXT_FILES_FUNCTION_ID } from '../common/context-functions';
21
21
  import { FILE_VARIABLE } from '@theia/ai-core/lib/browser/file-variable-contribution';
22
+ import { ContextFileValidationService, FileValidationState } from '@theia/ai-chat/lib/browser/context-file-validation-service';
22
23
 
23
24
  @injectable()
24
25
  export class ListChatContext implements ToolProvider {
@@ -91,6 +92,9 @@ export class ResolveChatContext implements ToolProvider {
91
92
  export class AddFileToChatContext implements ToolProvider {
92
93
  static ID = UPDATE_CONTEXT_FILES_FUNCTION_ID;
93
94
 
95
+ @inject(ContextFileValidationService) @optional()
96
+ protected readonly validationService: ContextFileValidationService | undefined;
97
+
94
98
  getTool(): ToolRequest {
95
99
  return {
96
100
  id: AddFileToChatContext.ID,
@@ -106,7 +110,10 @@ export class AddFileToChatContext implements ToolProvider {
106
110
  },
107
111
  required: ['filesToAdd']
108
112
  },
109
- description: 'Adds one or more files to the context of the current chat session, and returns the current list of files in the context.',
113
+ description: 'Adds one or more files to the context of the current chat session. ' +
114
+ 'Only files that exist within the workspace boundaries will be added. ' +
115
+ 'Files outside the workspace or non-existent files will be rejected. ' +
116
+ 'Returns a detailed status for each file, including which were successfully added and which were rejected with reasons.',
110
117
  handler: async (arg: string, ctx: MutableChatRequestModel): Promise<string> => {
111
118
  if (ctx?.response?.cancellationToken?.isCancellationRequested) {
112
119
  return JSON.stringify({ error: 'Operation cancelled by user' });
@@ -114,11 +121,38 @@ export class AddFileToChatContext implements ToolProvider {
114
121
 
115
122
  const { filesToAdd } = JSON.parse(arg) as { filesToAdd: string[] };
116
123
 
117
- ctx.session.context.addVariables(...filesToAdd.map(file => ({ arg: file, variable: FILE_VARIABLE })));
118
- const result = ctx.session.context.getVariables().filter(candidate => candidate.variable.id === FILE_VARIABLE.id && !!candidate.arg)
119
- .map(fileRequest => fileRequest.arg);
124
+ const added: string[] = [];
125
+ const rejected: Array<{ file: string; reason: string; state: string }> = [];
126
+
127
+ for (const file of filesToAdd) {
128
+ if (this.validationService) {
129
+ const validationResult = await this.validationService.validateFile(file);
130
+
131
+ if (validationResult.state === FileValidationState.VALID) {
132
+ ctx.session.context.addVariables({ arg: file, variable: FILE_VARIABLE });
133
+ added.push(file);
134
+ } else {
135
+ rejected.push({
136
+ file,
137
+ reason: validationResult.message || 'File validation failed',
138
+ state: validationResult.state
139
+ });
140
+ }
141
+ } else {
142
+ ctx.session.context.addVariables({ arg: file, variable: FILE_VARIABLE });
143
+ added.push(file);
144
+ }
145
+ }
120
146
 
121
- return JSON.stringify(result);
147
+ return JSON.stringify({
148
+ added,
149
+ rejected,
150
+ summary: {
151
+ totalRequested: filesToAdd.length,
152
+ added: added.length,
153
+ rejected: rejected.length
154
+ }
155
+ });
122
156
  }
123
157
  };
124
158
  }
@@ -25,14 +25,14 @@ import {
25
25
  SuggestFileContent,
26
26
  WriteFileContent,
27
27
  SuggestFileReplacements,
28
+ SuggestFileReplacements_Simple,
28
29
  WriteFileReplacements,
29
30
  ClearFileChanges,
30
31
  GetProposedFileState,
31
32
  ReplaceContentInFileFunctionHelper,
32
33
  FileChangeSetTitleProvider,
33
34
  DefaultFileChangeSetTitleProvider,
34
- ReplaceContentInFileFunctionHelperV2,
35
- SuggestFileReplacements_Next
35
+ ReplaceContentInFileFunctionHelperV2
36
36
  } from './file-changeset-functions';
37
37
  import { MutableChatRequestModel, MutableChatResponseModel, ChangeSet, ChangeSetElement, MutableChatModel } from '@theia/ai-chat';
38
38
  import { Container } from '@theia/core/shared/inversify';
@@ -106,12 +106,12 @@ describe('File Changeset Functions Cancellation Tests', () => {
106
106
  container.bind(ReplaceContentInFileFunctionHelper).toSelf();
107
107
  container.bind(SuggestFileContent).toSelf();
108
108
  container.bind(WriteFileContent).toSelf();
109
+ container.bind(SuggestFileReplacements_Simple).toSelf();
109
110
  container.bind(SuggestFileReplacements).toSelf();
110
111
  container.bind(WriteFileReplacements).toSelf();
111
112
  container.bind(ClearFileChanges).toSelf();
112
113
  container.bind(GetProposedFileState).toSelf();
113
114
  container.bind(ReplaceContentInFileFunctionHelperV2).toSelf();
114
- container.bind(SuggestFileReplacements_Next).toSelf();
115
115
  });
116
116
 
117
117
  afterEach(() => {
@@ -140,11 +140,11 @@ describe('File Changeset Functions Cancellation Tests', () => {
140
140
  expect(jsonResponse.error).to.equal('Operation cancelled by user');
141
141
  });
142
142
 
143
- it('SuggestFileReplacements should respect cancellation token', async () => {
144
- const suggestFileReplacements = container.get(SuggestFileReplacements);
143
+ it('SuggestFileReplacements_Simple should respect cancellation token', async () => {
144
+ const suggestFileReplacementsSimple = container.get(SuggestFileReplacements_Simple);
145
145
  cancellationTokenSource.cancel();
146
146
 
147
- const handler = suggestFileReplacements.getTool().handler;
147
+ const handler = suggestFileReplacementsSimple.getTool().handler;
148
148
  const result = await handler(
149
149
  JSON.stringify({
150
150
  path: 'test.txt',
@@ -214,11 +214,11 @@ describe('File Changeset Functions Cancellation Tests', () => {
214
214
 
215
215
  });
216
216
 
217
- it('SuggestFileReplacements_Next should respect cancellation token', async () => {
218
- const suggestFileReplacementsNext = container.get(SuggestFileReplacements_Next);
217
+ it('SuggestFileReplacements should respect cancellation token with V2 implementation', async () => {
218
+ const suggestFileReplacements = container.get(SuggestFileReplacements);
219
219
  cancellationTokenSource.cancel();
220
220
 
221
- const handler = suggestFileReplacementsNext.getTool().handler;
221
+ const handler = suggestFileReplacements.getTool().handler;
222
222
  const result = await handler(
223
223
  JSON.stringify({
224
224
  path: 'test.txt',
@@ -231,9 +231,9 @@ describe('File Changeset Functions Cancellation Tests', () => {
231
231
  expect(jsonResponse.error).to.equal('Operation cancelled by user');
232
232
  });
233
233
 
234
- it('SuggestFileReplacements_Next should have correct ID', () => {
235
- const suggestFileReplacementsNext = container.get(SuggestFileReplacements_Next);
236
- expect(SuggestFileReplacements_Next.ID).to.equal('suggestFileReplacements_Next');
237
- expect(suggestFileReplacementsNext.getTool().id).to.equal('suggestFileReplacements_Next');
234
+ it('SuggestFileReplacements should have correct ID', () => {
235
+ const suggestFileReplacements = container.get(SuggestFileReplacements);
236
+ expect(SuggestFileReplacements.ID).to.equal('suggestFileReplacements');
237
+ expect(suggestFileReplacements.getTool().id).to.equal('suggestFileReplacements');
238
238
  });
239
239
  });
@@ -31,7 +31,7 @@ import {
31
31
  SUGGEST_FILE_REPLACEMENTS_ID,
32
32
  WRITE_FILE_CONTENT_ID,
33
33
  WRITE_FILE_REPLACEMENTS_ID,
34
- SUGGEST_FILE_REPLACEMENTS_NEXT_ID
34
+ SUGGEST_FILE_REPLACEMENTS_SIMPLE_ID
35
35
  } from '../common/file-changeset-function-ids';
36
36
 
37
37
  export const FileChangeSetTitleProvider = Symbol('FileChangeSetTitleProvider');
@@ -492,16 +492,16 @@ export class SimpleWriteFileReplacements implements ToolProvider {
492
492
  }
493
493
 
494
494
  @injectable()
495
- export class SuggestFileReplacements implements ToolProvider {
496
- static ID = SUGGEST_FILE_REPLACEMENTS_ID;
495
+ export class SuggestFileReplacements_Simple implements ToolProvider {
496
+ static ID = SUGGEST_FILE_REPLACEMENTS_SIMPLE_ID;
497
497
  @inject(ReplaceContentInFileFunctionHelper)
498
498
  protected readonly replaceContentInFileFunctionHelper: ReplaceContentInFileFunctionHelper;
499
499
 
500
500
  getTool(): ToolRequest {
501
501
  const metadata = this.replaceContentInFileFunctionHelper.getToolMetadata(true);
502
502
  return {
503
- id: SuggestFileReplacements.ID,
504
- name: SuggestFileReplacements.ID,
503
+ id: SuggestFileReplacements_Simple.ID,
504
+ name: SuggestFileReplacements_Simple.ID,
505
505
  description: metadata.description,
506
506
  parameters: metadata.parameters,
507
507
  handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
@@ -611,8 +611,8 @@ export class ReplaceContentInFileFunctionHelperV2 extends ReplaceContentInFileFu
611
611
  }
612
612
 
613
613
  @injectable()
614
- export class SuggestFileReplacements_Next implements ToolProvider {
615
- static ID = SUGGEST_FILE_REPLACEMENTS_NEXT_ID;
614
+ export class SuggestFileReplacements implements ToolProvider {
615
+ static ID = SUGGEST_FILE_REPLACEMENTS_ID;
616
616
 
617
617
  @inject(ReplaceContentInFileFunctionHelperV2)
618
618
  protected readonly replaceContentInFileFunctionHelper: ReplaceContentInFileFunctionHelperV2;
@@ -620,8 +620,8 @@ export class SuggestFileReplacements_Next implements ToolProvider {
620
620
  getTool(): ToolRequest {
621
621
  const metadata = this.replaceContentInFileFunctionHelper.getToolMetadata(true);
622
622
  return {
623
- id: SuggestFileReplacements_Next.ID,
624
- name: SuggestFileReplacements_Next.ID,
623
+ id: SuggestFileReplacements.ID,
624
+ name: SuggestFileReplacements.ID,
625
625
  description: `Proposes to replace sections of content in an existing file by providing a list of replacements.
626
626
  Each replacement consists of oldContent to be matched and newContent to insert in its place.
627
627
  By default, a single occurrence of each oldContent is expected. If the 'multiple' flag is set to true, all occurrences will be replaced.
@@ -50,6 +50,7 @@ import {
50
50
  GetProposedFileState,
51
51
  ReplaceContentInFileFunctionHelper,
52
52
  SuggestFileReplacements,
53
+ SuggestFileReplacements_Simple,
53
54
  SimpleSuggestFileReplacements,
54
55
  SuggestFileContent,
55
56
  WriteFileContent,
@@ -57,8 +58,7 @@ import {
57
58
  SimpleWriteFileReplacements,
58
59
  FileChangeSetTitleProvider,
59
60
  DefaultFileChangeSetTitleProvider,
60
- ReplaceContentInFileFunctionHelperV2,
61
- SuggestFileReplacements_Next
61
+ ReplaceContentInFileFunctionHelperV2
62
62
  } from './file-changeset-functions';
63
63
  import { OrchestratorChatAgent, OrchestratorChatAgentId } from '../common/orchestrator-chat-agent';
64
64
  import { UniversalChatAgent, UniversalChatAgentId } from '../common/universal-chat-agent';
@@ -96,6 +96,9 @@ import { AiConfigurationPreferences } from '../common/ai-configuration-preferenc
96
96
  import { TaskContextAgent } from './task-context-agent';
97
97
  import { ProjectInfoAgent } from './project-info-agent';
98
98
  import { SuggestTerminalCommand } from './ai-terminal-functions';
99
+ import { ContextFileValidationService } from '@theia/ai-chat/lib/browser/context-file-validation-service';
100
+ import { ContextFileValidationServiceImpl } from './context-file-validation-service-impl';
101
+ import { RememberCommandContribution } from './remember-command-contribution';
99
102
 
100
103
  export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
101
104
  bind(PreferenceContribution).toConstantValue({ schema: aiIdePreferenceSchema });
@@ -165,10 +168,10 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
165
168
  bindToolProvider(LaunchStopProvider, bind);
166
169
  bind(ReplaceContentInFileFunctionHelper).toSelf().inSingletonScope();
167
170
  bind(FileChangeSetTitleProvider).to(DefaultFileChangeSetTitleProvider).inSingletonScope();
171
+ bind(ReplaceContentInFileFunctionHelperV2).toSelf().inSingletonScope();
168
172
  bindToolProvider(SuggestFileReplacements, bind);
173
+ bindToolProvider(SuggestFileReplacements_Simple, bind);
169
174
  bindToolProvider(WriteFileReplacements, bind);
170
- bind(ReplaceContentInFileFunctionHelperV2).toSelf().inSingletonScope();
171
- bindToolProvider(SuggestFileReplacements_Next, bind);
172
175
  bindToolProvider(ListChatContext, bind);
173
176
  bindToolProvider(ResolveChatContext, bind);
174
177
  bind(AIConfigurationSelectionService).toSelf().inSingletonScope();
@@ -270,4 +273,9 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
270
273
  .inSingletonScope();
271
274
 
272
275
  bindToolProvider(SuggestTerminalCommand, bind);
276
+
277
+ bind(ContextFileValidationServiceImpl).toSelf().inSingletonScope();
278
+ bind(ContextFileValidationService).toService(ContextFileValidationServiceImpl);
279
+
280
+ bind(FrontendApplicationContribution).to(RememberCommandContribution);
273
281
  });
@@ -14,12 +14,12 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
- import { ChatWelcomeMessageProvider, isEnterKey } from '@theia/ai-chat-ui/lib/browser/chat-tree-view';
17
+ import { ChatWelcomeMessageProvider } from '@theia/ai-chat-ui/lib/browser/chat-tree-view';
18
18
  import * as React from '@theia/core/shared/react';
19
19
  import { nls } from '@theia/core/lib/common/nls';
20
20
  import { inject, injectable } from '@theia/core/shared/inversify';
21
- import { CommandRegistry } from '@theia/core';
22
- import { CommonCommands } from '@theia/core/lib/browser';
21
+ import { CommonCommands, LocalizedMarkdown, MarkdownRenderer } from '@theia/core/lib/browser';
22
+ import { OPEN_AI_CONFIG_VIEW } from './ai-configuration/ai-configuration-view-contribution';
23
23
 
24
24
  const TheiaIdeAiLogo = ({ width = 200, height = 200, className = '' }) =>
25
25
  <svg
@@ -57,30 +57,34 @@ const TheiaIdeAiLogo = ({ width = 200, height = 200, className = '' }) =>
57
57
  @injectable()
58
58
  export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider {
59
59
 
60
- @inject(CommandRegistry)
61
- protected commandRegistry: CommandRegistry;
60
+ @inject(MarkdownRenderer)
61
+ protected readonly markdownRenderer: MarkdownRenderer;
62
62
 
63
- renderWelcomeMessage?(): React.ReactNode {
63
+ renderWelcomeMessage(): React.ReactNode {
64
64
  return <div className={'theia-WelcomeMessage'}>
65
65
  <TheiaIdeAiLogo width={200} height={200} className="theia-WelcomeMessage-Logo" />
66
- <div className="theia-WelcomeMessage-Content">
67
- <h1>Ask the Theia IDE AI</h1>
68
- <p>
69
- To talk to a specialized agent, simply start your message with <em>@</em> followed by the agent's name:{' '}
70
- <em>@Coder</em>, <em>@Architect</em>, <em>@Universal</em>, and more.
71
- </p>
72
- <p>
73
- Attach context: use variables, like <em>#file</em>, <em>#_f</em> (current file), <em>#selectedText</em>{' '}
74
- or click <span className="codicon codicon-add" />.
75
- </p>
76
- <p>
77
- Lean more in the <a target='_blank' href="https://theia-ide.org/docs/user_ai/#chat">documentation</a>.
78
- </p>
79
- </div>
66
+ <LocalizedMarkdown
67
+ localizationKey="theia/ai/ide/chatWelcomeMessage"
68
+ defaultMarkdown={`
69
+ # Ask the Theia IDE AI
70
+
71
+ To talk to a specialized agent, simply start your message with *@* followed by the agent's name: *@{0}*, *@{1}*, *@{2}*, and more.
72
+
73
+ Attach context: use variables, like *#{3}*, *#{4}* (current file), *#{5}* or click {6}.
74
+
75
+ Lean more in the [documentation](https://theia-ide.org/docs/user_ai/#chat).
76
+ `}
77
+ args={['Coder', 'Architect', 'Universal', 'file', '_f', 'selectedText', '<span class="codicon codicon-add"></span>']}
78
+ markdownRenderer={this.markdownRenderer}
79
+ className="theia-WelcomeMessage-Content"
80
+ markdownOptions={{ supportHtml: true }}
81
+ />
80
82
  </div>;
81
83
  }
82
84
 
83
- renderDisabledMessage?(): React.ReactNode {
85
+ renderDisabledMessage(): React.ReactNode {
86
+ const openAiHistory = 'aiHistory:open';
87
+
84
88
  return <div className={'theia-ResponseNode'}>
85
89
  <div className='theia-ResponseNode-Content' key={'disabled-message'}>
86
90
  <div className="disable-message">
@@ -93,59 +97,49 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
93
97
  <div className="section-title">
94
98
  <p>{nls.localize('theia/ai/chat-ui/chat-view-tree-widget/howToEnable', 'How to Enable the AI Features:')}</p>
95
99
  </div>
96
- <div className="section-content">
97
- <p>To enable the AI features, please go to the AI features section of the&nbsp;
98
- {this.renderLinkButton(nls.localize('theia/ai/chat-ui/chat-view-tree-widget/settingsMenu', 'the settings menu'),
99
- CommonCommands.OPEN_PREFERENCES.id, 'ai-features')}&nbsp;and
100
- </p>
101
- <ol>
102
- <li>Toggle the switch for <strong>{nls.localize('theia/ai/chat-ui/chat-view-tree-widget/aiFeaturesEnable', 'Ai-features: Enable')}</strong>.</li>
103
- <li>Provide at least one LLM provider (e.g. OpenAI). See <a href="https://theia-ide.org/docs/user_ai/" target="_blank">the documentation</a>
104
- &nbsp;for more information.</li>
105
- </ol>
106
- <p>This will activate the AI capabilities in the app. Please remember, these features are <strong>in a beta state</strong>,
107
- so they may change and we are working on improving them 🚧.<br></br>
108
- Please support us by <a href="https://github.com/eclipse-theia/theia">providing feedback
109
- </a>!</p>
110
- </div>
100
+ <LocalizedMarkdown
101
+ localizationKey="theia/ai/ide/chatDisabledMessage/howToEnable"
102
+ defaultMarkdown={`
103
+ To enable the AI features, please go to the AI features section of&nbsp;[the settings menu]({0})&nbsp;and
104
+ 1. Toggle the switch for **Ai-features: Enable**.
105
+ 2. Provide at least one LLM provider (e.g. OpenAI). See [the documentation](https://theia-ide.org/docs/user_ai/)&nbsp;for more information.
106
+
107
+ This will activate the AI capabilities in the app. Please remember, these features are **in a beta state**, so they may change and we are working on improving them 🚧.\\
108
+ Please support us by [providing feedback](https://github.com/eclipse-theia/theia)!
109
+ `}
110
+ args={[`command:${CommonCommands.OPEN_PREFERENCES.id}?ai-features`]}
111
+ markdownRenderer={this.markdownRenderer}
112
+ className="section-content"
113
+ markdownOptions={{ isTrusted: { enabledCommands: [CommonCommands.OPEN_PREFERENCES.id] } }}
114
+ />
111
115
 
112
116
  <div className="section-title">
113
- <p>Currently Supported Views and Features:</p>
114
- </div>
115
- <div className="section-content">
116
- <p>Once the AI features are enabled, you can access the following views and features:</p>
117
- <ul>
118
- <li>Code Completion</li>
119
- <li>Terminal Assistance (via CTRL+I in a terminal)</li>
120
- <li>This Chat View (features the following agents):
121
- <ul>
122
- <li>Universal Chat Agent</li>
123
- <li>Coder Chat Agent</li>
124
- <li>Architect Chat Agent</li>
125
- <li>Command Chat Agent</li>
126
- <li>Orchestrator Chat Agent</li>
127
- </ul>
128
- </li>
129
- <li>{this.renderLinkButton(nls.localize('theia/ai/chat-ui/chat-view-tree-widget/aiHistoryView', 'AI History View'), 'aiHistory:open')}</li>
130
- <li>{this.renderLinkButton(
131
- nls.localize('theia/ai/chat-ui/chat-view-tree-widget/aiConfigurationView', 'AI Configuration View'), 'aiConfiguration:open')}
132
- </li>
133
- </ul>
134
- <p>See <a href="https://theia-ide.org/docs/user_ai/" target="_blank">the documentation</a> for more information.</p>
117
+ <p>{nls.localize('theia/ai/ide/chatDisabledMessage/featuresTitle', 'Currently Supported Views and Features:')}</p>
135
118
  </div>
119
+ <LocalizedMarkdown
120
+ localizationKey="theia/ai/ide/chatDisabledMessage/features"
121
+ defaultMarkdown={`
122
+ Once the AI features are enabled, you can access the following views and features:
123
+ - Code Completion
124
+ - Terminal Assistance (via CTRL+I in a terminal)
125
+ - This Chat View (features the following agents):
126
+ * Universal Chat Agent
127
+ * Coder Chat Agent
128
+ * Architect Chat Agent
129
+ * Command Chat Agent
130
+ * Orchestrator Chat Agent
131
+ - [AI History View]({0})
132
+ - [AI Configuration View]({1})
133
+
134
+ See [the documentation](https://theia-ide.org/docs/user_ai/) for more information.
135
+ `}
136
+ args={[`command:${openAiHistory}`, `command:${OPEN_AI_CONFIG_VIEW.id}`]}
137
+ markdownRenderer={this.markdownRenderer}
138
+ className="section-content"
139
+ markdownOptions={{ isTrusted: { enabledCommands: [openAiHistory, OPEN_AI_CONFIG_VIEW.id] } }}
140
+ />
136
141
  </div>
137
142
  </div>
138
- </div >;
139
- }
140
-
141
- protected renderLinkButton(title: string, openCommandId: string, ...commandArgs: unknown[]): React.ReactNode {
142
- return <a
143
- role={'button'}
144
- tabIndex={0}
145
- onClick={() => this.commandRegistry.executeCommand(openCommandId, ...commandArgs)}
146
- onKeyDown={e => isEnterKey(e) && this.commandRegistry.executeCommand(openCommandId)}>
147
- {title}
148
- </a>;
143
+ </div>;
149
144
  }
150
-
151
145
  }