@theia/ai-ide 1.76.0-next.7 → 1.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/lib/browser/ai-allow-all-mode-chat-banner.js +1 -1
  2. package/lib/browser/ai-allow-all-mode-chat-banner.js.map +1 -1
  3. package/lib/browser/ai-aware-scm-commit-widget.d.ts +27 -0
  4. package/lib/browser/ai-aware-scm-commit-widget.d.ts.map +1 -0
  5. package/lib/browser/ai-aware-scm-commit-widget.js +142 -0
  6. package/lib/browser/ai-aware-scm-commit-widget.js.map +1 -0
  7. package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts +10 -4
  8. package/lib/browser/ai-configuration/ai-configuration-detail-widget.d.ts.map +1 -1
  9. package/lib/browser/ai-configuration/ai-configuration-detail-widget.js +12 -7
  10. package/lib/browser/ai-configuration/ai-configuration-detail-widget.js.map +1 -1
  11. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js +14 -14
  12. package/lib/browser/ai-configuration/ai-configuration-detail-widget.spec.js.map +1 -1
  13. package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts +6 -0
  14. package/lib/browser/ai-configuration/ai-configuration-tree-widget.d.ts.map +1 -1
  15. package/lib/browser/ai-configuration/ai-configuration-tree-widget.js +9 -0
  16. package/lib/browser/ai-configuration/ai-configuration-tree-widget.js.map +1 -1
  17. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.d.ts.map +1 -1
  18. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js +2 -1
  19. package/lib/browser/ai-configuration/categories/agent-capabilities-settings.js.map +1 -1
  20. package/lib/browser/ai-configuration/categories/agent-chips.js +1 -1
  21. package/lib/browser/ai-configuration/categories/agent-chips.js.map +1 -1
  22. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts +8 -0
  23. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.d.ts.map +1 -1
  24. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js +27 -8
  25. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.js.map +1 -1
  26. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js +38 -2
  27. package/lib/browser/ai-configuration/categories/model-aliases-configuration-category.spec.js.map +1 -1
  28. package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts +13 -2
  29. package/lib/browser/ai-configuration/categories/models-configuration-category.d.ts.map +1 -1
  30. package/lib/browser/ai-configuration/categories/models-configuration-category.js +41 -2
  31. package/lib/browser/ai-configuration/categories/models-configuration-category.js.map +1 -1
  32. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js +32 -2
  33. package/lib/browser/ai-configuration/categories/models-configuration-category.spec.js.map +1 -1
  34. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.d.ts +26 -0
  35. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.d.ts.map +1 -0
  36. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.js +212 -0
  37. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.js.map +1 -0
  38. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.spec.d.ts +2 -0
  39. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.spec.d.ts.map +1 -0
  40. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.spec.js +423 -0
  41. package/lib/browser/ai-configuration/categories/provider-model-discovery-section.spec.js.map +1 -0
  42. package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -1
  43. package/lib/browser/ai-configuration/language-model-renderer.js +10 -3
  44. package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -1
  45. package/lib/browser/ai-getting-started-commands.d.ts +10 -0
  46. package/lib/browser/ai-getting-started-commands.d.ts.map +1 -0
  47. package/lib/browser/ai-getting-started-commands.js +34 -0
  48. package/lib/browser/ai-getting-started-commands.js.map +1 -0
  49. package/lib/browser/ai-getting-started-contribution.d.ts +20 -0
  50. package/lib/browser/ai-getting-started-contribution.d.ts.map +1 -0
  51. package/lib/browser/ai-getting-started-contribution.js +70 -0
  52. package/lib/browser/ai-getting-started-contribution.js.map +1 -0
  53. package/lib/browser/ai-getting-started-walkthrough.d.ts +41 -0
  54. package/lib/browser/ai-getting-started-walkthrough.d.ts.map +1 -0
  55. package/lib/browser/ai-getting-started-walkthrough.js +225 -0
  56. package/lib/browser/ai-getting-started-walkthrough.js.map +1 -0
  57. package/lib/browser/ai-getting-started-walkthrough.spec.d.ts +2 -0
  58. package/lib/browser/ai-getting-started-walkthrough.spec.d.ts.map +1 -0
  59. package/lib/browser/ai-getting-started-walkthrough.spec.js +124 -0
  60. package/lib/browser/ai-getting-started-walkthrough.spec.js.map +1 -0
  61. package/lib/browser/ai-walkthrough-context-keys.d.ts +55 -0
  62. package/lib/browser/ai-walkthrough-context-keys.d.ts.map +1 -0
  63. package/lib/browser/ai-walkthrough-context-keys.js +145 -0
  64. package/lib/browser/ai-walkthrough-context-keys.js.map +1 -0
  65. package/lib/browser/ai-walkthrough-context-keys.spec.d.ts +2 -0
  66. package/lib/browser/ai-walkthrough-context-keys.spec.d.ts.map +1 -0
  67. package/lib/browser/ai-walkthrough-context-keys.spec.js +166 -0
  68. package/lib/browser/ai-walkthrough-context-keys.spec.js.map +1 -0
  69. package/lib/browser/chat-session-item.js +2 -2
  70. package/lib/browser/chat-session-item.js.map +1 -1
  71. package/lib/browser/commit-message-agent.d.ts +31 -0
  72. package/lib/browser/commit-message-agent.d.ts.map +1 -0
  73. package/lib/browser/commit-message-agent.js +99 -0
  74. package/lib/browser/commit-message-agent.js.map +1 -0
  75. package/lib/browser/commit-message-agent.spec.d.ts +2 -0
  76. package/lib/browser/commit-message-agent.spec.d.ts.map +1 -0
  77. package/lib/browser/commit-message-agent.spec.js +82 -0
  78. package/lib/browser/commit-message-agent.spec.js.map +1 -0
  79. package/lib/browser/commit-message-command-contribution.d.ts +15 -0
  80. package/lib/browser/commit-message-command-contribution.d.ts.map +1 -0
  81. package/lib/browser/commit-message-command-contribution.js +73 -0
  82. package/lib/browser/commit-message-command-contribution.js.map +1 -0
  83. package/lib/browser/commit-message-commands.d.ts +5 -0
  84. package/lib/browser/commit-message-commands.d.ts.map +1 -0
  85. package/lib/browser/commit-message-commands.js +28 -0
  86. package/lib/browser/commit-message-commands.js.map +1 -0
  87. package/lib/browser/commit-message-prompt-template.d.ts +11 -0
  88. package/lib/browser/commit-message-prompt-template.d.ts.map +1 -0
  89. package/lib/browser/commit-message-prompt-template.js +63 -0
  90. package/lib/browser/commit-message-prompt-template.js.map +1 -0
  91. package/lib/browser/commit-message-runner.d.ts +41 -0
  92. package/lib/browser/commit-message-runner.d.ts.map +1 -0
  93. package/lib/browser/commit-message-runner.js +143 -0
  94. package/lib/browser/commit-message-runner.js.map +1 -0
  95. package/lib/browser/commit-message-runner.spec.d.ts +2 -0
  96. package/lib/browser/commit-message-runner.spec.d.ts.map +1 -0
  97. package/lib/browser/commit-message-runner.spec.js +206 -0
  98. package/lib/browser/commit-message-runner.spec.js.map +1 -0
  99. package/lib/browser/frontend-module.d.ts.map +1 -1
  100. package/lib/browser/frontend-module.js +25 -0
  101. package/lib/browser/frontend-module.js.map +1 -1
  102. package/lib/browser/git-changes-tool.d.ts +73 -0
  103. package/lib/browser/git-changes-tool.d.ts.map +1 -0
  104. package/lib/browser/git-changes-tool.js +217 -0
  105. package/lib/browser/git-changes-tool.js.map +1 -0
  106. package/lib/browser/git-changes-tool.spec.d.ts +2 -0
  107. package/lib/browser/git-changes-tool.spec.d.ts.map +1 -0
  108. package/lib/browser/git-changes-tool.spec.js +167 -0
  109. package/lib/browser/git-changes-tool.spec.js.map +1 -0
  110. package/lib/browser/ide-chat-welcome-message-provider.d.ts +26 -28
  111. package/lib/browser/ide-chat-welcome-message-provider.d.ts.map +1 -1
  112. package/lib/browser/ide-chat-welcome-message-provider.js +61 -151
  113. package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
  114. package/lib/browser/review/pr-review-capability-contribution.js +1 -1
  115. package/lib/browser/review/pr-review-capability-contribution.js.map +1 -1
  116. package/lib/browser/user-interaction-tool-renderer.d.ts +6 -0
  117. package/lib/browser/user-interaction-tool-renderer.d.ts.map +1 -1
  118. package/lib/browser/user-interaction-tool-renderer.js +36 -7
  119. package/lib/browser/user-interaction-tool-renderer.js.map +1 -1
  120. package/lib/browser/user-interaction-tool.d.ts +23 -1
  121. package/lib/browser/user-interaction-tool.d.ts.map +1 -1
  122. package/lib/browser/user-interaction-tool.js +56 -17
  123. package/lib/browser/user-interaction-tool.js.map +1 -1
  124. package/lib/browser/user-interaction-tool.spec.js +151 -2
  125. package/lib/browser/user-interaction-tool.spec.js.map +1 -1
  126. package/lib/common/command-prompt-template.js +1 -1
  127. package/lib/common/user-interaction-tool.d.ts +19 -1
  128. package/lib/common/user-interaction-tool.d.ts.map +1 -1
  129. package/lib/common/user-interaction-tool.js +100 -29
  130. package/lib/common/user-interaction-tool.js.map +1 -1
  131. package/lib/common/user-interaction-tool.spec.js +215 -174
  132. package/lib/common/user-interaction-tool.spec.js.map +1 -1
  133. package/package.json +26 -25
  134. package/src/browser/ai-allow-all-mode-chat-banner.tsx +2 -2
  135. package/src/browser/ai-aware-scm-commit-widget.tsx +153 -0
  136. package/src/browser/ai-configuration/ai-configuration-detail-widget.spec.ts +14 -14
  137. package/src/browser/ai-configuration/ai-configuration-detail-widget.tsx +12 -7
  138. package/src/browser/ai-configuration/ai-configuration-tree-widget.tsx +8 -0
  139. package/src/browser/ai-configuration/categories/agent-capabilities-settings.tsx +7 -8
  140. package/src/browser/ai-configuration/categories/agent-chips.tsx +1 -1
  141. package/src/browser/ai-configuration/categories/model-aliases-configuration-category.spec.ts +40 -2
  142. package/src/browser/ai-configuration/categories/model-aliases-configuration-category.tsx +31 -10
  143. package/src/browser/ai-configuration/categories/models-configuration-category.spec.ts +47 -2
  144. package/src/browser/ai-configuration/categories/models-configuration-category.tsx +52 -5
  145. package/src/browser/ai-configuration/categories/provider-model-discovery-section.spec.tsx +451 -0
  146. package/src/browser/ai-configuration/categories/provider-model-discovery-section.tsx +341 -0
  147. package/src/browser/ai-configuration/language-model-renderer.tsx +11 -3
  148. package/src/browser/ai-getting-started-commands.ts +33 -0
  149. package/src/browser/ai-getting-started-contribution.ts +64 -0
  150. package/src/browser/ai-getting-started-walkthrough.spec.ts +146 -0
  151. package/src/browser/ai-getting-started-walkthrough.ts +249 -0
  152. package/src/browser/ai-walkthrough-context-keys.spec.ts +209 -0
  153. package/src/browser/ai-walkthrough-context-keys.ts +147 -0
  154. package/src/browser/chat-session-item.tsx +2 -2
  155. package/src/browser/commit-message-agent.spec.ts +97 -0
  156. package/src/browser/commit-message-agent.ts +113 -0
  157. package/src/browser/commit-message-command-contribution.ts +67 -0
  158. package/src/browser/commit-message-commands.ts +25 -0
  159. package/src/browser/commit-message-prompt-template.ts +65 -0
  160. package/src/browser/commit-message-runner.spec.ts +266 -0
  161. package/src/browser/commit-message-runner.ts +163 -0
  162. package/src/browser/frontend-module.ts +27 -0
  163. package/src/browser/git-changes-tool.spec.ts +200 -0
  164. package/src/browser/git-changes-tool.ts +239 -0
  165. package/src/browser/ide-chat-welcome-message-provider.tsx +93 -230
  166. package/src/browser/review/pr-review-capability-contribution.ts +1 -1
  167. package/src/browser/style/commit-message-overlay.css +64 -0
  168. package/src/browser/style/index.css +4 -42
  169. package/src/browser/user-interaction-tool-renderer.tsx +38 -8
  170. package/src/browser/user-interaction-tool.spec.ts +201 -2
  171. package/src/browser/user-interaction-tool.ts +69 -18
  172. package/src/common/command-prompt-template.ts +1 -1
  173. package/src/common/user-interaction-tool.spec.ts +217 -161
  174. package/src/common/user-interaction-tool.ts +127 -32
