@theia/ai-chat-ui 1.67.0-next.56 → 1.67.0-next.59
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-chat-ui-contribution.d.ts +66 -0
- package/lib/browser/ai-chat-ui-contribution.d.ts.map +1 -0
- package/lib/browser/ai-chat-ui-contribution.js +587 -0
- package/lib/browser/ai-chat-ui-contribution.js.map +1 -0
- package/lib/browser/ai-chat-ui-frontend-module.d.ts +5 -0
- package/lib/browser/ai-chat-ui-frontend-module.d.ts.map +1 -0
- package/lib/browser/ai-chat-ui-frontend-module.js +153 -0
- package/lib/browser/ai-chat-ui-frontend-module.js.map +1 -0
- package/lib/browser/change-set-actions/change-set-accept-action.d.ts +10 -0
- package/lib/browser/change-set-actions/change-set-accept-action.d.ts.map +1 -0
- package/lib/browser/change-set-actions/change-set-accept-action.js +47 -0
- package/lib/browser/change-set-actions/change-set-accept-action.js.map +1 -0
- package/lib/browser/change-set-actions/change-set-action-service.d.ts +31 -0
- package/lib/browser/change-set-actions/change-set-action-service.d.ts.map +1 -0
- package/lib/browser/change-set-actions/change-set-action-service.js +57 -0
- package/lib/browser/change-set-actions/change-set-action-service.js.map +1 -0
- package/lib/browser/chat-input-agent-suggestions.d.ts +11 -0
- package/lib/browser/chat-input-agent-suggestions.d.ts.map +1 -0
- package/lib/browser/chat-input-agent-suggestions.js +76 -0
- package/lib/browser/chat-input-agent-suggestions.js.map +1 -0
- package/lib/browser/chat-input-history-contribution.d.ts +17 -0
- package/lib/browser/chat-input-history-contribution.d.ts.map +1 -0
- package/lib/browser/chat-input-history-contribution.js +158 -0
- package/lib/browser/chat-input-history-contribution.js.map +1 -0
- package/lib/browser/chat-input-history.d.ts +32 -0
- package/lib/browser/chat-input-history.d.ts.map +1 -0
- package/lib/browser/chat-input-history.js +125 -0
- package/lib/browser/chat-input-history.js.map +1 -0
- package/lib/browser/chat-input-mode-contribution.d.ts +12 -0
- package/lib/browser/chat-input-mode-contribution.d.ts.map +1 -0
- package/lib/browser/chat-input-mode-contribution.js +77 -0
- package/lib/browser/chat-input-mode-contribution.js.map +1 -0
- package/lib/browser/chat-input-widget.d.ts +118 -0
- package/lib/browser/chat-input-widget.d.ts.map +1 -0
- package/lib/browser/chat-input-widget.js +1034 -0
- package/lib/browser/chat-input-widget.js.map +1 -0
- package/lib/browser/chat-node-toolbar-action-contribution.d.ts +56 -0
- package/lib/browser/chat-node-toolbar-action-contribution.d.ts.map +1 -0
- package/lib/browser/chat-node-toolbar-action-contribution.js +92 -0
- package/lib/browser/chat-node-toolbar-action-contribution.js.map +1 -0
- package/lib/browser/chat-progress-message.d.ts +7 -0
- package/lib/browser/chat-progress-message.d.ts.map +1 -0
- package/lib/browser/chat-progress-message.js +33 -0
- package/lib/browser/chat-progress-message.js.map +1 -0
- package/lib/browser/chat-response-part-renderer.d.ts +10 -0
- package/lib/browser/chat-response-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-part-renderer.js +20 -0
- package/lib/browser/chat-response-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/ai-selection-resolver.d.ts +23 -0
- package/lib/browser/chat-response-renderer/ai-selection-resolver.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/ai-selection-resolver.js +148 -0
- package/lib/browser/chat-response-renderer/ai-selection-resolver.js.map +1 -0
- package/lib/browser/chat-response-renderer/code-part-renderer.d.ts +73 -0
- package/lib/browser/chat-response-renderer/code-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/code-part-renderer.js +227 -0
- package/lib/browser/chat-response-renderer/code-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/command-part-renderer.d.ts +12 -0
- package/lib/browser/chat-response-renderer/command-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/command-part-renderer.js +67 -0
- package/lib/browser/chat-response-renderer/command-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/delegation-response-renderer.d.ts +14 -0
- package/lib/browser/chat-response-renderer/delegation-response-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/delegation-response-renderer.js +144 -0
- package/lib/browser/chat-response-renderer/delegation-response-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/error-part-renderer.d.ts +9 -0
- package/lib/browser/chat-response-renderer/error-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/error-part-renderer.js +40 -0
- package/lib/browser/chat-response-renderer/error-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.d.ts +12 -0
- package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.js +54 -0
- package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/index.d.ts +13 -0
- package/lib/browser/chat-response-renderer/index.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/index.js +31 -0
- package/lib/browser/chat-response-renderer/index.js.map +1 -0
- package/lib/browser/chat-response-renderer/markdown-part-renderer.d.ts +36 -0
- package/lib/browser/chat-response-renderer/markdown-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/markdown-part-renderer.js +129 -0
- package/lib/browser/chat-response-renderer/markdown-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/progress-part-renderer.d.ts +9 -0
- package/lib/browser/chat-response-renderer/progress-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/progress-part-renderer.js +39 -0
- package/lib/browser/chat-response-renderer/progress-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/question-part-renderer.d.ts +10 -0
- package/lib/browser/chat-response-renderer/question-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/question-part-renderer.js +49 -0
- package/lib/browser/chat-response-renderer/question-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.d.ts +9 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.js +43 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.spec.d.ts +2 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.spec.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.spec.js +46 -0
- package/lib/browser/chat-response-renderer/text-part-renderer.spec.js.map +1 -0
- package/lib/browser/chat-response-renderer/thinking-part-renderer.d.ts +9 -0
- package/lib/browser/chat-response-renderer/thinking-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/thinking-part-renderer.js +42 -0
- package/lib/browser/chat-response-renderer/thinking-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/tool-confirmation.d.ts +17 -0
- package/lib/browser/chat-response-renderer/tool-confirmation.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/tool-confirmation.js +122 -0
- package/lib/browser/chat-response-renderer/tool-confirmation.js.map +1 -0
- package/lib/browser/chat-response-renderer/toolcall-part-renderer.d.ts +20 -0
- package/lib/browser/chat-response-renderer/toolcall-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/toolcall-part-renderer.js +223 -0
- package/lib/browser/chat-response-renderer/toolcall-part-renderer.js.map +1 -0
- package/lib/browser/chat-response-renderer/unknown-part-renderer.d.ts +9 -0
- package/lib/browser/chat-response-renderer/unknown-part-renderer.d.ts.map +1 -0
- package/lib/browser/chat-response-renderer/unknown-part-renderer.js +42 -0
- package/lib/browser/chat-response-renderer/unknown-part-renderer.js.map +1 -0
- package/lib/browser/chat-tree-view/chat-view-tree-container.d.ts +4 -0
- package/lib/browser/chat-tree-view/chat-view-tree-container.d.ts.map +1 -0
- package/lib/browser/chat-tree-view/chat-view-tree-container.js +33 -0
- package/lib/browser/chat-tree-view/chat-view-tree-container.js.map +1 -0
- package/lib/browser/chat-tree-view/chat-view-tree-input-widget.d.ts +38 -0
- package/lib/browser/chat-tree-view/chat-view-tree-input-widget.d.ts.map +1 -0
- package/lib/browser/chat-tree-view/chat-view-tree-input-widget.js +88 -0
- package/lib/browser/chat-tree-view/chat-view-tree-input-widget.js.map +1 -0
- package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts +120 -0
- package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts.map +1 -0
- package/lib/browser/chat-tree-view/chat-view-tree-widget.js +654 -0
- package/lib/browser/chat-tree-view/chat-view-tree-widget.js.map +1 -0
- package/lib/browser/chat-tree-view/index.d.ts +3 -0
- package/lib/browser/chat-tree-view/index.d.ts.map +1 -0
- package/lib/browser/chat-tree-view/index.js +21 -0
- package/lib/browser/chat-tree-view/index.js.map +1 -0
- package/lib/browser/chat-tree-view/sub-chat-widget.d.ts +22 -0
- package/lib/browser/chat-tree-view/sub-chat-widget.d.ts.map +1 -0
- package/lib/browser/chat-tree-view/sub-chat-widget.js +92 -0
- package/lib/browser/chat-tree-view/sub-chat-widget.js.map +1 -0
- package/lib/browser/chat-view-commands.d.ts +15 -0
- package/lib/browser/chat-view-commands.d.ts.map +1 -0
- package/lib/browser/chat-view-commands.js +76 -0
- package/lib/browser/chat-view-commands.js.map +1 -0
- package/lib/browser/chat-view-contribution.d.ts +21 -0
- package/lib/browser/chat-view-contribution.d.ts.map +1 -0
- package/lib/browser/chat-view-contribution.js +183 -0
- package/lib/browser/chat-view-contribution.js.map +1 -0
- package/lib/browser/chat-view-language-contribution.d.ts +41 -0
- package/lib/browser/chat-view-language-contribution.d.ts.map +1 -0
- package/lib/browser/chat-view-language-contribution.js +269 -0
- package/lib/browser/chat-view-language-contribution.js.map +1 -0
- package/lib/browser/chat-view-widget-toolbar-contribution.d.ts +20 -0
- package/lib/browser/chat-view-widget-toolbar-contribution.d.ts.map +1 -0
- package/lib/browser/chat-view-widget-toolbar-contribution.js +115 -0
- package/lib/browser/chat-view-widget-toolbar-contribution.js.map +1 -0
- package/lib/browser/chat-view-widget.d.ts +60 -0
- package/lib/browser/chat-view-widget.d.ts.map +1 -0
- package/lib/browser/chat-view-widget.js +243 -0
- package/lib/browser/chat-view-widget.js.map +1 -0
- package/lib/browser/context-variable-picker.d.ts +9 -0
- package/lib/browser/context-variable-picker.d.ts.map +1 -0
- package/lib/browser/context-variable-picker.js +86 -0
- package/lib/browser/context-variable-picker.js.map +1 -0
- package/lib/browser/session-settings-dialog.d.ts +35 -0
- package/lib/browser/session-settings-dialog.d.ts.map +1 -0
- package/lib/browser/session-settings-dialog.js +118 -0
- package/lib/browser/session-settings-dialog.js.map +1 -0
- package/package.json +10 -10
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CommandRegistry, MessageService, QuickInputButton, QuickInputService, QuickPickItem } from '@theia/core';
|
|
2
|
+
import { ILogger } from '@theia/core/lib/common/logger';
|
|
3
|
+
import { Widget } from '@theia/core/lib/browser';
|
|
4
|
+
import { ChatAgent, ChatService } from '@theia/ai-chat';
|
|
5
|
+
import { ChatAgentService } from '@theia/ai-chat/lib/common/chat-agent-service';
|
|
6
|
+
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
|
7
|
+
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
|
8
|
+
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
|
9
|
+
import { ChatViewWidget } from './chat-view-widget';
|
|
10
|
+
import { SecondaryWindowHandler } from '@theia/core/lib/browser/secondary-window-handler';
|
|
11
|
+
import { AIActivationService } from '@theia/ai-core/lib/browser';
|
|
12
|
+
import { TaskContextService } from '@theia/ai-chat/lib/browser/task-context-service';
|
|
13
|
+
export declare const AI_CHAT_TOGGLE_COMMAND_ID = "aiChat:toggle";
|
|
14
|
+
export declare class AIChatContribution extends AbstractViewContribution<ChatViewWidget> implements TabBarToolbarContribution {
|
|
15
|
+
protected readonly chatService: ChatService;
|
|
16
|
+
protected readonly quickInputService: QuickInputService;
|
|
17
|
+
protected readonly taskContextService: TaskContextService;
|
|
18
|
+
protected readonly messageService: MessageService;
|
|
19
|
+
protected readonly chatAgentService: ChatAgentService;
|
|
20
|
+
protected readonly editorManager: EditorManager;
|
|
21
|
+
protected readonly activationService: AIActivationService;
|
|
22
|
+
protected readonly logger: ILogger;
|
|
23
|
+
/**
|
|
24
|
+
* Store whether there are persisted sessions to make this information available in
|
|
25
|
+
* command enablement checks which are synchronous.
|
|
26
|
+
*/
|
|
27
|
+
protected hasPersistedSessions: boolean;
|
|
28
|
+
protected static readonly RENAME_CHAT_BUTTON: QuickInputButton;
|
|
29
|
+
protected static readonly REMOVE_CHAT_BUTTON: QuickInputButton;
|
|
30
|
+
protected readonly secondaryWindowHandler: SecondaryWindowHandler;
|
|
31
|
+
constructor();
|
|
32
|
+
initialize(): void;
|
|
33
|
+
protected checkPersistedSessions(): Promise<void>;
|
|
34
|
+
registerCommands(registry: CommandRegistry): void;
|
|
35
|
+
registerToolbarItems(registry: TabBarToolbarRegistry): void;
|
|
36
|
+
protected selectChat(sessionId?: string): Promise<void>;
|
|
37
|
+
protected askForChatSession(): Promise<QuickPickItem | undefined>;
|
|
38
|
+
protected withWidget(widget?: Widget | undefined, predicate?: (output: ChatViewWidget) => boolean): boolean | false;
|
|
39
|
+
protected extractChatView(chatView: ChatViewWidget): void;
|
|
40
|
+
canExtractChatView(chatView: ChatViewWidget): boolean;
|
|
41
|
+
protected summarizeActiveSession(): Promise<string | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* Prompts the user to select a chat agent
|
|
44
|
+
* @returns The selected agent or undefined if cancelled
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Prompts the user to select a chat agent with an optional default (pre-selected) agent.
|
|
48
|
+
* @param defaultAgentId The id of the agent to pre-select, if present
|
|
49
|
+
* @returns The selected agent or undefined if cancelled
|
|
50
|
+
*/
|
|
51
|
+
protected selectAgent(defaultAgentId?: string): Promise<ChatAgent | undefined>;
|
|
52
|
+
/**
|
|
53
|
+
* Prompts the user to select a task context with special marking for currently opened files
|
|
54
|
+
* @returns The selected task context ID or undefined if cancelled
|
|
55
|
+
*/
|
|
56
|
+
protected selectTaskContextWithMarking(): Promise<string | undefined>;
|
|
57
|
+
/**
|
|
58
|
+
* Returns information about task context files that are currently opened
|
|
59
|
+
* @returns Object with arrays of opened context IDs and the active context ID
|
|
60
|
+
*/
|
|
61
|
+
protected getOpenedTaskContextFiles(): {
|
|
62
|
+
openedIds: string[];
|
|
63
|
+
activeId?: string;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=ai-chat-ui-contribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-chat-ui-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/ai-chat-ui-contribution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2024 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
var AIChatContribution_1;
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.AIChatContribution = exports.AI_CHAT_TOGGLE_COMMAND_ID = void 0;
|
|
20
|
+
const tslib_1 = require("tslib");
|
|
21
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
22
|
+
const core_1 = require("@theia/core");
|
|
23
|
+
const logger_1 = require("@theia/core/lib/common/logger");
|
|
24
|
+
const chat_view_commands_1 = require("./chat-view-commands");
|
|
25
|
+
const ai_chat_1 = require("@theia/ai-chat");
|
|
26
|
+
const chat_agent_service_1 = require("@theia/ai-chat/lib/common/chat-agent-service");
|
|
27
|
+
const editor_manager_1 = require("@theia/editor/lib/browser/editor-manager");
|
|
28
|
+
const view_contribution_1 = require("@theia/core/lib/browser/shell/view-contribution");
|
|
29
|
+
const chat_view_widget_1 = require("./chat-view-widget");
|
|
30
|
+
const promise_util_1 = require("@theia/core/lib/common/promise-util");
|
|
31
|
+
const secondary_window_handler_1 = require("@theia/core/lib/browser/secondary-window-handler");
|
|
32
|
+
const date_fns_1 = require("date-fns");
|
|
33
|
+
const locales = require("date-fns/locale");
|
|
34
|
+
const browser_1 = require("@theia/ai-core/lib/browser");
|
|
35
|
+
const chat_node_toolbar_action_contribution_1 = require("./chat-node-toolbar-action-contribution");
|
|
36
|
+
const chat_tree_view_1 = require("./chat-tree-view");
|
|
37
|
+
const task_context_variable_1 = require("@theia/ai-chat/lib/browser/task-context-variable");
|
|
38
|
+
const task_context_service_1 = require("@theia/ai-chat/lib/browser/task-context-service");
|
|
39
|
+
exports.AI_CHAT_TOGGLE_COMMAND_ID = 'aiChat:toggle';
|
|
40
|
+
let AIChatContribution = AIChatContribution_1 = class AIChatContribution extends view_contribution_1.AbstractViewContribution {
|
|
41
|
+
constructor() {
|
|
42
|
+
super({
|
|
43
|
+
widgetId: chat_view_widget_1.ChatViewWidget.ID,
|
|
44
|
+
widgetName: chat_view_widget_1.ChatViewWidget.LABEL,
|
|
45
|
+
defaultWidgetOptions: {
|
|
46
|
+
area: 'right',
|
|
47
|
+
rank: 100
|
|
48
|
+
},
|
|
49
|
+
toggleCommandId: exports.AI_CHAT_TOGGLE_COMMAND_ID,
|
|
50
|
+
toggleKeybinding: core_1.isOSX ? 'ctrl+cmd+i' : 'ctrl+alt+i'
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Store whether there are persisted sessions to make this information available in
|
|
54
|
+
* command enablement checks which are synchronous.
|
|
55
|
+
*/
|
|
56
|
+
this.hasPersistedSessions = false;
|
|
57
|
+
}
|
|
58
|
+
initialize() {
|
|
59
|
+
this.chatService.onSessionEvent(event => {
|
|
60
|
+
if (!(0, ai_chat_1.isActiveSessionChangedEvent)(event)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (event.focus) {
|
|
64
|
+
this.openView({ activate: true });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
this.checkPersistedSessions();
|
|
68
|
+
}
|
|
69
|
+
async checkPersistedSessions() {
|
|
70
|
+
try {
|
|
71
|
+
const index = await this.chatService.getPersistedSessions();
|
|
72
|
+
this.hasPersistedSessions = Object.keys(index).length > 0;
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
this.logger.error('Failed to check persisted AI sessions', e);
|
|
76
|
+
this.hasPersistedSessions = false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
registerCommands(registry) {
|
|
80
|
+
super.registerCommands(registry);
|
|
81
|
+
registry.registerCommand(chat_view_commands_1.ChatCommands.SCROLL_LOCK_WIDGET, {
|
|
82
|
+
isEnabled: widget => this.withWidget(widget, chatWidget => !chatWidget.isLocked),
|
|
83
|
+
isVisible: widget => this.withWidget(widget, chatWidget => !chatWidget.isLocked),
|
|
84
|
+
execute: widget => this.withWidget(widget, chatWidget => {
|
|
85
|
+
chatWidget.lock();
|
|
86
|
+
return true;
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
registry.registerCommand(chat_view_commands_1.ChatCommands.SCROLL_UNLOCK_WIDGET, {
|
|
90
|
+
isEnabled: widget => this.withWidget(widget, chatWidget => chatWidget.isLocked),
|
|
91
|
+
isVisible: widget => this.withWidget(widget, chatWidget => chatWidget.isLocked),
|
|
92
|
+
execute: widget => this.withWidget(widget, chatWidget => {
|
|
93
|
+
chatWidget.unlock();
|
|
94
|
+
return true;
|
|
95
|
+
})
|
|
96
|
+
});
|
|
97
|
+
registry.registerCommand(chat_view_commands_1.AI_CHAT_NEW_CHAT_WINDOW_COMMAND, {
|
|
98
|
+
execute: () => this.openView().then(() => this.chatService.createSession(ai_chat_1.ChatAgentLocation.Panel, { focus: true })),
|
|
99
|
+
isVisible: widget => this.activationService.isActive,
|
|
100
|
+
isEnabled: widget => this.activationService.isActive,
|
|
101
|
+
});
|
|
102
|
+
registry.registerCommand(chat_view_commands_1.ChatCommands.AI_CHAT_NEW_WITH_TASK_CONTEXT, {
|
|
103
|
+
execute: async () => {
|
|
104
|
+
const activeSession = this.chatService.getActiveSession();
|
|
105
|
+
const id = await this.summarizeActiveSession();
|
|
106
|
+
if (!id || !activeSession) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const newSession = this.chatService.createSession(ai_chat_1.ChatAgentLocation.Panel, { focus: true }, activeSession.pinnedAgent);
|
|
110
|
+
const summaryVariable = { variable: task_context_variable_1.TASK_CONTEXT_VARIABLE, arg: id };
|
|
111
|
+
newSession.model.context.addVariables(summaryVariable);
|
|
112
|
+
},
|
|
113
|
+
isVisible: () => false
|
|
114
|
+
});
|
|
115
|
+
registry.registerCommand(chat_view_commands_1.ChatCommands.AI_CHAT_SUMMARIZE_CURRENT_SESSION, {
|
|
116
|
+
execute: async () => this.summarizeActiveSession(),
|
|
117
|
+
isVisible: widget => {
|
|
118
|
+
if (!this.activationService.isActive) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
if (widget && !this.withWidget(widget)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const activeSession = this.chatService.getActiveSession();
|
|
125
|
+
return (activeSession === null || activeSession === void 0 ? void 0 : activeSession.model.location) === ai_chat_1.ChatAgentLocation.Panel
|
|
126
|
+
&& !this.taskContextService.hasSummary(activeSession);
|
|
127
|
+
},
|
|
128
|
+
isEnabled: widget => {
|
|
129
|
+
if (!this.activationService.isActive) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
if (widget && !this.withWidget(widget)) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const activeSession = this.chatService.getActiveSession();
|
|
136
|
+
return (activeSession === null || activeSession === void 0 ? void 0 : activeSession.model.location) === ai_chat_1.ChatAgentLocation.Panel
|
|
137
|
+
&& !activeSession.model.isEmpty()
|
|
138
|
+
&& !this.taskContextService.hasSummary(activeSession);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
registry.registerCommand(chat_view_commands_1.ChatCommands.AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION, {
|
|
142
|
+
execute: async () => {
|
|
143
|
+
const id = await this.summarizeActiveSession();
|
|
144
|
+
if (!id) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
await this.taskContextService.open(id);
|
|
148
|
+
},
|
|
149
|
+
isVisible: widget => {
|
|
150
|
+
if (!this.activationService.isActive) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (widget && !this.withWidget(widget)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const activeSession = this.chatService.getActiveSession();
|
|
157
|
+
return !!activeSession && this.taskContextService.hasSummary(activeSession);
|
|
158
|
+
},
|
|
159
|
+
isEnabled: widget => {
|
|
160
|
+
if (!this.activationService.isActive) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return this.withWidget(widget, () => true);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
registry.registerCommand(chat_view_commands_1.ChatCommands.AI_CHAT_INITIATE_SESSION_WITH_TASK_CONTEXT, {
|
|
167
|
+
execute: async () => {
|
|
168
|
+
const selectedContextId = await this.selectTaskContextWithMarking();
|
|
169
|
+
if (!selectedContextId) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const selectedAgent = await this.selectAgent('Coder');
|
|
173
|
+
if (!selectedAgent) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const newSession = this.chatService.createSession(ai_chat_1.ChatAgentLocation.Panel, { focus: true }, selectedAgent);
|
|
177
|
+
newSession.model.context.addVariables({ variable: task_context_variable_1.TASK_CONTEXT_VARIABLE, arg: selectedContextId });
|
|
178
|
+
},
|
|
179
|
+
isVisible: () => this.activationService.isActive,
|
|
180
|
+
isEnabled: () => this.activationService.isActive
|
|
181
|
+
});
|
|
182
|
+
registry.registerCommand(chat_view_commands_1.AI_CHAT_SHOW_CHATS_COMMAND, {
|
|
183
|
+
execute: () => this.selectChat(),
|
|
184
|
+
isEnabled: widget => {
|
|
185
|
+
if (!this.activationService.isActive || !this.withWidget(widget)) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
// Enable if there are active sessions with titles OR persisted sessions
|
|
189
|
+
return this.chatService.getSessions().some(session => !!session.title) || this.hasPersistedSessions;
|
|
190
|
+
},
|
|
191
|
+
isVisible: widget => this.activationService.isActive && this.withWidget(widget)
|
|
192
|
+
});
|
|
193
|
+
registry.registerCommand(chat_node_toolbar_action_contribution_1.ChatNodeToolbarCommands.EDIT, {
|
|
194
|
+
isEnabled: node => (0, chat_tree_view_1.isEditableRequestNode)(node) && !node.request.isEditing,
|
|
195
|
+
isVisible: node => (0, chat_tree_view_1.isEditableRequestNode)(node) && !node.request.isEditing,
|
|
196
|
+
execute: (node) => {
|
|
197
|
+
node.request.enableEdit();
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
registry.registerCommand(chat_node_toolbar_action_contribution_1.ChatNodeToolbarCommands.CANCEL, {
|
|
201
|
+
isEnabled: node => (0, chat_tree_view_1.isEditableRequestNode)(node) && node.request.isEditing,
|
|
202
|
+
isVisible: node => (0, chat_tree_view_1.isEditableRequestNode)(node) && node.request.isEditing,
|
|
203
|
+
execute: (node) => {
|
|
204
|
+
node.request.cancelEdit();
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
registry.registerCommand(chat_node_toolbar_action_contribution_1.ChatNodeToolbarCommands.RETRY, {
|
|
208
|
+
isEnabled: node => (0, chat_tree_view_1.isResponseNode)(node) && (node.response.isError || node.response.isCanceled),
|
|
209
|
+
isVisible: node => (0, chat_tree_view_1.isResponseNode)(node) && (node.response.isError || node.response.isCanceled),
|
|
210
|
+
execute: async (node) => {
|
|
211
|
+
try {
|
|
212
|
+
// Get the session for this response node
|
|
213
|
+
const session = this.chatService.getActiveSession();
|
|
214
|
+
if (!session) {
|
|
215
|
+
this.messageService.error(core_1.nls.localize('theia/ai/chat-ui/sessionNotFoundForRetry', 'Session not found for retry'));
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// Find the request associated with this response
|
|
219
|
+
const request = session.model.getRequests().find(req => req.response.id === node.response.id);
|
|
220
|
+
if (!request) {
|
|
221
|
+
this.messageService.error(core_1.nls.localize('theia/ai/chat-ui/requestNotFoundForRetry', 'Request not found for retry'));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Send the same request again using the chat service
|
|
225
|
+
await this.chatService.sendRequest(node.sessionId, request.request);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
console.error('Failed to retry chat message:', error);
|
|
229
|
+
this.messageService.error(core_1.nls.localize('theia/ai/chat-ui/failedToRetry', 'Failed to retry message'));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
registerToolbarItems(registry) {
|
|
235
|
+
registry.registerItem({
|
|
236
|
+
id: chat_view_commands_1.AI_CHAT_NEW_CHAT_WINDOW_COMMAND.id,
|
|
237
|
+
command: chat_view_commands_1.AI_CHAT_NEW_CHAT_WINDOW_COMMAND.id,
|
|
238
|
+
tooltip: chat_view_commands_1.AI_CHAT_NEW_CHAT_WINDOW_COMMAND.label,
|
|
239
|
+
isVisible: widget => this.activationService.isActive && this.withWidget(widget),
|
|
240
|
+
when: browser_1.ENABLE_AI_CONTEXT_KEY
|
|
241
|
+
});
|
|
242
|
+
registry.registerItem({
|
|
243
|
+
id: chat_view_commands_1.AI_CHAT_SHOW_CHATS_COMMAND.id,
|
|
244
|
+
command: chat_view_commands_1.AI_CHAT_SHOW_CHATS_COMMAND.id,
|
|
245
|
+
tooltip: chat_view_commands_1.AI_CHAT_SHOW_CHATS_COMMAND.label,
|
|
246
|
+
isVisible: widget => this.activationService.isActive && this.withWidget(widget),
|
|
247
|
+
when: browser_1.ENABLE_AI_CONTEXT_KEY
|
|
248
|
+
});
|
|
249
|
+
registry.registerItem({
|
|
250
|
+
id: 'chat-view.' + browser_1.AI_SHOW_SETTINGS_COMMAND.id,
|
|
251
|
+
command: browser_1.AI_SHOW_SETTINGS_COMMAND.id,
|
|
252
|
+
group: 'ai-settings',
|
|
253
|
+
priority: 3,
|
|
254
|
+
tooltip: core_1.nls.localize('theia/ai-chat-ui/open-settings-tooltip', 'Open AI settings...'),
|
|
255
|
+
isVisible: widget => this.activationService.isActive && this.withWidget(widget),
|
|
256
|
+
when: browser_1.ENABLE_AI_CONTEXT_KEY
|
|
257
|
+
});
|
|
258
|
+
const sessionSummarizibilityChangedEmitter = new core_1.Emitter();
|
|
259
|
+
this.taskContextService.onDidChange(() => sessionSummarizibilityChangedEmitter.fire());
|
|
260
|
+
this.chatService.onSessionEvent(event => event.type === 'activeChange' && sessionSummarizibilityChangedEmitter.fire());
|
|
261
|
+
this.activationService.onDidChangeActiveStatus(() => sessionSummarizibilityChangedEmitter.fire());
|
|
262
|
+
registry.registerItem({
|
|
263
|
+
id: 'chat-view.' + chat_view_commands_1.ChatCommands.AI_CHAT_SUMMARIZE_CURRENT_SESSION.id,
|
|
264
|
+
command: chat_view_commands_1.ChatCommands.AI_CHAT_SUMMARIZE_CURRENT_SESSION.id,
|
|
265
|
+
onDidChange: sessionSummarizibilityChangedEmitter.event,
|
|
266
|
+
when: browser_1.ENABLE_AI_CONTEXT_KEY
|
|
267
|
+
});
|
|
268
|
+
registry.registerItem({
|
|
269
|
+
id: 'chat-view.' + chat_view_commands_1.ChatCommands.AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION.id,
|
|
270
|
+
command: chat_view_commands_1.ChatCommands.AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION.id,
|
|
271
|
+
onDidChange: sessionSummarizibilityChangedEmitter.event,
|
|
272
|
+
when: browser_1.ENABLE_AI_CONTEXT_KEY
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
async selectChat(sessionId) {
|
|
276
|
+
let activeSessionId = sessionId;
|
|
277
|
+
if (!activeSessionId) {
|
|
278
|
+
const item = await this.askForChatSession();
|
|
279
|
+
if (item === undefined) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
activeSessionId = item.id;
|
|
283
|
+
}
|
|
284
|
+
this.chatService.setActiveSession(activeSessionId, { focus: true });
|
|
285
|
+
}
|
|
286
|
+
async askForChatSession() {
|
|
287
|
+
const getItems = async () => {
|
|
288
|
+
const activeSessions = this.chatService.getSessions()
|
|
289
|
+
.filter(session => session.title)
|
|
290
|
+
.map(session => ({
|
|
291
|
+
session,
|
|
292
|
+
isActive: true,
|
|
293
|
+
lastDate: session.lastInteraction ? session.lastInteraction.getTime() : 0
|
|
294
|
+
}));
|
|
295
|
+
// Try to load persisted sessions, but don't fail if it doesn't work
|
|
296
|
+
let persistedSessions = [];
|
|
297
|
+
try {
|
|
298
|
+
const persistedIndex = await this.chatService.getPersistedSessions();
|
|
299
|
+
const activeIds = new Set(activeSessions.map(s => s.session.id));
|
|
300
|
+
persistedSessions = Object.values(persistedIndex)
|
|
301
|
+
.filter(metadata => !activeIds.has(metadata.sessionId))
|
|
302
|
+
.map(metadata => ({
|
|
303
|
+
metadata,
|
|
304
|
+
isActive: false,
|
|
305
|
+
lastDate: metadata.saveDate
|
|
306
|
+
}));
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
this.logger.error('Failed to load persisted sessions, showing only active sessions', error);
|
|
310
|
+
// Continue with just active sessions
|
|
311
|
+
}
|
|
312
|
+
// Combine and sort by last interaction/message date
|
|
313
|
+
const allSessions = [
|
|
314
|
+
...activeSessions.map(s => {
|
|
315
|
+
var _a;
|
|
316
|
+
return ({
|
|
317
|
+
isActive: true,
|
|
318
|
+
id: s.session.id,
|
|
319
|
+
title: s.session.title,
|
|
320
|
+
lastDate: s.lastDate,
|
|
321
|
+
firstRequestText: (_a = s.session.model.getRequests().at(0)) === null || _a === void 0 ? void 0 : _a.request.text
|
|
322
|
+
});
|
|
323
|
+
}),
|
|
324
|
+
...persistedSessions.map(s => ({
|
|
325
|
+
isActive: false,
|
|
326
|
+
id: s.metadata.sessionId,
|
|
327
|
+
title: s.metadata.title,
|
|
328
|
+
lastDate: s.lastDate,
|
|
329
|
+
firstRequestText: undefined
|
|
330
|
+
}))
|
|
331
|
+
].sort((a, b) => b.lastDate - a.lastDate);
|
|
332
|
+
return allSessions.map(session => {
|
|
333
|
+
// Add icon for persisted sessions to visually distinguish them
|
|
334
|
+
const icon = session.isActive ? '' : '$(archive) ';
|
|
335
|
+
const label = `${icon}${session.title}`;
|
|
336
|
+
return ({
|
|
337
|
+
label,
|
|
338
|
+
description: (0, date_fns_1.formatDistance)(new Date(session.lastDate), new Date(), { addSuffix: false, locale: getDateFnsLocale() }),
|
|
339
|
+
detail: session.firstRequestText || (session.isActive ? undefined : core_1.nls.localize('theia/ai/chat-ui/persistedSession', 'Persisted session (click to restore)')),
|
|
340
|
+
id: session.id,
|
|
341
|
+
buttons: [AIChatContribution_1.RENAME_CHAT_BUTTON, AIChatContribution_1.REMOVE_CHAT_BUTTON]
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
};
|
|
345
|
+
const defer = new promise_util_1.Deferred();
|
|
346
|
+
const quickPick = this.quickInputService.createQuickPick();
|
|
347
|
+
quickPick.placeholder = core_1.nls.localize('theia/ai/chat-ui/selectChat', 'Select chat');
|
|
348
|
+
quickPick.canSelectMany = false;
|
|
349
|
+
quickPick.busy = true;
|
|
350
|
+
quickPick.show();
|
|
351
|
+
// Load items asynchronously
|
|
352
|
+
getItems().then(items => {
|
|
353
|
+
quickPick.items = items;
|
|
354
|
+
quickPick.busy = false;
|
|
355
|
+
}).catch(error => {
|
|
356
|
+
this.logger.error('Failed to load chat sessions', error);
|
|
357
|
+
quickPick.busy = false;
|
|
358
|
+
quickPick.placeholder = core_1.nls.localize('theia/ai/chat-ui/failedToLoadChats', 'Failed to load chat sessions');
|
|
359
|
+
});
|
|
360
|
+
quickPick.onDidTriggerItemButton(async (context) => {
|
|
361
|
+
if (context.button === AIChatContribution_1.RENAME_CHAT_BUTTON) {
|
|
362
|
+
quickPick.hide();
|
|
363
|
+
this.quickInputService.input({
|
|
364
|
+
placeHolder: core_1.nls.localize('theia/ai/chat-ui/enterChatName', 'Enter chat name')
|
|
365
|
+
}).then(name => {
|
|
366
|
+
if (name && name.length > 0) {
|
|
367
|
+
const session = this.chatService.getSession(context.item.id);
|
|
368
|
+
if (session) {
|
|
369
|
+
session.title = name;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
else if (context.button === AIChatContribution_1.REMOVE_CHAT_BUTTON) {
|
|
375
|
+
// Wait for deletion to complete before refreshing the list
|
|
376
|
+
this.chatService.deleteSession(context.item.id).then(() => getItems()).then(items => {
|
|
377
|
+
quickPick.items = items;
|
|
378
|
+
if (items.length === 0) {
|
|
379
|
+
quickPick.hide();
|
|
380
|
+
}
|
|
381
|
+
// Update persisted sessions flag after deletion
|
|
382
|
+
this.checkPersistedSessions();
|
|
383
|
+
}).catch(error => {
|
|
384
|
+
this.logger.error('Failed to delete chat session', error);
|
|
385
|
+
this.messageService.error(core_1.nls.localize('theia/ai/chat-ui/failedToDeleteSession', 'Failed to delete chat session'));
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
quickPick.onDidAccept(async () => {
|
|
390
|
+
const selectedItem = quickPick.selectedItems[0];
|
|
391
|
+
if (selectedItem) {
|
|
392
|
+
// Restore session if not already loaded
|
|
393
|
+
const session = this.chatService.getSession(selectedItem.id);
|
|
394
|
+
if (!session) {
|
|
395
|
+
try {
|
|
396
|
+
await this.chatService.getOrRestoreSession(selectedItem.id);
|
|
397
|
+
// Update persisted sessions flag after restoration
|
|
398
|
+
this.checkPersistedSessions();
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
this.logger.error('Failed to restore chat session', error);
|
|
402
|
+
this.messageService.error(core_1.nls.localize('theia/ai/chat-ui/failedToRestoreSession', 'Failed to restore chat session'));
|
|
403
|
+
defer.resolve(undefined);
|
|
404
|
+
quickPick.hide();
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
defer.resolve(selectedItem);
|
|
410
|
+
quickPick.hide();
|
|
411
|
+
});
|
|
412
|
+
quickPick.onDidHide(() => defer.resolve(undefined));
|
|
413
|
+
return defer.promise;
|
|
414
|
+
}
|
|
415
|
+
withWidget(widget = this.tryGetWidget(), predicate = () => true) {
|
|
416
|
+
return widget instanceof chat_view_widget_1.ChatViewWidget ? predicate(widget) : false;
|
|
417
|
+
}
|
|
418
|
+
extractChatView(chatView) {
|
|
419
|
+
this.secondaryWindowHandler.moveWidgetToSecondaryWindow(chatView);
|
|
420
|
+
}
|
|
421
|
+
canExtractChatView(chatView) {
|
|
422
|
+
return !chatView.secondaryWindow;
|
|
423
|
+
}
|
|
424
|
+
async summarizeActiveSession() {
|
|
425
|
+
const activeSession = this.chatService.getActiveSession();
|
|
426
|
+
if (!activeSession) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
return this.taskContextService.summarize(activeSession).catch(err => {
|
|
430
|
+
console.warn('Error while summarizing session:', err);
|
|
431
|
+
this.messageService.error(core_1.nls.localize('theia/ai/chat-ui/unableToSummarizeCurrentSession', 'Unable to summarize current session. Please confirm that the summary agent is not disabled.'));
|
|
432
|
+
return undefined;
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Prompts the user to select a chat agent
|
|
437
|
+
* @returns The selected agent or undefined if cancelled
|
|
438
|
+
*/
|
|
439
|
+
/**
|
|
440
|
+
* Prompts the user to select a chat agent with an optional default (pre-selected) agent.
|
|
441
|
+
* @param defaultAgentId The id of the agent to pre-select, if present
|
|
442
|
+
* @returns The selected agent or undefined if cancelled
|
|
443
|
+
*/
|
|
444
|
+
async selectAgent(defaultAgentId) {
|
|
445
|
+
const agents = this.chatAgentService.getAgents();
|
|
446
|
+
if (agents.length === 0) {
|
|
447
|
+
this.messageService.warn(core_1.nls.localize('theia/ai/chat-ui/noChatAgentsAvailable', 'No chat agents available.'));
|
|
448
|
+
return undefined;
|
|
449
|
+
}
|
|
450
|
+
const items = agents.map(agent => ({
|
|
451
|
+
label: agent.name || agent.id,
|
|
452
|
+
description: agent.description,
|
|
453
|
+
id: agent.id
|
|
454
|
+
}));
|
|
455
|
+
let preselected = undefined;
|
|
456
|
+
if (defaultAgentId) {
|
|
457
|
+
preselected = items.find(item => item.id === defaultAgentId);
|
|
458
|
+
}
|
|
459
|
+
const selected = await this.quickInputService.showQuickPick(items, {
|
|
460
|
+
placeholder: core_1.nls.localize('theia/ai/chat-ui/selectAgentQuickPickPlaceholder', 'Select an agent for the new session'),
|
|
461
|
+
activeItem: preselected
|
|
462
|
+
});
|
|
463
|
+
if (!selected) {
|
|
464
|
+
return undefined;
|
|
465
|
+
}
|
|
466
|
+
return this.chatAgentService.getAgent(selected.id);
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Prompts the user to select a task context with special marking for currently opened files
|
|
470
|
+
* @returns The selected task context ID or undefined if cancelled
|
|
471
|
+
*/
|
|
472
|
+
async selectTaskContextWithMarking() {
|
|
473
|
+
const contexts = this.taskContextService.getAll();
|
|
474
|
+
const openedFilesInfo = this.getOpenedTaskContextFiles();
|
|
475
|
+
// Create items with opened files marked and prioritized
|
|
476
|
+
const items = contexts.map(summary => {
|
|
477
|
+
const isOpened = openedFilesInfo.openedIds.includes(summary.id);
|
|
478
|
+
const isActive = openedFilesInfo.activeId === summary.id;
|
|
479
|
+
return {
|
|
480
|
+
label: isOpened ? `📄 ${summary.label} (${core_1.nls.localize('theia/ai/chat-ui/selectTaskContextQuickPickItem/currentlyOpen', 'currently open')})` : summary.label,
|
|
481
|
+
description: summary.id,
|
|
482
|
+
id: summary.id,
|
|
483
|
+
// We'll sort active file first, then opened files, then others
|
|
484
|
+
sortText: isActive ? `0-${summary.label}` : isOpened ? `1-${summary.label}` : `2-${summary.label}`
|
|
485
|
+
};
|
|
486
|
+
}).sort((a, b) => a.sortText.localeCompare(b.sortText));
|
|
487
|
+
const selected = await this.quickInputService.showQuickPick(items, {
|
|
488
|
+
placeholder: core_1.nls.localize('theia/ai/chat-ui/selectTaskContextQuickPickPlaceholder', 'Select a task context to attach')
|
|
489
|
+
});
|
|
490
|
+
return selected === null || selected === void 0 ? void 0 : selected.id;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Returns information about task context files that are currently opened
|
|
494
|
+
* @returns Object with arrays of opened context IDs and the active context ID
|
|
495
|
+
*/
|
|
496
|
+
getOpenedTaskContextFiles() {
|
|
497
|
+
var _a;
|
|
498
|
+
// Get all contexts with their URIs
|
|
499
|
+
const allContexts = this.taskContextService.getAll();
|
|
500
|
+
const contextMap = new Map(); // Map of URI -> ID
|
|
501
|
+
// Create a map of URI string -> context ID for lookup
|
|
502
|
+
for (const context of allContexts) {
|
|
503
|
+
if (context.uri) {
|
|
504
|
+
contextMap.set(context.uri.toString(), context.id);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
// Get all open editor URIs
|
|
508
|
+
const openEditorUris = this.editorManager.all.map(widget => widget.editor.uri.toString());
|
|
509
|
+
// Get the currently active/focused editor URI if any
|
|
510
|
+
const activeEditorUri = (_a = this.editorManager.currentEditor) === null || _a === void 0 ? void 0 : _a.editor.uri.toString();
|
|
511
|
+
let activeContextId;
|
|
512
|
+
if (activeEditorUri) {
|
|
513
|
+
activeContextId = contextMap.get(activeEditorUri);
|
|
514
|
+
}
|
|
515
|
+
// Filter to only task context files that are currently opened
|
|
516
|
+
const openedContextIds = [];
|
|
517
|
+
for (const uri of openEditorUris) {
|
|
518
|
+
const contextId = contextMap.get(uri);
|
|
519
|
+
if (contextId) {
|
|
520
|
+
openedContextIds.push(contextId);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return { openedIds: openedContextIds, activeId: activeContextId };
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
exports.AIChatContribution = AIChatContribution;
|
|
527
|
+
AIChatContribution.RENAME_CHAT_BUTTON = {
|
|
528
|
+
iconClass: 'codicon-edit',
|
|
529
|
+
tooltip: core_1.nls.localize('theia/ai/chat-ui/renameChat', 'Rename Chat'),
|
|
530
|
+
};
|
|
531
|
+
AIChatContribution.REMOVE_CHAT_BUTTON = {
|
|
532
|
+
iconClass: 'codicon-remove-close',
|
|
533
|
+
tooltip: core_1.nls.localize('theia/ai/chat-ui/removeChat', 'Remove Chat'),
|
|
534
|
+
};
|
|
535
|
+
tslib_1.__decorate([
|
|
536
|
+
(0, inversify_1.inject)(ai_chat_1.ChatService),
|
|
537
|
+
tslib_1.__metadata("design:type", Object)
|
|
538
|
+
], AIChatContribution.prototype, "chatService", void 0);
|
|
539
|
+
tslib_1.__decorate([
|
|
540
|
+
(0, inversify_1.inject)(core_1.QuickInputService),
|
|
541
|
+
tslib_1.__metadata("design:type", Object)
|
|
542
|
+
], AIChatContribution.prototype, "quickInputService", void 0);
|
|
543
|
+
tslib_1.__decorate([
|
|
544
|
+
(0, inversify_1.inject)(task_context_service_1.TaskContextService),
|
|
545
|
+
tslib_1.__metadata("design:type", task_context_service_1.TaskContextService)
|
|
546
|
+
], AIChatContribution.prototype, "taskContextService", void 0);
|
|
547
|
+
tslib_1.__decorate([
|
|
548
|
+
(0, inversify_1.inject)(core_1.MessageService),
|
|
549
|
+
tslib_1.__metadata("design:type", core_1.MessageService)
|
|
550
|
+
], AIChatContribution.prototype, "messageService", void 0);
|
|
551
|
+
tslib_1.__decorate([
|
|
552
|
+
(0, inversify_1.inject)(chat_agent_service_1.ChatAgentService),
|
|
553
|
+
tslib_1.__metadata("design:type", Object)
|
|
554
|
+
], AIChatContribution.prototype, "chatAgentService", void 0);
|
|
555
|
+
tslib_1.__decorate([
|
|
556
|
+
(0, inversify_1.inject)(editor_manager_1.EditorManager),
|
|
557
|
+
tslib_1.__metadata("design:type", editor_manager_1.EditorManager)
|
|
558
|
+
], AIChatContribution.prototype, "editorManager", void 0);
|
|
559
|
+
tslib_1.__decorate([
|
|
560
|
+
(0, inversify_1.inject)(browser_1.AIActivationService),
|
|
561
|
+
tslib_1.__metadata("design:type", Object)
|
|
562
|
+
], AIChatContribution.prototype, "activationService", void 0);
|
|
563
|
+
tslib_1.__decorate([
|
|
564
|
+
(0, inversify_1.inject)(logger_1.ILogger),
|
|
565
|
+
(0, inversify_1.named)('AIChatContribution'),
|
|
566
|
+
tslib_1.__metadata("design:type", Object)
|
|
567
|
+
], AIChatContribution.prototype, "logger", void 0);
|
|
568
|
+
tslib_1.__decorate([
|
|
569
|
+
(0, inversify_1.inject)(secondary_window_handler_1.SecondaryWindowHandler),
|
|
570
|
+
tslib_1.__metadata("design:type", secondary_window_handler_1.SecondaryWindowHandler)
|
|
571
|
+
], AIChatContribution.prototype, "secondaryWindowHandler", void 0);
|
|
572
|
+
tslib_1.__decorate([
|
|
573
|
+
(0, inversify_1.postConstruct)(),
|
|
574
|
+
tslib_1.__metadata("design:type", Function),
|
|
575
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
576
|
+
tslib_1.__metadata("design:returntype", void 0)
|
|
577
|
+
], AIChatContribution.prototype, "initialize", null);
|
|
578
|
+
exports.AIChatContribution = AIChatContribution = AIChatContribution_1 = tslib_1.__decorate([
|
|
579
|
+
(0, inversify_1.injectable)(),
|
|
580
|
+
tslib_1.__metadata("design:paramtypes", [])
|
|
581
|
+
], AIChatContribution);
|
|
582
|
+
function getDateFnsLocale() {
|
|
583
|
+
var _a;
|
|
584
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
585
|
+
return core_1.nls.locale ? (_a = locales[core_1.nls.locale]) !== null && _a !== void 0 ? _a : locales.enUS : locales.enUS;
|
|
586
|
+
}
|
|
587
|
+
//# sourceMappingURL=ai-chat-ui-contribution.js.map
|