@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,256 @@
1
+ import Visibility from '@mui/icons-material/Visibility';
2
+ import VisibilityOff from '@mui/icons-material/VisibilityOff';
3
+ import {
4
+ Alert,
5
+ Box,
6
+ Button,
7
+ Chip,
8
+ Dialog,
9
+ DialogActions,
10
+ DialogContent,
11
+ DialogTitle,
12
+ FormControl,
13
+ IconButton,
14
+ InputAdornment,
15
+ InputLabel,
16
+ MenuItem,
17
+ Select,
18
+ TextField,
19
+ Typography
20
+ } from '@mui/material';
21
+ import React from 'react';
22
+ import { IProviderConfig } from '../models/settings-model';
23
+ import type { IChatProviderRegistry } from '../tokens';
24
+
25
+ interface IProviderConfigDialogProps {
26
+ open: boolean;
27
+ onClose: () => void;
28
+ onSave: (config: Omit<IProviderConfig, 'id'>) => void;
29
+ initialConfig?: IProviderConfig;
30
+ mode: 'add' | 'edit';
31
+ chatProviderRegistry: IChatProviderRegistry;
32
+ }
33
+
34
+ export const ProviderConfigDialog: React.FC<IProviderConfigDialogProps> = ({
35
+ open,
36
+ onClose,
37
+ onSave,
38
+ initialConfig,
39
+ mode,
40
+ chatProviderRegistry
41
+ }) => {
42
+ const [name, setName] = React.useState(initialConfig?.name || '');
43
+ const [provider, setProvider] = React.useState(
44
+ initialConfig?.provider || 'anthropic'
45
+ );
46
+ const [model, setModel] = React.useState(initialConfig?.model || '');
47
+ const [apiKey, setApiKey] = React.useState(initialConfig?.apiKey || '');
48
+ const [baseURL, setBaseURL] = React.useState(initialConfig?.baseURL || '');
49
+ const [showApiKey, setShowApiKey] = React.useState(false);
50
+
51
+ // Get provider options from registry
52
+ const providerOptions = React.useMemo(() => {
53
+ const providers = chatProviderRegistry.providers;
54
+ return Object.keys(providers).map(id => {
55
+ const info = providers[id];
56
+ return {
57
+ value: id,
58
+ label: info.name,
59
+ models: info.defaultModels,
60
+ requiresApiKey: info.requiresApiKey,
61
+ allowCustomModel: id === 'ollama' // Only Ollama allows custom models for now
62
+ };
63
+ });
64
+ }, [chatProviderRegistry]);
65
+
66
+ const selectedProvider = providerOptions.find(p => p.value === provider);
67
+
68
+ React.useEffect(() => {
69
+ if (open) {
70
+ // Reset form when dialog opens
71
+ setName(initialConfig?.name || '');
72
+ setProvider(initialConfig?.provider || 'anthropic');
73
+ setModel(initialConfig?.model || '');
74
+ setApiKey(initialConfig?.apiKey || '');
75
+ setBaseURL(initialConfig?.baseURL || '');
76
+ setShowApiKey(false);
77
+ }
78
+ }, [open, initialConfig]);
79
+
80
+ React.useEffect(() => {
81
+ // Auto-select first model when provider changes
82
+ if (selectedProvider && selectedProvider.models.length > 0 && !model) {
83
+ setModel(selectedProvider.models[0]);
84
+ }
85
+ }, [provider, selectedProvider, model]);
86
+
87
+ const handleSave = () => {
88
+ if (!name.trim() || !provider || !model) {
89
+ return;
90
+ }
91
+
92
+ const config: Omit<IProviderConfig, 'id'> = {
93
+ name: name.trim(),
94
+ provider: provider as IProviderConfig['provider'],
95
+ model,
96
+ ...(selectedProvider?.requiresApiKey && apiKey && { apiKey }),
97
+ ...(baseURL && { baseURL })
98
+ };
99
+
100
+ onSave(config);
101
+ onClose();
102
+ };
103
+
104
+ const isValid =
105
+ name.trim() &&
106
+ provider &&
107
+ model &&
108
+ (!selectedProvider?.requiresApiKey || apiKey);
109
+
110
+ return (
111
+ <Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
112
+ <DialogTitle>
113
+ {mode === 'add' ? 'Add New Provider' : 'Edit Provider'}
114
+ </DialogTitle>
115
+ <DialogContent>
116
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, pt: 1 }}>
117
+ <TextField
118
+ fullWidth
119
+ label="Provider Name"
120
+ value={name}
121
+ onChange={e => setName(e.target.value)}
122
+ placeholder="e.g., My Anthropic Config, Work Provider"
123
+ helperText="A friendly name to identify this provider configuration"
124
+ required
125
+ />
126
+
127
+ <FormControl fullWidth required>
128
+ <InputLabel>Provider Type</InputLabel>
129
+ <Select
130
+ value={provider}
131
+ label="Provider Type"
132
+ onChange={e =>
133
+ setProvider(e.target.value as IProviderConfig['provider'])
134
+ }
135
+ >
136
+ {providerOptions.map(option => (
137
+ <MenuItem key={option.value} value={option.value}>
138
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
139
+ {option.label}
140
+ {option.requiresApiKey && (
141
+ <Chip
142
+ size="small"
143
+ label="API Key"
144
+ color="default"
145
+ variant="outlined"
146
+ />
147
+ )}
148
+ </Box>
149
+ </MenuItem>
150
+ ))}
151
+ </Select>
152
+ </FormControl>
153
+
154
+ {selectedProvider?.allowCustomModel ? (
155
+ <TextField
156
+ fullWidth
157
+ label="Model"
158
+ value={model}
159
+ onChange={e => setModel(e.target.value)}
160
+ placeholder="Enter model name"
161
+ helperText="Enter any compatible model name"
162
+ required
163
+ />
164
+ ) : (
165
+ <FormControl fullWidth required>
166
+ <InputLabel>Model</InputLabel>
167
+ <Select
168
+ value={model}
169
+ label="Model"
170
+ onChange={e => setModel(e.target.value)}
171
+ >
172
+ {selectedProvider?.models.map(modelOption => (
173
+ <MenuItem key={modelOption} value={modelOption}>
174
+ <Box>
175
+ <Typography variant="body1">{modelOption}</Typography>
176
+ <Typography variant="caption" color="text.secondary">
177
+ {modelOption.includes('sonnet')
178
+ ? 'Balanced performance'
179
+ : modelOption.includes('opus')
180
+ ? 'Advanced reasoning'
181
+ : modelOption.includes('haiku')
182
+ ? 'Fast and lightweight'
183
+ : modelOption.includes('large')
184
+ ? 'Most capable model'
185
+ : modelOption.includes('small')
186
+ ? 'Fast and efficient'
187
+ : modelOption.includes('codestral')
188
+ ? 'Code-specialized'
189
+ : 'General purpose'}
190
+ </Typography>
191
+ </Box>
192
+ </MenuItem>
193
+ ))}
194
+ </Select>
195
+ </FormControl>
196
+ )}
197
+
198
+ {selectedProvider?.requiresApiKey && (
199
+ <TextField
200
+ fullWidth
201
+ label="API Key"
202
+ type={showApiKey ? 'text' : 'password'}
203
+ value={apiKey}
204
+ onChange={e => setApiKey(e.target.value)}
205
+ placeholder="Enter your API key..."
206
+ required={selectedProvider.requiresApiKey}
207
+ InputProps={{
208
+ endAdornment: (
209
+ <InputAdornment position="end">
210
+ <IconButton
211
+ onClick={() => setShowApiKey(!showApiKey)}
212
+ edge="end"
213
+ >
214
+ {showApiKey ? <VisibilityOff /> : <Visibility />}
215
+ </IconButton>
216
+ </InputAdornment>
217
+ )
218
+ }}
219
+ />
220
+ )}
221
+
222
+ {(provider === 'ollama' || selectedProvider?.allowCustomModel) && (
223
+ <TextField
224
+ fullWidth
225
+ label="Base URL (Optional)"
226
+ value={baseURL}
227
+ onChange={e => setBaseURL(e.target.value)}
228
+ placeholder={
229
+ provider === 'ollama'
230
+ ? 'http://localhost:11434/api'
231
+ : 'Custom API endpoint'
232
+ }
233
+ helperText={
234
+ provider === 'ollama'
235
+ ? 'Ollama server endpoint'
236
+ : 'Custom API base URL if needed'
237
+ }
238
+ />
239
+ )}
240
+
241
+ {!selectedProvider?.requiresApiKey && (
242
+ <Alert severity="info">
243
+ This provider does not require an API key.
244
+ </Alert>
245
+ )}
246
+ </Box>
247
+ </DialogContent>
248
+ <DialogActions>
249
+ <Button onClick={onClose}>Cancel</Button>
250
+ <Button onClick={handleSave} variant="contained" disabled={!isValid}>
251
+ {mode === 'add' ? 'Add Provider' : 'Save Changes'}
252
+ </Button>
253
+ </DialogActions>
254
+ </Dialog>
255
+ );
256
+ };
package/style/base.css CHANGED
@@ -6,20 +6,6 @@
6
6
 