@@ -20,16 +20,16 @@ import { nls } from '@theia/core/lib/common/nls';
20
20
  import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
21
21
  import { codicon, LocalizedMarkdown, MarkdownRenderer } from '@theia/core/lib/browser';
22
22
  import { CommandRegistry, DisposableCollection, Emitter, Event, PreferenceScope } from '@theia/core';
23
- import { AgentService, FrontendLanguageModelRegistry } from '@theia/ai-core/lib/common';
23
+ import { FrontendLanguageModelRegistry } from '@theia/ai-core/lib/common';
24
24
  import { PreferenceService } from '@theia/core/lib/common';
25
- import { DEFAULT_CHAT_AGENT_PREF, BYPASS_MODEL_REQUIREMENT_PREF, PERSISTED_SESSION_LIMIT_PREF, SESSION_STORAGE_PREF } from '@theia/ai-chat/lib/common/ai-chat-preferences';
26
- import { ChatAgentRecommendationService, ChatAgentService, ChatService } from '@theia/ai-chat/lib/common';
27
- import { ToolConfirmationManager } from '@theia/ai-chat/lib/browser/chat-tool-preference-bindings';
28
- import { DEFAULT_TOOL_CONFIRMATION_PREFERENCE, TOOL_CONFIRMATION_PREFERENCE, ToolConfirmationMode } from '@theia/ai-chat/lib/common/chat-tool-preferences';
29
- import { OPEN_AI_CONFIG_VIEW, OPEN_AI_CONFIG_VIEW_TOOLS } from './ai-configuration/ai-configuration-view-contribution';
25
+ import { BYPASS_MODEL_REQUIREMENT_PREF, DEFAULT_CHAT_AGENT_PREF } from '@theia/ai-chat/lib/common/ai-chat-preferences';
26
+ import { WalkthroughService } from '@theia/getting-started/lib/browser/walkthrough-service';
27
+ import { OPEN_AI_CONFIG_VIEW } from './ai-configuration/ai-configuration-view-contribution';
30
28
  import { AIActivationService } from '@theia/ai-core/lib/browser';
