@jupyterlite/ai 0.9.1 → 0.11.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 (71) hide show
  1. package/README.md +5 -214
  2. package/lib/agent.d.ts +58 -66
  3. package/lib/agent.js +291 -310
  4. package/lib/approval-buttons.d.ts +19 -82
  5. package/lib/approval-buttons.js +36 -289
  6. package/lib/chat-model-registry.d.ts +6 -0
  7. package/lib/chat-model-registry.js +4 -1
  8. package/lib/chat-model.d.ts +26 -54
  9. package/lib/chat-model.js +277 -303
  10. package/lib/components/clear-button.d.ts +6 -1
  11. package/lib/components/clear-button.js +10 -6
  12. package/lib/components/completion-status.d.ts +5 -0
  13. package/lib/components/completion-status.js +5 -4
  14. package/lib/components/model-select.d.ts +6 -1
  15. package/lib/components/model-select.js +13 -16
  16. package/lib/components/stop-button.d.ts +6 -1
  17. package/lib/components/stop-button.js +12 -8
  18. package/lib/components/token-usage-display.d.ts +5 -0
  19. package/lib/components/token-usage-display.js +2 -2
  20. package/lib/components/tool-select.d.ts +6 -1
  21. package/lib/components/tool-select.js +10 -9
  22. package/lib/index.d.ts +1 -0
  23. package/lib/index.js +61 -81
  24. package/lib/models/settings-model.d.ts +1 -1
  25. package/lib/models/settings-model.js +40 -26
  26. package/lib/providers/built-in-providers.js +38 -19
  27. package/lib/providers/models.d.ts +3 -3
  28. package/lib/providers/provider-registry.d.ts +3 -4
  29. package/lib/providers/provider-registry.js +1 -4
  30. package/lib/tokens.d.ts +5 -6
  31. package/lib/tools/commands.d.ts +2 -1
  32. package/lib/tools/commands.js +36 -49
  33. package/lib/widgets/ai-settings.d.ts +6 -0
  34. package/lib/widgets/ai-settings.js +72 -71
  35. package/lib/widgets/main-area-chat.d.ts +2 -0
  36. package/lib/widgets/main-area-chat.js +5 -2
  37. package/lib/widgets/provider-config-dialog.d.ts +2 -0
  38. package/lib/widgets/provider-config-dialog.js +34 -34
  39. package/package.json +13 -13
  40. package/schema/settings-model.json +3 -2
  41. package/src/agent.ts +360 -372
  42. package/src/approval-buttons.ts +43 -389
  43. package/src/chat-model-registry.ts +9 -1
  44. package/src/chat-model.ts +399 -370
  45. package/src/completion/completion-provider.ts +2 -3
  46. package/src/components/clear-button.tsx +18 -6
  47. package/src/components/completion-status.tsx +18 -4
  48. package/src/components/model-select.tsx +25 -16
  49. package/src/components/stop-button.tsx +22 -9
  50. package/src/components/token-usage-display.tsx +14 -2
  51. package/src/components/tool-select.tsx +27 -9
  52. package/src/index.ts +78 -134
  53. package/src/models/settings-model.ts +41 -27
  54. package/src/providers/built-in-providers.ts +38 -19
  55. package/src/providers/models.ts +3 -3
  56. package/src/providers/provider-registry.ts +4 -8
  57. package/src/tokens.ts +5 -6
  58. package/src/tools/commands.ts +40 -53
  59. package/src/widgets/ai-settings.tsx +153 -84
  60. package/src/widgets/main-area-chat.ts +8 -2
  61. package/src/widgets/provider-config-dialog.tsx +54 -41
  62. package/style/base.css +24 -73
  63. package/lib/mcp/browser.d.ts +0 -68
  64. package/lib/mcp/browser.js +0 -138
  65. package/lib/tools/file.d.ts +0 -36
  66. package/lib/tools/file.js +0 -351
  67. package/lib/tools/notebook.d.ts +0 -40
  68. package/lib/tools/notebook.js +0 -779
  69. package/src/mcp/browser.ts +0 -220
  70. package/src/tools/file.ts +0 -438
  71. package/src/tools/notebook.ts +0 -986
@@ -5,8 +5,7 @@ import {
5
5
  IInlineCompletionProvider
6
6
  } from '@jupyterlab/completer';
7
7
  import { NotebookPanel } from '@jupyterlab/notebook';
8
- import { LanguageModelV2 } from '@ai-sdk/provider';
9
- import { generateText } from 'ai';
8
+ import { generateText, type LanguageModel } from 'ai';
10
9
  import { ISecretsManager } from 'jupyter-secrets-manager';
