@lvce-editor/chat-view 6.2.0 → 6.4.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 +189 -13
- package/package.json +1 -1
|
@@ -3336,7 +3336,7 @@ const executeChatTool = async (name, rawArguments, options) => {
|
|
|
3336
3336
|
const getReadFileTool = () => {
|
|
3337
3337
|
return {
|
|
3338
3338
|
function: {
|
|
3339
|
-
description: 'Read UTF-8 text content from a file inside the currently open workspace folder. Only pass an absolute URI.',
|
|
3339
|
+
description: 'Read UTF-8 text content from a file inside the currently open workspace folder. Only pass an absolute URI. When you reference files in your response, use markdown links like [index.ts](file:///workspace/src/index.ts).',
|
|
3340
3340
|
name: 'read_file',
|
|
3341
3341
|
parameters: {
|
|
3342
3342
|
additionalProperties: false,
|
|
@@ -4042,6 +4042,25 @@ const getToolCallExecutionStatus = content => {
|
|
|
4042
4042
|
status: 'error'
|
|
4043
4043
|
};
|
|
4044
4044
|
};
|
|
4045
|
+
const getToolCallResult = (name, content) => {
|
|
4046
|
+
if (name !== 'getWorkspaceUri') {
|
|
4047
|
+
return undefined;
|
|
4048
|
+
}
|
|
4049
|
+
let parsed;
|
|
4050
|
+
try {
|
|
4051
|
+
parsed = JSON.parse(content);
|
|
4052
|
+
} catch {
|
|
4053
|
+
return undefined;
|
|
4054
|
+
}
|
|
4055
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
4056
|
+
return undefined;
|
|
4057
|
+
}
|
|
4058
|
+
const workspaceUri = Reflect.get(parsed, 'workspaceUri');
|
|
4059
|
+
if (typeof workspaceUri !== 'string' || !workspaceUri) {
|
|
4060
|
+
return undefined;
|
|
4061
|
+
}
|
|
4062
|
+
return workspaceUri;
|
|
4063
|
+
};
|
|
4045
4064
|
const getResponseOutputText = parsed => {
|
|
4046
4065
|
if (!parsed || typeof parsed !== 'object') {
|
|
4047
4066
|
return '';
|
|
@@ -4645,6 +4664,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4645
4664
|
useChatToolWorker
|
|
4646
4665
|
});
|
|
4647
4666
|
const executionStatus = getToolCallExecutionStatus(content);
|
|
4667
|
+
const toolCallResult = getToolCallResult(toolCall.name, content);
|
|
4648
4668
|
executedToolCalls.push({
|
|
4649
4669
|
arguments: toolCall.arguments,
|
|
4650
4670
|
...(executionStatus.errorStack ? {
|
|
@@ -4658,6 +4678,9 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4658
4678
|
} : {}),
|
|
4659
4679
|
id: toolCall.callId,
|
|
4660
4680
|
name: toolCall.name,
|
|
4681
|
+
...(toolCallResult ? {
|
|
4682
|
+
result: toolCallResult
|
|
4683
|
+
} : {}),
|
|
4661
4684
|
...(executionStatus.status ? {
|
|
4662
4685
|
status: executionStatus.status
|
|
4663
4686
|
} : {})
|
|
@@ -4790,6 +4813,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4790
4813
|
useChatToolWorker
|
|
4791
4814
|
});
|
|
4792
4815
|
const executionStatus = getToolCallExecutionStatus(content);
|
|
4816
|
+
const toolCallResult = getToolCallResult(toolCall.name, content);
|
|
4793
4817
|
executedToolCalls.push({
|
|
4794
4818
|
arguments: toolCall.arguments,
|
|
4795
4819
|
...(executionStatus.errorStack ? {
|
|
@@ -4803,6 +4827,9 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4803
4827
|
} : {}),
|
|
4804
4828
|
id: toolCall.callId,
|
|
4805
4829
|
name: toolCall.name,
|
|
4830
|
+
...(toolCallResult ? {
|
|
4831
|
+
result: toolCallResult
|
|
4832
|
+
} : {}),
|
|
4806
4833
|
...(executionStatus.status ? {
|
|
4807
4834
|
status: executionStatus.status
|
|
4808
4835
|
} : {})
|
|
@@ -4863,6 +4890,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4863
4890
|
}) : '{}';
|
|
4864
4891
|
if (typeof name === 'string') {
|
|
4865
4892
|
const executionStatus = getToolCallExecutionStatus(content);
|
|
4893
|
+
const toolCallResult = getToolCallResult(name, content);
|
|
4866
4894
|
executedToolCalls.push({
|
|
4867
4895
|
arguments: typeof rawArguments === 'string' ? rawArguments : '',
|
|
4868
4896
|
...(executionStatus.errorStack ? {
|
|
@@ -4876,6 +4904,9 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4876
4904
|
} : {}),
|
|
4877
4905
|
id,
|
|
4878
4906
|
name,
|
|
4907
|
+
...(toolCallResult ? {
|
|
4908
|
+
result: toolCallResult
|
|
4909
|
+
} : {}),
|
|
4879
4910
|
...(executionStatus.status ? {
|
|
4880
4911
|
status: executionStatus.status
|
|
4881
4912
|
} : {})
|
|
@@ -5756,7 +5787,14 @@ const isAlphaNumeric = value => {
|
|
|
5756
5787
|
}
|
|
5757
5788
|
return code >= 97 && code <= 122;
|
|
5758
5789
|
};
|
|
5759
|
-
const
|
|
5790
|
+
const sanitizeLinkUrl = url => {
|
|
5791
|
+
const normalized = url.trim().toLowerCase();
|
|
5792
|
+
if (normalized.startsWith('http://') || normalized.startsWith('https://') || normalized.startsWith('file://')) {
|
|
5793
|
+
return url;
|
|
5794
|
+
}
|
|
5795
|
+
return '#';
|
|
5796
|
+
};
|
|
5797
|
+
const sanitizeImageUrl = url => {
|
|
5760
5798
|
const normalized = url.trim().toLowerCase();
|
|
5761
5799
|
if (normalized.startsWith('http://') || normalized.startsWith('https://')) {
|
|
5762
5800
|
return url;
|
|
@@ -5794,7 +5832,7 @@ const parseLinkToken = (value, start) => {
|
|
|
5794
5832
|
return {
|
|
5795
5833
|
length: index - start + 1,
|
|
5796
5834
|
node: {
|
|
5797
|
-
href:
|
|
5835
|
+
href: sanitizeLinkUrl(href),
|
|
5798
5836
|
text,
|
|
5799
5837
|
type: 'link'
|
|
5800
5838
|
}
|
|
@@ -5837,7 +5875,7 @@ const parseImageToken = (value, start) => {
|
|
|
5837
5875
|
length: index - start + 1,
|
|
5838
5876
|
node: {
|
|
5839
5877
|
alt,
|
|
5840
|
-
src:
|
|
5878
|
+
src: sanitizeImageUrl(src),
|
|
5841
5879
|
type: 'image'
|
|
5842
5880
|
}
|
|
5843
5881
|
};
|
|
@@ -5870,9 +5908,6 @@ const parseBoldToken = (value, start) => {
|
|
|
5870
5908
|
const findItalicEnd = (value, start) => {
|
|
5871
5909
|
let index = start + 1;
|
|
5872
5910
|
while (index < value.length) {
|
|
5873
|
-
if (value[index] === '\n') {
|
|
5874
|
-
return -1;
|
|
5875
|
-
}
|
|
5876
5911
|
if (value[index] !== '*') {
|
|
5877
5912
|
index++;
|
|
5878
5913
|
continue;
|
|
@@ -5897,7 +5932,7 @@ const parseItalicToken = (value, start) => {
|
|
|
5897
5932
|
return undefined;
|
|
5898
5933
|
}
|
|
5899
5934
|
const text = value.slice(start + 1, end);
|
|
5900
|
-
if (!text
|
|
5935
|
+
if (!text) {
|
|
5901
5936
|
return undefined;
|
|
5902
5937
|
}
|
|
5903
5938
|
return {
|
|
@@ -5928,6 +5963,26 @@ const parseStrikethroughToken = (value, start) => {
|
|
|
5928
5963
|
}
|
|
5929
5964
|
};
|
|
5930
5965
|
};
|
|
5966
|
+
const parseInlineCodeToken = (value, start) => {
|
|
5967
|
+
if (value[start] !== '`') {
|
|
5968
|
+
return undefined;
|
|
5969
|
+
}
|
|
5970
|
+
const end = value.indexOf('`', start + 1);
|
|
5971
|
+
if (end === -1) {
|
|
5972
|
+
return undefined;
|
|
5973
|
+
}
|
|
5974
|
+
const codeText = value.slice(start + 1, end);
|
|
5975
|
+
if (!codeText || codeText.includes('\n')) {
|
|
5976
|
+
return undefined;
|
|
5977
|
+
}
|
|
5978
|
+
return {
|
|
5979
|
+
length: end - start + 1,
|
|
5980
|
+
node: {
|
|
5981
|
+
text: codeText,
|
|
5982
|
+
type: 'inline-code'
|
|
5983
|
+
}
|
|
5984
|
+
};
|
|
5985
|
+
};
|
|
5931
5986
|
const parseMathToken = (value, start) => {
|
|
5932
5987
|
if (value[start] !== '$') {
|
|
5933
5988
|
return undefined;
|
|
@@ -5974,7 +6029,7 @@ const parseMathToken = (value, start) => {
|
|
|
5974
6029
|
return undefined;
|
|
5975
6030
|
};
|
|
5976
6031
|
const parseInlineToken = (value, start) => {
|
|
5977
|
-
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);
|
|
6032
|
+
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);
|
|
5978
6033
|
};
|
|
5979
6034
|
const parseInlineNodes = value => {
|
|
5980
6035
|
const nodes = [];
|
|
@@ -6299,7 +6354,6 @@ const parseBlockTokens = tokens => {
|
|
|
6299
6354
|
for (let i = 0; i < tokens.length; i++) {
|
|
6300
6355
|
const token = tokens[i];
|
|
6301
6356
|
if (token.type === 'blank-line') {
|
|
6302
|
-
flushList();
|
|
6303
6357
|
flushParagraph();
|
|
6304
6358
|
continue;
|
|
6305
6359
|
}
|
|
@@ -6842,6 +6896,33 @@ const getSseEventType = value => {
|
|
|
6842
6896
|
return value && typeof value === 'object' && Reflect.get(value, 'type') === 'response.completed' ? 'sse-response-completed' : 'sse-response-part';
|
|
6843
6897
|
};
|
|
6844
6898
|
|
|
6899
|
+
const getToolCallMergeKey = toolCall => {
|
|
6900
|
+
if (toolCall.id) {
|
|
6901
|
+
return `id:${toolCall.id}`;
|
|
6902
|
+
}
|
|
6903
|
+
return `value:${toolCall.name}:${toolCall.arguments}`;
|
|
6904
|
+
};
|
|
6905
|
+
const mergeToolCalls = (existing = [], incoming) => {
|
|
6906
|
+
if (incoming.length === 0) {
|
|
6907
|
+
return existing;
|
|
6908
|
+
}
|
|
6909
|
+
const merged = [...existing];
|
|
6910
|
+
const indexByKey = new Map();
|
|
6911
|
+
for (let i = 0; i < merged.length; i++) {
|
|
6912
|
+
indexByKey.set(getToolCallMergeKey(merged[i]), i);
|
|
6913
|
+
}
|
|
6914
|
+
for (const toolCall of incoming) {
|
|
6915
|
+
const key = getToolCallMergeKey(toolCall);
|
|
6916
|
+
const existingIndex = indexByKey.get(key);
|
|
6917
|
+
if (existingIndex === undefined) {
|
|
6918
|
+
indexByKey.set(key, merged.length);
|
|
6919
|
+
merged.push(toolCall);
|
|
6920
|
+
continue;
|
|
6921
|
+
}
|
|
6922
|
+
merged[existingIndex] = toolCall;
|
|
6923
|
+
}
|
|
6924
|
+
return merged;
|
|
6925
|
+
};
|
|
6845
6926
|
const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress) => {
|
|
6846
6927
|
let updatedMessage;
|
|
6847
6928
|
const updatedSessions = sessions.map(session => {
|
|
@@ -6886,7 +6967,7 @@ const updateMessageToolCallsInSelectedSession = (sessions, parsedMessages, selec
|
|
|
6886
6967
|
}
|
|
6887
6968
|
const updatedMessage = {
|
|
6888
6969
|
...message,
|
|
6889
|
-
toolCalls
|
|
6970
|
+
toolCalls: mergeToolCalls(message.toolCalls, toolCalls)
|
|
6890
6971
|
};
|
|
6891
6972
|
nextParsedMessages = copyParsedMessageContent(nextParsedMessages, message.id, updatedMessage.id);
|
|
6892
6973
|
return updatedMessage;
|
|
@@ -7743,6 +7824,13 @@ const handleMessagesContextMenu = async state => {
|
|
|
7743
7824
|
return state;
|
|
7744
7825
|
};
|
|
7745
7826
|
|
|
7827
|
+
const handleMissingApiKeySubmit = async (state, submitterName = '') => {
|
|
7828
|
+
if (!submitterName) {
|
|
7829
|
+
return state;
|
|
7830
|
+
}
|
|
7831
|
+
return handleClick(state, submitterName);
|
|
7832
|
+
};
|
|
7833
|
+
|
|
7746
7834
|
const handleModelChange = async (state, value) => {
|
|
7747
7835
|
return {
|
|
7748
7836
|
...state,
|
|
@@ -8568,6 +8656,30 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
8568
8656
|
.StrikeThrough {
|
|
8569
8657
|
text-decoration: line-through;
|
|
8570
8658
|
}
|
|
8659
|
+
|
|
8660
|
+
/* syntax highlight token colors */
|
|
8661
|
+
.TokenComment {
|
|
8662
|
+
color: var(--ColorSymbolIconColorForeground, #7f8794);
|
|
8663
|
+
}
|
|
8664
|
+
|
|
8665
|
+
.TokenString {
|
|
8666
|
+
color: var(--ColorChartsGreen, #a6d189);
|
|
8667
|
+
}
|
|
8668
|
+
|
|
8669
|
+
.TokenNumber,
|
|
8670
|
+
.TokenValue {
|
|
8671
|
+
color: var(--ColorChartsBlue, #8caaee);
|
|
8672
|
+
}
|
|
8673
|
+
|
|
8674
|
+
.TokenKeyword,
|
|
8675
|
+
.TokenTag {
|
|
8676
|
+
color: var(--ColorChartsPurple, #ca9ee6);
|
|
8677
|
+
}
|
|
8678
|
+
|
|
8679
|
+
.TokenAttribute,
|
|
8680
|
+
.TokenProperty {
|
|
8681
|
+
color: var(--ColorChartsOrange, #ef9f76);
|
|
8682
|
+
}
|
|
8571
8683
|
`;
|
|
8572
8684
|
if (!renderHtmlCss.trim()) {
|
|
8573
8685
|
return baseCss;
|
|
@@ -8723,6 +8835,7 @@ const HandleDragOverChatView = 31;
|
|
|
8723
8835
|
const HandleProjectListScroll = 32;
|
|
8724
8836
|
const HandleProjectListContextMenu = 33;
|
|
8725
8837
|
const HandleClickDictationButton = 34;
|
|
8838
|
+
const HandleMissingApiKeySubmit = 35;
|
|
8726
8839
|
|
|
8727
8840
|
const getModelLabel = model => {
|
|
8728
8841
|
if (model.provider === 'openRouter') {
|
|
@@ -8857,6 +8970,9 @@ const getImageAltText = alt => {
|
|
|
8857
8970
|
}
|
|
8858
8971
|
return `${alt} (image could not be loaded)`;
|
|
8859
8972
|
};
|
|
8973
|
+
const isFileUri = href => {
|
|
8974
|
+
return href.trim().toLowerCase().startsWith('file://');
|
|
8975
|
+
};
|
|
8860
8976
|
const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
|
|
8861
8977
|
if (inlineNode.type === 'text') {
|
|
8862
8978
|
return [text(inlineNode.text)];
|
|
@@ -8889,6 +9005,12 @@ const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
|
|
|
8889
9005
|
type: Span
|
|
8890
9006
|
}, ...inlineNode.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
|
|
8891
9007
|
}
|
|
9008
|
+
if (inlineNode.type === 'inline-code') {
|
|
9009
|
+
return [{
|
|
9010
|
+
childCount: 1,
|
|
9011
|
+
type: Code
|
|
9012
|
+
}, text(inlineNode.text)];
|
|
9013
|
+
}
|
|
8892
9014
|
if (inlineNode.type === 'math-inline') {
|
|
8893
9015
|
const fallback = inlineNode.displayMode ? `$$${inlineNode.text}$$` : `$${inlineNode.text}$`;
|
|
8894
9016
|
return [text(fallback)];
|
|
@@ -8896,6 +9018,17 @@ const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
|
|
|
8896
9018
|
if (inlineNode.type === 'math-inline-dom') {
|
|
8897
9019
|
return inlineNode.dom;
|
|
8898
9020
|
}
|
|
9021
|
+
if (isFileUri(inlineNode.href)) {
|
|
9022
|
+
return [{
|
|
9023
|
+
childCount: 1,
|
|
9024
|
+
className: ChatMessageLink,
|
|
9025
|
+
'data-uri': inlineNode.href,
|
|
9026
|
+
href: '#',
|
|
9027
|
+
onClick: HandleClickReadFile,
|
|
9028
|
+
title: inlineNode.href,
|
|
9029
|
+
type: A
|
|
9030
|
+
}, text(inlineNode.text)];
|
|
9031
|
+
}
|
|
8899
9032
|
return [{
|
|
8900
9033
|
childCount: 1,
|
|
8901
9034
|
className: ChatMessageLink,
|
|
@@ -8970,6 +9103,22 @@ const cssRules = [{
|
|
|
8970
9103
|
className: TokenProperty,
|
|
8971
9104
|
regex: /[a-zA-Z-]+(?=\s*:)/
|
|
8972
9105
|
}];
|
|
9106
|
+
const pythonRules = [{
|
|
9107
|
+
className: TokenComment,
|
|
9108
|
+
regex: /#[^\n]*/
|
|
9109
|
+
}, {
|
|
9110
|
+
className: TokenString,
|
|
9111
|
+
regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
|
|
9112
|
+
}, {
|
|
9113
|
+
className: TokenString,
|
|
9114
|
+
regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
|
|
9115
|
+
}, {
|
|
9116
|
+
className: TokenNumber,
|
|
9117
|
+
regex: /\b\d+\.?\d*\b/
|
|
9118
|
+
}, {
|
|
9119
|
+
className: TokenKeyword,
|
|
9120
|
+
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/
|
|
9121
|
+
}];
|
|
8973
9122
|
const tokenize = (code, rules) => {
|
|
8974
9123
|
const tokens = [];
|
|
8975
9124
|
let pos = 0;
|
|
@@ -9023,6 +9172,9 @@ const highlightCode = (code, language) => {
|
|
|
9023
9172
|
if (normalized === 'js' || normalized === 'javascript') {
|
|
9024
9173
|
return tokenize(code, jsRules);
|
|
9025
9174
|
}
|
|
9175
|
+
if (normalized === 'py' || normalized === 'python') {
|
|
9176
|
+
return tokenize(code, pythonRules);
|
|
9177
|
+
}
|
|
9026
9178
|
return [{
|
|
9027
9179
|
className: '',
|
|
9028
9180
|
text: code
|
|
@@ -9197,6 +9349,8 @@ const getMissingApiKeyDom = ({
|
|
|
9197
9349
|
}) => {
|
|
9198
9350
|
return [{
|
|
9199
9351
|
childCount: 2,
|
|
9352
|
+
method: useForm ? 'GET' : undefined,
|
|
9353
|
+
onSubmit: useForm ? HandleMissingApiKeySubmit : undefined,
|
|
9200
9354
|
type: useForm ? Form : Div
|
|
9201
9355
|
}, {
|
|
9202
9356
|
childCount: 0,
|
|
@@ -9218,7 +9372,7 @@ const getMissingApiKeyDom = ({
|
|
|
9218
9372
|
className: mergeClassNames(Button, ButtonPrimary),
|
|
9219
9373
|
disabled: saveButtonDisabled,
|
|
9220
9374
|
name: saveButtonName,
|
|
9221
|
-
onClick: HandleClick,
|
|
9375
|
+
onClick: useForm ? undefined : HandleClick,
|
|
9222
9376
|
type: Button$1
|
|
9223
9377
|
}, text(saveButtonText), {
|
|
9224
9378
|
childCount: 1,
|
|
@@ -9255,7 +9409,9 @@ const getMissingOpenRouterApiKeyDom = (openRouterApiKeyInput, openRouterApiKeySt
|
|
|
9255
9409
|
placeholder: openRouterApiKeyPlaceholder(),
|
|
9256
9410
|
saveButtonDisabled: isSaving,
|
|
9257
9411
|
saveButtonName: SaveOpenRouterApiKey,
|
|
9258
|
-
saveButtonText: isSaving ? saving() : save()
|
|
9412
|
+
saveButtonText: isSaving ? saving() : save(),
|
|
9413
|
+
saveButtonType: 'submit',
|
|
9414
|
+
useForm: true
|
|
9259
9415
|
});
|
|
9260
9416
|
};
|
|
9261
9417
|
|
|
@@ -9746,6 +9902,9 @@ const getToolCallDisplayName = name => {
|
|
|
9746
9902
|
};
|
|
9747
9903
|
const getToolCallLabel = toolCall => {
|
|
9748
9904
|
const displayName = getToolCallDisplayName(toolCall.name);
|
|
9905
|
+
if (toolCall.name === 'getWorkspaceUri' && toolCall.result) {
|
|
9906
|
+
return `${displayName} ${toolCall.result}`;
|
|
9907
|
+
}
|
|
9749
9908
|
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
9750
9909
|
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
9751
9910
|
if (argumentPreview === '{}') {
|
|
@@ -10259,7 +10418,19 @@ const renderItems = (oldState, newState) => {
|
|
|
10259
10418
|
return [SetDom2, uid, dom];
|
|
10260
10419
|
};
|
|
10261
10420
|
|
|
10421
|
+
const getSelectedSessionToolCallSignature = state => {
|
|
10422
|
+
const selectedSession = state.sessions.find(session => session.id === state.selectedSessionId);
|
|
10423
|
+
if (!selectedSession) {
|
|
10424
|
+
return '';
|
|
10425
|
+
}
|
|
10426
|
+
return selectedSession.messages.map(message => `${message.id}:${JSON.stringify(message.toolCalls || [])}`).join('|');
|
|
10427
|
+
};
|
|
10262
10428
|
const renderIncremental = (oldState, newState) => {
|
|
10429
|
+
const oldToolCallSignature = getSelectedSessionToolCallSignature(oldState);
|
|
10430
|
+
const newToolCallSignature = getSelectedSessionToolCallSignature(newState);
|
|
10431
|
+
if (oldToolCallSignature !== newToolCallSignature) {
|
|
10432
|
+
return renderItems(oldState, newState);
|
|
10433
|
+
}
|
|
10263
10434
|
const oldDom = renderItems(oldState, oldState)[2];
|
|
10264
10435
|
const newDom = renderItems(newState, newState)[2];
|
|
10265
10436
|
const patches = diffTree(oldDom, newDom);
|
|
@@ -10473,6 +10644,10 @@ const renderEventListeners = () => {
|
|
|
10473
10644
|
}, {
|
|
10474
10645
|
name: HandleSubmit,
|
|
10475
10646
|
params: ['handleSubmit']
|
|
10647
|
+
}, {
|
|
10648
|
+
name: HandleMissingApiKeySubmit,
|
|
10649
|
+
params: ['handleMissingApiKeySubmit', 'event.submitter?.name || ""'],
|
|
10650
|
+
preventDefault: true
|
|
10476
10651
|
}];
|
|
10477
10652
|
};
|
|
10478
10653
|
|
|
@@ -10658,6 +10833,7 @@ const commandMap = {
|
|
|
10658
10833
|
'Chat.handleKeyDown': wrapCommand(handleKeyDown),
|
|
10659
10834
|
'Chat.handleMessagesContextMenu': wrapCommand(handleMessagesContextMenu),
|
|
10660
10835
|
'Chat.handleMessagesScroll': wrapCommand(handleMessagesScroll),
|
|
10836
|
+
'Chat.handleMissingApiKeySubmit': wrapCommand(handleMissingApiKeySubmit),
|
|
10661
10837
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
10662
10838
|
'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
|
|
10663
10839
|
'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
|