31
29
  import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
32
30
  import { WorkspaceCommands } from '@theia/workspace/lib/browser/workspace-commands';
31
+ import { AI_OPEN_GETTING_STARTED_WALKTHROUGH } from './ai-getting-started-commands';
32
+ import { AI_GETTING_STARTED_WALKTHROUGH_ID } from './ai-getting-started-walkthrough';
33
33
 
34
34
  const TheiaIdeAiLogo = ({ width = 120, height = 120, className = '' }) =>
35
35
  <svg
@@ -59,6 +59,13 @@ const TheiaIdeAiLogo = ({ width = 120, height = 120, className = '' }) =>
59
59
  <circle cx="62" cy="84" r="2.5" fill="var(--theia-disabledForeground)" opacity="0.65" />
60
60
  </svg>;
61
61
 
62
+ /**
63
+ * The welcome message of the chat view.
64
+ *
65
+ * It only covers what has to be shown right here: the states that keep the chat from working (no language
66
+ * model, AI turned off, workspace not trusted) and a one-line reminder of how to talk to the agents. Everything
67
+ * that teaches the AI features lives in the "Get started with AI" walkthrough, which each state links to.
68
+ */
62
69
  @injectable()
63
70
  export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider {
64
71
 
@@ -76,31 +83,17 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
76
83
  @inject(PreferenceService)
77
84
  protected preferenceService: PreferenceService;
78
85
 
79
- @inject(ChatAgentRecommendationService)
80
- protected recommendationService: ChatAgentRecommendationService;
81
-
82
- @inject(ChatAgentService)
83
- protected chatAgentService: ChatAgentService;
84
-
85
- @inject(AgentService)
86
- protected agentService: AgentService;
87
-
88
- @inject(ToolConfirmationManager)
89
- protected readonly toolConfirmationManager: ToolConfirmationManager;
90
-
91
86
  @inject(AIActivationService)
92
87
  protected readonly activationService: AIActivationService;
93
88
 
94
- @inject(ChatService)
95
- protected readonly chatService: ChatService;
89
+ @inject(WalkthroughService)
90
+ protected readonly walkthroughService: WalkthroughService;
96
91
 
97
92
  protected readonly toDispose = new DisposableCollection();
98
93
  protected _hasReadyModels = false;
99
94
  protected _modelRequirementBypassed = false;
100
- protected _defaultAgent = '';
95
+ protected _hasDefaultAgent = false;
101
96
  protected modelConfig: { hasModels: boolean; errorMessages: string[] } | undefined;
102
- /** True once the user has any chat (active or persisted). Drives the compact "has-chats" welcome variant. */
103
- protected hasAnyChat = false;
104
97
 
105
98
  protected readonly onStateChangedEmitter = new Emitter<void>();
106
99
 
@@ -118,44 +111,28 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
118
111
  );
