@theia/ai-ide 1.75.0-next.8 → 1.75.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 (509) hide show
  1. package/lib/browser/ai-allow-all-mode-chat-banner.js +2 -20
  2. package/lib/browser/ai-allow-all-mode-chat-banner.js.map +1 -1
  3. package/lib/browser/ai-configuration/agent-icon.d.ts +16 -0
  4. package/lib/browser/ai-configuration/agent-icon.d.ts.map +1 -0
  5. package/lib/browser/ai-configuration/agent-icon.js +38 -0
  6. package/lib/browser/ai-configuration/agent-icon.js.map +1 -0
  7. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.d.ts +36 -0
  8. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.d.ts.map +1 -0
  9. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.js +163 -0
  10. package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.js.map +1 -0
  11. package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts +50 -0
  12. package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts.map +1 -0
  13. package/lib/browser/ai-configuration/ai-configuration-detail-widget.js +208 -0
  14. package/lib/browser/ai-configuration/ai-configuration-detail-widget.js.map +1 -0
  15. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.d.ts +2 -0
  16. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.d.ts.map +1 -0
  17. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js +139 -0
  18. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js.map +1 -0
  19. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.d.ts +13 -0
  20. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.d.ts.map +1 -0
  21. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.js +48 -0
  22. package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.js.map +1 -0
  23. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.d.ts +22 -0
  24. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.d.ts.map +1 -0
  25. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.js +72 -0
  26. package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.js.map +1 -0
  27. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.d.ts +2 -0
  28. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.d.ts.map +1 -0
  29. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.js +126 -0
  30. package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.js.map +1 -0
  31. package/lib/browser/ai-configuration/ai-configuration-resource.d.ts +10 -0
  32. package/lib/browser/ai-configuration/ai-configuration-resource.d.ts.map +1 -0
  33. package/lib/browser/ai-configuration/{components/configuration-section.js → ai-configuration-resource.js} +11 -11
  34. package/lib/browser/ai-configuration/ai-configuration-resource.js.map +1 -0
  35. package/lib/browser/ai-configuration/ai-configuration-search-widget.d.ts +29 -0
  36. package/lib/browser/ai-configuration/ai-configuration-search-widget.d.ts.map +1 -0
  37. package/lib/browser/ai-configuration/ai-configuration-search-widget.js +106 -0
  38. package/lib/browser/ai-configuration/ai-configuration-search-widget.js.map +1 -0
  39. package/lib/browser/ai-configuration/ai-configuration-search.d.ts +18 -0
  40. package/lib/browser/ai-configuration/ai-configuration-search.d.ts.map +1 -0
  41. package/lib/browser/ai-configuration/ai-configuration-search.js +45 -0
  42. package/lib/browser/ai-configuration/ai-configuration-search.js.map +1 -0
  43. package/lib/browser/ai-configuration/ai-configuration-search.spec.d.ts +2 -0
  44. package/lib/browser/ai-configuration/ai-configuration-search.spec.d.ts.map +1 -0
  45. package/lib/browser/ai-configuration/ai-configuration-search.spec.js +79 -0
  46. package/lib/browser/ai-configuration/ai-configuration-search.spec.js.map +1 -0
  47. package/lib/browser/ai-configuration/ai-configuration-tree-model.d.ts +8 -0
  48. package/lib/browser/ai-configuration/ai-configuration-tree-model.d.ts.map +1 -0
  49. package/lib/browser/ai-configuration/{base/ai-configuration-base-widget.js → ai-configuration-tree-model.js} +11 -14
  50. package/lib/browser/ai-configuration/ai-configuration-tree-model.js.map +1 -0
  51. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.d.ts +57 -0
  52. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.d.ts.map +1 -0
  53. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.js +134 -0
  54. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.js.map +1 -0
  55. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.d.ts +2 -0
  56. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.d.ts.map +1 -0
  57. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.js +134 -0
  58. package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.js.map +1 -0
  59. package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts +96 -0
  60. package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts.map +1 -0
  61. package/lib/browser/ai-configuration/ai-configuration-tree-widget.js +407 -0
  62. package/lib/browser/ai-configuration/ai-configuration-tree-widget.js.map +1 -0
  63. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts +38 -4
  64. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts.map +1 -1
  65. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js +151 -19
  66. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js.map +1 -1
  67. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts +21 -23
  68. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts.map +1 -1
  69. package/lib/browser/ai-configuration/ai-configuration-widget.js +102 -70
  70. package/lib/browser/ai-configuration/ai-configuration-widget.js.map +1 -1
  71. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.d.ts +56 -0
  72. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.d.ts.map +1 -0
  73. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js +195 -0
  74. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js.map +1 -0
  75. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.d.ts +2 -0
  76. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.d.ts.map +1 -0
  77. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.js +140 -0
  78. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.js.map +1 -0
  79. package/lib/browser/ai-configuration/categories/agent-chips.d.ts +15 -0
  80. package/lib/browser/ai-configuration/categories/agent-chips.d.ts.map +1 -0
  81. package/lib/browser/ai-configuration/categories/agent-chips.js +19 -0
  82. package/lib/browser/ai-configuration/categories/agent-chips.js.map +1 -0
  83. package/lib/browser/ai-configuration/categories/agent-detail-model.d.ts +37 -0
  84. package/lib/browser/ai-configuration/categories/agent-detail-model.d.ts.map +1 -0
  85. package/lib/browser/ai-configuration/categories/agent-detail-model.js +99 -0
  86. package/lib/browser/ai-configuration/categories/agent-detail-model.js.map +1 -0
  87. package/lib/browser/ai-configuration/categories/agent-detail-view.d.ts +28 -0
  88. package/lib/browser/ai-configuration/categories/agent-detail-view.d.ts.map +1 -0
  89. package/lib/browser/ai-configuration/categories/agent-detail-view.js +135 -0
  90. package/lib/browser/ai-configuration/categories/agent-detail-view.js.map +1 -0
  91. package/lib/browser/ai-configuration/categories/agents-configuration-category.d.ts +78 -0
  92. package/lib/browser/ai-configuration/categories/agents-configuration-category.d.ts.map +1 -0
  93. package/lib/browser/ai-configuration/categories/agents-configuration-category.js +352 -0
  94. package/lib/browser/ai-configuration/categories/agents-configuration-category.js.map +1 -0
  95. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.d.ts +2 -0
  96. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.d.ts.map +1 -0
  97. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.js +99 -0
  98. package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.js.map +1 -0
  99. package/lib/browser/ai-configuration/categories/general-configuration-category.d.ts +93 -0
  100. package/lib/browser/ai-configuration/categories/general-configuration-category.d.ts.map +1 -0
  101. package/lib/browser/ai-configuration/categories/general-configuration-category.js +313 -0
  102. package/lib/browser/ai-configuration/categories/general-configuration-category.js.map +1 -0
  103. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.d.ts +2 -0
  104. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.d.ts.map +1 -0
  105. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.js +213 -0
  106. package/lib/browser/ai-configuration/categories/general-configuration-category.spec.js.map +1 -0
  107. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts +53 -0
  108. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts.map +1 -0
  109. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js +241 -0
  110. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js.map +1 -0
  111. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.d.ts +2 -0
  112. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.d.ts.map +1 -0
  113. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js +75 -0
  114. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js.map +1 -0
  115. package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts +72 -0
  116. package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts.map +1 -0
  117. package/lib/browser/ai-configuration/categories/models-configuration-category.js +227 -0
  118. package/lib/browser/ai-configuration/categories/models-configuration-category.js.map +1 -0
  119. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.d.ts +2 -0
  120. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.d.ts.map +1 -0
  121. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js +145 -0
  122. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js.map +1 -0
  123. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.d.ts +114 -0
  124. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.d.ts.map +1 -0
  125. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.js +341 -0
  126. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.js.map +1 -0
  127. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.d.ts +2 -0
  128. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.d.ts.map +1 -0
  129. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.js +199 -0
  130. package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.js.map +1 -0
  131. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.d.ts +84 -0
  132. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.d.ts.map +1 -0
  133. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.js +341 -0
  134. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.js.map +1 -0
  135. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.d.ts +2 -0
  136. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.d.ts.map +1 -0
  137. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.js +184 -0
  138. package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.js.map +1 -0
  139. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.d.ts +38 -0
  140. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.d.ts.map +1 -0
  141. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.js +130 -0
  142. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.js.map +1 -0
  143. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.d.ts +2 -0
  144. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.d.ts.map +1 -0
  145. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.js +51 -0
  146. package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.js.map +1 -0
  147. package/lib/browser/ai-configuration/categories/tools-configuration-category.d.ts +60 -0
  148. package/lib/browser/ai-configuration/categories/tools-configuration-category.d.ts.map +1 -0
  149. package/lib/browser/ai-configuration/categories/tools-configuration-category.js +302 -0
  150. package/lib/browser/ai-configuration/categories/tools-configuration-category.js.map +1 -0
  151. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.d.ts +2 -0
  152. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.d.ts.map +1 -0
  153. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.js +111 -0
  154. package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.js.map +1 -0
  155. package/lib/browser/ai-configuration/categories/variables-configuration-category.d.ts +72 -0
  156. package/lib/browser/ai-configuration/categories/variables-configuration-category.d.ts.map +1 -0
  157. package/lib/browser/ai-configuration/categories/variables-configuration-category.js +245 -0
  158. package/lib/browser/ai-configuration/categories/variables-configuration-category.js.map +1 -0
  159. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.d.ts +2 -0
  160. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.d.ts.map +1 -0
  161. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.js +131 -0
  162. package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.js.map +1 -0
  163. package/lib/browser/ai-configuration/components/agent-notification-settings.d.ts +6 -2
  164. package/lib/browser/ai-configuration/components/agent-notification-settings.d.ts.map +1 -1
  165. package/lib/browser/ai-configuration/components/agent-notification-settings.js +15 -21
  166. package/lib/browser/ai-configuration/components/agent-notification-settings.js.map +1 -1
  167. package/lib/browser/ai-configuration/language-model-renderer.d.ts +25 -1
  168. package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -1
  169. package/lib/browser/ai-configuration/language-model-renderer.js +159 -63
  170. package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -1
  171. package/lib/browser/ai-configuration/language-model-renderer.spec.d.ts +2 -0
  172. package/lib/browser/ai-configuration/language-model-renderer.spec.d.ts.map +1 -0
  173. package/lib/browser/ai-configuration/language-model-renderer.spec.js +93 -0
  174. package/lib/browser/ai-configuration/language-model-renderer.spec.js.map +1 -0
  175. package/lib/browser/ai-sessions-widget.js +12 -16
  176. package/lib/browser/ai-sessions-widget.js.map +1 -1
  177. package/lib/browser/app-tester-chat-agent.d.ts +2 -0
  178. package/lib/browser/app-tester-chat-agent.d.ts.map +1 -1
  179. package/lib/browser/app-tester-chat-agent.js +5 -0
  180. package/lib/browser/app-tester-chat-agent.js.map +1 -1
  181. package/lib/browser/architect-agent.d.ts +2 -0
  182. package/lib/browser/architect-agent.d.ts.map +1 -1
  183. package/lib/browser/architect-agent.js +5 -0
  184. package/lib/browser/architect-agent.js.map +1 -1
  185. package/lib/browser/architect-prompt-template.d.ts.map +1 -1
  186. package/lib/browser/architect-prompt-template.js +7 -0
  187. package/lib/browser/architect-prompt-template.js.map +1 -1
  188. package/lib/browser/chat-session-item.d.ts.map +1 -1
  189. package/lib/browser/chat-session-item.js +17 -30
  190. package/lib/browser/chat-session-item.js.map +1 -1
  191. package/lib/browser/chat-session-list-components.js +7 -30
  192. package/lib/browser/chat-session-list-components.js.map +1 -1
  193. package/lib/browser/chat-session-list-service.d.ts +2 -1
  194. package/lib/browser/chat-session-list-service.d.ts.map +1 -1
  195. package/lib/browser/chat-session-list-service.js +6 -1
  196. package/lib/browser/chat-session-list-service.js.map +1 -1
  197. package/lib/browser/chat-sessions-welcome-message-provider.js +3 -21
  198. package/lib/browser/chat-sessions-welcome-message-provider.js.map +1 -1
  199. package/lib/browser/code-reviewer-agent.d.ts +2 -0
  200. package/lib/browser/code-reviewer-agent.d.ts.map +1 -1
  201. package/lib/browser/code-reviewer-agent.js +5 -0
  202. package/lib/browser/code-reviewer-agent.js.map +1 -1
  203. package/lib/browser/coder-agent.d.ts +2 -0
  204. package/lib/browser/coder-agent.d.ts.map +1 -1
  205. package/lib/browser/coder-agent.js +6 -1
  206. package/lib/browser/coder-agent.js.map +1 -1
  207. package/lib/browser/context-file-validation-service-impl.spec.js +2 -0
  208. package/lib/browser/context-file-validation-service-impl.spec.js.map +1 -1
  209. package/lib/browser/create-skill-agent.d.ts +2 -0
  210. package/lib/browser/create-skill-agent.d.ts.map +1 -1
  211. package/lib/browser/create-skill-agent.js +5 -0
  212. package/lib/browser/create-skill-agent.js.map +1 -1
  213. package/lib/browser/explore-agent.d.ts +2 -0
  214. package/lib/browser/explore-agent.d.ts.map +1 -1
  215. package/lib/browser/explore-agent.js +5 -0
  216. package/lib/browser/explore-agent.js.map +1 -1
  217. package/lib/browser/file-changeset-functions.d.ts +7 -1
  218. package/lib/browser/file-changeset-functions.d.ts.map +1 -1
  219. package/lib/browser/file-changeset-functions.js +62 -20
  220. package/lib/browser/file-changeset-functions.js.map +1 -1
  221. package/lib/browser/file-changeset-functions.spec.js +130 -1
  222. package/lib/browser/file-changeset-functions.spec.js.map +1 -1
  223. package/lib/browser/frontend-module.d.ts.map +1 -1
  224. package/lib/browser/frontend-module.js +65 -59
  225. package/lib/browser/frontend-module.js.map +1 -1
  226. package/lib/browser/github-chat-agent.d.ts +2 -1
  227. package/lib/browser/github-chat-agent.d.ts.map +1 -1
  228. package/lib/browser/github-chat-agent.js +5 -0
  229. package/lib/browser/github-chat-agent.js.map +1 -1
  230. package/lib/browser/github-repo-variable-contribution.d.ts +2 -1
  231. package/lib/browser/github-repo-variable-contribution.d.ts.map +1 -1
  232. package/lib/browser/github-repo-variable-contribution.js +6 -1
  233. package/lib/browser/github-repo-variable-contribution.js.map +1 -1
  234. package/lib/browser/ide-chat-welcome-message-provider.d.ts.map +1 -1
  235. package/lib/browser/ide-chat-welcome-message-provider.js +31 -118
  236. package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
  237. package/lib/browser/memory-capability-contribution.d.ts +8 -0
  238. package/lib/browser/memory-capability-contribution.d.ts.map +1 -0
  239. package/lib/browser/memory-capability-contribution.js +88 -0
  240. package/lib/browser/memory-capability-contribution.js.map +1 -0
  241. package/lib/browser/memory-capability-contribution.spec.d.ts +2 -0
  242. package/lib/browser/memory-capability-contribution.spec.d.ts.map +1 -0
  243. package/lib/browser/memory-capability-contribution.spec.js +74 -0
  244. package/lib/browser/memory-capability-contribution.spec.js.map +1 -0
  245. package/lib/browser/memory-directory-variable-contribution.d.ts +41 -0
  246. package/lib/browser/memory-directory-variable-contribution.d.ts.map +1 -0
  247. package/lib/browser/memory-directory-variable-contribution.js +107 -0
  248. package/lib/browser/memory-directory-variable-contribution.js.map +1 -0
  249. package/lib/browser/memory-directory-variable-contribution.spec.d.ts +2 -0
  250. package/lib/browser/memory-directory-variable-contribution.spec.d.ts.map +1 -0
  251. package/lib/browser/memory-directory-variable-contribution.spec.js +98 -0
  252. package/lib/browser/memory-directory-variable-contribution.spec.js.map +1 -0
  253. package/lib/browser/open-editors-hint-contribution.d.ts +7 -0
  254. package/lib/browser/open-editors-hint-contribution.d.ts.map +1 -0
  255. package/lib/browser/open-editors-hint-contribution.js +43 -0
  256. package/lib/browser/open-editors-hint-contribution.js.map +1 -0
  257. package/lib/browser/project-info-agent.d.ts +2 -0
  258. package/lib/browser/project-info-agent.d.ts.map +1 -1
  259. package/lib/browser/project-info-agent.js +5 -0
  260. package/lib/browser/project-info-agent.js.map +1 -1
  261. package/lib/browser/review/pr-review-agent.d.ts +2 -0
  262. package/lib/browser/review/pr-review-agent.d.ts.map +1 -1
  263. package/lib/browser/review/pr-review-agent.js +5 -0
  264. package/lib/browser/review/pr-review-agent.js.map +1 -1
  265. package/lib/browser/summarize-session-command-contribution.d.ts +2 -1
  266. package/lib/browser/summarize-session-command-contribution.d.ts.map +1 -1
  267. package/lib/browser/summarize-session-command-contribution.js +6 -1
  268. package/lib/browser/summarize-session-command-contribution.js.map +1 -1
  269. package/lib/browser/task-context-file-storage-service.d.ts.map +1 -1
  270. package/lib/browser/task-context-file-storage-service.js +1 -0
  271. package/lib/browser/task-context-file-storage-service.js.map +1 -1
  272. package/lib/browser/todo-tool-renderer.js +11 -19
  273. package/lib/browser/todo-tool-renderer.js.map +1 -1
  274. package/lib/browser/user-interaction-tool-renderer.js +39 -83
  275. package/lib/browser/user-interaction-tool-renderer.js.map +1 -1
  276. package/lib/browser/user-interaction-tool.d.ts +2 -0
  277. package/lib/browser/user-interaction-tool.d.ts.map +1 -1
  278. package/lib/browser/user-interaction-tool.js +7 -1
  279. package/lib/browser/user-interaction-tool.js.map +1 -1
  280. package/lib/browser/user-interaction-tool.spec.js +4 -2
  281. package/lib/browser/user-interaction-tool.spec.js.map +1 -1
  282. package/lib/browser/workspace-functions.d.ts +45 -7
  283. package/lib/browser/workspace-functions.d.ts.map +1 -1
  284. package/lib/browser/workspace-functions.js +108 -70
  285. package/lib/browser/workspace-functions.js.map +1 -1
  286. package/lib/browser/workspace-functions.spec.js +139 -9
  287. package/lib/browser/workspace-functions.spec.js.map +1 -1
  288. package/lib/browser/workspace-launch-provider.spec.js +3 -0
  289. package/lib/browser/workspace-launch-provider.spec.js.map +1 -1
  290. package/lib/browser/workspace-search-provider.d.ts.map +1 -1
  291. package/lib/browser/workspace-search-provider.js +4 -7
  292. package/lib/browser/workspace-search-provider.js.map +1 -1
  293. package/lib/browser/workspace-search-provider.spec.js +1 -2
  294. package/lib/browser/workspace-search-provider.spec.js.map +1 -1
  295. package/lib/browser/workspace-task-provider.spec.js +4 -0
  296. package/lib/browser/workspace-task-provider.spec.js.map +1 -1
  297. package/lib/common/coder-replace-prompt-template.d.ts +0 -2
  298. package/lib/common/coder-replace-prompt-template.d.ts.map +1 -1
  299. package/lib/common/coder-replace-prompt-template.js +10 -11
  300. package/lib/common/coder-replace-prompt-template.js.map +1 -1
  301. package/lib/common/command-chat-agents.d.ts +2 -1
  302. package/lib/common/command-chat-agents.d.ts.map +1 -1
  303. package/lib/common/command-chat-agents.js +6 -1
  304. package/lib/common/command-chat-agents.js.map +1 -1
  305. package/lib/common/open-editors-hint-fragment-id.d.ts +2 -0
  306. package/lib/common/open-editors-hint-fragment-id.d.ts.map +1 -0
  307. package/lib/{browser/ai-configuration/components/empty-state.js → common/open-editors-hint-fragment-id.js} +5 -11
  308. package/lib/common/open-editors-hint-fragment-id.js.map +1 -0
  309. package/lib/common/orchestrator-chat-agent.d.ts +2 -1
  310. package/lib/common/orchestrator-chat-agent.d.ts.map +1 -1
  311. package/lib/common/orchestrator-chat-agent.js +5 -0
  312. package/lib/common/orchestrator-chat-agent.js.map +1 -1
  313. package/lib/common/universal-chat-agent.d.ts +2 -0
  314. package/lib/common/universal-chat-agent.d.ts.map +1 -1
  315. package/lib/common/universal-chat-agent.js +5 -0
  316. package/lib/common/universal-chat-agent.js.map +1 -1
  317. package/lib/common/universal-prompt-template.d.ts.map +1 -1
  318. package/lib/common/universal-prompt-template.js +3 -0
  319. package/lib/common/universal-prompt-template.js.map +1 -1
  320. package/lib/common/workspace-preferences.js +2 -2
  321. package/lib/common/workspace-preferences.js.map +1 -1
  322. package/lib/common/workspace-search-provider-util.d.ts +2 -1
  323. package/lib/common/workspace-search-provider-util.d.ts.map +1 -1
  324. package/lib/common/workspace-search-provider-util.js +3 -2
  325. package/lib/common/workspace-search-provider-util.js.map +1 -1
  326. package/lib/common/workspace-search-provider-util.spec.d.ts +2 -0
  327. package/lib/common/workspace-search-provider-util.spec.d.ts.map +1 -0
  328. package/lib/common/workspace-search-provider-util.spec.js +55 -0
  329. package/lib/common/workspace-search-provider-util.spec.js.map +1 -0
  330. package/lib/node/github-repo-service-impl.d.ts +2 -0
  331. package/lib/node/github-repo-service-impl.d.ts.map +1 -1
  332. package/lib/node/github-repo-service-impl.js +7 -1
  333. package/lib/node/github-repo-service-impl.js.map +1 -1
  334. package/package.json +26 -25
  335. package/src/browser/ai-configuration/agent-icon.ts +37 -0
  336. package/src/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.ts +164 -0
  337. package/src/browser/ai-configuration/ai-configuration-detail-widget.spec.ts +165 -0
  338. package/src/browser/ai-configuration/ai-configuration-detail-widget.tsx +237 -0
  339. package/src/browser/ai-configuration/ai-configuration-label-provider-contribution.ts +47 -0
  340. package/src/browser/ai-configuration/ai-configuration-open-preference-renderer.ts +64 -0
  341. package/src/browser/ai-configuration/ai-configuration-preference-ownership.spec.ts +135 -0
  342. package/src/browser/ai-configuration/{components/configuration-section.tsx → ai-configuration-resource.ts} +9 -19
  343. package/src/browser/ai-configuration/ai-configuration-search-widget.tsx +135 -0
  344. package/src/browser/ai-configuration/ai-configuration-search.spec.ts +91 -0
  345. package/src/browser/ai-configuration/ai-configuration-search.ts +43 -0
  346. package/src/browser/ai-configuration/{components/empty-state.tsx → ai-configuration-tree-model.ts} +7 -11
  347. package/src/browser/ai-configuration/ai-configuration-tree-nodes.spec.ts +150 -0
  348. package/src/browser/ai-configuration/ai-configuration-tree-nodes.ts +167 -0
  349. package/src/browser/ai-configuration/ai-configuration-tree-widget.tsx +457 -0
  350. package/src/browser/ai-configuration/ai-configuration-view-contribution.ts +156 -18
  351. package/src/browser/ai-configuration/ai-configuration-widget.tsx +107 -75
  352. package/src/browser/ai-configuration/categories/agent-capabilities-settings.spec.ts +161 -0
  353. package/src/browser/ai-configuration/categories/agent-capabilities-settings.tsx +340 -0
  354. package/src/browser/ai-configuration/categories/agent-chips.tsx +51 -0
  355. package/src/browser/ai-configuration/categories/agent-detail-model.ts +152 -0
  356. package/src/browser/ai-configuration/categories/agent-detail-view.tsx +329 -0
  357. package/src/browser/ai-configuration/categories/agents-configuration-category.spec.ts +119 -0
  358. package/src/browser/ai-configuration/categories/agents-configuration-category.tsx +431 -0
  359. package/src/browser/ai-configuration/categories/general-configuration-category.spec.ts +225 -0
  360. package/src/browser/ai-configuration/categories/general-configuration-category.tsx +465 -0
  361. package/src/browser/ai-configuration/categories/model-aliases-configuration-category.spec.ts +87 -0
  362. package/src/browser/ai-configuration/categories/model-aliases-configuration-category.tsx +286 -0
  363. package/src/browser/ai-configuration/categories/models-configuration-category.spec.ts +167 -0
  364. package/src/browser/ai-configuration/categories/models-configuration-category.tsx +264 -0
  365. package/src/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.ts +250 -0
  366. package/src/browser/ai-configuration/categories/prompt-snippets-configuration-category.tsx +438 -0
  367. package/src/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.ts +226 -0
  368. package/src/browser/ai-configuration/categories/prompts-and-skills-configuration-category.tsx +419 -0
  369. package/src/browser/ai-configuration/categories/token-usage-configuration-category.spec.ts +57 -0
  370. package/src/browser/ai-configuration/categories/token-usage-configuration-category.tsx +185 -0
  371. package/src/browser/ai-configuration/categories/tools-configuration-category.spec.ts +130 -0
  372. package/src/browser/ai-configuration/categories/tools-configuration-category.tsx +421 -0
  373. package/src/browser/ai-configuration/categories/variables-configuration-category.spec.ts +154 -0
  374. package/src/browser/ai-configuration/categories/variables-configuration-category.tsx +322 -0
  375. package/src/browser/ai-configuration/components/agent-notification-settings.tsx +38 -33
  376. package/src/browser/ai-configuration/language-model-renderer.spec.ts +100 -0
  377. package/src/browser/ai-configuration/language-model-renderer.tsx +244 -100
  378. package/src/browser/app-tester-chat-agent.ts +5 -2
  379. package/src/browser/architect-agent.ts +5 -2
  380. package/src/browser/architect-prompt-template.ts +7 -0
  381. package/src/browser/chat-session-item.tsx +2 -4
  382. package/src/browser/chat-session-list-service.ts +6 -3
  383. package/src/browser/code-reviewer-agent.ts +5 -2
  384. package/src/browser/coder-agent.ts +7 -5
  385. package/src/browser/context-file-validation-service-impl.spec.ts +3 -2
  386. package/src/browser/create-skill-agent.ts +5 -2
  387. package/src/browser/explore-agent.ts +5 -2
  388. package/src/browser/file-changeset-functions.spec.ts +158 -5
  389. package/src/browser/file-changeset-functions.ts +61 -23
  390. package/src/browser/frontend-module.ts +76 -63
  391. package/src/browser/github-chat-agent.ts +5 -2
  392. package/src/browser/github-repo-variable-contribution.ts +6 -3
  393. package/src/browser/ide-chat-welcome-message-provider.tsx +11 -11
  394. package/src/browser/memory-capability-contribution.spec.ts +85 -0
  395. package/src/browser/memory-capability-contribution.ts +86 -0
  396. package/src/browser/memory-directory-variable-contribution.spec.ts +113 -0
  397. package/src/browser/memory-directory-variable-contribution.ts +113 -0
  398. package/src/browser/open-editors-hint-contribution.ts +38 -0
  399. package/src/browser/project-info-agent.ts +5 -2
  400. package/src/browser/review/pr-review-agent.ts +5 -2
  401. package/src/browser/style/ai-configuration-base.css +0 -6
  402. package/src/browser/style/ai-configuration-shell.css +416 -0
  403. package/src/browser/style/ai-configuration-table.css +2 -15
  404. package/src/browser/style/index.css +220 -276
  405. package/src/browser/summarize-session-command-contribution.ts +6 -3
  406. package/src/browser/task-context-file-storage-service.ts +5 -2
  407. package/src/browser/user-interaction-tool.spec.ts +5 -2
  408. package/src/browser/user-interaction-tool.ts +6 -2
  409. package/src/browser/workspace-functions.spec.ts +163 -10
  410. package/src/browser/workspace-functions.ts +121 -72
  411. package/src/browser/workspace-launch-provider.spec.ts +4 -1
  412. package/src/browser/workspace-search-provider.spec.ts +1 -2
  413. package/src/browser/workspace-search-provider.ts +4 -7
  414. package/src/browser/workspace-task-provider.spec.ts +5 -1
  415. package/src/common/coder-replace-prompt-template.ts +9 -9
  416. package/src/common/command-chat-agents.ts +6 -2
  417. package/src/{browser/ai-configuration/base/ai-configuration-base-widget.tsx → common/open-editors-hint-fragment-id.ts} +2 -22
  418. package/src/common/orchestrator-chat-agent.ts +5 -2
  419. package/src/common/universal-chat-agent.ts +5 -2
  420. package/src/common/universal-prompt-template.ts +3 -0
  421. package/src/common/workspace-preferences.ts +2 -2
  422. package/src/common/workspace-search-provider-util.spec.ts +61 -0
  423. package/src/common/workspace-search-provider-util.ts +3 -2
  424. package/src/node/github-repo-service-impl.ts +6 -2
  425. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts +0 -72
  426. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +0 -1
  427. package/lib/browser/ai-configuration/agent-configuration-widget.js +0 -620
  428. package/lib/browser/ai-configuration/agent-configuration-widget.js.map +0 -1
  429. package/lib/browser/ai-configuration/agent-configuration-widget.spec.d.ts +0 -2
  430. package/lib/browser/ai-configuration/agent-configuration-widget.spec.d.ts.map +0 -1
  431. package/lib/browser/ai-configuration/agent-configuration-widget.spec.js +0 -56
  432. package/lib/browser/ai-configuration/agent-configuration-widget.spec.js.map +0 -1
  433. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts +0 -31
  434. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts.map +0 -1
  435. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js +0 -55
  436. package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js.map +0 -1
  437. package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts +0 -13
  438. package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts.map +0 -1
  439. package/lib/browser/ai-configuration/base/ai-configuration-base-widget.js.map +0 -1
  440. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts +0 -23
  441. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts.map +0 -1
  442. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js +0 -60
  443. package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js.map +0 -1
  444. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts +0 -55
  445. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts.map +0 -1
  446. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js +0 -96
  447. package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js.map +0 -1
  448. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts +0 -44
  449. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts.map +0 -1
  450. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js +0 -66
  451. package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js.map +0 -1
  452. package/lib/browser/ai-configuration/components/configuration-section.d.ts +0 -12
  453. package/lib/browser/ai-configuration/components/configuration-section.d.ts.map +0 -1
  454. package/lib/browser/ai-configuration/components/configuration-section.js.map +0 -1
  455. package/lib/browser/ai-configuration/components/empty-state.d.ts +0 -10
  456. package/lib/browser/ai-configuration/components/empty-state.d.ts.map +0 -1
  457. package/lib/browser/ai-configuration/components/empty-state.js.map +0 -1
  458. package/lib/browser/ai-configuration/components/expandable-section.d.ts +0 -13
  459. package/lib/browser/ai-configuration/components/expandable-section.d.ts.map +0 -1
  460. package/lib/browser/ai-configuration/components/expandable-section.js +0 -31
  461. package/lib/browser/ai-configuration/components/expandable-section.js.map +0 -1
  462. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts +0 -26
  463. package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts.map +0 -1
  464. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js +0 -198
  465. package/lib/browser/ai-configuration/model-aliases-configuration-widget.js.map +0 -1
  466. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts +0 -140
  467. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts.map +0 -1
  468. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +0 -508
  469. package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +0 -1
  470. package/lib/browser/ai-configuration/skills-configuration-widget.d.ts +0 -29
  471. package/lib/browser/ai-configuration/skills-configuration-widget.d.ts.map +0 -1
  472. package/lib/browser/ai-configuration/skills-configuration-widget.js +0 -166
  473. package/lib/browser/ai-configuration/skills-configuration-widget.js.map +0 -1
  474. package/lib/browser/ai-configuration/skills-configuration-widget.spec.d.ts +0 -2
  475. package/lib/browser/ai-configuration/skills-configuration-widget.spec.d.ts.map +0 -1
  476. package/lib/browser/ai-configuration/skills-configuration-widget.spec.js +0 -191
  477. package/lib/browser/ai-configuration/skills-configuration-widget.spec.js.map +0 -1
  478. package/lib/browser/ai-configuration/template-settings-renderer.d.ts +0 -9
  479. package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +0 -1
  480. package/lib/browser/ai-configuration/template-settings-renderer.js +0 -78
  481. package/lib/browser/ai-configuration/template-settings-renderer.js.map +0 -1
  482. package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts +0 -20
  483. package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts.map +0 -1
  484. package/lib/browser/ai-configuration/token-usage-configuration-widget.js +0 -170
  485. package/lib/browser/ai-configuration/token-usage-configuration-widget.js.map +0 -1
  486. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +0 -52
  487. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +0 -1
  488. package/lib/browser/ai-configuration/tools-configuration-widget.js +0 -357
  489. package/lib/browser/ai-configuration/tools-configuration-widget.js.map +0 -1
  490. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts +0 -22
  491. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts.map +0 -1
  492. package/lib/browser/ai-configuration/variable-configuration-widget.js +0 -133
  493. package/lib/browser/ai-configuration/variable-configuration-widget.js.map +0 -1
  494. package/src/browser/ai-configuration/agent-configuration-widget.spec.ts +0 -71
  495. package/src/browser/ai-configuration/agent-configuration-widget.tsx +0 -928
  496. package/src/browser/ai-configuration/base/ai-card-grid-configuration-widget.tsx +0 -72
  497. package/src/browser/ai-configuration/base/ai-hierarchical-configuration-widget.tsx +0 -51
  498. package/src/browser/ai-configuration/base/ai-list-detail-configuration-widget.tsx +0 -140
  499. package/src/browser/ai-configuration/base/ai-table-configuration-widget.tsx +0 -107
  500. package/src/browser/ai-configuration/components/expandable-section.tsx +0 -51
  501. package/src/browser/ai-configuration/model-aliases-configuration-widget.tsx +0 -270
  502. package/src/browser/ai-configuration/prompt-fragments-configuration-widget.tsx +0 -736
  503. package/src/browser/ai-configuration/skills-configuration-widget.spec.ts +0 -248
  504. package/src/browser/ai-configuration/skills-configuration-widget.tsx +0 -229
  505. package/src/browser/ai-configuration/template-settings-renderer.tsx +0 -125
  506. package/src/browser/ai-configuration/token-usage-configuration-widget.tsx +0 -214
  507. package/src/browser/ai-configuration/tools-configuration-widget.tsx +0 -544
  508. package/src/browser/ai-configuration/variable-configuration-widget.tsx +0 -159
  509. package/src/browser/style/ai-configuration-cards.css +0 -60
