@jupyterlite/ai 0.16.0 → 0.18.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.
Files changed (40) hide show
  1. package/lib/agent.d.ts +19 -10
  2. package/lib/agent.js +82 -46
  3. package/lib/chat-commands/clear.js +1 -1
  4. package/lib/chat-model-handler.d.ts +2 -3
  5. package/lib/chat-model-handler.js +6 -2
  6. package/lib/chat-model.d.ts +129 -26
  7. package/lib/chat-model.js +543 -160
  8. package/lib/components/clear-button.d.ts +1 -1
  9. package/lib/components/clear-button.js +1 -1
  10. package/lib/components/save-button.d.ts +2 -2
  11. package/lib/index.js +224 -59
  12. package/lib/models/settings-model.js +1 -0
  13. package/lib/providers/built-in-providers.js +1 -1
  14. package/lib/providers/{generated-context-windows.d.ts → generated-model-info.d.ts} +2 -2
  15. package/lib/providers/generated-model-info.js +502 -0
  16. package/lib/providers/model-info.d.ts +3 -0
  17. package/lib/providers/model-info.js +33 -0
  18. package/lib/tokens.d.ts +98 -15
  19. package/lib/tokens.js +1 -0
  20. package/lib/widgets/ai-settings.js +5 -0
  21. package/lib/widgets/main-area-chat.d.ts +3 -3
  22. package/lib/widgets/main-area-chat.js +9 -5
  23. package/package.json +3 -3
  24. package/schema/settings-model.json +6 -0
  25. package/src/agent.ts +100 -52
  26. package/src/chat-commands/clear.ts +1 -1
  27. package/src/chat-model-handler.ts +10 -3
  28. package/src/chat-model.ts +727 -210
  29. package/src/components/clear-button.tsx +3 -3
  30. package/src/components/save-button.tsx +3 -3
  31. package/src/index.ts +289 -83
  32. package/src/models/settings-model.ts +1 -0
  33. package/src/providers/built-in-providers.ts +1 -1
  34. package/src/providers/generated-model-info.ts +508 -0
  35. package/src/providers/model-info.ts +57 -0
  36. package/src/tokens.ts +100 -15
  37. package/src/widgets/ai-settings.tsx +26 -0
  38. package/src/widgets/main-area-chat.ts +14 -9
  39. package/lib/providers/generated-context-windows.js +0 -96
  40. package/src/providers/generated-context-windows.ts +0 -102
package/lib/agent.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { IMessageContent } from '@jupyter/chat';
2
1
  import { ISignal } from '@lumino/signaling';
2
+ import { type ModelMessage, type UserContent } from 'ai';
3
3
  import { ISecretsManager } from 'jupyter-secrets-manager';
4
4
  import { type IAgentManager, type IAgentManagerFactory, type IAISettingsModel, type ISkillRegistry, type ITokenUsage, type ToolMap } from './tokens';
5
5
  /**
@@ -132,10 +132,10 @@ export declare class AgentManager implements IAgentManager {
132
132
  */
133
133
  clearHistory(): Promise<void>;
134
134
  /**
135
- * Sets the history with a list of messages from the chat.
136
- * @param messages The chat messages to set as history
135
+ * Sets the history from already-processed model messages.
136
+ * @param messages Pre-built model messages (may include binary content)
137
137
  */
138
- setHistory(messages: IMessageContent[]): void;
138
+ setHistory(messages: ModelMessage[]): void;
139
139
  /**
140
140
  * Stops the current streaming response by aborting the request.
141
141
  * Resolve any pending approval.
@@ -143,26 +143,35 @@ export declare class AgentManager implements IAgentManager {
143
143
  stopStreaming(reason?: string): void;
144
144
  /**
145
145
  * Approves a pending tool call.
146
- * @param approvalId The approval ID to approve
146
+ * @param toolCallId The tool call ID to approve
147
147
  * @param reason Optional reason for approval
148
148
  */
149
- approveToolCall(approvalId: string, reason?: string): void;
149
+ approveToolCall(toolCallId: string, reason?: string): void;
150
150
  /**
151
151
  * Rejects a pending tool call.
152
- * @param approvalId The approval ID to reject
152
+ * @param toolCallId The tool call ID to reject
153
153
  * @param reason Optional reason for rejection
154
154
  */
