@jupyterlite/ai 0.8.0 → 0.9.0-a0

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 (162) hide show
  1. package/lib/agent.d.ts +233 -0
  2. package/lib/agent.js +604 -0
  3. package/lib/chat-model.d.ts +195 -0
  4. package/lib/chat-model.js +590 -0
  5. package/lib/completion/completion-provider.d.ts +83 -0
  6. package/lib/completion/completion-provider.js +209 -0
  7. package/lib/completion/index.d.ts +1 -0
  8. package/lib/completion/index.js +1 -0
  9. package/lib/components/clear-button.d.ts +18 -0
  10. package/lib/components/clear-button.js +31 -0
  11. package/lib/components/index.d.ts +3 -0
  12. package/lib/components/index.js +3 -0
  13. package/lib/components/model-select.d.ts +19 -0
  14. package/lib/components/model-select.js +154 -0
  15. package/lib/components/stop-button.d.ts +3 -3
  16. package/lib/components/stop-button.js +8 -9
  17. package/lib/components/token-usage-display.d.ts +45 -0
  18. package/lib/components/token-usage-display.js +74 -0
  19. package/lib/components/tool-select.d.ts +27 -0
  20. package/lib/components/tool-select.js +130 -0
  21. package/lib/icons.d.ts +3 -1
  22. package/lib/icons.js +10 -13
  23. package/lib/index.d.ts +4 -5
  24. package/lib/index.js +322 -167
  25. package/lib/mcp/browser.d.ts +68 -0
  26. package/lib/mcp/browser.js +132 -0
  27. package/lib/models/settings-model.d.ts +69 -0
  28. package/lib/models/settings-model.js +295 -0
  29. package/lib/providers/built-in-providers.d.ts +9 -0
  30. package/lib/providers/built-in-providers.js +192 -0
  31. package/lib/providers/models.d.ts +37 -0
  32. package/lib/providers/models.js +28 -0
  33. package/lib/providers/provider-registry.d.ts +94 -0
  34. package/lib/providers/provider-registry.js +155 -0
  35. package/lib/tokens.d.ts +157 -86
  36. package/lib/tokens.js +16 -12
  37. package/lib/tools/commands.d.ts +11 -0
  38. package/lib/tools/commands.js +126 -0
  39. package/lib/tools/file.d.ts +27 -0
  40. package/lib/tools/file.js +262 -0
  41. package/lib/tools/notebook.d.ts +40 -0
  42. package/lib/tools/notebook.js +762 -0
  43. package/lib/tools/tool-registry.d.ts +35 -0
  44. package/lib/tools/tool-registry.js +55 -0
  45. package/lib/widgets/ai-settings.d.ts +39 -0
  46. package/lib/widgets/ai-settings.js +506 -0
  47. package/lib/widgets/chat-wrapper.d.ts +144 -0
  48. package/lib/widgets/chat-wrapper.js +390 -0
  49. package/lib/widgets/provider-config-dialog.d.ts +13 -0
  50. package/lib/widgets/provider-config-dialog.js +104 -0
  51. package/package.json +150 -41
  52. package/schema/settings-model.json +153 -0
  53. package/src/agent.ts +800 -0
  54. package/src/chat-model.ts +770 -0
  55. package/src/completion/completion-provider.ts +308 -0
  56. package/src/completion/index.ts +1 -0
  57. package/src/components/clear-button.tsx +56 -0
  58. package/src/components/index.ts +3 -0
  59. package/src/components/model-select.tsx +245 -0
  60. package/src/components/stop-button.tsx +11 -11
  61. package/src/components/token-usage-display.tsx +130 -0
  62. package/src/components/tool-select.tsx +218 -0
  63. package/src/icons.ts +12 -14
  64. package/src/index.ts +468 -238
  65. package/src/mcp/browser.ts +213 -0
  66. package/src/models/settings-model.ts +409 -0
  67. package/src/providers/built-in-providers.ts +216 -0
  68. package/src/providers/models.ts +79 -0
  69. package/src/providers/provider-registry.ts +189 -0
  70. package/src/tokens.ts +203 -90
  71. package/src/tools/commands.ts +151 -0
  72. package/src/tools/file.ts +307 -0
  73. package/src/tools/notebook.ts +964 -0
  74. package/src/tools/tool-registry.ts +63 -0
  75. package/src/types.d.ts +4 -0
  76. package/src/widgets/ai-settings.tsx +1100 -0
  77. package/src/widgets/chat-wrapper.tsx +543 -0
  78. package/src/widgets/provider-config-dialog.tsx +256 -0
  79. package/style/base.css +335 -14
  80. package/style/icons/jupyternaut-lite.svg +1 -1
  81. package/lib/base-completer.d.ts +0 -49
  82. package/lib/base-completer.js +0 -14
  83. package/lib/chat-handler.d.ts +0 -56
  84. package/lib/chat-handler.js +0 -201
  85. package/lib/completion-provider.d.ts +0 -34
  86. package/lib/completion-provider.js +0 -32
  87. package/lib/default-prompts.d.ts +0 -2
  88. package/lib/default-prompts.js +0 -31
  89. package/lib/default-providers/Anthropic/completer.d.ts +0 -12
  90. package/lib/default-providers/Anthropic/completer.js +0 -46
  91. package/lib/default-providers/Anthropic/settings-schema.json +0 -70
  92. package/lib/default-providers/ChromeAI/completer.d.ts +0 -12
  93. package/lib/default-providers/ChromeAI/completer.js +0 -56
  94. package/lib/default-providers/ChromeAI/instructions.d.ts +0 -6
  95. package/lib/default-providers/ChromeAI/instructions.js +0 -42
  96. package/lib/default-providers/ChromeAI/settings-schema.json +0 -18
  97. package/lib/default-providers/Gemini/completer.d.ts +0 -12
  98. package/lib/default-providers/Gemini/completer.js +0 -48
  99. package/lib/default-providers/Gemini/instructions.d.ts +0 -2
  100. package/lib/default-providers/Gemini/instructions.js +0 -9
  101. package/lib/default-providers/Gemini/settings-schema.json +0 -64
  102. package/lib/default-providers/MistralAI/completer.d.ts +0 -13
  103. package/lib/default-providers/MistralAI/completer.js +0 -52
  104. package/lib/default-providers/MistralAI/instructions.d.ts +0 -2
  105. package/lib/default-providers/MistralAI/instructions.js +0 -18
  106. package/lib/default-providers/MistralAI/settings-schema.json +0 -75
  107. package/lib/default-providers/Ollama/completer.d.ts +0 -12
  108. package/lib/default-providers/Ollama/completer.js +0 -43
  109. package/lib/default-providers/Ollama/instructions.d.ts +0 -2
  110. package/lib/default-providers/Ollama/instructions.js +0 -70
  111. package/lib/default-providers/Ollama/settings-schema.json +0 -143
  112. package/lib/default-providers/OpenAI/completer.d.ts +0 -12
  113. package/lib/default-providers/OpenAI/completer.js +0 -43
  114. package/lib/default-providers/OpenAI/settings-schema.json +0 -628
  115. package/lib/default-providers/WebLLM/completer.d.ts +0 -21
  116. package/lib/default-providers/WebLLM/completer.js +0 -127
  117. package/lib/default-providers/WebLLM/instructions.d.ts +0 -6
  118. package/lib/default-providers/WebLLM/instructions.js +0 -32
  119. package/lib/default-providers/WebLLM/settings-schema.json +0 -19
  120. package/lib/default-providers/index.d.ts +0 -2
  121. package/lib/default-providers/index.js +0 -179
  122. package/lib/provider.d.ts +0 -144
  123. package/lib/provider.js +0 -412
  124. package/lib/settings/base.json +0 -7
  125. package/lib/settings/index.d.ts +0 -3
  126. package/lib/settings/index.js +0 -3
  127. package/lib/settings/panel.d.ts +0 -226
  128. package/lib/settings/panel.js +0 -510
  129. package/lib/settings/textarea.d.ts +0 -2
  130. package/lib/settings/textarea.js +0 -18
  131. package/lib/settings/utils.d.ts +0 -2
  132. package/lib/settings/utils.js +0 -4
  133. package/lib/types/ai-model.d.ts +0 -24
  134. package/lib/types/ai-model.js +0 -5
  135. package/schema/chat.json +0 -28
  136. package/schema/provider-registry.json +0 -29
  137. package/schema/system-prompts.json +0 -22
  138. package/src/base-completer.ts +0 -75
  139. package/src/chat-handler.ts +0 -262
  140. package/src/completion-provider.ts +0 -64
  141. package/src/default-prompts.ts +0 -33
  142. package/src/default-providers/Anthropic/completer.ts +0 -59
  143. package/src/default-providers/ChromeAI/completer.ts +0 -73
  144. package/src/default-providers/ChromeAI/instructions.ts +0 -45
  145. package/src/default-providers/Gemini/completer.ts +0 -61
  146. package/src/default-providers/Gemini/instructions.ts +0 -9
  147. package/src/default-providers/MistralAI/completer.ts +0 -69
  148. package/src/default-providers/MistralAI/instructions.ts +0 -18
  149. package/src/default-providers/Ollama/completer.ts +0 -54
  150. package/src/default-providers/Ollama/instructions.ts +0 -70
  151. package/src/default-providers/OpenAI/completer.ts +0 -54
  152. package/src/default-providers/WebLLM/completer.ts +0 -151
  153. package/src/default-providers/WebLLM/instructions.ts +0 -33
  154. package/src/default-providers/index.ts +0 -211
  155. package/src/global.d.ts +0 -9
  156. package/src/provider.ts +0 -514
  157. package/src/settings/index.ts +0 -3
  158. package/src/settings/panel.tsx +0 -773
  159. package/src/settings/textarea.tsx +0 -33
  160. package/src/settings/utils.ts +0 -5
  161. package/src/types/ai-model.ts +0 -37
  162. package/src/types/service-worker.d.ts +0 -6
