@theia/ai-ide 1.72.1 → 1.72.3
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-configuration/ai-configuration-view-contribution.d.ts +1 -0
- package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-view-contribution.js +15 -2
- package/lib/browser/ai-configuration/ai-configuration-view-contribution.js.map +1 -1
- package/lib/browser/ai-configuration/tools-configuration-widget.d.ts +3 -0
- package/lib/browser/ai-configuration/tools-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/tools-configuration-widget.js +61 -4
- package/lib/browser/ai-configuration/tools-configuration-widget.js.map +1 -1
- package/lib/browser/ide-chat-welcome-message-provider.d.ts +11 -0
- package/lib/browser/ide-chat-welcome-message-provider.d.ts.map +1 -1
- package/lib/browser/ide-chat-welcome-message-provider.js +31 -1
- package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
- package/lib/browser/todo-tool-renderer.d.ts +7 -1
- package/lib/browser/todo-tool-renderer.d.ts.map +1 -1
- package/lib/browser/todo-tool-renderer.js +25 -1
- package/lib/browser/todo-tool-renderer.js.map +1 -1
- package/lib/browser/user-interaction-tool-renderer.d.ts +7 -1
- package/lib/browser/user-interaction-tool-renderer.d.ts.map +1 -1
- package/lib/browser/user-interaction-tool-renderer.js +25 -1
- package/lib/browser/user-interaction-tool-renderer.js.map +1 -1
- package/lib/browser/workspace-functions.d.ts +27 -3
- package/lib/browser/workspace-functions.d.ts.map +1 -1
- package/lib/browser/workspace-functions.js +123 -140
- package/lib/browser/workspace-functions.js.map +1 -1
- package/lib/browser/workspace-functions.spec.js +323 -24
- package/lib/browser/workspace-functions.spec.js.map +1 -1
- package/package.json +23 -22
- package/src/browser/ai-configuration/ai-configuration-view-contribution.ts +15 -1
- package/src/browser/ai-configuration/tools-configuration-widget.tsx +106 -17
- package/src/browser/ide-chat-welcome-message-provider.tsx +43 -1
- package/src/browser/style/index.css +16 -0
- package/src/browser/todo-tool-renderer.tsx +30 -3
- package/src/browser/user-interaction-tool-renderer.tsx +30 -3
- package/src/browser/workspace-functions.spec.ts +385 -25
- package/src/browser/workspace-functions.ts +128 -195
|
@@ -197,31 +197,120 @@ export class AIToolsConfigurationWidget extends AITableConfigurationWidget<ToolI
|
|
|
197
197
|
|
|
198
198
|
protected override renderHeader(): React.ReactNode {
|
|
199
199
|
return (
|
|
200
|
-
|
|
201
|
-
<div
|
|
202
|
-
{
|
|
200
|
+
<>
|
|
201
|
+
<div className="ai-tools-configuration-header">
|
|
202
|
+
<div style={{ fontWeight: 500 }}>
|
|
203
|
+
{nls.localize('theia/ai/ide/toolsConfiguration/default/label', 'Default Tool Confirmation Mode:')}
|
|
204
|
+
</div>
|
|
205
|
+
<select
|
|
206
|
+
className="theia-select"
|
|
207
|
+
value={this.defaultState}
|
|
208
|
+
onChange={this.handleDefaultStateChange}
|
|
209
|
+
>
|
|
210
|
+
{TOOL_OPTIONS.map(opt => (
|
|
211
|
+
<option key={opt.value} value={opt.value}>{opt.label}</option>
|
|
212
|
+
))}
|
|
213
|
+
</select>
|
|
214
|
+
<button
|
|
215
|
+
className='theia-button secondary ai-tools-reset-button'
|
|
216
|
+
style={{ marginLeft: 'auto' }}
|
|
217
|
+
title={nls.localize('theia/ai/ide/toolsConfiguration/resetAllTooltip', 'Reset all tools to default')}
|
|
218
|
+
onClick={() => this.resetAllToolsToDefault()}
|
|
219
|
+
>
|
|
220
|
+
{nls.localize('theia/ai/ide/toolsConfiguration/resetAll', 'Reset All')}
|
|
221
|
+
</button>
|
|
203
222
|
</div>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
223
|
+
{this.renderRecommendedDefaultsBanner()}
|
|
224
|
+
</>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
protected renderRecommendedDefaultsBanner(): React.ReactNode {
|
|
229
|
+
if (this.defaultState !== ToolConfirmationMode.CONFIRM) {
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
return (
|
|
233
|
+
<div className="ai-tools-recommended-defaults-banner">
|
|
234
|
+
<span className="ai-tools-recommended-defaults-text">
|
|
235
|
+
{nls.localize(
|
|
236
|
+
'theia/ai/ide/toolsConfiguration/recommendedDefaults/message',
|
|
237
|
+
'Tool calls currently require approval. Auto-allow all built-in tools at once.' +
|
|
238
|
+
' Tools that require extra confirmation (e.g. shell execution), MCP tools,' +
|
|
239
|
+
' and any tools added later will still ask before running.'
|
|
240
|
+
)}
|
|
241
|
+
</span>
|
|
213
242
|
<button
|
|
214
|
-
className='theia-button
|
|
215
|
-
|
|
216
|
-
title={nls.localize('theia/ai/ide/toolsConfiguration/resetAllTooltip', 'Reset all tools to default')}
|
|
217
|
-
onClick={() => this.resetAllToolsToDefault()}
|
|
243
|
+
className='theia-button main'
|
|
244
|
+
onClick={() => this.allowCurrentTools()}
|
|
218
245
|
>
|
|
219
|
-
{nls.localize('theia/ai/ide/toolsConfiguration/
|
|
246
|
+
{nls.localize('theia/ai/ide/toolsConfiguration/recommendedDefaults/apply', 'Allow Default Tools')}
|
|
220
247
|
</button>
|
|
221
248
|
</div>
|
|
222
249
|
);
|
|
223
250
|
}
|
|
224
251
|
|
|
252
|
+
protected async allowCurrentTools(): Promise<void> {
|
|
253
|
+
const dialog = new ConfirmDialog({
|
|
254
|
+
title: nls.localize('theia/ai/ide/toolsConfiguration/recommendedDefaults/dialogTitle', 'Allow Default Tools?'),
|
|
255
|
+
msg: this.buildAllowCurrentToolsMessage(),
|
|
256
|
+
ok: nls.localize('theia/ai/ide/toolsConfiguration/recommendedDefaults/dialogConfirm', 'I understand, allow'),
|
|
257
|
+
cancel: nls.localizeByDefault('Cancel')
|
|
258
|
+
});
|
|
259
|
+
const confirmed = await dialog.open();
|
|
260
|
+
if (!confirmed) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
// Leave the global default at CONFIRM so any tool added later still requires confirmation.
|
|
264
|
+
// Skip tools that require extra consent (confirmAlwaysAllow), MCP tools (third-party code
|
|
265
|
+
// that should require informed per-tool consent), and tools the user has explicitly disabled.
|
|
266
|
+
const updates: Array<{ toolId: string; mode: ToolConfirmationMode; toolRequest: ToolRequest }> = [];
|
|
267
|
+
for (const tool of this.toolInvocationRegistry.getAllFunctions()) {
|
|
268
|
+
if (tool.confirmAlwaysAllow) {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (tool.name.startsWith('mcp_')) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (this.toolConfirmationModes[tool.name] === ToolConfirmationMode.DISABLED) {
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
updates.push({ toolId: tool.name, mode: ToolConfirmationMode.ALWAYS_ALLOW, toolRequest: tool });
|
|
278
|
+
}
|
|
279
|
+
await this.confirmationManager.setConfirmationModes(updates);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
protected buildAllowCurrentToolsMessage(): HTMLElement {
|
|
283
|
+
const container = document.createElement('div');
|
|
284
|
+
const lines = [
|
|
285
|
+
nls.localize(
|
|
286
|
+
'theia/ai/ide/toolsConfiguration/recommendedDefaults/msg/line1',
|
|
287
|
+
'This sets all currently registered built-in tools to "Always Allow".'
|
|
288
|
+
),
|
|
289
|
+
nls.localize(
|
|
290
|
+
'theia/ai/ide/toolsConfiguration/recommendedDefaults/msg/line2',
|
|
291
|
+
'Tools that require extra confirmation (such as shell execution) will still ask before running.'
|
|
292
|
+
),
|
|
293
|
+
nls.localize(
|
|
294
|
+
'theia/ai/ide/toolsConfiguration/recommendedDefaults/msg/line3',
|
|
295
|
+
'MCP tools are third-party and are not included. You can allow them individually in this view.'
|
|
296
|
+
),
|
|
297
|
+
nls.localize(
|
|
298
|
+
'theia/ai/ide/toolsConfiguration/recommendedDefaults/msg/line4',
|
|
299
|
+
'Tools added later will still default to "Confirm" so you can review them.'
|
|
300
|
+
),
|
|
301
|
+
nls.localize(
|
|
302
|
+
'theia/ai/ide/toolsConfiguration/recommendedDefaults/msg/line5',
|
|
303
|
+
'You can change this later in this view.'
|
|
304
|
+
)
|
|
305
|
+
];
|
|
306
|
+
for (const line of lines) {
|
|
307
|
+
const p = document.createElement('p');
|
|
308
|
+
p.textContent = line;
|
|
309
|
+
container.appendChild(p);
|
|
310
|
+
}
|
|
311
|
+
return container;
|
|
312
|
+
}
|
|
313
|
+
|
|
225
314
|
protected getEffectiveState(toolName: string): ToolConfirmationMode {
|
|
226
315
|
// If there's an explicit setting for this tool, use it
|
|
227
316
|
const explicitSetting = this.toolConfirmationModes[toolName];
|
|
@@ -24,7 +24,9 @@ import { AgentService, FrontendLanguageModelRegistry } from '@theia/ai-core/lib/
|
|
|
24
24
|
import { PreferenceService } from '@theia/core/lib/common';
|
|
25
25
|
import { DEFAULT_CHAT_AGENT_PREF, BYPASS_MODEL_REQUIREMENT_PREF } from '@theia/ai-chat/lib/common/ai-chat-preferences';
|
|
26
26
|
import { ChatAgentRecommendationService, ChatAgentService } from '@theia/ai-chat/lib/common';
|
|
27
|
-
import {
|
|
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';
|
|
28
30
|
import { AIActivationService } from '@theia/ai-core/lib/browser';
|
|
29
31
|
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
|
30
32
|
import { WorkspaceCommands } from '@theia/workspace/lib/browser/workspace-commands';
|
|
@@ -83,6 +85,9 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
|
|
|
83
85
|
@inject(AgentService)
|
|
84
86
|
protected agentService: AgentService;
|
|
85
87
|
|
|
88
|
+
@inject(ToolConfirmationManager)
|
|
89
|
+
protected readonly toolConfirmationManager: ToolConfirmationManager;
|
|
90
|
+
|
|
86
91
|
@inject(AIActivationService)
|
|
87
92
|
protected readonly activationService: AIActivationService;
|
|
88
93
|
|
|
@@ -120,6 +125,9 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
|
|
|
120
125
|
this._modelRequirementBypassed = effectiveValue;
|
|
121
126
|
this.notifyStateChanged();
|
|
122
127
|
}
|
|
128
|
+
} else if (e.preferenceName === DEFAULT_TOOL_CONFIRMATION_PREFERENCE || e.preferenceName === TOOL_CONFIRMATION_PREFERENCE) {
|
|
129
|
+
// Re-render so the tool-confirmation explainer is hidden once the user configures confirmation behavior.
|
|
130
|
+
this.notifyStateChanged();
|
|
123
131
|
}
|
|
124
132
|
})
|
|
125
133
|
);
|
|
@@ -186,6 +194,19 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
|
|
|
186
194
|
return this._defaultAgent;
|
|
187
195
|
}
|
|
188
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Whether to show the tool-confirmation explainer on the welcome screen.
|
|
199
|
+
*
|
|
200
|
+
* Only shown while the user is still in the default state, i.e. every tool call is confirmed and
|
|
201
|
+
* no per-tool overrides exist. Once the user has changed the default mode (e.g. to always allow
|
|
202
|
+
* or to disable tools) or pre-approved individual tools (including via bulk approval), they are
|
|
203
|
+
* already aware of the mechanism, so the explainer is suppressed.
|
|
204
|
+
*/
|
|
205
|
+
protected get shouldShowToolConfirmationInfo(): boolean {
|
|
206
|
+
return this.toolConfirmationManager.getDefaultConfirmationMode() === ToolConfirmationMode.CONFIRM
|
|
207
|
+
&& Object.keys(this.toolConfirmationManager.getAllConfirmationSettings()).length === 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
189
210
|
protected setModelRequirementBypassed(bypassed: boolean): void {
|
|
190
211
|
this.preferenceService.set(BYPASS_MODEL_REQUIREMENT_PREF, bypassed, PreferenceScope.User);
|
|
191
212
|
}
|
|
@@ -227,6 +248,27 @@ Attach context with *#{3}*, *#{4}*, *#{5}*, or click {6}. [Learn more](https://t
|
|
|
227
248
|
className="theia-WelcomeMessage-Content"
|
|
228
249
|
markdownOptions={{ supportHtml: true }}
|
|
229
250
|
/>
|
|
251
|
+
{this.shouldShowToolConfirmationInfo && (
|
|
252
|
+
<div className="theia-alert theia-info-alert theia-WelcomeMessage-Alert">
|
|
253
|
+
<div className="theia-message-header">
|
|
254
|
+
<span className={codicon('info')}></span>
|
|
255
|
+
<span>{nls.localize('theia/ai/ide/toolConfirmationInfo/header', 'Tool confirmation')}</span>
|
|
256
|
+
</div>
|
|
257
|
+
<div className="theia-message-content">
|
|
258
|
+
<LocalizedMarkdown
|
|
259
|
+
localizationKey="theia/ai/ide/toolConfirmationInfo"
|
|
260
|
+
defaultMarkdown={
|
|
261
|
+
'AI agents may want to use tools to act on your workspace. ' +
|
|
262
|
+
'By default each tool call needs your confirmation. ' +
|
|
263
|
+
'You can change this default or pre-approve individual tools in the [Tools configuration view]({0}).'
|
|
264
|
+
}
|
|
265
|
+
args={[`command:${OPEN_AI_CONFIG_VIEW_TOOLS.id}`]}
|
|
266
|
+
markdownRenderer={this.markdownRenderer}
|
|
267
|
+
markdownOptions={{ isTrusted: { enabledCommands: [OPEN_AI_CONFIG_VIEW_TOOLS.id] } }}
|
|
268
|
+
/>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
)}
|
|
230
272
|
</div>;
|
|
231
273
|
}
|
|
232
274
|
|
|
@@ -1251,6 +1251,22 @@
|
|
|
1251
1251
|
border-radius: 3px;
|
|
1252
1252
|
}
|
|
1253
1253
|
|
|
1254
|
+
.ai-tools-recommended-defaults-banner {
|
|
1255
|
+
display: flex;
|
|
1256
|
+
align-items: center;
|
|
1257
|
+
gap: calc(var(--theia-ui-padding) * 2);
|
|
1258
|
+
margin-bottom: calc(var(--theia-ui-padding) * 2);
|
|
1259
|
+
padding: calc(var(--theia-ui-padding) * 1.5);
|
|
1260
|
+
background-color: var(--theia-editorInfo-background, var(--theia-editor-background));
|
|
1261
|
+
border: var(--theia-border-width) solid var(--theia-editorInfo-border, var(--theia-widget-border));
|
|
1262
|
+
border-radius: 3px;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
.ai-tools-recommended-defaults-text {
|
|
1266
|
+
flex: 1;
|
|
1267
|
+
line-height: var(--theia-content-line-height);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1254
1270
|
.ai-tools-configuration-default-section {
|
|
1255
1271
|
margin-bottom: calc(var(--theia-ui-padding) * 2);
|
|
1256
1272
|
}
|
|
@@ -20,11 +20,16 @@ import { ResponseNode } from '@theia/ai-chat-ui/lib/browser/chat-tree-view';
|
|
|
20
20
|
import { ChatResponseContent, ToolCallChatResponseContent } from '@theia/ai-chat/lib/common';
|
|
21
21
|
import { ReactNode } from '@theia/core/shared/react';
|
|
22
22
|
import * as React from '@theia/core/shared/react';
|
|
23
|
-
import { codicon, ContextMenuRenderer, OpenerService } from '@theia/core/lib/browser';
|
|
23
|
+
import { codicon, ContextMenuRenderer, KeybindingRegistry, OpenerService } from '@theia/core/lib/browser';
|
|
24
24
|
import { nls } from '@theia/core';
|
|
25
25
|
import { TODO_WRITE_FUNCTION_ID, TodoItem, isValidTodoItem } from '../common/todo-tool';
|
|
26
|
-
import { withToolCallConfirmation } from '@theia/ai-chat-ui/lib/browser/chat-response-renderer/tool-confirmation';
|
|
26
|
+
import { ToolConfirmationKeybindingHints, withToolCallConfirmation } from '@theia/ai-chat-ui/lib/browser/chat-response-renderer/tool-confirmation';
|
|
27
|
+
import {
|
|
28
|
+
APPROVE_LATEST_TOOL_CONFIRMATION_COMMAND,
|
|
29
|
+
DENY_LATEST_TOOL_CONFIRMATION_COMMAND
|
|
30
|
+
} from '@theia/ai-chat-ui/lib/browser/tool-confirmation-keybinding-contribution';
|
|
27
31
|
import { ToolConfirmationManager } from '@theia/ai-chat/lib/browser/chat-tool-preference-bindings';
|
|
32
|
+
import { PendingToolConfirmationTracker } from '@theia/ai-chat/lib/browser/pending-tool-confirmation-tracker';
|
|
28
33
|
import { ToolInvocationRegistry } from '@theia/ai-core';
|
|
29
34
|
|
|
30
35
|
interface TodoListComponentProps {
|
|
@@ -95,6 +100,12 @@ export class TodoToolRenderer implements ChatResponsePartRenderer<ToolCallChatRe
|
|
|
95
100
|
@inject(ToolInvocationRegistry)
|
|
96
101
|
protected toolInvocationRegistry: ToolInvocationRegistry;
|
|
97
102
|
|
|
103
|
+
@inject(PendingToolConfirmationTracker)
|
|
104
|
+
protected pendingToolConfirmationTracker: PendingToolConfirmationTracker;
|
|
105
|
+
|
|
106
|
+
@inject(KeybindingRegistry)
|
|
107
|
+
protected keybindingRegistry: KeybindingRegistry;
|
|
108
|
+
|
|
98
109
|
canHandle(response: ChatResponseContent): number {
|
|
99
110
|
if (ToolCallChatResponseContent.is(response) && response.name === TODO_WRITE_FUNCTION_ID) {
|
|
100
111
|
return 20;
|
|
@@ -128,7 +139,9 @@ export class TodoToolRenderer implements ChatResponsePartRenderer<ToolCallChatRe
|
|
|
128
139
|
chatId,
|
|
129
140
|
requestCanceled: parentNode.response.isCanceled,
|
|
130
141
|
contextMenuRenderer: this.contextMenuRenderer,
|
|
131
|
-
openerService: this.openerService
|
|
142
|
+
openerService: this.openerService,
|
|
143
|
+
pendingTracker: this.pendingToolConfirmationTracker,
|
|
144
|
+
keybindingHints: this.getKeybindingHints()
|
|
132
145
|
}}
|
|
133
146
|
/>
|
|
134
147
|
);
|
|
@@ -156,4 +169,18 @@ export class TodoToolRenderer implements ChatResponsePartRenderer<ToolCallChatRe
|
|
|
156
169
|
return undefined;
|
|
157
170
|
}
|
|
158
171
|
}
|
|
172
|
+
|
|
173
|
+
protected getKeybindingHints(): ToolConfirmationKeybindingHints {
|
|
174
|
+
const allow = this.formatKeybinding(APPROVE_LATEST_TOOL_CONFIRMATION_COMMAND.id);
|
|
175
|
+
const deny = this.formatKeybinding(DENY_LATEST_TOOL_CONFIRMATION_COMMAND.id);
|
|
176
|
+
return { allow, deny };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
protected formatKeybinding(commandId: string): string | undefined {
|
|
180
|
+
const bindings = this.keybindingRegistry.getKeybindingsForCommand(commandId);
|
|
181
|
+
if (!bindings.length) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
return this.keybindingRegistry.acceleratorFor(bindings[0], '+').join('+');
|
|
185
|
+
}
|
|
159
186
|
}
|
|
@@ -20,11 +20,16 @@ import { ResponseNode } from '@theia/ai-chat-ui/lib/browser/chat-tree-view';
|
|
|
20
20
|
import { ChatResponseContent, ToolCallChatResponseContent } from '@theia/ai-chat/lib/common';
|
|
21
21
|
import { ReactNode } from '@theia/core/shared/react';
|
|
22
22
|
import * as React from '@theia/core/shared/react';
|
|
23
|
-
import { codicon, ContextMenuRenderer, OpenerService } from '@theia/core/lib/browser';
|
|
23
|
+
import { codicon, ContextMenuRenderer, KeybindingRegistry, OpenerService } from '@theia/core/lib/browser';
|
|
24
24
|
import { nls } from '@theia/core/lib/common/nls';
|
|
25
25
|
import { useMarkdownRendering } from '@theia/ai-chat-ui/lib/browser/chat-response-renderer/markdown-part-renderer';
|
|
26
|
-
import { withToolCallConfirmation } from '@theia/ai-chat-ui/lib/browser/chat-response-renderer/tool-confirmation';
|
|
26
|
+
import { ToolConfirmationKeybindingHints, withToolCallConfirmation } from '@theia/ai-chat-ui/lib/browser/chat-response-renderer/tool-confirmation';
|
|
27
|
+
import {
|
|
28
|
+
APPROVE_LATEST_TOOL_CONFIRMATION_COMMAND,
|
|
29
|
+
DENY_LATEST_TOOL_CONFIRMATION_COMMAND
|
|
30
|
+
} from '@theia/ai-chat-ui/lib/browser/tool-confirmation-keybinding-contribution';
|
|
27
31
|
import { ToolConfirmationManager } from '@theia/ai-chat/lib/browser/chat-tool-preference-bindings';
|
|
32
|
+
import { PendingToolConfirmationTracker } from '@theia/ai-chat/lib/browser/pending-tool-confirmation-tracker';
|
|
28
33
|
import { ToolInvocationRegistry } from '@theia/ai-core';
|
|
29
34
|
import { UserInteractionTool } from './user-interaction-tool';
|
|
30
35
|
import {
|
|
@@ -499,6 +504,12 @@ export class UserInteractionToolRenderer implements ChatResponsePartRenderer<Too
|
|
|
499
504
|
@inject(OpenerService)
|
|
500
505
|
protected openerService: OpenerService;
|
|
501
506
|
|
|
507
|
+
@inject(PendingToolConfirmationTracker)
|
|
508
|
+
protected pendingToolConfirmationTracker: PendingToolConfirmationTracker;
|
|
509
|
+
|
|
510
|
+
@inject(KeybindingRegistry)
|
|
511
|
+
protected keybindingRegistry: KeybindingRegistry;
|
|
512
|
+
|
|
502
513
|
canHandle(response: ChatResponseContent): number {
|
|
503
514
|
if (ToolCallChatResponseContent.is(response) && response.name === USER_INTERACTION_FUNCTION_ID) {
|
|
504
515
|
return 20;
|
|
@@ -551,9 +562,25 @@ export class UserInteractionToolRenderer implements ChatResponsePartRenderer<Too
|
|
|
551
562
|
chatId,
|
|
552
563
|
requestCanceled: parentNode.response.isCanceled,
|
|
553
564
|
contextMenuRenderer: this.contextMenuRenderer,
|
|
554
|
-
openerService: this.openerService
|
|
565
|
+
openerService: this.openerService,
|
|
566
|
+
pendingTracker: this.pendingToolConfirmationTracker,
|
|
567
|
+
keybindingHints: this.getKeybindingHints()
|
|
555
568
|
}}
|
|
556
569
|
/>
|
|
557
570
|
);
|
|
558
571
|
}
|
|
572
|
+
|
|
573
|
+
protected getKeybindingHints(): ToolConfirmationKeybindingHints {
|
|
574
|
+
const allow = this.formatKeybinding(APPROVE_LATEST_TOOL_CONFIRMATION_COMMAND.id);
|
|
575
|
+
const deny = this.formatKeybinding(DENY_LATEST_TOOL_CONFIRMATION_COMMAND.id);
|
|
576
|
+
return { allow, deny };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
protected formatKeybinding(commandId: string): string | undefined {
|
|
580
|
+
const bindings = this.keybindingRegistry.getKeybindingsForCommand(commandId);
|
|
581
|
+
if (!bindings.length) {
|
|
582
|
+
return undefined;
|
|
583
|
+
}
|
|
584
|
+
return this.keybindingRegistry.acceleratorFor(bindings[0], '+').join('+');
|
|
585
|
+
}
|
|
559
586
|
}
|