@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,654 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var ChatViewTreeWidget_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ChatViewTreeWidget = exports.ChatWelcomeMessageProvider = exports.isEnterKey = exports.isResponseNode = exports.isEditableRequestNode = exports.isRequestNode = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
// *****************************************************************************
|
|
7
|
+
// Copyright (C) 2024 EclipseSource GmbH.
|
|
8
|
+
//
|
|
9
|
+
// This program and the accompanying materials are made available under the
|
|
10
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
11
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
12
|
+
//
|
|
13
|
+
// This Source Code may also be made available under the following Secondary
|
|
14
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
15
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
16
|
+
// with the GNU Classpath Exception which is available at
|
|
17
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
18
|
+
//
|
|
19
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
20
|
+
// *****************************************************************************
|
|
21
|
+
const ai_chat_1 = require("@theia/ai-chat");
|
|
22
|
+
const ai_core_1 = require("@theia/ai-core");
|
|
23
|
+
const browser_1 = require("@theia/ai-core/lib/browser");
|
|
24
|
+
const core_1 = require("@theia/core");
|
|
25
|
+
const browser_2 = require("@theia/core/lib/browser");
|
|
26
|
+
const nls_1 = require("@theia/core/lib/common/nls");
|
|
27
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
28
|
+
const React = require("@theia/core/shared/react");
|
|
29
|
+
const chat_node_toolbar_action_contribution_1 = require("../chat-node-toolbar-action-contribution");
|
|
30
|
+
const chat_response_part_renderer_1 = require("../chat-response-part-renderer");
|
|
31
|
+
const markdown_part_renderer_1 = require("../chat-response-renderer/markdown-part-renderer");
|
|
32
|
+
const chat_progress_message_1 = require("../chat-progress-message");
|
|
33
|
+
const chat_view_tree_input_widget_1 = require("./chat-view-tree-input-widget");
|
|
34
|
+
const isRequestNode = (node) => 'request' in node;
|
|
35
|
+
exports.isRequestNode = isRequestNode;
|
|
36
|
+
const isEditableRequestNode = (node) => (0, exports.isRequestNode)(node) && ai_chat_1.EditableChatRequestModel.is(node.request);
|
|
37
|
+
exports.isEditableRequestNode = isEditableRequestNode;
|
|
38
|
+
const isResponseNode = (node) => 'response' in node;
|
|
39
|
+
exports.isResponseNode = isResponseNode;
|
|
40
|
+
function isEnterKey(e) {
|
|
41
|
+
var _a;
|
|
42
|
+
return browser_2.Key.ENTER.keyCode === ((_a = browser_2.KeyCode.createKeyCode(e.nativeEvent).key) === null || _a === void 0 ? void 0 : _a.keyCode);
|
|
43
|
+
}
|
|
44
|
+
exports.isEnterKey = isEnterKey;
|
|
45
|
+
exports.ChatWelcomeMessageProvider = Symbol('ChatWelcomeMessageProvider');
|
|
46
|
+
let ChatViewTreeWidget = ChatViewTreeWidget_1 = class ChatViewTreeWidget extends browser_2.TreeWidget {
|
|
47
|
+
set shouldScrollToEnd(shouldScrollToEnd) {
|
|
48
|
+
this._shouldScrollToEnd = shouldScrollToEnd;
|
|
49
|
+
this.shouldScrollToRow = this._shouldScrollToEnd;
|
|
50
|
+
}
|
|
51
|
+
get shouldScrollToEnd() {
|
|
52
|
+
return this._shouldScrollToEnd;
|
|
53
|
+
}
|
|
54
|
+
constructor(props, model, contextMenuRenderer) {
|
|
55
|
+
super(props, model, contextMenuRenderer);
|
|
56
|
+
this.onDidSubmitEditEmitter = new core_1.Emitter();
|
|
57
|
+
this.onDidSubmitEdit = this.onDidSubmitEditEmitter.event;
|
|
58
|
+
this.chatInputs = new Map();
|
|
59
|
+
this._shouldScrollToEnd = true;
|
|
60
|
+
this.isEnabled = false;
|
|
61
|
+
/** Tracks if we are at the bottom for showing the scroll-to-bottom button. */
|
|
62
|
+
this.atBottom = true;
|
|
63
|
+
/**
|
|
64
|
+
* Track the visibility of the scroll button with debounce logic. Used to prevent flickering when streaming tokens.
|
|
65
|
+
*/
|
|
66
|
+
this._showScrollButton = false;
|
|
67
|
+
this.lastScrollTop = 0;
|
|
68
|
+
this.toDisposeOnChatModelChange = new core_1.DisposableCollection();
|
|
69
|
+
this.id = ChatViewTreeWidget_1.ID;
|
|
70
|
+
this.title.closable = false;
|
|
71
|
+
model.root = {
|
|
72
|
+
id: 'ChatTree',
|
|
73
|
+
name: 'ChatRootNode',
|
|
74
|
+
parent: undefined,
|
|
75
|
+
visible: false,
|
|
76
|
+
children: [],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
init() {
|
|
80
|
+
super.init();
|
|
81
|
+
this.id = ChatViewTreeWidget_1.ID + '-treeContainer';
|
|
82
|
+
this.addClass('treeContainer');
|
|
83
|
+
this.toDispose.pushAll([
|
|
84
|
+
this.toDisposeOnChatModelChange,
|
|
85
|
+
this.activationService.onDidChangeActiveStatus(change => {
|
|
86
|
+
this.chatInputs.forEach(widget => {
|
|
87
|
+
widget.setEnabled(change);
|
|
88
|
+
});
|
|
89
|
+
this.update();
|
|
90
|
+
}),
|
|
91
|
+
this.onScroll(scrollEvent => {
|
|
92
|
+
this.handleScrollEvent(scrollEvent);
|
|
93
|
+
})
|
|
94
|
+
]);
|
|
95
|
+
// Initialize lastScrollTop with current scroll position
|
|
96
|
+
this.lastScrollTop = this.getCurrentScrollTop(undefined);
|
|
97
|
+
}
|
|
98
|
+
setEnabled(enabled) {
|
|
99
|
+
this.isEnabled = enabled;
|
|
100
|
+
this.update();
|
|
101
|
+
}
|
|
102
|
+
handleScrollEvent(scrollEvent) {
|
|
103
|
+
const currentScrollTop = this.getCurrentScrollTop(scrollEvent);
|
|
104
|
+
const isScrollingUp = currentScrollTop < this.lastScrollTop;
|
|
105
|
+
const isScrollingDown = currentScrollTop > this.lastScrollTop;
|
|
106
|
+
const isAtBottom = this.isScrolledToBottom();
|
|
107
|
+
const isAtAbsoluteBottom = this.isAtAbsoluteBottom();
|
|
108
|
+
// Asymmetric threshold logic to prevent jitter:
|
|
109
|
+
if (this.shouldScrollToEnd && isScrollingUp) {
|
|
110
|
+
if (!isAtAbsoluteBottom) {
|
|
111
|
+
this.setTemporaryScrollLock(true);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (!this.shouldScrollToEnd && isAtBottom && isScrollingDown) {
|
|
115
|
+
this.setTemporaryScrollLock(false);
|
|
116
|
+
}
|
|
117
|
+
this.updateScrollToBottomButtonState(isAtBottom);
|
|
118
|
+
this.lastScrollTop = currentScrollTop;
|
|
119
|
+
}
|
|
120
|
+
/** Updates the scroll-to-bottom button state and handles debounce. */
|
|
121
|
+
updateScrollToBottomButtonState(isAtBottom) {
|
|
122
|
+
const atBottomNow = isAtBottom; // Use isScrolledToBottom for threshold
|
|
123
|
+
if (atBottomNow !== this.atBottom) {
|
|
124
|
+
this.atBottom = atBottomNow;
|
|
125
|
+
if (this.atBottom) {
|
|
126
|
+
// We're at the bottom, hide the button immediately and clear any debounce timer.
|
|
127
|
+
this._showScrollButton = false;
|
|
128
|
+
if (this._scrollButtonDebounceTimer !== undefined) {
|
|
129
|
+
clearTimeout(this._scrollButtonDebounceTimer);
|
|
130
|
+
this._scrollButtonDebounceTimer = undefined;
|
|
131
|
+
}
|
|
132
|
+
this.update();
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// User scrolled up; delay showing the scroll-to-bottom button.
|
|
136
|
+
if (this._scrollButtonDebounceTimer !== undefined) {
|
|
137
|
+
clearTimeout(this._scrollButtonDebounceTimer);
|
|
138
|
+
}
|
|
139
|
+
this._scrollButtonDebounceTimer = window.setTimeout(() => {
|
|
140
|
+
// Re-check: only show if we're still not at bottom
|
|
141
|
+
if (!this.atBottom) {
|
|
142
|
+
this._showScrollButton = true;
|
|
143
|
+
this.update();
|
|
144
|
+
}
|
|
145
|
+
this._scrollButtonDebounceTimer = undefined;
|
|
146
|
+
}, ChatViewTreeWidget_1.SCROLL_BUTTON_GRACE_PERIOD);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
setTemporaryScrollLock(enabled) {
|
|
151
|
+
var _a;
|
|
152
|
+
// Immediately apply scroll lock changes without delay
|
|
153
|
+
(_a = this.onScrollLockChange) === null || _a === void 0 ? void 0 : _a.call(this, enabled);
|
|
154
|
+
// Update cached scrollToRow so that outdated values do not cause unwanted scrolling on update()
|
|
155
|
+
this.updateScrollToRow();
|
|
156
|
+
}
|
|
157
|
+
getCurrentScrollTop(scrollEvent) {
|
|
158
|
+
// For virtualized trees, use the virtualized view's scroll state (most reliable)
|
|
159
|
+
if (this.props.virtualized !== false && this.view) {
|
|
160
|
+
const scrollState = this.getVirtualizedScrollState();
|
|
161
|
+
if (scrollState !== undefined) {
|
|
162
|
+
return scrollState.scrollTop;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Try to extract scroll position from the scroll event
|
|
166
|
+
if (scrollEvent && typeof scrollEvent === 'object' && 'scrollTop' in scrollEvent) {
|
|
167
|
+
const scrollEventWithScrollTop = scrollEvent;
|
|
168
|
+
const scrollTop = scrollEventWithScrollTop.scrollTop;
|
|
169
|
+
if (typeof scrollTop === 'number' && !isNaN(scrollTop)) {
|
|
170
|
+
return scrollTop;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Last resort: use DOM scroll position
|
|
174
|
+
if (this.node && typeof this.node.scrollTop === 'number') {
|
|
175
|
+
return this.node.scrollTop;
|
|
176
|
+
}
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Returns true if the scroll position is at the absolute (1px tolerance) bottom of the scroll container.
|
|
181
|
+
* Handles both virtualized and non-virtualized scroll containers.
|
|
182
|
+
* Allows for a tiny floating point epsilon (1px).
|
|
183
|
+
*/
|
|
184
|
+
isAtAbsoluteBottom() {
|
|
185
|
+
var _a, _b;
|
|
186
|
+
let scrollTop = 0;
|
|
187
|
+
let scrollHeight = 0;
|
|
188
|
+
let clientHeight = 0;
|
|
189
|
+
const EPSILON = 1; // px
|
|
190
|
+
if (this.props.virtualized !== false && this.view) {
|
|
191
|
+
const state = this.getVirtualizedScrollState();
|
|
192
|
+
if (state) {
|
|
193
|
+
scrollTop = state.scrollTop;
|
|
194
|
+
scrollHeight = (_a = state.scrollHeight) !== null && _a !== void 0 ? _a : 0;
|
|
195
|
+
clientHeight = (_b = state.clientHeight) !== null && _b !== void 0 ? _b : 0;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else if (this.node) {
|
|
199
|
+
scrollTop = this.node.scrollTop;
|
|
200
|
+
scrollHeight = this.node.scrollHeight;
|
|
201
|
+
clientHeight = this.node.clientHeight;
|
|
202
|
+
}
|
|
203
|
+
const diff = Math.abs(scrollTop + clientHeight - scrollHeight);
|
|
204
|
+
return diff <= EPSILON;
|
|
205
|
+
}
|
|
206
|
+
renderTree(model) {
|
|
207
|
+
var _a;
|
|
208
|
+
if (!this.isEnabled) {
|
|
209
|
+
return this.renderDisabledMessage();
|
|
210
|
+
}
|
|
211
|
+
const tree = browser_2.CompositeTreeNode.is(model.root) && ((_a = model.root.children) === null || _a === void 0 ? void 0 : _a.length) > 0
|
|
212
|
+
? super.renderTree(model)
|
|
213
|
+
: this.renderWelcomeMessage();
|
|
214
|
+
return React.createElement(React.Fragment, null,
|
|
215
|
+
tree,
|
|
216
|
+
this.renderScrollToBottomButton());
|
|
217
|
+
}
|
|
218
|
+
/** Shows the scroll to bottom button if not at the bottom (debounced). */
|
|
219
|
+
renderScrollToBottomButton() {
|
|
220
|
+
if (!this._showScrollButton) {
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
// Down-arrow, Theia codicon, fixed overlay on widget
|
|
224
|
+
return React.createElement("button", { className: "theia-ChatTree-ScrollToBottom codicon codicon-arrow-down", title: nls_1.nls.localize('theia/ai/chat-ui/chat-view-tree-widget/scrollToBottom', 'Jump to latest message'), onClick: () => this.handleScrollToBottomButtonClick() });
|
|
225
|
+
}
|
|
226
|
+
/** Scrolls to the bottom row and updates atBottom state. */
|
|
227
|
+
handleScrollToBottomButtonClick() {
|
|
228
|
+
this.scrollToRow = this.rows.size;
|
|
229
|
+
this.atBottom = true;
|
|
230
|
+
this._showScrollButton = false;
|
|
231
|
+
if (this._scrollButtonDebounceTimer !== undefined) {
|
|
232
|
+
clearTimeout(this._scrollButtonDebounceTimer);
|
|
233
|
+
this._scrollButtonDebounceTimer = undefined;
|
|
234
|
+
}
|
|
235
|
+
this.update();
|
|
236
|
+
}
|
|
237
|
+
renderDisabledMessage() {
|
|
238
|
+
var _a, _b, _c;
|
|
239
|
+
return (_c = (_b = (_a = this.welcomeMessageProvider) === null || _a === void 0 ? void 0 : _a.renderDisabledMessage) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : React.createElement(React.Fragment, null);
|
|
240
|
+
}
|
|
241
|
+
renderWelcomeMessage() {
|
|
242
|
+
var _a, _b, _c;
|
|
243
|
+
return (_c = (_b = (_a = this.welcomeMessageProvider) === null || _a === void 0 ? void 0 : _a.renderWelcomeMessage) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : React.createElement(React.Fragment, null);
|
|
244
|
+
}
|
|
245
|
+
mapRequestToNode(branch) {
|
|
246
|
+
return {
|
|
247
|
+
parent: this.model.root,
|
|
248
|
+
get id() {
|
|
249
|
+
return this.request.id;
|
|
250
|
+
},
|
|
251
|
+
get request() {
|
|
252
|
+
return branch.get();
|
|
253
|
+
},
|
|
254
|
+
branch,
|
|
255
|
+
sessionId: this.chatModelId
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
mapResponseToNode(response) {
|
|
259
|
+
return {
|
|
260
|
+
id: response.id,
|
|
261
|
+
parent: this.model.root,
|
|
262
|
+
response,
|
|
263
|
+
sessionId: this.chatModelId
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Tracks the ChatModel handed over.
|
|
268
|
+
* Tracking multiple chat models will result in a weird UI
|
|
269
|
+
*/
|
|
270
|
+
trackChatModel(chatModel) {
|
|
271
|
+
this.toDisposeOnChatModelChange.dispose();
|
|
272
|
+
this.recreateModelTree(chatModel);
|
|
273
|
+
chatModel.getRequests().forEach(request => {
|
|
274
|
+
if (!request.response.isComplete) {
|
|
275
|
+
request.response.onDidChange(() => this.scheduleUpdateScrollToRow());
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
this.toDisposeOnChatModelChange.pushAll([
|
|
279
|
+
core_1.Disposable.create(() => {
|
|
280
|
+
this.chatInputs.forEach(widget => widget.dispose());
|
|
281
|
+
this.chatInputs.clear();
|
|
282
|
+
}),
|
|
283
|
+
chatModel.onDidChange(event => {
|
|
284
|
+
var _a;
|
|
285
|
+
if (event.kind === 'enableEdit') {
|
|
286
|
+
this.scrollToRow = (_a = this.rows.get(event.request.id)) === null || _a === void 0 ? void 0 : _a.index;
|
|
287
|
+
this.update();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
else if (event.kind === 'cancelEdit') {
|
|
291
|
+
this.disposeChatInputWidget(event.request);
|
|
292
|
+
this.scrollToRow = undefined;
|
|
293
|
+
this.update();
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
else if (event.kind === 'changeHierarchyBranch') {
|
|
297
|
+
this.scrollToRow = undefined;
|
|
298
|
+
}
|
|
299
|
+
this.recreateModelTree(chatModel);
|
|
300
|
+
if (event.kind === 'addRequest' && !event.request.response.isComplete) {
|
|
301
|
+
event.request.response.onDidChange(() => this.scheduleUpdateScrollToRow());
|
|
302
|
+
}
|
|
303
|
+
else if (event.kind === 'submitEdit') {
|
|
304
|
+
event.branch.succeedingBranches().forEach(branch => {
|
|
305
|
+
this.disposeChatInputWidget(branch.get());
|
|
306
|
+
});
|
|
307
|
+
this.onDidSubmitEditEmitter.fire(event.newRequest);
|
|
308
|
+
}
|
|
309
|
+
})
|
|
310
|
+
]);
|
|
311
|
+
}
|
|
312
|
+
disposeChatInputWidget(request) {
|
|
313
|
+
const widget = this.chatInputs.get(request.id);
|
|
314
|
+
if (widget) {
|
|
315
|
+
widget.dispose();
|
|
316
|
+
this.chatInputs.delete(request.id);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
getScrollToRow() {
|
|
320
|
+
// Only scroll to end if auto-scroll is enabled (not locked)
|
|
321
|
+
if (this.shouldScrollToEnd) {
|
|
322
|
+
return this.rows.size;
|
|
323
|
+
}
|
|
324
|
+
// When auto-scroll is disabled, don't auto-scroll at all
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
async recreateModelTree(chatModel) {
|
|
328
|
+
if (browser_2.CompositeTreeNode.is(this.model.root)) {
|
|
329
|
+
const nodes = [];
|
|
330
|
+
this.chatModelId = chatModel.id;
|
|
331
|
+
chatModel.getBranches().forEach(branch => {
|
|
332
|
+
const request = branch.get();
|
|
333
|
+
nodes.push(this.mapRequestToNode(branch));
|
|
334
|
+
nodes.push(this.mapResponseToNode(request.response));
|
|
335
|
+
});
|
|
336
|
+
this.model.root.children = nodes;
|
|
337
|
+
this.model.refresh();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
renderNode(node, props) {
|
|
341
|
+
if (!browser_2.TreeNode.isVisible(node)) {
|
|
342
|
+
return undefined;
|
|
343
|
+
}
|
|
344
|
+
if (!((0, exports.isRequestNode)(node) || (0, exports.isResponseNode)(node))) {
|
|
345
|
+
return super.renderNode(node, props);
|
|
346
|
+
}
|
|
347
|
+
return React.createElement(React.Fragment, { key: node.id },
|
|
348
|
+
React.createElement("div", { className: 'theia-ChatNode', onContextMenu: e => this.handleContextMenu(node, e) },
|
|
349
|
+
this.renderAgent(node),
|
|
350
|
+
this.renderDetail(node)));
|
|
351
|
+
}
|
|
352
|
+
renderAgent(node) {
|
|
353
|
+
var _a;
|
|
354
|
+
const inProgress = (0, exports.isResponseNode)(node) && !node.response.isComplete && !node.response.isCanceled && !node.response.isError;
|
|
355
|
+
const waitingForInput = (0, exports.isResponseNode)(node) && node.response.isWaitingForInput;
|
|
356
|
+
const toolbarContributions = !inProgress
|
|
357
|
+
? this.chatNodeToolbarActionContributions.getContributions()
|
|
358
|
+
.flatMap(c => c.getToolbarActions(node))
|
|
359
|
+
.filter(action => this.commandRegistry.isEnabled(action.commandId, node))
|
|
360
|
+
.sort((a, b) => { var _a, _b; return ((_a = a.priority) !== null && _a !== void 0 ? _a : 0) - ((_b = b.priority) !== null && _b !== void 0 ? _b : 0); })
|
|
361
|
+
: [];
|
|
362
|
+
const agentLabel = React.createRef();
|
|
363
|
+
const agentDescription = (_a = this.getAgent(node)) === null || _a === void 0 ? void 0 : _a.description;
|
|
364
|
+
return React.createElement(React.Fragment, null,
|
|
365
|
+
React.createElement("div", { className: 'theia-ChatNodeHeader' },
|
|
366
|
+
React.createElement("div", { className: `theia-AgentAvatar ${this.getAgentIconClassName(node)}` }),
|
|
367
|
+
React.createElement("h3", { ref: agentLabel, className: 'theia-AgentLabel', onMouseEnter: () => {
|
|
368
|
+
if (agentDescription) {
|
|
369
|
+
this.hoverService.requestHover({
|
|
370
|
+
content: agentDescription,
|
|
371
|
+
target: agentLabel.current,
|
|
372
|
+
position: 'right'
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
} }, this.getAgentLabel(node)),
|
|
376
|
+
inProgress && !waitingForInput && React.createElement("span", { className: 'theia-ChatContentInProgress' }, nls_1.nls.localizeByDefault('Generating')),
|
|
377
|
+
inProgress && waitingForInput && React.createElement("span", { className: 'theia-ChatContentInProgress' }, nls_1.nls.localize('theia/ai/chat-ui/chat-view-tree-widget/waitingForInput', 'Waiting for input')),
|
|
378
|
+
React.createElement("div", { className: 'theia-ChatNodeToolbar' }, !inProgress &&
|
|
379
|
+
toolbarContributions.length > 0 &&
|
|
380
|
+
toolbarContributions.map(action => React.createElement("span", { key: action.commandId, className: `theia-ChatNodeToolbarAction ${action.icon}`, title: action.tooltip, onClick: e => {
|
|
381
|
+
e.stopPropagation();
|
|
382
|
+
this.commandRegistry.executeCommand(action.commandId, node);
|
|
383
|
+
}, onKeyDown: e => {
|
|
384
|
+
if (isEnterKey(e)) {
|
|
385
|
+
e.stopPropagation();
|
|
386
|
+
this.commandRegistry.executeCommand(action.commandId, node);
|
|
387
|
+
}
|
|
388
|
+
}, role: 'button' })))));
|
|
389
|
+
}
|
|
390
|
+
getAgentLabel(node) {
|
|
391
|
+
var _a, _b;
|
|
392
|
+
if ((0, exports.isRequestNode)(node)) {
|
|
393
|
+
// TODO find user name
|
|
394
|
+
return nls_1.nls.localize('theia/ai/chat-ui/chat-view-tree-widget/you', 'You');
|
|
395
|
+
}
|
|
396
|
+
return (_b = (_a = this.getAgent(node)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : nls_1.nls.localize('theia/ai/chat-ui/chat-view-tree-widget/ai', 'AI');
|
|
397
|
+
}
|
|
398
|
+
getAgent(node) {
|
|
399
|
+
if ((0, exports.isRequestNode)(node)) {
|
|
400
|
+
return undefined;
|
|
401
|
+
}
|
|
402
|
+
return node.response.agentId ? this.chatAgentService.getAgent(node.response.agentId) : undefined;
|
|
403
|
+
}
|
|
404
|
+
getAgentIconClassName(node) {
|
|
405
|
+
var _a;
|
|
406
|
+
if ((0, exports.isRequestNode)(node)) {
|
|
407
|
+
return (0, browser_2.codicon)('account');
|
|
408
|
+
}
|
|
409
|
+
const agent = node.response.agentId ? this.chatAgentService.getAgent(node.response.agentId) : undefined;
|
|
410
|
+
return (_a = agent === null || agent === void 0 ? void 0 : agent.iconClass) !== null && _a !== void 0 ? _a : (0, browser_2.codicon)('copilot');
|
|
411
|
+
}
|
|
412
|
+
renderDetail(node) {
|
|
413
|
+
if ((0, exports.isRequestNode)(node)) {
|
|
414
|
+
return this.renderChatRequest(node);
|
|
415
|
+
}
|
|
416
|
+
if ((0, exports.isResponseNode)(node)) {
|
|
417
|
+
return this.renderChatResponse(node);
|
|
418
|
+
}
|
|
419
|
+
;
|
|
420
|
+
}
|
|
421
|
+
renderChatRequest(node) {
|
|
422
|
+
return React.createElement(ChatRequestRender, { node: node, hoverService: this.hoverService, chatAgentService: this.chatAgentService, variableService: this.variableService, openerService: this.openerService, provideChatInputWidget: () => {
|
|
423
|
+
const editableNode = node;
|
|
424
|
+
if ((0, exports.isEditableRequestNode)(editableNode)) {
|
|
425
|
+
let widget = this.chatInputs.get(editableNode.id);
|
|
426
|
+
if (!widget) {
|
|
427
|
+
widget = this.inputWidgetFactory({
|
|
428
|
+
node: editableNode,
|
|
429
|
+
initialValue: editableNode.request.message.request.text,
|
|
430
|
+
onQuery: async (query) => {
|
|
431
|
+
editableNode.request.submitEdit({ text: query });
|
|
432
|
+
},
|
|
433
|
+
branch: editableNode.branch
|
|
434
|
+
});
|
|
435
|
+
this.chatInputs.set(editableNode.id, widget);
|
|
436
|
+
widget.disposed.connect(() => {
|
|
437
|
+
this.chatInputs.delete(editableNode.id);
|
|
438
|
+
editableNode.request.cancelEdit();
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
return widget;
|
|
442
|
+
}
|
|
443
|
+
return;
|
|
444
|
+
} });
|
|
445
|
+
}
|
|
446
|
+
renderChatResponse(node) {
|
|
447
|
+
return (React.createElement("div", { className: 'theia-ResponseNode' },
|
|
448
|
+
!node.response.isComplete
|
|
449
|
+
&& node.response.response.content.length === 0
|
|
450
|
+
&& node.response.progressMessages
|
|
451
|
+
.filter(c => c.show === 'untilFirstContent')
|
|
452
|
+
.map((c, i) => React.createElement(chat_progress_message_1.ProgressMessage, { ...c, key: `${node.id}-progress-untilFirstContent-${i}` })),
|
|
453
|
+
node.response.response.content.map((c, i) => React.createElement("div", { className: 'theia-ResponseNode-Content', key: `${node.id}-content-${i}` }, this.getChatResponsePartRenderer(c, node))),
|
|
454
|
+
!node.response.isComplete
|
|
455
|
+
&& node.response.progressMessages
|
|
456
|
+
.filter(c => c.show === 'whileIncomplete')
|
|
457
|
+
.map((c, i) => React.createElement(chat_progress_message_1.ProgressMessage, { ...c, key: `${node.id}-progress-whileIncomplete-${i}` })),
|
|
458
|
+
node.response.progressMessages
|
|
459
|
+
.filter(c => c.show === 'forever')
|
|
460
|
+
.map((c, i) => React.createElement(chat_progress_message_1.ProgressMessage, { ...c, key: `${node.id}-progress-afterComplete-${i}` }))));
|
|
461
|
+
}
|
|
462
|
+
getChatResponsePartRenderer(content, node) {
|
|
463
|
+
const renderer = this.chatResponsePartRenderers.getContributions().reduce((prev, current) => {
|
|
464
|
+
const prio = current.canHandle(content);
|
|
465
|
+
if (prio > prev[0]) {
|
|
466
|
+
return [prio, current];
|
|
467
|
+
}
|
|
468
|
+
return prev;
|
|
469
|
+
}, [-1, undefined])[1];
|
|
470
|
+
if (!renderer) {
|
|
471
|
+
console.error('No renderer found for content', content);
|
|
472
|
+
return React.createElement("div", null, nls_1.nls.localize('theia/ai/chat-ui/chat-view-tree-widget/noRenderer', 'Error: No renderer found'));
|
|
473
|
+
}
|
|
474
|
+
return renderer.render(content, node);
|
|
475
|
+
}
|
|
476
|
+
handleContextMenu(node, event) {
|
|
477
|
+
this.contextMenuRenderer.render({
|
|
478
|
+
menuPath: ChatViewTreeWidget_1.CONTEXT_MENU,
|
|
479
|
+
anchor: { x: event.clientX, y: event.clientY },
|
|
480
|
+
args: [node],
|
|
481
|
+
context: event.currentTarget
|
|
482
|
+
});
|
|
483
|
+
event.preventDefault();
|
|
484
|
+
}
|
|
485
|
+
handleSpace(event) {
|
|
486
|
+
// We need to return false to prevent the handler within
|
|
487
|
+
// packages/core/src/browser/widgets/widget.ts
|
|
488
|
+
// Otherwise, the space key will never be handled by the monaco editor
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Ensure atBottom state is correct when content grows (e.g., LLM streaming while scroll lock is enabled).
|
|
493
|
+
*/
|
|
494
|
+
updateScrollToRow() {
|
|
495
|
+
super.updateScrollToRow();
|
|
496
|
+
const isAtBottom = this.isScrolledToBottom();
|
|
497
|
+
this.updateScrollToBottomButtonState(isAtBottom);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
exports.ChatViewTreeWidget = ChatViewTreeWidget;
|
|
501
|
+
ChatViewTreeWidget.ID = 'chat-tree-widget';
|
|
502
|
+
ChatViewTreeWidget.CONTEXT_MENU = ['chat-tree-context-menu'];
|
|
503
|
+
/**
|
|
504
|
+
* Debounce period in ms before showing scroll-to-bottom button after scrolling up.
|
|
505
|
+
* Avoids flickering of the button during LLM token streaming.
|
|
506
|
+
*/
|
|
507
|
+
ChatViewTreeWidget.SCROLL_BUTTON_GRACE_PERIOD = 100;
|
|
508
|
+
tslib_1.__decorate([
|
|
509
|
+
(0, inversify_1.inject)(core_1.ContributionProvider),
|
|
510
|
+
(0, inversify_1.named)(chat_response_part_renderer_1.ChatResponsePartRenderer),
|
|
511
|
+
tslib_1.__metadata("design:type", Object)
|
|
512
|
+
], ChatViewTreeWidget.prototype, "chatResponsePartRenderers", void 0);
|
|
513
|
+
tslib_1.__decorate([
|
|
514
|
+
(0, inversify_1.inject)(core_1.ContributionProvider),
|
|
515
|
+
(0, inversify_1.named)(chat_node_toolbar_action_contribution_1.ChatNodeToolbarActionContribution),
|
|
516
|
+
tslib_1.__metadata("design:type", Object)
|
|
517
|
+
], ChatViewTreeWidget.prototype, "chatNodeToolbarActionContributions", void 0);
|
|
518
|
+
tslib_1.__decorate([
|
|
519
|
+
(0, inversify_1.inject)(ai_chat_1.ChatAgentService),
|
|
520
|
+
tslib_1.__metadata("design:type", Object)
|
|
521
|
+
], ChatViewTreeWidget.prototype, "chatAgentService", void 0);
|
|
522
|
+
tslib_1.__decorate([
|
|
523
|
+
(0, inversify_1.inject)(ai_core_1.AIVariableService),
|
|
524
|
+
tslib_1.__metadata("design:type", Object)
|
|
525
|
+
], ChatViewTreeWidget.prototype, "variableService", void 0);
|
|
526
|
+
tslib_1.__decorate([
|
|
527
|
+
(0, inversify_1.inject)(core_1.CommandRegistry),
|
|
528
|
+
tslib_1.__metadata("design:type", core_1.CommandRegistry)
|
|
529
|
+
], ChatViewTreeWidget.prototype, "commandRegistry", void 0);
|
|
530
|
+
tslib_1.__decorate([
|
|
531
|
+
(0, inversify_1.inject)(browser_2.OpenerService),
|
|
532
|
+
tslib_1.__metadata("design:type", Object)
|
|
533
|
+
], ChatViewTreeWidget.prototype, "openerService", void 0);
|
|
534
|
+
tslib_1.__decorate([
|
|
535
|
+
(0, inversify_1.inject)(browser_2.HoverService),
|
|
536
|
+
tslib_1.__metadata("design:type", browser_2.HoverService)
|
|
537
|
+
], ChatViewTreeWidget.prototype, "hoverService", void 0);
|
|
538
|
+
tslib_1.__decorate([
|
|
539
|
+
(0, inversify_1.inject)(exports.ChatWelcomeMessageProvider),
|
|
540
|
+
(0, inversify_1.optional)(),
|
|
541
|
+
tslib_1.__metadata("design:type", Object)
|
|
542
|
+
], ChatViewTreeWidget.prototype, "welcomeMessageProvider", void 0);
|
|
543
|
+
tslib_1.__decorate([
|
|
544
|
+
(0, inversify_1.inject)(chat_view_tree_input_widget_1.AIChatTreeInputFactory),
|
|
545
|
+
tslib_1.__metadata("design:type", Function)
|
|
546
|
+
], ChatViewTreeWidget.prototype, "inputWidgetFactory", void 0);
|
|
547
|
+
tslib_1.__decorate([
|
|
548
|
+
(0, inversify_1.inject)(browser_1.AIActivationService),
|
|
549
|
+
tslib_1.__metadata("design:type", Object)
|
|
550
|
+
], ChatViewTreeWidget.prototype, "activationService", void 0);
|
|
551
|
+
tslib_1.__decorate([
|
|
552
|
+
(0, inversify_1.inject)(ai_chat_1.ChatService),
|
|
553
|
+
tslib_1.__metadata("design:type", Object)
|
|
554
|
+
], ChatViewTreeWidget.prototype, "chatService", void 0);
|
|
555
|
+
tslib_1.__decorate([
|
|
556
|
+
(0, inversify_1.postConstruct)(),
|
|
557
|
+
tslib_1.__metadata("design:type", Function),
|
|
558
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
559
|
+
tslib_1.__metadata("design:returntype", void 0)
|
|
560
|
+
], ChatViewTreeWidget.prototype, "init", null);
|
|
561
|
+
exports.ChatViewTreeWidget = ChatViewTreeWidget = ChatViewTreeWidget_1 = tslib_1.__decorate([
|
|
562
|
+
(0, inversify_1.injectable)(),
|
|
563
|
+
tslib_1.__param(0, (0, inversify_1.inject)(browser_2.TreeProps)),
|
|
564
|
+
tslib_1.__param(1, (0, inversify_1.inject)(browser_2.TreeModel)),
|
|
565
|
+
tslib_1.__param(2, (0, inversify_1.inject)(browser_2.ContextMenuRenderer)),
|
|
566
|
+
tslib_1.__metadata("design:paramtypes", [Object, Object, browser_2.ContextMenuRenderer])
|
|
567
|
+
], ChatViewTreeWidget);
|
|
568
|
+
const WidgetContainer = ({ widget }) => {
|
|
569
|
+
// eslint-disable-next-line no-null/no-null
|
|
570
|
+
const containerRef = React.useRef(null);
|
|
571
|
+
React.useEffect(() => {
|
|
572
|
+
if (containerRef.current && !widget.isAttached) {
|
|
573
|
+
browser_2.Widget.attach(widget, containerRef.current);
|
|
574
|
+
}
|
|
575
|
+
}, [containerRef.current]);
|
|
576
|
+
// Clean up
|
|
577
|
+
React.useEffect(() => () => {
|
|
578
|
+
setTimeout(() => {
|
|
579
|
+
// Delay clean up to allow react to finish its rendering cycle
|
|
580
|
+
widget.clearFlag(browser_2.Widget.Flag.IsAttached);
|
|
581
|
+
widget.dispose();
|
|
582
|
+
});
|
|
583
|
+
}, []);
|
|
584
|
+
return React.createElement("div", { ref: containerRef });
|
|
585
|
+
};
|
|
586
|
+
const ChatRequestRender = ({ node, hoverService, chatAgentService, variableService, openerService, provideChatInputWidget }) => {
|
|
587
|
+
const parts = node.request.message.parts;
|
|
588
|
+
if (ai_chat_1.EditableChatRequestModel.isEditing(node.request)) {
|
|
589
|
+
const widget = provideChatInputWidget();
|
|
590
|
+
if (widget) {
|
|
591
|
+
return React.createElement("div", { className: "theia-RequestNode" },
|
|
592
|
+
React.createElement(WidgetContainer, { widget: widget }));
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
const renderFooter = () => {
|
|
596
|
+
if (node.branch.items.length < 2) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
const isFirst = node.branch.activeBranchIndex === 0;
|
|
600
|
+
const isLast = node.branch.activeBranchIndex === node.branch.items.length - 1;
|
|
601
|
+
return (React.createElement("div", { className: 'theia-RequestNode-Footer' },
|
|
602
|
+
React.createElement("div", { className: `item ${isFirst ? '' : 'enabled'}` },
|
|
603
|
+
React.createElement("div", { className: "codicon codicon-chevron-left action-label", title: "Previous", onClick: () => {
|
|
604
|
+
node.branch.enablePrevious();
|
|
605
|
+
} })),
|
|
606
|
+
React.createElement("small", null,
|
|
607
|
+
React.createElement("span", null,
|
|
608
|
+
node.branch.activeBranchIndex + 1,
|
|
609
|
+
"/"),
|
|
610
|
+
React.createElement("span", null, node.branch.items.length)),
|
|
611
|
+
React.createElement("div", { className: `item ${isLast ? '' : 'enabled'}` },
|
|
612
|
+
React.createElement("div", { className: 'codicon codicon-chevron-right action-label', title: "Next", onClick: () => {
|
|
613
|
+
node.branch.enableNext();
|
|
614
|
+
} }))));
|
|
615
|
+
};
|
|
616
|
+
return (React.createElement("div", { className: "theia-RequestNode" },
|
|
617
|
+
React.createElement("p", null, parts.map((part, index) => {
|
|
618
|
+
var _a, _b;
|
|
619
|
+
if (part instanceof ai_chat_1.ParsedChatRequestAgentPart || part instanceof ai_chat_1.ParsedChatRequestVariablePart) {
|
|
620
|
+
let description = undefined;
|
|
621
|
+
let className = '';
|
|
622
|
+
if (part instanceof ai_chat_1.ParsedChatRequestAgentPart) {
|
|
623
|
+
description = (_a = chatAgentService.getAgent(part.agentId)) === null || _a === void 0 ? void 0 : _a.description;
|
|
624
|
+
className = 'theia-RequestNode-AgentLabel';
|
|
625
|
+
}
|
|
626
|
+
else if (part instanceof ai_chat_1.ParsedChatRequestVariablePart) {
|
|
627
|
+
description = (_b = variableService.getVariable(part.variableName)) === null || _b === void 0 ? void 0 : _b.description;
|
|
628
|
+
className = 'theia-RequestNode-VariableLabel';
|
|
629
|
+
}
|
|
630
|
+
return (React.createElement(HoverableLabel, { key: index, text: part.text, description: description, hoverService: hoverService, className: className }));
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
const ref = (0, markdown_part_renderer_1.useMarkdownRendering)(part.text
|
|
634
|
+
.replace(/^[\r\n]+|[\r\n]+$/g, '') // remove excessive new lines
|
|
635
|
+
.replace(/(^ )/g, ' '), // enforce keeping space before
|
|
636
|
+
openerService, true);
|
|
637
|
+
return (React.createElement("span", { key: index, ref: ref }));
|
|
638
|
+
}
|
|
639
|
+
})),
|
|
640
|
+
renderFooter()));
|
|
641
|
+
};
|
|
642
|
+
const HoverableLabel = ({ text, description, hoverService, className }) => {
|
|
643
|
+
const spanRef = React.createRef();
|
|
644
|
+
return (React.createElement("span", { className: className, ref: spanRef, onMouseEnter: () => {
|
|
645
|
+
if (description) {
|
|
646
|
+
hoverService.requestHover({
|
|
647
|
+
content: description,
|
|
648
|
+
target: spanRef.current,
|
|
649
|
+
position: 'right'
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
} }, text));
|
|
653
|
+
};
|
|
654
|
+
//# sourceMappingURL=chat-view-tree-widget.js.map
|