Files
theia-code-os/packages/ai-chat/src/browser/chat-tool-preference-bindings.ts
mawkone 8bb5110148
Some checks failed
Playwright Tests / Playwright Tests (ubuntu-22.04, Node.js 22.x) (push) Has been cancelled
3PP License Check / 3PP License Check (11, 22.x, ubuntu-22.04) (push) Has been cancelled
Publish packages to NPM / Perform Publishing (push) Has been cancelled
deploy: current vibn theia state
Made-with: Cursor
2026-02-27 12:01:08 -08:00

139 lines
5.6 KiB
TypeScript

// *****************************************************************************
// Copyright (C) 2025 EclipseSource GmbH.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
import { injectable, inject } from '@theia/core/shared/inversify';
import {
PreferenceService,
} from '@theia/core/lib/common/preferences';
import { ToolConfirmationMode, TOOL_CONFIRMATION_PREFERENCE, ChatToolPreferences } from '../common/chat-tool-preferences';
import { ToolRequest } from '@theia/ai-core';
/**
* Utility class to manage tool confirmation settings
*/
@injectable()
export class ToolConfirmationManager {
@inject(ChatToolPreferences)
protected readonly preferences: ChatToolPreferences;
@inject(PreferenceService)
protected readonly preferenceService: PreferenceService;
// In-memory session overrides (not persisted), per chat
protected sessionOverrides: Map<string, Map<string, ToolConfirmationMode>> = new Map();
/**
* Get the confirmation mode for a specific tool, considering session overrides first (per chat).
*
* For tools with `confirmAlwaysAllow` flag:
* - They default to CONFIRM mode instead of ALWAYS_ALLOW
* - They don't inherit global ALWAYS_ALLOW from the '*' preference
*
* @param toolId - The tool identifier
* @param chatId - The chat session identifier
* @param toolRequest - Optional ToolRequest to check for confirmAlwaysAllow flag
*/
getConfirmationMode(toolId: string, chatId: string, toolRequest?: ToolRequest): ToolConfirmationMode {
const chatMap = this.sessionOverrides.get(chatId);
if (chatMap && chatMap.has(toolId)) {
return chatMap.get(toolId)!;
}
const toolConfirmation = this.preferences[TOOL_CONFIRMATION_PREFERENCE];
if (toolConfirmation[toolId]) {
return toolConfirmation[toolId];
}
if (toolConfirmation['*']) {
// For confirmAlwaysAllow tools, don't inherit global ALWAYS_ALLOW
if (toolRequest?.confirmAlwaysAllow && toolConfirmation['*'] === ToolConfirmationMode.ALWAYS_ALLOW) {
return ToolConfirmationMode.CONFIRM;
}
return toolConfirmation['*'];
}
// Default: ALWAYS_ALLOW for normal tools, CONFIRM for confirmAlwaysAllow tools
return toolRequest?.confirmAlwaysAllow
? ToolConfirmationMode.CONFIRM
: ToolConfirmationMode.ALWAYS_ALLOW;
}
/**
* Set the confirmation mode for a specific tool (persisted)
*
* @param toolId - The tool identifier
* @param mode - The confirmation mode to set
* @param toolRequest - Optional ToolRequest to check for confirmAlwaysAllow flag
*/
setConfirmationMode(toolId: string, mode: ToolConfirmationMode, toolRequest?: ToolRequest): void {
const current = this.preferences[TOOL_CONFIRMATION_PREFERENCE] || {};
let starMode = current['*'];
if (starMode === undefined) {
starMode = ToolConfirmationMode.ALWAYS_ALLOW;
}
// For confirmAlwaysAllow tools, the effective default is CONFIRM, not ALWAYS_ALLOW
const effectiveDefault = (toolRequest?.confirmAlwaysAllow && starMode === ToolConfirmationMode.ALWAYS_ALLOW)
? ToolConfirmationMode.CONFIRM
: starMode;
if (mode === effectiveDefault) {
if (toolId in current) {
const { [toolId]: _, ...rest } = current;
this.preferenceService.updateValue(TOOL_CONFIRMATION_PREFERENCE, rest);
}
} else {
const updated = { ...current, [toolId]: mode };
this.preferenceService.updateValue(TOOL_CONFIRMATION_PREFERENCE, updated);
}
}
/**
* Set the confirmation mode for a specific tool for this session only (not persisted, per chat)
*/
setSessionConfirmationMode(toolId: string, mode: ToolConfirmationMode, chatId: string): void {
let chatMap = this.sessionOverrides.get(chatId);
if (!chatMap) {
chatMap = new Map();
this.sessionOverrides.set(chatId, chatMap);
}
chatMap.set(toolId, mode);
}
/**
* Clear all session overrides for a specific chat, or all if no chatId is given
*/
clearSessionOverrides(chatId?: string): void {
if (chatId) {
this.sessionOverrides.delete(chatId);
} else {
this.sessionOverrides.clear();
}
}
/**
* Get all tool confirmation settings
*/
getAllConfirmationSettings(): { [toolId: string]: ToolConfirmationMode } {
return this.preferences[TOOL_CONFIRMATION_PREFERENCE] || {};
}
resetAllConfirmationModeSettings(): void {
const current = this.preferences[TOOL_CONFIRMATION_PREFERENCE] || {};
if ('*' in current) {
this.preferenceService.updateValue(TOOL_CONFIRMATION_PREFERENCE, { '*': current['*'] });
} else {
this.preferenceService.updateValue(TOOL_CONFIRMATION_PREFERENCE, {});
}
}
}