7
7
  @import url('@jupyter/chat/style/index.css');
8
8
 
9
- .jp-AISettingsInstructions {
10
- font-size: var(--jp-content-font-size1);
11
- }
12
-
13
- .jp-AISettingsError {
14
- color: var(--jp-error-color1);
15
- font-size: var(--jp-content-font-size1);
16
- }
17
-
18
- .jp-AISettingsTextArea {
19
- min-width: 400px;
20
- min-height: 300px;
21
- }
22
-
23
9
  .jp-chat-welcome-message {
24
10
  text-align: center;
25
11
  max-width: 350px;
@@ -43,3 +29,338 @@
43
29
  border-color: var(--jp-brand-color1);
44
30
  color: var(--jp-brand-color1);
45
31
  }
32
+
33
+ /* Tool Select Component Styles - Enhanced */
34
+ .jp-AIToolSelect-item {
35
+ display: flex;
36
+ align-items: center;
37
+ min-height: 36px;
38
+ padding: 8px 16px;
39
+ transition: background-color 0.2s ease;
40
+ }
41
+
42
+ .jp-AIToolSelect-item:hover {
43
+ background: var(--jp-layout-color2);
44
+ }
45
+
46
+ .jp-AIToolSelect-item .lm-Menu-itemIcon {
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ width: 24px;
51
+ height: 24px;
52
+ margin-right: 8px;
53
+ }
54
+
55
+ /* Enhanced tool select button styles */
56
+ .jp-AIToolSelect-button {
57
+ min-width: 36px;
58
+ padding: 6px 8px;
59
+ background: var(--jp-layout-color2) !important;
60
+ border: 1px solid var(--jp-border-color1) !important;
61
+ transition: all 0.2s ease;
62
+ }
63
+
64
+ .jp-AIToolSelect-button:hover {
65
+ background: var(--jp-layout-color3) !important;
66
+ border-color: var(--jp-brand-color1) !important;
67
+ }
68
+
69
+ .jp-AIToolSelect-button[aria-expanded='true'] {
70
+ background: var(--jp-brand-color1) !important;
71
+ color: white !important;
72
+ }
73
+
74
+ /* Enhanced tool select menu styles */
75
+ .jp-AIToolSelect-menu {
76
+ max-width: 300px;
77
+ box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
78
+ border: 1px solid var(--jp-border-color2);
79
+ }
80
+
81
+ .jp-AIToolSelect-menu .MuiMenuItem-root {
82
+ padding: 8px 16px;
83
+ min-height: 40px;
84
+ border-bottom: 1px solid var(--jp-border-color3);
85
+ }
86
+
87
+ .jp-AIToolSelect-menu .MuiMenuItem-root:last-child {
88
+ border-bottom: none;
89
+ }
90
+
91
+ /* Modern Tool Call Card Styling */
92
+ .jp-ai-tool-call {
93
+ margin: 8px 0;
94
+ border: 1px solid var(--jp-border-color1);
95
+ border-radius: 6px;
96
+ background: var(--jp-layout-color0);
97
+ box-shadow: 0 1px 3px rgb(0 0 0 / 8%);
98
+ transition: all 0.2s ease;
99
+ overflow: hidden;
100
+ }
101
+
102
+ .jp-ai-tool-call:hover {
103
+ border-color: var(--jp-border-color2);
104
+ box-shadow: 0 2px 6px rgb(0 0 0 / 12%);
105
+ }
106
+
107
+ /* Tool Header - clickable summary */
108
+ .jp-ai-tool-header {
109
+ display: flex;
110
+ align-items: center;
111
+ padding: 4px 8px;
112
+ background: var(--jp-layout-color1);
113
+ cursor: pointer;
114
+ user-select: none;
115
+ gap: 8px;
116
+ transition: background-color 0.2s ease;
117
+ }
118
+
119
+ .jp-ai-tool-header:hover {
120
+ background: var(--jp-layout-color2);
121
+ }
122
+
123
+ .jp-ai-tool-header::marker {
124
+ content: '';
125
+ }
126
+
127
+ .jp-ai-tool-header::before {
128
+ content: '';
129
+ width: 0;
130
+ height: 0;
131
+ border-left: 5px solid var(--jp-ui-font-color2);
132
+ border-top: 3px solid transparent;
133
+ border-bottom: 3px solid transparent;
134
+ transition: transform 0.2s ease;
135
+ }
136
+
137
+ .jp-ai-tool-call[open] .jp-ai-tool-header::before {
138
+ transform: rotate(90deg);
139
+ }
140
+
141
+ .jp-ai-tool-icon {
142
+ font-size: 14px;
143
+ opacity: 0.8;
144
+ }
145
+
146
+ .jp-ai-tool-title {
147
+ font-family: var(--jp-ui-font-family);
148
+ font-size: var(--jp-ui-font-size1);
149
+ font-weight: 500;
150
+ color: var(--jp-ui-font-color1);
151
+ flex: 1;
152
+ }
153
+
154
+ .jp-ai-tool-status {
155
+ font-size: var(--jp-ui-font-size0);
156
+ font-weight: 500;
157
+ padding: 2px 6px;
158
+ border-radius: 3px;
159
+ }
160
+
161
+ .jp-ai-tool-status-pending {
162
+ background: rgb(var(--jp-warn-color1-rgb) / 15%);
163
+ color: var(--jp-warn-color1);
164
+ }
165
+
166
+ .jp-ai-tool-status-completed {
167
+ background: rgb(var(--jp-success-color1-rgb) / 15%);
168
+ color: var(--jp-success-color1);
169
+ }
170
+
171
+ .jp-ai-tool-status-error {
172
+ background: rgb(var(--jp-error-color1-rgb) / 15%);
173
+ color: var(--jp-error-color1);
174
+ }
175
+
176
+ /* Tool Body */
177
+ .jp-ai-tool-body {
178
+ padding: 8px 12px 12px;
179
+ }
180
+
181
+ .jp-ai-tool-section {
182
+ margin-bottom: 8px;
183
+ }
184
+
185
+ .jp-ai-tool-section:last-child {
186
+ margin-bottom: 0;
187
+ }
188
+
189
+ .jp-ai-tool-label {
190
+ font-family: var(--jp-ui-font-family);
191
+ font-size: var(--jp-ui-font-size0);
192
+ font-weight: 600;
193
+ color: var(--jp-ui-font-color2);
194
+ margin-bottom: 4px;
195
+ text-transform: uppercase;
196
+ letter-spacing: 0.5px;
197
+ }
198
+
199
+ .jp-ai-tool-code {
200
+ background: var(--jp-layout-color2);
201
+ border: 1px solid var(--jp-border-color1);
202
+ border-radius: 4px;
203
+ padding: 8px;
204
+ margin: 0;
205
+ font-family: var(--jp-code-font-family);
206
+ font-size: var(--jp-code-font-size);
207
+ line-height: 1.4;
208
+ overflow: auto auto;
209
+ max-height: 200px;
210
+ }
211
+
212
+ .jp-ai-tool-code code {
213
+ background: none;
214
+ padding: 0;
215
+ border: none;
216
+ font-family: inherit;
217
+ font-size: inherit;
218
+ }
219
+
220
+ /* State-specific styling */
221
+ .jp-ai-tool-pending {
222
+ border-left: 4px solid var(--jp-warn-color1);
223
+ }
224
+
225
+ .jp-ai-tool-completed {
226
+ border-left: 4px solid var(--jp-success-color1);
227
+ }
228
+
229
+ .jp-ai-tool-error {
230
+ border-left: 4px solid var(--jp-error-color1);
231
+ }
232
+
233
+ .jp-AIChatToolbar {
234
+ display: flex;
235
+ flex-shrink: 0;
236
+ }
237
+
238
+ .jp-AIChatWrapper {
239
+ display: flex;
240
+ flex-direction: column;
241
+ height: 100%;
242
+ }
243
+
244
+ .jp-AIChatPanel {
245
+ flex: 1;
246
+ min-height: 0;
247
+ }
248
+
249
+ .jp-chat-attachment {
250
+ border-radius: 2px;
251
+ padding: 0 0.4em;
252
+ }
253
+
254
+ /* Tool Approval UI Styles */
255
+ .jp-ai-tool-approval {
256
+ margin: 8px 0;
257
+ border: 2px solid var(--jp-warn-color1);
258
+ border-radius: 8px;
259
+ background: var(--jp-layout-color0);
260
+ box-shadow: 0 2px 8px rgb(0 0 0 / 12%);
261
+ overflow: hidden;
262
+ }
263
+
264
+ .jp-ai-tool-approval-header {
265
+ display: flex;
266
+ align-items: center;
267
+ padding: 12px 16px;
268
+ background: rgb(var(--jp-warn-color1-rgb) / 8%);
269
+ gap: 12px;
270
+ }
271
+
272
+ .jp-ai-tool-approval-header .jp-ai-tool-icon {
273
+ font-size: 16px;
274
+ }
275
+
276
+ .jp-ai-tool-approval-header .jp-ai-tool-title {
277
+ font-family: var(--jp-ui-font-family);
278
+ font-size: var(--jp-ui-font-size1);
279
+ font-weight: 600;
280
+ color: var(--jp-warn-color1);
281
+ flex: 1;
282
+ }
283
+
284
+ .jp-ai-tool-approval-body {
285
+ padding: 16px;
286
+ }
287
+
288
+ .jp-ai-tool-approval-buttons,
289
+ .jp-ai-group-approval-buttons {
290
+ display: flex;
291
+ gap: 8px;
292
+ margin-top: 12px;
293
+ justify-content: flex-end;
294
+ }
295
+
296
+ .jp-ai-approval-btn {
297
+ padding: 6px 12px;
298
+ border: none;
299
+ border-radius: 4px;
300
+ font-family: var(--jp-ui-font-family);
301
+ font-size: var(--jp-ui-font-size0);
302
+ font-weight: 500;
303
+ cursor: pointer;
304
+ transition: all 0.2s ease;
305
+ min-width: 70px;
306
+ display: inline-block;
307
+ }
308
+
309
+ .jp-ai-approval-approve {
310
+ background: var(--jp-success-color1);
311
+ color: white;
312
+ }
313
+
314
+ .jp-ai-approval-approve:hover:not(:disabled) {
315
+ background: var(--jp-success-color0);
316
+ transform: translateY(-1px);
317
+ box-shadow: 0 2px 4px rgb(0 0 0 / 15%);
318
+ }
319
+
320
+ .jp-ai-approval-reject {
321
+ background: var(--jp-error-color1);
322
+ color: white;
323
+ }
324
+
325
+ .jp-ai-approval-reject:hover:not(:disabled) {
326
+ background: var(--jp-error-color0);
327
+ transform: translateY(-1px);
328
+ box-shadow: 0 2px 4px rgb(0 0 0 / 15%);
329
+ }
330
+
331
+ .jp-ai-approval-btn:disabled {
332
+ cursor: not-allowed;
333
+ opacity: 0.5;
334
+ }
335
+
336
+ /* Unified Approval Status Styles for both single and grouped tools */
337
+ .jp-ai-approval-status,
338
+ .jp-ai-group-approval-status {
339
+ display: flex;
340
+ align-items: center;
341
+ justify-content: center;
342
+ gap: 8px;
343
+ padding: 8px 16px;
344
+ border-radius: 4px;
345
+ font-family: var(--jp-ui-font-family);
346
+ font-size: var(--jp-ui-font-size1);
347
+ font-weight: 500;
348
+ }
349
+
350
+ .jp-ai-approval-status-approved,
351
+ .jp-ai-group-approval-status-approved {
352
+ background: rgb(var(--jp-success-color1-rgb) / 15%);
353
+ color: var(--jp-success-color1);
354
+ border: 1px solid rgb(var(--jp-success-color1-rgb) / 30%);
355
+ }
356
+
357
+ .jp-ai-approval-status-rejected,
358
+ .jp-ai-group-approval-status-rejected {
359
+ background: rgb(var(--jp-error-color1-rgb) / 15%);
360
+ color: var(--jp-error-color1);
361
+ border: 1px solid rgb(var(--jp-error-color1-rgb) / 30%);
362
+ }
363
+
364
+ .jp-ai-approval-icon {
365
+ font-size: 16px;
366
+ }
@@ -4,4 +4,4 @@
4
4
  <circle cx="19" cy="19" r="19" fill="#f7dc1e"/>