11
10
 
12
11
  import { AISettingsModel } from '../models/settings-model';
@@ -293,7 +292,7 @@ export class AICompletionProvider implements IInlineCompletionProvider {
293
292
 
294
293
  private _settingsModel: AISettingsModel;
295
294
  private _providerRegistry?: IProviderRegistry;
296
- private _model: LanguageModelV2 | null = null;
295
+ private _model: LanguageModel | null = null;
297
296
  private _secretsManager?: ISecretsManager;
298
297
  }
299
298
 
@@ -1,5 +1,7 @@
1
1
  import { InputToolbarRegistry, TooltippedButton } from '@jupyter/chat';
2
2
 
3
+ import type { TranslationBundle } from '@jupyterlab/translation';
4
+
3
5
  import ClearIcon from '@mui/icons-material/Clear';
4
6
 
5
7
  import React from 'react';
@@ -15,22 +17,26 @@ export interface IClearButtonProps
15
17
  * The function to clear messages.
16
18
  */
17
19
  clearMessages: () => void;
20
+ /**
21
+ * The application language translator.
22
+ */
23
+ translator: TranslationBundle;
18
24
  }
19
25
 
20
26
  /**
21
27
  * The clear button component.
22
28
  */
23
29
  export function ClearButton(props: IClearButtonProps): JSX.Element {
24
- const tooltip = 'Clear chat';
30
+ const { translator: trans } = props;
31
+ const tooltip = trans.__('Clear chat');
25
32
  return (
26
33
  <TooltippedButton
27
34
  onClick={props.clearMessages}
28
35
  tooltip={tooltip}
29
36
  buttonProps={{
30
- size: 'small',
37
+ title: tooltip,
31
38
  variant: 'outlined',
32
- color: 'secondary',
33
- title: tooltip
39
+ color: 'secondary'
34
40
  }}
35
41
  >
36
42
  <ClearIcon />
@@ -41,13 +47,19 @@ export function ClearButton(props: IClearButtonProps): JSX.Element {
41
47
  /**
42
48
  * Factory returning the clear button toolbar item.
43
49
  */
44
- export function clearItem(): InputToolbarRegistry.IToolbarItem {
50
+ export function clearItem(
51
+ translator: TranslationBundle
52
+ ): InputToolbarRegistry.IToolbarItem {
45
53
  return {
46
54
  element: (props: InputToolbarRegistry.IToolbarItemProps) => {
47
55
  const { model } = props;
48
56
  const clearMessages = () =>
49
57
  (model.chatContext as AIChatModel.IAIChatContext).clearMessages();
50
- const clearProps: IClearButtonProps = { ...props, clearMessages };
58
+ const clearProps: IClearButtonProps = {
59
+ ...props,
60
+ clearMessages,
61
+ translator
62
+ };
51
63
  return ClearButton(clearProps);
52
64
  },
53
65
  position: 0,
@@ -1,6 +1,7 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { AISettingsModel } from '../models/settings-model';
3
3
  import { ReactWidget } from '@jupyterlab/ui-components';
4
+ import type { TranslationBundle } from '@jupyterlab/translation';
4
5
  import { jupyternautIcon } from '../icons';
5
6
 
6
7
  const COMPLETION_STATUS_CLASS = 'jp-ai-completion-status';
@@ -14,12 +15,17 @@ interface ICompletionStatusProps {
14
15
  * The settings model.
15
16
  */
16
17
  settingsModel: AISettingsModel;
18
+ /**
19
+ * The application language translator.
20
+ */
21
+ translator: TranslationBundle;
17
22
  }
18
23
 
19
24
  /**
20
25
  * The completion status component.
21
26
  */
22
27
  function CompletionStatus(props: ICompletionStatusProps): JSX.Element {
28
+ const { translator: trans } = props;
23
29
  const [disabled, setDisabled] = useState<boolean>(true);
24
30
  const [title, setTitle] = useState<string>('');
25
31
 
@@ -30,15 +36,23 @@ function CompletionStatus(props: ICompletionStatusProps): JSX.Element {
30
36
  const stateChanged = (model: AISettingsModel) => {
31
37
  if (model.config.useSameProviderForChatAndCompleter) {
32
38
  setDisabled(false);
33
- setTitle(`Completion using ${model.getDefaultProvider()?.model}`);
39
+ setTitle(
40
+ trans.__(
41
+ 'Completion using %1',
42
+ model.getDefaultProvider()?.model ?? ''
43
+ )
44
+ );
34
45
  } else if (model.config.activeCompleterProvider) {
35
46
  setDisabled(false);
36
47
  setTitle(
37
- `Completion using ${model.getProvider(model.config.activeCompleterProvider)?.model}`
48
+ trans.__(
49
+ 'Completion using %1',
50
+ model.getProvider(model.config.activeCompleterProvider)?.model ?? ''
51
+ )
38
52
  );
39
53
  } else {
40
54
  setDisabled(true);
41
- setTitle('No completion');
55
+ setTitle(trans.__('No completion'));
42
56
  }
43
57
  };
44
58
 
@@ -48,7 +62,7 @@ function CompletionStatus(props: ICompletionStatusProps): JSX.Element {
48
62
  return () => {
49
63
  props.settingsModel.stateChanged.disconnect(stateChanged);
50
64
  };
51
- }, [props.settingsModel]);
65
+ }, [props.settingsModel, trans]);
52
66
 
53
67
  return (
54
68
  <jupyternautIcon.react
@@ -1,4 +1,5 @@
1
1
  import { InputToolbarRegistry, TooltippedButton } from '@jupyter/chat';
2
+ import type { TranslationBundle } from '@jupyterlab/translation';
2
3
  import CheckIcon from '@mui/icons-material/Check';
3
4
  import { Menu, MenuItem, Typography } from '@mui/material';
4
5
  import React, { useCallback, useEffect, useState } from 'react';
@@ -14,13 +15,17 @@ export interface IModelSelectProps
14
15
  * The settings model to get available models and current selection from.
15
16
  */
16
17
  settingsModel: AISettingsModel;
18
+ /**
19
+ * The application language translator.
20
+ */
21
+ translator: TranslationBundle;
17
22
  }
18
23
 
19
24
  /**
20
25
  * The model select component for choosing AI models.
21
26
  */
22
27
  export function ModelSelect(props: IModelSelectProps): JSX.Element {
23
- const { settingsModel, model } = props;
28
+ const { settingsModel, model, translator: trans } = props;
24
29
  const agentManager = (model.chatContext as AIChatModel.IAIChatContext)
25
30
  .agentManager;
26
31
 
@@ -97,26 +102,27 @@ export function ModelSelect(props: IModelSelectProps): JSX.Element {
97
102
  return (
98
103
  <TooltippedButton
99
104
  onClick={() => {}}
100
- tooltip="No providers configured. Please go to AI Settings to add a provider."
105
+ tooltip={trans.__(
106
+ 'No providers configured. Please go to AI Settings to add a provider.'
107
+ )}
101
108
  buttonProps={{
102
- size: 'small',
103
109
  variant: 'outlined',
104
110
  color: 'warning',
105
111
  disabled: true,
106
- title: 'No Providers Available'
112
+ title: trans.__('No Providers Available')
107
113
  }}
108
114
  sx={{
109
115
  minWidth: 'auto',
116
+ width: 'unset',
110
117
  display: 'flex',
111
- alignItems: 'center',
112
- height: '29px'
118
+ alignItems: 'center'
113
119
  }}
114
120
  >
115
121
  <Typography
116
122
  variant="caption"
117
123
  sx={{ fontSize: '0.7rem', fontWeight: 500 }}
118
124
  >
119
- No Providers
125
+ {trans.__('No Providers')}
120
126
  </Typography>
121
127
  </TooltippedButton>
122
128
  );
@@ -128,12 +134,13 @@ export function ModelSelect(props: IModelSelectProps): JSX.Element {
128
134
  onClick={e => {
129
135
  openMenu(e.currentTarget);
130
136
  }}
131
- tooltip={`Current Model: ${currentProviderLabel} - ${currentModel}`}
137
+ tooltip={trans.__(
138
+ 'Current Model: %1 - %2',
139
+ currentProviderLabel,
140
+ currentModel
141
+ )}
132
142
  buttonProps={{
133
- size: 'small',
134
- variant: 'contained',
135
- color: 'primary',
136
- title: 'Select AI Model',
143
+ title: trans.__('Select AI Model'),
137
144
  onKeyDown: e => {
138
145
  if (e.key !== 'Enter' && e.key !== ' ') {
139
146
  return;
@@ -145,9 +152,9 @@ export function ModelSelect(props: IModelSelectProps): JSX.Element {
145
152
  }}
146
153
  sx={{
147
154
  minWidth: 'auto',
155
+ width: 'unset',
148
156
  display: 'flex',
149
- alignItems: 'center',
150
- height: '29px'
157
+ alignItems: 'center'
151
158
  }}
152
159
  >
153
160
  <Typography
@@ -237,7 +244,8 @@ export function ModelSelect(props: IModelSelectProps): JSX.Element {
237
244
  * Factory function returning the toolbar item for model selection.
238
245
  */
239
246
  export function createModelSelectItem(
240
- settingsModel: AISettingsModel
247
+ settingsModel: AISettingsModel,
248
+ translator: TranslationBundle
241
249
  ): InputToolbarRegistry.IToolbarItem {
242
250
  return {
243
251
  element: (props: InputToolbarRegistry.IToolbarItemProps) => {
@@ -247,7 +255,8 @@ export function createModelSelectItem(
247
255
  }
248
256
  const modelSelectProps: IModelSelectProps = {
249
257
  ...props,
250
- settingsModel
258
+ settingsModel,
259
+ translator
251
260
  };
252
261
  return <ModelSelect {...modelSelectProps} />;
253
262
  },
@@ -1,4 +1,6 @@
1
- import { InputToolbarRegistry, TooltippedButton } from '@jupyter/chat';
1
+ import { InputToolbarRegistry, TooltippedIconButton } from '@jupyter/chat';
2
+
3
+ import type { TranslationBundle } from '@jupyterlab/translation';
2
4
 
3
5
  import StopIcon from '@mui/icons-material/Stop';
4
6
 
@@ -15,39 +17,50 @@ export interface IStopButtonProps
15
17
  * The function to stop streaming.
16
18
  */
17
19
  stopStreaming: () => void;
20
+ /**
21
+ * The application language translator.
22
+ */
23
+ translator: TranslationBundle;
18
24
  }
19
25
 
20
26
  /**
21
27
  * The stop button component.
22
28
  */
23
29
  export function StopButton(props: IStopButtonProps): JSX.Element {
24
- const tooltip = 'Stop streaming';
30
+ const { translator: trans } = props;
31
+ const tooltip = trans.__('Stop streaming');
25
32
  return (
26
- <TooltippedButton
33
+ <TooltippedIconButton
27
34
  onClick={props.stopStreaming}
28
35
  tooltip={tooltip}
29
36
  buttonProps={{
30
- size: 'small',
31
- variant: 'contained',
32
- color: 'error',
33
37
  title: tooltip
34
38
  }}
39
+ sx={{
40
+ backgroundColor: 'var(--mui-palette-error-main, #d32f2f);'
41
+ }}
35
42
  >
36
43
  <StopIcon />
37
- </TooltippedButton>
44
+ </TooltippedIconButton>
38
45
  );
39
46
  }
40
47
 
41
48
  /**
42
49
  * Factory returning the stop button toolbar item.
43
50
  */
44
- export function stopItem(): InputToolbarRegistry.IToolbarItem {
51
+ export function stopItem(
52
+ translator: TranslationBundle
53
+ ): InputToolbarRegistry.IToolbarItem {
45
54
  return {
46
55
  element: (props: InputToolbarRegistry.IToolbarItemProps) => {
47
56
  const { model } = props;
48
57
  const stopStreaming = () =>
49
58
  (model.chatContext as AIChatModel.IAIChatContext).stopStreaming();
50
- const stopProps: IStopButtonProps = { ...props, stopStreaming };
59
+ const stopProps: IStopButtonProps = {
60
+ ...props,
61
+ stopStreaming,
62
+ translator
63
+ };
51
64
  return StopButton(stopProps);
52
65
  },
53
66
  position: 50,
@@ -1,4 +1,5 @@
1
1
  import { ReactWidget, UseSignal } from '@jupyterlab/ui-components';
2
+ import type { TranslationBundle } from '@jupyterlab/translation';
2
3
  import React from 'react';
3
4
  import { ISignal } from '@lumino/signaling';
4
5
  import { AISettingsModel } from '../models/settings-model';
@@ -22,6 +23,11 @@ export interface ITokenUsageDisplayProps {
22
23
  * Initial token usage.
23
24
  */
24
25
  initialTokenUsage?: ITokenUsage;
26
+
27
+ /**
28
+ * The application language translator.
29
+ */
30
+ translator: TranslationBundle;
25
31
  }
26
32
 
27
33
  /**
@@ -32,7 +38,8 @@ export interface ITokenUsageDisplayProps {
32
38
  export const TokenUsageDisplay: React.FC<ITokenUsageDisplayProps> = ({
33
39
  tokenUsageChanged,
34
40
  settingsModel,
35
- initialTokenUsage
41
+ initialTokenUsage,
42
+ translator: trans
36
43
  }) => {
37
44
  return (
38
45
  <UseSignal signal={settingsModel.stateChanged} initialArgs={undefined}>
@@ -68,7 +75,12 @@ export const TokenUsageDisplay: React.FC<ITokenUsageDisplayProps> = ({
68
75
  borderRadius: '4px',
69
76
  whiteSpace: 'nowrap'
70
77
  }}
71
- title={`Token Usage - Sent: ${tokenUsage.inputTokens.toLocaleString()}, Received: ${tokenUsage.outputTokens.toLocaleString()}, Total: ${total.toLocaleString()}`}
78
+ title={trans.__(
79
+ 'Token Usage - Sent: %1, Received: %2, Total: %3',
80
+ tokenUsage.inputTokens.toLocaleString(),
81
+ tokenUsage.outputTokens.toLocaleString(),
82
+ total.toLocaleString()
83
+ )}
72
84
  >
73
85
  <span
74
86
  style={{
@@ -1,5 +1,7 @@
1
1
  import { InputToolbarRegistry, TooltippedButton } from '@jupyter/chat';
2
2
 
3
+ import type { TranslationBundle } from '@jupyterlab/translation';
4
+
3
5
  import BuildIcon from '@mui/icons-material/Build';
4
6
 
5
7
  import CheckIcon from '@mui/icons-material/Check';
@@ -32,13 +34,23 @@ export interface IToolSelectProps
32
34
  * Function to handle tool selection changes.
33
35
  */
34
36
  onToolSelectionChange: (selectedToolNames: string[]) => void;
37
+
38
+ /**
39
+ * The application language translator.
40
+ */
41
+ translator: TranslationBundle;
35
42
  }
36
43
 
37
44
  /**
38
45
  * The tool select component for choosing AI tools.
39
46
  */
40
47
  export function ToolSelect(props: IToolSelectProps): JSX.Element {
41
- const { toolRegistry, onToolSelectionChange, toolsEnabled } = props;
48
+ const {
49
+ toolRegistry,
50
+ onToolSelectionChange,
51
+ toolsEnabled,
52
+ translator: trans
53
+ } = props;
42
54
 
43
55
  const [selectedToolNames, setSelectedToolNames] = useState<string[]>([]);
44
56
  const [tools, setTools] = useState<INamedTool[]>(
@@ -111,12 +123,16 @@ export function ToolSelect(props: IToolSelectProps): JSX.Element {
111
123
  onClick={e => {
112
124
  openMenu(e.currentTarget);
113
125
  }}
114
- tooltip={`Tools (${selectedToolNames.length}/${tools.length} selected)`}
126
+ tooltip={trans.__(
127
+ 'Tools (%1/%2 selected)',
128
+ selectedToolNames.length.toString(),
129
+ tools.length.toString()
130
+ )}
115
131
  buttonProps={{
116
- size: 'small',
117
- variant: selectedToolNames.length > 0 ? 'contained' : 'outlined',
118
- color: 'primary',
119
- title: 'Select AI Tools',
132
+ ...(selectedToolNames.length === 0 && {
133
+ variant: 'outlined'
134
+ }),
135
+ title: trans.__('Select AI Tools'),
120
136
  onKeyDown: e => {
121
137
  if (e.key !== 'Enter' && e.key !== ' ') {
122
138
  return;
@@ -132,7 +148,7 @@ export function ToolSelect(props: IToolSelectProps): JSX.Element {
132
148
  : {}
133
149
  }
134
150
  >
135
- <BuildIcon />
151
+ <BuildIcon sx={{ fontSize: 'small' }} />
136
152
  </TooltippedButton>
137
153
 
138
154
  <Menu
@@ -192,7 +208,8 @@ export function ToolSelect(props: IToolSelectProps): JSX.Element {
192
208
  */
193
209
  export function createToolSelectItem(
194
210
  toolRegistry: IToolRegistry,
195
- toolsEnabled: boolean = true
211
+ toolsEnabled: boolean = true,
212
+ translator: TranslationBundle
196
213
  ): InputToolbarRegistry.IToolbarItem {
197
214
  return {
198
215
  element: (props: InputToolbarRegistry.IToolbarItemProps) => {
@@ -209,7 +226,8 @@ export function createToolSelectItem(
209
226
  ...props,
210
227
  toolRegistry,
211
228
  onToolSelectionChange,
212
- toolsEnabled
229
+ toolsEnabled,
230
+ translator
213
231
  };
214
232
  return <ToolSelect {...toolSelectProps} />;
215
233
  },