@lvce-editor/chat-view 2.7.0 → 2.8.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 +244 -32
- package/package.json +1 -1
|
@@ -1078,6 +1078,7 @@ const {
|
|
|
1078
1078
|
set: set$3
|
|
1079
1079
|
} = create$2(6002);
|
|
1080
1080
|
|
|
1081
|
+
const Div$1 = 4;
|
|
1081
1082
|
const Ol$1 = 49;
|
|
1082
1083
|
|
|
1083
1084
|
const ClientX = 'event.clientX';
|
|
@@ -1512,6 +1513,7 @@ const createDefaultState = () => {
|
|
|
1512
1513
|
useMockApi: false,
|
|
1513
1514
|
viewMode: 'list',
|
|
1514
1515
|
warningCount: 0,
|
|
1516
|
+
webSearchEnabled: true,
|
|
1515
1517
|
width: 0,
|
|
1516
1518
|
x: 0,
|
|
1517
1519
|
y: 0
|
|
@@ -3286,7 +3288,8 @@ const getOpenAiTools = tools => {
|
|
|
3286
3288
|
};
|
|
3287
3289
|
});
|
|
3288
3290
|
};
|
|
3289
|
-
const getOpenAiParams = (input, modelId, stream, includeObfuscation, tools, previousResponseId) => {
|
|
3291
|
+
const getOpenAiParams = (input, modelId, stream, includeObfuscation, tools, webSearchEnabled, previousResponseId) => {
|
|
3292
|
+
const openAiTools = getOpenAiTools(tools);
|
|
3290
3293
|
return {
|
|
3291
3294
|
input,
|
|
3292
3295
|
model: modelId,
|
|
@@ -3302,7 +3305,9 @@ const getOpenAiParams = (input, modelId, stream, includeObfuscation, tools, prev
|
|
|
3302
3305
|
previous_response_id: previousResponseId
|
|
3303
3306
|
} : {}),
|
|
3304
3307
|
tool_choice: 'auto',
|
|
3305
|
-
tools:
|
|
3308
|
+
tools: webSearchEnabled ? [...openAiTools, {
|
|
3309
|
+
type: 'web_search'
|
|
3310
|
+
}] : openAiTools
|
|
3306
3311
|
};
|
|
3307
3312
|
};
|
|
3308
3313
|
const getStreamChunkText = content => {
|
|
@@ -3320,6 +3325,47 @@ const getStreamChunkText = content => {
|
|
|
3320
3325
|
return typeof text === 'string' ? text : '';
|
|
3321
3326
|
}).join('');
|
|
3322
3327
|
};
|
|
3328
|
+
const getShortToolErrorMessage = error => {
|
|
3329
|
+
const trimmed = error.trim().replace(/^Error:\s*/, '');
|
|
3330
|
+
const firstLine = trimmed.split('\n')[0];
|
|
3331
|
+
if (firstLine.length <= 80) {
|
|
3332
|
+
return firstLine;
|
|
3333
|
+
}
|
|
3334
|
+
return `${firstLine.slice(0, 77)}...`;
|
|
3335
|
+
};
|
|
3336
|
+
const getToolCallExecutionStatus = content => {
|
|
3337
|
+
let parsed;
|
|
3338
|
+
try {
|
|
3339
|
+
parsed = JSON.parse(content);
|
|
3340
|
+
} catch {
|
|
3341
|
+
return {
|
|
3342
|
+
errorMessage: 'Invalid tool output',
|
|
3343
|
+
status: 'error'
|
|
3344
|
+
};
|
|
3345
|
+
}
|
|
3346
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
3347
|
+
return {
|
|
3348
|
+
errorMessage: 'Invalid tool output',
|
|
3349
|
+
status: 'error'
|
|
3350
|
+
};
|
|
3351
|
+
}
|
|
3352
|
+
const rawError = Reflect.get(parsed, 'error');
|
|
3353
|
+
if (typeof rawError !== 'string' || !rawError.trim()) {
|
|
3354
|
+
return {
|
|
3355
|
+
status: 'success'
|
|
3356
|
+
};
|
|
3357
|
+
}
|
|
3358
|
+
const errorMessage = getShortToolErrorMessage(rawError);
|
|
3359
|
+
if (/not[\s_-]?found|enoent/i.test(errorMessage)) {
|
|
3360
|
+
return {
|
|
3361
|
+
status: 'not-found'
|
|
3362
|
+
};
|
|
3363
|
+
}
|
|
3364
|
+
return {
|
|
3365
|
+
errorMessage,
|
|
3366
|
+
status: 'error'
|
|
3367
|
+
};
|
|
3368
|
+
};
|
|
3323
3369
|
const getResponseOutputText = parsed => {
|
|
3324
3370
|
if (!parsed || typeof parsed !== 'object') {
|
|
3325
3371
|
return '';
|
|
@@ -3457,12 +3503,29 @@ const updateToolCallAccumulator = (accumulator, chunk) => {
|
|
|
3457
3503
|
};
|
|
3458
3504
|
};
|
|
3459
3505
|
const getResponseFunctionCallsFromStreamingAccumulator = toolCallAccumulator => {
|
|
3460
|
-
return Object.entries(toolCallAccumulator).toSorted((a, b) =>
|
|
3506
|
+
return Object.entries(toolCallAccumulator).toSorted((a, b) => a[0].localeCompare(b[0])).map(entry => entry[1]).filter(toolCall => typeof toolCall.id === 'string' && !!toolCall.id && !!toolCall.name).map(toolCall => ({
|
|
3461
3507
|
arguments: toolCall.arguments,
|
|
3462
3508
|
callId: toolCall.id,
|
|
3463
3509
|
name: toolCall.name
|
|
3464
3510
|
}));
|
|
3465
3511
|
};
|
|
3512
|
+
const getStreamingToolCallKey = value => {
|
|
3513
|
+
if (!value || typeof value !== 'object') {
|
|
3514
|
+
return undefined;
|
|
3515
|
+
}
|
|
3516
|
+
const outputIndex = Reflect.get(value, 'output_index');
|
|
3517
|
+
if (typeof outputIndex === 'number') {
|
|
3518
|
+
return String(outputIndex);
|
|
3519
|
+
}
|
|
3520
|
+
if (typeof outputIndex === 'string' && outputIndex) {
|
|
3521
|
+
return outputIndex;
|
|
3522
|
+
}
|
|
3523
|
+
const itemId = Reflect.get(value, 'item_id');
|
|
3524
|
+
if (typeof itemId === 'string' && itemId) {
|
|
3525
|
+
return itemId;
|
|
3526
|
+
}
|
|
3527
|
+
return undefined;
|
|
3528
|
+
};
|
|
3466
3529
|
const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDataEvent) => {
|
|
3467
3530
|
if (!response.body) {
|
|
3468
3531
|
return {
|
|
@@ -3482,7 +3545,7 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3482
3545
|
if (!onToolCallsChunk) {
|
|
3483
3546
|
return;
|
|
3484
3547
|
}
|
|
3485
|
-
const toolCalls = Object.entries(toolCallAccumulator).toSorted((a, b) =>
|
|
3548
|
+
const toolCalls = Object.entries(toolCallAccumulator).toSorted((a, b) => a[0].localeCompare(b[0])).map(entry => entry[1]).filter(toolCall => !!toolCall.name);
|
|
3486
3549
|
if (toolCalls.length === 0) {
|
|
3487
3550
|
return;
|
|
3488
3551
|
}
|
|
@@ -3530,9 +3593,9 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3530
3593
|
return;
|
|
3531
3594
|
}
|
|
3532
3595
|
if (eventType === 'response.output_item.added') {
|
|
3533
|
-
const
|
|
3596
|
+
const toolCallKey = getStreamingToolCallKey(parsed);
|
|
3534
3597
|
const item = Reflect.get(parsed, 'item');
|
|
3535
|
-
if (
|
|
3598
|
+
if (!toolCallKey || !item || typeof item !== 'object') {
|
|
3536
3599
|
return;
|
|
3537
3600
|
}
|
|
3538
3601
|
const itemType = Reflect.get(item, 'type');
|
|
@@ -3551,15 +3614,15 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3551
3614
|
};
|
|
3552
3615
|
toolCallAccumulator = {
|
|
3553
3616
|
...toolCallAccumulator,
|
|
3554
|
-
[
|
|
3617
|
+
[toolCallKey]: next
|
|
3555
3618
|
};
|
|
3556
3619
|
await emitToolCallAccumulator();
|
|
3557
3620
|
return;
|
|
3558
3621
|
}
|
|
3559
3622
|
if (eventType === 'response.output_item.done') {
|
|
3560
|
-
const
|
|
3623
|
+
const toolCallKey = getStreamingToolCallKey(parsed);
|
|
3561
3624
|
const item = Reflect.get(parsed, 'item');
|
|
3562
|
-
if (
|
|
3625
|
+
if (!toolCallKey || !item || typeof item !== 'object') {
|
|
3563
3626
|
return;
|
|
3564
3627
|
}
|
|
3565
3628
|
const itemType = Reflect.get(item, 'type');
|
|
@@ -3569,13 +3632,13 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3569
3632
|
const callId = Reflect.get(item, 'call_id');
|
|
3570
3633
|
const name = Reflect.get(item, 'name');
|
|
3571
3634
|
const rawArguments = Reflect.get(item, 'arguments');
|
|
3572
|
-
const current = toolCallAccumulator[
|
|
3635
|
+
const current = toolCallAccumulator[toolCallKey] || {
|
|
3573
3636
|
arguments: '',
|
|
3574
3637
|
name: ''
|
|
3575
3638
|
};
|
|
3576
3639
|
toolCallAccumulator = {
|
|
3577
3640
|
...toolCallAccumulator,
|
|
3578
|
-
[
|
|
3641
|
+
[toolCallKey]: {
|
|
3579
3642
|
arguments: typeof rawArguments === 'string' ? rawArguments : current.arguments,
|
|
3580
3643
|
...(typeof callId === 'string' ? {
|
|
3581
3644
|
id: callId
|
|
@@ -3589,11 +3652,11 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3589
3652
|
return;
|
|
3590
3653
|
}
|
|
3591
3654
|
if (eventType === 'response.function_call_arguments.delta' || eventType === 'response.function_call_arguments.done') {
|
|
3592
|
-
const
|
|
3593
|
-
if (
|
|
3655
|
+
const toolCallKey = getStreamingToolCallKey(parsed);
|
|
3656
|
+
if (!toolCallKey) {
|
|
3594
3657
|
return;
|
|
3595
3658
|
}
|
|
3596
|
-
const current = toolCallAccumulator[
|
|
3659
|
+
const current = toolCallAccumulator[toolCallKey] || {
|
|
3597
3660
|
arguments: '',
|
|
3598
3661
|
name: ''
|
|
3599
3662
|
};
|
|
@@ -3612,7 +3675,7 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3612
3675
|
};
|
|
3613
3676
|
toolCallAccumulator = {
|
|
3614
3677
|
...toolCallAccumulator,
|
|
3615
|
-
[
|
|
3678
|
+
[toolCallKey]: next
|
|
3616
3679
|
};
|
|
3617
3680
|
await emitToolCallAccumulator();
|
|
3618
3681
|
return;
|
|
@@ -3746,7 +3809,8 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3746
3809
|
onEventStreamFinished,
|
|
3747
3810
|
onTextChunk,
|
|
3748
3811
|
onToolCallsChunk,
|
|
3749
|
-
stream
|
|
3812
|
+
stream,
|
|
3813
|
+
webSearchEnabled = false
|
|
3750
3814
|
} = options ?? {
|
|
3751
3815
|
stream: false
|
|
3752
3816
|
};
|
|
@@ -3761,7 +3825,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3761
3825
|
let response;
|
|
3762
3826
|
try {
|
|
3763
3827
|
response = await fetch(getOpenApiApiEndpoint(openApiApiBaseUrl), {
|
|
3764
|
-
body: JSON.stringify(getOpenAiParams(openAiInput, modelId, stream, includeObfuscation, tools, previousResponseId)),
|
|
3828
|
+
body: JSON.stringify(getOpenAiParams(openAiInput, modelId, stream, includeObfuscation, tools, webSearchEnabled, previousResponseId)),
|
|
3765
3829
|
headers: {
|
|
3766
3830
|
Authorization: `Bearer ${openApiApiKey}`,
|
|
3767
3831
|
'Content-Type': 'application/json',
|
|
@@ -3804,6 +3868,37 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3804
3868
|
if (streamResult.responseId) {
|
|
3805
3869
|
previousResponseId = streamResult.responseId;
|
|
3806
3870
|
}
|
|
3871
|
+
if (streamResult.responseFunctionCalls.length > 0) {
|
|
3872
|
+
openAiInput.length = 0;
|
|
3873
|
+
const executedToolCalls = [];
|
|
3874
|
+
for (const toolCall of streamResult.responseFunctionCalls) {
|
|
3875
|
+
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
3876
|
+
assetDir,
|
|
3877
|
+
platform
|
|
3878
|
+
});
|
|
3879
|
+
const executionStatus = getToolCallExecutionStatus(content);
|
|
3880
|
+
executedToolCalls.push({
|
|
3881
|
+
arguments: toolCall.arguments,
|
|
3882
|
+
...(executionStatus.errorMessage ? {
|
|
3883
|
+
errorMessage: executionStatus.errorMessage
|
|
3884
|
+
} : {}),
|
|
3885
|
+
id: toolCall.callId,
|
|
3886
|
+
name: toolCall.name,
|
|
3887
|
+
...(executionStatus.status ? {
|
|
3888
|
+
status: executionStatus.status
|
|
3889
|
+
} : {})
|
|
3890
|
+
});
|
|
3891
|
+
openAiInput.push({
|
|
3892
|
+
call_id: toolCall.callId,
|
|
3893
|
+
output: content,
|
|
3894
|
+
type: 'function_call_output'
|
|
3895
|
+
});
|
|
3896
|
+
}
|
|
3897
|
+
if (onToolCallsChunk && executedToolCalls.length > 0) {
|
|
3898
|
+
await onToolCallsChunk(executedToolCalls);
|
|
3899
|
+
}
|
|
3900
|
+
continue;
|
|
3901
|
+
}
|
|
3807
3902
|
if (onEventStreamFinished) {
|
|
3808
3903
|
await onEventStreamFinished();
|
|
3809
3904
|
}
|
|
@@ -3834,17 +3929,33 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3834
3929
|
const responseFunctionCalls = getResponseFunctionCalls(parsed);
|
|
3835
3930
|
if (responseFunctionCalls.length > 0) {
|
|
3836
3931
|
openAiInput.length = 0;
|
|
3932
|
+
const executedToolCalls = [];
|
|
3837
3933
|
for (const toolCall of responseFunctionCalls) {
|
|
3838
3934
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
3839
3935
|
assetDir,
|
|
3840
3936
|
platform
|
|
3841
3937
|
});
|
|
3938
|
+
const executionStatus = getToolCallExecutionStatus(content);
|
|
3939
|
+
executedToolCalls.push({
|
|
3940
|
+
arguments: toolCall.arguments,
|
|
3941
|
+
...(executionStatus.errorMessage ? {
|
|
3942
|
+
errorMessage: executionStatus.errorMessage
|
|
3943
|
+
} : {}),
|
|
3944
|
+
id: toolCall.callId,
|
|
3945
|
+
name: toolCall.name,
|
|
3946
|
+
...(executionStatus.status ? {
|
|
3947
|
+
status: executionStatus.status
|
|
3948
|
+
} : {})
|
|
3949
|
+
});
|
|
3842
3950
|
openAiInput.push({
|
|
3843
3951
|
call_id: toolCall.callId,
|
|
3844
3952
|
output: content,
|
|
3845
3953
|
type: 'function_call_output'
|
|
3846
3954
|
});
|
|
3847
3955
|
}
|
|
3956
|
+
if (onToolCallsChunk && executedToolCalls.length > 0) {
|
|
3957
|
+
await onToolCallsChunk(executedToolCalls);
|
|
3958
|
+
}
|
|
3848
3959
|
continue;
|
|
3849
3960
|
}
|
|
3850
3961
|
const outputText = getResponseOutputText(parsed);
|
|
@@ -3873,6 +3984,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3873
3984
|
const toolCalls = Reflect.get(message, 'tool_calls');
|
|
3874
3985
|
if (Array.isArray(toolCalls) && toolCalls.length > 0) {
|
|
3875
3986
|
openAiInput.length = 0;
|
|
3987
|
+
const executedToolCalls = [];
|
|
3876
3988
|
for (const toolCall of toolCalls) {
|
|
3877
3989
|
if (!toolCall || typeof toolCall !== 'object') {
|
|
3878
3990
|
continue;
|
|
@@ -3888,12 +4000,29 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3888
4000
|
assetDir,
|
|
3889
4001
|
platform
|
|
3890
4002
|
}) : '{}';
|
|
4003
|
+
if (typeof name === 'string') {
|
|
4004
|
+
const executionStatus = getToolCallExecutionStatus(content);
|
|
4005
|
+
executedToolCalls.push({
|
|
4006
|
+
arguments: typeof rawArguments === 'string' ? rawArguments : '',
|
|
4007
|
+
...(executionStatus.errorMessage ? {
|
|
4008
|
+
errorMessage: executionStatus.errorMessage
|
|
4009
|
+
} : {}),
|
|
4010
|
+
id,
|
|
4011
|
+
name,
|
|
4012
|
+
...(executionStatus.status ? {
|
|
4013
|
+
status: executionStatus.status
|
|
4014
|
+
} : {})
|
|
4015
|
+
});
|
|
4016
|
+
}
|
|
3891
4017
|
openAiInput.push({
|
|
3892
4018
|
call_id: id,
|
|
3893
4019
|
output: content,
|
|
3894
4020
|
type: 'function_call_output'
|
|
3895
4021
|
});
|
|
3896
4022
|
}
|
|
4023
|
+
if (onToolCallsChunk && executedToolCalls.length > 0) {
|
|
4024
|
+
await onToolCallsChunk(executedToolCalls);
|
|
4025
|
+
}
|
|
3897
4026
|
continue;
|
|
3898
4027
|
}
|
|
3899
4028
|
const content = Reflect.get(message, 'content');
|
|
@@ -4283,7 +4412,8 @@ const getAiResponse = async ({
|
|
|
4283
4412
|
selectedModelId,
|
|
4284
4413
|
streamingEnabled = false,
|
|
4285
4414
|
useMockApi,
|
|
4286
|
-
userText
|
|
4415
|
+
userText,
|
|
4416
|
+
webSearchEnabled = false
|
|
4287
4417
|
}) => {
|
|
4288
4418
|
let text = '';
|
|
4289
4419
|
const usesOpenApiModel = isOpenApiModel(selectedModelId, models);
|
|
@@ -4314,7 +4444,8 @@ const getAiResponse = async ({
|
|
|
4314
4444
|
...(onToolCallsChunk ? {
|
|
4315
4445
|
onToolCallsChunk
|
|
4316
4446
|
} : {}),
|
|
4317
|
-
stream: streamingEnabled
|
|
4447
|
+
stream: streamingEnabled,
|
|
4448
|
+
webSearchEnabled
|
|
4318
4449
|
});
|
|
4319
4450
|
if (result.type === 'success') {
|
|
4320
4451
|
const {
|
|
@@ -4703,7 +4834,8 @@ const handleSubmit = async state => {
|
|
|
4703
4834
|
sessions,
|
|
4704
4835
|
streamingEnabled,
|
|
4705
4836
|
useMockApi,
|
|
4706
|
-
viewMode
|
|
4837
|
+
viewMode,
|
|
4838
|
+
webSearchEnabled
|
|
4707
4839
|
} = state;
|
|
4708
4840
|
const userText = composerValue.trim();
|
|
4709
4841
|
if (!userText) {
|
|
@@ -4847,7 +4979,8 @@ const handleSubmit = async state => {
|
|
|
4847
4979
|
selectedModelId,
|
|
4848
4980
|
streamingEnabled,
|
|
4849
4981
|
useMockApi,
|
|
4850
|
-
userText
|
|
4982
|
+
userText,
|
|
4983
|
+
webSearchEnabled
|
|
4851
4984
|
});
|
|
4852
4985
|
const {
|
|
4853
4986
|
latestState
|
|
@@ -5168,6 +5301,11 @@ const handleKeyDown = async (state, key, shiftKey) => {
|
|
|
5168
5301
|
return handleSubmit(submitState);
|
|
5169
5302
|
};
|
|
5170
5303
|
|
|
5304
|
+
const handleMessagesContextMenu = async state => {
|
|
5305
|
+
await invoke('ContextMenu.show', 1234);
|
|
5306
|
+
return state;
|
|
5307
|
+
};
|
|
5308
|
+
|
|
5171
5309
|
const handleModelChange = async (state, value) => {
|
|
5172
5310
|
return {
|
|
5173
5311
|
...state,
|
|
@@ -5510,6 +5648,34 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
5510
5648
|
--ChatMessageFontSize: ${chatMessageFontSize}px;
|
|
5511
5649
|
--ChatMessageLineHeight: ${chatMessageLineHeight}px;
|
|
5512
5650
|
--ChatMessageFontFamily: ${chatMessageFontFamily};
|
|
5651
|
+
}
|
|
5652
|
+
|
|
5653
|
+
.ChatToolCalls {
|
|
5654
|
+
position: relative;
|
|
5655
|
+
border: 1px solid var(--vscode-editorWidget-border);
|
|
5656
|
+
border-radius: 4px;
|
|
5657
|
+
margin-bottom: 8px;
|
|
5658
|
+
padding: 10px 8px 6px;
|
|
5659
|
+
background: var(--vscode-editorWidget-background);
|
|
5660
|
+
}
|
|
5661
|
+
|
|
5662
|
+
.ChatToolCallsLabel {
|
|
5663
|
+
position: absolute;
|
|
5664
|
+
top: -8px;
|
|
5665
|
+
left: 8px;
|
|
5666
|
+
padding: 0 4px;
|
|
5667
|
+
border-radius: 3px;
|
|
5668
|
+
background: var(--vscode-editor-background);
|
|
5669
|
+
color: var(--vscode-descriptionForeground);
|
|
5670
|
+
font-size: 10px;
|
|
5671
|
+
line-height: 14px;
|
|
5672
|
+
text-transform: lowercase;
|
|
5673
|
+
letter-spacing: 0.02em;
|
|
5674
|
+
}
|
|
5675
|
+
|
|
5676
|
+
.ChatToolCallReadFileLink {
|
|
5677
|
+
color: var(--vscode-textLink-foreground);
|
|
5678
|
+
text-decoration: underline;
|
|
5513
5679
|
}`;
|
|
5514
5680
|
};
|
|
5515
5681
|
|
|
@@ -5577,6 +5743,9 @@ const ChatListItemLabel = 'ChatListItemLabel';
|
|
|
5577
5743
|
const Markdown = 'Markdown';
|
|
5578
5744
|
const Message = 'Message';
|
|
5579
5745
|
const ChatMessageContent = 'ChatMessageContent';
|
|
5746
|
+
const ChatToolCalls = 'ChatToolCalls';
|
|
5747
|
+
const ChatToolCallsLabel = 'ChatToolCallsLabel';
|
|
5748
|
+
const ChatToolCallReadFileLink = 'ChatToolCallReadFileLink';
|
|
5580
5749
|
const ChatOrderedList = 'ChatOrderedList';
|
|
5581
5750
|
const ChatOrderedListItem = 'ChatOrderedListItem';
|
|
5582
5751
|
const MessageUser = 'MessageUser';
|
|
@@ -5607,6 +5776,7 @@ const HandleChatListScroll = 21;
|
|
|
5607
5776
|
const HandleMessagesScroll = 22;
|
|
5608
5777
|
const HandleClickSessionDebug = 23;
|
|
5609
5778
|
const HandleClickReadFile = 24;
|
|
5779
|
+
const HandleMessagesContextMenu = 25;
|
|
5610
5780
|
|
|
5611
5781
|
const getModelLabel = model => {
|
|
5612
5782
|
if (model.provider === 'openRouter') {
|
|
@@ -5921,8 +6091,10 @@ const getToolCallArgumentPreview = rawArguments => {
|
|
|
5921
6091
|
return rawArguments;
|
|
5922
6092
|
};
|
|
5923
6093
|
|
|
6094
|
+
const RE_QUERY_OR_HASH = /[?#].*$/;
|
|
6095
|
+
const RE_TRAILING_SLASH = /\/$/;
|
|
5924
6096
|
const getFileNameFromUri = uri => {
|
|
5925
|
-
const stripped = uri.replace(
|
|
6097
|
+
const stripped = uri.replace(RE_QUERY_OR_HASH, '').replace(RE_TRAILING_SLASH, '');
|
|
5926
6098
|
const slashIndex = Math.max(stripped.lastIndexOf('/'), stripped.lastIndexOf('\\\\'));
|
|
5927
6099
|
const fileName = slashIndex === -1 ? stripped : stripped.slice(slashIndex + 1);
|
|
5928
6100
|
return fileName || uri;
|
|
@@ -5946,42 +6118,68 @@ const getReadFileTarget = rawArguments => {
|
|
|
5946
6118
|
if (!title) {
|
|
5947
6119
|
return undefined;
|
|
5948
6120
|
}
|
|
5949
|
-
|
|
6121
|
+
// `read_file` tool calls usually provide a relative `path`; pass it through so UI clicks can open the file.
|
|
6122
|
+
const clickableUri = uriValue || pathValue;
|
|
5950
6123
|
return {
|
|
5951
6124
|
clickableUri,
|
|
5952
6125
|
title
|
|
5953
6126
|
};
|
|
5954
6127
|
};
|
|
5955
6128
|
|
|
6129
|
+
const getToolCallStatusLabel$1 = toolCall => {
|
|
6130
|
+
if (toolCall.status === 'not-found') {
|
|
6131
|
+
return ' (not-found)';
|
|
6132
|
+
}
|
|
6133
|
+
if (toolCall.status === 'error') {
|
|
6134
|
+
if (toolCall.errorMessage) {
|
|
6135
|
+
return ` (error: ${toolCall.errorMessage})`;
|
|
6136
|
+
}
|
|
6137
|
+
return ' (error)';
|
|
6138
|
+
}
|
|
6139
|
+
return '';
|
|
6140
|
+
};
|
|
6141
|
+
|
|
5956
6142
|
const getToolCallReadFileVirtualDom = toolCall => {
|
|
5957
6143
|
const target = getReadFileTarget(toolCall.arguments);
|
|
5958
6144
|
if (!target) {
|
|
5959
6145
|
return [];
|
|
5960
6146
|
}
|
|
5961
6147
|
const fileName = getFileNameFromUri(target.title);
|
|
5962
|
-
const
|
|
6148
|
+
const toolNameLabel = `${toolCall.name} `;
|
|
6149
|
+
const statusLabel = getToolCallStatusLabel$1(toolCall);
|
|
6150
|
+
const fileNameClickableProps = target.clickableUri ? {
|
|
5963
6151
|
'data-uri': target.clickableUri,
|
|
5964
6152
|
onClick: HandleClickReadFile
|
|
5965
6153
|
} : {};
|
|
5966
6154
|
return [{
|
|
5967
|
-
childCount:
|
|
6155
|
+
childCount: statusLabel ? 4 : 3,
|
|
5968
6156
|
className: ChatOrderedListItem,
|
|
5969
|
-
...clickableProps,
|
|
5970
6157
|
title: target.title,
|
|
5971
6158
|
type: Li
|
|
5972
6159
|
}, {
|
|
5973
6160
|
childCount: 0,
|
|
5974
6161
|
className: FileIcon,
|
|
5975
|
-
...clickableProps,
|
|
5976
6162
|
type: Div
|
|
5977
|
-
}, {
|
|
6163
|
+
}, text(toolNameLabel), {
|
|
5978
6164
|
childCount: 1,
|
|
5979
|
-
|
|
5980
|
-
|
|
6165
|
+
className: ChatToolCallReadFileLink,
|
|
6166
|
+
...fileNameClickableProps,
|
|
5981
6167
|
type: Span
|
|
5982
|
-
}, text(fileName)];
|
|
6168
|
+
}, text(fileName), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
5983
6169
|
};
|
|
5984
6170
|
|
|
6171
|
+
const getToolCallStatusLabel = toolCall => {
|
|
6172
|
+
if (toolCall.status === 'not-found') {
|
|
6173
|
+
return ' (not-found)';
|
|
6174
|
+
}
|
|
6175
|
+
if (toolCall.status === 'error') {
|
|
6176
|
+
if (toolCall.errorMessage) {
|
|
6177
|
+
return ` (error: ${toolCall.errorMessage})`;
|
|
6178
|
+
}
|
|
6179
|
+
return ' (error)';
|
|
6180
|
+
}
|
|
6181
|
+
return '';
|
|
6182
|
+
};
|
|
5985
6183
|
const getToolCallDom = toolCall => {
|
|
5986
6184
|
if (toolCall.name === 'read_file') {
|
|
5987
6185
|
const virtualDom = getToolCallReadFileVirtualDom(toolCall);
|
|
@@ -5990,7 +6188,7 @@ const getToolCallDom = toolCall => {
|
|
|
5990
6188
|
}
|
|
5991
6189
|
}
|
|
5992
6190
|
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
5993
|
-
const label = `${toolCall.name} ${argumentPreview}`;
|
|
6191
|
+
const label = `${toolCall.name} ${argumentPreview}${getToolCallStatusLabel(toolCall)}`;
|
|
5994
6192
|
return [{
|
|
5995
6193
|
childCount: 1,
|
|
5996
6194
|
className: ChatOrderedListItem,
|
|
@@ -6003,6 +6201,14 @@ const getToolCallsDom = message => {
|
|
|
6003
6201
|
return [];
|
|
6004
6202
|
}
|
|
6005
6203
|
return [{
|
|
6204
|
+
childCount: 2,
|
|
6205
|
+
className: ChatToolCalls,
|
|
6206
|
+
type: Div$1
|
|
6207
|
+
}, {
|
|
6208
|
+
childCount: 1,
|
|
6209
|
+
className: ChatToolCallsLabel,
|
|
6210
|
+
type: Div$1
|
|
6211
|
+
}, text('tools'), {
|
|
6006
6212
|
childCount: message.toolCalls.length,
|
|
6007
6213
|
className: ChatOrderedList,
|
|
6008
6214
|
type: Ol$1
|
|
@@ -6126,6 +6332,7 @@ const getMessagesDom = (messages, openRouterApiKeyInput, openApiApiKeyInput = ''
|
|
|
6126
6332
|
return [{
|
|
6127
6333
|
childCount: messages.length,
|
|
6128
6334
|
className: 'ChatMessages',
|
|
6335
|
+
onContextMenu: HandleMessagesContextMenu,
|
|
6129
6336
|
onScroll: HandleMessagesScroll,
|
|
6130
6337
|
scrollTop: messagesScrollTop,
|
|
6131
6338
|
type: Div
|
|
@@ -6376,6 +6583,10 @@ const renderEventListeners = () => {
|
|
|
6376
6583
|
}, {
|
|
6377
6584
|
name: HandleMessagesScroll,
|
|
6378
6585
|
params: ['handleMessagesScroll', 'event.target.scrollTop']
|
|
6586
|
+
}, {
|
|
6587
|
+
name: HandleMessagesContextMenu,
|
|
6588
|
+
params: ['handleMessagesContextMenu'],
|
|
6589
|
+
preventDefault: true
|
|
6379
6590
|
}, {
|
|
6380
6591
|
name: HandleFocus,
|
|
6381
6592
|
params: ['handleInputFocus', TargetName]
|
|
@@ -6519,6 +6730,7 @@ const commandMap = {
|
|
|
6519
6730
|
'Chat.handleInput': wrapCommand(handleInput),
|
|
6520
6731
|
'Chat.handleInputFocus': wrapCommand(handleInputFocus),
|
|
6521
6732
|
'Chat.handleKeyDown': wrapCommand(handleKeyDown),
|
|
6733
|
+
'Chat.handleMessagesContextMenu': wrapCommand(handleMessagesContextMenu),
|
|
6522
6734
|
'Chat.handleMessagesScroll': wrapCommand(handleMessagesScroll),
|
|
6523
6735
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
6524
6736
|
'Chat.handleSubmit': wrapCommand(handleSubmit),
|