deploy: current vibn theia state
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

Made-with: Cursor
This commit is contained in:
2026-02-27 12:01:08 -08:00
commit 8bb5110148
3782 changed files with 640947 additions and 0 deletions

View File

@@ -0,0 +1,242 @@
// *****************************************************************************
// 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 { MessageService } from '@theia/core/lib/common/message-service';
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
import { nls } from '@theia/core/lib/common/nls';
import {
PREFERENCE_NAME_DEFAULT_NOTIFICATION_TYPE,
} from '../common/ai-core-preferences';
import { AgentService } from '../common/agent-service';
import { AISettingsService } from '../common/settings-service';
import { OSNotificationService } from './os-notification-service';
import { WindowBlinkService } from './window-blink-service';
import {
NotificationType,
NOTIFICATION_TYPE_OFF,
NOTIFICATION_TYPE_OS_NOTIFICATION,
NOTIFICATION_TYPE_MESSAGE,
NOTIFICATION_TYPE_BLINK,
} from '../common/notification-types';
import { PreferenceService } from '@theia/core';
@injectable()
export class AgentCompletionNotificationService {
@inject(PreferenceService)
protected readonly preferenceService: PreferenceService;
@inject(AgentService)
protected readonly agentService: AgentService;
@inject(AISettingsService)
protected readonly settingsService: AISettingsService;
@inject(OSNotificationService)
protected readonly osNotificationService: OSNotificationService;
@inject(MessageService)
protected readonly messageService: MessageService;
@inject(WindowBlinkService)
protected readonly windowBlinkService: WindowBlinkService;
@inject(ApplicationShell)
protected readonly shell: ApplicationShell;
/**
* Show a completion notification for the specified agent if enabled in preferences.
*
* @param agentId The unique identifier of the agent
* @param taskDescription Optional description of the completed task
*/
async showCompletionNotification(
agentId: string,
taskDescription?: string,
): Promise<void> {
const notificationType =
await this.getNotificationTypeForAgent(agentId);
if (notificationType === NOTIFICATION_TYPE_OFF || this.isChatWidgetFocused()) {
return;
}
try {
const agentName = this.resolveAgentName(agentId);
await this.executeNotificationType(
agentName,
taskDescription,
notificationType,
);
} catch (error) {
console.error(
'Failed to show agent completion notification:',
error,
);
}
}
/**
* Resolve the display name for an agent by its ID.
*
* @param agentId The unique identifier of the agent
* @returns The agent's display name or the agent ID if not found
*/
protected resolveAgentName(agentId: string): string {
try {
const agents = this.agentService.getAllAgents();
const agent = agents.find(a => a.id === agentId);
return agent?.name || agentId;
} catch (error) {
console.warn(
`Failed to resolve agent name for ID '${agentId}':`,
error,
);
return agentId;
}
}
/**
* Get the preferred notification type for a specific agent.
* If no agent-specific preference is set, returns the global default notification type.
*/
protected async getNotificationTypeForAgent(
agentId: string,
): Promise<NotificationType> {
const agentSettings =
await this.settingsService.getAgentSettings(agentId);
const agentNotificationType = agentSettings?.completionNotification as NotificationType;
// If agent has no specific setting, use the global default
if (!agentNotificationType) {
return this.preferenceService.get<NotificationType>(
PREFERENCE_NAME_DEFAULT_NOTIFICATION_TYPE,
NOTIFICATION_TYPE_OFF,
);
}
return agentNotificationType;
}
/**
* Execute the specified notification type.
*/
private async executeNotificationType(
agentName: string,
taskDescription: string | undefined,
type: NotificationType,
): Promise<void> {
switch (type) {
case NOTIFICATION_TYPE_OS_NOTIFICATION:
await this.showOSNotification(agentName, taskDescription);
break;
case NOTIFICATION_TYPE_MESSAGE:
await this.showMessageServiceNotification(
agentName,
taskDescription,
);
break;
case NOTIFICATION_TYPE_BLINK:
await this.showBlinkNotification(agentName);
break;
default:
throw new Error(`Unknown notification type: ${type}`);
}
}
/**
* Show OS notification directly.
*/
protected async showOSNotification(
agentName: string,
taskDescription?: string,
): Promise<void> {
const result =
await this.osNotificationService.showAgentCompletionNotification(
agentName,
taskDescription,
);
if (!result.success) {
throw new Error(`OS notification failed: ${result.error}`);
}
}
/**
* Show MessageService notification.
*/
protected async showMessageServiceNotification(
agentName: string,
taskDescription?: string,
): Promise<void> {
const message = taskDescription
? nls.localize(
'theia/ai-core/agentCompletionWithTask',
'Agent "{0}" has completed the task: {1}',
agentName,
taskDescription,
)
: nls.localize(
'theia/ai-core/agentCompletionMessage',
'Agent "{0}" has completed its task.',
agentName,
);
this.messageService.info(message);
}
/**
* Show window blink notification.
*/
protected async showBlinkNotification(agentName: string): Promise<void> {
const result = await this.windowBlinkService.blinkWindow(agentName);
if (!result.success) {
throw new Error(
`Window blink notification failed: ${result.error}`,
);
}
}
/**
* Check if OS notifications are supported and enabled.
*/
isOSNotificationSupported(): boolean {
return this.osNotificationService.isNotificationSupported();
}
/**
* Get the current OS notification permission status.
*/
getOSNotificationPermission(): NotificationPermission {
return this.osNotificationService.getPermissionStatus();
}
/**
* Request OS notification permission from the user.
*/
async requestOSNotificationPermission(): Promise<NotificationPermission> {
return this.osNotificationService.requestPermission();
}
/**
* Check if any chat widget currently has focus.
*/
protected isChatWidgetFocused(): boolean {
const activeWidget = this.shell.activeWidget;
if (!activeWidget) {
return false;
}
return activeWidget.id === 'chat-view-widget';
}
}