@theia/ai-ide 1.74.0-next.8 → 1.74.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 (96) hide show
  1. package/lib/browser/ai-allow-all-mode-chat-banner.d.ts +68 -0
  2. package/lib/browser/ai-allow-all-mode-chat-banner.d.ts.map +1 -0
  3. package/lib/browser/ai-allow-all-mode-chat-banner.js +184 -0
  4. package/lib/browser/ai-allow-all-mode-chat-banner.js.map +1 -0
  5. package/lib/browser/ai-allow-all-mode-chat-banner.spec.d.ts +2 -0
  6. package/lib/browser/ai-allow-all-mode-chat-banner.spec.d.ts.map +1 -0
  7. package/lib/browser/ai-allow-all-mode-chat-banner.spec.js +170 -0
  8. package/lib/browser/ai-allow-all-mode-chat-banner.spec.js.map +1 -0
  9. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +3 -4
  10. package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +1 -1
  11. package/lib/browser/ai-configuration/tools-configuration-widget.js +17 -10
  12. package/lib/browser/ai-configuration/tools-configuration-widget.js.map +1 -1
  13. package/lib/browser/ai-first-perspective-contribution.d.ts +6 -0
  14. package/lib/browser/ai-first-perspective-contribution.d.ts.map +1 -0
  15. package/lib/browser/ai-first-perspective-contribution.js +50 -0
  16. package/lib/browser/ai-first-perspective-contribution.js.map +1 -0
  17. package/lib/browser/ai-sessions-view-contribution.d.ts +13 -0
  18. package/lib/browser/ai-sessions-view-contribution.d.ts.map +1 -0
  19. package/lib/browser/ai-sessions-view-contribution.js +69 -0
  20. package/lib/browser/ai-sessions-view-contribution.js.map +1 -0
  21. package/lib/browser/ai-sessions-widget.d.ts +27 -0
  22. package/lib/browser/ai-sessions-widget.d.ts.map +1 -0
  23. package/lib/browser/ai-sessions-widget.js +131 -0
  24. package/lib/browser/ai-sessions-widget.js.map +1 -0
  25. package/lib/browser/chat-session-item-action-contribution.js +2 -2
  26. package/lib/browser/chat-session-item-action-contribution.js.map +1 -1
  27. package/lib/browser/chat-session-item.d.ts +15 -0
  28. package/lib/browser/chat-session-item.d.ts.map +1 -1
  29. package/lib/browser/chat-session-item.js +39 -18
  30. package/lib/browser/chat-session-item.js.map +1 -1
  31. package/lib/browser/chat-session-list-components.d.ts +38 -0
  32. package/lib/browser/chat-session-list-components.d.ts.map +1 -0
  33. package/lib/browser/chat-session-list-components.js +87 -0
  34. package/lib/browser/chat-session-list-components.js.map +1 -0
  35. package/lib/browser/chat-session-list-service.d.ts +34 -0
  36. package/lib/browser/chat-session-list-service.d.ts.map +1 -0
  37. package/lib/browser/chat-session-list-service.js +251 -0
  38. package/lib/browser/chat-session-list-service.js.map +1 -0
  39. package/lib/browser/chat-session-list-service.spec.d.ts +2 -0
  40. package/lib/browser/chat-session-list-service.spec.d.ts.map +1 -0
  41. package/lib/browser/{chat-sessions-welcome-message-provider.spec.js → chat-session-list-service.spec.js} +133 -39
  42. package/lib/browser/chat-session-list-service.spec.js.map +1 -0
  43. package/lib/browser/chat-session-tooltip.d.ts +2 -2
  44. package/lib/browser/chat-session-tooltip.d.ts.map +1 -1
  45. package/lib/browser/chat-session-tooltip.js +33 -10
  46. package/lib/browser/chat-session-tooltip.js.map +1 -1
  47. package/lib/browser/chat-sessions-welcome-message-provider.d.ts +9 -35
  48. package/lib/browser/chat-sessions-welcome-message-provider.d.ts.map +1 -1
  49. package/lib/browser/chat-sessions-welcome-message-provider.js +51 -205
  50. package/lib/browser/chat-sessions-welcome-message-provider.js.map +1 -1
  51. package/lib/browser/context-file-validation-service-impl.spec.js +2 -2
  52. package/lib/browser/context-file-validation-service-impl.spec.js.map +1 -1
  53. package/lib/browser/frontend-module.d.ts.map +1 -1
  54. package/lib/browser/frontend-module.js +20 -0
  55. package/lib/browser/frontend-module.js.map +1 -1
  56. package/lib/browser/workspace-functions.d.ts +5 -6
  57. package/lib/browser/workspace-functions.d.ts.map +1 -1
  58. package/lib/browser/workspace-functions.js +24 -9
  59. package/lib/browser/workspace-functions.js.map +1 -1
  60. package/lib/browser/workspace-functions.spec.js +29 -29
  61. package/lib/browser/workspace-functions.spec.js.map +1 -1
  62. package/lib/browser/workspace-launch-provider.spec.js +3 -3
  63. package/lib/browser/workspace-launch-provider.spec.js.map +1 -1
  64. package/lib/browser/workspace-search-provider.d.ts.map +1 -1
  65. package/lib/browser/workspace-search-provider.js +28 -20
  66. package/lib/browser/workspace-search-provider.js.map +1 -1
  67. package/lib/browser/workspace-search-provider.spec.js +68 -0
  68. package/lib/browser/workspace-search-provider.spec.js.map +1 -1
  69. package/lib/browser/workspace-task-provider.spec.js +4 -4
  70. package/lib/browser/workspace-task-provider.spec.js.map +1 -1
  71. package/package.json +25 -25
  72. package/src/browser/ai-allow-all-mode-chat-banner.spec.ts +205 -0
  73. package/src/browser/ai-allow-all-mode-chat-banner.tsx +217 -0
  74. package/src/browser/ai-configuration/tools-configuration-widget.tsx +20 -13
  75. package/src/browser/ai-first-perspective-contribution.ts +48 -0
  76. package/src/browser/ai-sessions-view-contribution.ts +67 -0
  77. package/src/browser/ai-sessions-widget.tsx +151 -0
  78. package/src/browser/chat-session-item-action-contribution.ts +2 -2
  79. package/src/browser/chat-session-item.tsx +82 -27
  80. package/src/browser/chat-session-list-components.tsx +136 -0
  81. package/src/browser/{chat-sessions-welcome-message-provider.spec.ts → chat-session-list-service.spec.ts} +136 -30
  82. package/src/browser/chat-session-list-service.ts +261 -0
  83. package/src/browser/chat-session-tooltip.ts +31 -11
  84. package/src/browser/chat-sessions-welcome-message-provider.tsx +78 -268
  85. package/src/browser/context-file-validation-service-impl.spec.ts +3 -3
  86. package/src/browser/frontend-module.ts +23 -0
  87. package/src/browser/style/index.css +150 -3
  88. package/src/browser/workspace-functions.spec.ts +36 -37
  89. package/src/browser/workspace-functions.ts +8 -9
  90. package/src/browser/workspace-launch-provider.spec.ts +5 -5
  91. package/src/browser/workspace-search-provider.spec.ts +101 -0
  92. package/src/browser/workspace-search-provider.ts +34 -23
  93. package/src/browser/workspace-task-provider.spec.ts +6 -7
  94. package/lib/browser/chat-sessions-welcome-message-provider.spec.d.ts +0 -2
  95. package/lib/browser/chat-sessions-welcome-message-provider.spec.d.ts.map +0 -1
  96. package/lib/browser/chat-sessions-welcome-message-provider.spec.js.map +0 -1
