@lvce-editor/chat-view 2.6.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 +464 -39
- package/package.json +1 -1
|
@@ -1079,6 +1079,7 @@ const {
|
|
|
1079
1079
|
} = create$2(6002);
|
|
1080
1080
|
|
|
1081
1081
|
const Div$1 = 4;
|
|
1082
|
+
const Ol$1 = 49;
|
|
1082
1083
|
|
|
1083
1084
|
const ClientX = 'event.clientX';
|
|
1084
1085
|
const ClientY = 'event.clientY';
|
|
@@ -1469,6 +1470,7 @@ const createDefaultState = () => {
|
|
|
1469
1470
|
composerHeight: composerLineHeight + 8,
|
|
1470
1471
|
composerLineHeight,
|
|
1471
1472
|
composerValue: '',
|
|
1473
|
+
emitStreamingFunctionCallEvents: false,
|
|
1472
1474
|
errorCount: 0,
|
|
1473
1475
|
focus: 'composer',
|
|
1474
1476
|
focused: false,
|
|
@@ -1511,6 +1513,7 @@ const createDefaultState = () => {
|
|
|
1511
1513
|
useMockApi: false,
|
|
1512
1514
|
viewMode: 'list',
|
|
1513
1515
|
warningCount: 0,
|
|
1516
|
+
webSearchEnabled: true,
|
|
1514
1517
|
width: 0,
|
|
1515
1518
|
x: 0,
|
|
1516
1519
|
y: 0
|
|
@@ -3285,7 +3288,8 @@ const getOpenAiTools = tools => {
|
|
|
3285
3288
|
};
|
|
3286
3289
|
});
|
|
3287
3290
|
};
|
|
3288
|
-
const getOpenAiParams = (input, modelId, stream, includeObfuscation, tools, previousResponseId) => {
|
|
3291
|
+
const getOpenAiParams = (input, modelId, stream, includeObfuscation, tools, webSearchEnabled, previousResponseId) => {
|
|
3292
|
+
const openAiTools = getOpenAiTools(tools);
|
|
3289
3293
|
return {
|
|
3290
3294
|
input,
|
|
3291
3295
|
model: modelId,
|
|
@@ -3301,7 +3305,9 @@ const getOpenAiParams = (input, modelId, stream, includeObfuscation, tools, prev
|
|
|
3301
3305
|
previous_response_id: previousResponseId
|
|
3302
3306
|
} : {}),
|
|
3303
3307
|
tool_choice: 'auto',
|
|
3304
|
-
tools:
|
|
3308
|
+
tools: webSearchEnabled ? [...openAiTools, {
|
|
3309
|
+
type: 'web_search'
|
|
3310
|
+
}] : openAiTools
|
|
3305
3311
|
};
|
|
3306
3312
|
};
|
|
3307
3313
|
const getStreamChunkText = content => {
|
|
@@ -3319,6 +3325,47 @@ const getStreamChunkText = content => {
|
|
|
3319
3325
|
return typeof text === 'string' ? text : '';
|
|
3320
3326
|
}).join('');
|
|
3321
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
|
+
};
|
|
3322
3369
|
const getResponseOutputText = parsed => {
|
|
3323
3370
|
if (!parsed || typeof parsed !== 'object') {
|
|
3324
3371
|
return '';
|
|
@@ -3455,7 +3502,31 @@ const updateToolCallAccumulator = (accumulator, chunk) => {
|
|
|
3455
3502
|
toolCalls
|
|
3456
3503
|
};
|
|
3457
3504
|
};
|
|
3458
|
-
const
|
|
3505
|
+
const getResponseFunctionCallsFromStreamingAccumulator = toolCallAccumulator => {
|
|
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 => ({
|
|
3507
|
+
arguments: toolCall.arguments,
|
|
3508
|
+
callId: toolCall.id,
|
|
3509
|
+
name: toolCall.name
|
|
3510
|
+
}));
|
|
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
|
+
};
|
|
3529
|
+
const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDataEvent) => {
|
|
3459
3530
|
if (!response.body) {
|
|
3460
3531
|
return {
|
|
3461
3532
|
details: 'request-failed',
|
|
@@ -3467,22 +3538,14 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3467
3538
|
let remainder = '';
|
|
3468
3539
|
let text = '';
|
|
3469
3540
|
let done = false;
|
|
3470
|
-
let finishedNotified = false;
|
|
3471
3541
|
let toolCallAccumulator = {};
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
return;
|
|
3475
|
-
}
|
|
3476
|
-
finishedNotified = true;
|
|
3477
|
-
if (onEventStreamFinished) {
|
|
3478
|
-
await onEventStreamFinished();
|
|
3479
|
-
}
|
|
3480
|
-
};
|
|
3542
|
+
let responseId;
|
|
3543
|
+
let completedResponseFunctionCalls = [];
|
|
3481
3544
|
const emitToolCallAccumulator = async () => {
|
|
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
|
}
|
|
@@ -3497,7 +3560,25 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3497
3560
|
}
|
|
3498
3561
|
const eventType = Reflect.get(parsed, 'type');
|
|
3499
3562
|
if (eventType === 'response.completed') {
|
|
3500
|
-
|
|
3563
|
+
const response = Reflect.get(parsed, 'response');
|
|
3564
|
+
if (response && typeof response === 'object') {
|
|
3565
|
+
const parsedResponseId = Reflect.get(response, 'id');
|
|
3566
|
+
if (typeof parsedResponseId === 'string' && parsedResponseId) {
|
|
3567
|
+
responseId = parsedResponseId;
|
|
3568
|
+
}
|
|
3569
|
+
completedResponseFunctionCalls = getResponseFunctionCalls(response);
|
|
3570
|
+
}
|
|
3571
|
+
return;
|
|
3572
|
+
}
|
|
3573
|
+
if (eventType === 'response.created' || eventType === 'response.in_progress') {
|
|
3574
|
+
const response = Reflect.get(parsed, 'response');
|
|
3575
|
+
if (!response || typeof response !== 'object') {
|
|
3576
|
+
return;
|
|
3577
|
+
}
|
|
3578
|
+
const parsedResponseId = Reflect.get(response, 'id');
|
|
3579
|
+
if (typeof parsedResponseId === 'string' && parsedResponseId) {
|
|
3580
|
+
responseId = parsedResponseId;
|
|
3581
|
+
}
|
|
3501
3582
|
return;
|
|
3502
3583
|
}
|
|
3503
3584
|
if (eventType === 'response.output_text.delta') {
|
|
@@ -3512,9 +3593,9 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3512
3593
|
return;
|
|
3513
3594
|
}
|
|
3514
3595
|
if (eventType === 'response.output_item.added') {
|
|
3515
|
-
const
|
|
3596
|
+
const toolCallKey = getStreamingToolCallKey(parsed);
|
|
3516
3597
|
const item = Reflect.get(parsed, 'item');
|
|
3517
|
-
if (
|
|
3598
|
+
if (!toolCallKey || !item || typeof item !== 'object') {
|
|
3518
3599
|
return;
|
|
3519
3600
|
}
|
|
3520
3601
|
const itemType = Reflect.get(item, 'type');
|
|
@@ -3533,17 +3614,49 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3533
3614
|
};
|
|
3534
3615
|
toolCallAccumulator = {
|
|
3535
3616
|
...toolCallAccumulator,
|
|
3536
|
-
[
|
|
3617
|
+
[toolCallKey]: next
|
|
3618
|
+
};
|
|
3619
|
+
await emitToolCallAccumulator();
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3622
|
+
if (eventType === 'response.output_item.done') {
|
|
3623
|
+
const toolCallKey = getStreamingToolCallKey(parsed);
|
|
3624
|
+
const item = Reflect.get(parsed, 'item');
|
|
3625
|
+
if (!toolCallKey || !item || typeof item !== 'object') {
|
|
3626
|
+
return;
|
|
3627
|
+
}
|
|
3628
|
+
const itemType = Reflect.get(item, 'type');
|
|
3629
|
+
if (itemType !== 'function_call') {
|
|
3630
|
+
return;
|
|
3631
|
+
}
|
|
3632
|
+
const callId = Reflect.get(item, 'call_id');
|
|
3633
|
+
const name = Reflect.get(item, 'name');
|
|
3634
|
+
const rawArguments = Reflect.get(item, 'arguments');
|
|
3635
|
+
const current = toolCallAccumulator[toolCallKey] || {
|
|
3636
|
+
arguments: '',
|
|
3637
|
+
name: ''
|
|
3638
|
+
};
|
|
3639
|
+
toolCallAccumulator = {
|
|
3640
|
+
...toolCallAccumulator,
|
|
3641
|
+
[toolCallKey]: {
|
|
3642
|
+
arguments: typeof rawArguments === 'string' ? rawArguments : current.arguments,
|
|
3643
|
+
...(typeof callId === 'string' ? {
|
|
3644
|
+
id: callId
|
|
3645
|
+
} : current.id ? {
|
|
3646
|
+
id: current.id
|
|
3647
|
+
} : {}),
|
|
3648
|
+
name: typeof name === 'string' && name ? name : current.name
|
|
3649
|
+
}
|
|
3537
3650
|
};
|
|
3538
3651
|
await emitToolCallAccumulator();
|
|
3539
3652
|
return;
|
|
3540
3653
|
}
|
|
3541
3654
|
if (eventType === 'response.function_call_arguments.delta' || eventType === 'response.function_call_arguments.done') {
|
|
3542
|
-
const
|
|
3543
|
-
if (
|
|
3655
|
+
const toolCallKey = getStreamingToolCallKey(parsed);
|
|
3656
|
+
if (!toolCallKey) {
|
|
3544
3657
|
return;
|
|
3545
3658
|
}
|
|
3546
|
-
const current = toolCallAccumulator[
|
|
3659
|
+
const current = toolCallAccumulator[toolCallKey] || {
|
|
3547
3660
|
arguments: '',
|
|
3548
3661
|
name: ''
|
|
3549
3662
|
};
|
|
@@ -3562,7 +3675,7 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3562
3675
|
};
|
|
3563
3676
|
toolCallAccumulator = {
|
|
3564
3677
|
...toolCallAccumulator,
|
|
3565
|
-
[
|
|
3678
|
+
[toolCallKey]: next
|
|
3566
3679
|
};
|
|
3567
3680
|
await emitToolCallAccumulator();
|
|
3568
3681
|
return;
|
|
@@ -3622,7 +3735,6 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3622
3735
|
}
|
|
3623
3736
|
for (const line of dataLines) {
|
|
3624
3737
|
if (line === '[DONE]') {
|
|
3625
|
-
await notifyFinished();
|
|
3626
3738
|
done = true;
|
|
3627
3739
|
break;
|
|
3628
3740
|
}
|
|
@@ -3640,7 +3752,6 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3640
3752
|
const dataLines = parseSseEvent(remainder);
|
|
3641
3753
|
for (const line of dataLines) {
|
|
3642
3754
|
if (line === '[DONE]') {
|
|
3643
|
-
await notifyFinished();
|
|
3644
3755
|
continue;
|
|
3645
3756
|
}
|
|
3646
3757
|
let parsed;
|
|
@@ -3652,8 +3763,12 @@ const parseOpenApiStream = async (response, onTextChunk, onToolCallsChunk, onDat
|
|
|
3652
3763
|
await handleParsedStreamEvent(parsed);
|
|
3653
3764
|
}
|
|
3654
3765
|
}
|
|
3655
|
-
|
|
3766
|
+
const responseFunctionCalls = completedResponseFunctionCalls.length > 0 ? completedResponseFunctionCalls : getResponseFunctionCallsFromStreamingAccumulator(toolCallAccumulator);
|
|
3656
3767
|
return {
|
|
3768
|
+
...(responseId ? {
|
|
3769
|
+
responseId
|
|
3770
|
+
} : {}),
|
|
3771
|
+
responseFunctionCalls,
|
|
3657
3772
|
text,
|
|
3658
3773
|
type: 'success'
|
|
3659
3774
|
};
|
|
@@ -3694,7 +3809,8 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3694
3809
|
onEventStreamFinished,
|
|
3695
3810
|
onTextChunk,
|
|
3696
3811
|
onToolCallsChunk,
|
|
3697
|
-
stream
|
|
3812
|
+
stream,
|
|
3813
|
+
webSearchEnabled = false
|
|
3698
3814
|
} = options ?? {
|
|
3699
3815
|
stream: false
|
|
3700
3816
|
};
|
|
@@ -3709,7 +3825,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3709
3825
|
let response;
|
|
3710
3826
|
try {
|
|
3711
3827
|
response = await fetch(getOpenApiApiEndpoint(openApiApiBaseUrl), {
|
|
3712
|
-
body: JSON.stringify(getOpenAiParams(openAiInput, modelId, stream, includeObfuscation, tools, previousResponseId)),
|
|
3828
|
+
body: JSON.stringify(getOpenAiParams(openAiInput, modelId, stream, includeObfuscation, tools, webSearchEnabled, previousResponseId)),
|
|
3713
3829
|
headers: {
|
|
3714
3830
|
Authorization: `Bearer ${openApiApiKey}`,
|
|
3715
3831
|
'Content-Type': 'application/json',
|
|
@@ -3745,7 +3861,51 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3745
3861
|
};
|
|
3746
3862
|
}
|
|
3747
3863
|
if (stream) {
|
|
3748
|
-
|
|
3864
|
+
const streamResult = await parseOpenApiStream(response, onTextChunk, onToolCallsChunk, onDataEvent);
|
|
3865
|
+
if (streamResult.type !== 'success') {
|
|
3866
|
+
return streamResult;
|
|
3867
|
+
}
|
|
3868
|
+
if (streamResult.responseId) {
|
|
3869
|
+
previousResponseId = streamResult.responseId;
|
|
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
|
+
}
|
|
3902
|
+
if (onEventStreamFinished) {
|
|
3903
|
+
await onEventStreamFinished();
|
|
3904
|
+
}
|
|
3905
|
+
return {
|
|
3906
|
+
text: streamResult.text,
|
|
3907
|
+
type: 'success'
|
|
3908
|
+
};
|
|
3749
3909
|
}
|
|
3750
3910
|
let parsed;
|
|
3751
3911
|
try {
|
|
@@ -3769,17 +3929,33 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3769
3929
|
const responseFunctionCalls = getResponseFunctionCalls(parsed);
|
|
3770
3930
|
if (responseFunctionCalls.length > 0) {
|
|
3771
3931
|
openAiInput.length = 0;
|
|
3932
|
+
const executedToolCalls = [];
|
|
3772
3933
|
for (const toolCall of responseFunctionCalls) {
|
|
3773
3934
|
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
3774
3935
|
assetDir,
|
|
3775
3936
|
platform
|
|
3776
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
|
+
});
|
|
3777
3950
|
openAiInput.push({
|
|
3778
3951
|
call_id: toolCall.callId,
|
|
3779
3952
|
output: content,
|
|
3780
3953
|
type: 'function_call_output'
|
|
3781
3954
|
});
|
|
3782
3955
|
}
|
|
3956
|
+
if (onToolCallsChunk && executedToolCalls.length > 0) {
|
|
3957
|
+
await onToolCallsChunk(executedToolCalls);
|
|
3958
|
+
}
|
|
3783
3959
|
continue;
|
|
3784
3960
|
}
|
|
3785
3961
|
const outputText = getResponseOutputText(parsed);
|
|
@@ -3808,6 +3984,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3808
3984
|
const toolCalls = Reflect.get(message, 'tool_calls');
|
|
3809
3985
|
if (Array.isArray(toolCalls) && toolCalls.length > 0) {
|
|
3810
3986
|
openAiInput.length = 0;
|
|
3987
|
+
const executedToolCalls = [];
|
|
3811
3988
|
for (const toolCall of toolCalls) {
|
|
3812
3989
|
if (!toolCall || typeof toolCall !== 'object') {
|
|
3813
3990
|
continue;
|
|
@@ -3823,12 +4000,29 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
3823
4000
|
assetDir,
|
|
3824
4001
|
platform
|
|
3825
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
|
+
}
|
|
3826
4017
|
openAiInput.push({
|
|
3827
4018
|
call_id: id,
|
|
3828
4019
|
output: content,
|
|
3829
4020
|
type: 'function_call_output'
|
|
3830
4021
|
});
|
|
3831
4022
|
}
|
|
4023
|
+
if (onToolCallsChunk && executedToolCalls.length > 0) {
|
|
4024
|
+
await onToolCallsChunk(executedToolCalls);
|
|
4025
|
+
}
|
|
3832
4026
|
continue;
|
|
3833
4027
|
}
|
|
3834
4028
|
const content = Reflect.get(message, 'content');
|
|
@@ -4218,7 +4412,8 @@ const getAiResponse = async ({
|
|
|
4218
4412
|
selectedModelId,
|
|
4219
4413
|
streamingEnabled = false,
|
|
4220
4414
|
useMockApi,
|
|
4221
|
-
userText
|
|
4415
|
+
userText,
|
|
4416
|
+
webSearchEnabled = false
|
|
4222
4417
|
}) => {
|
|
4223
4418
|
let text = '';
|
|
4224
4419
|
const usesOpenApiModel = isOpenApiModel(selectedModelId, models);
|
|
@@ -4249,7 +4444,8 @@ const getAiResponse = async ({
|
|
|
4249
4444
|
...(onToolCallsChunk ? {
|
|
4250
4445
|
onToolCallsChunk
|
|
4251
4446
|
} : {}),
|
|
4252
|
-
stream: streamingEnabled
|
|
4447
|
+
stream: streamingEnabled,
|
|
4448
|
+
webSearchEnabled
|
|
4253
4449
|
});
|
|
4254
4450
|
if (result.type === 'success') {
|
|
4255
4451
|
const {
|
|
@@ -4576,10 +4772,53 @@ const appendMessageToSelectedSession = (sessions, selectedSessionId, message) =>
|
|
|
4576
4772
|
};
|
|
4577
4773
|
});
|
|
4578
4774
|
};
|
|
4775
|
+
const hasLegacyStreamingToolCalls = parsed => {
|
|
4776
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
4777
|
+
return false;
|
|
4778
|
+
}
|
|
4779
|
+
const choices = Reflect.get(parsed, 'choices');
|
|
4780
|
+
if (!Array.isArray(choices) || choices.length === 0) {
|
|
4781
|
+
return false;
|
|
4782
|
+
}
|
|
4783
|
+
const firstChoice = choices[0];
|
|
4784
|
+
if (!firstChoice || typeof firstChoice !== 'object') {
|
|
4785
|
+
return false;
|
|
4786
|
+
}
|
|
4787
|
+
const delta = Reflect.get(firstChoice, 'delta');
|
|
4788
|
+
if (!delta || typeof delta !== 'object') {
|
|
4789
|
+
return false;
|
|
4790
|
+
}
|
|
4791
|
+
const toolCalls = Reflect.get(delta, 'tool_calls');
|
|
4792
|
+
return Array.isArray(toolCalls) && toolCalls.length > 0;
|
|
4793
|
+
};
|
|
4794
|
+
const isStreamingFunctionCallEvent = parsed => {
|
|
4795
|
+
if (hasLegacyStreamingToolCalls(parsed)) {
|
|
4796
|
+
return true;
|
|
4797
|
+
}
|
|
4798
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
4799
|
+
return false;
|
|
4800
|
+
}
|
|
4801
|
+
const type = Reflect.get(parsed, 'type');
|
|
4802
|
+
if (type === 'response.function_call_arguments.delta' || type === 'response.function_call_arguments.done') {
|
|
4803
|
+
return true;
|
|
4804
|
+
}
|
|
4805
|
+
if (type !== 'response.output_item.added' && type !== 'response.output_item.done') {
|
|
4806
|
+
return false;
|
|
4807
|
+
}
|
|
4808
|
+
const item = Reflect.get(parsed, 'item');
|
|
4809
|
+
if (!item || typeof item !== 'object') {
|
|
4810
|
+
return false;
|
|
4811
|
+
}
|
|
4812
|
+
return Reflect.get(item, 'type') === 'function_call';
|
|
4813
|
+
};
|
|
4814
|
+
const getSseEventType = value => {
|
|
4815
|
+
return value && typeof value === 'object' && Reflect.get(value, 'type') === 'response.completed' ? 'sse-response-completed' : 'sse-response-part';
|
|
4816
|
+
};
|
|
4579
4817
|
const handleSubmit = async state => {
|
|
4580
4818
|
const {
|
|
4581
4819
|
assetDir,
|
|
4582
4820
|
composerValue,
|
|
4821
|
+
emitStreamingFunctionCallEvents,
|
|
4583
4822
|
mockAiResponseDelay,
|
|
4584
4823
|
mockApiCommandId,
|
|
4585
4824
|
models,
|
|
@@ -4595,7 +4834,8 @@ const handleSubmit = async state => {
|
|
|
4595
4834
|
sessions,
|
|
4596
4835
|
streamingEnabled,
|
|
4597
4836
|
useMockApi,
|
|
4598
|
-
viewMode
|
|
4837
|
+
viewMode,
|
|
4838
|
+
webSearchEnabled
|
|
4599
4839
|
} = state;
|
|
4600
4840
|
const userText = composerValue.trim();
|
|
4601
4841
|
if (!userText) {
|
|
@@ -4705,10 +4945,14 @@ const handleSubmit = async state => {
|
|
|
4705
4945
|
mockApiCommandId,
|
|
4706
4946
|
models,
|
|
4707
4947
|
onDataEvent: async value => {
|
|
4948
|
+
if (!emitStreamingFunctionCallEvents && isStreamingFunctionCallEvent(value)) {
|
|
4949
|
+
return;
|
|
4950
|
+
}
|
|
4951
|
+
const sseEventType = getSseEventType(value);
|
|
4708
4952
|
await appendChatViewEvent({
|
|
4709
4953
|
sessionId: optimisticState.selectedSessionId,
|
|
4710
4954
|
timestamp: new Date().toISOString(),
|
|
4711
|
-
type:
|
|
4955
|
+
type: sseEventType,
|
|
4712
4956
|
value
|
|
4713
4957
|
});
|
|
4714
4958
|
},
|
|
@@ -4735,7 +4979,8 @@ const handleSubmit = async state => {
|
|
|
4735
4979
|
selectedModelId,
|
|
4736
4980
|
streamingEnabled,
|
|
4737
4981
|
useMockApi,
|
|
4738
|
-
userText
|
|
4982
|
+
userText,
|
|
4983
|
+
webSearchEnabled
|
|
4739
4984
|
});
|
|
4740
4985
|
const {
|
|
4741
4986
|
latestState
|
|
@@ -4916,6 +5161,13 @@ const handleClickNew = async state => {
|
|
|
4916
5161
|
return createSession(state);
|
|
4917
5162
|
};
|
|
4918
5163
|
|
|
5164
|
+
const handleClickReadFile = async uri => {
|
|
5165
|
+
if (!uri) {
|
|
5166
|
+
return;
|
|
5167
|
+
}
|
|
5168
|
+
await invoke('Main.openUri', uri);
|
|
5169
|
+
};
|
|
5170
|
+
|
|
4919
5171
|
const handleClickSessionDebug = async state => {
|
|
4920
5172
|
await invoke('Main.openUri', `chat-debug://${state.selectedSessionId}`);
|
|
4921
5173
|
return state;
|
|
@@ -5049,6 +5301,11 @@ const handleKeyDown = async (state, key, shiftKey) => {
|
|
|
5049
5301
|
return handleSubmit(submitState);
|
|
5050
5302
|
};
|
|
5051
5303
|
|
|
5304
|
+
const handleMessagesContextMenu = async state => {
|
|
5305
|
+
await invoke('ContextMenu.show', 1234);
|
|
5306
|
+
return state;
|
|
5307
|
+
};
|
|
5308
|
+
|
|
5052
5309
|
const handleModelChange = async (state, value) => {
|
|
5053
5310
|
return {
|
|
5054
5311
|
...state,
|
|
@@ -5186,6 +5443,15 @@ const getSavedViewMode = savedState => {
|
|
|
5186
5443
|
return viewMode;
|
|
5187
5444
|
};
|
|
5188
5445
|
|
|
5446
|
+
const loadEmitStreamingFunctionCallEvents = async () => {
|
|
5447
|
+
try {
|
|
5448
|
+
const savedEmitStreamingFunctionCallEvents = await get('chatView.emitStreamingFunctionCallEvents');
|
|
5449
|
+
return typeof savedEmitStreamingFunctionCallEvents === 'boolean' ? savedEmitStreamingFunctionCallEvents : false;
|
|
5450
|
+
} catch {
|
|
5451
|
+
return false;
|
|
5452
|
+
}
|
|
5453
|
+
};
|
|
5454
|
+
|
|
5189
5455
|
const loadOpenApiApiKey = async () => {
|
|
5190
5456
|
try {
|
|
5191
5457
|
const savedOpenApiKey = await get('secrets.openApiKey');
|
|
@@ -5233,9 +5499,11 @@ const loadStreamingEnabled = async () => {
|
|
|
5233
5499
|
const loadPreferences = async () => {
|
|
5234
5500
|
const openApiApiKey = await loadOpenApiApiKey();
|
|
5235
5501
|
const openRouterApiKey = await loadOpenRouterApiKey();
|
|
5502
|
+
const emitStreamingFunctionCallEvents = await loadEmitStreamingFunctionCallEvents();
|
|
5236
5503
|
const streamingEnabled = await loadStreamingEnabled();
|
|
5237
5504
|
const passIncludeObfuscation = await loadPassIncludeObfuscation();
|
|
5238
5505
|
return {
|
|
5506
|
+
emitStreamingFunctionCallEvents,
|
|
5239
5507
|
openApiApiKey,
|
|
5240
5508
|
openRouterApiKey,
|
|
5241
5509
|
passIncludeObfuscation,
|
|
@@ -5270,6 +5538,7 @@ const loadContent = async (state, savedState) => {
|
|
|
5270
5538
|
const savedSelectedModelId = getSavedSelectedModelId(savedState);
|
|
5271
5539
|
const savedViewMode = getSavedViewMode(savedState);
|
|
5272
5540
|
const {
|
|
5541
|
+
emitStreamingFunctionCallEvents,
|
|
5273
5542
|
openApiApiKey,
|
|
5274
5543
|
openRouterApiKey,
|
|
5275
5544
|
passIncludeObfuscation,
|
|
@@ -5302,6 +5571,7 @@ const loadContent = async (state, savedState) => {
|
|
|
5302
5571
|
return {
|
|
5303
5572
|
...state,
|
|
5304
5573
|
chatListScrollTop,
|
|
5574
|
+
emitStreamingFunctionCallEvents,
|
|
5305
5575
|
initial: false,
|
|
5306
5576
|
messagesScrollTop,
|
|
5307
5577
|
openApiApiKey,
|
|
@@ -5378,6 +5648,34 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
5378
5648
|
--ChatMessageFontSize: ${chatMessageFontSize}px;
|
|
5379
5649
|
--ChatMessageLineHeight: ${chatMessageLineHeight}px;
|
|
5380
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;
|
|
5381
5679
|
}`;
|
|
5382
5680
|
};
|
|
5383
5681
|
|
|
@@ -5433,6 +5731,7 @@ const ChatHeader = 'ChatHeader';
|
|
|
5433
5731
|
const Button = 'Button';
|
|
5434
5732
|
const ButtonPrimary = 'ButtonPrimary';
|
|
5435
5733
|
const ButtonSecondary = 'ButtonSecondary';
|
|
5734
|
+
const FileIcon = 'FileIcon';
|
|
5436
5735
|
const IconButton = 'IconButton';
|
|
5437
5736
|
const InputBox = 'InputBox';
|
|
5438
5737
|
const Label = 'Label';
|
|
@@ -5444,6 +5743,9 @@ const ChatListItemLabel = 'ChatListItemLabel';
|
|
|
5444
5743
|
const Markdown = 'Markdown';
|
|
5445
5744
|
const Message = 'Message';
|
|
5446
5745
|
const ChatMessageContent = 'ChatMessageContent';
|
|
5746
|
+
const ChatToolCalls = 'ChatToolCalls';
|
|
5747
|
+
const ChatToolCallsLabel = 'ChatToolCallsLabel';
|
|
5748
|
+
const ChatToolCallReadFileLink = 'ChatToolCallReadFileLink';
|
|
5447
5749
|
const ChatOrderedList = 'ChatOrderedList';
|
|
5448
5750
|
const ChatOrderedListItem = 'ChatOrderedListItem';
|
|
5449
5751
|
const MessageUser = 'MessageUser';
|
|
@@ -5473,6 +5775,8 @@ const HandleModelChange = 20;
|
|
|
5473
5775
|
const HandleChatListScroll = 21;
|
|
5474
5776
|
const HandleMessagesScroll = 22;
|
|
5475
5777
|
const HandleClickSessionDebug = 23;
|
|
5778
|
+
const HandleClickReadFile = 24;
|
|
5779
|
+
const HandleMessagesContextMenu = 25;
|
|
5476
5780
|
|
|
5477
5781
|
const getModelLabel = model => {
|
|
5478
5782
|
if (model.provider === 'openRouter') {
|
|
@@ -5787,13 +6091,108 @@ const getToolCallArgumentPreview = rawArguments => {
|
|
|
5787
6091
|
return rawArguments;
|
|
5788
6092
|
};
|
|
5789
6093
|
|
|
6094
|
+
const RE_QUERY_OR_HASH = /[?#].*$/;
|
|
6095
|
+
const RE_TRAILING_SLASH = /\/$/;
|
|
6096
|
+
const getFileNameFromUri = uri => {
|
|
6097
|
+
const stripped = uri.replace(RE_QUERY_OR_HASH, '').replace(RE_TRAILING_SLASH, '');
|
|
6098
|
+
const slashIndex = Math.max(stripped.lastIndexOf('/'), stripped.lastIndexOf('\\\\'));
|
|
6099
|
+
const fileName = slashIndex === -1 ? stripped : stripped.slice(slashIndex + 1);
|
|
6100
|
+
return fileName || uri;
|
|
6101
|
+
};
|
|
6102
|
+
|
|
6103
|
+
const getReadFileTarget = rawArguments => {
|
|
6104
|
+
let parsed;
|
|
6105
|
+
try {
|
|
6106
|
+
parsed = JSON.parse(rawArguments);
|
|
6107
|
+
} catch {
|
|
6108
|
+
return undefined;
|
|
6109
|
+
}
|
|
6110
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
6111
|
+
return undefined;
|
|
6112
|
+
}
|
|
6113
|
+
const uri = Reflect.get(parsed, 'uri');
|
|
6114
|
+
const path = Reflect.get(parsed, 'path');
|
|
6115
|
+
const uriValue = typeof uri === 'string' ? uri : '';
|
|
6116
|
+
const pathValue = typeof path === 'string' ? path : '';
|
|
6117
|
+
const title = uriValue || pathValue;
|
|
6118
|
+
if (!title) {
|
|
6119
|
+
return undefined;
|
|
6120
|
+
}
|
|
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;
|
|
6123
|
+
return {
|
|
6124
|
+
clickableUri,
|
|
6125
|
+
title
|
|
6126
|
+
};
|
|
6127
|
+
};
|
|
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
|
+
|
|
6142
|
+
const getToolCallReadFileVirtualDom = toolCall => {
|
|
6143
|
+
const target = getReadFileTarget(toolCall.arguments);
|
|
6144
|
+
if (!target) {
|
|
6145
|
+
return [];
|
|
6146
|
+
}
|
|
6147
|
+
const fileName = getFileNameFromUri(target.title);
|
|
6148
|
+
const toolNameLabel = `${toolCall.name} `;
|
|
6149
|
+
const statusLabel = getToolCallStatusLabel$1(toolCall);
|
|
6150
|
+
const fileNameClickableProps = target.clickableUri ? {
|
|
6151
|
+
'data-uri': target.clickableUri,
|
|
6152
|
+
onClick: HandleClickReadFile
|
|
6153
|
+
} : {};
|
|
6154
|
+
return [{
|
|
6155
|
+
childCount: statusLabel ? 4 : 3,
|
|
6156
|
+
className: ChatOrderedListItem,
|
|
6157
|
+
title: target.title,
|
|
6158
|
+
type: Li
|
|
6159
|
+
}, {
|
|
6160
|
+
childCount: 0,
|
|
6161
|
+
className: FileIcon,
|
|
6162
|
+
type: Div
|
|
6163
|
+
}, text(toolNameLabel), {
|
|
6164
|
+
childCount: 1,
|
|
6165
|
+
className: ChatToolCallReadFileLink,
|
|
6166
|
+
...fileNameClickableProps,
|
|
6167
|
+
type: Span
|
|
6168
|
+
}, text(fileName), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
6169
|
+
};
|
|
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
|
+
};
|
|
5790
6183
|
const getToolCallDom = toolCall => {
|
|
6184
|
+
if (toolCall.name === 'read_file') {
|
|
6185
|
+
const virtualDom = getToolCallReadFileVirtualDom(toolCall);
|
|
6186
|
+
if (virtualDom.length > 0) {
|
|
6187
|
+
return virtualDom;
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
5791
6190
|
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
5792
|
-
const label = `${toolCall.name} ${argumentPreview}`;
|
|
6191
|
+
const label = `${toolCall.name} ${argumentPreview}${getToolCallStatusLabel(toolCall)}`;
|
|
5793
6192
|
return [{
|
|
5794
6193
|
childCount: 1,
|
|
5795
|
-
className:
|
|
5796
|
-
type:
|
|
6194
|
+
className: ChatOrderedListItem,
|
|
6195
|
+
type: Li
|
|
5797
6196
|
}, text(label)];
|
|
5798
6197
|
};
|
|
5799
6198
|
|
|
@@ -5802,9 +6201,17 @@ const getToolCallsDom = message => {
|
|
|
5802
6201
|
return [];
|
|
5803
6202
|
}
|
|
5804
6203
|
return [{
|
|
5805
|
-
childCount:
|
|
5806
|
-
className:
|
|
6204
|
+
childCount: 2,
|
|
6205
|
+
className: ChatToolCalls,
|
|
5807
6206
|
type: Div$1
|
|
6207
|
+
}, {
|
|
6208
|
+
childCount: 1,
|
|
6209
|
+
className: ChatToolCallsLabel,
|
|
6210
|
+
type: Div$1
|
|
6211
|
+
}, text('tools'), {
|
|
6212
|
+
childCount: message.toolCalls.length,
|
|
6213
|
+
className: ChatOrderedList,
|
|
6214
|
+
type: Ol$1
|
|
5808
6215
|
}, ...message.toolCalls.flatMap(getToolCallDom)];
|
|
5809
6216
|
};
|
|
5810
6217
|
|
|
@@ -5907,7 +6314,7 @@ const getChatMessageDom = (message, openRouterApiKeyInput, openApiApiKeyInput =
|
|
|
5907
6314
|
childCount: extraChildCount,
|
|
5908
6315
|
className: ChatMessageContent,
|
|
5909
6316
|
type: Div
|
|
5910
|
-
}, ...
|
|
6317
|
+
}, ...toolCallsDom, ...messageDom, ...(isOpenApiApiKeyMissingMessage ? getMissingOpenApiApiKeyDom(openApiApiKeyInput) : []), ...(isOpenRouterApiKeyMissingMessage ? getMissingOpenRouterApiKeyDom(openRouterApiKeyInput, openRouterApiKeyState) : []), ...(isOpenRouterRequestFailedMessage ? getOpenRouterRequestFailedDom() : []), ...(isOpenRouterTooManyRequestsMessage ? getOpenRouterTooManyRequestsDom() : [])];
|
|
5911
6318
|
};
|
|
5912
6319
|
|
|
5913
6320
|
const getEmptyMessagesDom = () => {
|
|
@@ -5925,6 +6332,7 @@ const getMessagesDom = (messages, openRouterApiKeyInput, openApiApiKeyInput = ''
|
|
|
5925
6332
|
return [{
|
|
5926
6333
|
childCount: messages.length,
|
|
5927
6334
|
className: 'ChatMessages',
|
|
6335
|
+
onContextMenu: HandleMessagesContextMenu,
|
|
5928
6336
|
onScroll: HandleMessagesScroll,
|
|
5929
6337
|
scrollTop: messagesScrollTop,
|
|
5930
6338
|
type: Div
|
|
@@ -6139,6 +6547,9 @@ const renderEventListeners = () => {
|
|
|
6139
6547
|
}, {
|
|
6140
6548
|
name: HandleClick,
|
|
6141
6549
|
params: ['handleClick', TargetName, 'event.target.dataset.id']
|
|
6550
|
+
}, {
|
|
6551
|
+
name: HandleClickReadFile,
|
|
6552
|
+
params: ['handleClickReadFile', 'event.target.dataset.uri']
|
|
6142
6553
|
}, {
|
|
6143
6554
|
name: HandleClickDelete,
|
|
6144
6555
|
params: ['handleClickDelete', 'event.target.dataset.id']
|
|
@@ -6172,6 +6583,10 @@ const renderEventListeners = () => {
|
|
|
6172
6583
|
}, {
|
|
6173
6584
|
name: HandleMessagesScroll,
|
|
6174
6585
|
params: ['handleMessagesScroll', 'event.target.scrollTop']
|
|
6586
|
+
}, {
|
|
6587
|
+
name: HandleMessagesContextMenu,
|
|
6588
|
+
params: ['handleMessagesContextMenu'],
|
|
6589
|
+
preventDefault: true
|
|
6175
6590
|
}, {
|
|
6176
6591
|
name: HandleFocus,
|
|
6177
6592
|
params: ['handleInputFocus', TargetName]
|
|
@@ -6264,6 +6679,13 @@ const setChatList = state => {
|
|
|
6264
6679
|
};
|
|
6265
6680
|
};
|
|
6266
6681
|
|
|
6682
|
+
const setEmitStreamingFunctionCallEvents = (state, emitStreamingFunctionCallEvents) => {
|
|
6683
|
+
return {
|
|
6684
|
+
...state,
|
|
6685
|
+
emitStreamingFunctionCallEvents
|
|
6686
|
+
};
|
|
6687
|
+
};
|
|
6688
|
+
|
|
6267
6689
|
const setStreamingEnabled = (state, streamingEnabled) => {
|
|
6268
6690
|
return {
|
|
6269
6691
|
...state,
|
|
@@ -6302,11 +6724,13 @@ const commandMap = {
|
|
|
6302
6724
|
'Chat.handleClickDelete': wrapCommand(handleClickDelete),
|
|
6303
6725
|
'Chat.handleClickList': wrapCommand(handleClickList),
|
|
6304
6726
|
'Chat.handleClickNew': wrapCommand(handleClickNew),
|
|
6727
|
+
'Chat.handleClickReadFile': handleClickReadFile,
|
|
6305
6728
|
'Chat.handleClickSessionDebug': wrapCommand(handleClickSessionDebug),
|
|
6306
6729
|
'Chat.handleClickSettings': handleClickSettings,
|
|
6307
6730
|
'Chat.handleInput': wrapCommand(handleInput),
|
|
6308
6731
|
'Chat.handleInputFocus': wrapCommand(handleInputFocus),
|
|
6309
6732
|
'Chat.handleKeyDown': wrapCommand(handleKeyDown),
|
|
6733
|
+
'Chat.handleMessagesContextMenu': wrapCommand(handleMessagesContextMenu),
|
|
6310
6734
|
'Chat.handleMessagesScroll': wrapCommand(handleMessagesScroll),
|
|
6311
6735
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
6312
6736
|
'Chat.handleSubmit': wrapCommand(handleSubmit),
|
|
@@ -6325,6 +6749,7 @@ const commandMap = {
|
|
|
6325
6749
|
'Chat.resize': wrapCommand(resize),
|
|
6326
6750
|
'Chat.saveState': wrapGetter(saveState),
|
|
6327
6751
|
'Chat.setChatList': wrapCommand(setChatList),
|
|
6752
|
+
'Chat.setEmitStreamingFunctionCallEvents': wrapCommand(setEmitStreamingFunctionCallEvents),
|
|
6328
6753
|
'Chat.setOpenRouterApiKey': wrapCommand(setOpenRouterApiKey),
|
|
6329
6754
|
'Chat.setStreamingEnabled': wrapCommand(setStreamingEnabled),
|
|
6330
6755
|
'Chat.terminate': terminate,
|