@jupyterlite/ai 0.17.0 → 0.18.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/agent.d.ts +12 -9
- package/lib/agent.js +38 -51
- package/lib/chat-model-handler.d.ts +2 -3
- package/lib/chat-model-handler.js +2 -1
- package/lib/chat-model.d.ts +110 -8
- package/lib/chat-model.js +322 -63
- package/lib/components/save-button.d.ts +2 -2
- package/lib/index.js +29 -49
- package/lib/models/settings-model.js +1 -0
- package/lib/providers/built-in-providers.js +1 -1
- package/lib/providers/{generated-context-windows.d.ts → generated-model-info.d.ts} +2 -2
- package/lib/providers/generated-model-info.js +502 -0
- package/lib/providers/model-info.d.ts +3 -0
- package/lib/providers/model-info.js +33 -0
- package/lib/tokens.d.ts +85 -12
- package/lib/widgets/ai-settings.js +5 -0
- package/lib/widgets/main-area-chat.d.ts +2 -3
- package/lib/widgets/main-area-chat.js +2 -4
- package/package.json +3 -3
- package/schema/settings-model.json +6 -0
- package/src/agent.ts +46 -56
- package/src/chat-model-handler.ts +4 -2
- package/src/chat-model.ts +435 -90
- package/src/components/save-button.tsx +3 -3
- package/src/index.ts +52 -74
- package/src/models/settings-model.ts +1 -0
- package/src/providers/built-in-providers.ts +1 -1
- package/src/providers/generated-model-info.ts +508 -0
- package/src/providers/model-info.ts +57 -0
- package/src/tokens.ts +87 -12
- package/src/widgets/ai-settings.tsx +26 -0
- package/src/widgets/main-area-chat.ts +5 -8
- package/lib/providers/generated-context-windows.js +0 -96
- package/src/providers/generated-context-windows.ts +0 -102
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
8
8
|
import React, { useEffect, useState } from 'react';
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { IAIChatModel } from '../tokens';
|
|
11
11
|
|
|
12
12
|
const COMPONENT_CLASS = 'jp-ai-SaveButton';
|
|
13
13
|
const AUTOSAVE_BUTTON_CLASS = 'jp-ai-AutoSaveButton';
|
|
@@ -19,7 +19,7 @@ export interface ISaveButtonProps {
|
|
|
19
19
|
/**
|
|
20
20
|
* The chat model, used to listen for message changes for auto-save.
|
|
21
21
|
*/
|
|
22
|
-
model:
|
|
22
|
+
model: IAIChatModel;
|
|
23
23
|
/**
|
|
24
24
|
* The application language translator.
|
|
25
25
|
*/
|
|
@@ -40,7 +40,7 @@ export function SaveComponent(props: ISaveButtonProps): JSX.Element {
|
|
|
40
40
|
* Effect that update the autosave state when it is updated on the model.
|
|
41
41
|
*/
|
|
42
42
|
useEffect(() => {
|
|
43
|
-
const updateAutosave = (_:
|
|
43
|
+
const updateAutosave = (_: IAIChatModel, value: boolean) => {
|
|
44
44
|
setAutosave(value);
|
|
45
45
|
};
|
|
46
46
|
|
package/src/index.ts
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
ToolbarButton
|
|
59
59
|
} from '@jupyterlab/ui-components';
|
|
60
60
|
|
|
61
|
-
import {
|
|
61
|
+
import { UUID } from '@lumino/coreutils';
|
|
62
62
|
|
|
63
63
|
import { DisposableSet } from '@lumino/disposable';
|
|
64
64
|
|
|
@@ -70,8 +70,6 @@ import { ISecretsManager, SecretsManager } from 'jupyter-secrets-manager';
|
|
|
70
70
|
|
|
71
71
|
import { AgentManagerFactory } from './agent';
|
|
72
72
|
|
|
73
|
-
import { AIChatModel } from './chat-model';
|
|
74
|
-
|
|
75
73
|
import { RenderedMessageOutputAreaCompat } from './rendered-message-outputarea';
|
|
76
74
|
|
|
77
75
|
import { ClearCommandProvider } from './chat-commands/clear';
|
|
@@ -95,7 +93,8 @@ import {
|
|
|
95
93
|
IProviderRegistry,
|
|
96
94
|
IToolRegistry,
|
|
97
95
|
ISkillRegistry,
|
|
98
|
-
SECRETS_NAMESPACE
|
|
96
|
+
SECRETS_NAMESPACE,
|
|
97
|
+
IAIChatModel
|
|
99
98
|
} from './tokens';
|
|
100
99
|
|
|
101
100
|
import {
|
|
@@ -526,7 +525,7 @@ const plugin: JupyterFrontEndPlugin<IChatTracker> = {
|
|
|
526
525
|
|
|
527
526
|
let usageWidget: UsageWidget | null = null;
|
|
528
527
|
chatPanel.chatOpened.connect((_, widget) => {
|
|
529
|
-
const model = widget.model as
|
|
528
|
+
const model = widget.model as IAIChatModel;
|
|
530
529
|
|
|
531
530
|
// Add the widget to the tracker.
|
|
532
531
|
tracker.add(widget);
|
|
@@ -585,11 +584,9 @@ const plugin: JupyterFrontEndPlugin<IChatTracker> = {
|
|
|
585
584
|
);
|
|
586
585
|
|
|
587
586
|
if (aiWriting) {
|
|
588
|
-
widget.inputToolbarRegistry?.hide('send');
|
|
589
587
|
widget.inputToolbarRegistry?.show('stop');
|
|
590
588
|
} else {
|
|
591
589
|
widget.inputToolbarRegistry?.hide('stop');
|
|
592
|
-
widget.inputToolbarRegistry?.show('send');
|
|
593
590
|
}
|
|
594
591
|
}
|
|
595
592
|
|
|
@@ -628,7 +625,7 @@ const plugin: JupyterFrontEndPlugin<IChatTracker> = {
|
|
|
628
625
|
args: widget => ({
|
|
629
626
|
name: widget.model.name,
|
|
630
627
|
area: widget instanceof MainAreaChat ? 'main' : 'side',
|
|
631
|
-
provider: (widget.model as
|
|
628
|
+
provider: (widget.model as IAIChatModel).agentManager.activeProvider
|
|
632
629
|
}),
|
|
633
630
|
name: widget => {
|
|
634
631
|
const area = widget instanceof MainAreaChat ? 'main' : 'side';
|
|
@@ -662,24 +659,39 @@ const plugin: JupyterFrontEndPlugin<IChatTracker> = {
|
|
|
662
659
|
);
|
|
663
660
|
|
|
664
661
|
/**
|
|
665
|
-
* The callback
|
|
662
|
+
* The callback for grouped tool calls permission decisions.
|
|
666
663
|
*/
|
|
667
|
-
function
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
664
|
+
function toolCallPermissionDecision(
|
|
665
|
+
sessionId: string,
|
|
666
|
+
toolCallId: string,
|
|
667
|
+
optionId: string
|
|
671
668
|
) {
|
|
672
|
-
const model = tracker.find(chat => chat.model.name ===
|
|
669
|
+
const model = tracker.find(chat => chat.model.name === sessionId)
|
|
670
|
+
?.model as IAIChatModel;
|
|
673
671
|
if (!model) {
|
|
674
672
|
return;
|
|
675
673
|
}
|
|
674
|
+
|
|
675
|
+
const isApproved = optionId === 'approve';
|
|
676
676
|
isApproved
|
|
677
|
-
?
|
|
678
|
-
:
|
|
677
|
+
? model.agentManager.approveToolCall(toolCallId)
|
|
678
|
+
: model.agentManager.rejectToolCall(toolCallId);
|
|
679
679
|
}
|
|
680
680
|
|
|
681
681
|
if (chatComponentsFactory) {
|
|
682
|
-
chatComponentsFactory.
|
|
682
|
+
chatComponentsFactory.toolCallPermissionDecision =
|
|
683
|
+
toolCallPermissionDecision;
|
|
684
|
+
|
|
685
|
+
chatComponentsFactory.removeQueuedMessage = (
|
|
686
|
+
targetId: string,
|
|
687
|
+
messageId: string
|
|
688
|
+
) => {
|
|
689
|
+
const model = tracker.find(chat => chat.model.name === targetId)?.model;
|
|
690
|
+
if (!model) {
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
(model as IAIChatModel).removeQueuedMessage(messageId);
|
|
694
|
+
};
|
|
683
695
|
}
|
|
684
696
|
|
|
685
697
|
return tracker;
|
|
@@ -755,12 +767,13 @@ function registerCommands(
|
|
|
755
767
|
}
|
|
756
768
|
});
|
|
757
769
|
|
|
758
|
-
const openInMain = (model:
|
|
770
|
+
const openInMain = (model: IAIChatModel): MainAreaChat => {
|
|
771
|
+
const inputToolbarRegistry = inputToolbarFactory.create();
|
|
759
772
|
const content = new ChatWidget({
|
|
760
773
|
model,
|
|
761
774
|
rmRegistry,
|
|
762
775
|
themeManager: themeManager ?? null,
|
|
763
|
-
inputToolbarRegistry
|
|
776
|
+
inputToolbarRegistry,
|
|
764
777
|
attachmentOpenerRegistry,
|
|
765
778
|
chatCommandRegistry
|
|
766
779
|
});
|
|
@@ -827,7 +840,7 @@ function registerCommands(
|
|
|
827
840
|
return;
|
|
828
841
|
}
|
|
829
842
|
return tracker.find(widget => {
|
|
830
|
-
const model = widget.model as
|
|
843
|
+
const model = widget.model as IAIChatModel;
|
|
831
844
|
return (
|
|
832
845
|
(!name || widget.model.name === name) &&
|
|
833
846
|
(!provider || model.agentManager.activeProvider === provider)
|
|
@@ -1064,11 +1077,11 @@ function registerCommands(
|
|
|
1064
1077
|
return false;
|
|
1065
1078
|
}
|
|
1066
1079
|
let previousWidget: ChatWidget | MainAreaChat | undefined;
|
|
1067
|
-
let previousModel:
|
|
1080
|
+
let previousModel: IAIChatModel | undefined;
|
|
1068
1081
|
tracker.forEach(widget => {
|
|
1069
1082
|
if (widget.model.name === args.name) {
|
|
1070
1083
|
previousWidget = widget;
|
|
1071
|
-
previousModel = widget.model as
|
|
1084
|
+
previousModel = widget.model as IAIChatModel;
|
|
1072
1085
|
}
|
|
1073
1086
|
});
|
|
1074
1087
|
|
|
@@ -1079,61 +1092,26 @@ function registerCommands(
|
|
|
1079
1092
|
return false;
|
|
1080
1093
|
}
|
|
1081
1094
|
|
|
1082
|
-
// Listen for the widget updated in tracker, to ensure the previous model name
|
|
1083
|
-
// has been updated. This is required to remove the widget from the restorer
|
|
1084
|
-
// when the previous widget is disposed.
|
|
1085
|
-
const trackerUpdated = new PromiseDelegate<boolean>();
|
|
1086
|
-
const widgetUpdated = (_: any, widget: ChatWidget | MainAreaChat) => {
|
|
1087
|
-
if (widget.model === previousModel) {
|
|
1088
|
-
trackerUpdated.resolve(true);
|
|
1089
|
-
}
|
|
1090
|
-
};
|
|
1091
|
-
tracker.widgetUpdated.connect(widgetUpdated);
|
|
1092
|
-
|
|
1093
|
-
// Rename temporary the previous model to be able to reuse this name for the new
|
|
1094
|
-
// model. The previous is intended to be disposed anyway.
|
|
1095
|
-
previousModel.name = UUID.uuid4();
|
|
1096
|
-
|
|
1097
|
-
// Create a new model by duplicating the previous model attributes.
|
|
1098
|
-
const model = modelRegistry.createModel({
|
|
1099
|
-
name: args.name as string,
|
|
1100
|
-
activeProvider: previousModel.agentManager.activeProvider,
|
|
1101
|
-
tokenUsage: previousModel.agentManager.tokenUsage,
|
|
1102
|
-
messages: previousModel.messages,
|
|
1103
|
-
autosave: previousModel.autosave,
|
|
1104
|
-
title: previousModel.title
|
|
1105
|
-
});
|
|
1106
|
-
|
|
1107
|
-
// Wait (with timeout) for the tracker to have updated the previous widget.
|
|
1108
|
-
const status = await Promise.any([
|
|
1109
|
-
trackerUpdated.promise,
|
|
1110
|
-
new Promise<boolean>(r =>
|
|
1111
|
-
setTimeout(() => {
|
|
1112
|
-
r(false);
|
|
1113
|
-
}, 2000)
|
|
1114
|
-
)
|
|
1115
|
-
]);
|
|
1116
|
-
tracker.widgetUpdated.disconnect(widgetUpdated);
|
|
1117
|
-
|
|
1118
|
-
if (!status) {
|
|
1119
|
-
return false;
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
1095
|
if (area === 'main') {
|
|
1123
|
-
|
|
1096
|
+
// Temporarily bypass model disposal to transport model to main view
|
|
1097
|
+
// to keep the conversation when switching views
|
|
1098
|
+
// TODO: Remove this code when jupyter-chat PR #423 is merged and released
|
|
1099
|
+
const originalDispose = previousModel.dispose.bind(previousModel);
|
|
1100
|
+
previousModel.dispose = () => {};
|
|
1124
1101
|
|
|
1125
1102
|
if (previousWidget instanceof ChatWidget) {
|
|
1126
|
-
// Clean up the side-panel model entry before disposing the previous
|
|
1127
|
-
// widget/model state.
|
|
1128
1103
|
if (!disposeSideChatModel(previousModel)) {
|
|
1129
1104
|
previousWidget.dispose();
|
|
1130
|
-
previousModel.dispose();
|
|
1131
1105
|
}
|
|
1132
1106
|
}
|
|
1107
|
+
|
|
1108
|
+
// Restore model disposal and transport to main view
|
|
1109
|
+
previousModel.dispose = originalDispose;
|
|
1110
|
+
openInMain(previousModel);
|
|
1133
1111
|
} else {
|
|
1112
|
+
// MainAreaChat disposal does not dispose the model internally, so this is safe.
|
|
1134
1113
|
previousWidget?.dispose();
|
|
1135
|
-
|
|
1136
|
-
chatPanel.open({ model });
|
|
1114
|
+
chatPanel.open({ model: previousModel });
|
|
1137
1115
|
}
|
|
1138
1116
|
|
|
1139
1117
|
return true;
|
|
@@ -1162,15 +1140,15 @@ function registerCommands(
|
|
|
1162
1140
|
caption: trans.__('Save the chat as local file'),
|
|
1163
1141
|
icon: saveIcon,
|
|
1164
1142
|
execute: async (args): Promise<boolean> => {
|
|
1165
|
-
let model:
|
|
1143
|
+
let model: IAIChatModel | null = null;
|
|
1166
1144
|
if (args.name) {
|
|
1167
1145
|
tracker.forEach(widget => {
|
|
1168
1146
|
if (widget.model.name === args.name) {
|
|
1169
|
-
model = widget.model as
|
|
1147
|
+
model = widget.model as IAIChatModel;
|
|
1170
1148
|
}
|
|
1171
1149
|
});
|
|
1172
1150
|
} else {
|
|
1173
|
-
model = (tracker.currentWidget?.model as
|
|
1151
|
+
model = (tracker.currentWidget?.model as IAIChatModel) ?? null;
|
|
1174
1152
|
}
|
|
1175
1153
|
if (model === null) {
|
|
1176
1154
|
console.log('No chat to save');
|
|
@@ -1207,15 +1185,15 @@ function registerCommands(
|
|
|
1207
1185
|
console.warn('The restoration is not possible');
|
|
1208
1186
|
return false;
|
|
1209
1187
|
}
|
|
1210
|
-
let model:
|
|
1188
|
+
let model: IAIChatModel | null = null;
|
|
1211
1189
|
if (args.name) {
|
|
1212
1190
|
tracker.forEach(widget => {
|
|
1213
1191
|
if (widget.model.name === args.name) {
|
|
1214
|
-
model = widget.model as
|
|
1192
|
+
model = widget.model as IAIChatModel;
|
|
1215
1193
|
}
|
|
1216
1194
|
});
|
|
1217
1195
|
} else {
|
|
1218
|
-
model = (tracker.currentWidget?.model as
|
|
1196
|
+
model = (tracker.currentWidget?.model as IAIChatModel) ?? null;
|
|
1219
1197
|
}
|
|
1220
1198
|
if (model === null) {
|
|
1221
1199
|
console.warn('There is no chat to restore');
|
|
@@ -29,6 +29,7 @@ export class AISettingsModel extends VDomModel implements IAISettingsModel {
|
|
|
29
29
|
diffDisplayMode: 'split',
|
|
30
30
|
skillsPaths: ['.agents/skills', '_agents/skills'],
|
|
31
31
|
chatBackupDirectory: '',
|
|
32
|
+
autoTitle: false,
|
|
32
33
|
commandsRequiringApproval: [
|
|
33
34
|
'notebook:restart-run-all',
|
|
34
35
|
'notebook:run-cell',
|
|
@@ -4,7 +4,7 @@ import { createMistral } from '@ai-sdk/mistral';
|
|
|
4
4
|
import { createOpenAI } from '@ai-sdk/openai';
|
|
5
5
|
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
|
6
6
|
|
|
7
|
-
import { BUILT_IN_PROVIDER_MODEL_INFO } from './generated-
|
|
7
|
+
import { BUILT_IN_PROVIDER_MODEL_INFO } from './generated-model-info';
|
|
8
8
|
import type { IProviderInfo } from '../tokens';
|
|
9
9
|
import type { IModelOptions } from './models';
|
|
10
10
|
|