@@ -0,0 +1,130 @@
1
+ import { ReactWidget, UseSignal } from '@jupyterlab/ui-components';
2
+ import React from 'react';
3
+ import { ISignal } from '@lumino/signaling';
4
+ import { AISettingsModel } from '../models/settings-model';
5
+ import { ITokenUsage } from '../tokens';
6
+
7
+ /**
8
+ * Props for the TokenUsageDisplay component.
9
+ */
10
+ export interface ITokenUsageDisplayProps {
11
+ /**
12
+ * The token usage changed signal
13
+ */
14
+ tokenUsageChanged: ISignal<any, ITokenUsage>;
15
+
16
+ /**
17
+ * The settings model instance for configuration options
18
+ */
19
+ settingsModel: AISettingsModel;
20
+ }
21
+
22
+ /**
23
+ * React component that displays token usage information.
24
+ * Shows input/output token counts with up/down arrows.
25
+ * Only renders when token usage display is enabled in settings.
26
+ */
27
+ export const TokenUsageDisplay: React.FC<ITokenUsageDisplayProps> = ({
28
+ tokenUsageChanged,
29
+ settingsModel
30
+ }) => {
31
+ return (
32
+ <UseSignal signal={settingsModel.stateChanged} initialArgs={undefined}>
33
+ {() => {
34
+ const config = settingsModel.config;
35
+ if (!config.showTokenUsage) {
36
+ return null;
37
+ }
38
+
39
+ return (
40
+ <UseSignal signal={tokenUsageChanged}>
41
+ {(_, tokenUsage: ITokenUsage | null | undefined) => {
42
+ if (!tokenUsage) {
43
+ return null;
44
+ }
45
+
46
+ const total = tokenUsage.inputTokens + tokenUsage.outputTokens;
47
+ if (total === 0) {
48
+ return null;
49
+ }
50
+
51
+ return (
52
+ <div
53
+ style={{
54
+ display: 'flex',
55
+ alignItems: 'center',
56
+ gap: '6px',
57
+ fontSize: '12px',
58
+ color: 'var(--jp-ui-font-color2)',
59
+ padding: '4px 8px',
60
+ backgroundColor: 'var(--jp-layout-color1)',
61
+ border: '1px solid var(--jp-border-color1)',
62
+ borderRadius: '4px',
63
+ whiteSpace: 'nowrap'
64
+ }}
65
+ title={`Token Usage - Sent: ${tokenUsage.inputTokens.toLocaleString()}, Received: ${tokenUsage.outputTokens.toLocaleString()}, Total: ${total.toLocaleString()}`}
66
+ >
67
+ <span
68
+ style={{
69
+ display: 'flex',
70
+ alignItems: 'center',
71
+ gap: '2px'
72
+ }}
73
+ >
74
+ <span>↑</span>
75
+ <span>{tokenUsage.inputTokens.toLocaleString()}</span>
76
+ </span>
77
+ <span
78
+ style={{
79
+ display: 'flex',
80
+ alignItems: 'center',
81
+ gap: '2px'
82
+ }}
83
+ >
84
+ <span>↓</span>
85
+ <span>{tokenUsage.outputTokens.toLocaleString()}</span>
86
+ </span>
87
+ </div>
88
+ );
89
+ }}
90
+ </UseSignal>
91
+ );
92
+ }}
93
+ </UseSignal>
94
+ );
95
+ };
96
+
97
+ /**
98
+ * JupyterLab widget wrapper for the TokenUsageDisplay component.
99
+ * Extends ReactWidget to integrate with the JupyterLab widget system.
100
+ */
101
+ export class TokenUsageWidget extends ReactWidget {
102
+ /**
103
+ * Creates a new TokenUsageWidget instance.
104
+ * @param options - Configuration options containing required models
105
+ */
106
+ constructor(options: {
107
+ tokenUsageChanged: ISignal<any, ITokenUsage>;
108
+ settingsModel: AISettingsModel;
109
+ }) {
110
+ super();
111
+ this._tokenUsageChanged = options.tokenUsageChanged;
112
+ this._settingsModel = options.settingsModel;
113
+ }
114
+
115
+ /**
116
+ * Renders the React component within the widget.
117
+ * @returns The TokenUsageDisplay React element
118
+ */
119
+ protected render(): React.ReactElement {
120
+ return (
121
+ <TokenUsageDisplay
122
+ tokenUsageChanged={this._tokenUsageChanged}
123
+ settingsModel={this._settingsModel}
124
+ />
125
+ );
126
+ }
127
+
128
+ private _tokenUsageChanged: ISignal<any, ITokenUsage>;
129
+ private _settingsModel: AISettingsModel;
130
+ }
@@ -0,0 +1,218 @@
1
+ import { InputToolbarRegistry, TooltippedButton } from '@jupyter/chat';
2
+
3
+ import BuildIcon from '@mui/icons-material/Build';
4
+
5
+ import CheckIcon from '@mui/icons-material/Check';
6
+
7
+ import { Menu, MenuItem, Tooltip, Typography } from '@mui/material';
8
+
9
+ import React, { useCallback, useEffect, useState } from 'react';
10
+
11
+ import { INamedTool, IToolRegistry } from '../tokens';
12
+ import { AIChatModel } from '../chat-model';
13
+
14
+ const SELECT_ITEM_CLASS = 'jp-AIToolSelect-item';
15
+
16
+ /**
17
+ * Properties for the tool select component.
18
+ */
19
+ export interface IToolSelectProps
20
+ extends InputToolbarRegistry.IToolbarItemProps {
21
+ /**
22
+ * The tool registry to get available tools from.
23
+ */
24
+ toolRegistry: IToolRegistry;
25
+
26
+ /**
27
+ * Whether tools are enabled.
28
+ */
29
+ toolsEnabled: boolean;
30
+
31
+ /**
32
+ * Function to handle tool selection changes.
33
+ */
34
+ onToolSelectionChange: (selectedToolNames: string[]) => void;
35
+ }
36
+
37
+ /**
38
+ * The tool select component for choosing AI tools.
39
+ */
40
+ export function ToolSelect(props: IToolSelectProps): JSX.Element {
41
+ const { toolRegistry, onToolSelectionChange, toolsEnabled } = props;
42
+
43
+ const [selectedToolNames, setSelectedToolNames] = useState<string[]>([]);
44
+ const [tools, setTools] = useState<INamedTool[]>(
45
+ toolRegistry?.namedTools || []
46
+ );
47
+ const [menuAnchorEl, setMenuAnchorEl] = useState<HTMLElement | null>(null);
48
+ const [menuOpen, setMenuOpen] = useState(false);
49
+
50
+ const openMenu = useCallback((el: HTMLElement | null) => {
51
+ setMenuAnchorEl(el);
52
+ setMenuOpen(true);
53
+ }, []);
54
+
55
+ const closeMenu = useCallback(() => {
56
+ setMenuOpen(false);
57
+ }, []);
58
+
59
+ const toggleTool = useCallback(
60
+ (toolName: string) => {
61
+ const currentToolNames = [...selectedToolNames];
62
+ const index = currentToolNames.indexOf(toolName);
63
+
64
+ if (index !== -1) {
65
+ // Remove tool
66
+ currentToolNames.splice(index, 1);
67
+ } else {
68
+ // Add tool
69
+ currentToolNames.push(toolName);
70
+ }
71
+
72
+ setSelectedToolNames(currentToolNames);
73
+ onToolSelectionChange(currentToolNames);
74
+ },
75
+ [selectedToolNames, onToolSelectionChange]
76
+ );
77
+
78
+ // Update tools when registry changes
79
+ useEffect(() => {
80
+ const updateTools = () => {
81
+ const newTools = toolRegistry?.namedTools || [];
82
+ setTools(newTools);
83
+ };
84
+
85
+ if (toolRegistry) {
86
+ updateTools();
87
+ toolRegistry.toolsChanged.connect(updateTools);
88
+ return () => {
89
+ toolRegistry.toolsChanged.disconnect(updateTools);
90
+ };
91
+ }
92
+ }, [toolRegistry]);
93
+
94
+ // Initialize selected tools to all tools by default
95
+ useEffect(() => {
96
+ if (tools.length > 0 && selectedToolNames.length === 0) {
97
+ const defaultToolNames = tools.map(tool => tool.name);
98
+ setSelectedToolNames(defaultToolNames);
99
+ onToolSelectionChange(defaultToolNames);
100
+ }
101
+ }, [tools, selectedToolNames.length, onToolSelectionChange]);
102
+
103
+ // Don't render if tools are disabled or no tools available
104
+ if (!toolsEnabled || tools.length === 0) {
105
+ return <></>;
106
+ }
107
+
108
+ return (
109
+ <>
110
+ <TooltippedButton
111
+ onClick={e => {
112
+ openMenu(e.currentTarget);
113
+ }}
114
+ tooltip={`Tools (${selectedToolNames.length}/${tools.length} selected)`}
115
+ buttonProps={{
116
+ size: 'small',
117
+ variant: selectedToolNames.length > 0 ? 'contained' : 'outlined',
118
+ color: 'primary',
119
+ title: 'Select AI Tools',
120
+ onKeyDown: e => {
121
+ if (e.key !== 'Enter' && e.key !== ' ') {
122
+ return;
123
+ }
124
+ openMenu(e.currentTarget);
125
+ // Stop propagation to prevent sending message
126
+ e.stopPropagation();
127
+ }
128
+ }}
129
+ sx={
130
+ selectedToolNames.length === 0
131
+ ? { backgroundColor: 'var(--jp-layout-color3)' }
132
+ : {}
133
+ }
134
+ >
135
+ <BuildIcon />
136
+ </TooltippedButton>
137
+
138
+ <Menu
139
+ open={menuOpen}
140
+ onClose={closeMenu}
141
+ anchorEl={menuAnchorEl}
142
+ anchorOrigin={{
143
+ vertical: 'top',
144
+ horizontal: 'right'
145
+ }}
146
+ transformOrigin={{
147
+ vertical: 'bottom',
148
+ horizontal: 'right'
149
+ }}
150
+ sx={{
151
+ '& .MuiMenuItem-root': {
152
+ padding: '0.5em',
153
+ paddingRight: '2em'
154
+ }
155
+ }}
156
+ >
157
+ {tools.map(namedTool => (
158
+ <Tooltip
159
+ key={namedTool.name}
160
+ title={namedTool.tool.description || namedTool.name}
161
+ placement="left"
162
+ >
163
+ <MenuItem
164
+ className={SELECT_ITEM_CLASS}
165
+ onClick={e => {
166
+ toggleTool(namedTool.name);
167
+ // Prevent sending message on tool selection
168
+ e.stopPropagation();
169
+ }}
170
+ >
171
+ {selectedToolNames.includes(namedTool.name) ? (
172
+ <CheckIcon
173
+ sx={{
174
+ marginRight: '8px',
175
+ color: 'var(--jp-brand-color1, #2196F3)'
176
+ }}
177
+ />
178
+ ) : (
179
+ <div style={{ width: '24px', marginRight: '8px' }} />
180
+ )}
181
+ <Typography variant="body2">{namedTool.name}</Typography>
182
+ </MenuItem>
183
+ </Tooltip>
184
+ ))}
185
+ </Menu>
186
+ </>
187
+ );
188
+ }
189
+
190
+ /**
191
+ * Factory function returning the toolbar item for tool selection.
192
+ */
193
+ export function createToolSelectItem(
194
+ toolRegistry: IToolRegistry,
195
+ toolsEnabled: boolean = true
196
+ ): InputToolbarRegistry.IToolbarItem {
197
+ return {
198
+ element: (props: InputToolbarRegistry.IToolbarItemProps) => {
199
+ const onToolSelectionChange = (tools: string[]) => {
200
+ const chatContext = props.model
201
+ .chatContext as AIChatModel.IAIChatContext;
202
+ if (!chatContext.agentManager) {
203
+ return;
204
+ }
205
+ chatContext.agentManager.setSelectedTools(tools);
206
+ };
207
+
208
+ const toolSelectProps: IToolSelectProps = {
209
+ ...props,
210
+ toolRegistry,
211
+ onToolSelectionChange,
212
+ toolsEnabled
213
+ };
214
+ return <ToolSelect {...toolSelectProps} />;
215
+ },
216
+ position: 1
217
+ };
218
+ }
package/src/icons.ts CHANGED
@@ -1,18 +1,16 @@
1
- /*
2
- * Copyright (c) Jupyter Development Team.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
-
6
1
  import { LabIcon } from '@jupyterlab/ui-components';
7
2
 
8
- /**
9
- * This icon is based on the jupyternaut icon from Jupyter AI:
10
- * https://github.com/jupyterlab/jupyter-ai/blob/main/packages/jupyter-ai/style/icons/jupyternaut.svg
11
- * With a small tweak for the colors to match the JupyterLite icon.
12
- */
13
- import jupyternautLiteSvg from '../style/icons/jupyternaut-lite.svg';
3
+ import labaiIconSvg from '../style/icons/jupyternaut-lite.svg';
4
+
5
+ export const labaiIcon = new LabIcon({
6
+ name: '@jupyterlite/ai:icon',
7
+ svgstr: labaiIconSvg
8
+ });
14
9
 
15
- export const jupyternautLiteIcon = new LabIcon({
16
- name: '@jupyterlite/ai:jupyternaut-lite',
17
- svgstr: jupyternautLiteSvg
10
+ export const jupyternautIcon = new LabIcon({
11
+ name: '@jupyterlite/ai:jupyternaut',
12
+ svgstr: labaiIconSvg
18
13
  });
14
+
15
+ const AI_AVATAR_BASE64 = btoa(jupyternautIcon.svgstr);
16
+ export const AI_AVATAR = `data:image/svg+xml;base64,${AI_AVATAR_BASE64}`;