@@ -0,0 +1,431 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import {
18
+ AgentService,
19
+ AISettingsService,
20
+ AIVariableService,
21
+ CustomAgentsLocation,
22
+ FrontendLanguageModelRegistry,
23
+ LanguageModel,
24
+ LanguageModelRegistry,
25
+ NOTIFICATION_TYPES,
26
+ NOTIFICATION_TYPE_LABELS,
27
+ PREFERENCE_NAME_DEFAULT_NOTIFICATION_TYPE,
28
+ PromptFragmentCustomizationService,
29
+ PromptService,
30
+ ToolInvocationRegistry,
31
+ } from '@theia/ai-core/lib/common';
32
+ import { AGENT_SETTINGS_PREF } from '@theia/ai-core/lib/common/agent-preferences';
33
+ import { LanguageModelAlias, LanguageModelAliasRegistry } from '@theia/ai-core/lib/common/language-model-alias';
34
+ import { DEFAULT_CHAT_AGENT_PREF } from '@theia/ai-chat/lib/common/ai-chat-preferences';
35
+ import { isChatAgent } from '@theia/ai-chat/lib/common';
36
+ import { CommandService, DisposableCollection, Emitter, Event, ILogger, MessageService, nls, URI } from '@theia/core';
37
+ import { codicon, QuickInputService } from '@theia/core/lib/browser';
38
+ import { SelectOption } from '@theia/core/lib/browser/widgets/select-component';
39
+ import { inject, injectable, named, postConstruct } from '@theia/core/shared/inversify';
40
+ import * as React from '@theia/core/shared/react';
41
+ import {
42
+ AiConfigurationCategory,
43
+ AiConfigurationCategoryId,
44
+ AiConfigurationCategoryOrder,
45
+ AiConfigurationRenderContext,
46
+ AiConfigurationTools,
47
+ AiConfigurationSearchItem,
48
+ AiConfigurationSearchProvider,
49
+ AiConfigurationTreeItem
50
+ } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
51
+ import { CollectionCategoryRenderer, AiConfigurationAddDescriptor } from '@theia/ai-core-ui/lib/browser/ai-configuration/renderers/collection-category-renderer';
52
+ import { AiConfigurationSection } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-configuration-primitives';
53
+ import { AiSettingsRow } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-settings-row';
54
+ import { AiSettingsRowService } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-settings-row-service';
55
+ import { PREFERENCE_NAME_AGENT_MODE_ENABLED, PREFERENCE_NAME_ORCHESTRATOR_EXCLUSION_LIST } from '../../../common/ai-ide-preferences';
56
+ import { AgentDetailView } from './agent-detail-view';
57
+ import { PromptSnippetsConfiguration } from './prompt-snippets-configuration-category';
58
+ import { AgentDetailServices } from './agent-detail-model';
59
+ import { getAgentIconClass } from '../agent-icon';
60
+
61
+ /** A candidate location for creating a new custom agent: its scope directory and `agents/` folder. */
62
+ interface CustomAgentScopeOption {
63
+ scopeDir: URI;
64
+ agentsDir: URI;
65
+ }
66
+
67
+ /**
68
+ * The Agents category: a `collection` contributed onto the shared primitives.
69
+ * Owns the agent-related service logic (previously in `AIAgentConfigurationWidget`)
70
+ * and delegates the per-item detail to {@link AgentDetailView}.
71
+ */
72
+ @injectable()
73
+ export class AgentsConfigurationCategory extends CollectionCategoryRenderer implements AiConfigurationCategory, AiConfigurationSearchProvider {
74
+
75
+ readonly id = AiConfigurationCategoryId.AGENTS;
76
+ readonly label = nls.localizeByDefault('Agents');
77
+ readonly description = nls.localize('theia/ai/ide/agentsConfiguration/description',
78
+ 'The AI agents available in the IDE. Open an agent to configure its prompts, model and capabilities.');
79
+ readonly iconClass = codicon('copilot');
80
+ readonly order = AiConfigurationCategoryOrder.AGENTS;
81
+ readonly kind = 'collection' as const;
82
+
83
+ @inject(AgentService)
84
+ protected readonly agentService: AgentService;
85
+
86
+ @inject(LanguageModelRegistry)
87
+ protected readonly languageModelRegistry: FrontendLanguageModelRegistry;
88
+
89
+ @inject(PromptFragmentCustomizationService)
90
+ protected readonly promptFragmentCustomizationService: PromptFragmentCustomizationService;
91
+
92
+ @inject(LanguageModelAliasRegistry)
93
+ protected readonly languageModelAliasRegistry: LanguageModelAliasRegistry;
94
+
95
+ @inject(AISettingsService)
96
+ protected readonly aiSettingsService: AISettingsService;
97
+
98
+ @inject(AIVariableService)
99
+ protected readonly variableService: AIVariableService;
100
+
101
+ @inject(PromptService)
102
+ protected readonly promptService: PromptService;
103
+
104
+ @inject(QuickInputService)
105
+ protected readonly quickInputService: QuickInputService;
106
+
107
+ @inject(MessageService)
108
+ protected readonly messageService: MessageService;
109
+
110
+ @inject(AiSettingsRowService)
111
+ protected readonly settingsRowService: AiSettingsRowService;
112
+
113
+ @inject(ToolInvocationRegistry)
114
+ protected readonly toolInvocationRegistry: ToolInvocationRegistry;
115
+
116
+ @inject(CommandService)
117
+ protected readonly commandService: CommandService;
118
+
119
+ @inject(ILogger) @named('ai-ide:AgentsConfigurationCategory')
120
+ protected readonly logger: ILogger;
121
+
122
+ protected readonly onDidChangeEmitter = new Emitter<void>();
123
+ readonly onDidChange: Event<void> = this.onDidChangeEmitter.event;
124
+ protected readonly toDispose = new DisposableCollection(this.onDidChangeEmitter);
125
+
126
+ /** Category-wide caches consumed by the item detail; refreshed on the corresponding service events. */
127
+ protected languageModels: LanguageModel[] | undefined;
128
+ protected languageModelAliases: LanguageModelAlias[] = [];
129
+ /** Bumped on every upstream change so the item-detail view re-runs its async load. */
130
+ protected revision = 0;
131
+
132
+ get renderer(): this {
133
+ return this;
134
+ }
135
+
136
+ protected override get overviewListTitle(): string {
137
+ return nls.localizeByDefault('Agents');
138
+ }
139
+
140
+ getOwnedPreferenceIds(): string[] {
141
+ return [
142
+ DEFAULT_CHAT_AGENT_PREF,
143
+ PREFERENCE_NAME_DEFAULT_NOTIFICATION_TYPE,
144
+ PREFERENCE_NAME_ORCHESTRATOR_EXCLUSION_LIST,
145
+ PREFERENCE_NAME_AGENT_MODE_ENABLED,
146
+ // Per-agent settings storage; edited through the agent detail pages, not as a raw row.
147
+ AGENT_SETTINGS_PREF
148
+ ];
149
+ }
150
+
151
+ get search(): AiConfigurationSearchProvider {
152
+ return this;
153
+ }
154
+
155
+ @postConstruct()
156
+ protected init(): void {
157
+ this.languageModelRegistry.getLanguageModels().then(models => {
158
+ this.languageModels = models ?? [];
159
+ this.fireChange();
160
+ });
161
+ this.languageModelAliasRegistry.ready.then(() => {
162
+ this.languageModelAliases = this.languageModelAliasRegistry.getAliases();
163
+ this.toDispose.push(this.languageModelAliasRegistry.onDidChange(() => {
164
+ this.languageModelAliases = this.languageModelAliasRegistry.getAliases();
165
+ this.fireChange();
166
+ }));
167
+ this.fireChange();
168
+ });
169
+ this.toDispose.pushAll([
170
+ this.languageModelRegistry.onChange(({ models }) => {
171
+ this.languageModels = models;
172
+ this.fireChange();
173
+ }),
174
+ this.agentService.onDidChangeAgents(() => this.fireChange()),
175
+ this.promptService.onPromptsChange(() => this.fireChange()),
176
+ this.promptFragmentCustomizationService.onDidChangePromptFragmentCustomization(() => this.fireChange()),
177
+ this.aiSettingsService.onDidChange(() => this.fireChange())
178
+ ]);
179
+ }
180
+
181
+ protected fireChange(): void {
182
+ this.revision++;
183
+ this.onDidChangeEmitter.fire();
184
+ }
185
+
186
+ dispose(): void {
187
+ this.toDispose.dispose();
188
+ }
189
+
190
+ protected get categoryId(): string {
191
+ return this.id;
192
+ }
193
+
194
+ getTreeChildren(): AiConfigurationTreeItem[] {
195
+ return this.agentService.getAllAgents().map(agent => {
196
+ const enabled = this.agentService.isEnabled(agent.id);
197
+ return {
198
+ id: agent.id,
199
+ label: agent.name,
200
+ iconClass: getAgentIconClass(agent),
201
+ description: agent.description,
202
+ status: {
203
+ kind: enabled ? 'on' : 'off',
204
+ label: enabled ? nls.localizeByDefault('Enabled') : nls.localizeByDefault('Disabled')
205
+ }
206
+ } satisfies AiConfigurationTreeItem;
207
+ });
208
+ }
209
+
210
+ protected override renderCategorySettings(ctx: AiConfigurationRenderContext): React.ReactNode {
211
+ return <>
212
+ <AiConfigurationSection title={nls.localize('theia/ai/ide/agentConfiguration/behavior', 'Behavior')}>
213
+ <AiSettingsRow
214
+ service={this.settingsRowService}
215
+ preferenceId={PREFERENCE_NAME_AGENT_MODE_ENABLED}
216
+ label={nls.localize('theia/ai/ide/agentConfiguration/agentMode', 'Agent mode for Coder')}
217
+ scope={ctx.scope}
218
+ control={{ type: 'boolean' }}
219
+ onDidChange={ctx.update}
220
+ />
221
+ <AiSettingsRow
222
+ service={this.settingsRowService}
223
+ preferenceId={PREFERENCE_NAME_ORCHESTRATOR_EXCLUSION_LIST}
224
+ label={nls.localize('theia/ai/ide/agentConfiguration/orchestratorExclude', 'Agents hidden from the orchestrator')}
225
+ scope={ctx.scope}
226
+ control={{ type: 'array', placeholder: nls.localize('theia/ai/ide/agentConfiguration/orchestratorExcludePlaceholder', 'Add agent ID...') }}
227
+ onDidChange={ctx.update}
228
+ />
229
+ </AiConfigurationSection>
230
+ <AiConfigurationSection title={nls.localize('theia/ai/ide/agentConfiguration/defaults', 'Defaults')}>
231
+ <AiSettingsRow
232
+ service={this.settingsRowService}
233
+ preferenceId={DEFAULT_CHAT_AGENT_PREF}
234
+ label={nls.localize('theia/ai/ide/agentConfiguration/defaultChatAgent', 'Default Chat Agent')}
235
+ scope={ctx.scope}
236
+ control={{ type: 'select', options: this.getChatAgentOptions() }}
237
+ onDidChange={ctx.update}
238
+ />
239
+ <AiSettingsRow
240
+ service={this.settingsRowService}
241
+ preferenceId={PREFERENCE_NAME_DEFAULT_NOTIFICATION_TYPE}
242
+ scope={ctx.scope}
243
+ control={{ type: 'select', options: this.getNotificationTypeOptions() }}
244
+ onDidChange={ctx.update}
245
+ />
246
+ </AiConfigurationSection>
247
+ </>;
248
+ }
249
+
250
+ protected getChatAgentOptions(): SelectOption[] {
251
+ // Leading empty entry so the (optional) preference can show and select its unset state, where Theia's
252
+ // built-in defaults apply. Without it the select would fall back to showing the first agent when unset.
253
+ const none: SelectOption = {
254
+ value: '',
255
+ label: nls.localize('theia/ai/ide/agentConfiguration/defaultChatAgentNone', 'Built-in default'),
256
+ description: nls.localize('theia/ai/ide/agentConfiguration/defaultChatAgentNoneDescription',
257
+ 'No explicit default; Theia picks the default Chat Agent.')
258
+ };
259
+ return [none, ...this.agentService.getAllAgents()
260
+ .filter(agent => isChatAgent(agent))
261
+ .map(agent => ({ value: agent.id, label: agent.name }))];
262
+ }
263
+
264
+ protected getNotificationTypeOptions(): SelectOption[] {
265
+ return NOTIFICATION_TYPES.map(type => ({ value: type, label: NOTIFICATION_TYPE_LABELS[type] }));
266
+ }
267
+
268
+ override getAddAction(ctx: AiConfigurationRenderContext): AiConfigurationAddDescriptor {
269
+ return {
270
+ label: nls.localize('theia/ai/core/agentConfiguration/addCustomAgent', 'Add Custom Agent'),
271
+ iconClass: codicon('add'),
272
+ run: () => this.addCustomAgent()
273
+ };
274
+ }
275
+
276
+ protected override getEmptyMessage(): string {
277
+ return nls.localize('theia/ai/ide/agentConfiguration/noAgents', 'No agents are available.');
278
+ }
279
+
280
+ protected override renderItemHeader(): React.ReactNode {
281
+ // The detail view renders its own header (with the enable / show-in-chat toggles).
282
+ return undefined;
283
+ }
284
+
285
+ protected renderItemSections(item: AiConfigurationTreeItem, ctx: AiConfigurationRenderContext): React.ReactNode {
286
+ const agent = this.agentService.getAllAgents().find(candidate => candidate.id === item.id);
287
+ if (!agent) {
288
+ return undefined;
289
+ }
290
+ return <AgentDetailView
291
+ agent={agent}
292
+ services={this.detailServices}
293
+ languageModels={this.languageModels}
294
+ languageModelAliases={this.languageModelAliases}
295
+ revision={this.revision}
296
+ onOpenPromptSnippet={fragmentId => ctx.navigate(PromptSnippetsConfiguration.selectionFor(fragmentId))}
297
+ onOpenTool={toolName => ctx.navigate(AiConfigurationTools.selectionFor(toolName))}
298
+ />;
299
+ }
300
+
301
+ protected get detailServices(): AgentDetailServices {
302
+ return {
303
+ agentService: this.agentService,
304
+ aiSettingsService: this.aiSettingsService,
305
+ variableService: this.variableService,
306
+ promptService: this.promptService,
307
+ languageModelRegistry: this.languageModelRegistry,
308
+ toolInvocationRegistry: this.toolInvocationRegistry,
309
+ commandService: this.commandService,
310
+ settingsRowService: this.settingsRowService,
311
+ logger: this.logger
312
+ };
313
+ }
314
+
315
+ getSearchItems(): AiConfigurationSearchItem[] {
316
+ const settingLabel = nls.localizeByDefault('Setting');
317
+ const items: AiConfigurationSearchItem[] = [{
318
+ label: nls.localize('theia/ai/ide/agentConfiguration/agentMode', 'Agent mode for Coder'),
319
+ typeLabel: settingLabel,
320
+ categoryId: this.id,
321
+ target: { categoryId: this.id },
322
+ keywords: PREFERENCE_NAME_AGENT_MODE_ENABLED
323
+ }, {
324
+ label: nls.localize('theia/ai/ide/agentConfiguration/orchestratorExclude', 'Agents hidden from the orchestrator'),
325
+ typeLabel: settingLabel,
326
+ categoryId: this.id,
327
+ target: { categoryId: this.id, highlight: { rowId: PREFERENCE_NAME_ORCHESTRATOR_EXCLUSION_LIST } },
328
+ keywords: PREFERENCE_NAME_ORCHESTRATOR_EXCLUSION_LIST
329
+ }, {
330
+ label: nls.localize('theia/ai/ide/agentConfiguration/defaultChatAgent', 'Default Chat Agent'),
331
+ typeLabel: settingLabel,
332
+ categoryId: this.id,
333
+ target: { categoryId: this.id, highlight: { rowId: DEFAULT_CHAT_AGENT_PREF } },
334
+ keywords: DEFAULT_CHAT_AGENT_PREF
335
+ }, {
336
+ label: nls.localize('theia/ai/core/defaultNotification/title', 'Default Notification Type'),
337
+ typeLabel: settingLabel,
338
+ categoryId: this.id,
339
+ target: { categoryId: this.id, highlight: { rowId: PREFERENCE_NAME_DEFAULT_NOTIFICATION_TYPE } },
340
+ keywords: PREFERENCE_NAME_DEFAULT_NOTIFICATION_TYPE
341
+ }];
342
+ const agentTypeLabel = nls.localizeByDefault('Agent');
343
+ for (const agent of this.agentService.getAllAgents()) {
344
+ items.push({
345
+ label: agent.name,
346
+ typeLabel: agentTypeLabel,
347
+ categoryId: this.id,
348
+ target: { categoryId: this.id, itemId: agent.id },
349
+ keywords: `${agent.id} ${agent.description ?? ''}`
350
+ });
351
+ }
352
+ return items;
353
+ }
354
+
355
+ /**
356
+ * Selects the candidate creation locations from the reported agent locations. Only `agents/`
357
+ * directories are considered (legacy `customAgents.yml` entries exist for discovery only). A
358
+ * scope is offered when it already contains an `agents/` folder; the preferred scope (the first
359
+ * one, i.e. `.agents`) is always kept so a fresh workspace defaults to `.agents` without
360
+ * surfacing empty fallback folders such as `.prompts`.
361
+ */
362
+ protected selectAgentScopeOptions(locations: CustomAgentsLocation[]): CustomAgentScopeOption[] {
363
+ return locations
364
+ .filter(location => location.kind === 'agents-dir')
365
+ .filter((location, index) => index === 0 || location.exists)
366
+ .map(location => ({ scopeDir: location.uri.parent, agentsDir: location.uri }));
367
+ }
368
+
369
+ protected async addCustomAgent(): Promise<void> {
370
+ const allLocations = await this.promptFragmentCustomizationService.getCustomAgentsLocations();
371
+ const scopeOptions = this.selectAgentScopeOptions(allLocations);
372
+ if (scopeOptions.length === 0) {
373
+ this.messageService.warn(nls.localize('theia/ai/ide/agentConfiguration/newAgent/noLocation',
374
+ 'Cannot create a custom agent: no prompt-templates location is configured. Set a global or workspace prompt-templates folder and try again.'));
375
+ return;
376
+ }
377
+
378
+ let chosen = scopeOptions[0];
379
+ if (scopeOptions.length > 1) {
380
+ chosen = await new Promise<CustomAgentScopeOption>((resolve, reject) => {
381
+ const quickPick = this.quickInputService.createQuickPick();
382
+ quickPick.title = nls.localize('theia/ai/ide/agentConfiguration/customAgentLocationQuickPick/title',
383
+ 'Select location for the new custom agent');
384
+ quickPick.placeholder = nls.localize('theia/ai/ide/agentConfiguration/customAgentLocationQuickPick/placeholder',
385
+ 'Choose where to create the agents/<id>/agent.md file');
386
+ quickPick.items = scopeOptions.map(opt => ({
387
+ label: opt.scopeDir.path.toString(),
388
+ description: opt.agentsDir.path.toString(),
389
+ option: opt
390
+ }));
391
+ quickPick.onDidAccept(() => {
392
+ const selected = quickPick.selectedItems[0] as unknown as { option: CustomAgentScopeOption };
393
+ quickPick.dispose();
394
+ if (selected?.option) {
395
+ resolve(selected.option);
396
+ } else {
397
+ reject(new Error('No location selected'));
398
+ }
399
+ });
400
+ quickPick.onDidHide(() => reject(new Error('Selection cancelled')));
401
+ quickPick.show();
402
+ }).catch(() => undefined) ?? scopeOptions[0];
403
+ }
404
+
405
+ const id = await this.quickInputService.input({
406
+ title: nls.localize('theia/ai/ide/agentConfiguration/newAgent/idTitle', 'New custom agent'),
407
+ prompt: nls.localize('theia/ai/ide/agentConfiguration/newAgent/idPrompt', 'Agent id (used as folder name under agents/)'),
408
+ placeHolder: 'my-agent',
409
+ validateInput: async value => /^[A-Za-z0-9._-]+$/.test(value)
410
+ ? undefined
411
+ : nls.localize('theia/ai/ide/agentConfiguration/newAgent/idInvalid', 'Use letters, digits, dash, underscore, or dot only.')
412
+ });
413
+ if (!id) {
414
+ return;
415
+ }
416
+
417
+ try {
418
+ await this.promptFragmentCustomizationService.createCustomAgentFile(chosen.scopeDir, {
419
+ id,
420
+ name: id,
421
+ description: nls.localize('theia/ai/ide/agentConfiguration/newAgent/defaultDescription', 'Custom agent. Edit this description in agent.md.'),
422
+ prompt: nls.localize('theia/ai/ide/agentConfiguration/newAgent/defaultPrompt', 'You are a helpful agent. Adjust this prompt to fit your needs.'),
423
+ defaultLLM: 'default/universal',
424
+ showInChat: true
425
+ });
426
+ } catch (error) {
427
+ this.messageService.error(nls.localize('theia/ai/ide/agentConfiguration/newAgent/createFailed',
428
+ 'Could not create the custom agent "{0}": {1}', id, error instanceof Error ? error.message : String(error)));
429
+ }
430
+ }
431
+ }
@@ -0,0 +1,225 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
18
+ let disableJSDOM = enableJSDOM();
19
+
20
+ // @lumino/dragdrop (pulled in transitively via the file dialog service) extends the DragEvent DOM
21
+ // global at module load, which JSDOM does not provide; stub it so the import succeeds.
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ if (!(global as any).DragEvent) {
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ (global as any).DragEvent = class DragEvent extends (global as any).Event { };
26
+ }
27
+
28
+ import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
29
+ FrontendApplicationConfigProvider.set({});
30
+
31
+ import { expect } from 'chai';
32
+ import { createRoot } from '@theia/core/shared/react-dom/client';
33
+ import { flushSync } from '@theia/core/shared/react-dom';
34
+ import { SelectOption } from '@theia/core/lib/browser/widgets/select-component';
35
+ import { AiSettingsRowService } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-settings-row-service';
36
+ import { AiConfigurationCategoryId, AiConfigurationRenderContext } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
37
+ import { PREFERENCE_NAME_ENABLE_AI } from '../../../common/ai-ide-preferences';
38
+ import { GeneralConfigurationCategory } from './general-configuration-category';
39
+
40
+ disableJSDOM();
41
+
42
+ /** A preference id no category claims, so it renders through the General catch-all. */
43
+ const UNCLAIMED_PREF = 'ai-features.codeCompletion.enabled';
44
+
45
+ /**
46
+ * A category whose stub service is complete enough to render the whole page, so the tests can assert on
47
+ * the produced DOM rather than only on the render inputs.
48
+ */
49
+ function createRenderableCategory(enabled: boolean): GeneralConfigurationCategory {
50
+ const category = new GeneralConfigurationCategory();
51
+ const values: Record<string, unknown> = { [PREFERENCE_NAME_ENABLE_AI]: enabled };
52
+ const service: Partial<AiSettingsRowService> = {
53
+ inspect: (preferenceId: string) => ({
54
+ value: values[preferenceId],
55
+ scopeValue: values[preferenceId],
56
+ defaultValue: undefined,
57
+ modified: false
58
+ }),
59
+ describe: (preferenceId: string) => ({ label: `label:${preferenceId}`, description: `description:${preferenceId}` }),
60
+ tags: (): string[] => [],
61
+ renderMarkdown: (markdown: string) => {
62
+ const element = document.createElement('span');
63
+ element.textContent = markdown;
64
+ return element;
65
+ },
66
+ controlFor: () => ({ type: 'boolean' }),
67
+ enumOptions: (): SelectOption[] => [],
68
+ aiFeaturePreferenceIds: (): string[] => [UNCLAIMED_PREF]
69
+ };
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ (category as any).settingsRowService = service;
72
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
+ (category as any).categoryRegistry = { getCategories: () => [] };
74
+ return category;
75
+ }
76
+
77
+ /** Renders the category's page into a detached container; the caller disposes it. */
78
+ function renderPage(category: GeneralConfigurationCategory): { container: HTMLElement; dispose: () => void } {
79
+ const container = document.createElement('div');
80
+ document.body.appendChild(container);
81
+ const root = createRoot(container);
82
+ const ctx: AiConfigurationRenderContext = { scope: 'user', navigate: () => { }, update: () => { } };
83
+ flushSync(() => root.render(category.renderPage(ctx)));
84
+ return {
85
+ container,
86
+ dispose: () => {
87
+ flushSync(() => root.unmount());
88
+ container.remove();
89
+ }
90
+ };
91
+ }
92
+
93
+ /** A stub settings-row service that echoes the preference id as its label and declares no enums. */
94
+ function createCategory(): GeneralConfigurationCategory {
95
+ const category = new GeneralConfigurationCategory();
96
+ const service: Partial<AiSettingsRowService> = {
97
+ describe: (preferenceId: string) => ({ label: `label:${preferenceId}` }),
98
+ enumOptions: (): SelectOption[] => [],
99
+ // No unclaimed preferences in this stub, so the catch-all contributes nothing.
100
+ aiFeaturePreferenceIds: (): string[] => []
101
+ };
102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
+ (category as any).settingsRowService = service;
104
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
+ (category as any).categoryRegistry = { getCategories: () => [] };
106
+ return category;
107
+ }
108
+
109
+ describe('GeneralConfigurationCategory', () => {
110
+
111
+ before(() => {
112
+ disableJSDOM = enableJSDOM();
113
+ // The config is stored on `window`, which the line above replaces, so the module-level `set` no
114
+ // longer applies. The hero reads `applicationName` from it while rendering.
115
+ try {
116
+ FrontendApplicationConfigProvider.get();
117
+ } catch {
118
+ FrontendApplicationConfigProvider.set({});
119
+ }
120
+ });
121
+ after(() => disableJSDOM());
122
+
123
+ it('declares the general single-page metadata', () => {
124
+ const category = createCategory();
125
+ expect(category.id).to.equal(AiConfigurationCategoryId.GENERAL);
126
+ expect(category.kind).to.equal('single-page');
127
+ expect(category.renderer).to.equal(category);
128
+ expect(category.search).to.equal(category);
129
+ });
130
+
131
+ it('the catch-all surfaces every ai-features preference that no category claims (nothing is lost from the view)', () => {
132
+ const category = new GeneralConfigurationCategory();
133
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
134
+ (category as any).settingsRowService = {
135
+ aiFeaturePreferenceIds: (): string[] => ['ai-features.chat.a', 'ai-features.foo.b', 'ai-features.bar.c']
136
+ };
137
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
+ (category as any).categoryRegistry = {
139
+ getCategories: () => [
140
+ { renderer: { getOwnedPreferenceIds: () => ['ai-features.foo.b'] } },
141
+ { renderer: {} } // a category that owns nothing
142
+ ]
143
+ };
144
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
145
+ const unclaimed = (category as any).unclaimedPreferenceIds() as string[];
146
+ expect([...unclaimed].sort()).to.deep.equal(['ai-features.bar.c', 'ai-features.chat.a']);
147
+ });
148
+
149
+ it('indexes one search item per setting, deep-linking to the row', () => {
150
+ const category = createCategory();
151
+ const items = category.getSearchItems();
152
+ // master toggle (hero) + Chat (5)
153
+ expect(items).to.have.lengthOf(6);
154
+ const enableAi = items.find(item => item.keywords?.startsWith('ai-features.AiEnable.enableAI'));
155
+ expect(enableAi).to.not.equal(undefined);
156
+ // The master toggle authors its own title, so it does not fall back to the schema label.
157
+ expect(enableAi!.label).to.equal('Enable AI features');
158
+ expect(enableAi!.target).to.deep.equal({
159
+ categoryId: AiConfigurationCategoryId.GENERAL,
160
+ highlight: { rowId: 'ai-features.AiEnable.enableAI' }
161
+ });
162
+ });
163
+
164
+ describe('rendered page', () => {
165
+
166
+ it('anchors every row its search index deep-links to', () => {
167
+ // The two halves of a deep link are produced independently: `getSearchItems` names a `rowId`
168
+ // and the page has to emit a matching `data-ai-config-row-id`. Nothing else ties them together,
169
+ // so a row indexed but not anchored (as the hero toggle was) silently never scrolls or flashes.
170
+ const category = createRenderableCategory(true);
171
+ const { container, dispose } = renderPage(category);
172
+ try {
173
+ const anchored = new Set(Array.from(container.querySelectorAll('[data-ai-config-row-id]'))
174
+ .map(element => element.getAttribute('data-ai-config-row-id')));
175
+ const deepLinked = category.getSearchItems()
176
+ .map(item => item.target.highlight?.rowId)
177
+ .filter((rowId): rowId is string => rowId !== undefined);
178
+ expect(deepLinked, 'the search index deep-links to no rows at all').to.not.be.empty;
179
+ const unanchored = deepLinked.filter(rowId => !anchored.has(rowId));
180
+ expect(unanchored, `search items deep-link to rows the page never anchors: ${unanchored.join(', ')}`).to.be.empty;
181
+ } finally {
182
+ dispose();
183
+ }
184
+ });
185
+
186
+ it('does not print the raw preference id next to the hero title', () => {
187
+ const category = createRenderableCategory(true);
188
+ const { container, dispose } = renderPage(category);
189
+ try {
190
+ const title = container.querySelector('.ai-configuration-hero .ai-settings-row-title');
191
+ expect(title, 'the hero renders no title').to.exist;
192
+ expect(title!.textContent).to.not.contain('ai-features.');
193
+ } finally {
194
+ dispose();
195
+ }
196
+ });
197
+
198
+ it('renders the catch-all rows read-only while AI features are off', () => {
199
+ // The gate note promises the settings below take effect once AI is enabled, so they must not be
200
+ // editable meanwhile. The catch-all rows are generated, so they do not inherit the hand-authored
201
+ // rows' `disabled` state unless it is plumbed through `AiSettingsRow`.
202
+ const off = createRenderableCategory(false);
203
+ const rendered = renderPage(off);
204
+ try {
205
+ const control = rendered.container.querySelector<HTMLInputElement>(`[data-ai-config-row-id="${UNCLAIMED_PREF}"] input`);
206
+ expect(control, 'the catch-all row renders no control').to.exist;
207
+ expect(control!.disabled).to.equal(true);
208
+ } finally {
209
+ rendered.dispose();
210
+ }
211
+ });
212
+
213
+ it('renders the catch-all rows editable once AI features are on', () => {
214
+ const on = createRenderableCategory(true);
215
+ const rendered = renderPage(on);
216
+ try {
217
+ const control = rendered.container.querySelector<HTMLInputElement>(`[data-ai-config-row-id="${UNCLAIMED_PREF}"] input`);
218
+ expect(control, 'the catch-all row renders no control').to.exist;
219
+ expect(control!.disabled).to.equal(false);
220
+ } finally {
221
+ rendered.dispose();
222
+ }
223
+ });
224
+ });
225
+ });