@lvce-editor/chat-view 6.1.0 → 6.3.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/dist/chatViewWorkerMain.js +108 -10
- package/package.json +1 -1
|
@@ -1157,6 +1157,7 @@ const None = 0;
|
|
|
1157
1157
|
const RestoreFocus = 6;
|
|
1158
1158
|
|
|
1159
1159
|
const ChatNetworkWorker = 6002;
|
|
1160
|
+
const ChatToolWorker = 6005;
|
|
1160
1161
|
const ExtensionHostWorker = 44;
|
|
1161
1162
|
const OpenerWorker = 4561;
|
|
1162
1163
|
const RendererWorker = 1;
|
|
@@ -1179,7 +1180,7 @@ const {
|
|
|
1179
1180
|
const {
|
|
1180
1181
|
invoke: invoke$3,
|
|
1181
1182
|
set: set$5
|
|
1182
|
-
} = create$2(
|
|
1183
|
+
} = create$2(ChatToolWorker);
|
|
1183
1184
|
|
|
1184
1185
|
const {
|
|
1185
1186
|
invoke: invoke$2,
|
|
@@ -5869,9 +5870,6 @@ const parseBoldToken = (value, start) => {
|
|
|
5869
5870
|
const findItalicEnd = (value, start) => {
|
|
5870
5871
|
let index = start + 1;
|
|
5871
5872
|
while (index < value.length) {
|
|
5872
|
-
if (value[index] === '\n') {
|
|
5873
|
-
return -1;
|
|
5874
|
-
}
|
|
5875
5873
|
if (value[index] !== '*') {
|
|
5876
5874
|
index++;
|
|
5877
5875
|
continue;
|
|
@@ -5896,7 +5894,7 @@ const parseItalicToken = (value, start) => {
|
|
|
5896
5894
|
return undefined;
|
|
5897
5895
|
}
|
|
5898
5896
|
const text = value.slice(start + 1, end);
|
|
5899
|
-
if (!text
|
|
5897
|
+
if (!text) {
|
|
5900
5898
|
return undefined;
|
|
5901
5899
|
}
|
|
5902
5900
|
return {
|
|
@@ -5927,6 +5925,26 @@ const parseStrikethroughToken = (value, start) => {
|
|
|
5927
5925
|
}
|
|
5928
5926
|
};
|
|
5929
5927
|
};
|
|
5928
|
+
const parseInlineCodeToken = (value, start) => {
|
|
5929
|
+
if (value[start] !== '`') {
|
|
5930
|
+
return undefined;
|
|
5931
|
+
}
|
|
5932
|
+
const end = value.indexOf('`', start + 1);
|
|
5933
|
+
if (end === -1) {
|
|
5934
|
+
return undefined;
|
|
5935
|
+
}
|
|
5936
|
+
const codeText = value.slice(start + 1, end);
|
|
5937
|
+
if (!codeText || codeText.includes('\n')) {
|
|
5938
|
+
return undefined;
|
|
5939
|
+
}
|
|
5940
|
+
return {
|
|
5941
|
+
length: end - start + 1,
|
|
5942
|
+
node: {
|
|
5943
|
+
text: codeText,
|
|
5944
|
+
type: 'inline-code'
|
|
5945
|
+
}
|
|
5946
|
+
};
|
|
5947
|
+
};
|
|
5930
5948
|
const parseMathToken = (value, start) => {
|
|
5931
5949
|
if (value[start] !== '$') {
|
|
5932
5950
|
return undefined;
|
|
@@ -5973,7 +5991,7 @@ const parseMathToken = (value, start) => {
|
|
|
5973
5991
|
return undefined;
|
|
5974
5992
|
};
|
|
5975
5993
|
const parseInlineToken = (value, start) => {
|
|
5976
|
-
return parseImageToken(value, start) || parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseStrikethroughToken(value, start) || parseMathToken(value, start);
|
|
5994
|
+
return parseImageToken(value, start) || parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseStrikethroughToken(value, start) || parseInlineCodeToken(value, start) || parseMathToken(value, start);
|
|
5977
5995
|
};
|
|
5978
5996
|
const parseInlineNodes = value => {
|
|
5979
5997
|
const nodes = [];
|
|
@@ -6298,7 +6316,6 @@ const parseBlockTokens = tokens => {
|
|
|
6298
6316
|
for (let i = 0; i < tokens.length; i++) {
|
|
6299
6317
|
const token = tokens[i];
|
|
6300
6318
|
if (token.type === 'blank-line') {
|
|
6301
|
-
flushList();
|
|
6302
6319
|
flushParagraph();
|
|
6303
6320
|
continue;
|
|
6304
6321
|
}
|
|
@@ -6841,6 +6858,33 @@ const getSseEventType = value => {
|
|
|
6841
6858
|
return value && typeof value === 'object' && Reflect.get(value, 'type') === 'response.completed' ? 'sse-response-completed' : 'sse-response-part';
|
|
6842
6859
|
};
|
|
6843
6860
|
|
|
6861
|
+
const getToolCallMergeKey = toolCall => {
|
|
6862
|
+
if (toolCall.id) {
|
|
6863
|
+
return `id:${toolCall.id}`;
|
|
6864
|
+
}
|
|
6865
|
+
return `value:${toolCall.name}:${toolCall.arguments}`;
|
|
6866
|
+
};
|
|
6867
|
+
const mergeToolCalls = (existing = [], incoming) => {
|
|
6868
|
+
if (incoming.length === 0) {
|
|
6869
|
+
return existing;
|
|
6870
|
+
}
|
|
6871
|
+
const merged = [...existing];
|
|
6872
|
+
const indexByKey = new Map();
|
|
6873
|
+
for (let i = 0; i < merged.length; i++) {
|
|
6874
|
+
indexByKey.set(getToolCallMergeKey(merged[i]), i);
|
|
6875
|
+
}
|
|
6876
|
+
for (const toolCall of incoming) {
|
|
6877
|
+
const key = getToolCallMergeKey(toolCall);
|
|
6878
|
+
const existingIndex = indexByKey.get(key);
|
|
6879
|
+
if (existingIndex === undefined) {
|
|
6880
|
+
indexByKey.set(key, merged.length);
|
|
6881
|
+
merged.push(toolCall);
|
|
6882
|
+
continue;
|
|
6883
|
+
}
|
|
6884
|
+
merged[existingIndex] = toolCall;
|
|
6885
|
+
}
|
|
6886
|
+
return merged;
|
|
6887
|
+
};
|
|
6844
6888
|
const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress) => {
|
|
6845
6889
|
let updatedMessage;
|
|
6846
6890
|
const updatedSessions = sessions.map(session => {
|
|
@@ -6885,7 +6929,7 @@ const updateMessageToolCallsInSelectedSession = (sessions, parsedMessages, selec
|
|
|
6885
6929
|
}
|
|
6886
6930
|
const updatedMessage = {
|
|
6887
6931
|
...message,
|
|
6888
|
-
toolCalls
|
|
6932
|
+
toolCalls: mergeToolCalls(message.toolCalls, toolCalls)
|
|
6889
6933
|
};
|
|
6890
6934
|
nextParsedMessages = copyParsedMessageContent(nextParsedMessages, message.id, updatedMessage.id);
|
|
6891
6935
|
return updatedMessage;
|
|
@@ -7742,6 +7786,13 @@ const handleMessagesContextMenu = async state => {
|
|
|
7742
7786
|
return state;
|
|
7743
7787
|
};
|
|
7744
7788
|
|
|
7789
|
+
const handleMissingApiKeySubmit = async (state, submitterName = '') => {
|
|
7790
|
+
if (!submitterName) {
|
|
7791
|
+
return state;
|
|
7792
|
+
}
|
|
7793
|
+
return handleClick(state, submitterName);
|
|
7794
|
+
};
|
|
7795
|
+
|
|
7745
7796
|
const handleModelChange = async (state, value) => {
|
|
7746
7797
|
return {
|
|
7747
7798
|
...state,
|
|
@@ -8722,6 +8773,7 @@ const HandleDragOverChatView = 31;
|
|
|
8722
8773
|
const HandleProjectListScroll = 32;
|
|
8723
8774
|
const HandleProjectListContextMenu = 33;
|
|
8724
8775
|
const HandleClickDictationButton = 34;
|
|
8776
|
+
const HandleMissingApiKeySubmit = 35;
|
|
8725
8777
|
|
|
8726
8778
|
const getModelLabel = model => {
|
|
8727
8779
|
if (model.provider === 'openRouter') {
|
|
@@ -8888,6 +8940,12 @@ const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
|
|
|
8888
8940
|
type: Span
|
|
8889
8941
|
}, ...inlineNode.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
|
|
8890
8942
|
}
|
|
8943
|
+
if (inlineNode.type === 'inline-code') {
|
|
8944
|
+
return [{
|
|
8945
|
+
childCount: 1,
|
|
8946
|
+
type: Code
|
|
8947
|
+
}, text(inlineNode.text)];
|
|
8948
|
+
}
|
|
8891
8949
|
if (inlineNode.type === 'math-inline') {
|
|
8892
8950
|
const fallback = inlineNode.displayMode ? `$$${inlineNode.text}$$` : `$${inlineNode.text}$`;
|
|
8893
8951
|
return [text(fallback)];
|
|
@@ -8969,6 +9027,22 @@ const cssRules = [{
|
|
|
8969
9027
|
className: TokenProperty,
|
|
8970
9028
|
regex: /[a-zA-Z-]+(?=\s*:)/
|
|
8971
9029
|
}];
|
|
9030
|
+
const pythonRules = [{
|
|
9031
|
+
className: TokenComment,
|
|
9032
|
+
regex: /#[^\n]*/
|
|
9033
|
+
}, {
|
|
9034
|
+
className: TokenString,
|
|
9035
|
+
regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
|
|
9036
|
+
}, {
|
|
9037
|
+
className: TokenString,
|
|
9038
|
+
regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
|
|
9039
|
+
}, {
|
|
9040
|
+
className: TokenNumber,
|
|
9041
|
+
regex: /\b\d+\.?\d*\b/
|
|
9042
|
+
}, {
|
|
9043
|
+
className: TokenKeyword,
|
|
9044
|
+
regex: /\b(?:def|class|return|if|elif|else|for|while|in|import|from|as|with|try|except|finally|raise|lambda|yield|pass|break|continue|True|False|None|and|or|not|is)\b/
|
|
9045
|
+
}];
|
|
8972
9046
|
const tokenize = (code, rules) => {
|
|
8973
9047
|
const tokens = [];
|
|
8974
9048
|
let pos = 0;
|
|
@@ -9022,6 +9096,9 @@ const highlightCode = (code, language) => {
|
|
|
9022
9096
|
if (normalized === 'js' || normalized === 'javascript') {
|
|
9023
9097
|
return tokenize(code, jsRules);
|
|
9024
9098
|
}
|
|
9099
|
+
if (normalized === 'py' || normalized === 'python') {
|
|
9100
|
+
return tokenize(code, pythonRules);
|
|
9101
|
+
}
|
|
9025
9102
|
return [{
|
|
9026
9103
|
className: '',
|
|
9027
9104
|
text: code
|
|
@@ -9196,6 +9273,8 @@ const getMissingApiKeyDom = ({
|
|
|
9196
9273
|
}) => {
|
|
9197
9274
|
return [{
|
|
9198
9275
|
childCount: 2,
|
|
9276
|
+
method: useForm ? 'GET' : undefined,
|
|
9277
|
+
onSubmit: useForm ? HandleMissingApiKeySubmit : undefined,
|
|
9199
9278
|
type: useForm ? Form : Div
|
|
9200
9279
|
}, {
|
|
9201
9280
|
childCount: 0,
|
|
@@ -9217,7 +9296,7 @@ const getMissingApiKeyDom = ({
|
|
|
9217
9296
|
className: mergeClassNames(Button, ButtonPrimary),
|
|
9218
9297
|
disabled: saveButtonDisabled,
|
|
9219
9298
|
name: saveButtonName,
|
|
9220
|
-
onClick: HandleClick,
|
|
9299
|
+
onClick: useForm ? undefined : HandleClick,
|
|
9221
9300
|
type: Button$1
|
|
9222
9301
|
}, text(saveButtonText), {
|
|
9223
9302
|
childCount: 1,
|
|
@@ -9254,7 +9333,9 @@ const getMissingOpenRouterApiKeyDom = (openRouterApiKeyInput, openRouterApiKeySt
|
|
|
9254
9333
|
placeholder: openRouterApiKeyPlaceholder(),
|
|
9255
9334
|
saveButtonDisabled: isSaving,
|
|
9256
9335
|
saveButtonName: SaveOpenRouterApiKey,
|
|
9257
|
-
saveButtonText: isSaving ? saving() : save()
|
|
9336
|
+
saveButtonText: isSaving ? saving() : save(),
|
|
9337
|
+
saveButtonType: 'submit',
|
|
9338
|
+
useForm: true
|
|
9258
9339
|
});
|
|
9259
9340
|
};
|
|
9260
9341
|
|
|
@@ -10258,7 +10339,19 @@ const renderItems = (oldState, newState) => {
|
|
|
10258
10339
|
return [SetDom2, uid, dom];
|
|
10259
10340
|
};
|
|
10260
10341
|
|
|
10342
|
+
const getSelectedSessionToolCallSignature = state => {
|
|
10343
|
+
const selectedSession = state.sessions.find(session => session.id === state.selectedSessionId);
|
|
10344
|
+
if (!selectedSession) {
|
|
10345
|
+
return '';
|
|
10346
|
+
}
|
|
10347
|
+
return selectedSession.messages.map(message => `${message.id}:${JSON.stringify(message.toolCalls || [])}`).join('|');
|
|
10348
|
+
};
|
|
10261
10349
|
const renderIncremental = (oldState, newState) => {
|
|
10350
|
+
const oldToolCallSignature = getSelectedSessionToolCallSignature(oldState);
|
|
10351
|
+
const newToolCallSignature = getSelectedSessionToolCallSignature(newState);
|
|
10352
|
+
if (oldToolCallSignature !== newToolCallSignature) {
|
|
10353
|
+
return renderItems(oldState, newState);
|
|
10354
|
+
}
|
|
10262
10355
|
const oldDom = renderItems(oldState, oldState)[2];
|
|
10263
10356
|
const newDom = renderItems(newState, newState)[2];
|
|
10264
10357
|
const patches = diffTree(oldDom, newDom);
|
|
@@ -10472,6 +10565,10 @@ const renderEventListeners = () => {
|
|
|
10472
10565
|
}, {
|
|
10473
10566
|
name: HandleSubmit,
|
|
10474
10567
|
params: ['handleSubmit']
|
|
10568
|
+
}, {
|
|
10569
|
+
name: HandleMissingApiKeySubmit,
|
|
10570
|
+
params: ['handleMissingApiKeySubmit', 'event.submitter?.name || ""'],
|
|
10571
|
+
preventDefault: true
|
|
10475
10572
|
}];
|
|
10476
10573
|
};
|
|
10477
10574
|
|
|
@@ -10657,6 +10754,7 @@ const commandMap = {
|
|
|
10657
10754
|
'Chat.handleKeyDown': wrapCommand(handleKeyDown),
|
|
10658
10755
|
'Chat.handleMessagesContextMenu': wrapCommand(handleMessagesContextMenu),
|
|
10659
10756
|
'Chat.handleMessagesScroll': wrapCommand(handleMessagesScroll),
|
|
10757
|
+
'Chat.handleMissingApiKeySubmit': wrapCommand(handleMissingApiKeySubmit),
|
|
10660
10758
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
10661
10759
|
'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
|
|
10662
10760
|
'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
|