@@ -0,0 +1,261 @@
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
+ import { ChatService, ChatSession, ChatSessionMetadata, ChatSessionStatus } from '@theia/ai-chat';
18
+ import { PERSISTED_SESSION_LIMIT_PREF, SESSION_STORAGE_PREF } from '@theia/ai-chat/lib/common/ai-chat-preferences';
19
+ import { ChatViewWidget } from '@theia/ai-chat-ui/lib/browser/chat-view-widget';
20
+ import { DisposableCollection, Emitter, Event, PreferenceService } from '@theia/core';
21
+ import { ApplicationShell } from '@theia/core/lib/browser';
22
+ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
23
+ import { UnreadStateProvider } from './chat-session-item';
24
+ import { SectionedSessions, SessionRow, parentIdOf } from './chat-session-list-components';
25
+
26
+ @injectable()
27
+ export class ChatSessionListService implements UnreadStateProvider {
28
+
29
+ @inject(ChatService)
30
+ protected readonly chatService: ChatService;
31
+
32
+ @inject(PreferenceService)
33
+ protected readonly preferenceService: PreferenceService;
34
+
35
+ @inject(ApplicationShell)
36
+ protected readonly shell: ApplicationShell;
37
+
38
+ private readonly unreadSessions = new Map<string, {
39
+ unread: boolean;
40
+ requiresAction: boolean;
41
+ seenRequests: number;
42
+ seenCompleted: number;
43
+ listener: DisposableCollection;
44
+ }>();
45
+ private readonly onUnreadChangedEmitter = new Emitter<string>();
46
+ readonly onUnreadChanged: Event<string> = this.onUnreadChangedEmitter.event;
47
+
48
+ protected _persistedSessions: ChatSessionMetadata[] = [];
49
+
50
+ /** Expanded root session IDs (default collapsed). */
51
+ protected expandedRoots = new Set<string>();
52
+
53
+ protected readonly onStateChangedEmitter = new Emitter<void>();
54
+ readonly onStateChanged: Event<void> = this.onStateChangedEmitter.event;
55
+
56
+ @postConstruct()
57
+ protected init(): void {
58
+ for (const session of this.chatService.getSessions()) {
59
+ this.watchSession(session);
60
+ }
61
+
62
+ this.chatService.onSessionEvent(event => {
63
+ if (event.type === 'created') {
64
+ const s = this.chatService.getSession(event.sessionId);
65
+ if (s) {
66
+ this.watchSession(s);
67
+ }
68
+ } else if (event.type === 'activeChange' && event.sessionId) {
69
+ this.markSessionRead(event.sessionId);
70
+ } else if (event.type === 'deleted') {
71
+ this.unwatchSession(event.sessionId);
72
+ }
73
+ this.loadSessions();
74
+ });
75
+
76
+ this.loadSessions();
77
+ this.preferenceService.onPreferenceChanged(e => {
78
+ if (e.preferenceName === PERSISTED_SESSION_LIMIT_PREF || e.preferenceName === SESSION_STORAGE_PREF) {
79
+ this.loadSessions();
80
+ }
81
+ });
82
+ }
83
+
84
+ isUnread(sessionId: string): boolean {
85
+ return this.unreadSessions.get(sessionId)?.unread === true;
86
+ }
87
+
88
+ protected watchSession(session: ChatSession): void {
89
+ if (this.unreadSessions.has(session.id)) {
90
+ return;
91
+ }
92
+ const reqs = session.model.getRequests();
93
+ const state = {
94
+ unread: false,
95
+ requiresAction: ChatSessionStatus.requiresUserAction(session.model.status),
96
+ seenRequests: reqs.length,
97
+ seenCompleted: this.countCompleted(reqs),
98
+ listener: new DisposableCollection()
99
+ };
100
+ this.unreadSessions.set(session.id, state);
101
+
102
+ session.model.onDidChange(() => {
103
+ const requiresAction = ChatSessionStatus.requiresUserAction(session.model.status);
104
+ if (requiresAction !== state.requiresAction) {
105
+ state.requiresAction = requiresAction;
106
+ if (requiresAction) {
107
+ this.expandAncestors(session);
108
+ }
109
+ this.onStateChangedEmitter.fire();
110
+ }
111
+ const current = session.model.getRequests();
112
+ if (current.length > state.seenRequests || this.countCompleted(current) > state.seenCompleted) {
113
+ const activeSession = this.chatService.getActiveSession();
114
+ const chatViewFocused = ChatViewWidget.findActive(this.shell) !== undefined;
115
+ if (chatViewFocused && activeSession && activeSession.id === session.id) {
116
+ state.seenRequests = current.length;
117
+ state.seenCompleted = this.countCompleted(current);
118
+ } else if (!state.unread) {
119
+ state.unread = true;
120
+ this.onUnreadChangedEmitter.fire(session.id);
121
+ }
122
+ }
123
+ }, undefined, state.listener);
124
+ }
125
+
126
+ protected markSessionRead(sessionId: string): void {
127
+ const state = this.unreadSessions.get(sessionId);
128
+ if (!state) {
129
+ return;
130
+ }
131
+ const session = this.chatService.getSession(sessionId);
132
+ const reqs = session?.model.getRequests() ?? [];
133
+ state.seenRequests = reqs.length;
134
+ state.seenCompleted = this.countCompleted(reqs);
135
+ if (state.unread) {
136
+ state.unread = false;
137
+ this.onUnreadChangedEmitter.fire(sessionId);
138
+ }
139
+ }
140
+
141
+ protected unwatchSession(sessionId: string): void {
142
+ const state = this.unreadSessions.get(sessionId);
143
+ if (state) {
144
+ state.listener.dispose();
145
+ this.unreadSessions.delete(sessionId);
146
+ }
147
+ }
148
+
149
+ private countCompleted(reqs: ReturnType<ChatSession['model']['getRequests']>): number {
150
+ return reqs.filter(r => r.response.isComplete).length;
151
+ }
152
+
153
+ isPersistenceEnabled(): boolean {
154
+ const limit = this.preferenceService.get<number>(PERSISTED_SESSION_LIMIT_PREF, 25);
155
+ return limit !== 0;
156
+ }
157
+
158
+ protected async loadSessions(): Promise<void> {
159
+ if (!this.isPersistenceEnabled()) {
160
+ this._persistedSessions = [];
161
+ this.onStateChangedEmitter.fire();
162
+ return;
163
+ }
164
+
165
+ const hasSessions = await this.chatService.hasPersistedSessions();
166
+ if (!hasSessions) {
167
+ this._persistedSessions = [];
168
+ this.onStateChangedEmitter.fire();
169
+ return;
170
+ }
171
+
172
+ try {
173
+ const index = await this.chatService.getPersistedSessions();
174
+ this._persistedSessions = Object.values(index)
175
+ .toSorted((a, b) => b.saveDate - a.saveDate);
176
+ } catch (error) {
177
+ console.error('Failed to load persisted sessions:', error);
178
+ this._persistedSessions = [];
179
+ } finally {
180
+ this.onStateChangedEmitter.fire();
181
+ }
182
+ }
183
+
184
+ getSections(): SectionedSessions {
185
+ const activeRaw = this.chatService.getSessions().filter(s => !!s.title);
186
+ const activeIds = new Set(activeRaw.map(s => s.id));
187
+ const active: ChatSessionMetadata[] = activeRaw
188
+ .toSorted((a, b) => (b.lastInteraction?.getTime() ?? 0) - (a.lastInteraction?.getTime() ?? 0))
189
+ .map(session => ({
190
+ sessionId: session.id,
191
+ title: session.title!,
192
+ saveDate: session.lastInteraction?.getTime() ?? Date.now(),
193
+ location: session.model.location,
194
+ pinnedAgentId: session.pinnedAgent?.id,
195
+ hasError: session.model.status === 'failed',
196
+ rootSessionId: session.rootSessionId,
197
+ parentSessionId: session.parentSessionId
198
+ }));
199
+ const restored = this._persistedSessions.filter(metadata => !activeIds.has(metadata.sessionId));
200
+ return { active, restored };
201
+ }
202
+
203
+ toggleExpand(sessionId: string): void {
204
+ this.expandedRoots = new Set(this.expandedRoots);
205
+ if (this.expandedRoots.has(sessionId)) {
206
+ this.expandedRoots.delete(sessionId);
207
+ } else {
208
+ this.expandedRoots.add(sessionId);
209
+ }
210
+ this.onStateChangedEmitter.fire();
211
+ }
212
+
213
+ isExpanded(sessionId: string): boolean {
214
+ return this.expandedRoots.has(sessionId);
215
+ }
216
+
217
+ sessionRequiresAction(sessionId: string): boolean {
218
+ const session = this.chatService.getSession(sessionId);
219
+ return session !== undefined && ChatSessionStatus.requiresUserAction(session.model.status);
220
+ }
221
+
222
+ descendantRequiresAction(row: SessionRow): boolean {
223
+ return row.childSessions.some(child =>
224
+ this.sessionRequiresAction(child.session.sessionId) || this.descendantRequiresAction(child));
225
+ }
226
+
227
+ protected expandAncestors(session: ChatSession): void {
228
+ const persistedById = new Map(this._persistedSessions.map(metadata => [metadata.sessionId, metadata]));
229
+ const parentIdFor = (id: string): string | undefined => {
230
+ const loaded = this.chatService.getSession(id);
231
+ if (loaded) {
232
+ return loaded.parentSessionId ?? loaded.rootSessionId;
233
+ }
234
+ const metadata = persistedById.get(id);
235
+ return metadata && parentIdOf(metadata);
236
+ };
237
+ const visited = new Set<string>();
238
+ let parentId = session.parentSessionId ?? session.rootSessionId;
239
+ while (parentId && !visited.has(parentId)) {
240
+ visited.add(parentId);
241
+ this.expandedRoots.add(parentId);
242
+ parentId = parentIdFor(parentId);
243
+ }
244
+ }
245
+
246
+ buildRows(sections: SectionedSessions): SessionRow[] {
247
+ const allSessions = [...sections.active, ...sections.restored];
248
+ const activeIds = new Set(sections.active.map(s => s.sessionId));
249
+ const rowsById = new Map<string, SessionRow>();
250
+ for (const session of allSessions) {
251
+ rowsById.set(session.sessionId, { session, isRestored: !activeIds.has(session.sessionId), childSessions: [] });
252
+ }
253
+ for (const session of allSessions) {
254
+ const pid = parentIdOf(session);
255
+ if (pid) {
256
+ rowsById.get(pid)?.childSessions.push(rowsById.get(session.sessionId)!);
257
+ }
258
+ }
259
+ return [...rowsById.values()];
260
+ }
261
+ }
@@ -16,7 +16,7 @@
16
16
 
