@jupyterlite/ai 0.14.0 → 0.16.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 (64) hide show
  1. package/lib/agent.d.ts +33 -115
  2. package/lib/agent.js +192 -106
  3. package/lib/chat-model-handler.d.ts +9 -11
  4. package/lib/chat-model-handler.js +9 -4
  5. package/lib/chat-model.d.ts +84 -13
  6. package/lib/chat-model.js +214 -136
  7. package/lib/completion/completion-provider.d.ts +2 -3
  8. package/lib/components/completion-status.d.ts +2 -2
  9. package/lib/components/index.d.ts +1 -1
  10. package/lib/components/index.js +1 -1
  11. package/lib/components/model-select.d.ts +3 -3
  12. package/lib/components/save-button.d.ts +31 -0
  13. package/lib/components/save-button.js +41 -0
  14. package/lib/components/tool-select.d.ts +3 -4
  15. package/lib/components/{token-usage-display.d.ts → usage-display.d.ts} +13 -14
  16. package/lib/components/usage-display.js +109 -0
  17. package/lib/diff-manager.d.ts +2 -3
  18. package/lib/index.d.ts +2 -4
  19. package/lib/index.js +186 -28
  20. package/lib/models/settings-model.d.ts +11 -53
  21. package/lib/models/settings-model.js +38 -22
  22. package/lib/providers/built-in-providers.js +22 -36
  23. package/lib/providers/generated-context-windows.d.ts +8 -0
  24. package/lib/providers/generated-context-windows.js +96 -0
  25. package/lib/providers/model-info.d.ts +3 -0
  26. package/lib/providers/model-info.js +58 -0
  27. package/lib/tokens.d.ts +361 -36
  28. package/lib/tokens.js +18 -13
  29. package/lib/tools/commands.d.ts +2 -3
  30. package/lib/widgets/ai-settings.d.ts +3 -5
  31. package/lib/widgets/ai-settings.js +12 -0
  32. package/lib/widgets/main-area-chat.d.ts +2 -3
  33. package/lib/widgets/main-area-chat.js +12 -12
  34. package/lib/widgets/provider-config-dialog.d.ts +1 -2
  35. package/lib/widgets/provider-config-dialog.js +34 -34
  36. package/package.json +17 -10
  37. package/schema/settings-model.json +18 -1
  38. package/src/agent.ts +275 -248
  39. package/src/chat-model-handler.ts +25 -21
  40. package/src/chat-model.ts +307 -196
  41. package/src/completion/completion-provider.ts +7 -4
  42. package/src/components/completion-status.tsx +3 -3
  43. package/src/components/index.ts +1 -1
  44. package/src/components/model-select.tsx +4 -3
  45. package/src/components/save-button.tsx +84 -0
  46. package/src/components/tool-select.tsx +10 -4
  47. package/src/components/usage-display.tsx +208 -0
  48. package/src/diff-manager.ts +4 -4
  49. package/src/index.ts +250 -58
  50. package/src/models/settings-model.ts +46 -88
  51. package/src/providers/built-in-providers.ts +22 -36
  52. package/src/providers/generated-context-windows.ts +102 -0
  53. package/src/providers/model-info.ts +88 -0
  54. package/src/tokens.ts +438 -58
  55. package/src/tools/commands.ts +2 -3
  56. package/src/widgets/ai-settings.tsx +69 -15
  57. package/src/widgets/main-area-chat.ts +18 -15
  58. package/src/widgets/provider-config-dialog.tsx +96 -61
  59. package/style/base.css +17 -195
  60. package/lib/approval-buttons.d.ts +0 -49
  61. package/lib/approval-buttons.js +0 -79
  62. package/lib/components/token-usage-display.js +0 -72
  63. package/src/approval-buttons.ts +0 -115
  64. package/src/components/token-usage-display.tsx +0 -138
package/lib/tokens.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { ActiveCellManager } from '@jupyter/chat';
1
+ import { ActiveCellManager, IMessage, IMessageContent } from '@jupyter/chat';
2
+ import { VDomRenderer } from '@jupyterlab/apputils';
3
+ import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
2
4
  import { Token } from '@lumino/coreutils';
3
5
  import type { IDisposable } from '@lumino/disposable';
4
6
  import { ISignal } from '@lumino/signaling';
5
7
  import type { Tool, LanguageModel } from 'ai';