155
- rejectToolCall(approvalId: string, reason?: string): void;
155
+ rejectToolCall(toolCallId: string, reason?: string): void;
156
156
  /**
157
157
  * Generates AI response to user message using the agent.
158
158
  * Handles the complete execution cycle including tool calls.
159
159
  * @param message The user message to respond to (may include processed attachment content)
160
160
  */
161
- generateResponse(message: string): Promise<void>;
161
+ generateResponse(message: UserContent): Promise<void>;
162
+ /**
163
+ * Create a transient language model to request a text response which won't be added to history.
164
+ * @param messages - the messages sequence to send to the model.
165
+ */
166
+ textResponse(messages: ModelMessage[]): Promise<string>;
162
167
  /**
163
168
  * Updates cumulative token usage statistics from a completed model step.
164
169
  */
165
170
  private _updateTokenUsage;
171
+ /**
172
+ * Removes image and file parts from all user messages in the given list.
173
+ */
174
+ private _stripAttachments;
166
175
  /**
167
176
  * Gets the configured context window for the active provider.
168
177
  */
@@ -217,7 +226,7 @@ export declare class AgentManager implements IAgentManager {
217
226
  private _handleApprovalRequest;
218
227
  /**
219
228
  * Waits for user approval of a tool call.
220
- * @param approvalId The approval ID to wait for
229
+ * @param toolCallId The tool call ID to wait for approval
221
230
  * @returns Promise that resolves to true if approved, false if rejected
222
231
  */
223
232
  private _waitForApproval;
package/lib/agent.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createMCPClient } from '@ai-sdk/mcp';
2
2
  import { PromiseDelegate } from '@lumino/coreutils';
3
3
  import { Signal } from '@lumino/signaling';
4
- import { ToolLoopAgent, stepCountIs } from 'ai';
4
+ import { generateText, ToolLoopAgent, stepCountIs, APICallError } from 'ai';
5
5
  import { createModel } from './providers/models';
6
6
  import { getEffectiveContextWindow } from './providers/model-info';
7
7
  import { createProviderTools } from './providers/provider-tools';
@@ -331,29 +331,12 @@ export class AgentManager {
331
331
  this._tokenUsageChanged.emit(this._tokenUsage);
332
332
  }
333
333
  /**
334
- * Sets the history with a list of messages from the chat.
335
- * @param messages The chat messages to set as history
334
+ * Sets the history from already-processed model messages.
335
+ * @param messages Pre-built model messages (may include binary content)
336
336
  */
337
337
  setHistory(messages) {
338
- // Stop any ongoing streaming and reject awaiting approvals
339
- this.stopStreaming();
340
- for (const [approvalId, pending] of this._pendingApprovals) {
341
- pending.resolve(false, 'Chat history changed');
342
- this._agentEvent.emit({
343
- type: 'tool_approval_resolved',
344
- data: { approvalId, approved: false }
345
- });
346
- }
347
- this._pendingApprovals.clear();
348
- // Convert chat messages to model messages
349
- const modelMessages = messages.map(msg => {
350
- const isAIMessage = msg.sender.username === 'ai-assistant';
351
- return {
352
- role: isAIMessage ? 'assistant' : 'user',
353
- content: msg.body
354
- };
355
- });
356
- this._history = Private.sanitizeModelMessages(modelMessages);
338
+ this.stopStreaming('Chat history changed');
339
+ this._history = Private.sanitizeModelMessages(messages);
357
340
  }
358
341
  /**
359
342
  * Stops the current streaming response by aborting the request.
@@ -362,44 +345,44 @@ export class AgentManager {
362
345
  stopStreaming(reason) {
363
346
  this._controller?.abort();
364
347
  // Reject any pending approvals
365
- for (const [approvalId, pending] of this._pendingApprovals) {
348
+ for (const [toolCallId, pending] of this._pendingApprovals) {
366
349
  pending.resolve(false, reason ?? 'Stream ended by user');
367
350
  this._agentEvent.emit({
368
351
  type: 'tool_approval_resolved',
369
- data: { approvalId, approved: false }
352
+ data: { toolCallId, approved: false }
370
353
  });
371
354
  }
372
355
  this._pendingApprovals.clear();
373
356
  }
374
357
  /**
375
358
  * Approves a pending tool call.
376
- * @param approvalId The approval ID to approve
359
+ * @param toolCallId The tool call ID to approve
377
360
  * @param reason Optional reason for approval
378
361
  */
