@lvce-editor/chat-view 3.6.0 → 3.7.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 +411 -113
- package/package.json +1 -1
|
@@ -1075,6 +1075,7 @@ const create$2 = rpcId => {
|
|
|
1075
1075
|
};
|
|
1076
1076
|
|
|
1077
1077
|
const {
|
|
1078
|
+
invoke: invoke$2,
|
|
1078
1079
|
set: set$3
|
|
1079
1080
|
} = create$2(6002);
|
|
1080
1081
|
|
|
@@ -1525,6 +1526,7 @@ const createDefaultState = () => {
|
|
|
1525
1526
|
tokensUsed: 0,
|
|
1526
1527
|
uid: 0,
|
|
1527
1528
|
usageOverviewEnabled: false,
|
|
1529
|
+
useChatNetworkWorkerForRequests: false,
|
|
1528
1530
|
useMockApi: false,
|
|
1529
1531
|
viewMode: 'list',
|
|
1530
1532
|
warningCount: 0,
|
|
@@ -3177,6 +3179,13 @@ const getMockOpenRouterAssistantText = async (messages, modelId, openRouterApiBa
|
|
|
3177
3179
|
}
|
|
3178
3180
|
};
|
|
3179
3181
|
|
|
3182
|
+
const makeApiRequest = async options => {
|
|
3183
|
+
return invoke$2('ChatNetwork.makeApiRequest', options);
|
|
3184
|
+
};
|
|
3185
|
+
const makeStreamingApiRequest = async options => {
|
|
3186
|
+
return invoke$2('ChatNetwork.makeStreamingApiRequest', options);
|
|
3187
|
+
};
|
|
3188
|
+
|
|
3180
3189
|
const executeGetWorkspaceUriTool = async (_args, _options) => {
|
|
3181
3190
|
try {
|
|
3182
3191
|
const workspaceUri = await getWorkspacePath();
|
|
@@ -3521,6 +3530,8 @@ const getTextContent = content => {
|
|
|
3521
3530
|
return textParts.join('\n');
|
|
3522
3531
|
};
|
|
3523
3532
|
|
|
3533
|
+
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
3534
|
+
|
|
3524
3535
|
const getOpenAiTools = tools => {
|
|
3525
3536
|
return tools.map(tool => {
|
|
3526
3537
|
if (!tool || typeof tool !== 'object') {
|
|
@@ -4062,6 +4073,52 @@ const getOpenApiErrorDetails = async response => {
|
|
|
4062
4073
|
} : {})
|
|
4063
4074
|
};
|
|
4064
4075
|
};
|
|
4076
|
+
const getOpenApiErrorDetailsFromResponseText = responseText => {
|
|
4077
|
+
let parsed;
|
|
4078
|
+
try {
|
|
4079
|
+
parsed = JSON.parse(responseText);
|
|
4080
|
+
} catch {
|
|
4081
|
+
return {};
|
|
4082
|
+
}
|
|
4083
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
4084
|
+
return {};
|
|
4085
|
+
}
|
|
4086
|
+
const error = Reflect.get(parsed, 'error');
|
|
4087
|
+
if (!error || typeof error !== 'object') {
|
|
4088
|
+
return {};
|
|
4089
|
+
}
|
|
4090
|
+
const errorCode = Reflect.get(error, 'code');
|
|
4091
|
+
const errorMessage = Reflect.get(error, 'message');
|
|
4092
|
+
const errorType = Reflect.get(error, 'type');
|
|
4093
|
+
return {
|
|
4094
|
+
...(typeof errorCode === 'string' ? {
|
|
4095
|
+
errorCode
|
|
4096
|
+
} : {}),
|
|
4097
|
+
...(typeof errorMessage === 'string' ? {
|
|
4098
|
+
errorMessage
|
|
4099
|
+
} : {}),
|
|
4100
|
+
...(typeof errorType === 'string' ? {
|
|
4101
|
+
errorType
|
|
4102
|
+
} : {})
|
|
4103
|
+
};
|
|
4104
|
+
};
|
|
4105
|
+
const getResponseFromSseEvents = events => {
|
|
4106
|
+
const chunks = events.map(event => {
|
|
4107
|
+
const data = typeof event === 'string' ? event : JSON.stringify(event);
|
|
4108
|
+
return `data: ${data}\n\n`;
|
|
4109
|
+
});
|
|
4110
|
+
const stream = new ReadableStream({
|
|
4111
|
+
start(controller) {
|
|
4112
|
+
for (const chunk of chunks) {
|
|
4113
|
+
controller.enqueue(new TextEncoder().encode(chunk));
|
|
4114
|
+
}
|
|
4115
|
+
controller.close();
|
|
4116
|
+
}
|
|
4117
|
+
});
|
|
4118
|
+
return {
|
|
4119
|
+
body: stream
|
|
4120
|
+
};
|
|
4121
|
+
};
|
|
4065
4122
|
const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApiApiBaseUrl, assetDir, platform, options) => {
|
|
4066
4123
|
const {
|
|
4067
4124
|
includeObfuscation = false,
|
|
@@ -4070,6 +4127,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4070
4127
|
onTextChunk,
|
|
4071
4128
|
onToolCallsChunk,
|
|
4072
4129
|
stream,
|
|
4130
|
+
useChatNetworkWorkerForRequests = false,
|
|
4073
4131
|
webSearchEnabled = false
|
|
4074
4132
|
} = options ?? {
|
|
4075
4133
|
stream: false
|
|
@@ -4082,46 +4140,89 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4082
4140
|
const maxToolIterations = 4;
|
|
4083
4141
|
let previousResponseId;
|
|
4084
4142
|
for (let i = 0; i <= maxToolIterations; i++) {
|
|
4085
|
-
|
|
4086
|
-
try {
|
|
4087
|
-
response = await fetch(getOpenApiApiEndpoint(openApiApiBaseUrl), {
|
|
4088
|
-
body: JSON.stringify(getOpenAiParams(openAiInput, modelId, stream, includeObfuscation, tools, webSearchEnabled, previousResponseId)),
|
|
4089
|
-
headers: {
|
|
4090
|
-
Authorization: `Bearer ${openApiApiKey}`,
|
|
4091
|
-
'Content-Type': 'application/json',
|
|
4092
|
-
...getClientRequestIdHeader()
|
|
4093
|
-
},
|
|
4094
|
-
method: 'POST'
|
|
4095
|
-
});
|
|
4096
|
-
} catch {
|
|
4097
|
-
return {
|
|
4098
|
-
details: 'request-failed',
|
|
4099
|
-
type: 'error'
|
|
4100
|
-
};
|
|
4101
|
-
}
|
|
4102
|
-
if (!response.ok) {
|
|
4103
|
-
const {
|
|
4104
|
-
errorCode,
|
|
4105
|
-
errorMessage,
|
|
4106
|
-
errorType
|
|
4107
|
-
} = await getOpenApiErrorDetails(response);
|
|
4108
|
-
return {
|
|
4109
|
-
details: 'http-error',
|
|
4110
|
-
...(errorCode ? {
|
|
4111
|
-
errorCode
|
|
4112
|
-
} : {}),
|
|
4113
|
-
...(errorMessage ? {
|
|
4114
|
-
errorMessage
|
|
4115
|
-
} : {}),
|
|
4116
|
-
...(errorType ? {
|
|
4117
|
-
errorType
|
|
4118
|
-
} : {}),
|
|
4119
|
-
statusCode: response.status,
|
|
4120
|
-
type: 'error'
|
|
4121
|
-
};
|
|
4122
|
-
}
|
|
4143
|
+
const postBody = getOpenAiParams(openAiInput, modelId, stream, includeObfuscation, tools, webSearchEnabled, previousResponseId);
|
|
4123
4144
|
if (stream) {
|
|
4124
|
-
const streamResult = await
|
|
4145
|
+
const streamResult = useChatNetworkWorkerForRequests ? await (async () => {
|
|
4146
|
+
const requestResult = await makeStreamingApiRequest({
|
|
4147
|
+
headers: {
|
|
4148
|
+
Authorization: `Bearer ${openApiApiKey}`,
|
|
4149
|
+
'Content-Type': 'application/json',
|
|
4150
|
+
...getClientRequestIdHeader()
|
|
4151
|
+
},
|
|
4152
|
+
method: 'POST',
|
|
4153
|
+
postBody,
|
|
4154
|
+
url: getOpenApiApiEndpoint(openApiApiBaseUrl)
|
|
4155
|
+
});
|
|
4156
|
+
if (requestResult.type === 'error') {
|
|
4157
|
+
if (requestResult.statusCode === 0) {
|
|
4158
|
+
return {
|
|
4159
|
+
details: 'request-failed',
|
|
4160
|
+
type: 'error'
|
|
4161
|
+
};
|
|
4162
|
+
}
|
|
4163
|
+
const {
|
|
4164
|
+
errorCode,
|
|
4165
|
+
errorMessage,
|
|
4166
|
+
errorType
|
|
4167
|
+
} = getOpenApiErrorDetailsFromResponseText(requestResult.response);
|
|
4168
|
+
return {
|
|
4169
|
+
details: 'http-error',
|
|
4170
|
+
...(errorCode ? {
|
|
4171
|
+
errorCode
|
|
4172
|
+
} : {}),
|
|
4173
|
+
...(errorMessage ? {
|
|
4174
|
+
errorMessage
|
|
4175
|
+
} : {}),
|
|
4176
|
+
...(errorType ? {
|
|
4177
|
+
errorType
|
|
4178
|
+
} : {}),
|
|
4179
|
+
statusCode: requestResult.statusCode,
|
|
4180
|
+
type: 'error'
|
|
4181
|
+
};
|
|
4182
|
+
}
|
|
4183
|
+
const response = getResponseFromSseEvents(requestResult.body);
|
|
4184
|
+
return parseOpenApiStream(response, onTextChunk, onToolCallsChunk, onDataEvent);
|
|
4185
|
+
})() : await (async () => {
|
|
4186
|
+
let response;
|
|
4187
|
+
try {
|
|
4188
|
+
response = await fetch(getOpenApiApiEndpoint(openApiApiBaseUrl), {
|
|
4189
|
+
body: JSON.stringify(postBody),
|
|
4190
|
+
headers: {
|
|
4191
|
+
Authorization: `Bearer ${openApiApiKey}`,
|
|
4192
|
+
'Content-Type': 'application/json',
|
|
4193
|
+
...getClientRequestIdHeader()
|
|
4194
|
+
},
|
|
4195
|
+
method: 'POST'
|
|
4196
|
+
});
|
|
4197
|
+
} catch {
|
|
4198
|
+
return {
|
|
4199
|
+
details: 'request-failed',
|
|
4200
|
+
type: 'error'
|
|
4201
|
+
};
|
|
4202
|
+
}
|
|
4203
|
+
if (!response.ok) {
|
|
4204
|
+
const {
|
|
4205
|
+
errorCode,
|
|
4206
|
+
errorMessage,
|
|
4207
|
+
errorType
|
|
4208
|
+
} = await getOpenApiErrorDetails(response);
|
|
4209
|
+
return {
|
|
4210
|
+
details: 'http-error',
|
|
4211
|
+
...(errorCode ? {
|
|
4212
|
+
errorCode
|
|
4213
|
+
} : {}),
|
|
4214
|
+
...(errorMessage ? {
|
|
4215
|
+
errorMessage
|
|
4216
|
+
} : {}),
|
|
4217
|
+
...(errorType ? {
|
|
4218
|
+
errorType
|
|
4219
|
+
} : {}),
|
|
4220
|
+
statusCode: response.status,
|
|
4221
|
+
type: 'error'
|
|
4222
|
+
};
|
|
4223
|
+
}
|
|
4224
|
+
return parseOpenApiStream(response, onTextChunk, onToolCallsChunk, onDataEvent);
|
|
4225
|
+
})();
|
|
4125
4226
|
if (streamResult.type !== 'success') {
|
|
4126
4227
|
return streamResult;
|
|
4127
4228
|
}
|
|
@@ -4168,13 +4269,92 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4168
4269
|
};
|
|
4169
4270
|
}
|
|
4170
4271
|
let parsed;
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4272
|
+
if (useChatNetworkWorkerForRequests) {
|
|
4273
|
+
const requestResult = await makeApiRequest({
|
|
4274
|
+
headers: {
|
|
4275
|
+
Authorization: `Bearer ${openApiApiKey}`,
|
|
4276
|
+
'Content-Type': 'application/json',
|
|
4277
|
+
...getClientRequestIdHeader()
|
|
4278
|
+
},
|
|
4279
|
+
method: 'POST',
|
|
4280
|
+
postBody,
|
|
4281
|
+
url: getOpenApiApiEndpoint(openApiApiBaseUrl)
|
|
4282
|
+
});
|
|
4283
|
+
if (requestResult.type === 'error') {
|
|
4284
|
+
if (requestResult.statusCode === 0) {
|
|
4285
|
+
return {
|
|
4286
|
+
details: 'request-failed',
|
|
4287
|
+
type: 'error'
|
|
4288
|
+
};
|
|
4289
|
+
}
|
|
4290
|
+
const {
|
|
4291
|
+
errorCode,
|
|
4292
|
+
errorMessage,
|
|
4293
|
+
errorType
|
|
4294
|
+
} = getOpenApiErrorDetailsFromResponseText(requestResult.response);
|
|
4295
|
+
return {
|
|
4296
|
+
details: 'http-error',
|
|
4297
|
+
...(errorCode ? {
|
|
4298
|
+
errorCode
|
|
4299
|
+
} : {}),
|
|
4300
|
+
...(errorMessage ? {
|
|
4301
|
+
errorMessage
|
|
4302
|
+
} : {}),
|
|
4303
|
+
...(errorType ? {
|
|
4304
|
+
errorType
|
|
4305
|
+
} : {}),
|
|
4306
|
+
statusCode: requestResult.statusCode,
|
|
4307
|
+
type: 'error'
|
|
4308
|
+
};
|
|
4309
|
+
}
|
|
4310
|
+
parsed = requestResult.body;
|
|
4311
|
+
} else {
|
|
4312
|
+
let response;
|
|
4313
|
+
try {
|
|
4314
|
+
response = await fetch(getOpenApiApiEndpoint(openApiApiBaseUrl), {
|
|
4315
|
+
body: JSON.stringify(postBody),
|
|
4316
|
+
headers: {
|
|
4317
|
+
Authorization: `Bearer ${openApiApiKey}`,
|
|
4318
|
+
'Content-Type': 'application/json',
|
|
4319
|
+
...getClientRequestIdHeader()
|
|
4320
|
+
},
|
|
4321
|
+
method: 'POST'
|
|
4322
|
+
});
|
|
4323
|
+
} catch {
|
|
4324
|
+
return {
|
|
4325
|
+
details: 'request-failed',
|
|
4326
|
+
type: 'error'
|
|
4327
|
+
};
|
|
4328
|
+
}
|
|
4329
|
+
if (!response.ok) {
|
|
4330
|
+
const {
|
|
4331
|
+
errorCode,
|
|
4332
|
+
errorMessage,
|
|
4333
|
+
errorType
|
|
4334
|
+
} = await getOpenApiErrorDetails(response);
|
|
4335
|
+
return {
|
|
4336
|
+
details: 'http-error',
|
|
4337
|
+
...(errorCode ? {
|
|
4338
|
+
errorCode
|
|
4339
|
+
} : {}),
|
|
4340
|
+
...(errorMessage ? {
|
|
4341
|
+
errorMessage
|
|
4342
|
+
} : {}),
|
|
4343
|
+
...(errorType ? {
|
|
4344
|
+
errorType
|
|
4345
|
+
} : {}),
|
|
4346
|
+
statusCode: response.status,
|
|
4347
|
+
type: 'error'
|
|
4348
|
+
};
|
|
4349
|
+
}
|
|
4350
|
+
try {
|
|
4351
|
+
parsed = await response.json();
|
|
4352
|
+
} catch {
|
|
4353
|
+
return {
|
|
4354
|
+
details: 'request-failed',
|
|
4355
|
+
type: 'error'
|
|
4356
|
+
};
|
|
4357
|
+
}
|
|
4178
4358
|
}
|
|
4179
4359
|
if (!parsed || typeof parsed !== 'object') {
|
|
4180
4360
|
return {
|
|
@@ -4409,28 +4589,67 @@ const getOpenRouterRaw429Message = async response => {
|
|
|
4409
4589
|
}
|
|
4410
4590
|
return raw;
|
|
4411
4591
|
};
|
|
4412
|
-
const
|
|
4413
|
-
let
|
|
4592
|
+
const getOpenRouterRaw429MessageFromText = responseText => {
|
|
4593
|
+
let parsed;
|
|
4414
4594
|
try {
|
|
4415
|
-
|
|
4416
|
-
headers: {
|
|
4417
|
-
Authorization: `Bearer ${openRouterApiKey}`,
|
|
4418
|
-
...getClientRequestIdHeader()
|
|
4419
|
-
},
|
|
4420
|
-
method: 'GET'
|
|
4421
|
-
});
|
|
4595
|
+
parsed = JSON.parse(responseText);
|
|
4422
4596
|
} catch {
|
|
4423
4597
|
return undefined;
|
|
4424
4598
|
}
|
|
4425
|
-
if (!
|
|
4599
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
4426
4600
|
return undefined;
|
|
4427
4601
|
}
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
}
|
|
4602
|
+
const error = Reflect.get(parsed, 'error');
|
|
4603
|
+
if (!error || typeof error !== 'object') {
|
|
4604
|
+
return undefined;
|
|
4605
|
+
}
|
|
4606
|
+
const metadata = Reflect.get(error, 'metadata');
|
|
4607
|
+
if (!metadata || typeof metadata !== 'object') {
|
|
4432
4608
|
return undefined;
|
|
4433
4609
|
}
|
|
4610
|
+
const raw = Reflect.get(metadata, 'raw');
|
|
4611
|
+
if (typeof raw !== 'string' || !raw) {
|
|
4612
|
+
return undefined;
|
|
4613
|
+
}
|
|
4614
|
+
return raw;
|
|
4615
|
+
};
|
|
4616
|
+
const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl, useChatNetworkWorkerForRequests) => {
|
|
4617
|
+
let parsed;
|
|
4618
|
+
if (useChatNetworkWorkerForRequests) {
|
|
4619
|
+
const result = await makeApiRequest({
|
|
4620
|
+
headers: {
|
|
4621
|
+
Authorization: `Bearer ${openRouterApiKey}`,
|
|
4622
|
+
...getClientRequestIdHeader()
|
|
4623
|
+
},
|
|
4624
|
+
method: 'GET',
|
|
4625
|
+
url: getOpenRouterKeyEndpoint(openRouterApiBaseUrl)
|
|
4626
|
+
});
|
|
4627
|
+
if (result.type === 'error') {
|
|
4628
|
+
return undefined;
|
|
4629
|
+
}
|
|
4630
|
+
parsed = result.body;
|
|
4631
|
+
} else {
|
|
4632
|
+
let response;
|
|
4633
|
+
try {
|
|
4634
|
+
response = await fetch(getOpenRouterKeyEndpoint(openRouterApiBaseUrl), {
|
|
4635
|
+
headers: {
|
|
4636
|
+
Authorization: `Bearer ${openRouterApiKey}`,
|
|
4637
|
+
...getClientRequestIdHeader()
|
|
4638
|
+
},
|
|
4639
|
+
method: 'GET'
|
|
4640
|
+
});
|
|
4641
|
+
} catch {
|
|
4642
|
+
return undefined;
|
|
4643
|
+
}
|
|
4644
|
+
if (!response.ok) {
|
|
4645
|
+
return undefined;
|
|
4646
|
+
}
|
|
4647
|
+
try {
|
|
4648
|
+
parsed = await response.json();
|
|
4649
|
+
} catch {
|
|
4650
|
+
return undefined;
|
|
4651
|
+
}
|
|
4652
|
+
}
|
|
4434
4653
|
if (!parsed || typeof parsed !== 'object') {
|
|
4435
4654
|
return undefined;
|
|
4436
4655
|
}
|
|
@@ -4462,7 +4681,7 @@ const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl) =>
|
|
|
4462
4681
|
}
|
|
4463
4682
|
return normalizedLimitInfo;
|
|
4464
4683
|
};
|
|
4465
|
-
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform) => {
|
|
4684
|
+
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false) => {
|
|
4466
4685
|
const completionMessages = messages.map(message => ({
|
|
4467
4686
|
content: message.text,
|
|
4468
4687
|
role: message.role
|
|
@@ -4470,64 +4689,111 @@ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, o
|
|
|
4470
4689
|
const tools = getBasicChatTools();
|
|
4471
4690
|
const maxToolIterations = 4;
|
|
4472
4691
|
for (let i = 0; i <= maxToolIterations; i++) {
|
|
4473
|
-
let
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
body: JSON.stringify({
|
|
4477
|
-
messages: completionMessages,
|
|
4478
|
-
model: modelId,
|
|
4479
|
-
tool_choice: 'auto',
|
|
4480
|
-
tools
|
|
4481
|
-
}),
|
|
4692
|
+
let parsed;
|
|
4693
|
+
if (useChatNetworkWorkerForRequests) {
|
|
4694
|
+
const requestResult = await makeApiRequest({
|
|
4482
4695
|
headers: {
|
|
4483
4696
|
Authorization: `Bearer ${openRouterApiKey}`,
|
|
4484
4697
|
'Content-Type': 'application/json',
|
|
4485
4698
|
...getClientRequestIdHeader()
|
|
4486
4699
|
},
|
|
4487
|
-
method: 'POST'
|
|
4700
|
+
method: 'POST',
|
|
4701
|
+
postBody: {
|
|
4702
|
+
messages: completionMessages,
|
|
4703
|
+
model: modelId,
|
|
4704
|
+
tool_choice: 'auto',
|
|
4705
|
+
tools
|
|
4706
|
+
},
|
|
4707
|
+
url: getOpenRouterApiEndpoint(openRouterApiBaseUrl)
|
|
4488
4708
|
});
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4709
|
+
if (requestResult.type === 'error') {
|
|
4710
|
+
if (requestResult.statusCode === 429) {
|
|
4711
|
+
const retryAfter = requestResult.headers?.['retry-after'] ?? null;
|
|
4712
|
+
const rawMessage = getOpenRouterRaw429MessageFromText(requestResult.response);
|
|
4713
|
+
const limitInfo = await getOpenRouterLimitInfo(openRouterApiKey, openRouterApiBaseUrl, useChatNetworkWorkerForRequests);
|
|
4714
|
+
return {
|
|
4715
|
+
details: 'too-many-requests',
|
|
4716
|
+
...(limitInfo || retryAfter ? {
|
|
4717
|
+
limitInfo: {
|
|
4718
|
+
...limitInfo,
|
|
4719
|
+
...(retryAfter ? {
|
|
4720
|
+
retryAfter
|
|
4721
|
+
} : {})
|
|
4722
|
+
}
|
|
4723
|
+
} : {}),
|
|
4724
|
+
...(rawMessage ? {
|
|
4725
|
+
rawMessage
|
|
4726
|
+
} : {}),
|
|
4727
|
+
statusCode: 429,
|
|
4728
|
+
type: 'error'
|
|
4729
|
+
};
|
|
4730
|
+
}
|
|
4500
4731
|
return {
|
|
4501
|
-
details: '
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4732
|
+
details: 'http-error',
|
|
4733
|
+
statusCode: requestResult.statusCode,
|
|
4734
|
+
type: 'error'
|
|
4735
|
+
};
|
|
4736
|
+
}
|
|
4737
|
+
parsed = requestResult.body;
|
|
4738
|
+
} else {
|
|
4739
|
+
let response;
|
|
4740
|
+
try {
|
|
4741
|
+
response = await fetch(getOpenRouterApiEndpoint(openRouterApiBaseUrl), {
|
|
4742
|
+
body: JSON.stringify({
|
|
4743
|
+
messages: completionMessages,
|
|
4744
|
+
model: modelId,
|
|
4745
|
+
tool_choice: 'auto',
|
|
4746
|
+
tools
|
|
4747
|
+
}),
|
|
4748
|
+
headers: {
|
|
4749
|
+
Authorization: `Bearer ${openRouterApiKey}`,
|
|
4750
|
+
'Content-Type': 'application/json',
|
|
4751
|
+
...getClientRequestIdHeader()
|
|
4752
|
+
},
|
|
4753
|
+
method: 'POST'
|
|
4754
|
+
});
|
|
4755
|
+
} catch {
|
|
4756
|
+
return {
|
|
4757
|
+
details: 'request-failed',
|
|
4758
|
+
type: 'error'
|
|
4759
|
+
};
|
|
4760
|
+
}
|
|
4761
|
+
if (!response.ok) {
|
|
4762
|
+
if (response.status === 429) {
|
|
4763
|
+
const retryAfter = response.headers?.get?.('retry-after') ?? null;
|
|
4764
|
+
const rawMessage = await getOpenRouterRaw429Message(response);
|
|
4765
|
+
const limitInfo = await getOpenRouterLimitInfo(openRouterApiKey, openRouterApiBaseUrl, useChatNetworkWorkerForRequests);
|
|
4766
|
+
return {
|
|
4767
|
+
details: 'too-many-requests',
|
|
4768
|
+
...(limitInfo || retryAfter ? {
|
|
4769
|
+
limitInfo: {
|
|
4770
|
+
...limitInfo,
|
|
4771
|
+
...(retryAfter ? {
|
|
4772
|
+
retryAfter
|
|
4773
|
+
} : {})
|
|
4774
|
+
}
|
|
4775
|
+
} : {}),
|
|
4776
|
+
...(rawMessage ? {
|
|
4777
|
+
rawMessage
|
|
4778
|
+
} : {}),
|
|
4779
|
+
statusCode: 429,
|
|
4780
|
+
type: 'error'
|
|
4781
|
+
};
|
|
4782
|
+
}
|
|
4783
|
+
return {
|
|
4784
|
+
details: 'http-error',
|
|
4785
|
+
statusCode: response.status,
|
|
4786
|
+
type: 'error'
|
|
4787
|
+
};
|
|
4788
|
+
}
|
|
4789
|
+
try {
|
|
4790
|
+
parsed = await response.json();
|
|
4791
|
+
} catch {
|
|
4792
|
+
return {
|
|
4793
|
+
details: 'request-failed',
|
|
4514
4794
|
type: 'error'
|
|
4515
4795
|
};
|
|
4516
4796
|
}
|
|
4517
|
-
return {
|
|
4518
|
-
details: 'http-error',
|
|
4519
|
-
statusCode: response.status,
|
|
4520
|
-
type: 'error'
|
|
4521
|
-
};
|
|
4522
|
-
}
|
|
4523
|
-
let parsed;
|
|
4524
|
-
try {
|
|
4525
|
-
parsed = await response.json();
|
|
4526
|
-
} catch {
|
|
4527
|
-
return {
|
|
4528
|
-
details: 'request-failed',
|
|
4529
|
-
type: 'error'
|
|
4530
|
-
};
|
|
4531
4797
|
}
|
|
4532
4798
|
if (!parsed || typeof parsed !== 'object') {
|
|
4533
4799
|
return {
|
|
@@ -4686,6 +4952,7 @@ const getAiResponse = async ({
|
|
|
4686
4952
|
platform,
|
|
4687
4953
|
selectedModelId,
|
|
4688
4954
|
streamingEnabled = true,
|
|
4955
|
+
useChatNetworkWorkerForRequests = false,
|
|
4689
4956
|
useMockApi,
|
|
4690
4957
|
userText,
|
|
4691
4958
|
webSearchEnabled = false
|
|
@@ -4720,6 +4987,7 @@ const getAiResponse = async ({
|
|
|
4720
4987
|
onToolCallsChunk
|
|
4721
4988
|
} : {}),
|
|
4722
4989
|
stream: streamingEnabled,
|
|
4990
|
+
useChatNetworkWorkerForRequests,
|
|
4723
4991
|
webSearchEnabled
|
|
4724
4992
|
});
|
|
4725
4993
|
if (result.type === 'success') {
|
|
@@ -4746,7 +5014,7 @@ const getAiResponse = async ({
|
|
|
4746
5014
|
text = getOpenRouterErrorMessage(result);
|
|
4747
5015
|
}
|
|
4748
5016
|
} else if (openRouterApiKey) {
|
|
4749
|
-
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform);
|
|
5017
|
+
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests);
|
|
4750
5018
|
if (result.type === 'success') {
|
|
4751
5019
|
const {
|
|
4752
5020
|
text: assistantText
|
|
@@ -4830,6 +5098,7 @@ const handleClickSaveOpenApiApiKey = async state => {
|
|
|
4830
5098
|
platform: updatedState.platform,
|
|
4831
5099
|
selectedModelId: updatedState.selectedModelId,
|
|
4832
5100
|
streamingEnabled: updatedState.streamingEnabled,
|
|
5101
|
+
useChatNetworkWorkerForRequests: updatedState.useChatNetworkWorkerForRequests,
|
|
4833
5102
|
useMockApi: updatedState.useMockApi,
|
|
4834
5103
|
userText: previousUserMessage.text
|
|
4835
5104
|
});
|
|
@@ -4910,6 +5179,7 @@ const handleClickSaveOpenRouterApiKey = async state => {
|
|
|
4910
5179
|
openRouterApiKey,
|
|
4911
5180
|
platform: updatedState.platform,
|
|
4912
5181
|
selectedModelId: updatedState.selectedModelId,
|
|
5182
|
+
useChatNetworkWorkerForRequests: updatedState.useChatNetworkWorkerForRequests,
|
|
4913
5183
|
useMockApi: updatedState.useMockApi,
|
|
4914
5184
|
userText: previousUserMessage.text
|
|
4915
5185
|
});
|
|
@@ -5286,6 +5556,7 @@ Assistant: ${assistantText}`;
|
|
|
5286
5556
|
platform: state.platform,
|
|
5287
5557
|
selectedModelId,
|
|
5288
5558
|
streamingEnabled: false,
|
|
5559
|
+
useChatNetworkWorkerForRequests: state.useChatNetworkWorkerForRequests,
|
|
5289
5560
|
useMockApi,
|
|
5290
5561
|
userText: titlePrompt,
|
|
5291
5562
|
webSearchEnabled: false
|
|
@@ -5313,6 +5584,7 @@ const handleSubmit = async state => {
|
|
|
5313
5584
|
selectedSessionId,
|
|
5314
5585
|
sessions,
|
|
5315
5586
|
streamingEnabled,
|
|
5587
|
+
useChatNetworkWorkerForRequests,
|
|
5316
5588
|
useMockApi,
|
|
5317
5589
|
viewMode,
|
|
5318
5590
|
webSearchEnabled
|
|
@@ -5465,6 +5737,7 @@ const handleSubmit = async state => {
|
|
|
5465
5737
|
platform,
|
|
5466
5738
|
selectedModelId,
|
|
5467
5739
|
streamingEnabled,
|
|
5740
|
+
useChatNetworkWorkerForRequests,
|
|
5468
5741
|
useMockApi,
|
|
5469
5742
|
userText,
|
|
5470
5743
|
webSearchEnabled
|
|
@@ -6105,8 +6378,17 @@ const loadStreamingEnabled = async () => {
|
|
|
6105
6378
|
}
|
|
6106
6379
|
};
|
|
6107
6380
|
|
|
6381
|
+
const loadUseChatNetworkWorkerForRequests = async () => {
|
|
6382
|
+
try {
|
|
6383
|
+
const savedUseChatNetworkWorkerForRequests = await get('chatView.useChatNetworkWorkerForRequests');
|
|
6384
|
+
return typeof savedUseChatNetworkWorkerForRequests === 'boolean' ? savedUseChatNetworkWorkerForRequests : false;
|
|
6385
|
+
} catch {
|
|
6386
|
+
return false;
|
|
6387
|
+
}
|
|
6388
|
+
};
|
|
6389
|
+
|
|
6108
6390
|
const loadPreferences = async () => {
|
|
6109
|
-
const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation()]);
|
|
6391
|
+
const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatNetworkWorkerForRequests] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatNetworkWorkerForRequests()]);
|
|
6110
6392
|
return {
|
|
6111
6393
|
aiSessionTitleGenerationEnabled,
|
|
6112
6394
|
composerDropEnabled,
|
|
@@ -6114,7 +6396,8 @@ const loadPreferences = async () => {
|
|
|
6114
6396
|
openApiApiKey,
|
|
6115
6397
|
openRouterApiKey,
|
|
6116
6398
|
passIncludeObfuscation,
|
|
6117
|
-
streamingEnabled
|
|
6399
|
+
streamingEnabled,
|
|
6400
|
+
useChatNetworkWorkerForRequests
|
|
6118
6401
|
};
|
|
6119
6402
|
};
|
|
6120
6403
|
|
|
@@ -6151,7 +6434,8 @@ const loadContent = async (state, savedState) => {
|
|
|
6151
6434
|
openApiApiKey,
|
|
6152
6435
|
openRouterApiKey,
|
|
6153
6436
|
passIncludeObfuscation,
|
|
6154
|
-
streamingEnabled
|
|
6437
|
+
streamingEnabled,
|
|
6438
|
+
useChatNetworkWorkerForRequests
|
|
6155
6439
|
} = await loadPreferences();
|
|
6156
6440
|
const legacySavedSessions = getSavedSessions(savedState);
|
|
6157
6441
|
const storedSessions = await listChatSessions();
|
|
@@ -6195,6 +6479,7 @@ const loadContent = async (state, savedState) => {
|
|
|
6195
6479
|
selectedSessionId,
|
|
6196
6480
|
sessions,
|
|
6197
6481
|
streamingEnabled,
|
|
6482
|
+
useChatNetworkWorkerForRequests,
|
|
6198
6483
|
viewMode
|
|
6199
6484
|
};
|
|
6200
6485
|
};
|
|
@@ -7936,6 +8221,18 @@ const setStreamingEnabled = (state, streamingEnabled) => {
|
|
|
7936
8221
|
};
|
|
7937
8222
|
};
|
|
7938
8223
|
|
|
8224
|
+
const setUseChatNetworkWorkerForRequests = async (state, useChatNetworkWorkerForRequests, persist = true) => {
|
|
8225
|
+
if (persist) {
|
|
8226
|
+
await update({
|
|
8227
|
+
'chatView.useChatNetworkWorkerForRequests': useChatNetworkWorkerForRequests
|
|
8228
|
+
});
|
|
8229
|
+
}
|
|
8230
|
+
return {
|
|
8231
|
+
...state,
|
|
8232
|
+
useChatNetworkWorkerForRequests
|
|
8233
|
+
};
|
|
8234
|
+
};
|
|
8235
|
+
|
|
7939
8236
|
const defaultMockApiCommandId = 'ChatE2e.mockApi';
|
|
7940
8237
|
const useMockApi = (state, value, mockApiCommandId = defaultMockApiCommandId) => {
|
|
7941
8238
|
if (!value) {
|
|
@@ -8001,6 +8298,7 @@ const commandMap = {
|
|
|
8001
8298
|
'Chat.setEmitStreamingFunctionCallEvents': wrapCommand(setEmitStreamingFunctionCallEvents),
|
|
8002
8299
|
'Chat.setOpenRouterApiKey': wrapCommand(setOpenRouterApiKey),
|
|
8003
8300
|
'Chat.setStreamingEnabled': wrapCommand(setStreamingEnabled),
|
|
8301
|
+
'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
|
|
8004
8302
|
'Chat.terminate': terminate,
|
|
8005
8303
|
'Chat.useMockApi': wrapCommand(useMockApi)
|
|
8006
8304
|
};
|