6
- import { AgentManager } from './agent';
7
- import type { AISettingsModel } from './models/settings-model';
8
+ import { ISecretsManager } from 'jupyter-secrets-manager';
8
9
  import type { IModelOptions } from './providers/models';
9
- import { AgentManagerFactory } from './agent';
10
10
  import { AIChatModel } from './chat-model';
11
11
  import type { ISkillDefinition, ISkillRegistration, ISkillResourceResult, ISkillSummary } from './skills/types';
12
12
  export type { ISkillDefinition, ISkillRegistration, ISkillResourceResult, ISkillSummary } from './skills/types';
@@ -19,24 +19,17 @@ export declare namespace CommandIds {
19
19
  const openChat = "@jupyterlite/ai:open-chat";
20
20
  const moveChat = "@jupyterlite/ai:move-chat";
21
21
  const refreshSkills = "@jupyterlite/ai:refresh-skills";
22
+ const saveChat = "@jupyterlite/ai:save-chat";
23
+ const restoreChat = "@jupyterlite/ai:restore-chat";
22
24
  }
23
25
  /**
24
26
  * Type definition for a tool
25
27
  */
26
28
  export type ITool = Tool;
27
29
  /**
28
- * Interface for token usage statistics from AI model interactions
30
+ * A map containing tools.
29
31
  */
30
- export interface ITokenUsage {
31
- /**
32
- * Number of input tokens consumed (prompt tokens)
33
- */
34
- inputTokens: number;
35
- /**
36
- * Number of output tokens generated (completion tokens)
37
- */
38
- outputTokens: number;
39
- }
32
+ export type ToolMap = Record<string, ITool>;
40
33
  /**
41
34
  * Interface for a named tool (tool with a name identifier)
42
35
  */
