@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.
- package/lib/browser/ai-allow-all-mode-chat-banner.js +2 -20
- package/lib/browser/ai-allow-all-mode-chat-banner.js.map +1 -1
- package/lib/browser/ai-configuration/agent-icon.d.ts +16 -0
- package/lib/browser/ai-configuration/agent-icon.d.ts.map +1 -0
- package/lib/browser/ai-configuration/agent-icon.js +38 -0
- package/lib/browser/ai-configuration/agent-icon.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.d.ts +36 -0
- package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.js +163 -0
- package/lib/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts +50 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.js +208 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js +139 -0
- package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.d.ts +13 -0
- package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.js +48 -0
- package/lib/browser/ai-configuration/ai-configuration-label-provider-contribution.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.d.ts +22 -0
- package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.js +72 -0
- package/lib/browser/ai-configuration/ai-configuration-open-preference-renderer.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.js +126 -0
- package/lib/browser/ai-configuration/ai-configuration-preference-ownership.spec.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-resource.d.ts +10 -0
- package/lib/browser/ai-configuration/ai-configuration-resource.d.ts.map +1 -0
- package/lib/browser/ai-configuration/{components/configuration-section.js → ai-configuration-resource.js} +11 -11
- package/lib/browser/ai-configuration/ai-configuration-resource.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-search-widget.d.ts +29 -0
- package/lib/browser/ai-configuration/ai-configuration-search-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-search-widget.js +106 -0
- package/lib/browser/ai-configuration/ai-configuration-search-widget.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-search.d.ts +18 -0
- package/lib/browser/ai-configuration/ai-configuration-search.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-search.js +45 -0
- package/lib/browser/ai-configuration/ai-configuration-search.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-search.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/ai-configuration-search.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-search.spec.js +79 -0
- package/lib/browser/ai-configuration/ai-configuration-search.spec.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-model.d.ts +8 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-model.d.ts.map +1 -0
- package/lib/browser/ai-configuration/{base/ai-configuration-base-widget.js → ai-configuration-tree-model.js} +11 -14
- package/lib/browser/ai-configuration/ai-configuration-tree-model.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.d.ts +57 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.js +134 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.js +134 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-nodes.spec.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts +96 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-widget.js +407 -0
- package/lib/browser/ai-configuration/ai-configuration-tree-widget.js.map +1 -0
- package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts +38 -4
- package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-view-contribution.js +151 -19
- package/lib/browser/ai-configuration/ai-configuration-view-contribution.js.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-widget.d.ts +21 -23
- package/lib/browser/ai-configuration/ai-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-widget.js +102 -70
- package/lib/browser/ai-configuration/ai-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.d.ts +56 -0
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js +195 -0
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.js +140 -0
- package/lib/browser/ai-configuration/categories/agent-capabilities-settings.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-chips.d.ts +15 -0
- package/lib/browser/ai-configuration/categories/agent-chips.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-chips.js +19 -0
- package/lib/browser/ai-configuration/categories/agent-chips.js.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-detail-model.d.ts +37 -0
- package/lib/browser/ai-configuration/categories/agent-detail-model.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-detail-model.js +99 -0
- package/lib/browser/ai-configuration/categories/agent-detail-model.js.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-detail-view.d.ts +28 -0
- package/lib/browser/ai-configuration/categories/agent-detail-view.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/agent-detail-view.js +135 -0
- package/lib/browser/ai-configuration/categories/agent-detail-view.js.map +1 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.d.ts +78 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.js +352 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.js +99 -0
- package/lib/browser/ai-configuration/categories/agents-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.d.ts +93 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.js +313 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.spec.js +213 -0
- package/lib/browser/ai-configuration/categories/general-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts +53 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js +241 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js +75 -0
- package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts +72 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.js +227 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js +145 -0
- package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.d.ts +114 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.js +341 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.js +199 -0
- package/lib/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.d.ts +84 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.js +341 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.js +184 -0
- package/lib/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.d.ts +38 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.js +130 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.js +51 -0
- package/lib/browser/ai-configuration/categories/token-usage-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.d.ts +60 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.js +302 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.js +111 -0
- package/lib/browser/ai-configuration/categories/tools-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.d.ts +72 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.js +245 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.js.map +1 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.js +131 -0
- package/lib/browser/ai-configuration/categories/variables-configuration-category.spec.js.map +1 -0
- package/lib/browser/ai-configuration/components/agent-notification-settings.d.ts +6 -2
- package/lib/browser/ai-configuration/components/agent-notification-settings.d.ts.map +1 -1
- package/lib/browser/ai-configuration/components/agent-notification-settings.js +15 -21
- package/lib/browser/ai-configuration/components/agent-notification-settings.js.map +1 -1
- package/lib/browser/ai-configuration/language-model-renderer.d.ts +25 -1
- package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -1
- package/lib/browser/ai-configuration/language-model-renderer.js +159 -63
- package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -1
- package/lib/browser/ai-configuration/language-model-renderer.spec.d.ts +2 -0
- package/lib/browser/ai-configuration/language-model-renderer.spec.d.ts.map +1 -0
- package/lib/browser/ai-configuration/language-model-renderer.spec.js +93 -0
- package/lib/browser/ai-configuration/language-model-renderer.spec.js.map +1 -0
- package/lib/browser/ai-sessions-widget.js +12 -16
- package/lib/browser/ai-sessions-widget.js.map +1 -1
- package/lib/browser/app-tester-chat-agent.d.ts +2 -0
- package/lib/browser/app-tester-chat-agent.d.ts.map +1 -1
- package/lib/browser/app-tester-chat-agent.js +5 -0
- package/lib/browser/app-tester-chat-agent.js.map +1 -1
- package/lib/browser/architect-agent.d.ts +2 -0
- package/lib/browser/architect-agent.d.ts.map +1 -1
- package/lib/browser/architect-agent.js +5 -0
- package/lib/browser/architect-agent.js.map +1 -1
- package/lib/browser/architect-prompt-template.d.ts.map +1 -1
- package/lib/browser/architect-prompt-template.js +7 -0
- package/lib/browser/architect-prompt-template.js.map +1 -1
- package/lib/browser/chat-session-item.d.ts.map +1 -1
- package/lib/browser/chat-session-item.js +17 -30
- package/lib/browser/chat-session-item.js.map +1 -1
- package/lib/browser/chat-session-list-components.js +7 -30
- package/lib/browser/chat-session-list-components.js.map +1 -1
- package/lib/browser/chat-session-list-service.d.ts +2 -1
- package/lib/browser/chat-session-list-service.d.ts.map +1 -1
- package/lib/browser/chat-session-list-service.js +6 -1
- package/lib/browser/chat-session-list-service.js.map +1 -1
- package/lib/browser/chat-sessions-welcome-message-provider.js +3 -21
- package/lib/browser/chat-sessions-welcome-message-provider.js.map +1 -1
- package/lib/browser/code-reviewer-agent.d.ts +2 -0
- package/lib/browser/code-reviewer-agent.d.ts.map +1 -1
- package/lib/browser/code-reviewer-agent.js +5 -0
- package/lib/browser/code-reviewer-agent.js.map +1 -1
- package/lib/browser/coder-agent.d.ts +2 -0
- package/lib/browser/coder-agent.d.ts.map +1 -1
- package/lib/browser/coder-agent.js +6 -1
- package/lib/browser/coder-agent.js.map +1 -1
- package/lib/browser/context-file-validation-service-impl.spec.js +2 -0
- package/lib/browser/context-file-validation-service-impl.spec.js.map +1 -1
- package/lib/browser/create-skill-agent.d.ts +2 -0
- package/lib/browser/create-skill-agent.d.ts.map +1 -1
- package/lib/browser/create-skill-agent.js +5 -0
- package/lib/browser/create-skill-agent.js.map +1 -1
- package/lib/browser/explore-agent.d.ts +2 -0
- package/lib/browser/explore-agent.d.ts.map +1 -1
- package/lib/browser/explore-agent.js +5 -0
- package/lib/browser/explore-agent.js.map +1 -1
- package/lib/browser/file-changeset-functions.d.ts +7 -1
- package/lib/browser/file-changeset-functions.d.ts.map +1 -1
- package/lib/browser/file-changeset-functions.js +62 -20
- package/lib/browser/file-changeset-functions.js.map +1 -1
- package/lib/browser/file-changeset-functions.spec.js +130 -1
- package/lib/browser/file-changeset-functions.spec.js.map +1 -1
- package/lib/browser/frontend-module.d.ts.map +1 -1
- package/lib/browser/frontend-module.js +65 -59
- package/lib/browser/frontend-module.js.map +1 -1
- package/lib/browser/github-chat-agent.d.ts +2 -1
- package/lib/browser/github-chat-agent.d.ts.map +1 -1
- package/lib/browser/github-chat-agent.js +5 -0
- package/lib/browser/github-chat-agent.js.map +1 -1
- package/lib/browser/github-repo-variable-contribution.d.ts +2 -1
- package/lib/browser/github-repo-variable-contribution.d.ts.map +1 -1
- package/lib/browser/github-repo-variable-contribution.js +6 -1
- package/lib/browser/github-repo-variable-contribution.js.map +1 -1
- package/lib/browser/ide-chat-welcome-message-provider.d.ts.map +1 -1
- package/lib/browser/ide-chat-welcome-message-provider.js +31 -118
- package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
- package/lib/browser/memory-capability-contribution.d.ts +8 -0
- package/lib/browser/memory-capability-contribution.d.ts.map +1 -0
- package/lib/browser/memory-capability-contribution.js +88 -0
- package/lib/browser/memory-capability-contribution.js.map +1 -0
- package/lib/browser/memory-capability-contribution.spec.d.ts +2 -0
- package/lib/browser/memory-capability-contribution.spec.d.ts.map +1 -0
- package/lib/browser/memory-capability-contribution.spec.js +74 -0
- package/lib/browser/memory-capability-contribution.spec.js.map +1 -0
- package/lib/browser/memory-directory-variable-contribution.d.ts +41 -0
- package/lib/browser/memory-directory-variable-contribution.d.ts.map +1 -0
- package/lib/browser/memory-directory-variable-contribution.js +107 -0
- package/lib/browser/memory-directory-variable-contribution.js.map +1 -0
- package/lib/browser/memory-directory-variable-contribution.spec.d.ts +2 -0
- package/lib/browser/memory-directory-variable-contribution.spec.d.ts.map +1 -0
- package/lib/browser/memory-directory-variable-contribution.spec.js +98 -0
- package/lib/browser/memory-directory-variable-contribution.spec.js.map +1 -0
- package/lib/browser/open-editors-hint-contribution.d.ts +7 -0
- package/lib/browser/open-editors-hint-contribution.d.ts.map +1 -0
- package/lib/browser/open-editors-hint-contribution.js +43 -0
- package/lib/browser/open-editors-hint-contribution.js.map +1 -0
- package/lib/browser/project-info-agent.d.ts +2 -0
- package/lib/browser/project-info-agent.d.ts.map +1 -1
- package/lib/browser/project-info-agent.js +5 -0
- package/lib/browser/project-info-agent.js.map +1 -1
- package/lib/browser/review/pr-review-agent.d.ts +2 -0
- package/lib/browser/review/pr-review-agent.d.ts.map +1 -1
- package/lib/browser/review/pr-review-agent.js +5 -0
- package/lib/browser/review/pr-review-agent.js.map +1 -1
- package/lib/browser/summarize-session-command-contribution.d.ts +2 -1
- package/lib/browser/summarize-session-command-contribution.d.ts.map +1 -1
- package/lib/browser/summarize-session-command-contribution.js +6 -1
- package/lib/browser/summarize-session-command-contribution.js.map +1 -1
- package/lib/browser/task-context-file-storage-service.d.ts.map +1 -1
- package/lib/browser/task-context-file-storage-service.js +1 -0
- package/lib/browser/task-context-file-storage-service.js.map +1 -1
- package/lib/browser/todo-tool-renderer.js +11 -19
- package/lib/browser/todo-tool-renderer.js.map +1 -1
- package/lib/browser/user-interaction-tool-renderer.js +39 -83
- package/lib/browser/user-interaction-tool-renderer.js.map +1 -1
- package/lib/browser/user-interaction-tool.d.ts +2 -0
- package/lib/browser/user-interaction-tool.d.ts.map +1 -1
- package/lib/browser/user-interaction-tool.js +7 -1
- package/lib/browser/user-interaction-tool.js.map +1 -1
- package/lib/browser/user-interaction-tool.spec.js +4 -2
- package/lib/browser/user-interaction-tool.spec.js.map +1 -1
- package/lib/browser/workspace-functions.d.ts +45 -7
- package/lib/browser/workspace-functions.d.ts.map +1 -1
- package/lib/browser/workspace-functions.js +108 -70
- package/lib/browser/workspace-functions.js.map +1 -1
- package/lib/browser/workspace-functions.spec.js +139 -9
- package/lib/browser/workspace-functions.spec.js.map +1 -1
- package/lib/browser/workspace-launch-provider.spec.js +3 -0
- package/lib/browser/workspace-launch-provider.spec.js.map +1 -1
- package/lib/browser/workspace-search-provider.d.ts.map +1 -1
- package/lib/browser/workspace-search-provider.js +4 -7
- package/lib/browser/workspace-search-provider.js.map +1 -1
- package/lib/browser/workspace-search-provider.spec.js +1 -2
- package/lib/browser/workspace-search-provider.spec.js.map +1 -1
- package/lib/browser/workspace-task-provider.spec.js +4 -0
- package/lib/browser/workspace-task-provider.spec.js.map +1 -1
- package/lib/common/coder-replace-prompt-template.d.ts +0 -2
- package/lib/common/coder-replace-prompt-template.d.ts.map +1 -1
- package/lib/common/coder-replace-prompt-template.js +10 -11
- package/lib/common/coder-replace-prompt-template.js.map +1 -1
- package/lib/common/command-chat-agents.d.ts +2 -1
- package/lib/common/command-chat-agents.d.ts.map +1 -1
- package/lib/common/command-chat-agents.js +6 -1
- package/lib/common/command-chat-agents.js.map +1 -1
- package/lib/common/open-editors-hint-fragment-id.d.ts +2 -0
- package/lib/common/open-editors-hint-fragment-id.d.ts.map +1 -0
- package/lib/{browser/ai-configuration/components/empty-state.js → common/open-editors-hint-fragment-id.js} +5 -11
- package/lib/common/open-editors-hint-fragment-id.js.map +1 -0
- package/lib/common/orchestrator-chat-agent.d.ts +2 -1
- package/lib/common/orchestrator-chat-agent.d.ts.map +1 -1
- package/lib/common/orchestrator-chat-agent.js +5 -0
- package/lib/common/orchestrator-chat-agent.js.map +1 -1
- package/lib/common/universal-chat-agent.d.ts +2 -0
- package/lib/common/universal-chat-agent.d.ts.map +1 -1
- package/lib/common/universal-chat-agent.js +5 -0
- package/lib/common/universal-chat-agent.js.map +1 -1
- package/lib/common/universal-prompt-template.d.ts.map +1 -1
- package/lib/common/universal-prompt-template.js +3 -0
- package/lib/common/universal-prompt-template.js.map +1 -1
- package/lib/common/workspace-preferences.js +2 -2
- package/lib/common/workspace-preferences.js.map +1 -1
- package/lib/common/workspace-search-provider-util.d.ts +2 -1
- package/lib/common/workspace-search-provider-util.d.ts.map +1 -1
- package/lib/common/workspace-search-provider-util.js +3 -2
- package/lib/common/workspace-search-provider-util.js.map +1 -1
- package/lib/common/workspace-search-provider-util.spec.d.ts +2 -0
- package/lib/common/workspace-search-provider-util.spec.d.ts.map +1 -0
- package/lib/common/workspace-search-provider-util.spec.js +55 -0
- package/lib/common/workspace-search-provider-util.spec.js.map +1 -0
- package/lib/node/github-repo-service-impl.d.ts +2 -0
- package/lib/node/github-repo-service-impl.d.ts.map +1 -1
- package/lib/node/github-repo-service-impl.js +7 -1
- package/lib/node/github-repo-service-impl.js.map +1 -1
- package/package.json +26 -25
- package/src/browser/ai-configuration/agent-icon.ts +37 -0
- package/src/browser/ai-configuration/ai-configuration-breadcrumbs-contribution.ts +164 -0
- package/src/browser/ai-configuration/ai-configuration-detail-widget.spec.ts +165 -0
- package/src/browser/ai-configuration/ai-configuration-detail-widget.tsx +237 -0
- package/src/browser/ai-configuration/ai-configuration-label-provider-contribution.ts +47 -0
- package/src/browser/ai-configuration/ai-configuration-open-preference-renderer.ts +64 -0
- package/src/browser/ai-configuration/ai-configuration-preference-ownership.spec.ts +135 -0
- package/src/browser/ai-configuration/{components/configuration-section.tsx → ai-configuration-resource.ts} +9 -19
- package/src/browser/ai-configuration/ai-configuration-search-widget.tsx +135 -0
- package/src/browser/ai-configuration/ai-configuration-search.spec.ts +91 -0
- package/src/browser/ai-configuration/ai-configuration-search.ts +43 -0
- package/src/browser/ai-configuration/{components/empty-state.tsx → ai-configuration-tree-model.ts} +7 -11
- package/src/browser/ai-configuration/ai-configuration-tree-nodes.spec.ts +150 -0
- package/src/browser/ai-configuration/ai-configuration-tree-nodes.ts +167 -0
- package/src/browser/ai-configuration/ai-configuration-tree-widget.tsx +457 -0
- package/src/browser/ai-configuration/ai-configuration-view-contribution.ts +156 -18
- package/src/browser/ai-configuration/ai-configuration-widget.tsx +107 -75
- package/src/browser/ai-configuration/categories/agent-capabilities-settings.spec.ts +161 -0
- package/src/browser/ai-configuration/categories/agent-capabilities-settings.tsx +340 -0
- package/src/browser/ai-configuration/categories/agent-chips.tsx +51 -0
- package/src/browser/ai-configuration/categories/agent-detail-model.ts +152 -0
- package/src/browser/ai-configuration/categories/agent-detail-view.tsx +329 -0
- package/src/browser/ai-configuration/categories/agents-configuration-category.spec.ts +119 -0
- package/src/browser/ai-configuration/categories/agents-configuration-category.tsx +431 -0
- package/src/browser/ai-configuration/categories/general-configuration-category.spec.ts +225 -0
- package/src/browser/ai-configuration/categories/general-configuration-category.tsx +465 -0
- package/src/browser/ai-configuration/categories/model-aliases-configuration-category.spec.ts +87 -0
- package/src/browser/ai-configuration/categories/model-aliases-configuration-category.tsx +286 -0
- package/src/browser/ai-configuration/categories/models-configuration-category.spec.ts +167 -0
- package/src/browser/ai-configuration/categories/models-configuration-category.tsx +264 -0
- package/src/browser/ai-configuration/categories/prompt-snippets-configuration-category.spec.ts +250 -0
- package/src/browser/ai-configuration/categories/prompt-snippets-configuration-category.tsx +438 -0
- package/src/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.ts +226 -0
- package/src/browser/ai-configuration/categories/prompts-and-skills-configuration-category.tsx +419 -0
- package/src/browser/ai-configuration/categories/token-usage-configuration-category.spec.ts +57 -0
- package/src/browser/ai-configuration/categories/token-usage-configuration-category.tsx +185 -0
- package/src/browser/ai-configuration/categories/tools-configuration-category.spec.ts +130 -0
- package/src/browser/ai-configuration/categories/tools-configuration-category.tsx +421 -0
- package/src/browser/ai-configuration/categories/variables-configuration-category.spec.ts +154 -0
- package/src/browser/ai-configuration/categories/variables-configuration-category.tsx +322 -0
- package/src/browser/ai-configuration/components/agent-notification-settings.tsx +38 -33
- package/src/browser/ai-configuration/language-model-renderer.spec.ts +100 -0
- package/src/browser/ai-configuration/language-model-renderer.tsx +244 -100
- package/src/browser/app-tester-chat-agent.ts +5 -2
- package/src/browser/architect-agent.ts +5 -2
- package/src/browser/architect-prompt-template.ts +7 -0
- package/src/browser/chat-session-item.tsx +2 -4
- package/src/browser/chat-session-list-service.ts +6 -3
- package/src/browser/code-reviewer-agent.ts +5 -2
- package/src/browser/coder-agent.ts +7 -5
- package/src/browser/context-file-validation-service-impl.spec.ts +3 -2
- package/src/browser/create-skill-agent.ts +5 -2
- package/src/browser/explore-agent.ts +5 -2
- package/src/browser/file-changeset-functions.spec.ts +158 -5
- package/src/browser/file-changeset-functions.ts +61 -23
- package/src/browser/frontend-module.ts +76 -63
- package/src/browser/github-chat-agent.ts +5 -2
- package/src/browser/github-repo-variable-contribution.ts +6 -3
- package/src/browser/ide-chat-welcome-message-provider.tsx +11 -11
- package/src/browser/memory-capability-contribution.spec.ts +85 -0
- package/src/browser/memory-capability-contribution.ts +86 -0
- package/src/browser/memory-directory-variable-contribution.spec.ts +113 -0
- package/src/browser/memory-directory-variable-contribution.ts +113 -0
- package/src/browser/open-editors-hint-contribution.ts +38 -0
- package/src/browser/project-info-agent.ts +5 -2
- package/src/browser/review/pr-review-agent.ts +5 -2
- package/src/browser/style/ai-configuration-base.css +0 -6
- package/src/browser/style/ai-configuration-shell.css +416 -0
- package/src/browser/style/ai-configuration-table.css +2 -15
- package/src/browser/style/index.css +220 -276
- package/src/browser/summarize-session-command-contribution.ts +6 -3
- package/src/browser/task-context-file-storage-service.ts +5 -2
- package/src/browser/user-interaction-tool.spec.ts +5 -2
- package/src/browser/user-interaction-tool.ts +6 -2
- package/src/browser/workspace-functions.spec.ts +163 -10
- package/src/browser/workspace-functions.ts +121 -72
- package/src/browser/workspace-launch-provider.spec.ts +4 -1
- package/src/browser/workspace-search-provider.spec.ts +1 -2
- package/src/browser/workspace-search-provider.ts +4 -7
- package/src/browser/workspace-task-provider.spec.ts +5 -1
- package/src/common/coder-replace-prompt-template.ts +9 -9
- package/src/common/command-chat-agents.ts +6 -2
- package/src/{browser/ai-configuration/base/ai-configuration-base-widget.tsx → common/open-editors-hint-fragment-id.ts} +2 -22
- package/src/common/orchestrator-chat-agent.ts +5 -2
- package/src/common/universal-chat-agent.ts +5 -2
- package/src/common/universal-prompt-template.ts +3 -0
- package/src/common/workspace-preferences.ts +2 -2
- package/src/common/workspace-search-provider-util.spec.ts +61 -0
- package/src/common/workspace-search-provider-util.ts +3 -2
- package/src/node/github-repo-service-impl.ts +6 -2
- package/lib/browser/ai-configuration/agent-configuration-widget.d.ts +0 -72
- package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js +0 -620
- package/lib/browser/ai-configuration/agent-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.spec.d.ts +0 -2
- package/lib/browser/ai-configuration/agent-configuration-widget.spec.d.ts.map +0 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.spec.js +0 -56
- package/lib/browser/ai-configuration/agent-configuration-widget.spec.js.map +0 -1
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts +0 -31
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js +0 -55
- package/lib/browser/ai-configuration/base/ai-card-grid-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts +0 -13
- package/lib/browser/ai-configuration/base/ai-configuration-base-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/base/ai-configuration-base-widget.js.map +0 -1
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts +0 -23
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js +0 -60
- package/lib/browser/ai-configuration/base/ai-hierarchical-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts +0 -55
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js +0 -96
- package/lib/browser/ai-configuration/base/ai-list-detail-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts +0 -44
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js +0 -66
- package/lib/browser/ai-configuration/base/ai-table-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/components/configuration-section.d.ts +0 -12
- package/lib/browser/ai-configuration/components/configuration-section.d.ts.map +0 -1
- package/lib/browser/ai-configuration/components/configuration-section.js.map +0 -1
- package/lib/browser/ai-configuration/components/empty-state.d.ts +0 -10
- package/lib/browser/ai-configuration/components/empty-state.d.ts.map +0 -1
- package/lib/browser/ai-configuration/components/empty-state.js.map +0 -1
- package/lib/browser/ai-configuration/components/expandable-section.d.ts +0 -13
- package/lib/browser/ai-configuration/components/expandable-section.d.ts.map +0 -1
- package/lib/browser/ai-configuration/components/expandable-section.js +0 -31
- package/lib/browser/ai-configuration/components/expandable-section.js.map +0 -1
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts +0 -26
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.js +0 -198
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts +0 -140
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +0 -508
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/skills-configuration-widget.d.ts +0 -29
- package/lib/browser/ai-configuration/skills-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/skills-configuration-widget.js +0 -166
- package/lib/browser/ai-configuration/skills-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/skills-configuration-widget.spec.d.ts +0 -2
- package/lib/browser/ai-configuration/skills-configuration-widget.spec.d.ts.map +0 -1
- package/lib/browser/ai-configuration/skills-configuration-widget.spec.js +0 -191
- package/lib/browser/ai-configuration/skills-configuration-widget.spec.js.map +0 -1
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts +0 -9
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +0 -1
- package/lib/browser/ai-configuration/template-settings-renderer.js +0 -78
- package/lib/browser/ai-configuration/template-settings-renderer.js.map +0 -1
- package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts +0 -20
- package/lib/browser/ai-configuration/token-usage-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/token-usage-configuration-widget.js +0 -170
- package/lib/browser/ai-configuration/token-usage-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +0 -52
- package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/tools-configuration-widget.js +0 -357
- package/lib/browser/ai-configuration/tools-configuration-widget.js.map +0 -1
- package/lib/browser/ai-configuration/variable-configuration-widget.d.ts +0 -22
- package/lib/browser/ai-configuration/variable-configuration-widget.d.ts.map +0 -1
- package/lib/browser/ai-configuration/variable-configuration-widget.js +0 -133
- package/lib/browser/ai-configuration/variable-configuration-widget.js.map +0 -1
- package/src/browser/ai-configuration/agent-configuration-widget.spec.ts +0 -71
- package/src/browser/ai-configuration/agent-configuration-widget.tsx +0 -928
- package/src/browser/ai-configuration/base/ai-card-grid-configuration-widget.tsx +0 -72
- package/src/browser/ai-configuration/base/ai-hierarchical-configuration-widget.tsx +0 -51
- package/src/browser/ai-configuration/base/ai-list-detail-configuration-widget.tsx +0 -140
- package/src/browser/ai-configuration/base/ai-table-configuration-widget.tsx +0 -107
- package/src/browser/ai-configuration/components/expandable-section.tsx +0 -51
- package/src/browser/ai-configuration/model-aliases-configuration-widget.tsx +0 -270
- package/src/browser/ai-configuration/prompt-fragments-configuration-widget.tsx +0 -736
- package/src/browser/ai-configuration/skills-configuration-widget.spec.ts +0 -248
- package/src/browser/ai-configuration/skills-configuration-widget.tsx +0 -229
- package/src/browser/ai-configuration/template-settings-renderer.tsx +0 -125
- package/src/browser/ai-configuration/token-usage-configuration-widget.tsx +0 -214
- package/src/browser/ai-configuration/tools-configuration-widget.tsx +0 -544
- package/src/browser/ai-configuration/variable-configuration-widget.tsx +0 -159
- package/src/browser/style/ai-configuration-cards.css +0 -60
|
@@ -0,0 +1,438 @@
|
|
|
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 { Agent, AgentService } from '@theia/ai-core';
|
|
18
|
+
import { CAPABILITY_TYPE_PROMPT_MAP, parseCapabilitiesFromTemplate } from '@theia/ai-core/lib/common';
|
|
19
|
+
import { isCustomizedPromptFragment, PromptFragment, PromptService } from '@theia/ai-core/lib/common/prompt-service';
|
|
20
|
+
import { Emitter, Event, nls } from '@theia/core';
|
|
21
|
+
import { codicon, ConfirmDialog } from '@theia/core/lib/browser';
|
|
22
|
+
import { DisposableCollection } from '@theia/core/lib/common';
|
|
23
|
+
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
24
|
+
import * as React from '@theia/core/shared/react';
|
|
25
|
+
import {
|
|
26
|
+
AiConfigurationCategory,
|
|
27
|
+
AiConfigurationCategoryId,
|
|
28
|
+
AiConfigurationCategoryOrder,
|
|
29
|
+
AiConfigurationRenderContext,
|
|
30
|
+
AiConfigurationSearchItem,
|
|
31
|
+
AiConfigurationSearchProvider,
|
|
32
|
+
AiConfigurationSelection
|
|
33
|
+
} from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
|
|
34
|
+
import { SinglePageCategoryRenderer } from '@theia/ai-core-ui/lib/browser/ai-configuration/renderers/single-page-category-renderer';
|
|
35
|
+
import {
|
|
36
|
+
CollapsibleGroup,
|
|
37
|
+
CollapsibleList,
|
|
38
|
+
CollapsibleRow,
|
|
39
|
+
CollapsibleRowAction
|
|
40
|
+
} from '@theia/ai-core-ui/lib/browser/ai-configuration/components/collapsible-list';
|
|
41
|
+
import { PromptCustomizationDialogs } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/prompt-customization-dialogs';
|
|
42
|
+
import { AiConfigurationCallout } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-configuration-primitives';
|
|
43
|
+
import { AgentChips } from './agent-chips';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Fragments generated per running MCP server, named after `McpFrontendService.getPromptTemplateId`.
|
|
47
|
+
* Excluded from this page: they are rebuilt from the live tool list whenever a server starts, so a
|
|
48
|
+
* customization would silently diverge from the tools the server actually offers. The generated tool
|
|
49
|
+
* list is visible on the MCP Servers page instead.
|
|
50
|
+
*/
|
|
51
|
+
const MCP_TOOL_LIST_FRAGMENT_PATTERN = /^mcp_.+_tools$/;
|
|
52
|
+
|
|
53
|
+
/** Which group a fragment belongs to, in the order the page renders them. */
|
|
54
|
+
export type PromptSnippetKind = 'snippet' | 'capability' | 'generic-capability';
|
|
55
|
+
|
|
56
|
+
/** One prompt fragment as this page shows it, resolved from the prompt service on load. */
|
|
57
|
+
export interface PromptSnippetEntry {
|
|
58
|
+
readonly id: string;
|
|
59
|
+
readonly kind: PromptSnippetKind;
|
|
60
|
+
/** Frontmatter `name`, when the fragment declares one. */
|
|
61
|
+
readonly name?: string;
|
|
62
|
+
/** Frontmatter `description`, when the fragment declares one. */
|
|
63
|
+
readonly description?: string;
|
|
64
|
+
/** A customization currently overrides (or, without a built-in, provides) the text. */
|
|
65
|
+
readonly customized: boolean;
|
|
66
|
+
/** `false` for a fragment that exists only as a user/workspace file, where reset has nothing to fall back to. */
|
|
67
|
+
readonly hasBuiltIn: boolean;
|
|
68
|
+
/** Agents whose selected prompt references this fragment as a capability; empty for plain snippets. */
|
|
69
|
+
readonly agentIds: string[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export namespace PromptSnippetsConfiguration {
|
|
73
|
+
/**
|
|
74
|
+
* Prefix of the `data-ai-config-row-id` of every row on this page, regardless of its group, so that
|
|
75
|
+
* a deep link only needs the fragment id (an agent's capability list, for instance, does not know
|
|
76
|
+
* whether a fragment ends up under Capabilities or Generic Capabilities).
|
|
77
|
+
*/
|
|
78
|
+
export const ROW_ID_PREFIX = 'fragment:';
|
|
79
|
+
|
|
80
|
+
/** Navigation target that scrolls to and flashes `fragmentId`'s row on this page. */
|
|
81
|
+
export function selectionFor(fragmentId: string): AiConfigurationSelection {
|
|
82
|
+
return {
|
|
83
|
+
categoryId: AiConfigurationCategoryId.PROMPT_SNIPPETS,
|
|
84
|
+
highlight: { rowId: ROW_ID_PREFIX + fragmentId }
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The "Prompt Snippets" category: every prompt fragment that has no other home in this view, as a
|
|
91
|
+
* filterable list of expandable rows in three groups — user-authored snippets, agent capabilities and
|
|
92
|
+
* generic capabilities. Prompt variant sets live in the agent detail, skills and slash commands on the
|
|
93
|
+
* Skills page, so those are filtered out here; what remains would otherwise be uneditable, which is
|
|
94
|
+
* what this page fixes.
|
|
95
|
+
*
|
|
96
|
+
* Capability fragments are global: editing one affects every agent that references it, which is why
|
|
97
|
+
* each row lists the agents using it rather than pretending the text belongs to one of them.
|
|
98
|
+
*/
|
|
99
|
+
@injectable()
|
|
100
|
+
export class PromptSnippetsConfigurationCategory extends SinglePageCategoryRenderer implements AiConfigurationCategory, AiConfigurationSearchProvider {
|
|
101
|
+
|
|
102
|
+
readonly id = AiConfigurationCategoryId.PROMPT_SNIPPETS;
|
|
103
|
+
readonly label = nls.localize('theia/ai/ide/promptSnippetsConfiguration/label', 'Prompt Snippets');
|
|
104
|
+
readonly description = nls.localize('theia/ai/ide/promptSnippetsConfiguration/description',
|
|
105
|
+
'Reusable prompt text: your own snippets plus the capability snippets agents pull in. Editing a snippet affects every agent that uses it.');
|
|
106
|
+
readonly iconClass = codicon('file-code');
|
|
107
|
+
readonly order = AiConfigurationCategoryOrder.PROMPT_SNIPPETS;
|
|
108
|
+
readonly kind = 'single-page' as const;
|
|
109
|
+
|
|
110
|
+
@inject(PromptService)
|
|
111
|
+
protected readonly promptService: PromptService;
|
|
112
|
+
|
|
113
|
+
@inject(AgentService)
|
|
114
|
+
protected readonly agentService: AgentService;
|
|
115
|
+
|
|
116
|
+
protected readonly onDidChangeEmitter = new Emitter<void>();
|
|
117
|
+
readonly onDidChange: Event<void> = this.onDidChangeEmitter.event;
|
|
118
|
+
protected readonly toDispose = new DisposableCollection(this.onDidChangeEmitter);
|
|
119
|
+
|
|
120
|
+
protected entries: PromptSnippetEntry[] = [];
|
|
121
|
+
protected availableAgents: Agent[] = [];
|
|
122
|
+
|
|
123
|
+
get renderer(): this {
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get search(): AiConfigurationSearchProvider {
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@postConstruct()
|
|
132
|
+
protected init(): void {
|
|
133
|
+
this.reload();
|
|
134
|
+
this.toDispose.pushAll([
|
|
135
|
+
this.promptService.onPromptsChange(() => {
|
|
136
|
+
this.reload();
|
|
137
|
+
this.onDidChangeEmitter.fire();
|
|
138
|
+
}),
|
|
139
|
+
this.agentService.onDidChangeAgents(() => {
|
|
140
|
+
this.reload();
|
|
141
|
+
this.onDidChangeEmitter.fire();
|
|
142
|
+
})
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
dispose(): void {
|
|
147
|
+
this.toDispose.dispose();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
protected reload(): void {
|
|
151
|
+
this.availableAgents = this.agentService.getAllAgents();
|
|
152
|
+
this.entries = this.loadEntries();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Classifies every registered fragment, dropping those another part of the view already owns.
|
|
157
|
+
* Grouped by {@link PromptSnippetKind} and sorted by display name within each group.
|
|
158
|
+
*/
|
|
159
|
+
protected loadEntries(): PromptSnippetEntry[] {
|
|
160
|
+
const capabilityAgents = this.collectCapabilityReferences();
|
|
161
|
+
const genericCapabilityIds = new Set(CAPABILITY_TYPE_PROMPT_MAP.map(({ promptId }) => promptId));
|
|
162
|
+
const ownedElsewhere = this.collectFragmentIdsOwnedElsewhere();
|
|
163
|
+
const entries: PromptSnippetEntry[] = [];
|
|
164
|
+
for (const [id, fragments] of this.promptService.getAllPromptFragments()) {
|
|
165
|
+
if (ownedElsewhere.has(id) || MCP_TOOL_LIST_FRAGMENT_PATTERN.test(id)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const effective = this.promptService.getRawPromptFragment(id) ?? fragments[0];
|
|
169
|
+
// Slash commands (including the synthetic ones backing a skill) belong to the Skills page. Checking
|
|
170
|
+
// every fragment, not just the effective one, keeps a command hidden here even if a customization
|
|
171
|
+
// drops the `isCommand` frontmatter.
|
|
172
|
+
if (!effective || fragments.some(fragment => fragment.isCommand)) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const agentIds = capabilityAgents.get(id) ?? [];
|
|
176
|
+
entries.push({
|
|
177
|
+
id,
|
|
178
|
+
kind: this.classify(id, effective, genericCapabilityIds, agentIds.length > 0),
|
|
179
|
+
name: effective.name,
|
|
180
|
+
description: effective.description,
|
|
181
|
+
customized: fragments.some(fragment => isCustomizedPromptFragment(fragment)),
|
|
182
|
+
hasBuiltIn: fragments.some(fragment => !isCustomizedPromptFragment(fragment)),
|
|
183
|
+
agentIds
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return entries.sort((left, right) => this.displayName(left).localeCompare(this.displayName(right)));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* A fragment is a *generic* capability when it is one of the fixed set the chat dropdowns inject
|
|
191
|
+
* (`CAPABILITY_TYPE_PROMPT_MAP` is that single source of truth), and a *capability* when an agent
|
|
192
|
+
* references it as `{{capability:id}}`. Declared frontmatter is accepted as a fallback so that a
|
|
193
|
+
* capability shipped by an extension still groups correctly before any agent template pulls it in.
|
|
194
|
+
*/
|
|
195
|
+
protected classify(id: string, fragment: PromptFragment, genericCapabilityIds: Set<string>, referencedByAgent: boolean): PromptSnippetKind {
|
|
196
|
+
if (genericCapabilityIds.has(id)) {
|
|
197
|
+
return 'generic-capability';
|
|
198
|
+
}
|
|
199
|
+
if (referencedByAgent || fragment.name !== undefined || fragment.description !== undefined) {
|
|
200
|
+
return 'capability';
|
|
201
|
+
}
|
|
202
|
+
return 'snippet';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Maps capability fragment id -> ids of the agents referencing it. Mirrors the agent detail page,
|
|
207
|
+
* which parses `{{capability:...}}` out of each agent's selected prompt, so both agree on what
|
|
208
|
+
* counts as a capability. Uses the globally effective variant to stay synchronous; the agent detail
|
|
209
|
+
* additionally honours that agent's own variant selection.
|
|
210
|
+
*/
|
|
211
|
+
protected collectCapabilityReferences(): Map<string, string[]> {
|
|
212
|
+
const references = new Map<string, string[]>();
|
|
213
|
+
for (const agent of this.availableAgents) {
|
|
214
|
+
for (const prompt of agent.prompts) {
|
|
215
|
+
const variantId = this.promptService.getEffectiveVariantId(prompt.id) ?? prompt.id;
|
|
216
|
+
const template = this.promptService.getRawPromptFragment(variantId)?.template;
|
|
217
|
+
if (!template) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
for (const capability of parseCapabilitiesFromTemplate(template)) {
|
|
221
|
+
const agents = references.get(capability.fragmentId) ?? [];
|
|
222
|
+
if (!agents.includes(agent.id)) {
|
|
223
|
+
agents.push(agent.id);
|
|
224
|
+
}
|
|
225
|
+
references.set(capability.fragmentId, agents);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return references;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Fragment ids another part of the view is responsible for: the prompt variant sets and their
|
|
234
|
+
* variants, which the agent detail owns as the single source of truth.
|
|
235
|
+
*/
|
|
236
|
+
protected collectFragmentIdsOwnedElsewhere(): Set<string> {
|
|
237
|
+
const owned = new Set<string>();
|
|
238
|
+
for (const [variantSetId, variantIds] of this.promptService.getPromptVariantSets()) {
|
|
239
|
+
owned.add(variantSetId);
|
|
240
|
+
variantIds.forEach(variantId => owned.add(variantId));
|
|
241
|
+
}
|
|
242
|
+
return owned;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
protected displayName(entry: PromptSnippetEntry): string {
|
|
246
|
+
return entry.name ?? entry.id;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
protected renderSections(ctx: AiConfigurationRenderContext): React.ReactNode {
|
|
250
|
+
const onOpenAgent = (agentId: string): void => ctx.navigate({ categoryId: AiConfigurationCategoryId.AGENTS, itemId: agentId });
|
|
251
|
+
const groups: CollapsibleGroup[] = [
|
|
252
|
+
{
|
|
253
|
+
id: 'snippets',
|
|
254
|
+
title: nls.localizeByDefault('Snippets'),
|
|
255
|
+
description: nls.localize('theia/ai/ide/promptSnippetsConfiguration/snippetsGroupDescription',
|
|
256
|
+
'Prompt text you maintain yourself, referenced from other prompts with {{prompt:id}}.'),
|
|
257
|
+
rows: this.buildRows('snippet', ctx, onOpenAgent)
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
id: 'capabilities',
|
|
261
|
+
title: nls.localizeByDefault('Capabilities'),
|
|
262
|
+
description: nls.localize('theia/ai/ide/promptSnippetsConfiguration/capabilitiesGroupDescription',
|
|
263
|
+
'Instructions an agent adds to its prompt when enabled. They are shared, so an edit affects every agent using them.'),
|
|
264
|
+
rows: this.buildRows('capability', ctx, onOpenAgent)
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
id: 'generic-capabilities',
|
|
268
|
+
title: nls.localize('theia/ai/ide/promptSnippetsConfiguration/genericCapabilitiesGroup', 'Generic Capabilities'),
|
|
269
|
+
description: nls.localize('theia/ai/ide/promptSnippetsConfiguration/genericCapabilitiesGroupDescription',
|
|
270
|
+
'Basic instructions to integrate the selected capabilities into the agent\'s prompt. They are shared, so an edit affects every agent using them.'),
|
|
271
|
+
rows: this.buildRows('generic-capability', ctx, onOpenAgent)
|
|
272
|
+
}
|
|
273
|
+
];
|
|
274
|
+
return <>
|
|
275
|
+
{this.renderResetAllCallout(ctx)}
|
|
276
|
+
<CollapsibleList
|
|
277
|
+
groups={groups}
|
|
278
|
+
filterPlaceholder={nls.localize('theia/ai/ide/promptSnippetsConfiguration/filterPlaceholder', 'Filter prompt snippets by name, id or description')}
|
|
279
|
+
emptyMessage={nls.localize('theia/ai/ide/promptSnippetsConfiguration/empty', 'No prompt snippets are available.')}
|
|
280
|
+
filterEmptyMessage={query => nls.localize('theia/ai/ide/promptSnippetsConfiguration/noMatches', 'No prompt snippets match "{0}".', query)}
|
|
281
|
+
/>
|
|
282
|
+
</>;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Page-level reset, as the prompt fragments page it replaces had. Shown only while something is
|
|
287
|
+
* customized, and explicit that it reverts *every* customization — including the agents' prompt
|
|
288
|
+
* variants, which live on their own pages.
|
|
289
|
+
*/
|
|
290
|
+
protected renderResetAllCallout(ctx: AiConfigurationRenderContext): React.ReactNode {
|
|
291
|
+
if (!this.hasResettableCustomizations()) {
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
return <AiConfigurationCallout
|
|
295
|
+
message={nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAllMessage',
|
|
296
|
+
'Some prompt fragments are customized. Resetting reverts every one of them to its built-in version, '
|
|
297
|
+
+ 'including the agents\' prompt templates. Snippets that have no built-in version are kept.')}
|
|
298
|
+
action={<button className='theia-button secondary' onClick={() => this.resetAllCustomizations(ctx)}>
|
|
299
|
+
{nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAll', 'Reset All Customizations')}
|
|
300
|
+
</button>}
|
|
301
|
+
/>;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Whether anything would actually be reset. Deliberately not limited to this page's entries: the action
|
|
306
|
+
* reverts every customized fragment that has a built-in, which includes the agents' prompt templates
|
|
307
|
+
* (listed on their own pages), so gating on the rows here would hide it exactly when it is needed.
|
|
308
|
+
*/
|
|
309
|
+
protected hasResettableCustomizations(): boolean {
|
|
310
|
+
for (const fragments of this.promptService.getAllPromptFragments().values()) {
|
|
311
|
+
if (fragments.some(fragment => isCustomizedPromptFragment(fragment)) && fragments.some(fragment => !isCustomizedPromptFragment(fragment))) {
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
protected async resetAllCustomizations(ctx: AiConfigurationRenderContext): Promise<void> {
|
|
319
|
+
const dialog = new ConfirmDialog({
|
|
320
|
+
title: nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAllDialogTitle', 'Reset All Customizations'),
|
|
321
|
+
msg: nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetAllDialogMsg',
|
|
322
|
+
'Are you sure you want to reset every customized prompt fragment to its built-in version? '
|
|
323
|
+
+ 'This includes the agents\' prompt templates, not only the snippets listed here. '
|
|
324
|
+
+ 'Snippets that have no built-in version are kept.'),
|
|
325
|
+
ok: nls.localizeByDefault('Reset'),
|
|
326
|
+
cancel: nls.localizeByDefault('Cancel')
|
|
327
|
+
});
|
|
328
|
+
if (await dialog.open()) {
|
|
329
|
+
await this.promptService.resetAllToBuiltIn();
|
|
330
|
+
ctx.update();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
protected buildRows(kind: PromptSnippetKind, ctx: AiConfigurationRenderContext, onOpenAgent: (agentId: string) => void): CollapsibleRow[] {
|
|
335
|
+
return this.entries.filter(entry => entry.kind === kind).map(entry => this.buildRow(entry, ctx, onOpenAgent));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
protected buildRow(entry: PromptSnippetEntry, ctx: AiConfigurationRenderContext, onOpenAgent: (agentId: string) => void): CollapsibleRow {
|
|
339
|
+
const agents = this.availableAgents.filter(agent => entry.agentIds.includes(agent.id));
|
|
340
|
+
const pills: string[] = [];
|
|
341
|
+
if (entry.customized) {
|
|
342
|
+
pills.push(nls.localize('theia/ai/ide/promptSnippetsConfiguration/customized', 'Customized'));
|
|
343
|
+
}
|
|
344
|
+
if (agents.length > 0) {
|
|
345
|
+
pills.push(agents.length === 1 ? nls.localizeByDefault('1 agent') : nls.localizeByDefault('{0} agents', agents.length));
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
id: PromptSnippetsConfiguration.ROW_ID_PREFIX + entry.id,
|
|
349
|
+
title: this.displayName(entry),
|
|
350
|
+
description: entry.description,
|
|
351
|
+
pills,
|
|
352
|
+
filterText: `${entry.id} ${entry.name ?? ''} ${entry.description ?? ''}`.toLocaleLowerCase(),
|
|
353
|
+
actions: <>
|
|
354
|
+
<CollapsibleRowAction
|
|
355
|
+
iconClass={codicon('edit')}
|
|
356
|
+
label={nls.localize('theia/ai/ide/promptSnippetsConfiguration/editSnippet', 'Edit snippet')}
|
|
357
|
+
onActivate={() => this.editEntry(entry)}
|
|
358
|
+
/>
|
|
359
|
+
{/* A customization of a built-in can be reverted; a snippet that only exists as a file has
|
|
360
|
+
nothing to revert to, so it offers deletion instead. */}
|
|
361
|
+
{entry.customized && entry.hasBuiltIn && <CollapsibleRowAction
|
|
362
|
+
iconClass={codicon('discard')}
|
|
363
|
+
label={nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetSnippet', 'Reset snippet to built-in')}
|
|
364
|
+
onActivate={() => this.resetEntry(entry, ctx)}
|
|
365
|
+
/>}
|
|
366
|
+
{entry.customized && !entry.hasBuiltIn && <CollapsibleRowAction
|
|
367
|
+
iconClass={codicon('trash')}
|
|
368
|
+
label={nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeSnippet', 'Remove snippet')}
|
|
369
|
+
onActivate={() => this.removeEntry(entry, ctx)}
|
|
370
|
+
/>}
|
|
371
|
+
</>,
|
|
372
|
+
body: <>
|
|
373
|
+
<div className='ai-variable-id-row'>
|
|
374
|
+
<span className='ai-variable-id-label'>{nls.localizeByDefault('ID')}</span>
|
|
375
|
+
<code className='ai-variable-id-value'>{entry.id}</code>
|
|
376
|
+
</div>
|
|
377
|
+
{agents.length > 0 && <div className='ai-variable-section'>
|
|
378
|
+
<div className='ai-variable-section-label'>
|
|
379
|
+
{nls.localize('theia/ai/ide/promptSnippetsConfiguration/usedByAgents', 'Used by Agents')}
|
|
380
|
+
</div>
|
|
381
|
+
<AgentChips agents={agents} onOpenAgent={onOpenAgent} />
|
|
382
|
+
</div>}
|
|
383
|
+
</>
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** Opens the effective text: the customization if there is one, otherwise a fresh copy of the built-in. */
|
|
388
|
+
protected editEntry(entry: PromptSnippetEntry): void {
|
|
389
|
+
const fragment = this.promptService.getRawPromptFragment(entry.id);
|
|
390
|
+
if (fragment && isCustomizedPromptFragment(fragment)) {
|
|
391
|
+
this.promptService.editCustomization(fragment.id, fragment.customizationId);
|
|
392
|
+
} else {
|
|
393
|
+
this.promptService.editBuiltInCustomization(entry.id);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/** Drops all customizations so the built-in text applies again. */
|
|
398
|
+
protected async resetEntry(entry: PromptSnippetEntry, ctx: AiConfigurationRenderContext): Promise<void> {
|
|
399
|
+
await PromptCustomizationDialogs.confirmAndReset(
|
|
400
|
+
this.promptService,
|
|
401
|
+
entry.id,
|
|
402
|
+
nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetDialogTitle', 'Reset Snippet to Built-in'),
|
|
403
|
+
nls.localize('theia/ai/ide/promptSnippetsConfiguration/resetDialogMsg',
|
|
404
|
+
'Are you sure you want to reset the snippet "{0}" to its built-in version? This will remove all customizations.', entry.id)
|
|
405
|
+
);
|
|
406
|
+
ctx.update();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/** Deletes a snippet that has no built-in behind it, naming the file, since it is gone afterwards. */
|
|
410
|
+
protected async removeEntry(entry: PromptSnippetEntry, ctx: AiConfigurationRenderContext): Promise<void> {
|
|
411
|
+
await PromptCustomizationDialogs.confirmAndRemove(this.promptService, entry.id, {
|
|
412
|
+
title: nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeDialogTitle', 'Remove Snippet'),
|
|
413
|
+
message: ({ type, description }) => description
|
|
414
|
+
? nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeWithDescDialogMsg',
|
|
415
|
+
'Are you sure you want to remove the {0} customization for snippet "{1}" ({2})? It has no built-in version, so it will be gone entirely.',
|
|
416
|
+
type ?? '', entry.id, description)
|
|
417
|
+
: nls.localize('theia/ai/ide/promptSnippetsConfiguration/removeDialogMsg',
|
|
418
|
+
'Are you sure you want to remove the {0} customization for snippet "{1}"? It has no built-in version, so it will be gone entirely.',
|
|
419
|
+
type ?? '', entry.id)
|
|
420
|
+
});
|
|
421
|
+
ctx.update();
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
getSearchItems(): AiConfigurationSearchItem[] {
|
|
425
|
+
const typeLabels: Record<PromptSnippetKind, string> = {
|
|
426
|
+
'snippet': nls.localizeByDefault('Snippet'),
|
|
427
|
+
'capability': nls.localize('theia/ai/ide/promptSnippetsConfiguration/capabilityTypeLabel', 'Capability'),
|
|
428
|
+
'generic-capability': nls.localize('theia/ai/ide/promptSnippetsConfiguration/genericCapabilityTypeLabel', 'Generic capability')
|
|
429
|
+
};
|
|
430
|
+
return this.entries.map(entry => ({
|
|
431
|
+
label: this.displayName(entry),
|
|
432
|
+
typeLabel: typeLabels[entry.kind],
|
|
433
|
+
categoryId: this.id,
|
|
434
|
+
target: PromptSnippetsConfiguration.selectionFor(entry.id),
|
|
435
|
+
keywords: `${entry.id} ${entry.description ?? ''}`
|
|
436
|
+
}));
|
|
437
|
+
}
|
|
438
|
+
}
|
package/src/browser/ai-configuration/categories/prompts-and-skills-configuration-category.spec.ts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
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
|
+
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
|
21
|
+
FrontendApplicationConfigProvider.set({});
|
|
22
|
+
|
|
23
|
+
import { expect } from 'chai';
|
|
24
|
+
import { Event } from '@theia/core';
|
|
25
|
+
import { PromptFragment } from '@theia/ai-core/lib/common/prompt-service';
|
|
26
|
+
import { Skill } from '@theia/ai-core/lib/common/skill';
|
|
27
|
+
import { AgentPluginUiBridge, InstalledAgentPluginInfo } from '@theia/ai-core/lib/browser/agent-plugin-ui-bridge';
|
|
28
|
+
import { SkillRegistryUiBridge } from '@theia/ai-core/lib/browser/skill-registry-ui-bridge';
|
|
29
|
+
import { AiConfigurationCategoryId } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
|
|
30
|
+
import { CollapsibleRow } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/collapsible-list';
|
|
31
|
+
import { PromptsAndSkillsConfigurationCategory } from './prompts-and-skills-configuration-category';
|
|
32
|
+
|
|
33
|
+
disableJSDOM();
|
|
34
|
+
|
|
35
|
+
/** A plugin as the bridge knows it, plus the qualifier its contributed skill root carries. */
|
|
36
|
+
type InstalledPlugin = InstalledAgentPluginInfo & { qualifier: string };
|
|
37
|
+
|
|
38
|
+
describe('PromptsAndSkillsConfigurationCategory', () => {
|
|
39
|
+
|
|
40
|
+
before(() => disableJSDOM = enableJSDOM());
|
|
41
|
+
after(() => disableJSDOM());
|
|
42
|
+
|
|
43
|
+
function categoryWith(skills: Skill[], slashCommands: PromptFragment[]): PromptsAndSkillsConfigurationCategory {
|
|
44
|
+
const category = new PromptsAndSkillsConfigurationCategory();
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
(category as any).skills = skills;
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
(category as any).slashCommands = slashCommands;
|
|
49
|
+
return category;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Leaves the bridge unbound when `installedPlugins` is omitted, i.e. a product without `@theia/ai-registry`. */
|
|
53
|
+
function categoryWithPlugins(skills: Skill[], installedPlugins: InstalledPlugin[] | undefined, revealed: string[] = []): PromptsAndSkillsConfigurationCategory {
|
|
54
|
+
const category = categoryWith(skills, []);
|
|
55
|
+
if (installedPlugins) {
|
|
56
|
+
const bridge: AgentPluginUiBridge = {
|
|
57
|
+
getPlugin: pluginId => installedPlugins.find(plugin => plugin.pluginId === pluginId),
|
|
58
|
+
getPluginByQualifier: qualifier => installedPlugins.find(plugin => plugin.qualifier === qualifier),
|
|
59
|
+
revealPlugin: pluginId => { revealed.push(pluginId); },
|
|
60
|
+
onDidChange: Event.None
|
|
61
|
+
};
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
+
(category as any).agentPluginUiBridge = bridge;
|
|
64
|
+
}
|
|
65
|
+
return category;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Leaves the bridge unbound when `managed` is omitted. `managed` maps a skill location to the
|
|
70
|
+
* registry entry it was installed from, which is how the real bridge keys them.
|
|
71
|
+
*/
|
|
72
|
+
function categoryWithRegistrySkills(
|
|
73
|
+
skills: Skill[], managed: Record<string, string> | undefined, revealed: string[] = []
|
|
74
|
+
): PromptsAndSkillsConfigurationCategory {
|
|
75
|
+
const category = categoryWith(skills, []);
|
|
76
|
+
if (managed) {
|
|
77
|
+
const bridge: SkillRegistryUiBridge = {
|
|
78
|
+
getRegistryEntryId: forSkill => managed[forSkill.location],
|
|
79
|
+
revealSkill: skillId => { revealed.push(skillId); },
|
|
80
|
+
onDidChange: Event.None
|
|
81
|
+
};
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
(category as any).skillRegistryUiBridge = bridge;
|
|
84
|
+
}
|
|
85
|
+
return category;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function skillRow(category: PromptsAndSkillsConfigurationCategory, forSkill: Skill): CollapsibleRow {
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
|
+
return (category as any).buildSkillRow(forSkill) as CollapsibleRow;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function skill(overrides: Partial<Skill>): Skill {
|
|
94
|
+
return { name: 'query-builder', qualifiedName: 'query-builder', description: 'Build SQL', location: '/skills/query-builder/SKILL.md', ...overrides } as Skill;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
it('declares the skills and slash commands single-page metadata', () => {
|
|
98
|
+
const category = new PromptsAndSkillsConfigurationCategory();
|
|
99
|
+
expect(category.id).to.equal(AiConfigurationCategoryId.PROMPTS_AND_SKILLS);
|
|
100
|
+
expect(category.kind).to.equal('single-page');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('indexes skills and slash commands for search, highlighting their rows', () => {
|
|
104
|
+
const category = categoryWith(
|
|
105
|
+
[{ name: 'refactor', qualifiedName: 'refactor', description: 'do it', location: '/s' } as unknown as Skill],
|
|
106
|
+
[{ id: 'cmd', commandName: 'go', commandDescription: 'run' } as unknown as PromptFragment]
|
|
107
|
+
);
|
|
108
|
+
const items = category.getSearchItems();
|
|
109
|
+
const byType = (typeIncludes: string) => items.filter(i => i.typeLabel.toLowerCase().includes(typeIncludes));
|
|
110
|
+
|
|
111
|
+
expect(byType('skill')).to.have.lengthOf(1);
|
|
112
|
+
expect(byType('slash')).to.have.lengthOf(1);
|
|
113
|
+
expect(items.find(i => i.label === 'refactor')?.target.highlight?.rowId).to.equal('skill:refactor');
|
|
114
|
+
expect(items.find(i => i.label === '/go')?.target.highlight?.rowId).to.equal('cmd:cmd');
|
|
115
|
+
expect(items.every(i => i.target.categoryId === AiConfigurationCategoryId.PROMPTS_AND_SKILLS)).to.equal(true);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('does not list skill-backed synthetic commands as slash commands', () => {
|
|
119
|
+
const category = new PromptsAndSkillsConfigurationCategory();
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
121
|
+
(category as any).promptService = {
|
|
122
|
+
getCommands: () => [
|
|
123
|
+
{ id: 'skill-command-refactor', commandName: 'refactor', isCommand: true },
|
|
124
|
+
{ id: 'remember', commandName: 'remember', isCommand: true }
|
|
125
|
+
] as unknown as PromptFragment[]
|
|
126
|
+
};
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
128
|
+
(category as any).loadSlashCommands();
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
130
|
+
const commands = (category as any).slashCommands as PromptFragment[];
|
|
131
|
+
expect(commands.map(command => command.id)).to.deep.equal(['remember']);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('Agent Plugin provenance', () => {
|
|
135
|
+
|
|
136
|
+
const bigquery: InstalledPlugin = { pluginId: 'io.example/bq', name: 'BigQuery Data Analytics', qualifier: 'bigquery' };
|
|
137
|
+
const contributed = skill({ qualifiedName: 'bigquery:query-builder', location: '/plugins/bigquery/skills/query-builder/SKILL.md' });
|
|
138
|
+
|
|
139
|
+
it('keys and titles a skill row by its qualified name, which is what the model addresses', () => {
|
|
140
|
+
const row = skillRow(categoryWithPlugins([contributed], [bigquery]), contributed);
|
|
141
|
+
expect(row.id).to.equal('skill:bigquery:query-builder');
|
|
142
|
+
expect(row.title).to.equal('bigquery:query-builder');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('labels a contributed skill with the shared origin badge naming the plugin that supplied it', () => {
|
|
146
|
+
const row = skillRow(categoryWithPlugins([contributed], [bigquery]), contributed);
|
|
147
|
+
// The same descriptor the MCP page builds, so both pages render one badge rather than two designs.
|
|
148
|
+
expect(row.origins?.map(origin => origin.label)).to.deep.equal(['via BigQuery Data Analytics']);
|
|
149
|
+
// Filterable by the plugin name too, so a plugin's skills can be listed together.
|
|
150
|
+
expect(row.filterText).to.contain('bigquery data analytics');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('reveals the owning plugin when the origin badge is activated', () => {
|
|
154
|
+
const revealed: string[] = [];
|
|
155
|
+
const row = skillRow(categoryWithPlugins([contributed], [bigquery], revealed), contributed);
|
|
156
|
+
// Activated directly: rendering the badge as a button is `AiConfigurationOriginBadge`'s
|
|
157
|
+
// contract, tested where it lives; what belongs here is where this page's badge leads.
|
|
158
|
+
row.origins![0].activate!();
|
|
159
|
+
expect(revealed).to.deep.equal([bigquery.pluginId]);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('keeps the provenance out of the pills, which state what the skill is rather than where it came from', () => {
|
|
163
|
+
const row = skillRow(categoryWithPlugins([contributed], [bigquery]), contributed);
|
|
164
|
+
expect(row.pills?.some(pill => pill.startsWith('via '))).to.not.equal(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('labels nothing for a skill from a built-in root, which is the common case', () => {
|
|
168
|
+
const own = skill({});
|
|
169
|
+
expect(skillRow(categoryWithPlugins([own], [bigquery]), own).origins).to.equal(undefined);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('labels nothing rather than a bare qualifier when the qualifier belongs to no installed plugin', () => {
|
|
173
|
+
const row = skillRow(categoryWithPlugins([contributed], []), contributed);
|
|
174
|
+
expect(row.origins).to.equal(undefined);
|
|
175
|
+
expect(row.title).to.equal('bigquery:query-builder');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('labels nothing when no bridge is bound, i.e. without `@theia/ai-registry`', () => {
|
|
179
|
+
expect(skillRow(categoryWithPlugins([contributed], undefined), contributed).origins).to.equal(undefined);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('AI registry provenance', () => {
|
|
184
|
+
|
|
185
|
+
const installed = skill({ location: '/home/alex/.agents/skills/query-builder/SKILL.md' });
|
|
186
|
+
const entryId = 'io.github.acme/query-builder';
|
|
187
|
+
|
|
188
|
+
it('labels a registry-installed skill with the shared "From registry" badge', () => {
|
|
189
|
+
const row = skillRow(categoryWithRegistrySkills([installed], { [installed.location]: entryId }), installed);
|
|
190
|
+
expect(row.origins?.map(origin => origin.label)).to.deep.equal(['From registry']);
|
|
191
|
+
expect(row.origins![0].tooltip).to.contain(entryId);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('reveals the registry entry when the badge is activated', () => {
|
|
195
|
+
const revealed: string[] = [];
|
|
196
|
+
const row = skillRow(categoryWithRegistrySkills([installed], { [installed.location]: entryId }, revealed), installed);
|
|
197
|
+
row.origins![0].activate!();
|
|
198
|
+
expect(revealed).to.deep.equal([entryId]);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('labels nothing for a skill in a directory the user controls', () => {
|
|
202
|
+
const own = skill({ location: '/workspace/.agents/skills/query-builder/SKILL.md' });
|
|
203
|
+
expect(skillRow(categoryWithRegistrySkills([own], { [installed.location]: entryId }), own).origins).to.equal(undefined);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('labels nothing when no bridge is bound, i.e. without `@theia/ai-registry`', () => {
|
|
207
|
+
expect(skillRow(categoryWithRegistrySkills([installed], undefined), installed).origins).to.equal(undefined);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('credits the plugin, not the registry, for a skill a plugin contributed', () => {
|
|
211
|
+
// A plugin ships its skills inside the plugin, so the two origins cannot both apply; were the
|
|
212
|
+
// registry consulted anyway, a stale name collision would show a skill as coming from both.
|
|
213
|
+
const bigquery: InstalledPlugin = { pluginId: 'io.example/bq', name: 'BigQuery', qualifier: 'bigquery' };
|
|
214
|
+
const contributed = skill({ qualifiedName: 'bigquery:query-builder', location: '/plugins/bigquery/skills/query-builder/SKILL.md' });
|
|
215
|
+
const category = categoryWithPlugins([contributed], [bigquery]);
|
|
216
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
217
|
+
(category as any).skillRegistryUiBridge = {
|
|
218
|
+
getRegistryEntryId: () => entryId,
|
|
219
|
+
revealSkill: () => { },
|
|
220
|
+
onDidChange: Event.None
|
|
221
|
+
} satisfies SkillRegistryUiBridge;
|
|
222
|
+
|
|
223
|
+
expect(skillRow(category, contributed).origins?.map(origin => origin.label)).to.deep.equal(['via BigQuery']);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|