@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,419 @@
|
|
|
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 { GENERIC_CAPABILITIES_SKILLS_PROMPT_ID, matchVariablesRegEx, parseCapabilitiesFromTemplate } from '@theia/ai-core/lib/common';
|
|
19
|
+
import { PREFERENCE_NAME_SKILL_DIRECTORIES } from '@theia/ai-core/lib/common/ai-core-preferences';
|
|
20
|
+
import { SkillService } from '@theia/ai-core/lib/browser/skill-service';
|
|
21
|
+
import { AgentPluginUiBridge, InstalledAgentPluginInfo } from '@theia/ai-core/lib/browser/agent-plugin-ui-bridge';
|
|
22
|
+
import { SkillRegistryUiBridge } from '@theia/ai-core/lib/browser/skill-registry-ui-bridge';
|
|
23
|
+
import { Skill } from '@theia/ai-core/lib/common/skill';
|
|
24
|
+
import { isCustomizedPromptFragment, PromptFragment, PromptService } from '@theia/ai-core/lib/common/prompt-service';
|
|
25
|
+
import { Emitter, Event, ILogger, nls, URI } from '@theia/core';
|
|
26
|
+
import { codicon, open, OpenerService } from '@theia/core/lib/browser';
|
|
27
|
+
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
28
|
+
import { DisposableCollection } from '@theia/core/lib/common';
|
|
29
|
+
import { inject, injectable, named, optional, postConstruct } from '@theia/core/shared/inversify';
|
|
30
|
+
import * as React from '@theia/core/shared/react';
|
|
31
|
+
import {
|
|
32
|
+
AiConfigurationCategory,
|
|
33
|
+
AiConfigurationCategoryId,
|
|
34
|
+
AiConfigurationCategoryOrder,
|
|
35
|
+
AiConfigurationRenderContext,
|
|
36
|
+
AiConfigurationSearchItem,
|
|
37
|
+
AiConfigurationSearchProvider
|
|
38
|
+
} from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
|
|
39
|
+
import { SinglePageCategoryRenderer } from '@theia/ai-core-ui/lib/browser/ai-configuration/renderers/single-page-category-renderer';
|
|
40
|
+
import {
|
|
41
|
+
AiConfigurationKindBadge,
|
|
42
|
+
AiConfigurationSection,
|
|
43
|
+
AiConfigurationValueRow
|
|
44
|
+
} from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-configuration-primitives';
|
|
45
|
+
import { AiSettingsRow } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-settings-row';
|
|
46
|
+
import { AiSettingsRowService } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-settings-row-service';
|
|
47
|
+
import {
|
|
48
|
+
CollapsibleGroup,
|
|
49
|
+
CollapsibleList,
|
|
50
|
+
CollapsibleRow,
|
|
51
|
+
CollapsibleRowAction
|
|
52
|
+
} from '@theia/ai-core-ui/lib/browser/ai-configuration/components/collapsible-list';
|
|
53
|
+
import { AiConfigurationOrigin } from '@theia/ai-core-ui/lib/browser/ai-configuration/components/ai-configuration-origin-badge';
|
|
54
|
+
import { AgentChips } from './agent-chips';
|
|
55
|
+
|
|
56
|
+
const SKILL_ROW_PREFIX = 'skill:';
|
|
57
|
+
const COMMAND_ROW_PREFIX = 'cmd:';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The "Skills & Slash Commands" category: a `single-page` category that lists skills (file-based
|
|
61
|
+
* `SKILL.md` units) and slash commands (prompt fragments with command metadata) as filterable,
|
|
62
|
+
* expandable rows. A skill row opens its `SKILL.md`; a slash command row opens its template in the
|
|
63
|
+
* editor. Prompt variant sets live in the agent detail, so they are not listed here.
|
|
64
|
+
*/
|
|
65
|
+
@injectable()
|
|
66
|
+
export class PromptsAndSkillsConfigurationCategory extends SinglePageCategoryRenderer implements AiConfigurationCategory, AiConfigurationSearchProvider {
|
|
67
|
+
|
|
68
|
+
readonly id = AiConfigurationCategoryId.PROMPTS_AND_SKILLS;
|
|
69
|
+
readonly label = nls.localize('theia/ai/ide/promptsAndSkillsConfiguration/label', 'Skills & Slash Commands');
|
|
70
|
+
readonly description = nls.localize('theia/ai/ide/promptsAndSkillsConfiguration/pageSubtitle',
|
|
71
|
+
'Skills the model can use and slash commands you invoke with /. Open a skill to edit its SKILL.md, or edit a slash command’s template.');
|
|
72
|
+
readonly iconClass = codicon('mortar-board');
|
|
73
|
+
readonly order = AiConfigurationCategoryOrder.PROMPTS_AND_SKILLS;
|
|
74
|
+
readonly kind = 'single-page' as const;
|
|
75
|
+
|
|
76
|
+
@inject(PromptService)
|
|
77
|
+
protected readonly promptService: PromptService;
|
|
78
|
+
|
|
79
|
+
@inject(AgentService)
|
|
80
|
+
protected readonly agentService: AgentService;
|
|
81
|
+
|
|
82
|
+
@inject(SkillService)
|
|
83
|
+
protected readonly skillService: SkillService;
|
|
84
|
+
|
|
85
|
+
@inject(OpenerService)
|
|
86
|
+
protected readonly openerService: OpenerService;
|
|
87
|
+
|
|
88
|
+
@inject(AiSettingsRowService)
|
|
89
|
+
protected readonly settingsRowService: AiSettingsRowService;
|
|
90
|
+
|
|
91
|
+
@inject(ClipboardService)
|
|
92
|
+
protected readonly clipboardService: ClipboardService;
|
|
93
|
+
|
|
94
|
+
@inject(ILogger) @named('ai-ide:PromptsAndSkillsConfigurationCategory')
|
|
95
|
+
protected readonly logger: ILogger;
|
|
96
|
+
|
|
97
|
+
@inject(AgentPluginUiBridge) @optional()
|
|
98
|
+
protected readonly agentPluginUiBridge?: AgentPluginUiBridge;
|
|
99
|
+
|
|
100
|
+
@inject(SkillRegistryUiBridge) @optional()
|
|
101
|
+
protected readonly skillRegistryUiBridge?: SkillRegistryUiBridge;
|
|
102
|
+
|
|
103
|
+
protected readonly onDidChangeEmitter = new Emitter<void>();
|
|
104
|
+
readonly onDidChange: Event<void> = this.onDidChangeEmitter.event;
|
|
105
|
+
protected readonly toDispose = new DisposableCollection(this.onDidChangeEmitter);
|
|
106
|
+
|
|
107
|
+
protected availableAgents: Agent[] = [];
|
|
108
|
+
protected skills: Skill[] = [];
|
|
109
|
+
protected slashCommands: PromptFragment[] = [];
|
|
110
|
+
|
|
111
|
+
get renderer(): this {
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
getOwnedPreferenceIds(): string[] {
|
|
116
|
+
return [PREFERENCE_NAME_SKILL_DIRECTORIES];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
get search(): AiConfigurationSearchProvider {
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@postConstruct()
|
|
124
|
+
protected init(): void {
|
|
125
|
+
this.loadAgents();
|
|
126
|
+
this.loadSkills();
|
|
127
|
+
this.loadSlashCommands();
|
|
128
|
+
this.toDispose.pushAll([
|
|
129
|
+
this.promptService.onPromptsChange(() => {
|
|
130
|
+
this.loadSlashCommands();
|
|
131
|
+
this.onDidChangeEmitter.fire();
|
|
132
|
+
}),
|
|
133
|
+
this.agentService.onDidChangeAgents(() => {
|
|
134
|
+
this.loadAgents();
|
|
135
|
+
this.onDidChangeEmitter.fire();
|
|
136
|
+
}),
|
|
137
|
+
this.skillService.onSkillsChanged(() => {
|
|
138
|
+
this.loadSkills();
|
|
139
|
+
this.onDidChangeEmitter.fire();
|
|
140
|
+
}),
|
|
141
|
+
this.settingsRowService.onPreferenceChanged(() => this.onDidChangeEmitter.fire())
|
|
142
|
+
]);
|
|
143
|
+
if (this.agentPluginUiBridge) {
|
|
144
|
+
// The plugin names come from the bridge, so installing one changes this page even when the skills do not.
|
|
145
|
+
this.toDispose.push(this.agentPluginUiBridge.onDidChange(() => this.onDidChangeEmitter.fire()));
|
|
146
|
+
}
|
|
147
|
+
if (this.skillRegistryUiBridge) {
|
|
148
|
+
// Likewise: linking or unlinking a skill folder changes its provenance, not the skill itself.
|
|
149
|
+
this.toDispose.push(this.skillRegistryUiBridge.onDidChange(() => this.onDidChangeEmitter.fire()));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
dispose(): void {
|
|
154
|
+
this.toDispose.dispose();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
protected loadAgents(): void {
|
|
158
|
+
this.availableAgents = this.agentService.getAllAgents();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected loadSkills(): void {
|
|
162
|
+
// Sorted and keyed by the qualified name: it is what the model addresses and the only name unique across roots.
|
|
163
|
+
this.skills = this.skillService.getSkills().sort((a, b) => a.qualifiedName.localeCompare(b.qualifiedName));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
protected loadSlashCommands(): void {
|
|
167
|
+
// Skills are surfaced as synthetic `skill-command-*` fragments; they are shown as skills, not duplicated here.
|
|
168
|
+
this.slashCommands = this.promptService.getCommands()
|
|
169
|
+
.filter(command => !command.id.startsWith('skill-command-'))
|
|
170
|
+
.sort((a, b) => (a.commandName ?? a.id).localeCompare(b.commandName ?? b.id));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Stable identity so the value rows do not re-render on every page update. */
|
|
174
|
+
protected copyValue = (value: string): void => {
|
|
175
|
+
// `writeText` may be async depending on the platform; nothing here depends on its completion.
|
|
176
|
+
Promise.resolve(this.clipboardService.writeText(value)).catch(
|
|
177
|
+
error => this.logger.error(`Failed to copy "${value}" to the clipboard`, error));
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
protected getAgentsForCommand(command: PromptFragment): Agent[] {
|
|
181
|
+
if (!command.commandAgents || command.commandAgents.length === 0) {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
return this.availableAgents.filter(agent => command.commandAgents!.includes(agent.id));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
protected renderSections(ctx: AiConfigurationRenderContext): React.ReactNode {
|
|
188
|
+
const onOpenAgent = (agentId: string): void => ctx.navigate({ categoryId: AiConfigurationCategoryId.AGENTS, itemId: agentId });
|
|
189
|
+
const skillAgents = this.getSkillCapableAgents();
|
|
190
|
+
const groups: CollapsibleGroup[] = [
|
|
191
|
+
{
|
|
192
|
+
id: 'skills',
|
|
193
|
+
title: nls.localizeByDefault('Skills'),
|
|
194
|
+
description: skillAgents.length === 0
|
|
195
|
+
? nls.localize('theia/ai/ide/skillsConfiguration/noSkillAgents',
|
|
196
|
+
'No agent currently surfaces skills, so none of these are reached: a skill needs the {{skills}} variable '
|
|
197
|
+
+ 'or the skill usage capability in an agent\'s prompt.')
|
|
198
|
+
: nls.localize('theia/ai/ide/skillsConfiguration/skillsGroupDescription',
|
|
199
|
+
'File-based SKILL.md units the model can choose to follow, surfaced via the {{skills}} variable and the skill usage capability.'),
|
|
200
|
+
rows: this.skills.map(skill => this.buildSkillRow(skill))
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: 'slash-commands',
|
|
204
|
+
title: nls.localize('theia/ai/ide/skillsConfiguration/slashCommandsSectionHeader', 'Slash Commands'),
|
|
205
|
+
description: nls.localize('theia/ai/ide/skillsConfiguration/slashCommandsGroupDescription',
|
|
206
|
+
'Prompt fragments you invoke by typing /name in chat, available to one or more agents.'),
|
|
207
|
+
rows: this.slashCommands.map(command => this.buildCommandRow(command, onOpenAgent))
|
|
208
|
+
}
|
|
209
|
+
];
|
|
210
|
+
return <>
|
|
211
|
+
<AiConfigurationSection title={nls.localizeByDefault('Settings')}>
|
|
212
|
+
<AiSettingsRow
|
|
213
|
+
service={this.settingsRowService}
|
|
214
|
+
preferenceId={PREFERENCE_NAME_SKILL_DIRECTORIES}
|
|
215
|
+
scope={ctx.scope}
|
|
216
|
+
control={this.settingsRowService.controlFor(PREFERENCE_NAME_SKILL_DIRECTORIES)}
|
|
217
|
+
onDidChange={ctx.update}
|
|
218
|
+
/>
|
|
219
|
+
</AiConfigurationSection>
|
|
220
|
+
<CollapsibleList
|
|
221
|
+
groups={groups}
|
|
222
|
+
filterPlaceholder={nls.localize('theia/ai/ide/skillsConfiguration/filterPlaceholder', 'Filter skills and slash commands by name or description')}
|
|
223
|
+
emptyMessage={nls.localize('theia/ai/ide/skillsConfiguration/empty', 'No skills or slash commands are available.')}
|
|
224
|
+
filterEmptyMessage={query => nls.localize('theia/ai/ide/skillsConfiguration/noMatches', 'No skills or slash commands match "{0}".', query)}
|
|
225
|
+
/>
|
|
226
|
+
</>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
protected buildSkillRow(skill: Skill): CollapsibleRow {
|
|
230
|
+
const tools = skill.allowedTools ?? [];
|
|
231
|
+
const metadata = skill.metadata ? Object.entries(skill.metadata) : [];
|
|
232
|
+
const plugin = this.getOwningPlugin(skill);
|
|
233
|
+
const origins = this.getSkillOrigins(skill);
|
|
234
|
+
const pills: string[] = [];
|
|
235
|
+
if (tools.length > 0) {
|
|
236
|
+
pills.push(nls.localizeByDefault('{0} tools', tools.length));
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
id: SKILL_ROW_PREFIX + skill.qualifiedName,
|
|
240
|
+
title: skill.qualifiedName,
|
|
241
|
+
description: skill.description,
|
|
242
|
+
pills,
|
|
243
|
+
origins,
|
|
244
|
+
filterText: `${skill.qualifiedName} ${skill.description ?? ''} ${plugin?.name ?? ''}`.toLocaleLowerCase(),
|
|
245
|
+
actions: <CollapsibleRowAction
|
|
246
|
+
iconClass={codicon('edit')}
|
|
247
|
+
label={nls.localize('theia/ai/ide/skillsConfiguration/openSkillFile', 'Open SKILL.md')}
|
|
248
|
+
onActivate={() => this.openSkill(skill)}
|
|
249
|
+
/>,
|
|
250
|
+
body: <>
|
|
251
|
+
<AiConfigurationValueRow label={nls.localizeByDefault('Location')} value={skill.location} onCopy={this.copyValue} />
|
|
252
|
+
{(skill.license || skill.compatibility || metadata.length > 0) && <div className='ai-variable-section'>
|
|
253
|
+
<div className='ai-variable-section-label'>{nls.localize('theia/ai/ide/skillsConfiguration/frontmatter', 'Frontmatter')}</div>
|
|
254
|
+
{skill.license && <AiConfigurationValueRow
|
|
255
|
+
label={nls.localizeByDefault('License')} value={skill.license} onCopy={this.copyValue} />}
|
|
256
|
+
{skill.compatibility && <AiConfigurationValueRow
|
|
257
|
+
label={nls.localize('theia/ai/ide/skillsConfiguration/compatibility', 'Compatibility')}
|
|
258
|
+
value={skill.compatibility} onCopy={this.copyValue} />}
|
|
259
|
+
{metadata.map(([key, value]) => <AiConfigurationValueRow key={key} label={key} value={value} onCopy={this.copyValue} />)}
|
|
260
|
+
</div>}
|
|
261
|
+
<div className='ai-variable-section'>
|
|
262
|
+
<div className='ai-variable-section-label'>{nls.localizeByDefault('Allowed tools')}</div>
|
|
263
|
+
{tools.length === 0
|
|
264
|
+
? <div className='ai-variable-section-note'>
|
|
265
|
+
{nls.localize('theia/ai/ide/skillsConfiguration/noAllowedTools',
|
|
266
|
+
'No allowed tools declared. The skill may use any tool the agent already has.')}
|
|
267
|
+
</div>
|
|
268
|
+
: <div className='ai-configuration-chip-row'>
|
|
269
|
+
{tools.map(tool => <AiConfigurationKindBadge key={tool} label={tool} variant='outline' />)}
|
|
270
|
+
</div>}
|
|
271
|
+
</div>
|
|
272
|
+
</>
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
protected buildCommandRow(command: PromptFragment, onOpenAgent: (agentId: string) => void): CollapsibleRow {
|
|
277
|
+
const commandName = command.commandName ?? command.id;
|
|
278
|
+
const agents = this.getAgentsForCommand(command);
|
|
279
|
+
const isGlobal = !command.commandAgents || command.commandAgents.length === 0;
|
|
280
|
+
const example = `/${commandName}${command.commandArgumentHint ? ' ' + command.commandArgumentHint : ''}`;
|
|
281
|
+
const pills = [isGlobal
|
|
282
|
+
? nls.localize('theia/ai/ide/skillsConfiguration/slashCommand/allAgents', 'All agents')
|
|
283
|
+
: (agents.length === 1 ? nls.localizeByDefault('1 agent') : nls.localizeByDefault('{0} agents', agents.length))];
|
|
284
|
+
return {
|
|
285
|
+
id: COMMAND_ROW_PREFIX + command.id,
|
|
286
|
+
title: '/' + commandName,
|
|
287
|
+
description: command.commandDescription,
|
|
288
|
+
pills,
|
|
289
|
+
filterText: `${commandName} ${command.id} ${command.commandDescription ?? ''}`.toLocaleLowerCase(),
|
|
290
|
+
actions: <CollapsibleRowAction
|
|
291
|
+
iconClass={codicon('edit')}
|
|
292
|
+
label={nls.localize('theia/ai/ide/skillsConfiguration/editCommandTemplate', 'Edit prompt template')}
|
|
293
|
+
onActivate={() => this.editCommand(command)}
|
|
294
|
+
/>,
|
|
295
|
+
body: <>
|
|
296
|
+
<AiConfigurationValueRow label={nls.localizeByDefault('Command')} value={example} onCopy={this.copyValue} />
|
|
297
|
+
<div className='ai-variable-section'>
|
|
298
|
+
<div className='ai-variable-section-label'>{nls.localize('theia/ai/ide/skillsConfiguration/slashCommand/availableForAgents', 'Available for agents')}</div>
|
|
299
|
+
{/* "All agents" is a value, not an empty state: render it as a chip so it lines up with the
|
|
300
|
+
per-agent chips of a scoped command instead of being centered like a placeholder. */}
|
|
301
|
+
{isGlobal
|
|
302
|
+
? <div className='ai-configuration-chip-row'>
|
|
303
|
+
<AiConfigurationKindBadge
|
|
304
|
+
label={nls.localize('theia/ai/ide/skillsConfiguration/slashCommand/allAgents', 'All agents')}
|
|
305
|
+
variant='outline'
|
|
306
|
+
title={nls.localize('theia/ai/ide/skillsConfiguration/slashCommand/allAgentsTooltip',
|
|
307
|
+
'This command declares no agents, so it is available to every agent.')}
|
|
308
|
+
/>
|
|
309
|
+
</div>
|
|
310
|
+
: <AgentChips agents={agents} onOpenAgent={onOpenAgent} />}
|
|
311
|
+
</div>
|
|
312
|
+
</>
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** Opens the slash command's backing template: its customization if one exists, otherwise the built-in. */
|
|
317
|
+
protected editCommand(command: PromptFragment): void {
|
|
318
|
+
const fragment = this.promptService.getRawPromptFragment(command.id);
|
|
319
|
+
if (fragment && isCustomizedPromptFragment(fragment)) {
|
|
320
|
+
this.promptService.editCustomization(fragment.id, fragment.customizationId);
|
|
321
|
+
} else {
|
|
322
|
+
this.promptService.editBuiltInCustomization(command.id);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Agents that surface skills, i.e. whose effective system prompt references the `{{skills}}`
|
|
328
|
+
* variable or the skills capability (following `{{prompt:...}}` references). Skills are the same
|
|
329
|
+
* for every agent, so this list is not skill-specific.
|
|
330
|
+
*/
|
|
331
|
+
protected getSkillCapableAgents(): Agent[] {
|
|
332
|
+
return this.availableAgents.filter(agent => agent.prompts.some(prompt => {
|
|
333
|
+
const effectiveId = this.promptService.getEffectiveVariantId(prompt.id) ?? prompt.id;
|
|
334
|
+
return this.templateSurfacesSkills(effectiveId, new Set<string>());
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
protected templateSurfacesSkills(fragmentId: string, visited: Set<string>): boolean {
|
|
339
|
+
if (visited.has(fragmentId)) {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
visited.add(fragmentId);
|
|
343
|
+
const template = this.promptService.getRawPromptFragment(fragmentId)?.template;
|
|
344
|
+
if (!template) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
const variableTokens = matchVariablesRegEx(template).map(match => match[1].trim());
|
|
348
|
+
if (variableTokens.some(token => {
|
|
349
|
+
const base = token.split(':')[0].trim();
|
|
350
|
+
return base === 'skills' || base === 'skill';
|
|
351
|
+
})) {
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
if (parseCapabilitiesFromTemplate(template).some(capability => capability.fragmentId === GENERIC_CAPABILITIES_SKILLS_PROMPT_ID)) {
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
return variableTokens.some(token => token.startsWith('prompt:')
|
|
358
|
+
&& this.templateSurfacesSkills(token.slice('prompt:'.length).trim().split('|')[0].trim(), visited));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
protected openSkill(skill: Skill): void {
|
|
362
|
+
open(this.openerService, URI.fromFilePath(skill.location));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* The registry entry a skill was installed from, or the Agent Plugin that contributed it - never
|
|
367
|
+
* both: the registry installs a skill into a root of its own, a plugin ships it inside the plugin.
|
|
368
|
+
* Empty for a workspace or configured skill, which is the common case, and always empty without
|
|
369
|
+
* `@theia/ai-registry`, which binds both bridges.
|
|
370
|
+
*/
|
|
371
|
+
protected getSkillOrigins(skill: Skill): AiConfigurationOrigin[] | undefined {
|
|
372
|
+
const plugin = this.getOwningPlugin(skill);
|
|
373
|
+
if (plugin) {
|
|
374
|
+
return [AiConfigurationOrigin.agentPlugin(plugin, () => this.agentPluginUiBridge?.revealPlugin(plugin.pluginId))];
|
|
375
|
+
}
|
|
376
|
+
const entryId = this.skillRegistryUiBridge?.getRegistryEntryId(skill);
|
|
377
|
+
if (entryId) {
|
|
378
|
+
return [AiConfigurationOrigin.registry(entryId, () => this.skillRegistryUiBridge?.revealSkill(entryId))];
|
|
379
|
+
}
|
|
380
|
+
return undefined;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* The Agent Plugin a skill was contributed by, or `undefined` for a skill from a built-in root - the
|
|
385
|
+
* common case - and for a qualifier belonging to no installed plugin: a bare qualifier is worth neither
|
|
386
|
+
* a label nor a reveal action. Always `undefined` without `@theia/ai-registry`, which binds the bridge.
|
|
387
|
+
*/
|
|
388
|
+
protected getOwningPlugin(skill: Skill): InstalledAgentPluginInfo | undefined {
|
|
389
|
+
const qualifier = Skill.qualifierOf(skill);
|
|
390
|
+
return qualifier ? this.agentPluginUiBridge?.getPluginByQualifier(qualifier) : undefined;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
getSearchItems(): AiConfigurationSearchItem[] {
|
|
394
|
+
const items: AiConfigurationSearchItem[] = [];
|
|
395
|
+
const skillLabel = nls.localizeByDefault('Skill');
|
|
396
|
+
const slashCommandLabel = nls.localize('theia/ai/ide/skillsConfiguration/slashCommandsSectionHeader', 'Slash Commands');
|
|
397
|
+
for (const skill of this.skills) {
|
|
398
|
+
items.push({
|
|
399
|
+
label: skill.qualifiedName,
|
|
400
|
+
typeLabel: skillLabel,
|
|
401
|
+
categoryId: this.id,
|
|
402
|
+
target: { categoryId: this.id, highlight: { rowId: SKILL_ROW_PREFIX + skill.qualifiedName } },
|
|
403
|
+
// The unqualified name too: a skill contributed by a plugin is still looked up by the name in its SKILL.md.
|
|
404
|
+
keywords: `${skill.name} ${skill.description ?? ''}`
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
for (const command of this.slashCommands) {
|
|
408
|
+
items.push({
|
|
409
|
+
label: '/' + (command.commandName ?? command.id),
|
|
410
|
+
typeLabel: slashCommandLabel,
|
|
411
|
+
categoryId: this.id,
|
|
412
|
+
target: { categoryId: this.id, highlight: { rowId: COMMAND_ROW_PREFIX + command.id } },
|
|
413
|
+
keywords: `${command.id} ${command.commandDescription ?? ''}`
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
return items;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
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 { ModelTokenUsageData } from '@theia/ai-core/lib/browser/token-usage-frontend-service';
|
|
25
|
+
import { AiConfigurationCategoryId } from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
|
|
26
|
+
import { TokenUsageConfigurationCategory } from './token-usage-configuration-category';
|
|
27
|
+
|
|
28
|
+
disableJSDOM();
|
|
29
|
+
|
|
30
|
+
describe('TokenUsageConfigurationCategory', () => {
|
|
31
|
+
|
|
32
|
+
before(() => disableJSDOM = enableJSDOM());
|
|
33
|
+
after(() => disableJSDOM());
|
|
34
|
+
|
|
35
|
+
it('declares the token-usage single-page metadata and a page-level search item', () => {
|
|
36
|
+
const category = new TokenUsageConfigurationCategory();
|
|
37
|
+
expect(category.id).to.equal(AiConfigurationCategoryId.TOKEN_USAGE);
|
|
38
|
+
expect(category.kind).to.equal('single-page');
|
|
39
|
+
const items = category.getSearchItems();
|
|
40
|
+
expect(items).to.have.lengthOf(1);
|
|
41
|
+
expect(items[0].target).to.deep.equal({ categoryId: AiConfigurationCategoryId.TOKEN_USAGE });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('shows cache columns only when at least one model reports cache data', () => {
|
|
45
|
+
const category = new TokenUsageConfigurationCategory();
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
+
const withoutCache: ModelTokenUsageData[] = [{ modelId: 'm', inputTokens: 1, outputTokens: 2 } as any];
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
+
(category as any).items = withoutCache;
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
|
+
expect((category as any).hasCacheData()).to.equal(false);
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
+
(category as any).items = [{ modelId: 'm', inputTokens: 1, outputTokens: 2, cachedInputTokens: 3 } as any];
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
+
expect((category as any).hasCacheData()).to.equal(true);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,185 @@
|
|
|
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 { ModelTokenUsageData, TokenUsageFrontendService } from '@theia/ai-core/lib/browser/token-usage-frontend-service';
|
|
18
|
+
import { Emitter, Event, MessageService, nls } from '@theia/core';
|
|
19
|
+
import { codicon } from '@theia/core/lib/browser';
|
|
20
|
+
import { DisposableCollection } from '@theia/core/lib/common';
|
|
21
|
+
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
22
|
+
import * as React from '@theia/core/shared/react';
|
|
23
|
+
import { formatDistanceToNow } from 'date-fns';
|
|
24
|
+
import {
|
|
25
|
+
AiConfigurationCategory,
|
|
26
|
+
AiConfigurationCategoryId,
|
|
27
|
+
AiConfigurationCategoryOrder,
|
|
28
|
+
AiConfigurationSearchItem,
|
|
29
|
+
AiConfigurationSearchProvider
|
|
30
|
+
} from '@theia/ai-core-ui/lib/browser/ai-configuration/ai-configuration-category';
|
|
31
|
+
import { SinglePageCategoryRenderer } from '@theia/ai-core-ui/lib/browser/ai-configuration/renderers/single-page-category-renderer';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The Token Usage category: a read-only `single-page` category showing per-model token usage
|
|
35
|
+
* (input / cache write / cache read / output / total / last-used) with totals. Data is cached and
|
|
36
|
+
* refreshed on the token-usage service updates.
|
|
37
|
+
*/
|
|
38
|
+
@injectable()
|
|
39
|
+
export class TokenUsageConfigurationCategory extends SinglePageCategoryRenderer implements AiConfigurationCategory, AiConfigurationSearchProvider {
|
|
40
|
+
|
|
41
|
+
readonly id = AiConfigurationCategoryId.TOKEN_USAGE;
|
|
42
|
+
readonly label = nls.localize('theia/ai/tokenUsage/label', 'Token Usage');
|
|
43
|
+
readonly description = nls.localize('theia/ai/tokenUsage/description',
|
|
44
|
+
'Review token consumption across providers and models.');
|
|
45
|
+
readonly iconClass = codicon('graph');
|
|
46
|
+
readonly order = AiConfigurationCategoryOrder.TOKEN_USAGE;
|
|
47
|
+
readonly kind = 'single-page' as const;
|
|
48
|
+
|
|
49
|
+
@inject(MessageService)
|
|
50
|
+
protected readonly messageService: MessageService;
|
|
51
|
+
|
|
52
|
+
@inject(TokenUsageFrontendService)
|
|
53
|
+
protected readonly tokenUsageService: TokenUsageFrontendService;
|
|
54
|
+
|
|
55
|
+
protected readonly onDidChangeEmitter = new Emitter<void>();
|
|
56
|
+
readonly onDidChange: Event<void> = this.onDidChangeEmitter.event;
|
|
57
|
+
protected readonly toDispose = new DisposableCollection(this.onDidChangeEmitter);
|
|
58
|
+
|
|
59
|
+
protected items: ModelTokenUsageData[] = [];
|
|
60
|
+
|
|
61
|
+
get renderer(): this {
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get search(): AiConfigurationSearchProvider {
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@postConstruct()
|
|
70
|
+
protected init(): void {
|
|
71
|
+
this.load();
|
|
72
|
+
this.toDispose.push(this.tokenUsageService.onTokenUsageUpdated(data => {
|
|
73
|
+
this.items = [...data].sort((a, b) => a.modelId.localeCompare(b.modelId));
|
|
74
|
+
this.onDidChangeEmitter.fire();
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
dispose(): void {
|
|
79
|
+
this.toDispose.dispose();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
protected async load(): Promise<void> {
|
|
83
|
+
try {
|
|
84
|
+
this.items = (await this.tokenUsageService.getTokenUsageData()).sort((a, b) => a.modelId.localeCompare(b.modelId));
|
|
85
|
+
this.onDidChangeEmitter.fire();
|
|
86
|
+
} catch (error) {
|
|
87
|
+
this.messageService.error(nls.localize('theia/ai/tokenUsage/failedToGetTokenUsageData', 'Failed to fetch token usage data: {0}', String(error)));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected formatNumber(value: number): string {
|
|
92
|
+
return value.toLocaleString();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
protected formatDate(date?: Date): string {
|
|
96
|
+
return date ? formatDistanceToNow(date, { addSuffix: true }) : nls.localizeByDefault('Never');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
protected hasCacheData(): boolean {
|
|
100
|
+
return this.items.some(model => model.cachedInputTokens !== undefined || model.readCachedInputTokens !== undefined);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
protected renderSections(): React.ReactNode {
|
|
104
|
+
if (this.items.length === 0) {
|
|
105
|
+
return <div className='ai-empty-state-content'>
|
|
106
|
+
<p>{nls.localize('theia/ai/tokenUsage/noData', 'No token usage data available yet.')}</p>
|
|
107
|
+
</div>;
|
|
108
|
+
}
|
|
109
|
+
const showCache = this.hasCacheData();
|
|
110
|
+
return <div className='ai-configuration-page'>
|
|
111
|
+
<table className='ai-configuration-table'>
|
|
112
|
+
<thead>
|
|
113
|
+
<tr>
|
|
114
|
+
<th className='token-usage-model-column'>{nls.localizeByDefault('Model')}</th>
|
|
115
|
+
<th className='token-usage-column'>{nls.localize('theia/ai/tokenUsage/inputTokens', 'Input Tokens')}</th>
|
|
116
|
+
{showCache && <>
|
|
117
|
+
<th className='token-usage-column'>{nls.localize('theia/ai/tokenUsage/cachedInputTokens', 'Input Tokens Written to Cache')}</th>
|
|
118
|
+
<th className='token-usage-column'>{nls.localize('theia/ai/tokenUsage/readCachedInputTokens', 'Input Tokens Read From Cache')}</th>
|
|
119
|
+
</>}
|
|
120
|
+
<th className='token-usage-column'>{nls.localize('theia/ai/tokenUsage/outputTokens', 'Output Tokens')}</th>
|
|
121
|
+
<th className='token-usage-column'>{nls.localizeByDefault('Total Tokens')}</th>
|
|
122
|
+
<th className='token-usage-column'>{nls.localize('theia/ai/tokenUsage/lastUsed', 'Last Used')}</th>
|
|
123
|
+
</tr>
|
|
124
|
+
</thead>
|
|
125
|
+
<tbody>
|
|
126
|
+
{this.items.map(item => this.renderRow(item, showCache))}
|
|
127
|
+
</tbody>
|
|
128
|
+
{this.renderTotals(showCache)}
|
|
129
|
+
</table>
|
|
130
|
+
<div className='ai-configuration-info-box'>
|
|
131
|
+
<p className='ai-configuration-info-text'>
|
|
132
|
+
<i className={`${codicon('info')} ai-configuration-info-icon`}></i>
|
|
133
|
+
{nls.localize('theia/ai/tokenUsage/note', 'Token usage is tracked since the start of the application and is not persisted.')}
|
|
134
|
+
</p>
|
|
135
|
+
</div>
|
|
136
|
+
</div>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
protected renderRow(item: ModelTokenUsageData, showCache: boolean): React.ReactNode {
|
|
140
|
+
const total = item.inputTokens + item.outputTokens + (item.cachedInputTokens ?? 0);
|
|
141
|
+
const lastUsedDate = item.lastUsed ? new Date(item.lastUsed) : undefined;
|
|
142
|
+
return <tr key={item.modelId}>
|
|
143
|
+
<td className='token-usage-model-column'>{item.modelId}</td>
|
|
144
|
+
<td className='token-usage-column'>{this.formatNumber(item.inputTokens)}</td>
|
|
145
|
+
{showCache && <>
|
|
146
|
+
<td className='token-usage-column'>{item.cachedInputTokens !== undefined ? this.formatNumber(item.cachedInputTokens) : '-'}</td>
|
|
147
|
+
<td className='token-usage-column'>{item.readCachedInputTokens !== undefined ? this.formatNumber(item.readCachedInputTokens) : '-'}</td>
|
|
148
|
+
</>}
|
|
149
|
+
<td className='token-usage-column'>{this.formatNumber(item.outputTokens)}</td>
|
|
150
|
+
<td className='token-usage-column'>{this.formatNumber(total)}</td>
|
|
151
|
+
<td className='token-usage-column' title={lastUsedDate ? lastUsedDate.toLocaleString() : undefined}>{this.formatDate(lastUsedDate)}</td>
|
|
152
|
+
</tr>;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
protected renderTotals(showCache: boolean): React.ReactNode {
|
|
156
|
+
const sum = (pick: (model: ModelTokenUsageData) => number): number => this.items.reduce((total, model) => total + pick(model), 0);
|
|
157
|
+
const totalInput = sum(model => model.inputTokens);
|
|
158
|
+
const totalOutput = sum(model => model.outputTokens);
|
|
159
|
+
const totalCached = sum(model => model.cachedInputTokens ?? 0);
|
|
160
|
+
const totalRead = sum(model => model.readCachedInputTokens ?? 0);
|
|
161
|
+
return <tfoot>
|
|
162
|
+
<tr className='ai-configuration-footer-total-row'>
|
|
163
|
+
<td className='token-usage-model-column'>{nls.localizeByDefault('Total')}</td>
|
|
164
|
+
<td className='token-usage-column'>{this.formatNumber(totalInput)}</td>
|
|
165
|
+
{showCache && <>
|
|
166
|
+
<td className='token-usage-column'>{this.formatNumber(totalCached)}</td>
|
|
167
|
+
<td className='token-usage-column'>{this.formatNumber(totalRead)}</td>
|
|
168
|
+
</>}
|
|
169
|
+
<td className='token-usage-column'>{this.formatNumber(totalOutput)}</td>
|
|
170
|
+
<td className='token-usage-column'>{this.formatNumber(totalInput + totalCached + totalOutput)}</td>
|
|
171
|
+
<td className='token-usage-column'></td>
|
|
172
|
+
</tr>
|
|
173
|
+
</tfoot>;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
getSearchItems(): AiConfigurationSearchItem[] {
|
|
177
|
+
return [{
|
|
178
|
+
label: this.label,
|
|
179
|
+
typeLabel: nls.localize('theia/ai/ide/aiConfiguration/pageTypeLabel', 'Page'),
|
|
180
|
+
categoryId: this.id,
|
|
181
|
+
target: { categoryId: this.id },
|
|
182
|
+
keywords: 'token usage tokens cost'
|
|
183
|
+
}];
|
|
184
|
+
}
|
|
185
|
+
}
|