@jupyterlite/ai 0.17.0 → 0.19.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.
- package/lib/chat-commands/clear.d.ts +1 -0
- package/lib/chat-commands/index.d.ts +1 -0
- package/lib/chat-commands/skills.d.ts +2 -1
- package/lib/chat-model-handler.d.ts +4 -3
- package/lib/chat-model-handler.js +2 -1
- package/lib/chat-model.d.ts +148 -8
- package/lib/chat-model.js +368 -79
- package/lib/completion/completion-provider.d.ts +3 -1
- package/lib/completion/completion-provider.js +1 -2
- package/lib/completion/index.d.ts +1 -0
- package/lib/components/clear-button.d.ts +1 -0
- package/lib/components/clear-button.js +3 -4
- package/lib/components/completion-status.d.ts +1 -0
- package/lib/components/completion-status.js +5 -4
- package/lib/components/index.d.ts +1 -0
- package/lib/components/model-select.d.ts +1 -0
- package/lib/components/model-select.js +62 -67
- package/lib/components/save-button.d.ts +3 -2
- package/lib/components/save-button.js +4 -5
- package/lib/components/stop-button.d.ts +1 -0
- package/lib/components/stop-button.js +3 -4
- package/lib/components/tool-select.d.ts +3 -1
- package/lib/components/tool-select.js +47 -60
- package/lib/components/usage-display.d.ts +4 -2
- package/lib/components/usage-display.js +50 -61
- package/lib/diff-manager.d.ts +3 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.js +50 -59
- package/lib/models/settings-model.d.ts +3 -1
- package/lib/models/settings-model.js +1 -0
- package/lib/rendered-message-outputarea.d.ts +1 -0
- package/lib/tokens.d.ts +48 -597
- package/lib/tokens.js +2 -31
- package/lib/widgets/ai-settings.d.ts +3 -1
- package/lib/widgets/ai-settings.js +185 -344
- package/lib/widgets/main-area-chat.d.ts +3 -3
- package/lib/widgets/main-area-chat.js +2 -4
- package/lib/widgets/provider-config-dialog.d.ts +2 -1
- package/lib/widgets/provider-config-dialog.js +102 -167
- package/package.json +111 -258
- package/schema/settings-model.json +6 -0
- package/src/chat-commands/skills.ts +2 -2
- package/src/chat-model-handler.ts +10 -6
- package/src/chat-model.ts +488 -96
- package/src/completion/completion-provider.ts +6 -6
- package/src/components/clear-button.tsx +0 -2
- package/src/components/completion-status.tsx +2 -2
- package/src/components/model-select.tsx +1 -1
- package/src/components/save-button.tsx +3 -3
- package/src/components/stop-button.tsx +0 -2
- package/src/components/tool-select.tsx +10 -9
- package/src/components/usage-display.tsx +4 -2
- package/src/diff-manager.ts +4 -3
- package/src/index.ts +103 -107
- package/src/models/settings-model.ts +7 -6
- package/src/tokens.ts +54 -744
- package/src/widgets/ai-settings.tsx +40 -11
- package/src/widgets/main-area-chat.ts +5 -8
- package/src/widgets/provider-config-dialog.tsx +8 -8
- package/LICENSE +0 -30
- package/README.md +0 -49
- package/lib/agent.d.ts +0 -277
- package/lib/agent.js +0 -1116
- package/lib/icons.d.ts +0 -3
- package/lib/icons.js +0 -8
- package/lib/providers/built-in-providers.d.ts +0 -21
- package/lib/providers/built-in-providers.js +0 -233
- package/lib/providers/generated-context-windows.d.ts +0 -8
- package/lib/providers/generated-context-windows.js +0 -96
- package/lib/providers/model-info.d.ts +0 -3
- package/lib/providers/model-info.js +0 -58
- package/lib/providers/models.d.ts +0 -37
- package/lib/providers/models.js +0 -28
- package/lib/providers/provider-registry.d.ts +0 -49
- package/lib/providers/provider-registry.js +0 -72
- package/lib/providers/provider-tools.d.ts +0 -36
- package/lib/providers/provider-tools.js +0 -93
- package/lib/skills/index.d.ts +0 -4
- package/lib/skills/index.js +0 -7
- package/lib/skills/parse-skill.d.ts +0 -25
- package/lib/skills/parse-skill.js +0 -69
- package/lib/skills/skill-loader.d.ts +0 -25
- package/lib/skills/skill-loader.js +0 -133
- package/lib/skills/skill-registry.d.ts +0 -31
- package/lib/skills/skill-registry.js +0 -100
- package/lib/skills/types.d.ts +0 -29
- package/lib/skills/types.js +0 -5
- package/lib/tools/commands.d.ts +0 -11
- package/lib/tools/commands.js +0 -154
- package/lib/tools/skills.d.ts +0 -9
- package/lib/tools/skills.js +0 -73
- package/lib/tools/tool-registry.d.ts +0 -35
- package/lib/tools/tool-registry.js +0 -55
- package/lib/tools/web.d.ts +0 -8
- package/lib/tools/web.js +0 -196
- package/src/agent.ts +0 -1441
- package/src/icons.ts +0 -11
- package/src/providers/built-in-providers.ts +0 -241
- package/src/providers/generated-context-windows.ts +0 -102
- package/src/providers/model-info.ts +0 -88
- package/src/providers/models.ts +0 -76
- package/src/providers/provider-registry.ts +0 -88
- package/src/providers/provider-tools.ts +0 -179
- package/src/skills/index.ts +0 -14
- package/src/skills/parse-skill.ts +0 -91
- package/src/skills/skill-loader.ts +0 -175
- package/src/skills/skill-registry.ts +0 -137
- package/src/skills/types.ts +0 -37
- package/src/tools/commands.ts +0 -210
- package/src/tools/skills.ts +0 -84
- package/src/tools/tool-registry.ts +0 -63
- package/src/tools/web.ts +0 -238
- package/src/types.d.ts +0 -4
- package/style/icons/jupyternaut-lite.svg +0 -7
|
@@ -2,8 +2,7 @@ import { ChatWidget } from '@jupyter/chat';
|
|
|
2
2
|
import { MainAreaWidget } from '@jupyterlab/apputils';
|
|
3
3
|
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
4
4
|
import { CommandRegistry } from '@lumino/commands';
|
|
5
|
-
import {
|
|
6
|
-
import { type IAISettingsModel } from '../tokens';
|
|
5
|
+
import { IAIChatModel, type IAISettingsModel } from '../tokens';
|
|
7
6
|
export declare namespace MainAreaChat {
|
|
8
7
|
interface IOptions extends MainAreaWidget.IOptions<ChatWidget> {
|
|
9
8
|
commands: CommandRegistry;
|
|
@@ -20,7 +19,7 @@ export declare class MainAreaChat extends MainAreaWidget<ChatWidget> {
|
|
|
20
19
|
/**
|
|
21
20
|
* Get the model of the chat.
|
|
22
21
|
*/
|
|
23
|
-
get model():
|
|
22
|
+
get model(): IAIChatModel;
|
|
24
23
|
/**
|
|
25
24
|
* Get the area of the chat.
|
|
26
25
|
*/
|
|
@@ -29,3 +28,4 @@ export declare class MainAreaChat extends MainAreaWidget<ChatWidget> {
|
|
|
29
28
|
private _titleChanged;
|
|
30
29
|
private _outputAreaCompat;
|
|
31
30
|
}
|
|
31
|
+
//# sourceMappingURL=main-area-chat.d.ts.map
|
|
@@ -43,14 +43,14 @@ export class MainAreaChat extends MainAreaWidget {
|
|
|
43
43
|
this._outputAreaCompat = new RenderedMessageOutputAreaCompat({
|
|
44
44
|
chatPanel: this.content
|
|
45
45
|
});
|
|
46
|
-
this.model.writersChanged
|
|
46
|
+
this.model.writersChanged?.connect(this._writersChanged);
|
|
47
47
|
this.model.titleChanged.connect(this._titleChanged);
|
|
48
48
|
}
|
|
49
49
|
dispose() {
|
|
50
50
|
super.dispose();
|
|
51
51
|
// Dispose of the approval buttons widget when the chat is disposed.
|
|
52
52
|
this._outputAreaCompat.dispose();
|
|
53
|
-
this.model.writersChanged
|
|
53
|
+
this.model.writersChanged?.disconnect(this._writersChanged);
|
|
54
54
|
this.model.titleChanged.disconnect(this._titleChanged);
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
@@ -69,12 +69,10 @@ export class MainAreaChat extends MainAreaWidget {
|
|
|
69
69
|
// Check if AI is currently writing (streaming)
|
|
70
70
|
const aiWriting = writers.some(writer => writer.user.username === 'ai-assistant');
|
|
71
71
|
if (aiWriting) {
|
|
72
|
-
this.content.inputToolbarRegistry?.hide('send');
|
|
73
72
|
this.content.inputToolbarRegistry?.show('stop');
|
|
74
73
|
}
|
|
75
74
|
else {
|
|
76
75
|
this.content.inputToolbarRegistry?.hide('stop');
|
|
77
|
-
this.content.inputToolbarRegistry?.show('send');
|
|
78
76
|
}
|
|
79
77
|
};
|
|
80
78
|
_titleChanged = () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { IProviderConfig, IProviderRegistry } from '@jupyternaut/agent';
|
|
1
2
|
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
2
3
|
import React from 'react';
|
|
3
|
-
import type { IProviderConfig, IProviderRegistry } from '../tokens';
|
|
4
4
|
interface IProviderConfigDialogProps {
|
|
5
5
|
open: boolean;
|
|
6
6
|
onClose: () => void;
|
|
@@ -13,3 +13,4 @@ interface IProviderConfigDialogProps {
|
|
|
13
13
|
}
|
|
14
14
|
export declare const ProviderConfigDialog: React.FC<IProviderConfigDialogProps>;
|
|
15
15
|
export {};
|
|
16
|
+
//# sourceMappingURL=provider-config-dialog.d.ts.map
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { createElement as _createElement } from "react";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { getProviderModelInfo } from '@jupyternaut/agent';
|
|
1
4
|
import ExpandMore from '@mui/icons-material/ExpandMore';
|
|
2
5
|
import Delete from '@mui/icons-material/Delete';
|
|
3
6
|
import Visibility from '@mui/icons-material/Visibility';
|
|
4
7
|
import VisibilityOff from '@mui/icons-material/VisibilityOff';
|
|
5
8
|
import { Accordion, AccordionDetails, AccordionSummary, Autocomplete, Box, Button, Chip, Dialog, DialogActions, DialogContent, DialogTitle, FormControl, FormControlLabel, IconButton, InputAdornment, InputLabel, List, ListItem, ListItemText, MenuItem, Select, Slider, Switch, TextField, Typography } from '@mui/material';
|
|
6
9
|
import React from 'react';
|
|
7
|
-
import { getProviderModelInfo } from '../providers/model-info';
|
|
8
10
|
/**
|
|
9
11
|
* Default parameter values for provider configuration
|
|
10
12
|
*/
|
|
@@ -188,32 +190,26 @@ export const ProviderConfigDialog = ({ open, onClose, onSave, initialConfig, mod
|
|
|
188
190
|
}, [customSettings, updateCustomSetting]);
|
|
189
191
|
const renderDomainList = React.useCallback((fieldId, label, placeholder, values) => {
|
|
190
192
|
const domainValues = toStringArray(values);
|
|
191
|
-
return (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
193
|
+
return (_jsxs(Box, { children: [_jsx(Typography, { variant: "body2", gutterBottom: true, children: label }), _jsx(List, { dense: true, sx: {
|
|
194
|
+
mb: 1,
|
|
195
|
+
maxHeight: 160,
|
|
196
|
+
overflow: 'auto',
|
|
197
|
+
border: 1,
|
|
198
|
+
borderColor: 'divider',
|
|
199
|
+
borderRadius: 1
|
|
200
|
+
}, children: domainValues.length === 0 ? (_jsx(ListItem, { children: _jsx(ListItemText, { secondary: trans.__('No domains added.'), slotProps: {
|
|
201
|
+
secondary: {
|
|
202
|
+
color: 'text.secondary'
|
|
203
|
+
}
|
|
204
|
+
} }) })) : (domainValues.map(value => (_jsx(ListItem, { secondaryAction: _jsx(IconButton, { onClick: () => removeDomainValue(fieldId, value), size: "small", children: _jsx(Delete, { fontSize: "small" }) }), children: _jsx(ListItemText, { primary: value }) }, value)))) }), _jsx(TextField, { fullWidth: true, size: "small", label: trans.__('Add Domain'), value: domainInputs[fieldId], onChange: e => setDomainInputs(prev => ({
|
|
205
|
+
...prev,
|
|
206
|
+
[fieldId]: e.target.value
|
|
207
|
+
})), onKeyDown: e => {
|
|
208
|
+
if (e.key === 'Enter') {
|
|
209
|
+
e.preventDefault();
|
|
210
|
+
addDomainValue(fieldId);
|
|
204
211
|
}
|
|
205
|
-
}
|
|
206
|
-
React.createElement(Delete, { fontSize: "small" })) },
|
|
207
|
-
React.createElement(ListItemText, { primary: value })))))),
|
|
208
|
-
React.createElement(TextField, { fullWidth: true, size: "small", label: trans.__('Add Domain'), value: domainInputs[fieldId], onChange: e => setDomainInputs(prev => ({
|
|
209
|
-
...prev,
|
|
210
|
-
[fieldId]: e.target.value
|
|
211
|
-
})), onKeyDown: e => {
|
|
212
|
-
if (e.key === 'Enter') {
|
|
213
|
-
e.preventDefault();
|
|
214
|
-
addDomainValue(fieldId);
|
|
215
|
-
}
|
|
216
|
-
}, placeholder: placeholder, helperText: trans.__('Press Enter to add one domain.') })));
|
|
212
|
+
}, placeholder: placeholder, helperText: trans.__('Press Enter to add one domain.') })] }));
|
|
217
213
|
}, [addDomainValue, domainInputs, removeDomainValue, trans]);
|
|
218
214
|
const handleSave = () => {
|
|
219
215
|
if (!name.trim() || !provider || !model) {
|
|
@@ -240,145 +236,84 @@ export const ProviderConfigDialog = ({ open, onClose, onSave, initialConfig, mod
|
|
|
240
236
|
provider &&
|
|
241
237
|
model &&
|
|
242
238
|
(selectedProvider?.apiKeyRequirement !== 'required' || apiKey);
|
|
243
|
-
return (
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
React.createElement(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 2, mb: 1 } }, trans.__('Completion Options')),
|
|
324
|
-
React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: parameters.supportsFillInMiddle ?? false, onChange: e => setParameters({
|
|
325
|
-
...parameters,
|
|
326
|
-
supportsFillInMiddle: e.target.checked
|
|
327
|
-
}) }), label: trans.__('Fill-in-the-middle support') }),
|
|
328
|
-
React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: parameters.useFilterText ?? false, onChange: e => setParameters({
|
|
329
|
-
...parameters,
|
|
330
|
-
useFilterText: e.target.checked
|
|
331
|
-
}) }), label: trans.__('Use filter text') }),
|
|
332
|
-
(supportsWebSearch || supportsWebFetch) && (React.createElement(React.Fragment, null,
|
|
333
|
-
React.createElement(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 2, mb: 1 } }, trans.__('Provider Web Tools')),
|
|
334
|
-
supportsWebSearch && (React.createElement(React.Fragment, null,
|
|
335
|
-
React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: webSearchSettings.enabled === true, onChange: e => updateCustomSetting('webSearch', 'enabled', e.target.checked) }), label: trans.__('Enable Web Search') }),
|
|
336
|
-
webSearchSettings.enabled === true && (React.createElement(Box, { sx: {
|
|
337
|
-
pl: 2,
|
|
338
|
-
borderLeft: 2,
|
|
339
|
-
borderColor: 'divider',
|
|
340
|
-
display: 'flex',
|
|
341
|
-
flexDirection: 'column',
|
|
342
|
-
gap: 1.5
|
|
343
|
-
} },
|
|
344
|
-
(webSearchImplementation === 'openai' ||
|
|
345
|
-
webSearchImplementation === 'anthropic') &&
|
|
346
|
-
renderDomainList('webSearch.allowedDomains', trans.__('Allowed Domains'), trans.__('example.com'), webSearchSettings.allowedDomains),
|
|
347
|
-
webSearchImplementation === 'openai' && (React.createElement(React.Fragment, null,
|
|
348
|
-
React.createElement(FormControl, { fullWidth: true },
|
|
349
|
-
React.createElement(InputLabel, null, trans.__('Search Context Size')),
|
|
350
|
-
React.createElement(Select, { value: webSearchSettings.searchContextSize ??
|
|
351
|
-
'medium', label: trans.__('Search Context Size'), onChange: e => updateCustomSetting('webSearch', 'searchContextSize', e.target.value) },
|
|
352
|
-
React.createElement(MenuItem, { value: "low" }, trans.__('Low')),
|
|
353
|
-
React.createElement(MenuItem, { value: "medium" }, trans.__('Medium')),
|
|
354
|
-
React.createElement(MenuItem, { value: "high" }, trans.__('High')))),
|
|
355
|
-
React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: webSearchSettings.externalWebAccess !==
|
|
356
|
-
false, onChange: e => updateCustomSetting('webSearch', 'externalWebAccess', e.target.checked) }), label: trans.__('Use External Web Access') }))),
|
|
357
|
-
webSearchImplementation === 'anthropic' && (React.createElement(React.Fragment, null,
|
|
358
|
-
React.createElement(TextField, { fullWidth: true, label: trans.__('Web Search Max Uses'), type: "number", value: webSearchSettings.maxUses ?? '', onChange: e => updateCustomSetting('webSearch', 'maxUses', e.target.value
|
|
359
|
-
? Number(e.target.value)
|
|
360
|
-
: undefined), slotProps: { htmlInput: { min: 1 } } }),
|
|
361
|
-
renderDomainList('webSearch.blockedDomains', trans.__('Blocked Domains'), trans.__('spam.example.com'), webSearchSettings.blockedDomains))))))),
|
|
362
|
-
supportsWebFetch && (React.createElement(React.Fragment, null,
|
|
363
|
-
React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: webFetchSettings.enabled === true, onChange: e => updateCustomSetting('webFetch', 'enabled', e.target.checked) }), label: trans.__('Enable Web Fetch') }),
|
|
364
|
-
webFetchSettings.enabled === true && (React.createElement(Box, { sx: {
|
|
365
|
-
pl: 2,
|
|
366
|
-
borderLeft: 2,
|
|
367
|
-
borderColor: 'divider',
|
|
368
|
-
display: 'flex',
|
|
369
|
-
flexDirection: 'column',
|
|
370
|
-
gap: 1.5
|
|
371
|
-
} },
|
|
372
|
-
React.createElement(TextField, { fullWidth: true, label: trans.__('Web Fetch Max Uses'), type: "number", value: webFetchSettings.maxUses ?? '', onChange: e => updateCustomSetting('webFetch', 'maxUses', e.target.value
|
|
373
|
-
? Number(e.target.value)
|
|
374
|
-
: undefined), slotProps: { htmlInput: { min: 1 } } }),
|
|
375
|
-
React.createElement(TextField, { fullWidth: true, label: trans.__('Web Fetch Max Content Tokens'), type: "number", value: webFetchSettings.maxContentTokens ?? '', onChange: e => updateCustomSetting('webFetch', 'maxContentTokens', e.target.value
|
|
376
|
-
? Number(e.target.value)
|
|
377
|
-
: undefined), slotProps: { htmlInput: { min: 1 } } }),
|
|
378
|
-
renderDomainList('webFetch.allowedDomains', trans.__('Allowed Domains'), trans.__('docs.example.com'), webFetchSettings.allowedDomains),
|
|
379
|
-
renderDomainList('webFetch.blockedDomains', trans.__('Blocked Domains'), trans.__('spam.example.com'), webFetchSettings.blockedDomains),
|
|
380
|
-
React.createElement(FormControlLabel, { control: React.createElement(Switch, { checked: webFetchSettings.citationsEnabled === true, onChange: e => updateCustomSetting('webFetch', 'citationsEnabled', e.target.checked) }), label: trans.__('Enable Citations') })))))))))))),
|
|
381
|
-
React.createElement(DialogActions, null,
|
|
382
|
-
React.createElement(Button, { onClick: onClose }, trans.__('Cancel')),
|
|
383
|
-
React.createElement(Button, { onClick: handleSave, variant: "contained", disabled: !isValid }, mode === 'add' ? trans.__('Add Provider') : trans.__('Save Changes')))));
|
|
239
|
+
return (_jsxs(Dialog, { open: open, onClose: onClose, maxWidth: "md", fullWidth: true, children: [_jsx(DialogTitle, { children: mode === 'add'
|
|
240
|
+
? trans.__('Add New Provider')
|
|
241
|
+
: trans.__('Edit Provider') }), _jsx(DialogContent, { children: _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2, pt: 1 }, children: [_jsx(TextField, { fullWidth: true, label: trans.__('Provider Name'), value: name, onChange: e => setName(e.target.value), placeholder: trans.__('e.g., My Anthropic Config, Work Provider'), helperText: trans.__('A friendly name to identify this provider configuration'), required: true }), _jsxs(FormControl, { fullWidth: true, required: true, children: [_jsx(InputLabel, { children: trans.__('Provider Type') }), _jsx(Select, { value: provider, label: trans.__('Provider Type'), onChange: e => handleProviderChange(e.target.value), children: providerOptions.map(option => (_jsx(MenuItem, { value: option.value, children: _jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [option.label, option.apiKeyRequirement === 'required' && (_jsx(Chip, { size: "small", label: trans.__('API Key'), color: "default", variant: "outlined" }))] }), option.description && (_jsx(Typography, { variant: "caption", color: "text.secondary", children: option.description }))] }) }, option.value))) })] }), _jsx(Autocomplete, { freeSolo: true, fullWidth: true, options: selectedProvider?.models ?? [], value: model, onChange: (_, value) => {
|
|
242
|
+
setModel(typeof value === 'string' ? value : '');
|
|
243
|
+
}, inputValue: model, onInputChange: (_, value) => {
|
|
244
|
+
setModel(value);
|
|
245
|
+
}, renderInput: params => (_jsx(TextField, { ...params, fullWidth: true, label: trans.__('Model'), placeholder: trans.__('Select or type a model ID'), required: true, helperText: trans.__('Choose from the list or enter a custom model ID') })), clearOnBlur: false }), selectedProvider &&
|
|
246
|
+
selectedProvider?.apiKeyRequirement !== 'none' && (_jsx(TextField, { fullWidth: true, inputRef: handleRef, label: selectedProvider?.apiKeyRequirement === 'required'
|
|
247
|
+
? trans.__('API Key')
|
|
248
|
+
: trans.__('API Key (Optional)'), type: showApiKey ? 'text' : 'password', value: apiKey, onChange: e => setApiKey(e.target.value), placeholder: trans.__('Enter your API key...'), required: selectedProvider?.apiKeyRequirement === 'required', InputProps: {
|
|
249
|
+
endAdornment: (_jsx(InputAdornment, { position: "end", children: _jsx(IconButton, { onClick: () => setShowApiKey(!showApiKey), edge: "end", children: showApiKey ? _jsx(VisibilityOff, {}) : _jsx(Visibility, {}) }) }))
|
|
250
|
+
} })), selectedProvider?.supportsBaseURL && (_jsx(Autocomplete, { freeSolo: true, fullWidth: true, options: (selectedProvider.baseUrls ?? []).map(option => option.url), value: baseURL || '', onChange: (_, value) => {
|
|
251
|
+
if (value && typeof value === 'string') {
|
|
252
|
+
setBaseURL(value);
|
|
253
|
+
}
|
|
254
|
+
}, inputValue: baseURL || '', renderOption: (props, option) => {
|
|
255
|
+
const urlOption = (selectedProvider.baseUrls ?? []).find(u => u.url === option);
|
|
256
|
+
return (_createElement(Box, { component: "li", ...props, key: option },
|
|
257
|
+
_jsxs(Box, { children: [_jsx(Typography, { variant: "body2", children: option }), urlOption?.description && (_jsx(Typography, { variant: "caption", color: "text.secondary", children: urlOption.description }))] })));
|
|
258
|
+
}, renderInput: params => (_jsx(TextField, { ...params, fullWidth: true, label: trans.__('Base URL'), placeholder: "https://api.example.com/v1", onChange: e => setBaseURL(e.target.value) })), clearOnBlur: false })), _jsxs(Accordion, { expanded: expandedAdvanced, onChange: (_, isExpanded) => setExpandedAdvanced(isExpanded), sx: {
|
|
259
|
+
mt: 2,
|
|
260
|
+
bgcolor: 'transparent',
|
|
261
|
+
boxShadow: 'none',
|
|
262
|
+
border: 1,
|
|
263
|
+
borderColor: 'divider',
|
|
264
|
+
borderRadius: 1
|
|
265
|
+
}, children: [_jsx(AccordionSummary, { expandIcon: _jsx(ExpandMore, {}), children: _jsx(Typography, { variant: "subtitle1", fontWeight: "medium", children: trans.__('Advanced Settings') }) }), _jsx(AccordionDetails, { sx: { bgcolor: 'transparent' }, children: _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { children: [_jsx(Typography, { gutterBottom: true, children: trans.__('Temperature: %1', parameters.temperature ?? trans.__('Default')) }), _jsx(Slider, { value: parameters.temperature ?? DEFAULT_TEMPERATURE, onChange: (_, value) => setParameters({
|
|
266
|
+
...parameters,
|
|
267
|
+
temperature: value
|
|
268
|
+
}), min: 0, max: 2, step: 0.1, valueLabelDisplay: "auto" }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: trans.__('Temperature for the model (lower values are more deterministic)') })] }), _jsx(TextField, { fullWidth: true, label: trans.__('Max Tokens (Optional)'), type: "number", value: parameters.maxOutputTokens ?? '', onChange: e => setParameters({
|
|
269
|
+
...parameters,
|
|
270
|
+
maxOutputTokens: e.target.value
|
|
271
|
+
? Number(e.target.value)
|
|
272
|
+
: undefined
|
|
273
|
+
}), placeholder: trans.__('Leave empty for provider default'), helperText: trans.__('Maximum length of AI responses'), slotProps: { htmlInput: { min: 1 } } }), _jsx(TextField, { fullWidth: true, label: trans.__('Max Turns (Optional)'), type: "number", value: parameters.maxTurns ?? '', onChange: e => setParameters({
|
|
274
|
+
...parameters,
|
|
275
|
+
maxTurns: e.target.value
|
|
276
|
+
? Number(e.target.value)
|
|
277
|
+
: undefined
|
|
278
|
+
}), placeholder: trans.__('Default: %1', DEFAULT_MAX_TURNS), helperText: trans.__('Maximum number of tool execution turns'), slotProps: { htmlInput: { min: 1, max: 100 } } }), _jsx(TextField, { fullWidth: true, label: trans.__('Context Window (Optional)'), type: "number", value: parameters.contextWindow ?? '', onChange: e => setParameters({
|
|
279
|
+
...parameters,
|
|
280
|
+
contextWindow: e.target.value
|
|
281
|
+
? Number(e.target.value)
|
|
282
|
+
: undefined
|
|
283
|
+
}), placeholder: selectedModelInfo?.contextWindow !== undefined
|
|
284
|
+
? trans.__('Default: %1', selectedModelInfo.contextWindow.toLocaleString())
|
|
285
|
+
: trans.__('e.g., 128000'), helperText: selectedModelInfo?.contextWindow !== undefined &&
|
|
286
|
+
parameters.contextWindow === undefined
|
|
287
|
+
? trans.__('Using provider metadata default of %1 tokens for this model unless you override it here.', selectedModelInfo.contextWindow.toLocaleString())
|
|
288
|
+
: trans.__('Model context window size in tokens (used for context usage estimation)'), slotProps: { htmlInput: { min: 1 } } }), _jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 2, mb: 1 }, children: trans.__('Completion Options') }), _jsx(FormControlLabel, { control: _jsx(Switch, { checked: parameters.supportsFillInMiddle ?? false, onChange: e => setParameters({
|
|
289
|
+
...parameters,
|
|
290
|
+
supportsFillInMiddle: e.target.checked
|
|
291
|
+
}) }), label: trans.__('Fill-in-the-middle support') }), _jsx(FormControlLabel, { control: _jsx(Switch, { checked: parameters.useFilterText ?? false, onChange: e => setParameters({
|
|
292
|
+
...parameters,
|
|
293
|
+
useFilterText: e.target.checked
|
|
294
|
+
}) }), label: trans.__('Use filter text') }), (supportsWebSearch || supportsWebFetch) && (_jsxs(_Fragment, { children: [_jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 2, mb: 1 }, children: trans.__('Provider Web Tools') }), supportsWebSearch && (_jsxs(_Fragment, { children: [_jsx(FormControlLabel, { control: _jsx(Switch, { checked: webSearchSettings.enabled === true, onChange: e => updateCustomSetting('webSearch', 'enabled', e.target.checked) }), label: trans.__('Enable Web Search') }), webSearchSettings.enabled === true && (_jsxs(Box, { sx: {
|
|
295
|
+
pl: 2,
|
|
296
|
+
borderLeft: 2,
|
|
297
|
+
borderColor: 'divider',
|
|
298
|
+
display: 'flex',
|
|
299
|
+
flexDirection: 'column',
|
|
300
|
+
gap: 1.5
|
|
301
|
+
}, children: [(webSearchImplementation === 'openai' ||
|
|
302
|
+
webSearchImplementation === 'anthropic') &&
|
|
303
|
+
renderDomainList('webSearch.allowedDomains', trans.__('Allowed Domains'), trans.__('example.com'), webSearchSettings.allowedDomains), webSearchImplementation === 'openai' && (_jsxs(_Fragment, { children: [_jsxs(FormControl, { fullWidth: true, children: [_jsx(InputLabel, { children: trans.__('Search Context Size') }), _jsxs(Select, { value: webSearchSettings.searchContextSize ??
|
|
304
|
+
'medium', label: trans.__('Search Context Size'), onChange: e => updateCustomSetting('webSearch', 'searchContextSize', e.target.value), children: [_jsx(MenuItem, { value: "low", children: trans.__('Low') }), _jsx(MenuItem, { value: "medium", children: trans.__('Medium') }), _jsx(MenuItem, { value: "high", children: trans.__('High') })] })] }), _jsx(FormControlLabel, { control: _jsx(Switch, { checked: webSearchSettings.externalWebAccess !==
|
|
305
|
+
false, onChange: e => updateCustomSetting('webSearch', 'externalWebAccess', e.target.checked) }), label: trans.__('Use External Web Access') })] })), webSearchImplementation === 'anthropic' && (_jsxs(_Fragment, { children: [_jsx(TextField, { fullWidth: true, label: trans.__('Web Search Max Uses'), type: "number", value: webSearchSettings.maxUses ?? '', onChange: e => updateCustomSetting('webSearch', 'maxUses', e.target.value
|
|
306
|
+
? Number(e.target.value)
|
|
307
|
+
: undefined), slotProps: { htmlInput: { min: 1 } } }), renderDomainList('webSearch.blockedDomains', trans.__('Blocked Domains'), trans.__('spam.example.com'), webSearchSettings.blockedDomains)] }))] }))] })), supportsWebFetch && (_jsxs(_Fragment, { children: [_jsx(FormControlLabel, { control: _jsx(Switch, { checked: webFetchSettings.enabled === true, onChange: e => updateCustomSetting('webFetch', 'enabled', e.target.checked) }), label: trans.__('Enable Web Fetch') }), webFetchSettings.enabled === true && (_jsxs(Box, { sx: {
|
|
308
|
+
pl: 2,
|
|
309
|
+
borderLeft: 2,
|
|
310
|
+
borderColor: 'divider',
|
|
311
|
+
display: 'flex',
|
|
312
|
+
flexDirection: 'column',
|
|
313
|
+
gap: 1.5
|
|
314
|
+
}, children: [_jsx(TextField, { fullWidth: true, label: trans.__('Web Fetch Max Uses'), type: "number", value: webFetchSettings.maxUses ?? '', onChange: e => updateCustomSetting('webFetch', 'maxUses', e.target.value
|
|
315
|
+
? Number(e.target.value)
|
|
316
|
+
: undefined), slotProps: { htmlInput: { min: 1 } } }), _jsx(TextField, { fullWidth: true, label: trans.__('Web Fetch Max Content Tokens'), type: "number", value: webFetchSettings.maxContentTokens ?? '', onChange: e => updateCustomSetting('webFetch', 'maxContentTokens', e.target.value
|
|
317
|
+
? Number(e.target.value)
|
|
318
|
+
: undefined), slotProps: { htmlInput: { min: 1 } } }), renderDomainList('webFetch.allowedDomains', trans.__('Allowed Domains'), trans.__('docs.example.com'), webFetchSettings.allowedDomains), renderDomainList('webFetch.blockedDomains', trans.__('Blocked Domains'), trans.__('spam.example.com'), webFetchSettings.blockedDomains), _jsx(FormControlLabel, { control: _jsx(Switch, { checked: webFetchSettings.citationsEnabled === true, onChange: e => updateCustomSetting('webFetch', 'citationsEnabled', e.target.checked) }), label: trans.__('Enable Citations') })] }))] }))] }))] }) })] })] }) }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: onClose, children: trans.__('Cancel') }), _jsx(Button, { onClick: handleSave, variant: "contained", disabled: !isValid, children: mode === 'add' ? trans.__('Add Provider') : trans.__('Save Changes') })] })] }));
|
|
384
319
|
};
|