5
5
  <path d="m19.948 6.8365c0.6344-0.21603 1.0908-0.81693 1.0908-1.5244 0-0.88916-0.7208-1.61-1.61-1.61s-1.61 0.72081-1.61 1.61c0 0.70739 0.4562 1.3082 1.0905 1.5243v1.1674h-0.5394c-6.2858 0-11.399 5.1132-11.399 11.399 0 6.2859 5.1133 11.399 11.399 11.399h1.398c6.2859 0 11.399-5.1132 11.399-11.399 0-6.2253-5.0159-11.301-11.219-11.397v-1.1687zm-1.5781 22.163h1.398c5.3669 0 9.7303-4.9787 9.7303-8.3455 0-5.3669-4.3634-9.7303-9.7303-9.7303h-1.398c-5.3668 0-9.7302 4.3634-9.7302 9.7303 0 3.3668 4.3634 8.3455 9.7302 8.3455zm14.522-5.003c0.7341 0 0.7375-0.5123 0.7422-1.2408v-1e-4c0.0012-0.1847 0.0025-0.3833 0.0158-0.591 0.0573-0.8624 0.0739-1.7008 0.0573-2.4892l-0.0033-0.119c-0.0373-1.3318-0.0436-1.5579-1.3047-1.8058l-0.1479-0.0246 0.0015 0.0495c0.0076 0.2465 0.0151 0.493 0.0151 0.739 0 1.8018-0.2712 3.5478-0.773 5.189-0.1363 0.4459 0.3433 0.8629 0.7534 0.6411l0.6436-0.3481zm-27.612 0c-0.73409 0-0.73741-0.5123-0.74215-1.2407-0.0012-0.1848-0.00249-0.3834-0.01581-0.5912-0.0573-0.8624-0.07392-1.7007-0.05731-2.4892l0.00336-0.1189c0.03721-1.3319 0.04352-1.5579 1.3047-1.8058l0.14784-0.0247-0.00151 0.0495c-0.00756 0.2465-0.01511 0.493-0.01511 0.739 0 1.8019 0.27119 3.5478 0.773 5.189 0.13634 0.4459-0.34326 0.8629-0.7534 0.6411l-0.64361-0.3481zm14.242-12.005c-4.6297 0-8.4776 2.9361-9.4584 6.7577-0.13379 0.5212 0.5513 0.6935 0.877 0.2653 1.3829-1.818 3.1418-2.153 4.7068-2.4511 2.1143-0.4027 3.8746-0.7379 3.8746-4.5719z" clip-rule="evenodd" fill="#000" fill-rule="evenodd"/>