119
112
  this.toDispose.push(
120
113
  this.preferenceService.onPreferenceChanged(e => {
121
- if (e.preferenceName === DEFAULT_CHAT_AGENT_PREF) {
122
- const effectiveValue = this.preferenceService.get<string>(DEFAULT_CHAT_AGENT_PREF, '');
123
- if (this._defaultAgent !== effectiveValue) {
124
- this._defaultAgent = effectiveValue;
125
- this.notifyStateChanged();
126
- }
127
- } else if (e.preferenceName === BYPASS_MODEL_REQUIREMENT_PREF) {
114
+ if (e.preferenceName === BYPASS_MODEL_REQUIREMENT_PREF) {
128
115
  const effectiveValue = this.preferenceService.get<boolean>(BYPASS_MODEL_REQUIREMENT_PREF, false);
129
116
  if (this._modelRequirementBypassed !== effectiveValue) {
130
117
  this._modelRequirementBypassed = effectiveValue;
131
118
  this.notifyStateChanged();
132
119
  }
133
- } else if (e.preferenceName === DEFAULT_TOOL_CONFIRMATION_PREFERENCE || e.preferenceName === TOOL_CONFIRMATION_PREFERENCE) {
134
- // Re-render so the tool-confirmation explainer is hidden once the user configures confirmation behavior.
135
- this.notifyStateChanged();
136
- } else if (e.preferenceName === SESSION_STORAGE_PREF || e.preferenceName === PERSISTED_SESSION_LIMIT_PREF) {
137
- this.refreshHasAnyChat();
120
+ } else if (e.preferenceName === DEFAULT_CHAT_AGENT_PREF) {
121
+ this.updateDefaultAgentState();
138
122
  }
139
123
  })
140
124
  );
125
+ // The setup action disappears once the walkthrough is done.
141
126
  this.toDispose.push(
142
- this.chatService.onSessionEvent(() => this.refreshHasAnyChat())
143
- );
144
- this.refreshHasAnyChat();
145
- this.toDispose.push(
146
- this.agentService.onDidChangeAgents(() => {
147
- this.notifyStateChanged();
148
- })
127
+ this.walkthroughService.onDidChangeWalkthroughs(() => this.notifyStateChanged())
149
128
  );
150
129
  this.analyzeModelConfiguration().then(config => {
151
130
  this.modelConfig = config;
152
131
  this.notifyStateChanged();
153
132
  });
154
133
  this.preferenceService.ready.then(() => {
155
- const defaultAgentValue = this.preferenceService.get(DEFAULT_CHAT_AGENT_PREF, '');
156
- const bypassValue = this.preferenceService.get(BYPASS_MODEL_REQUIREMENT_PREF, false);
157
- this._defaultAgent = defaultAgentValue;
158
- this._modelRequirementBypassed = bypassValue;
134
+ this._modelRequirementBypassed = this.preferenceService.get(BYPASS_MODEL_REQUIREMENT_PREF, false);
135
+ this.updateDefaultAgentState();
159
136
  this.notifyStateChanged();
160
137
  });
161
138
  // Listen to both canRun and activeStatus changes. They may change independent from each other.
@@ -171,6 +148,14 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
171
148
  );
172
149
  }
173
150
 
151
+ protected updateDefaultAgentState(): void {
152
+ const hasDefaultAgent = !!this.preferenceService.get<string>(DEFAULT_CHAT_AGENT_PREF, '');
153
+ if (this._hasDefaultAgent !== hasDefaultAgent) {
154
+ this._hasDefaultAgent = hasDefaultAgent;
155
+ this.notifyStateChanged();
156
+ }
157
+ }
158
+
174
159
  protected async checkLanguageModelStatus(): Promise<void> {
175
160
  const models = await this.languageModelRegistry.getLanguageModels();
176
161
  this._hasReadyModels = models.some(model => model.status.status === 'ready');
@@ -193,28 +178,6 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
193
178
  this.onStateChangedEmitter.fire();
194
179
  }
195
180
 
196
- /**
197
- * Recomputes {@link hasAnyChat} (true when the user has any titled active session or any
198
- * persisted session on disk). Fires a state change when the flag flips so the welcome
199
- * variant updates between the rich onboarding (no chats yet) and the compact mode.
200
- */
201
- protected async refreshHasAnyChat(): Promise<void> {
202
- const hasTitledActive = this.chatService.getSessions().some(s => !!s.title);
203
- let hasPersisted = false;
204
- if (!hasTitledActive) {
205
- try {
206
- hasPersisted = await this.chatService.hasPersistedSessions();
207
- } catch {
208
- hasPersisted = false;
209
- }
210
- }
211
- const next = hasTitledActive || hasPersisted;
212
- if (this.hasAnyChat !== next) {
213
- this.hasAnyChat = next;
214
- this.notifyStateChanged();
215
- }
216
- }
217
-
218
181
  get hasReadyModels(): boolean {
219
182
  return this._hasReadyModels;
220
183
  }
@@ -223,31 +186,23 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
223
186
  return this._modelRequirementBypassed;
224
187
  }
225
188
 
226
- get defaultAgent(): string {
227
- return this._defaultAgent;
228
- }
229
-
230
189
  /**
231
- * Whether to show the tool-confirmation explainer on the welcome screen.
232
- *
233
- * Only shown while the user is still in the default state, i.e. every tool call is confirmed and
234
- * no per-tool overrides exist. Once the user has changed the default mode (e.g. to always allow
235
- * or to disable tools) or pre-approved individual tools (including via bulk approval), they are
236
- * already aware of the mechanism, so the explainer is suppressed.
190
+ * Whether the getting started walkthrough still has something to offer. Once it is finished, the chat view
191
+ * stops advertising it.
237
192
  */