17
17
  import {
18
18
  ChatAgentService, ChatRequestModel, ChatResponseContent, ChatSession, ChatSessionMetadata,
19
- ErrorChatResponseContent, FormattedProviderError, formatProviderError, ThinkingChatResponseContent
19
+ ChatSessionStatus, ErrorChatResponseContent, FormattedProviderError, formatProviderError, ThinkingChatResponseContent
20
20
  } from '@theia/ai-chat';
21
21
  import { MarkdownRenderer } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
22
22
  import { nls } from '@theia/core/lib/common/nls';
@@ -89,27 +89,41 @@ function addDefinitionEntry(definitionList: HTMLDListElement, term: string, deta
89
89
  export function buildSessionTooltip(
90
90
  session: ChatSession, metadata: ChatSessionMetadata,
91
91
  agentService: ChatAgentService, markdownRenderer: MarkdownRenderer,
92
- isUnread: boolean, isRunning: boolean, hasError: boolean, isWaitingForInput: boolean
92
+ isUnread: boolean, descendantNeedsAttention: boolean = false
93
93
  ): SessionTooltip {
94
94
  const toDispose = new DisposableCollection();
95
95
  const requests = session.model.getRequests();
96
96
  const lastRequest = requests.at(-1);
97
+ const status = session.model.status;
97
98
 
98
99
  const container = document.createElement('div');
99
100
  container.className = 'theia-chat-session-tooltip';
100
101
 
101
- // A session waiting for input is also "running", so check it first to give it precedence.
102
- if (isWaitingForInput) {
102
+ // Waiting on the user takes precedence over the generic running badge: it signals that the
103
+ // user, not the agent, needs to act.
104
+ if (status === 'awaitingApproval') {
105
+ const badge = document.createElement('div');
106
+ badge.className = 'theia-chat-session-badge-attention-tooltip';
107
+ badge.textContent = nls.localize('theia/ai/ide/requiresApproval', 'Requires your approval');
108
+ container.appendChild(badge);
109
+ } else if (status === 'awaitingInput') {
103
110
  const badge = document.createElement('div');
104
111
  badge.className = 'theia-chat-session-badge-attention-tooltip';
105
112
  badge.textContent = nls.localize('theia/ai/ide/waitingForInput', 'Waiting for your input');
106
113
  container.appendChild(badge);
107
- } else if (isRunning) {
114
+ } else if (descendantNeedsAttention) {
115
+ // The session itself is not awaiting the user, but one of its delegated children is;
116
+ // surface that instead of the generic running badge so the reason is clear.
117
+ const badge = document.createElement('div');
118
+ badge.className = 'theia-chat-session-badge-attention-tooltip';
119
+ badge.textContent = nls.localize('theia/ai/ide/childInteractionNeeded', 'A delegated session needs your attention');
120
+ container.appendChild(badge);
121
+ } else if (ChatSessionStatus.isInProgress(status)) {
108
122
  const badge = document.createElement('div');
109
123
  badge.className = 'theia-chat-session-badge-running-tooltip';
110
124
  badge.textContent = nls.localizeByDefault('Running');
111
125
  container.appendChild(badge);
112
- } else if (hasError) {
126
+ } else if (status === 'failed') {
113
127
  const badge = document.createElement('div');
114
128
  badge.className = 'theia-chat-session-badge-error-tooltip';
115
129
  badge.textContent = nls.localizeByDefault('Error');
@@ -123,7 +137,7 @@ export function buildSessionTooltip(
123
137
 
124
138
  if (lastRequest) {
125
139
  const lastResponse = lastRequest.response;
126
- const errorText = hasError ? getResponseErrorMessage(lastResponse) : undefined;
140
+ const errorText = status === 'failed' ? getResponseErrorMessage(lastResponse) : undefined;
127
141
 
128
142
  if (errorText) {
129
143
  const label = document.createElement('div');
@@ -175,7 +189,7 @@ export function buildSessionTooltip(
175
189
  const exchangeLabel = count === 1
176
190
  ? nls.localize('theia/ai/ide/tooltip/oneExchange', '1 exchange')
177
191
  : nls.localize('theia/ai/ide/tooltip/multipleExchanges', '{0} exchanges', count);
178
- addDefinitionEntry(definitionList, nls.localize('theia/ai/ide/tooltip/messages', 'Messages'), exchangeLabel);
192
+ addDefinitionEntry(definitionList, nls.localizeByDefault('Messages'), exchangeLabel);
179
193
 
180
194
  const date = session.lastInteraction ?? new Date(metadata.saveDate);
181
195
  addDefinitionEntry(definitionList, nls.localize('theia/ai/ide/tooltip/lastActivity', 'Last activity'), date.toLocaleString());
@@ -189,14 +203,20 @@ export function buildSessionTooltip(
189
203
  * shown on the home view). Avoids any restore I/O so hover does not promote the item to Active.
190
204
  */
191
205
  export function buildRestoredSessionTooltip(
192
- metadata: ChatSessionMetadata, agentService: ChatAgentService
206
+ metadata: ChatSessionMetadata, agentService: ChatAgentService, descendantNeedsAttention: boolean = false
193
207
  ): SessionTooltip {
194
208
  const container = document.createElement('div');
195
209
  container.className = 'theia-chat-session-tooltip';
196
210
 
197
211
  const badge = document.createElement('div');
198
- badge.className = 'theia-chat-session-badge-restored-tooltip';
199
- badge.textContent = nls.localize('theia/ai/ide/restoredSession', 'Restored session');
212
+ if (descendantNeedsAttention) {
213
+ // A persisted parent whose delegated child needs the user; show that rather than "Restored".
214
+ badge.className = 'theia-chat-session-badge-attention-tooltip';
215
+ badge.textContent = nls.localize('theia/ai/ide/childInteractionNeeded', 'A delegated session needs your attention');
216
+ } else {
217
+ badge.className = 'theia-chat-session-badge-restored-tooltip';
218
+ badge.textContent = nls.localize('theia/ai/ide/restoredSession', 'Restored session');
219
+ }
200
220
  container.appendChild(badge);
201
221
 
202
222
  const definitionList = document.createElement('dl');