6
6
  </g>
7
- </svg>
7
+ </svg>
@@ -1,49 +0,0 @@
1
- import { CompletionHandler, IInlineCompletionContext } from '@jupyterlab/completer';
2
- import { BaseLanguageModel } from '@langchain/core/language_models/base';
3
- import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
4
- import { IAIProviderRegistry } from './tokens';
5
- export interface IBaseCompleter {
6
- /**
7
- * The completion prompt.
8
- */
9
- readonly systemPrompt: string;
10
- /**
11
- * The function to fetch a new completion.
12
- */
13
- requestCompletion?: () => void;
14
- /**
15
- * The fetch request for the LLM completer.
16
- */
17
- fetch(request: CompletionHandler.IRequest, context: IInlineCompletionContext): Promise<any>;
18
- }
19
- export declare abstract class BaseCompleter implements IBaseCompleter {
20
- constructor(options: BaseCompleter.IOptions);
21
- /**
22
- * Get the system prompt for the completion.
23
- */
24
- get systemPrompt(): string;
25
- /**
26
- * The fetch request for the LLM completer.
27
- */
28
- abstract fetch(request: CompletionHandler.IRequest, context: IInlineCompletionContext): Promise<any>;
29
- protected _providerRegistry: IAIProviderRegistry;
30
- protected abstract _completer: BaseLanguageModel<any, any>;
31
- }
32
- /**
33
- * The namespace for the base completer.
34
- */
35
- export declare namespace BaseCompleter {
36
- /**
37
- * The options for the constructor of a completer.
38
- */
39
- interface IOptions {
40
- /**
41
- * The provider registry.
42
- */
43
- providerRegistry: IAIProviderRegistry;
44
- /**
45
- * The settings of the provider.
46
- */
47
- settings: ReadonlyPartialJSONObject;
48
- }
49
- }
@@ -1,14 +0,0 @@
1
- import { DEFAULT_COMPLETION_SYSTEM_PROMPT } from './default-prompts';
2
- export class BaseCompleter {
3
- constructor(options) {
4
- this._providerRegistry = options.providerRegistry;
5
- }
6
- /**
7
- * Get the system prompt for the completion.
8
- */
9
- get systemPrompt() {
10
- return (this._providerRegistry.completerSystemPrompt ??
11
- DEFAULT_COMPLETION_SYSTEM_PROMPT);
12
- }
13
- _providerRegistry;
14
- }