379
- approveToolCall(approvalId, reason) {
380
- const pending = this._pendingApprovals.get(approvalId);
362
+ approveToolCall(toolCallId, reason) {
363
+ const pending = this._pendingApprovals.get(toolCallId);
381
364
  if (pending) {
382
365
  pending.resolve(true, reason);
383
- this._pendingApprovals.delete(approvalId);
366
+ this._pendingApprovals.delete(toolCallId);
384
367
  this._agentEvent.emit({
385
368
  type: 'tool_approval_resolved',
386
- data: { approvalId, approved: true }
369
+ data: { toolCallId, approved: true }
387
370
  });
388
371
  }
389
372
  }
390
373
  /**
391
374
  * Rejects a pending tool call.
392
- * @param approvalId The approval ID to reject
375
+ * @param toolCallId The tool call ID to reject
393
376
  * @param reason Optional reason for rejection
394
377
  */
395
- rejectToolCall(approvalId, reason) {
396
- const pending = this._pendingApprovals.get(approvalId);
378
+ rejectToolCall(toolCallId, reason) {
379
+ const pending = this._pendingApprovals.get(toolCallId);
397
380
  if (pending) {
398
381
  pending.resolve(false, reason);
399
- this._pendingApprovals.delete(approvalId);
382
+ this._pendingApprovals.delete(toolCallId);
400
383
  this._agentEvent.emit({
401
384
  type: 'tool_approval_resolved',
402
- data: { approvalId, approved: false }
385
+ data: { toolCallId, approved: false }
403
386
  });
404
387
  }
405
388
  }
@@ -412,6 +395,11 @@ export class AgentManager {
412
395
  this._streaming = new PromiseDelegate();
413
396
  this._controller = new AbortController();
414
397
  const responseHistory = [];
398
+ // Add user message to history
399
+ responseHistory.push({
400
+ role: 'user',
401
+ content: message
402
+ });
415
403
  try {
416
404
  // Ensure we have an agent
417
405
  if (!this._agent) {
@@ -420,11 +408,6 @@ export class AgentManager {
420
408
  if (!this._agent) {
421
409
  throw new Error('Failed to initialize agent');
422
410
  }
423
- // Add user message to history
424
- responseHistory.push({
425
- role: 'user',
426
- content: message
427
- });
428
411
  let continueLoop = true;
429
412
  while (continueLoop) {
430
413
  const result = await this._agent.stream({
@@ -473,9 +456,26 @@ export class AgentManager {
473
456
  }
474
457
  catch (error) {
475
458
  if (error.name !== 'AbortError') {
459
+ let helpMessage = `${error.message}`;
460
+ // Remove attachments from history on payload rejection errors
461
+ if (APICallError.isInstance(error) &&
462
+ (error.statusCode === 400 ||
463
+ error.statusCode === 404 ||
464
+ error.statusCode === 413 ||
465
+ error.statusCode === 415 ||
466
+ error.statusCode === 422)) {
467
+ this._stripAttachments([...this._history, ...responseHistory], '_Attachment removed due to error_');
468
+ helpMessage +=
469
+ '\n\nAttachments have been removed from history. Please send your prompt again.';
470
+ }
476
471
  this._agentEvent.emit({
477
472
  type: 'error',
478
- data: { error: error }
473
+ data: { error: new Error(helpMessage) }
474
+ });
475
+ this._history.push(...Private.sanitizeModelMessages(responseHistory));
476
+ this._history.push({
477
+ role: 'assistant',
478
+ content: helpMessage
479
479
  });
480
480
  }
481
481
  }
@@ -484,6 +484,24 @@ export class AgentManager {
484
484
  this._streaming.resolve();
485
485
  }
486
486
  }
487
+ /**
488
+ * Create a transient language model to request a text response which won't be added to history.
489
+ * @param messages - the messages sequence to send to the model.
490
+ */
491
+ async textResponse(messages) {
492
+ try {
493
+ const model = await this._createModel();
494
+ const result = await generateText({
495
+ model,
496
+ messages
497
+ });
498
+ this._updateTokenUsage(result.totalUsage, result.totalUsage.inputTokens);
499
+ return result.text;
500
+ }
501
+ catch (e) {
502
+ throw `Error while getting the topic of the chat\n${e}`;
503
+ }
504
+ }
487
505
  /**
488
506
  * Updates cumulative token usage statistics from a completed model step.
489
507
  */
@@ -498,6 +516,23 @@ export class AgentManager {
498
516
  this._tokenUsage.contextWindow = contextWindow;
499
517
  this._tokenUsageChanged.emit(this._tokenUsage);
500
518
  }
519
+ /**
520
+ * Removes image and file parts from all user messages in the given list.
521
+ */
522
+ _stripAttachments(messages, placeholder) {
523
+ for (const msg of messages) {
524
+ if (msg.role === 'user' && Array.isArray(msg.content)) {
525
+ const hasMedia = msg.content.some(p => p.type !== 'text');
526
+ if (hasMedia) {
527
+ const textContent = msg.content
528
+ .filter(p => p.type === 'text')
529
+ .map(p => p.text)
530
+ .join('\n');
531
+ msg.content = textContent || placeholder;
532
+ }
533
+ }
534
+ }
535
+ }
501
536
  /**
502
537
  * Gets the configured context window for the active provider.
503
538
  */
@@ -694,13 +729,15 @@ ${richOutputWorkflowInstruction}`;
694
729
  }
695
730
  await this._handleApprovalRequest(part, processResult);
696
731
  break;
732
+ case 'error':
733
+ throw part.error;
697
734
  case 'finish-step':
698
735
  this._updateTokenUsage(part.usage, part.usage.inputTokens);
699
736
  break;
700
737
  case 'abort':
701
738
  processResult.aborted = true;
702
739
  break;
703
- // Ignore: text-start, text-end, finish, error, and others
740
+ // Ignore: text-start, text-end, finish, and others
704
741
  default:
705
742
  break;
706
743
  }
@@ -779,13 +816,12 @@ ${richOutputWorkflowInstruction}`;
779
816
  this._agentEvent.emit({
780
817
  type: 'tool_approval_request',
781
818
  data: {
782
- approvalId,
783
819
  toolCallId: toolCall.toolCallId,
784
820
  toolName: toolCall.toolName,
785
821
  args: toolCall.input
786
822
  }
787
823
  });
788
- const approved = await this._waitForApproval(approvalId);
824
+ const approved = await this._waitForApproval(toolCall.toolCallId);
789
825
  result.approvalProcessed = true;
790
826
  result.approvalResponse = {
791
827
  role: 'tool',
@@ -800,12 +836,12 @@ ${richOutputWorkflowInstruction}`;
800
836
  }
801
837
  /**
802
838
  * Waits for user approval of a tool call.
803
- * @param approvalId The approval ID to wait for
839
+ * @param toolCallId The tool call ID to wait for approval
804
840
  * @returns Promise that resolves to true if approved, false if rejected
805
841
  */
806
- _waitForApproval(approvalId) {
842
+ _waitForApproval(toolCallId) {
807
843
  return new Promise(resolve => {
808
- this._pendingApprovals.set(approvalId, {
844
+ this._pendingApprovals.set(toolCallId, {
809
845
  resolve: (approved) => {
810
846
  resolve(approved);
811
847
  }
@@ -16,7 +16,7 @@ export class ClearCommandProvider {
16
16
  return;
17
17
  }
18
18
  const context = inputModel.chatContext;
19
- context?.clearMessages?.();
19
+ await context?.clearMessages?.();
20
20
  inputModel.value = '';
21
21
  inputModel.clearAttachments();
22
22
  inputModel.clearMentions();
@@ -2,14 +2,13 @@ import { ActiveCellManager } from '@jupyter/chat';
2
2
  import { IDocumentManager } from '@jupyterlab/docmanager';
3
3
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
4
4
  import { Contents } from '@jupyterlab/services';
5
- import { AIChatModel } from './chat-model';
6
- import type { IAgentManagerFactory, IAISettingsModel, IChatModelHandler, ICreateChatOptions, IProviderRegistry, IToolRegistry } from './tokens';
5
+ import type { IAgentManagerFactory, IAIChatModel, IAISettingsModel, IChatModelHandler, ICreateChatOptions, IProviderRegistry, IToolRegistry } from './tokens';
7
6
  /**
8
7
  * The chat model handler.
9
8
  */
10
9
  export declare class ChatModelHandler implements IChatModelHandler {
11
10
  constructor(options: ChatModelHandler.IOptions);
12
- createModel(options: ICreateChatOptions): AIChatModel;
11
+ createModel(options: ICreateChatOptions): IAIChatModel;
13
12
  /**
14
13
  * Getter/setter for the active cell manager.
15
14
  */
@@ -14,7 +14,7 @@ export class ChatModelHandler {
14
14
  this._contentsManager = options.contentsManager;
15
15
  }
16
16
  createModel(options) {
17
- const { name, activeProvider, tokenUsage, messages, autosave } = options;
17
+ const { name, activeProvider, tokenUsage, messages, autosave, title } = options;
18
18
  // Create Agent Manager first so it can be shared
19
19
  const agentManager = this._agentManagerFactory.createAgent({
20
20
  settingsModel: this._settingsModel,
@@ -31,13 +31,17 @@ export class ChatModelHandler {
31
31
  agentManager,
32
32
  activeCellManager: this._activeCellManager,
33
33
  documentManager: this._docManager,
34
- contentsManager: this._contentsManager
34
+ contentsManager: this._contentsManager,
35
+ providerRegistry: this._providerRegistry
35
36
  });
36
37
  messages?.forEach(message => {
37
38
  model.messageAdded({ ...message.content });
38
39
  });
39
40
  model.autosave = autosave ?? false;
40
41
  model.name = name;
42
+ if (title) {
43
+ model.title = title;
44
+ }
41
45
  return model;
42
46
  }
43
47
  /**
@@ -1,13 +1,14 @@
1
- import { AbstractChatModel, IActiveCellManager, IAttachment, IChatContext, IMessageContent, INewMessage, IUser } from '@jupyter/chat';
1
+ import { AbstractChatModel, IActiveCellManager, IAttachment, IChatContext, IMessageContent, IMimeModelBody, INewMessage, IUser } from '@jupyter/chat';
2
2
  import { IDocumentManager } from '@jupyterlab/docmanager';
3
3
  import { Contents } from '@jupyterlab/services';
4
4
  import { ISignal } from '@lumino/signaling';
5
- import type { IAgentManager, IAISettingsModel, ITokenUsage } from './tokens';
5
+ import type { UserContent } from 'ai';
6
+ import type { IAgentManager, IAIChatModel, IAISettingsModel, IProviderRegistry, ITokenUsage } from './tokens';
6
7
  /**
7
8
  * AI Chat Model implementation that provides chat functionality tool integration,
8
9
  * and MCP server support.
9
10
  */
10
- export declare class AIChatModel extends AbstractChatModel {
11
+ export declare class AIChatModel extends AbstractChatModel implements IAIChatModel {
11
12
  /**
12
13
  * Constructs a new AIChatModel instance.
13
14
  * @param options Configuration options for the chat model
@@ -18,6 +19,19 @@ export declare class AIChatModel extends AbstractChatModel {
18
19
  */
19
20
  get name(): string;
20
21
  set name(value: string);
22
+ /**
23
+ * A signal emitting when the chat name has changed.
24
+ */
25
+ get nameChanged(): ISignal<IAIChatModel, string>;
26
+ /**
27
+ * The title of the chat.
28
+ */
29
+ get title(): string | null;
30
+ set title(value: string | null);
31
+ /**
32
+ * A signal emitting when the chat title has changed.
33
+ */
34
+ get titleChanged(): ISignal<IAIChatModel, string | null>;
21
35
  /**
22
36
  * Whether to save the chat automatically.
23
37
  */
@@ -26,11 +40,7 @@ export declare class AIChatModel extends AbstractChatModel {
26
40
  /**
27
41
  * A signal emitting when the autosave flag changed.
28
42
  */
29
- get autosaveChanged(): ISignal<AIChatModel, boolean>;
30
- /**
31
- * A signal emitting when the chat name has changed.
32
- */
33
- get nameChanged(): ISignal<AIChatModel, string>;
43
+ get autosaveChanged(): ISignal<IAIChatModel, boolean>;
34
44
  /**
35
45
  * Gets the current user information.
36
46
  */
@@ -40,7 +50,7 @@ export declare class AIChatModel extends AbstractChatModel {
40
50
  */
41
51
  get tokenUsageChanged(): ISignal<IAgentManager, ITokenUsage>;
42
52
  /**
43
- * Get the agent manager associated to the model.
53
+ * The agent manager used in the model.
44
54
  */
45
55
  get agentManager(): IAgentManager;
46
56
  /**
@@ -62,16 +72,41 @@ export declare class AIChatModel extends AbstractChatModel {
62
72
  /**
63
73
  * Clears all messages from the chat and resets conversation state.
64
74
  */
65
- clearMessages: () => void;
75
+ clearMessages: () => Promise<void>;
76
+ /**
77
+ * Overrides messageAdded to ensure queued messages stay at the bottom.
78
+ */
79
+ messageAdded(message: IMessageContent): void;
66
80
  /**
67
81
  * Adds a non-user message to the chat (used by chat commands).
68
82
  */
69
- addSystemMessage(body: string): void;
83
+ private _addSystemMessage;
70
84
  /**
71
85
  * Sends a message to the AI and generates a response.
72
86
  * @param message The user message to send
73
87
  */
74
88
  sendMessage(message: INewMessage): Promise<void>;
89
+ /**
90
+ * Internal method to process attachments and send the message to the agent.
91
+ */
92
+ private _processMessage;
93
+ /**
94
+ * Removes the message-queue chat component.
95
+ */
96
+ private _removeQueueUI;
97
+ /**
98
+ * Creates or updates the message-queue chat component.
99
+ */
100
+ private _updateQueueUI;
101
+ /**
102
+ * Processes the next message in the queue, or marks the agent as idle.
103
+ */
104
+ private _drainQueue;
105
+ /**
106
+ * Removes a queued message by its ID.
107
+ * @param messageId The ID of the queued message to remove
108
+ */
109
+ removeQueuedMessage(messageId: string): void;
75
110
  /**
76
111
  * Save the chat as json file.
77
112
  */
@@ -83,6 +118,10 @@ export declare class AIChatModel extends AbstractChatModel {
83
118
  * restoration is not possible.
84
119
  */
85
120
  restore: (filepath: string, silent?: boolean) => Promise<boolean>;
121
+ /**
122
+ * Request a title to this chat, regarding the message history.
123
+ */
124
+ requestTitle(): Promise<string>;
86
125
  /**
87
126
  * Serialize the model for backup
88
127
  */
@@ -95,6 +134,16 @@ export declare class AIChatModel extends AbstractChatModel {
95
134
  * Handles settings changes and updates chat configuration accordingly.
96
135
  */
97
136
  private _onSettingsChanged;
137
+ /**
138
+ * Rebuild history when the active model changes.
139
+ */
140
+ private _onModelChanged;
141
+ /**
142
+ * Rebuilds the agent history from the current messages.
143
+ * For vision-capable models, re-reads binary attachments from disk.
144
+ * For text-only models, uses message text only.
145
+ */
146
+ private _rebuildHistory;
98
147
  /**
99
148
  * Handles events emitted by the agent manager.
100
149
  * @param event The event data containing type and payload
@@ -156,33 +205,78 @@ export declare class AIChatModel extends AbstractChatModel {
156
205
  */
157
206
  private _updateToolCallUI;
158
207
  /**
159
- * Processes file attachments and returns their content as formatted strings.
160
- * @param attachments Array of file attachments to process
161
- * @returns Array of formatted attachment contents
162
- */
163
- private _processAttachments;
164
- /**
165
- * Reads the content of a notebook cell.
166
- * @param attachment The notebook attachment to read
167
- * @returns Cell content as string or null if unable to read
208
+ * The current message queue
168
209
  */
169
- private _readNotebookCells;
210
+ get messageQueue(): Private.IQueuedItem[];
211
+ set messageQueue(value: Private.IQueuedItem[]);
170
212
  /**
171
- * Reads the content of a file attachment.
172
- * @param attachment The file attachment to read
173
- * @returns File content as string or null if unable to read
213
+ * Whether the chat is busy
174
214
  */
175
- private _readFileAttachment;
215
+ get isBusy(): boolean;
216
+ set isBusy(value: boolean);
176
217
  private _settingsModel;
177
218
  private _user;
178
219
  private _toolContexts;
179
220
  private _agentManager;
221
+ private _providerRegistry?;
222
+ private _currentModelKey;
180
223
  private _currentStreamingMessage;
181
224
  private _nameChanged;
182
225
  private _contentsManager?;
183
226
  private _autosave;
184
227
  private _autosaveChanged;
185
228
  private _autosaveDebouncer;
229
+ private _messageQueue;
230
+ private _isBusy;
231
+ private _queueMessageId;
232
+ private _title;
233
+ private _titleChanged;
234
+ }
235
+ declare namespace Private {
236
+ interface IQueuedItem {
237
+ id: string;
238
+ body: string;
239
+ _originalMsg: IMessageContent;
240
+ }
241
+ /**
242
+ * Extract rendermime-ready mime bundles from arbitrary tool results.
243
+ */
244
+ function extractMimeBundlesFromUnknown(content: unknown, options?: {
245
+ trustedMimeTypes?: ReadonlyArray<string>;
246
+ }): IMimeModelBody[];
247
+ function formatToolOutput(outputData: unknown): string;
248
+ /**
249
+ * Processes file attachments and returns the message content with the attachments.
250
+ * @param attachments Array of file attachments to process
251
+ * @param documentManager Optional document manager for file operations
252
+ * @param body The message body
253
+ * @param supportsImages Whether the model supports images
254
+ * @param supportsPdf Whether the model supports pdfs
255
+ * @param supportsAudio Whether the model supports audio
256
+ * @returns Enhanced message content
257
+ */
258
+ function processAttachments(attachments: IAttachment[], documentManager: IDocumentManager | null | undefined, body: string, supportsImages: boolean, supportsPdf: boolean, supportsAudio: boolean): Promise<UserContent>;
259
+ /**
260
+ * Reads a binary attachment and returns its base64-encoded content.
261
+ * @param attachment The attachment to read
262
+ * @param documentManager Optional document manager for file operations
263
+ * @returns Base64 string or null if unable to read
264
+ */
265
+ function readBinaryAttachment(attachment: IAttachment, documentManager: IDocumentManager | null | undefined): Promise<string | null>;
266
+ /**
267
+ * Reads the content of a notebook cell.
268
+ * @param attachment The notebook attachment to read
269
+ * @param documentManager Optional document manager for file operations
270
+ * @returns Cell content as string or null if unable to read
271
+ */
272
+ function readNotebookCells(attachment: IAttachment, documentManager: IDocumentManager | null | undefined): Promise<string | null>;
273
+ /**
274
+ * Reads the content of a file attachment.
275
+ * @param attachment The file attachment to read
276
+ * @param documentManager Optional document manager for file operations
277
+ * @returns File content as string or null if unable to read
278
+ */
279
+ function readFileAttachment(attachment: IAttachment, documentManager: IDocumentManager | null | undefined): Promise<string | null>;
186
280
  }
187
281
  /**
188
282
  * Namespace containing types and interfaces for AIChatModel.
@@ -216,6 +310,10 @@ export declare namespace AIChatModel {
216
310
  * The contents manager.
217
311
  */
218
312
  contentsManager?: Contents.IManager;
313
+ /**
314
+ * Optional provider registry for model capability lookups.
315
+ */
316
+ providerRegistry?: IProviderRegistry;
219
317
  /**
220
318
  * Whether to restore or not the message (default to true)
221
319
  */
@@ -232,7 +330,7 @@ export declare namespace AIChatModel {
232
330
  /**
233
331
  * The clear messages callback.
234
332
  */
235
- clearMessages: () => void;
333
+ clearMessages: () => Promise<void>;
236
334
  /**
237
335
  * Adds an assistant/system message to the chat.
238
336
  */
@@ -274,6 +372,11 @@ export declare namespace AIChatModel {
274
372
  * Whether the chat is automatically saved.
275
373
  */
276
374
  autosave?: boolean;
375
+ /**
376
+ * An optional title of the chat.
377
+ */
378
+ title?: string;
277
379
  };
278
380
  };
279
381
  }
382
+ export {};