238
- protected get shouldShowToolConfirmationInfo(): boolean {
239
- return this.toolConfirmationManager.getDefaultConfirmationMode() === ToolConfirmationMode.CONFIRM
240
- && Object.keys(this.toolConfirmationManager.getAllConfirmationSettings()).length === 0;
193
+ protected get hasPendingWalkthroughSteps(): boolean {
194
+ const { completed, total } = this.walkthroughService.getStepProgress(AI_GETTING_STARTED_WALKTHROUGH_ID);
195
+ return total > 0 && completed < total;
241
196
  }
242
197
 
198
+ protected openWalkthrough = () => this.commandRegistry.executeCommand(AI_OPEN_GETTING_STARTED_WALKTHROUGH.id);
199
+
200
+ protected openAiConfiguration = () => this.commandRegistry.executeCommand(OPEN_AI_CONFIG_VIEW.id);
201
+
243
202
  protected setModelRequirementBypassed(bypassed: boolean): void {
244
203
  this.preferenceService.set(BYPASS_MODEL_REQUIREMENT_PREF, bypassed, PreferenceScope.User);
245
204
  }
246
205
 
247
- protected setDefaultAgent(agentId: string): void {
248
- this.preferenceService.set(DEFAULT_CHAT_AGENT_PREF, agentId, PreferenceScope.User);
249
- }
250
-
251
206
  dispose(): void {
252
207
  this.toDispose.dispose();
253
208
  this.onStateChangedEmitter.dispose();
@@ -257,87 +212,75 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
257
212
  if (!this._hasReadyModels && !this._modelRequirementBypassed) {
258
213
  return this.renderModelConfigurationScreen();
259
214
  }
260
- if (!this._defaultAgent) {
261
- return this.renderAgentSelectionScreen();
262
- }
263
215
  return this.renderWelcomeScreen();
264
216
  }
265
217
 
266
218
  protected renderWelcomeScreen(): React.ReactNode {
267
- if (this.hasAnyChat) {
268
- // Returning user: keep a slim banner (logo + heading + one-line tip) above the
269
- // sessions list so the chat view still has identity, but skip the verbose
270
- // multi-paragraph tutorial.
271
- return <div className={'theia-WelcomeMessage theia-WelcomeMessage-Compact'} key="normal-welcome-compact">
272
- <TheiaIdeAiLogo className="theia-WelcomeMessage-Logo" width={64} height={64} />
273
- <LocalizedMarkdown
274
- localizationKey="theia/ai/ide/chatWelcomeMessageShort"
275
- defaultMarkdown={`
276
- ## Ask the {0} AI
277
-
278
- Use *@agent* to call a specialized agent and *#* (or {1}) to attach context. [Learn more](https://theia-ide.org/docs/user_ai/#chat).
279
- `}
280
- args={[
281
- FrontendApplicationConfigProvider.get().applicationName,
282
- '<span class="codicon codicon-attach"></span>'
283
- ]}
284
- markdownRenderer={this.markdownRenderer}
285
- className="theia-WelcomeMessage-Content"
286
- markdownOptions={{ supportHtml: true }}
287
- />
288
- {this.renderToolConfirmationAlert()}
289
- </div>;
290
- }
291
- // First-time user: original full-length onboarding with the larger logo and the
292
- // verbose agent/context paragraphs so the empty panel feels welcoming.
293
- return <div className={'theia-WelcomeMessage theia-WelcomeMessage-Main'} key="normal-welcome">
294
- <TheiaIdeAiLogo className="theia-WelcomeMessage-Logo" />
219
+ return <div className={'theia-WelcomeMessage theia-WelcomeMessage-Compact'} key="normal-welcome">
220
+ <TheiaIdeAiLogo className="theia-WelcomeMessage-Logo" width={64} height={64} />
295
221
  <LocalizedMarkdown
296
- localizationKey="theia/ai/ide/chatWelcomeMessage"
222
+ localizationKey="theia/ai/ide/chatWelcomeMessageShort"
297
223
  defaultMarkdown={`
298
- ## Ask the {7} AI
299
-
300
- Use *@AgentName* to talk to a specialized agent, like *@{0}*, *@{1}*, or *@{2}*.
224
+ ## Ask the {0} AI
301
225
 
302
- Attach context with *#{3}*, *#{4}*, *#{5}*, or click {6}. [Learn more](https://theia-ide.org/docs/user_ai/#chat).
226
+ Use *@agent* to call a specialized agent and *#* (or {1}) to attach context. [Learn more](https://theia-ide.org/docs/user_ai/#chat).
303
227
  `}
304
- args={['Coder', 'Architect', 'Universal', 'file', '_f', 'selectedText', '<span class="codicon codicon-attach"></span>',
305
- FrontendApplicationConfigProvider.get().applicationName]}
228
+ args={[
229
+ FrontendApplicationConfigProvider.get().applicationName,
230
+ '<span class="codicon codicon-attach"></span>'
231
+ ]}
306
232
  markdownRenderer={this.markdownRenderer}
307
233
  className="theia-WelcomeMessage-Content"
308
234
  markdownOptions={{ supportHtml: true }}
309
235
  />
310
- {this.renderToolConfirmationAlert()}
236
+ {this.renderDefaultAgentAlert()}
237
+ {this.renderWalkthroughAction()}
311
238
  </div>;
312
239
  }
313
240
 
314
- protected renderToolConfirmationAlert(): React.ReactNode {
315
- if (!this.shouldShowToolConfirmationInfo) {
241
+ /**
242
+ * Nothing answers a message that does not name an agent while no default agent is configured, so the chat
243
+ * has to say so where the message is typed rather than leaving the first request to fail.
244
+ */
245
+ protected renderDefaultAgentAlert(): React.ReactNode {
246
+ if (this._hasDefaultAgent) {
316
247
  return undefined;
317
248
  }
318
249
  return (
319
250
  <div className="theia-alert theia-info-alert theia-WelcomeMessage-Alert">
320
251
  <div className="theia-message-header">
321
252
  <span className={codicon('info')}></span>
322
- <span>{nls.localize('theia/ai/ide/toolConfirmationInfo/header', 'Tool confirmation')}</span>
253
+ <span>{nls.localize('theia/ai/ide/noDefaultAgent/header', 'No default agent')}</span>
323
254
  </div>
324
255
  <div className="theia-message-content">
325
256
  <LocalizedMarkdown
326
- localizationKey="theia/ai/ide/toolConfirmationInfo"
327
- defaultMarkdown={
328
- 'AI agents may want to use tools to act on your workspace. ' +
329
- 'By default each tool call needs your confirmation. ' +
330
- 'You can change this default or pre-approve individual tools in the [Tools configuration view]({0}).'
331
- }
332
- args={[`command:${OPEN_AI_CONFIG_VIEW_TOOLS.id}`]}
257
+ localizationKey="theia/ai/ide/noDefaultAgent"
258
+ defaultMarkdown={'Address an agent with *@AgentName*, or [choose the agent]({0}) that answers when you do not name one.'}
259
+ args={[`command:${OPEN_AI_CONFIG_VIEW.id}?${DEFAULT_CHAT_AGENT_PREF}`]}
333
260
  markdownRenderer={this.markdownRenderer}
334
- markdownOptions={{ isTrusted: { enabledCommands: [OPEN_AI_CONFIG_VIEW_TOOLS.id] } }}
261
+ markdownOptions={{ isTrusted: { enabledCommands: [OPEN_AI_CONFIG_VIEW.id] } }}
335
262
  />
336
263
  </div>
337
264
  </div>
338
265
  );
339
266
  }
340
267
 
268
+ /**
269
+ * The entry point into the walkthrough, shown while it is unfinished.
270
+ */
271
+ protected renderWalkthroughAction(): React.ReactNode {
272
+ if (!this.hasPendingWalkthroughSteps) {
273
+ return undefined;
274
+ }
275
+ return <div className="theia-WelcomeMessage-Actions">
276
+ <button
277
+ className="theia-button secondary"
278
+ onClick={this.openWalkthrough}>
279
+ {AI_OPEN_GETTING_STARTED_WALKTHROUGH.label}
280
+ </button>
281
+ </div>;
282
+ }
283
+
341
284
  protected renderModelConfigurationScreen(): React.ReactNode {
342
285
  const config = this.modelConfig ?? { hasModels: false, errorMessages: [] };
343
286
  const { hasModels, errorMessages } = config;
@@ -383,20 +326,16 @@ This typically happens in custom IDE distributions where Theia AI language model
383
326
  defaultMarkdown={`
384
327
  ## Configure a Language Model
385
328
 
386
- Set up an API key for [OpenAI]({0}), [Anthropic]({1}), or [GoogleAI]({2}) or configure another provider like Ollama in the settings.
329
+ Set up an API key for a provider like OpenAI, Anthropic or GoogleAI, or connect a local one such as Ollama.
387
330
 
388
- Some agents (e.g. Claude Code) work without a provider. [Learn more](https://theia-ide.org/docs/user_ai/).
331
+ New here? [Get started with AI]({0}) walks you through the setup.
389
332
  `}
390
- args={[
391
- `command:${OPEN_AI_CONFIG_VIEW.id}?ai-features.openAiOfficial.openAiApiKey`,
392
- `command:${OPEN_AI_CONFIG_VIEW.id}?ai-features.anthropic.AnthropicApiKey`,
393
- `command:${OPEN_AI_CONFIG_VIEW.id}?ai-features.google.apiKey`
394
- ]}
333
+ args={[`command:${AI_OPEN_GETTING_STARTED_WALKTHROUGH.id}`]}
395
334
  markdownRenderer={this.markdownRenderer}
396
335
  className="theia-WelcomeMessage-Content"
397
336
  markdownOptions={{
398
337
  supportHtml: true,
399
- isTrusted: { enabledCommands: [OPEN_AI_CONFIG_VIEW.id] }
338
+ isTrusted: { enabledCommands: [AI_OPEN_GETTING_STARTED_WALKTHROUGH.id] }
400
339
  }}
401
340
  />
402
341
  {errorMessages.length > 0 && (
@@ -415,7 +354,7 @@ Some agents (e.g. Claude Code) work without a provider. [Learn more](https://the
415
354
  <div className="theia-WelcomeMessage-Actions">
416
355
  <button
417
356
  className="theia-button main"
418
- onClick={() => this.commandRegistry.executeCommand(OPEN_AI_CONFIG_VIEW.id)}>
357
+ onClick={this.openAiConfiguration}>
419
358
  {nls.localize('theia/ai/ide/openAiConfiguration', 'Open AI Configuration')}
420
359
  </button>
421
360
  <button
@@ -427,62 +366,6 @@ Some agents (e.g. Claude Code) work without a provider. [Learn more](https://the
427
366
  </div>;
428
367
  }
429
368
 
430
- protected renderAgentSelectionScreen(): React.ReactNode {
431
- const recommendedAgents = this.recommendationService.getRecommendedAgents()
432
- .filter(agent => this.chatAgentService.getAgent(agent.id) !== undefined);
433
-
434
- return <div className={'theia-WelcomeMessage theia-WelcomeMessage-Main theia-WelcomeMessage-AgentSelection'} key="agent-selection">
435
- <TheiaIdeAiLogo className="theia-WelcomeMessage-Logo" />
436
- <LocalizedMarkdown
437
- localizationKey="theia/ai/ide/selectDefaultAgent"
438
- defaultMarkdown={`
439
- ## Select a Default Chat Agent
440
-
441
- Choose the agent to use by default. You can always override this by mentioning *@AgentName* in your message.
442
- `}
443
- markdownRenderer={this.markdownRenderer}
444
- className="theia-WelcomeMessage-Content"
445
- />
446
- {recommendedAgents.length > 0 ? (
447
- <div className="theia-WelcomeMessage-AgentButtons">
448
- {recommendedAgents.map(agent => (
449
- <button
450
- key={agent.id}
451
- className="theia-WelcomeMessage-AgentButton"
452
- onClick={() => this.setDefaultAgent(agent.id)}
453
- title={agent.description}>
454
- <span className={`theia-WelcomeMessage-AgentButton-Icon ${codicon('mention')}`}></span>
455
- <span className="theia-WelcomeMessage-AgentButton-Label">{agent.label}</span>
456
- </button>
457
- ))}
458
- </div>
459
- ) : (
460
- <p className="theia-WelcomeMessage-SubNote">
461
- {nls.localize('theia/ai/ide/noRecommendedAgents', 'No recommended agents are available.')}
462
- </p>
463
- )}
464
- <div className="theia-alert theia-info-alert theia-WelcomeMessage-Alert">
465
- <div className="theia-message-header">
466
- <span className={codicon('info')}></span>
467
- <span>
468
- {recommendedAgents.length > 0
469
- ? nls.localize('theia/ai/ide/moreAgentsAvailable/header', 'More agents are available')
470
- : nls.localize('theia/ai/ide/configureAgent/header', 'Configure a default agent')}
471
- </span>
472
- </div>
473
- <div className="theia-message-content">
474
- <LocalizedMarkdown
475
- localizationKey="theia/ai/ide/moreAgentsAvailable"
476
- defaultMarkdown='Use @AgentName to try others or configure a different default in [preferences]({0}).'
477
- args={[`command:${OPEN_AI_CONFIG_VIEW.id}?ai-features.chat.defaultChatAgent`]}
478
- markdownRenderer={this.markdownRenderer}
479
- markdownOptions={{ isTrusted: { enabledCommands: [OPEN_AI_CONFIG_VIEW.id] } }}
480
- />
481
- </div>
482
- </div>
483
- </div>;
484
- }
485
-
486
369
  renderDisabledMessage(): React.ReactNode {
487
370
  if (this.activationService.isActive && !this.activationService.canRun) {
488
371
  return this.renderTrustRestrictedMessage();
@@ -521,8 +404,6 @@ Choose the agent to use by default. You can always override this by mentioning *
521
404
  }
522
405
 
523
406
  protected renderPreferenceDisabledMessage(): React.ReactNode {
524
- const openAiHistory = 'aiHistory:open';
525
-
526
407
  return <div className={'theia-WelcomeMessage theia-WelcomeMessage-Main theia-WelcomeMessage-Disabled'} key="disabled-message">
527
408
  <TheiaIdeAiLogo className="theia-WelcomeMessage-Logo" />
528
409
  <div className="theia-WelcomeMessage-Content">
@@ -536,44 +417,26 @@ Choose the agent to use by default. You can always override this by mentioning *
536
417
  <div className="theia-message-content">
537
418
  <LocalizedMarkdown
538
419
  localizationKey="theia/ai/ide/chatDisabledMessage/steps"
539
- defaultMarkdown={`1. Enable AI features in the settings
540
- 2. Configure at least one LLM provider (e.g. OpenAI, Anthropic, GoogleAI or Ollama)
541
- 3. Start chatting with powerful AI agents`}
420
+ defaultMarkdown={'Turn the AI features on, connect a language model and pick an agent. '
421
+ + '[Get started with AI]({0}) takes you through it step by step.'}
422
+ args={[`command:${AI_OPEN_GETTING_STARTED_WALKTHROUGH.id}`]}
542
423
  markdownRenderer={this.markdownRenderer}
424
+ markdownOptions={{ isTrusted: { enabledCommands: [AI_OPEN_GETTING_STARTED_WALKTHROUGH.id] } }}
543
425
  />
544
426
  </div>
545
427
  </div>
546
428
  <div className="theia-WelcomeMessage-Actions">
547
429
  <button
548
430
  className="theia-button main"
549
- onClick={() => this.commandRegistry.executeCommand(OPEN_AI_CONFIG_VIEW.id)}>
431
+ onClick={this.openAiConfiguration}>
550
432
  {nls.localize('theia/ai/ide/openAiConfiguration', 'Open AI Configuration')}
551
433
  </button>
434
+ <button
435
+ className="theia-button secondary"
436
+ onClick={this.openWalkthrough}>
437
+ {AI_OPEN_GETTING_STARTED_WALKTHROUGH.label}
438
+ </button>
552
439
  </div>
553
- <LocalizedMarkdown
554
- localizationKey="theia/ai/ide/chatDisabledMessage/features"
555
- defaultMarkdown={`This will activate the AI features in the app.
556
-
557
- Please support us by [providing feedback](https://github.com/eclipse-theia/theia)!
558
-
559
- Once the AI features are enabled, you can access the following views and features:
560
- - Code Completion
561
- - Terminal Assistance (via CTRL+I in a terminal)
562
- - This Chat View - available agents include:
563
- - Coder Chat Agent
564
- - Architect Chat Agent
565
- - Universal Chat Agent
566
- - [AI History View]({0})
567
- - [AI Configuration View]({1})
568
-
569
- See [the documentation](https://theia-ide.org/docs/user_ai/) for more information.`}
570
- args={[`command:${openAiHistory}`, `command:${OPEN_AI_CONFIG_VIEW.id}`]}
571
- markdownRenderer={this.markdownRenderer}
572
- className="theia-WelcomeMessage-Content"
573
- markdownOptions={{
574
- isTrusted: { enabledCommands: [openAiHistory, OPEN_AI_CONFIG_VIEW.id] }
575
- }}
576
- />
577
440
  </div>;
578
441
  }
579
442
  }
@@ -99,7 +99,7 @@ Completeness is critical. Every review comment and every changed file must be in
99
99
  }
100
100
 
101
101
  protected buildLocalCheckoutTemplate(): string {
102
- const name = nls.localize('theia/ai/ide/prReview/capability/localCheckout/name', 'Checkout');
102
+ const name = nls.localizeByDefault('Checkout');
103
103
  const description = nls.localize('theia/ai/ide/prReview/capability/localCheckout/description',
104
104
  'Checks out the pull request locally and protects existing worktree changes.');
105
105
 
@@ -0,0 +1,64 @@
1
+ /********************************************************************************
2
+ * Copyright (C) 2026 EclipseSource GmbH.
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
+ .theia-ai-commit-message-input-wrapper {
18
+ position: relative;
19
+ }
20
+
21
+ /* Reserve space on the right of the SCM input so user text does not run under the icon.
22
+ Selecting by descendant `textarea` instead of `#theia-scm-input-message` decouples this
23
+ rule from the SCM widget's element id (`ScmCommitWidget.Styles.INPUT_MESSAGE`), which
24
+ would otherwise silently break this layout if it ever gets renamed upstream. */
25
+ .theia-ai-commit-message-input-wrapper textarea {
26
+ padding-right: 30px;
27
+ }
28
+
29
+ .theia-ai-commit-message-overlay {
30
+ position: absolute;
31
+ top: 4px;
32
+ right: 6px;
33
+ display: inline-flex;
34
+ pointer-events: auto;
35
+ /* Stay above the textarea so the button remains clickable. */
36
+ z-index: 1;
37
+ }
38
+
39
+ .theia-ai-commit-message-icon {
40
+ background: transparent;
41
+ border: none;
42
+ cursor: pointer;
43
+ padding: 2px;
44
+ color: var(--theia-icon-foreground);
45
+ opacity: 0.7;
46
+ display: inline-flex;
47
+ align-items: center;
48
+ justify-content: center;
49
+ border-radius: 3px;
50
+ }
51
+
52
+ .theia-ai-commit-message-icon:hover:not(:disabled) {
53
+ opacity: 1;
54
+ background-color: var(--theia-toolbar-hoverBackground);
55
+ }
56
+
57
+ .theia-ai-commit-message-icon:disabled {
58
+ opacity: 0.3;
59
+ cursor: default;
60
+ }
61
+
62
+ .theia-ai-commit-message-icon .codicon {
63
+ font-size: var(--theia-ui-font-size1);
64
+ }
@@ -23,6 +23,7 @@
23
23
 
24
24
  /* Import widget-specific styles */
25
25
  @import "./widgets/model-aliases-configuration.css";
26
+ @import "./commit-message-overlay.css";
26
27
 
27
28
  /* Override preferences grid layout for AI Configuration widgets */
28
29
  .ai-configuration-widget.theia-settings-container {
@@ -869,7 +870,7 @@ button.agent-chip:focus-visible {
869
870
  padding-top: calc(var(--theia-ui-padding) * 8);
870
871
  }
871
872
 
872
- /* Compact greeting used when the home view also shows recent sessions */
873
+ /* Compact greeting of a working chat: the onboarding itself lives in the getting started walkthrough */
873
874
  .theia-WelcomeMessage-Compact {
874
875
  padding-top: calc(var(--theia-ui-padding) * 2);
875
876
  }
@@ -1025,46 +1026,6 @@ button.agent-chip:focus-visible {
1025
1026
  margin-bottom: calc(var(--theia-ui-padding) * 0.25);
1026
1027
  }
1027
1028
 
1028
- .theia-WelcomeMessage-AgentButtons {
1029
- display: flex;
1030
- flex-direction: column;
1031
- gap: var(--theia-ui-padding);
1032
- margin: calc(var(--theia-ui-padding) * 2) 0;
1033
- }
1034
-
1035
- .theia-WelcomeMessage-AgentButton {
1036
- display: inline-flex;
1037
- align-items: center;
1038
- justify-content: center;
1039
- gap: calc(var(--theia-ui-padding) * 0.5);
1040
- padding: calc(var(--theia-ui-padding) * 0.75) calc(var(--theia-ui-padding) * 1.5);
1041
- background-color: var(--theia-button-background);
1042
- color: var(--theia-button-foreground);
1043
- border: 1px solid var(--theia-button-border);
1044
- border-radius: 4px;
1045
- cursor: pointer;
1046
- font-size: var(--theia-ui-font-size1);
1047
- transition: background-color 0.15s;
1048
- }
1049
-
1050
- .theia-WelcomeMessage-AgentButton:hover {
1051
- background-color: var(--theia-button-hoverBackground);
1052
- }
1053
-
1054
- .theia-WelcomeMessage-AgentButton-Icon {
1055
- font-size: var(--theia-ui-font-size1);
1056
- }
1057
-
1058
- .theia-WelcomeMessage-AgentButton-Label {
1059
- font-weight: 500;
1060
- }
1061
-
1062
- .theia-WelcomeMessage-SubNote {
1063
- font-size: var(--theia-ui-font-size1);
1064
- color: var(--theia-descriptionForeground);
1065
- margin-top: calc(var(--theia-ui-padding) * 2);
1066
- }
1067
-
1068
1029
  .theia-WelcomeMessage-Alert {
1069
1030
  max-width: 350px;
1070
1031
  margin-top: calc(var(--theia-ui-padding) * 3);
@@ -2231,7 +2192,8 @@ button.agent-chip:focus-visible {
2231
2192
  margin: 0;
2232
2193
  padding: 4px 0;
2233
2194
  min-width: 180px;
2234
- max-height: 320px;
2195
+ max-height: 200px;
2196
+ box-sizing: border-box;
2235
2197
  overflow-y: auto;
2236
2198
  }
2237
2199