@@ -114,10 +107,6 @@ export interface ISkillRegistry {
114
107
  * The skill registry token.
115
108
  */
116
109
  export declare const ISkillRegistry: Token<ISkillRegistry>;
117
- /**
118
- * Token for the provider registry.
119
- */
120
- export declare const IProviderRegistry: Token<IProviderRegistry>;
121
110
  /**
122
111
  * Interface for a provider factory function that creates language models
123
112
  */
@@ -164,6 +153,12 @@ export interface IProviderToolCapabilities {
164
153
  /**
165
154
  * Provider information
166
155
  */
156
+ export interface IProviderModelInfo {
157
+ /**
158
+ * Default context window for the model in tokens.
159
+ */
160
+ contextWindow?: number;
161
+ }
167
162
  export interface IProviderInfo {
168
163
  /**
169
164
  * Unique identifier for the provider
@@ -184,6 +179,10 @@ export interface IProviderInfo {
184
179
  * Default model names for this provider
185
180
  */
186
181
  defaultModels: string[];
182
+ /**
183
+ * Optional per-model metadata keyed by model ID.
184
+ */
185
+ modelInfo?: Record<string, IProviderModelInfo>;
187
186
  /**
188
187
  * Whether this provider supports custom base URLs
189
188
  */
@@ -249,45 +248,323 @@ export interface IProviderRegistry {
249
248
  */
250
249
  getAvailableProviders(): string[];
251
250
  }
251
+ /**
252
+ * Token for the provider registry.
253
+ */
254
+ export declare const IProviderRegistry: Token<IProviderRegistry>;
255
+ export interface IProviderParameters {
256
+ temperature?: number;
257
+ maxOutputTokens?: number;
258
+ maxTurns?: number;
259
+ contextWindow?: number;
260
+ supportsFillInMiddle?: boolean;
261
+ useFilterText?: boolean;
262
+ }
263
+ export interface IProviderConfig {
264
+ id: string;
265
+ name: string;
266
+ provider: string;
267
+ model: string;
268
+ apiKey?: string;
269
+ baseURL?: string;
270
+ headers?: Record<string, string>;
271
+ parameters?: IProviderParameters;
272
+ customSettings?: Record<string, any>;
273
+ [key: string]: any;
274
+ }
275
+ export interface IMCPServerConfig {
276
+ id: string;
277
+ name: string;
278
+ url: string;
279
+ enabled: boolean;
280
+ [key: string]: any;
281
+ }
282
+ export interface IAIConfig {
283
+ useSecretsManager: boolean;
284
+ providers: IProviderConfig[];
285
+ defaultProvider: string;
286
+ activeCompleterProvider?: string;
287
+ useSameProviderForChatAndCompleter: boolean;
288
+ mcpServers: IMCPServerConfig[];
289
+ contextAwareness: boolean;
290
+ codeExecution: boolean;
291
+ systemPrompt: string;
292
+ completionSystemPrompt: string;
293
+ toolsEnabled: boolean;
294
+ sendWithShiftEnter: boolean;
295
+ showTokenUsage: boolean;
296
+ showContextUsage: boolean;
297
+ commandsRequiringApproval: string[];
298
+ commandsAutoRenderMimeBundles: string[];
299
+ trustedMimeTypesForAutoRender: string[];
300
+ showCellDiff: boolean;
301
+ showFileDiff: boolean;
302
+ diffDisplayMode: 'split' | 'unified';
303
+ skillsPaths: string[];
304
+ chatBackupDirectory: string;
305
+ }
306
+ export interface IAISettingsModel extends VDomRenderer.IModel {
307
+ readonly config: IAIConfig;
308
+ updateConfig(updates: Partial<IAIConfig>): Promise<void>;
309
+ readonly providers: IProviderConfig[];
310
+ getProvider(id: string): IProviderConfig | undefined;
311
+ getDefaultProvider(): IProviderConfig | undefined;
312
+ getCompleterProvider(): IProviderConfig | undefined;
313
+ addProvider(providerConfig: Omit<IProviderConfig, 'id'>): Promise<string>;
314
+ removeProvider(id: string): Promise<void>;
315
+ updateProvider(id: string, updates: Partial<IProviderConfig>): Promise<void>;
316
+ setActiveProvider(id: string): Promise<void>;
317
+ setActiveCompleterProvider(id: string | undefined): Promise<void>;
318
+ readonly mcpServers: IMCPServerConfig[];
319
+ getMCPServer(id: string): IMCPServerConfig | undefined;
320
+ addMCPServer(serverConfig: Omit<IMCPServerConfig, 'id'>): Promise<string>;
321
+ removeMCPServer(id: string): Promise<void>;
322
+ updateMCPServer(id: string, updates: Partial<IMCPServerConfig>): Promise<void>;
323
+ /**
324
+ * Get the API key saved in the settings file for a given provider.
325
+ *
326
+ * @param id - the id of the provider.
327
+ */
328
+ getApiKey(id: string): string;
329
+ }
252
330
  /**
253
331
  * Token for the AI settings model.
254
332
  */
255
- export declare const IAISettingsModel: Token<AISettingsModel>;
333
+ export declare const IAISettingsModel: Token<IAISettingsModel>;
256
334
  /**
257
- * Internal interface for AI provider secret access within the shared namespace.
335
+ * A namespace for agent manager.
258
336
  */
259
- export interface IAISecretsAccess {
337
+ export declare namespace IAgentManager {
338
+ /**
339
+ * Configuration options for the AgentManager
340
+ */
341
+ interface IOptions {
342
+ /**
343
+ * AI settings model for configuration
344
+ */
345
+ settingsModel: IAISettingsModel;
346
+ /**
347
+ * Optional tool registry for managing available tools
348
+ */
349
+ toolRegistry?: IToolRegistry;
350
+ /**
351
+ * Optional provider registry for model creation
352
+ */
353
+ providerRegistry?: IProviderRegistry;
354
+ /**
355
+ * The skill registry for discovering skills.
356
+ */
357
+ skillRegistry?: ISkillRegistry;
358
+ /**
359
+ * The secrets manager.
360
+ */
361
+ secretsManager?: ISecretsManager;
362
+ /**
363
+ * The active provider to use with this agent.
364
+ */
365
+ activeProvider?: string;
366
+ /**
367
+ * Initial token usage.
368
+ */
369
+ tokenUsage?: ITokenUsage;
370
+ /**
371
+ * JupyterLab render mime registry for discovering supported MIME types.
372
+ */
373
+ renderMimeRegistry?: IRenderMimeRegistry;
374
+ }
375
+ /**
376
+ * Event type mapping for type safety with inlined interface definitions
377
+ */
378
+ interface IAgentEventTypeMap {
379
+ message_start: {
380
+ messageId: string;
381
+ };
382
+ message_chunk: {
383
+ messageId: string;
384
+ chunk: string;
385
+ fullContent: string;
386
+ };
387
+ message_complete: {
388
+ messageId: string;
389
+ content: string;
390
+ };
391
+ tool_call_start: {
392
+ callId: string;
393
+ toolName: string;
394
+ input: string;
395
+ };
396
+ tool_call_complete: {
397
+ callId: string;
398
+ toolName: string;
399
+ outputData: unknown;
400
+ isError: boolean;
401
+ };
402
+ tool_approval_request: {
403
+ approvalId: string;
404
+ toolCallId: string;
405
+ toolName: string;
406
+ args: unknown;
407
+ };
408
+ tool_approval_resolved: {
409
+ approvalId: string;
410
+ approved: boolean;
411
+ };
412
+ error: {
413
+ error: Error;
414
+ };
415
+ }
416
+ /**
417
+ * Events emitted by the AgentManager
418
+ */
419
+ type IAgentEvent<T extends keyof IAgentEventTypeMap = keyof IAgentEventTypeMap> = T extends keyof IAgentEventTypeMap ? {
420
+ type: T;
421
+ data: IAgentEventTypeMap[T];
422
+ } : never;
423
+ }
424
+ export interface IAgentManager {
260
425
  /**
261
- * Whether secrets access is currently available.
426
+ * The active provider for this agent.
262
427
  */
263
- readonly isAvailable: boolean;
428
+ activeProvider: string;
264
429
  /**
265
- * Get a secret value by ID.
430
+ * Signal emitted when agent events occur
266
431
  */
267
- get(id: string): Promise<string | undefined>;
432
+ readonly agentEvent: ISignal<IAgentManager, IAgentManager.IAgentEvent>;
268
433
  /**
269
- * Set a secret value by ID.
434
+ * Signal emitted when the active provider has changed.
270
435
  */
271
- set(id: string, value: string): Promise<void>;
436
+ readonly activeProviderChanged: ISignal<IAgentManager, string | undefined>;
272
437
  /**
273
- * Attach an input field to a secret ID.
438
+ * Gets the current token usage statistics.
274
439
  */
275
- attach(id: string, input: HTMLInputElement, callback?: (value: string) => void): Promise<void>;
440
+ readonly tokenUsage: ITokenUsage;
441
+ /**
442
+ * Signal emitted when token usage statistics change.
443
+ */
444
+ readonly tokenUsageChanged: ISignal<IAgentManager, ITokenUsage>;
445
+ /**
446
+ * Refresh the skills snapshot and rebuild the agent if resources are ready.
447
+ */
448
+ refreshSkills(): void;
449
+ /**
450
+ * Sets the selected tools by name and reinitializes the agent.
451
+ * @param toolNames Array of tool names to select
452
+ */
453
+ setSelectedTools(toolNames: string[]): void;
454
+ /**
455
+ * Gets the currently selected tools as a record.
456
+ * @returns Record of selected tools
457
+ */
458
+ readonly selectedAgentTools: ToolMap;
459
+ /**
460
+ * Checks if the current configuration is valid for agent operations.
461
+ * Uses the provider registry to determine if an API key is required.
462
+ * @returns True if the configuration is valid, false otherwise
463
+ */
464
+ hasValidConfig(): boolean;
465
+ /**
466
+ * Clears conversation history and resets agent state.
467
+ */
468
+ clearHistory(): void;
469
+ /**
470
+ * Sets the conversation history with a list of messages from the chat.
471
+ * @param messages The chat messages to set as history
472
+ */
473
+ setHistory(messages: IMessageContent[]): void;
474
+ /**
475
+ * Stops the current streaming response by aborting the request.
476
+ */
477
+ stopStreaming(): void;
478
+ /**
479
+ * Approves a pending tool call.
480
+ * @param approvalId The approval ID to approve
481
+ * @param reason Optional reason for approval
482
+ */
483
+ approveToolCall(approvalId: string, reason?: string): void;
484
+ /**
485
+ * Rejects a pending tool call.
486
+ * @param approvalId The approval ID to reject
487
+ * @param reason Optional reason for rejection
488
+ */
489
+ rejectToolCall(approvalId: string, reason?: string): void;
490
+ /**
491
+ * Generates AI response to user message using the agent.
492
+ * Handles the complete execution cycle including tool calls.
493
+ * @param message The user message to respond to (may include processed attachment content)
494
+ */
495
+ generateResponse(message: string): Promise<void>;
496
+ /**
497
+ * Initializes the AI agent with current settings and tools.
498
+ * Sets up the agent with model configuration, tools, and MCP tools.
499
+ */
500
+ initializeAgent(mcpTools?: ToolMap): Promise<void>;
276
501
  }
277
502
  /**
278
503
  * Token for the agent manager.
279
504
  */
280
- export declare const IAgentManager: Token<AgentManager>;
505
+ export declare const IAgentManager: Token<IAgentManager>;
281
506
  /**
282
- * The string that replaces a secret key in settings.
507
+ * The interface for a agent manager factory.
508
+ */
509
+ export interface IAgentManagerFactory {
510
+ /**
511
+ * Create a new agent.
512
+ */
513
+ createAgent(options: IAgentManager.IOptions): IAgentManager;
514
+ /**
515
+ * Signal emitted when MCP connection status changes
516
+ */
517
+ readonly mcpConnectionChanged: ISignal<IAgentManagerFactory, boolean>;
518
+ /**
519
+ * Checks whether a specific MCP server is connected.
520
+ * @param serverName The name of the MCP server to check
521
+ * @returns True if the server is connected, false otherwise
522
+ */
523
+ isMCPServerConnected(serverName: string): boolean;
524
+ /**
525
+ * Gets the MCP tools from connected servers
526
+ */
527
+ getMCPTools(): Promise<ToolMap>;
528
+ }
529
+ export declare const IAgentManagerFactory: Token<IAgentManagerFactory>;
530
+ /**
531
+ * The interface for the chat model handler.
283
532
  */
284
- export declare const SECRETS_NAMESPACE = "@jupyterlite/ai:providers";
285
- export declare const SECRETS_REPLACEMENT = "***";
286
- export declare const IAgentManagerFactory: Token<AgentManagerFactory>;
287
533
  export interface IChatModelHandler {
288
- createModel(name: string, activeProvider: string, tokenUsage?: ITokenUsage): AIChatModel;
534
+ /**
535
+ * The function to create a new model.
536
+ */
537
+ createModel(options: ICreateChatOptions): AIChatModel;
538
+ /**
539
+ * The active cell manager (to copy code from chat to cell).
540
+ */
289
541
  activeCellManager: ActiveCellManager | undefined;
290
542
  }
543
+ export interface ICreateChatOptions {
544
+ /**
545
+ * The name of the chat.
546
+ */
547
+ name: string;
548
+ /**
549
+ * The id of the active provider of the chat.
550
+ */
551
+ activeProvider: string;
552
+ /**
553
+ * The current token usage in this chat.
554
+ */
555
+ tokenUsage?: ITokenUsage;
556
+ /**
557
+ * The messages to ad by default.
558
+ */
559
+ messages?: IMessage[];
560
+ /**
561
+ * Whether the chat is autosaved or not.
562
+ */
563
+ autosave?: boolean;
564
+ }
565
+ /**
566
+ * Token for the chat model handler.
567
+ */
291
568
  export declare const IChatModelHandler: Token<IChatModelHandler>;
292
569
  /**
293
570
  * Parameters for showing cell diff
@@ -356,3 +633,51 @@ export interface IDiffManager {
356
633
  * Token for the diff manager.
357
634
  */
358
635
  export declare const IDiffManager: Token<IDiffManager>;
636
+ /**
637
+ * Interface for token usage statistics from AI model interactions
638
+ */
639
+ export interface ITokenUsage {
640
+ /**
641
+ * Number of input tokens consumed (prompt tokens)
642
+ */
643
+ inputTokens: number;
644
+ /**
645
+ * Number of output tokens generated (completion tokens)
646
+ */
647
+ outputTokens: number;
648
+ /**
649
+ * Estimated prompt tokens used by the most recent model request.
650
+ * This is based on the final step of the latest request.
651
+ */
652
+ lastRequestInputTokens?: number;
653
+ /**
654
+ * Configured context window size for the active provider/model.
655
+ */
656
+ contextWindow?: number;
657
+ }
658
+ /**
659
+ * The string that replaces a secret key in settings.
660
+ */
661
+ export declare const SECRETS_NAMESPACE = "@jupyterlite/ai:providers";
662
+ export declare const SECRETS_REPLACEMENT = "***";
663
+ /**
664
+ * Internal interface for AI provider secret access within the shared namespace.
665
+ */
666
+ export interface IAISecretsAccess {
667
+ /**
668
+ * Whether secrets access is currently available.
669
+ */
670
+ readonly isAvailable: boolean;
671
+ /**
672
+ * Get a secret value by ID.
673
+ */
674
+ get(id: string): Promise<string | undefined>;
675
+ /**
676
+ * Set a secret value by ID.
677
+ */
678
+ set(id: string, value: string): Promise<void>;
679
+ /**
680
+ * Attach an input field to a secret ID.
681
+ */
682
+ attach(id: string, input: HTMLInputElement, callback?: (value: string) => void): Promise<void>;
683
+ }
package/lib/tokens.js CHANGED
@@ -9,19 +9,21 @@ export var CommandIds;
9
9
  CommandIds.openChat = '@jupyterlite/ai:open-chat';
10
10
  CommandIds.moveChat = '@jupyterlite/ai:move-chat';
11
11
  CommandIds.refreshSkills = '@jupyterlite/ai:refresh-skills';
12
+ CommandIds.saveChat = '@jupyterlite/ai:save-chat';
13
+ CommandIds.restoreChat = '@jupyterlite/ai:restore-chat';
12
14
  })(CommandIds || (CommandIds = {}));
13
15
  /**
14
16
  * The tool registry token.
15
17
  */
16
- export const IToolRegistry = new Token('@jupyterlite/ai:tool-registry', 'Tool registry for AI agent functionality');
18
+ export const IToolRegistry = new Token('@jupyterlite/ai:IToolRegistry', 'Tool registry for AI agent functionality');
17
19
  /**
18
20
  * The skill registry token.
19
21
  */
20
- export const ISkillRegistry = new Token('@jupyterlite/ai:skill-registry', 'Skill registry for AI agent functionality');
22
+ export const ISkillRegistry = new Token('@jupyterlite/ai:ISkillRegistry', 'Skill registry for AI agent functionality');
21
23
  /**
22
24
  * Token for the provider registry.
23
25
  */
24
- export const IProviderRegistry = new Token('@jupyterlite/ai:provider-registry', 'Registry for AI providers');
26
+ export const IProviderRegistry = new Token('@jupyterlite/ai:IProviderRegistry', 'Registry for AI providers');
25
27
  /**
26
28
  * Token for the AI settings model.
27
29
  */
@@ -29,18 +31,21 @@ export const IAISettingsModel = new Token('@jupyterlite/ai:IAISettingsModel');
29
31
  /**
30
32
  * Token for the agent manager.
31
33
  */
32
- export const IAgentManager = new Token('@jupyterlite/ai:agent-manager');
33
- /**
34
- * The string that replaces a secret key in settings.
35
- */
36
- export const SECRETS_NAMESPACE = '@jupyterlite/ai:providers';
37
- export const SECRETS_REPLACEMENT = '***';
34
+ export const IAgentManager = new Token('@jupyterlite/ai:IAgentManager');
38
35
  /*
39
- * Token for the agent manager registry.
36
+ * Token for the agent manager factory.
37
+ */
38
+ export const IAgentManagerFactory = new Token('@jupyterlite/ai:IAgentManagerFactory');
39
+ /**
40
+ * Token for the chat model handler.
40
41
  */
41
- export const IAgentManagerFactory = new Token('@jupyterlite/ai:agent-manager-factory');
42
- export const IChatModelHandler = new Token('@jupyterlite/ai:chat-model-handler');
42
+ export const IChatModelHandler = new Token('@jupyterlite/ai:IChatModelHandler');
43
43
  /**
44
44
  * Token for the diff manager.
45
45
  */
46
- export const IDiffManager = new Token('@jupyterlite/ai:diff-manager');
46
+ export const IDiffManager = new Token('@jupyterlite/ai:IDiffManager');
47
+ /**
48
+ * The string that replaces a secret key in settings.
49
+ */
50
+ export const SECRETS_NAMESPACE = '@jupyterlite/ai:providers';
51
+ export const SECRETS_REPLACEMENT = '***';
@@ -1,6 +1,5 @@
1
1
  import { CommandRegistry } from '@lumino/commands';
2
- import { ITool } from '../tokens';
3
- import { AISettingsModel } from '../models/settings-model';
2
+ import type { IAISettingsModel, ITool } from '../tokens';
4
3
  /**
5
4
  * Create a tool to discover all available commands and their metadata
6
5
  */
@@ -9,4 +8,4 @@ export declare function createDiscoverCommandsTool(commands: CommandRegistry): I
9
8
  * Create a tool to execute a specific JupyterLab command.
10
9
  * Commands in the settings' commandsRequiringApproval list will need approval.
11
10
  */
12
- export declare function createExecuteCommandTool(commands: CommandRegistry, settingsModel: AISettingsModel): ITool;
11
+ export declare function createExecuteCommandTool(commands: CommandRegistry, settingsModel: IAISettingsModel): ITool;
@@ -2,9 +2,7 @@ import { IThemeManager } from '@jupyterlab/apputils';
2
2
  import { ReactWidget } from '@jupyterlab/ui-components';
3
3
  import type { TranslationBundle } from '@jupyterlab/translation';
4
4
  import React from 'react';
5
- import { AgentManagerFactory } from '../agent';
6
- import { AISettingsModel } from '../models/settings-model';
7
- import { type IAISecretsAccess, type IProviderRegistry } from '../tokens';
5
+ import { type IAgentManagerFactory, type IAISecretsAccess, type IAISettingsModel, type IProviderRegistry } from '../tokens';
8
6
  /**
9
7
  * A JupyterLab widget for AI settings configuration
10
8
  */
@@ -34,8 +32,8 @@ export declare namespace AISettingsWidget {
34
32
  * Options interface for constructing an AISettingsWidget
35
33
  */
36
34
  interface IOptions {
37
- settingsModel: AISettingsModel;
38
- agentManagerFactory?: AgentManagerFactory;
35
+ settingsModel: IAISettingsModel;
36
+ agentManagerFactory?: IAgentManagerFactory;
39
37
  themeManager?: IThemeManager;
40
38
  providerRegistry: IProviderRegistry;
41
39
  /**
@@ -13,6 +13,7 @@ import MoreVert from '@mui/icons-material/MoreVert';
13
13
  import Settings from '@mui/icons-material/Settings';
14
14
  import { Alert, Box, Button, Card, CardContent, Chip, Dialog, DialogActions, DialogContent, DialogTitle, Divider, FormControl, FormControlLabel, IconButton, InputLabel, List, ListItem, ListItemText, Menu, MenuItem, Select, Switch, Tab, Tabs, TextField, ThemeProvider, Tooltip, Typography, createTheme } from '@mui/material';
15
15
  import React, { useEffect, useMemo, useState } from 'react';
16
+ import { getEffectiveContextWindow } from '../providers/model-info';
16
17
  import { SECRETS_REPLACEMENT } from '../tokens';
17
18
  import { ProviderConfigDialog } from './provider-config-dialog';
18
19
  /**
@@ -409,6 +410,7 @@ const AISettingsComponent = ({ model, agentManagerFactory, themeManager, provide
409
410
  const providerInfo = providerRegistry.getProviderInfo(provider.provider);
410
411
  const providerToolCapabilities = providerInfo?.providerToolCapabilities;
411
412
  const params = provider.parameters;
413
+ const effectiveContextWindow = getEffectiveContextWindow(provider, providerRegistry);
412
414
  const webSearchEnabled = !!providerToolCapabilities?.webSearch &&
413
415
  provider.customSettings?.webSearch?.enabled === true;
414
416
  const webFetchEnabled = !!providerToolCapabilities?.webFetch &&
@@ -444,6 +446,7 @@ const AISettingsComponent = ({ model, agentManagerFactory, themeManager, provide
444
446
  (params?.temperature !== undefined ||
445
447
  params?.maxOutputTokens !== undefined ||
446
448
  params?.maxTurns !== undefined ||
449
+ effectiveContextWindow !== undefined ||
447
450
  webSearchEnabled ||
448
451
  webFetchEnabled) && (React.createElement(Box, { sx: {
449
452
  display: 'flex',
@@ -454,6 +457,7 @@ const AISettingsComponent = ({ model, agentManagerFactory, themeManager, provide
454
457
  params?.temperature !== undefined && (React.createElement(Chip, { label: trans.__('Temp: %1', params.temperature), size: "small", variant: "outlined" })),
455
458
  params?.maxOutputTokens !== undefined && (React.createElement(Chip, { label: trans.__('Tokens: %1', params.maxOutputTokens), size: "small", variant: "outlined" })),
456
459
  params?.maxTurns !== undefined && (React.createElement(Chip, { label: trans.__('Turns: %1', params.maxTurns), size: "small", variant: "outlined" })),
460
+ effectiveContextWindow !== undefined && (React.createElement(Chip, { label: trans.__('Context: %1', effectiveContextWindow), size: "small", variant: "outlined" })),
457
461
  webSearchEnabled && (React.createElement(Chip, { label: trans.__('Web Search'), size: "small", variant: "outlined", color: "info" })),
458
462
  webFetchEnabled && (React.createElement(Chip, { label: trans.__('Web Fetch'), size: "small", variant: "outlined", color: "info" }))))),
459
463
  React.createElement(IconButton, { onClick: e => handleMenuClick(e, provider.id), size: "small" },
@@ -483,6 +487,11 @@ const AISettingsComponent = ({ model, agentManagerFactory, themeManager, provide
483
487
  }), color: "primary" }), label: React.createElement(Box, null,
484
488
  React.createElement(Typography, { variant: "body1" }, trans.__('Show Token Usage')),
485
489
  React.createElement(Typography, { variant: "caption", color: "text.secondary" }, trans.__('Display token usage information in the chat toolbar'))) }),
490
+ React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: config.showContextUsage, onChange: e => handleConfigUpdate({
491
+ showContextUsage: e.target.checked
492
+ }), color: "primary" }), label: React.createElement(Box, null,
493
+ React.createElement(Typography, { variant: "body1" }, trans.__('Show Context Usage')),
494
+ React.createElement(Typography, { variant: "caption", color: "text.secondary" }, trans.__('Display estimated context usage in the chat toolbar'))) }),
486
495
  React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: config.showCellDiff, onChange: e => handleConfigUpdate({
487
496
  showCellDiff: e.target.checked
488
497
  }), color: "primary" }), label: React.createElement(Box, null,
@@ -500,6 +509,9 @@ const AISettingsComponent = ({ model, agentManagerFactory, themeManager, provide
500
509
  }), color: "primary" }), label: React.createElement(Box, null,
501
510
  React.createElement(Typography, { variant: "body1" }, trans.__('Show File Diff')),
502
511
  React.createElement(Typography, { variant: "caption", color: "text.secondary" }, trans.__('Show diff view when AI modifies file content'))) }),
512
+ React.createElement(TextField, { fullWidth: true, label: trans.__('Chat Backup Directory'), value: config.chatBackupDirectory, onChange: e => handleConfigUpdate({
513
+ chatBackupDirectory: e.target.value
514
+ }), helperText: trans.__('Directory where chat history backups are saved (relative to the server root)') }),
503
515
  React.createElement(Divider, { sx: { my: 1 } }),
504
516
  React.createElement(TextField, { fullWidth: true, multiline: true, rows: 3, label: trans.__('System Prompt'), value: systemPromptValue, onChange: e => handleSystemPromptChange(e.target.value), placeholder: trans.__("Define the AI's behavior and personality..."), helperText: trans.__('Instructions that define how the AI should behave and respond') }),
505
517
  React.createElement(TextField, { fullWidth: true, multiline: true, rows: 3, label: trans.__('Completion System Prompt'), value: completionPromptValue, onChange: e => handleCompletionPromptChange(e.target.value), placeholder: trans.__('Define how the AI should generate code completions...'), helperText: trans.__('Instructions that define how the AI should generate code completions') }),
@@ -3,11 +3,11 @@ import { MainAreaWidget } from '@jupyterlab/apputils';
3
3
  import type { TranslationBundle } from '@jupyterlab/translation';
4
4
  import { CommandRegistry } from '@lumino/commands';
5
5
  import { AIChatModel } from '../chat-model';
6
- import { AISettingsModel } from '../models/settings-model';
6
+ import { type IAISettingsModel } from '../tokens';
7
7
  export declare namespace MainAreaChat {
8
8
  interface IOptions extends MainAreaWidget.IOptions<ChatWidget> {
9
9
  commands: CommandRegistry;
10
- settingsModel: AISettingsModel;
10
+ settingsModel: IAISettingsModel;
11
11
  trans: TranslationBundle;
12
12
  }
13
13
  }
@@ -26,6 +26,5 @@ export declare class MainAreaChat extends MainAreaWidget<ChatWidget> {
26
26
  */
27
27
  get area(): string | undefined;
28
28
  private _writersChanged;
29
- private _approvalButtons;
30
29
  private _outputAreaCompat;
31
30
  }