@jupyterlite/ai 0.9.1 → 0.10.0
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/README.md +5 -214
- package/lib/agent.d.ts +58 -66
- package/lib/agent.js +274 -300
- package/lib/approval-buttons.d.ts +19 -82
- package/lib/approval-buttons.js +36 -289
- package/lib/chat-model-registry.d.ts +6 -0
- package/lib/chat-model-registry.js +4 -1
- package/lib/chat-model.d.ts +19 -54
- package/lib/chat-model.js +243 -303
- package/lib/components/clear-button.d.ts +6 -1
- package/lib/components/clear-button.js +8 -3
- package/lib/components/completion-status.d.ts +5 -0
- package/lib/components/completion-status.js +5 -4
- package/lib/components/model-select.d.ts +6 -1
- package/lib/components/model-select.js +9 -8
- package/lib/components/stop-button.d.ts +6 -1
- package/lib/components/stop-button.js +8 -3
- package/lib/components/token-usage-display.d.ts +5 -0
- package/lib/components/token-usage-display.js +2 -2
- package/lib/components/tool-select.d.ts +6 -1
- package/lib/components/tool-select.js +6 -5
- package/lib/index.js +58 -38
- package/lib/models/settings-model.d.ts +1 -1
- package/lib/providers/built-in-providers.js +38 -19
- package/lib/providers/models.d.ts +3 -3
- package/lib/providers/provider-registry.d.ts +3 -4
- package/lib/providers/provider-registry.js +1 -4
- package/lib/tokens.d.ts +5 -6
- package/lib/tools/commands.d.ts +2 -1
- package/lib/tools/commands.js +37 -46
- package/lib/tools/file.js +49 -73
- package/lib/tools/notebook.js +370 -445
- package/lib/widgets/ai-settings.d.ts +6 -0
- package/lib/widgets/ai-settings.js +72 -71
- package/lib/widgets/main-area-chat.d.ts +2 -0
- package/lib/widgets/main-area-chat.js +5 -2
- package/lib/widgets/provider-config-dialog.d.ts +2 -0
- package/lib/widgets/provider-config-dialog.js +34 -34
- package/package.json +12 -12
- package/src/agent.ts +342 -361
- package/src/approval-buttons.ts +43 -389
- package/src/chat-model-registry.ts +9 -1
- package/src/chat-model.ts +355 -370
- package/src/completion/completion-provider.ts +2 -3
- package/src/components/clear-button.tsx +16 -3
- package/src/components/completion-status.tsx +18 -4
- package/src/components/model-select.tsx +21 -8
- package/src/components/stop-button.tsx +16 -3
- package/src/components/token-usage-display.tsx +14 -2
- package/src/components/tool-select.tsx +23 -5
- package/src/index.ts +75 -36
- package/src/models/settings-model.ts +1 -1
- package/src/providers/built-in-providers.ts +38 -19
- package/src/providers/models.ts +3 -3
- package/src/providers/provider-registry.ts +4 -8
- package/src/tokens.ts +5 -6
- package/src/tools/commands.ts +39 -50
- package/src/tools/file.ts +49 -75
- package/src/tools/notebook.ts +451 -510
- package/src/widgets/ai-settings.tsx +153 -84
- package/src/widgets/main-area-chat.ts +8 -2
- package/src/widgets/provider-config-dialog.tsx +54 -41
- package/style/base.css +13 -73
- package/lib/mcp/browser.d.ts +0 -68
- package/lib/mcp/browser.js +0 -138
- package/src/mcp/browser.ts +0 -220
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ChatWidget } from '@jupyter/chat';
|
|
2
2
|
import { IDisposable } from '@lumino/disposable';
|
|
3
|
+
import type { AgentManager } from './agent';
|
|
4
|
+
/**
|
|
5
|
+
* Handles click events for approval buttons in the chat panel.
|
|
6
|
+
*/
|
|
3
7
|
export declare class ApprovalButtons implements IDisposable {
|
|
4
8
|
constructor(options: ApprovalButtons.IOptions);
|
|
5
9
|
get isDisposed(): boolean;
|
|
@@ -8,105 +12,38 @@ export declare class ApprovalButtons implements IDisposable {
|
|
|
8
12
|
*/
|
|
9
13
|
dispose(): void;
|
|
10
14
|
/**
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
private _setupApprovalHandlers;
|
|
14
|
-
/**
|
|
15
|
-
* Adds click event handler to an approval button.
|
|
16
|
-
*
|
|
17
|
-
* @param button - The button element to add handler to
|
|
18
|
-
*/
|
|
19
|
-
private _addButtonHandler;
|
|
20
|
-
/**
|
|
21
|
-
* Handles click events for individual approval buttons.
|
|
22
|
-
*
|
|
23
|
-
* @param event - The click event
|
|
24
|
-
*/
|
|
25
|
-
private _handleButtonClick;
|
|
26
|
-
/**
|
|
27
|
-
* Adds click event handler to a grouped approval button.
|
|
28
|
-
*
|
|
29
|
-
* @param button - The button element to add handler to
|
|
30
|
-
*/
|
|
31
|
-
private _addGroupedButtonHandler;
|
|
32
|
-
/**
|
|
33
|
-
* Handles click events for grouped approval buttons.
|
|
34
|
-
*
|
|
35
|
-
* @param event - The click event
|
|
36
|
-
*/
|
|
37
|
-
private _handleGroupedButtonClick;
|
|
38
|
-
/**
|
|
39
|
-
* Shows approval status by replacing buttons with status indicator.
|
|
40
|
-
*
|
|
41
|
-
* @param buttonsContainer - The container element holding the buttons
|
|
42
|
-
* @param isApprove - Whether the action was approval or rejection
|
|
15
|
+
* Handles click events using event delegation.
|
|
16
|
+
* Detects clicks on approval buttons and calls the appropriate handler.
|
|
43
17
|
*/
|
|
44
|
-
private
|
|
18
|
+
private _handleClick;
|
|
45
19
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* @param buttonsContainer - The container element holding the buttons
|
|
49
|
-
* @param isApprove - Whether the action was approval or rejection
|
|
50
|
-
* @param toolCount - The number of tools that were approved/rejected
|
|
20
|
+
* Handles approval/rejection of a tool call.
|
|
51
21
|
*/
|
|
52
|
-
private
|
|
22
|
+
private _handleApproval;
|
|
53
23
|
/**
|
|
54
|
-
*
|
|
24
|
+
* Extracts the approval ID from an element's class list.
|
|
25
|
+
* The ID is encoded in a class name like "jp-ai-approval-id--{id}".
|
|
55
26
|
*/
|
|
56
|
-
private
|
|
57
|
-
/**
|
|
58
|
-
* Processes text nodes to replace approval button placeholders with actual button elements.
|
|
59
|
-
*
|
|
60
|
-
* @param element - The element to search for approval button placeholders
|
|
61
|
-
*/
|
|
62
|
-
private _processApprovalButtons;
|
|
63
|
-
/**
|
|
64
|
-
* Creates an approval button element with appropriate styling and classes.
|
|
65
|
-
*
|
|
66
|
-
* @param text - The button text
|
|
67
|
-
* @param isApprove - Whether this is an approve or reject button
|
|
68
|
-
* @param additionalClasses - Additional CSS classes to add
|
|
69
|
-
* @returns The created button element
|
|
70
|
-
*/
|
|
71
|
-
private _createApprovalButton;
|
|
72
|
-
/**
|
|
73
|
-
* Creates and inserts approval buttons for a single tool call.
|
|
74
|
-
*
|
|
75
|
-
* @param textNode - The text node to replace with buttons
|
|
76
|
-
* @param interruptionId - The interruption ID for the tool call
|
|
77
|
-
*/
|
|
78
|
-
private _createSingleApprovalButtons;
|
|
79
|
-
/**
|
|
80
|
-
* Creates and inserts approval buttons for grouped tool calls.
|
|
81
|
-
*
|
|
82
|
-
* @param textNode - The text node to replace with buttons
|
|
83
|
-
* @param groupId - The group ID for the tool calls
|
|
84
|
-
* @param interruptionIds - Comma-separated interruption IDs
|
|
85
|
-
*/
|
|
86
|
-
private _createGroupedApprovalButtons;
|
|
87
|
-
/**
|
|
88
|
-
* Finds the message ID by traversing up the DOM tree from a text node.
|
|
89
|
-
*
|
|
90
|
-
* @param textNode - The text node to start searching from
|
|
91
|
-
* @returns The message ID if found, null otherwise
|
|
92
|
-
*/
|
|
93
|
-
private _findMessageId;
|
|
27
|
+
private _extractApprovalId;
|
|
94
28
|
private _chatPanel;
|
|
95
|
-
private _chatModel;
|
|
96
29
|
private _isDisposed;
|
|
97
|
-
private
|
|
30
|
+
private _agentManager;
|
|
98
31
|
}
|
|
99
32
|
/**
|
|
100
|
-
* Namespace for
|
|
33
|
+
* Namespace for ApprovalButtons statics.
|
|
101
34
|
*/
|
|
102
35
|
export declare namespace ApprovalButtons {
|
|
103
36
|
/**
|
|
104
|
-
* The options for the constructor of the
|
|
37
|
+
* The options for the constructor of the approval buttons.
|
|
105
38
|
*/
|
|
106
39
|
interface IOptions {
|
|
107
40
|
/**
|
|
108
41
|
* The chat panel widget to wrap.
|
|
109
42
|
*/
|
|
110
43
|
chatPanel: ChatWidget;
|
|
44
|
+
/**
|
|
45
|
+
* The agent manager for handling approvals.
|
|
46
|
+
*/
|
|
47
|
+
agentManager: AgentManager;
|
|
111
48
|
}
|
|
112
49
|
}
|
package/lib/approval-buttons.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles click events for approval buttons in the chat panel.
|
|
3
|
+
*/
|
|
1
4
|
export class ApprovalButtons {
|
|
2
5
|
constructor(options) {
|
|
3
6
|
this._chatPanel = options.chatPanel;
|
|
4
|
-
this.
|
|
5
|
-
|
|
6
|
-
this._setupApprovalHandlers();
|
|
7
|
-
// Set up message processing for approval buttons
|
|
8
|
-
this._setupMessageProcessing();
|
|
7
|
+
this._agentManager = options.agentManager;
|
|
8
|
+
this._chatPanel.node.addEventListener('click', this._handleClick);
|
|
9
9
|
}
|
|
10
10
|
get isDisposed() {
|
|
11
11
|
return this._isDisposed;
|
|
@@ -18,315 +18,62 @@ export class ApprovalButtons {
|
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
this._isDisposed = true;
|
|
21
|
-
|
|
22
|
-
if (this._mutationObserver) {
|
|
23
|
-
this._mutationObserver.disconnect();
|
|
24
|
-
this._mutationObserver = undefined;
|
|
25
|
-
}
|
|
26
|
-
// Remove all listener on existing buttons.
|
|
27
|
-
const existingButtons = this._chatPanel.node.querySelectorAll('.jp-ai-approval-btn');
|
|
28
|
-
existingButtons.forEach(button => {
|
|
29
|
-
button.removeEventListener('click', this._handleButtonClick);
|
|
30
|
-
});
|
|
31
|
-
const existingGroupButtons = this._chatPanel.node.querySelectorAll('.jp-ai-group-approval-buttons button');
|
|
32
|
-
existingGroupButtons.forEach(button => {
|
|
33
|
-
button.removeEventListener('click', this._handleGroupedButtonClick);
|
|
34
|
-
});
|
|
35
|
-
// Clean the references.
|
|
36
|
-
this._chatModel = null;
|
|
21
|
+
this._chatPanel.node.removeEventListener('click', this._handleClick);
|
|
37
22
|
this._chatPanel = null;
|
|
38
23
|
}
|
|
39
24
|
/**
|
|
40
|
-
*
|
|
41
|
-
|
|
42
|
-
_setupApprovalHandlers() {
|
|
43
|
-
// This method will be called to add handlers to existing buttons
|
|
44
|
-
// New buttons get handlers added in _processApprovalButtons
|
|
45
|
-
const existingButtons = this._chatPanel.node.querySelectorAll('.jp-ai-approval-btn');
|
|
46
|
-
existingButtons.forEach(button => {
|
|
47
|
-
this._addButtonHandler(button);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Adds click event handler to an approval button.
|
|
52
|
-
*
|
|
53
|
-
* @param button - The button element to add handler to
|
|
54
|
-
*/
|
|
55
|
-
_addButtonHandler(button) {
|
|
56
|
-
// Remove any existing listeners to avoid duplicates
|
|
57
|
-
button.removeEventListener('click', this._handleButtonClick);
|
|
58
|
-
button.addEventListener('click', this._handleButtonClick);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Handles click events for individual approval buttons.
|
|
62
|
-
*
|
|
63
|
-
* @param event - The click event
|
|
25
|
+
* Handles click events using event delegation.
|
|
26
|
+
* Detects clicks on approval buttons and calls the appropriate handler.
|
|
64
27
|
*/
|
|
65
|
-
|
|
28
|
+
_handleClick = (event) => {
|
|
66
29
|
const target = event.target;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const buttonsContainer = target.closest('.jp-ai-tool-approval-buttons');
|
|
70
|
-
if (!buttonsContainer) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
const interruptionId = buttonsContainer.getAttribute('data-interruption-id');
|
|
74
|
-
if (!interruptionId) {
|
|
30
|
+
// Check if the click target is an approval button
|
|
31
|
+
if (!target.classList.contains('jp-ai-approval-btn')) {
|
|
75
32
|
return;
|
|
76
33
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// Hide buttons immediately and show status
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
event.stopPropagation();
|
|
80
36
|
const isApprove = target.classList.contains('jp-ai-approval-approve');
|
|
81
|
-
this.
|
|
82
|
-
if (isApprove) {
|
|
83
|
-
// Execute approval with message ID for updating the tool call box
|
|
84
|
-
await this._chatModel.approveToolCall(interruptionId, messageId || undefined);
|
|
85
|
-
}
|
|
86
|
-
else if (target.classList.contains('jp-ai-approval-reject')) {
|
|
87
|
-
// Execute rejection with message ID for updating the tool call box
|
|
88
|
-
await this._chatModel.rejectToolCall(interruptionId, messageId || undefined);
|
|
89
|
-
}
|
|
37
|
+
this._handleApproval(target, isApprove);
|
|
90
38
|
};
|
|
91
39
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* @param button - The button element to add handler to
|
|
40
|
+
* Handles approval/rejection of a tool call.
|
|
95
41
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
button.addEventListener('click', this._handleGroupedButtonClick);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Handles click events for grouped approval buttons.
|
|
103
|
-
*
|
|
104
|
-
* @param event - The click event
|
|
105
|
-
*/
|
|
106
|
-
_handleGroupedButtonClick = async (event) => {
|
|
107
|
-
const target = event.target;
|
|
108
|
-
event.preventDefault();
|
|
109
|
-
event.stopPropagation();
|
|
110
|
-
const buttonsContainer = target.closest('.jp-ai-group-approval-buttons');
|
|
111
|
-
if (!buttonsContainer) {
|
|
42
|
+
_handleApproval(target, isApprove) {
|
|
43
|
+
const container = target.closest('.jp-ai-tool-approval-buttons');
|
|
44
|
+
if (!container) {
|
|
112
45
|
return;
|
|
113
46
|
}
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
if (!
|
|
47
|
+
// Extract approval ID from class name (encoded as jp-ai-approval-id--{id})
|
|
48
|
+
const approvalId = this._extractApprovalId(container);
|
|
49
|
+
if (!approvalId) {
|
|
50
|
+
console.warn('No approval ID found for button');
|
|
117
51
|
return;
|
|
118
52
|
}
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
const isApprove = target.classList.contains('jp-ai-group-approve-all');
|
|
123
|
-
this._showGroupApprovalStatus(buttonsContainer, isApprove);
|
|
53
|
+
// Disable buttons to prevent double-clicks
|
|
54
|
+
const buttons = container.querySelectorAll('button');
|
|
55
|
+
buttons.forEach(btn => btn.setAttribute('disabled', 'true'));
|
|
124
56
|
if (isApprove) {
|
|
125
|
-
|
|
126
|
-
await this._chatModel.approveGroupedToolCalls(groupId, interruptionIds, messageId || undefined);
|
|
127
|
-
}
|
|
128
|
-
else if (target.classList.contains('jp-ai-group-reject-all')) {
|
|
129
|
-
// Execute grouped rejection
|
|
130
|
-
await this._chatModel.rejectGroupedToolCalls(groupId, interruptionIds, messageId || undefined);
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
/**
|
|
134
|
-
* Shows approval status by replacing buttons with status indicator.
|
|
135
|
-
*
|
|
136
|
-
* @param buttonsContainer - The container element holding the buttons
|
|
137
|
-
* @param isApprove - Whether the action was approval or rejection
|
|
138
|
-
*/
|
|
139
|
-
_showApprovalStatus(buttonsContainer, isApprove) {
|
|
140
|
-
// Clear the container and add status indicator
|
|
141
|
-
buttonsContainer.innerHTML = '';
|
|
142
|
-
const statusDiv = document.createElement('div');
|
|
143
|
-
statusDiv.className = `jp-ai-approval-status ${isApprove ? 'jp-ai-approval-status-approved' : 'jp-ai-approval-status-rejected'}`;
|
|
144
|
-
const icon = document.createElement('span');
|
|
145
|
-
icon.className = 'jp-ai-approval-icon';
|
|
146
|
-
icon.textContent = isApprove ? '✅' : '❌';
|
|
147
|
-
const text = document.createElement('span');
|
|
148
|
-
text.textContent = isApprove ? 'Tools approved' : 'Tools rejected';
|
|
149
|
-
statusDiv.appendChild(icon);
|
|
150
|
-
statusDiv.appendChild(text);
|
|
151
|
-
buttonsContainer.appendChild(statusDiv);
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Shows group approval status by replacing buttons with status indicator.
|
|
155
|
-
*
|
|
156
|
-
* @param buttonsContainer - The container element holding the buttons
|
|
157
|
-
* @param isApprove - Whether the action was approval or rejection
|
|
158
|
-
* @param toolCount - The number of tools that were approved/rejected
|
|
159
|
-
*/
|
|
160
|
-
_showGroupApprovalStatus(buttonsContainer, isApprove) {
|
|
161
|
-
// Clear the container and add status indicator
|
|
162
|
-
buttonsContainer.innerHTML = '';
|
|
163
|
-
const statusDiv = document.createElement('div');
|
|
164
|
-
statusDiv.className = `jp-ai-group-approval-status ${isApprove ? 'jp-ai-group-approval-status-approved' : 'jp-ai-group-approval-status-rejected'}`;
|
|
165
|
-
const icon = document.createElement('span');
|
|
166
|
-
icon.className = 'jp-ai-approval-icon';
|
|
167
|
-
icon.textContent = isApprove ? '✅' : '❌';
|
|
168
|
-
const text = document.createElement('span');
|
|
169
|
-
text.textContent = isApprove ? 'Tools approved' : 'Tools rejected';
|
|
170
|
-
statusDiv.appendChild(icon);
|
|
171
|
-
statusDiv.appendChild(text);
|
|
172
|
-
buttonsContainer.appendChild(statusDiv);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Sets up mutation observer to watch for new messages and process approval buttons.
|
|
176
|
-
*/
|
|
177
|
-
_setupMessageProcessing() {
|
|
178
|
-
// Use a MutationObserver to watch for new messages and process approval buttons
|
|
179
|
-
this._mutationObserver = new MutationObserver(mutations => {
|
|
180
|
-
if (this._isDisposed) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
mutations.forEach(mutation => {
|
|
184
|
-
mutation.addedNodes.forEach(node => {
|
|
185
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
186
|
-
const element = node;
|
|
187
|
-
this._processApprovalButtons(element);
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
this._mutationObserver.observe(this._chatPanel.node, {
|
|
193
|
-
childList: true,
|
|
194
|
-
subtree: true
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Processes text nodes to replace approval button placeholders with actual button elements.
|
|
199
|
-
*
|
|
200
|
-
* @param element - The element to search for approval button placeholders
|
|
201
|
-
*/
|
|
202
|
-
_processApprovalButtons(element) {
|
|
203
|
-
// Find all text nodes that contain approval buttons and replace them with actual buttons
|
|
204
|
-
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null);
|
|
205
|
-
const textNodes = [];
|
|
206
|
-
let node;
|
|
207
|
-
while ((node = walker.nextNode())) {
|
|
208
|
-
textNodes.push(node);
|
|
209
|
-
}
|
|
210
|
-
textNodes.forEach(textNode => {
|
|
211
|
-
const text = textNode.textContent || '';
|
|
212
|
-
// Handle single tool approval buttons [APPROVAL_BUTTONS:id]
|
|
213
|
-
const singleMatch = text.match(/\[APPROVAL_BUTTONS:([^\]]+)\]/);
|
|
214
|
-
if (singleMatch) {
|
|
215
|
-
this._createSingleApprovalButtons(textNode, singleMatch[1]);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
// Handle grouped tool approval buttons [GROUP_APPROVAL_BUTTONS:groupId:id1,id2,id3]
|
|
219
|
-
const groupMatch = text.match(/\[GROUP_APPROVAL_BUTTONS:([^:]+):([^\]]+)\]/);
|
|
220
|
-
if (groupMatch) {
|
|
221
|
-
this._createGroupedApprovalButtons(textNode, groupMatch[1], groupMatch[2]);
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Creates an approval button element with appropriate styling and classes.
|
|
228
|
-
*
|
|
229
|
-
* @param text - The button text
|
|
230
|
-
* @param isApprove - Whether this is an approve or reject button
|
|
231
|
-
* @param additionalClasses - Additional CSS classes to add
|
|
232
|
-
* @returns The created button element
|
|
233
|
-
*/
|
|
234
|
-
_createApprovalButton(text, isApprove, additionalClasses = '') {
|
|
235
|
-
const button = document.createElement('button');
|
|
236
|
-
const baseClass = isApprove
|
|
237
|
-
? 'jp-ai-approval-approve'
|
|
238
|
-
: 'jp-ai-approval-reject';
|
|
239
|
-
button.className = `jp-ai-approval-btn ${baseClass}${additionalClasses ? ' ' + additionalClasses : ''}`;
|
|
240
|
-
button.textContent = text;
|
|
241
|
-
return button;
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Creates and inserts approval buttons for a single tool call.
|
|
245
|
-
*
|
|
246
|
-
* @param textNode - The text node to replace with buttons
|
|
247
|
-
* @param interruptionId - The interruption ID for the tool call
|
|
248
|
-
*/
|
|
249
|
-
_createSingleApprovalButtons(textNode, interruptionId) {
|
|
250
|
-
// Create approval buttons for single tool
|
|
251
|
-
const buttonContainer = document.createElement('div');
|
|
252
|
-
buttonContainer.className = 'jp-ai-tool-approval-buttons';
|
|
253
|
-
buttonContainer.setAttribute('data-interruption-id', interruptionId);
|
|
254
|
-
// Try to find the message ID from the closest message container
|
|
255
|
-
const messageId = this._findMessageId(textNode);
|
|
256
|
-
if (messageId) {
|
|
257
|
-
buttonContainer.setAttribute('data-message-id', messageId);
|
|
258
|
-
}
|
|
259
|
-
const approveBtn = this._createApprovalButton('Approve', true);
|
|
260
|
-
const rejectBtn = this._createApprovalButton('Reject', false);
|
|
261
|
-
// Add click handlers directly to the buttons
|
|
262
|
-
this._addButtonHandler(approveBtn);
|
|
263
|
-
this._addButtonHandler(rejectBtn);
|
|
264
|
-
buttonContainer.appendChild(approveBtn);
|
|
265
|
-
buttonContainer.appendChild(rejectBtn);
|
|
266
|
-
// Replace the text node with the button container
|
|
267
|
-
const parent = textNode.parentNode;
|
|
268
|
-
if (parent) {
|
|
269
|
-
parent.replaceChild(buttonContainer, textNode);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Creates and inserts approval buttons for grouped tool calls.
|
|
274
|
-
*
|
|
275
|
-
* @param textNode - The text node to replace with buttons
|
|
276
|
-
* @param groupId - The group ID for the tool calls
|
|
277
|
-
* @param interruptionIds - Comma-separated interruption IDs
|
|
278
|
-
*/
|
|
279
|
-
_createGroupedApprovalButtons(textNode, groupId, interruptionIds) {
|
|
280
|
-
// Create approval buttons for grouped tools
|
|
281
|
-
const buttonContainer = document.createElement('div');
|
|
282
|
-
buttonContainer.className = 'jp-ai-group-approval-buttons';
|
|
283
|
-
buttonContainer.setAttribute('data-group-id', groupId);
|
|
284
|
-
buttonContainer.setAttribute('data-interruption-ids', interruptionIds);
|
|
285
|
-
// Try to find the message ID from the closest message container
|
|
286
|
-
const messageId = this._findMessageId(textNode);
|
|
287
|
-
if (messageId) {
|
|
288
|
-
buttonContainer.setAttribute('data-message-id', messageId);
|
|
57
|
+
this._agentManager.approveToolCall(approvalId);
|
|
289
58
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// Add click handlers for grouped approvals
|
|
293
|
-
this._addGroupedButtonHandler(approveBtn);
|
|
294
|
-
this._addGroupedButtonHandler(rejectBtn);
|
|
295
|
-
buttonContainer.appendChild(approveBtn);
|
|
296
|
-
buttonContainer.appendChild(rejectBtn);
|
|
297
|
-
// Replace the text node with the button container
|
|
298
|
-
const parent = textNode.parentNode;
|
|
299
|
-
if (parent) {
|
|
300
|
-
parent.replaceChild(buttonContainer, textNode);
|
|
59
|
+
else {
|
|
60
|
+
this._agentManager.rejectToolCall(approvalId);
|
|
301
61
|
}
|
|
302
62
|
}
|
|
303
63
|
/**
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
* @param textNode - The text node to start searching from
|
|
307
|
-
* @returns The message ID if found, null otherwise
|
|
64
|
+
* Extracts the approval ID from an element's class list.
|
|
65
|
+
* The ID is encoded in a class name like "jp-ai-approval-id--{id}".
|
|
308
66
|
*/
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (
|
|
313
|
-
|
|
314
|
-
// Look for common message container attributes or classes
|
|
315
|
-
const messageId = element.getAttribute('data-message-id') ||
|
|
316
|
-
element.getAttribute('id') ||
|
|
317
|
-
element
|
|
318
|
-
.querySelector('[data-message-id]')
|
|
319
|
-
?.getAttribute('data-message-id');
|
|
320
|
-
if (messageId) {
|
|
321
|
-
return messageId;
|
|
322
|
-
}
|
|
67
|
+
_extractApprovalId(element) {
|
|
68
|
+
const prefix = 'jp-ai-approval-id--';
|
|
69
|
+
for (const className of element.classList) {
|
|
70
|
+
if (className.startsWith(prefix)) {
|
|
71
|
+
return className.slice(prefix.length);
|
|
323
72
|
}
|
|
324
|
-
messageElement = messageElement.parentNode;
|
|
325
73
|
}
|
|
326
74
|
return null;
|
|
327
75
|
}
|
|
328
76
|
_chatPanel;
|
|
329
|
-
_chatModel;
|
|
330
77
|
_isDisposed = false;
|
|
331
|
-
|
|
78
|
+
_agentManager;
|
|
332
79
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ActiveCellManager } from '@jupyter/chat';
|
|
2
|
+
import { TranslationBundle } from '@jupyterlab/translation';
|
|
2
3
|
import { AgentManagerFactory } from './agent';
|
|
3
4
|
import { AIChatModel } from './chat-model';
|
|
4
5
|
import { AISettingsModel } from './models/settings-model';
|
|
@@ -21,6 +22,7 @@ export declare class ChatModelRegistry implements IChatModelRegistry {
|
|
|
21
22
|
private _toolRegistry?;
|
|
22
23
|
private _providerRegistry?;
|
|
23
24
|
private _activeCellManager?;
|
|
25
|
+
private _trans;
|
|
24
26
|
}
|
|
25
27
|
export declare namespace ChatModelRegistry {
|
|
26
28
|
interface IOptions {
|
|
@@ -48,5 +50,9 @@ export declare namespace ChatModelRegistry {
|
|
|
48
50
|
* The active cell manager.
|
|
49
51
|
*/
|
|
50
52
|
activeCellManager: ActiveCellManager | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* The application language translation bundle.
|
|
55
|
+
*/
|
|
56
|
+
trans: TranslationBundle;
|
|
51
57
|
}
|
|
52
58
|
}
|
|
@@ -11,6 +11,7 @@ export class ChatModelRegistry {
|
|
|
11
11
|
this._toolRegistry = options.toolRegistry;
|
|
12
12
|
this._providerRegistry = options.providerRegistry;
|
|
13
13
|
this._activeCellManager = options.activeCellManager;
|
|
14
|
+
this._trans = options.trans;
|
|
14
15
|
}
|
|
15
16
|
createModel(name, activeProvider, tokenUsage) {
|
|
16
17
|
// Create Agent Manager first so it can be shared
|
|
@@ -27,7 +28,8 @@ export class ChatModelRegistry {
|
|
|
27
28
|
settingsModel: this._settingsModel,
|
|
28
29
|
agentManager,
|
|
29
30
|
activeCellManager: this._activeCellManager,
|
|
30
|
-
documentManager: this._docManager
|
|
31
|
+
documentManager: this._docManager,
|
|
32
|
+
trans: this._trans
|
|
31
33
|
});
|
|
32
34
|
// Set the name of the chat if not provided.
|
|
33
35
|
// The name will be the name set by the user to the model if not already used by
|
|
@@ -71,4 +73,5 @@ export class ChatModelRegistry {
|
|
|
71
73
|
_toolRegistry;
|
|
72
74
|
_providerRegistry;
|
|
73
75
|
_activeCellManager;
|
|
76
|
+
_trans;
|
|
74
77
|
}
|
package/lib/chat-model.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { AbstractChatModel, IActiveCellManager, IChatContext, INewMessage, IUser } from '@jupyter/chat';
|
|
2
2
|
import { IDocumentManager } from '@jupyterlab/docmanager';
|
|
3
|
+
import { TranslationBundle } from '@jupyterlab/translation';
|
|
3
4
|
import { ISignal } from '@lumino/signaling';
|
|
4
5
|
import { AgentManager } from './agent';
|
|
5
6
|
import { AISettingsModel } from './models/settings-model';
|
|
6
7
|
import { ITokenUsage } from './tokens';
|
|
7
8
|
/**
|
|
8
|
-
* AI Chat Model implementation that provides chat functionality
|
|
9
|
-
*
|
|
10
|
-
* Extends the base AbstractChatModel to provide AI-powered conversations.
|
|
9
|
+
* AI Chat Model implementation that provides chat functionality tool integration,
|
|
10
|
+
* and MCP server support.
|
|
11
11
|
*/
|
|
12
12
|
export declare class AIChatModel extends AbstractChatModel {
|
|
13
13
|
/**
|
|
@@ -53,32 +53,6 @@ export declare class AIChatModel extends AbstractChatModel {
|
|
|
53
53
|
* @param message The user message to send
|
|
54
54
|
*/
|
|
55
55
|
sendMessage(message: INewMessage): Promise<void>;
|
|
56
|
-
/**
|
|
57
|
-
* Approves a tool call and updates the UI accordingly.
|
|
58
|
-
* @param interruptionId The interruption ID to approve
|
|
59
|
-
* @param messageId Optional message ID for UI updates
|
|
60
|
-
*/
|
|
61
|
-
approveToolCall(interruptionId: string, messageId?: string): Promise<void>;
|
|
62
|
-
/**
|
|
63
|
-
* Rejects a tool call and updates the UI accordingly.
|
|
64
|
-
* @param interruptionId The interruption ID to reject
|
|
65
|
-
* @param messageId Optional message ID for UI updates
|
|
66
|
-
*/
|
|
67
|
-
rejectToolCall(interruptionId: string, messageId?: string): Promise<void>;
|
|
68
|
-
/**
|
|
69
|
-
* Approves all tools in a group.
|
|
70
|
-
* @param groupId The group ID containing the tool calls
|
|
71
|
-
* @param interruptionIds Array of interruption IDs to approve
|
|
72
|
-
* @param messageId Optional message ID for UI updates
|
|
73
|
-
*/
|
|
74
|
-
approveGroupedToolCalls(groupId: string, interruptionIds: string[], messageId?: string): Promise<void>;
|
|
75
|
-
/**
|
|
76
|
-
* Rejects all tools in a group.
|
|
77
|
-
* @param groupId The group ID containing the tool calls
|
|
78
|
-
* @param interruptionIds Array of interruption IDs to reject
|
|
79
|
-
* @param messageId Optional message ID for UI updates
|
|
80
|
-
*/
|
|
81
|
-
rejectGroupedToolCalls(groupId: string, interruptionIds: string[], messageId?: string): Promise<void>;
|
|
82
56
|
/**
|
|
83
57
|
* Gets the AI user information for system messages.
|
|
84
58
|
*/
|
|
@@ -114,24 +88,24 @@ export declare class AIChatModel extends AbstractChatModel {
|
|
|
114
88
|
private _handleToolCallStartEvent;
|
|
115
89
|
/**
|
|
116
90
|
* Handles the completion of a tool call execution.
|
|
117
|
-
* @param event Event containing the tool call completion data
|
|
118
91
|
*/
|
|
119
92
|
private _handleToolCallCompleteEvent;
|
|
120
93
|
/**
|
|
121
|
-
* Handles
|
|
122
|
-
|
|
94
|
+
* Handles error events from the AI agent.
|
|
95
|
+
*/
|
|
96
|
+
private _handleErrorEvent;
|
|
97
|
+
/**
|
|
98
|
+
* Handles tool approval request events from the AI agent.
|
|
123
99
|
*/
|
|
124
|
-
private
|
|
100
|
+
private _handleToolApprovalRequest;
|
|
125
101
|
/**
|
|
126
|
-
* Handles
|
|
127
|
-
* @param event Event containing the grouped tool approval request data
|
|
102
|
+
* Handles tool approval resolved events from the AI agent.
|
|
128
103
|
*/
|
|
129
|
-
private
|
|
104
|
+
private _handleToolApprovalResolved;
|
|
130
105
|
/**
|
|
131
|
-
*
|
|
132
|
-
* @param event Event containing the error information
|
|
106
|
+
* Updates a tool call's UI with new status and optional output.
|
|
133
107
|
*/
|
|
134
|
-
private
|
|
108
|
+
private _updateToolCallUI;
|
|
135
109
|
/**
|
|
136
110
|
* Processes file attachments and returns their content as formatted strings.
|
|
137
111
|
* @param attachments Array of file attachments to process
|
|
@@ -150,26 +124,13 @@ export declare class AIChatModel extends AbstractChatModel {
|
|
|
150
124
|
* @returns File content as string or null if unable to read
|
|
151
125
|
*/
|
|
152
126
|
private _readFileAttachment;
|
|
153
|
-
/**
|
|
154
|
-
* Updates the status display of a grouped approval message.
|
|
155
|
-
* @param messageId The message ID to update
|
|
156
|
-
* @param status The status text to display
|
|
157
|
-
* @param isSuccess Whether the action was successful
|
|
158
|
-
*/
|
|
159
|
-
private _updateGroupedApprovalStatus;
|
|
160
|
-
/**
|
|
161
|
-
* Updates the status display of a tool call box.
|
|
162
|
-
* @param messageId The message ID to update
|
|
163
|
-
* @param status The status text to display
|
|
164
|
-
* @param isSuccess Whether the action was successful
|
|
165
|
-
*/
|
|
166
|
-
private _updateToolCallBoxStatus;
|
|
167
127
|
private _settingsModel;
|
|
168
128
|
private _user;
|
|
169
|
-
private
|
|
129
|
+
private _toolContexts;
|
|
170
130
|
private _agentManager;
|
|
171
131
|
private _currentStreamingMessage;
|
|
172
132
|
private _nameChanged;
|
|
133
|
+
private _trans;
|
|
173
134
|
}
|
|
174
135
|
/**
|
|
175
136
|
* Namespace containing types and interfaces for AIChatModel.
|
|
@@ -199,6 +160,10 @@ export declare namespace AIChatModel {
|
|
|
199
160
|
* Optional document manager for file operations
|
|
200
161
|
*/
|
|
201
162
|
documentManager?: IDocumentManager;
|
|
163
|
+
/**
|
|
164
|
+
* The application language translation bundle.
|
|
165
|
+
*/
|
|
166
|
+
trans: TranslationBundle;
|
|
202
167
|
}
|
|
203
168
|
/**
|
|
204
169
|
* The chat context for toolbar buttons.
|