@lazyingart/agent-web 0.1.41 → 0.1.43
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/package.json +1 -1
- package/src/cloud-server.js +19 -11
- package/src/http-contract.js +2 -1
- package/src/web/browser-app.js +41 -3
package/package.json
CHANGED
package/src/cloud-server.js
CHANGED
|
@@ -90,6 +90,7 @@ function exactLimitOverrides(input = {}) {
|
|
|
90
90
|
bodyTimeoutMs: [50, 15_000],
|
|
91
91
|
visionBodyTimeoutMs: [1_000, 300_000],
|
|
92
92
|
dependencyTimeoutMs: [50, 120_000],
|
|
93
|
+
jobAdmissionTimeoutMs: [50, 600_000],
|
|
93
94
|
jobTimeoutMs: [50, 600_000],
|
|
94
95
|
visionJobTimeoutMs: [50, 900_000],
|
|
95
96
|
sseLifetimeMs: [100, 120_000],
|
|
@@ -1244,19 +1245,23 @@ export function createCloudRequestHandler({
|
|
|
1244
1245
|
if (jobs.has(jobKey)) return true;
|
|
1245
1246
|
if (stopping || !directChatConnector || jobs.size >= limits.directChatJobs) return false;
|
|
1246
1247
|
const scheduled = chat.getGeneration({ accountId, threadId, generationId });
|
|
1247
|
-
const
|
|
1248
|
+
const executionTimeoutMs = scheduled?.modelAlias === visionModelAlias
|
|
1248
1249
|
? limits.visionJobTimeoutMs
|
|
1249
1250
|
: limits.jobTimeoutMs;
|
|
1250
1251
|
const controller = new AbortController();
|
|
1251
|
-
const job = { controller, timedOut: false, promise: null, lease: null };
|
|
1252
|
+
const job = { controller, timedOut: false, promise: null, lease: null, timer: null };
|
|
1252
1253
|
jobs.set(jobKey, job);
|
|
1253
|
-
const
|
|
1254
|
-
job.
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1254
|
+
const armJobTimeout = (milliseconds, phase) => {
|
|
1255
|
+
clearTimeout(job.timer);
|
|
1256
|
+
job.timer = setTimeout(() => {
|
|
1257
|
+
job.timedOut = true;
|
|
1258
|
+
const error = new Error(`direct chat generation ${phase} timed out`);
|
|
1259
|
+
error.name = 'TimeoutError';
|
|
1260
|
+
controller.abort(error);
|
|
1261
|
+
}, milliseconds);
|
|
1262
|
+
job.timer.unref?.();
|
|
1263
|
+
};
|
|
1264
|
+
armJobTimeout(limits.jobAdmissionTimeoutMs, 'admission');
|
|
1260
1265
|
job.promise = (async () => {
|
|
1261
1266
|
try {
|
|
1262
1267
|
const thread = chat.getThread(accountId, threadId);
|
|
@@ -1338,7 +1343,10 @@ export function createCloudRequestHandler({
|
|
|
1338
1343
|
ownerToken,
|
|
1339
1344
|
fence: lease.fence
|
|
1340
1345
|
});
|
|
1341
|
-
if (marker.dispatchAuthorized === true)
|
|
1346
|
+
if (marker.dispatchAuthorized === true) {
|
|
1347
|
+
armJobTimeout(executionTimeoutMs, 'execution');
|
|
1348
|
+
break;
|
|
1349
|
+
}
|
|
1342
1350
|
if (marker.dispatchState !== 'global_busy') {
|
|
1343
1351
|
const error = new Error('inference dispatch is already ambiguous');
|
|
1344
1352
|
error.failureCode = 'provider_unavailable';
|
|
@@ -1431,7 +1439,7 @@ export function createCloudRequestHandler({
|
|
|
1431
1439
|
// Another request may have cancelled or completed the same durable generation.
|
|
1432
1440
|
}
|
|
1433
1441
|
} finally {
|
|
1434
|
-
clearTimeout(timer);
|
|
1442
|
+
clearTimeout(job.timer);
|
|
1435
1443
|
if (job.renewTimer) clearInterval(job.renewTimer);
|
|
1436
1444
|
if (job.lease) {
|
|
1437
1445
|
try {
|
package/src/http-contract.js
CHANGED
|
@@ -42,7 +42,8 @@ export const CLOUD_HTTP_LIMITS = Object.freeze({
|
|
|
42
42
|
bodyTimeoutMs: 5_000,
|
|
43
43
|
visionBodyTimeoutMs: 240_000,
|
|
44
44
|
dependencyTimeoutMs: 30_000,
|
|
45
|
-
|
|
45
|
+
jobAdmissionTimeoutMs: 120_000,
|
|
46
|
+
jobTimeoutMs: 600_000,
|
|
46
47
|
visionJobTimeoutMs: 600_000,
|
|
47
48
|
sseLifetimeMs: 30_000,
|
|
48
49
|
ssePollMs: 100,
|
package/src/web/browser-app.js
CHANGED
|
@@ -912,6 +912,46 @@ function chatFailureDiagnostic(error) {
|
|
|
912
912
|
});
|
|
913
913
|
}
|
|
914
914
|
|
|
915
|
+
function chatNotSentRecoveryMessage(diagnostic, imageCount = 0) {
|
|
916
|
+
const hasImages = Number.isSafeInteger(imageCount) && imageCount > 0;
|
|
917
|
+
const subject = hasImages ? "This image message" : "This message";
|
|
918
|
+
const preserved = hasImages
|
|
919
|
+
? `Your prompt and ${imageCount === 1 ? "image are" : "images are"} still ready.`
|
|
920
|
+
: "Your prompt is still ready.";
|
|
921
|
+
if (diagnostic.stage === "authentication" || diagnostic.stage === "csrf") {
|
|
922
|
+
return `${subject} was not sent because your sign-in expired. ${preserved} Sign in again, then retry.`;
|
|
923
|
+
}
|
|
924
|
+
if (diagnostic.stage === "body_rejection" && diagnostic.code === "request_too_large") {
|
|
925
|
+
return `${subject} was not sent because the upload was too large. ${preserved} Remove an image or choose smaller files, then retry.`;
|
|
926
|
+
}
|
|
927
|
+
if (diagnostic.stage === "body_rejection" && diagnostic.code === "invalid_attachment") {
|
|
928
|
+
return `${subject} was not sent because an image format or file was rejected. ${preserved} Replace the affected image, then retry.`;
|
|
929
|
+
}
|
|
930
|
+
if (diagnostic.stage === "authoritative_conflict") {
|
|
931
|
+
return `${subject} was not sent because the conversation changed. ${preserved} Reopen this conversation, then retry.`;
|
|
932
|
+
}
|
|
933
|
+
if (diagnostic.stage === "network_timeout") {
|
|
934
|
+
return `${subject} was not sent because the request timed out. ${preserved} Check your connection, then retry.`;
|
|
935
|
+
}
|
|
936
|
+
if (diagnostic.stage === "network") {
|
|
937
|
+
return `${subject} was not sent because the network was unavailable. ${preserved} Reconnect, then retry.`;
|
|
938
|
+
}
|
|
939
|
+
if (diagnostic.stage === "snapshot") {
|
|
940
|
+
return `${subject} was not sent because the conversation could not be refreshed. ${preserved} Check your connection, then reopen it and retry.`;
|
|
941
|
+
}
|
|
942
|
+
if (diagnostic.stage === "local_preparation") {
|
|
943
|
+
return `${subject} was not sent because the browser could not prepare it. ${preserved} ${hasImages
|
|
944
|
+
? "Remove and re-add the images, then retry; refresh the app if it repeats."
|
|
945
|
+
: "Refresh the app, then retry."}`;
|
|
946
|
+
}
|
|
947
|
+
if (diagnostic.stage === "body_rejection") {
|
|
948
|
+
return `${subject} was not sent because the service could not accept it. ${preserved} ${hasImages
|
|
949
|
+
? "Remove or replace the affected image, then retry."
|
|
950
|
+
: "Edit it, then retry."}`;
|
|
951
|
+
}
|
|
952
|
+
return `${subject} was not sent because the service rejected it before it ran. ${preserved} Edit it or retry when the service is available.`;
|
|
953
|
+
}
|
|
954
|
+
|
|
915
955
|
function normalizedBrowserPath(value, name, { trailingSlash = false } = {}) {
|
|
916
956
|
if (typeof value !== "string" || value.length > 160 || !/^\/[A-Za-z0-9._~/-]*$/u.test(value) || value.includes("//")
|
|
917
957
|
|| value.split("/").some((part) => part === "." || part === "..")) {
|
|
@@ -4341,9 +4381,7 @@ export function createBrowserApp({
|
|
|
4341
4381
|
const imageRestored = restoreDetachedImage(detachedImage);
|
|
4342
4382
|
detachedImage = null;
|
|
4343
4383
|
const diagnostic = applyChatFailureDiagnostic(error);
|
|
4344
|
-
showToast(imageRestored
|
|
4345
|
-
? `This image message was not sent. Your prompt and ${selected.length === 1 ? "image" : "images"} are still ready; edit or retry them.`
|
|
4346
|
-
: "This message was not sent. Your prompt is still in the composer; edit it and try again.");
|
|
4384
|
+
showToast(chatNotSentRecoveryMessage(diagnostic, imageRestored ? selected.length : 0));
|
|
4347
4385
|
if (diagnostic.reauthenticate) requireFreshAuthentication();
|
|
4348
4386
|
} else if (state.mode === "chat" && state.chatPendingSend && !state.chatPendingSend.runDispatched) {
|
|
4349
4387
|
elements.message_input.value = draft;
|