Ensure Docker images keep their container-built native dependencies, wait for the Laya sidecar healthcheck, expose accurate Laya readiness, and treat empty AI language batches as fallback failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -8,6 +8,7 @@ const MAX_BATCH_BYTES = 64 * 1024;
|
||||
const MAX_TEXT_LENGTH = 4096;
|
||||
const ALLOWED_MODELS = new Set(['english', 'multilingual', 'typed-decisions']);
|
||||
const DOWNLOAD_TIMEOUT_MS = 30 * 60 * 1000;
|
||||
const BATCH_TIMEOUT_MS = 2 * 60 * 1000;
|
||||
|
||||
class LayaRequestError extends Error {
|
||||
constructor(message, statusCode = 503) {
|
||||
@ -128,6 +129,9 @@ class LayaService {
|
||||
? require('../db/sqlite').layaLanguageCache
|
||||
: options.cache;
|
||||
this.timeoutMs = options.timeoutMs || 3000;
|
||||
this.batchTimeoutMs = options.batchTimeoutMs
|
||||
|| Number(process.env.LAYA_BATCH_TIMEOUT_MS)
|
||||
|| BATCH_TIMEOUT_MS;
|
||||
this.downloadTimeoutMs = options.downloadTimeoutMs || DOWNLOAD_TIMEOUT_MS;
|
||||
this.progressIntervalMs = options.progressIntervalMs || 500;
|
||||
this.downloadState = initialDownloadState();
|
||||
@ -152,6 +156,9 @@ class LayaService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
if (error instanceof LayaRequestError) throw error;
|
||||
if (error?.name === 'AbortError') {
|
||||
throw new LayaRequestError(`Laya runtime request timed out after ${timeoutMs} ms`, 504);
|
||||
}
|
||||
throw new LayaRequestError('Laya runtime is unavailable');
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
@ -168,9 +175,27 @@ class LayaService {
|
||||
if (!this.downloadState.downloading && this.downloadState.phase !== 'failed' && modelPresent) {
|
||||
this.downloadState.phase = 'ready';
|
||||
}
|
||||
return { ...this.downloadState, runtimeAvailable: true, modelPresent, sizeBytes, runtime };
|
||||
return {
|
||||
...this.downloadState,
|
||||
runtimeAvailable: true,
|
||||
modelPresent,
|
||||
ready: modelPresent,
|
||||
sizeBytes,
|
||||
runtime,
|
||||
runtimeError: null
|
||||
};
|
||||
} catch (error) {
|
||||
return { ...this.downloadState, runtimeAvailable: false, modelPresent, sizeBytes };
|
||||
return {
|
||||
...this.downloadState,
|
||||
runtimeAvailable: false,
|
||||
modelPresent,
|
||||
ready: false,
|
||||
sizeBytes,
|
||||
runtimeError: {
|
||||
message: error.message,
|
||||
detail: 'Start the Laya sidecar and verify LAYA_BASE_URL.'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,6 +312,7 @@ class LayaService {
|
||||
if (misses.length) {
|
||||
const response = await this.request('/v1/systemone/batch', {
|
||||
method: 'POST',
|
||||
timeoutMs: this.batchTimeoutMs,
|
||||
body: JSON.stringify({
|
||||
states: misses.map(({ item }) => item.text),
|
||||
model,
|
||||
@ -323,6 +349,7 @@ class LayaService {
|
||||
}
|
||||
const response = await this.request('/v1/systemone/batch', {
|
||||
method: 'POST',
|
||||
timeoutMs: this.batchTimeoutMs,
|
||||
body: JSON.stringify({
|
||||
states: pairs.map(pair => ({
|
||||
left: sanitizeIdentityDescriptor(pair.left),
|
||||
@ -355,6 +382,7 @@ class LayaService {
|
||||
|
||||
module.exports = {
|
||||
ALLOWED_MODELS,
|
||||
BATCH_TIMEOUT_MS,
|
||||
LayaRequestError,
|
||||
LayaService,
|
||||
MODEL_DIR,
|
||||
|
||||
Reference in New Issue
Block a user