@pellux/goodvibes-sdk 0.25.7 → 0.25.10
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/README.md +4 -0
- package/dist/_internal/contracts/artifacts/operator-contract.json +100 -4
- package/dist/_internal/contracts/generated/foundation-metadata.d.ts +2 -2
- package/dist/_internal/contracts/generated/foundation-metadata.js +2 -2
- package/dist/_internal/contracts/generated/operator-contract.d.ts.map +1 -1
- package/dist/_internal/contracts/generated/operator-contract.js +100 -4
- package/dist/_internal/contracts/generated/operator-method-ids.d.ts +1 -1
- package/dist/_internal/contracts/generated/operator-method-ids.d.ts.map +1 -1
- package/dist/_internal/contracts/generated/operator-method-ids.js +1 -0
- package/dist/_internal/daemon/context.d.ts +1 -0
- package/dist/_internal/daemon/context.d.ts.map +1 -1
- package/dist/_internal/daemon/media-route-types.d.ts +10 -0
- package/dist/_internal/daemon/media-route-types.d.ts.map +1 -1
- package/dist/_internal/daemon/media-routes.d.ts +1 -1
- package/dist/_internal/daemon/media-routes.d.ts.map +1 -1
- package/dist/_internal/daemon/media-routes.js +91 -10
- package/dist/_internal/daemon/operator.d.ts +1 -1
- package/dist/_internal/daemon/operator.d.ts.map +1 -1
- package/dist/_internal/daemon/operator.js +2 -0
- package/dist/_internal/platform/adapters/ntfy/index.js +13 -2
- package/dist/_internal/platform/adapters/types.d.ts +2 -0
- package/dist/_internal/platform/adapters/types.d.ts.map +1 -1
- package/dist/_internal/platform/batch/index.d.ts +4 -0
- package/dist/_internal/platform/batch/index.d.ts.map +1 -0
- package/dist/_internal/platform/batch/index.js +2 -0
- package/dist/_internal/platform/batch/manager.d.ts +41 -0
- package/dist/_internal/platform/batch/manager.d.ts.map +1 -0
- package/dist/_internal/platform/batch/manager.js +404 -0
- package/dist/_internal/platform/batch/types.d.ts +89 -0
- package/dist/_internal/platform/batch/types.d.ts.map +1 -0
- package/dist/_internal/platform/batch/types.js +10 -0
- package/dist/_internal/platform/channels/builtin/plugins.d.ts.map +1 -1
- package/dist/_internal/platform/channels/builtin/plugins.js +1 -0
- package/dist/_internal/platform/channels/reply-pipeline.d.ts +9 -1
- package/dist/_internal/platform/channels/reply-pipeline.d.ts.map +1 -1
- package/dist/_internal/platform/channels/reply-pipeline.js +156 -6
- package/dist/_internal/platform/cloudflare/client.d.ts +3 -0
- package/dist/_internal/platform/cloudflare/client.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/client.js +9 -0
- package/dist/_internal/platform/cloudflare/config.d.ts +8 -0
- package/dist/_internal/platform/cloudflare/config.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/config.js +48 -0
- package/dist/_internal/platform/cloudflare/constants.d.ts +18 -0
- package/dist/_internal/platform/cloudflare/constants.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/constants.js +36 -0
- package/dist/_internal/platform/cloudflare/discovery.d.ts +23 -0
- package/dist/_internal/platform/cloudflare/discovery.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/discovery.js +57 -0
- package/dist/_internal/platform/cloudflare/index.d.ts +6 -0
- package/dist/_internal/platform/cloudflare/index.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/index.js +4 -0
- package/dist/_internal/platform/cloudflare/manager.d.ts +30 -0
- package/dist/_internal/platform/cloudflare/manager.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/manager.js +671 -0
- package/dist/_internal/platform/cloudflare/resources.d.ts +79 -0
- package/dist/_internal/platform/cloudflare/resources.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/resources.js +353 -0
- package/dist/_internal/platform/cloudflare/types.d.ts +689 -0
- package/dist/_internal/platform/cloudflare/types.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/types.js +10 -0
- package/dist/_internal/platform/cloudflare/utils.d.ts +14 -0
- package/dist/_internal/platform/cloudflare/utils.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/utils.js +222 -0
- package/dist/_internal/platform/cloudflare/worker-source.d.ts +2 -0
- package/dist/_internal/platform/cloudflare/worker-source.d.ts.map +1 -0
- package/dist/_internal/platform/cloudflare/worker-source.js +165 -0
- package/dist/_internal/platform/config/schema-domain-core.d.ts +6 -0
- package/dist/_internal/platform/config/schema-domain-core.d.ts.map +1 -1
- package/dist/_internal/platform/config/schema-domain-core.js +30 -0
- package/dist/_internal/platform/config/schema-domain-runtime.d.ts +43 -0
- package/dist/_internal/platform/config/schema-domain-runtime.d.ts.map +1 -1
- package/dist/_internal/platform/config/schema-domain-runtime.js +287 -0
- package/dist/_internal/platform/config/schema-types.d.ts +57 -2
- package/dist/_internal/platform/config/schema-types.d.ts.map +1 -1
- package/dist/_internal/platform/config/schema.d.ts.map +1 -1
- package/dist/_internal/platform/config/schema.js +3 -0
- package/dist/_internal/platform/control-plane/method-catalog-media.d.ts.map +1 -1
- package/dist/_internal/platform/control-plane/method-catalog-media.js +17 -0
- package/dist/_internal/platform/control-plane/routes/operator.d.ts +1 -1
- package/dist/_internal/platform/control-plane/routes/operator.d.ts.map +1 -1
- package/dist/_internal/platform/control-plane/routes/operator.js +2 -0
- package/dist/_internal/platform/daemon/facade-composition.d.ts +2 -0
- package/dist/_internal/platform/daemon/facade-composition.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/facade-composition.js +10 -0
- package/dist/_internal/platform/daemon/http/batch-routes.d.ts +8 -0
- package/dist/_internal/platform/daemon/http/batch-routes.d.ts.map +1 -0
- package/dist/_internal/platform/daemon/http/batch-routes.js +113 -0
- package/dist/_internal/platform/daemon/http/cloudflare-routes.d.ts +7 -0
- package/dist/_internal/platform/daemon/http/cloudflare-routes.d.ts.map +1 -0
- package/dist/_internal/platform/daemon/http/cloudflare-routes.js +201 -0
- package/dist/_internal/platform/daemon/http/router-route-contexts.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/http/router-route-contexts.js +1 -0
- package/dist/_internal/platform/daemon/http/router.d.ts +5 -1
- package/dist/_internal/platform/daemon/http/router.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/http/router.js +30 -0
- package/dist/_internal/platform/daemon/http/runtime-route-types.d.ts +2 -0
- package/dist/_internal/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/surface-actions.d.ts +6 -0
- package/dist/_internal/platform/daemon/surface-actions.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/surface-actions.js +13 -0
- package/dist/_internal/platform/daemon/surface-delivery.d.ts +3 -0
- package/dist/_internal/platform/daemon/surface-delivery.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/surface-delivery.js +42 -6
- package/dist/_internal/platform/daemon/types.d.ts +2 -0
- package/dist/_internal/platform/daemon/types.d.ts.map +1 -1
- package/dist/_internal/platform/providers/anthropic.d.ts +13 -1
- package/dist/_internal/platform/providers/anthropic.d.ts.map +1 -1
- package/dist/_internal/platform/providers/anthropic.js +219 -1
- package/dist/_internal/platform/providers/interface.d.ts +48 -0
- package/dist/_internal/platform/providers/interface.d.ts.map +1 -1
- package/dist/_internal/platform/providers/openai.d.ts +13 -1
- package/dist/_internal/platform/providers/openai.d.ts.map +1 -1
- package/dist/_internal/platform/providers/openai.js +189 -1
- package/dist/_internal/platform/version.js +1 -1
- package/dist/_internal/platform/voice/index.d.ts +1 -1
- package/dist/_internal/platform/voice/index.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/elevenlabs.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/elevenlabs.js +150 -4
- package/dist/_internal/platform/voice/service.d.ts +2 -1
- package/dist/_internal/platform/voice/service.d.ts.map +1 -1
- package/dist/_internal/platform/voice/service.js +7 -0
- package/dist/_internal/platform/voice/types.d.ts +18 -1
- package/dist/_internal/platform/voice/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/workers.d.ts +43 -0
- package/dist/workers.d.ts.map +1 -0
- package/dist/workers.js +156 -0
- package/package.json +6 -1
|
@@ -337,6 +337,8 @@ export async function dispatchOperatorRoutes(req, handlers) {
|
|
|
337
337
|
return handlers.getVoiceProviders();
|
|
338
338
|
if (pathname === '/api/voice/voices' && method === 'GET')
|
|
339
339
|
return handlers.getVoiceVoices(url);
|
|
340
|
+
if (pathname === '/api/voice/tts/stream' && method === 'POST')
|
|
341
|
+
return handlers.postVoiceTtsStream(req);
|
|
340
342
|
if (pathname === '/api/voice/tts' && method === 'POST')
|
|
341
343
|
return handlers.postVoiceTts(req);
|
|
342
344
|
if (pathname === '/api/voice/stt' && method === 'POST')
|
|
@@ -94,7 +94,7 @@ async function handleNtfyChatPayload(body, context, topic, message) {
|
|
|
94
94
|
if (!context.publishConversationFollowup) {
|
|
95
95
|
return Response.json({ error: 'ntfy chat routing is unavailable in this runtime' }, { status: 503 });
|
|
96
96
|
}
|
|
97
|
-
const session = await context
|
|
97
|
+
const session = await findPreferredTuiSession(context);
|
|
98
98
|
if (!session) {
|
|
99
99
|
return Response.json({ error: 'No active terminal TUI session is available for ntfy chat' }, { status: 409 });
|
|
100
100
|
}
|
|
@@ -156,7 +156,7 @@ async function handleNtfyAgentPayload(body, context, topic, message) {
|
|
|
156
156
|
const denied = await authorizeNtfyPayload(body, context, topic, message);
|
|
157
157
|
if (denied)
|
|
158
158
|
return denied;
|
|
159
|
-
const preferredTuiSession = await context
|
|
159
|
+
const preferredTuiSession = await findPreferredTuiSession(context);
|
|
160
160
|
const binding = await context.routeBindings.upsertBinding({
|
|
161
161
|
kind: 'channel',
|
|
162
162
|
surfaceKind: 'ntfy',
|
|
@@ -197,6 +197,8 @@ async function handleNtfyAgentPayload(body, context, topic, message) {
|
|
|
197
197
|
context.queueSurfaceReplyFromBinding(submission.routeBinding ?? binding, {
|
|
198
198
|
agentId: spawnResult.id,
|
|
199
199
|
task: message,
|
|
200
|
+
...(typeof submission.task === 'string' && submission.task.length > 0 ? { agentTask: submission.task } : {}),
|
|
201
|
+
...(typeof spawnResult.wrfcId === 'string' && spawnResult.wrfcId.length > 0 ? { workflowChainId: spawnResult.wrfcId } : {}),
|
|
200
202
|
sessionId: submission.session.id,
|
|
201
203
|
});
|
|
202
204
|
return Response.json({
|
|
@@ -208,3 +210,12 @@ async function handleNtfyAgentPayload(body, context, topic, message) {
|
|
|
208
210
|
agentId: spawnResult.id,
|
|
209
211
|
});
|
|
210
212
|
}
|
|
213
|
+
async function findPreferredTuiSession(context) {
|
|
214
|
+
const direct = await context.sessionBroker.findPreferredSession({ surfaceKind: 'tui' });
|
|
215
|
+
if (direct)
|
|
216
|
+
return direct;
|
|
217
|
+
return context.sessionBroker
|
|
218
|
+
.listSessions(500)
|
|
219
|
+
.find((candidate) => candidate.status !== 'closed' && candidate.metadata?.source === 'tui')
|
|
220
|
+
?? null;
|
|
221
|
+
}
|
|
@@ -14,6 +14,8 @@ export interface SurfaceControlCommand {
|
|
|
14
14
|
export interface QueueSurfaceReplyInput {
|
|
15
15
|
readonly agentId: string;
|
|
16
16
|
readonly task: string;
|
|
17
|
+
readonly agentTask?: string;
|
|
18
|
+
readonly workflowChainId?: string;
|
|
17
19
|
readonly sessionId?: string;
|
|
18
20
|
}
|
|
19
21
|
export interface QueueNtfyChatReplyInput {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/adapters/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/adapters/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { DaemonBatchManager } from './manager.js';
|
|
2
|
+
export type { CreateDaemonBatchJobInput, DaemonBatchChatRequest, DaemonBatchFallback, DaemonBatchJob, DaemonBatchJobStatus, DaemonBatchMode, DaemonBatchQueueBackend, DaemonBatchRuntimeSnapshot, DaemonBatchTickResult, } from './types.js';
|
|
3
|
+
export { DaemonBatchError } from './types.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/batch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACV,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ConfigManager } from '../config/manager.js';
|
|
2
|
+
import type { ProviderRegistry } from '../providers/registry.js';
|
|
3
|
+
import type { CreateDaemonBatchJobInput, DaemonBatchJob, DaemonBatchRuntimeSnapshot, DaemonBatchTickResult } from './types.js';
|
|
4
|
+
export declare class DaemonBatchManager {
|
|
5
|
+
private readonly options;
|
|
6
|
+
private readonly store;
|
|
7
|
+
private data;
|
|
8
|
+
private interval;
|
|
9
|
+
private ticking;
|
|
10
|
+
constructor(options: {
|
|
11
|
+
readonly configManager: Pick<ConfigManager, 'get' | 'getControlPlaneConfigDir'>;
|
|
12
|
+
readonly providerRegistry: Pick<ProviderRegistry, 'getCurrentModel' | 'getForModel' | 'getRegistered' | 'listProviders'>;
|
|
13
|
+
readonly storePath?: string;
|
|
14
|
+
});
|
|
15
|
+
start(): void;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
describeRuntime(): Promise<DaemonBatchRuntimeSnapshot>;
|
|
18
|
+
createJob(input: CreateDaemonBatchJobInput): Promise<DaemonBatchJob>;
|
|
19
|
+
getJob(jobId: string): Promise<DaemonBatchJob | null>;
|
|
20
|
+
listJobs(limit?: number): Promise<readonly DaemonBatchJob[]>;
|
|
21
|
+
cancelJob(jobId: string): Promise<DaemonBatchJob>;
|
|
22
|
+
tick(options?: {
|
|
23
|
+
readonly forceSubmit?: boolean;
|
|
24
|
+
}): Promise<DaemonBatchTickResult>;
|
|
25
|
+
private runTick;
|
|
26
|
+
private submitQueuedJobs;
|
|
27
|
+
private submitProviderBatch;
|
|
28
|
+
private pollProviderBatches;
|
|
29
|
+
private applyProviderResults;
|
|
30
|
+
private getBatchProvider;
|
|
31
|
+
private requireProviderBatchSupport;
|
|
32
|
+
private load;
|
|
33
|
+
private persist;
|
|
34
|
+
private getMode;
|
|
35
|
+
private getFallback;
|
|
36
|
+
private getQueueBackend;
|
|
37
|
+
private getNumberConfig;
|
|
38
|
+
private getBooleanConfig;
|
|
39
|
+
private getStringConfig;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/batch/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,OAAO,KAAK,EACV,yBAAyB,EACzB,cAAc,EACd,0BAA0B,EAE1B,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAuBpB,qBAAa,kBAAkB;IAO3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwC;IAC9D,OAAO,CAAC,IAAI,CAAqC;IACjD,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,OAAO,CAA+C;gBAG3C,OAAO,EAAE;QACxB,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,0BAA0B,CAAC,CAAC;QAChF,QAAQ,CAAC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,iBAAiB,GAAG,aAAa,GAAG,eAAe,GAAG,eAAe,CAAC,CAAC;QACzH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;KAC7B;IAOH,KAAK,IAAI,IAAI;IAOb,OAAO,IAAI,IAAI;IAOT,eAAe,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAkCtD,SAAS,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,cAAc,CAAC;IAyDpE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAKrD,QAAQ,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAOzD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBjD,IAAI,CAAC,OAAO,GAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,qBAAqB,CAAC;YAQ9E,OAAO;YAgBP,gBAAgB;YA2BhB,mBAAmB;YA+DnB,mBAAmB;IA6DjC,OAAO,CAAC,oBAAoB;IAoC5B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,2BAA2B;YASrB,IAAI;YAOJ,OAAO;IAIrB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,eAAe;CAIxB"}
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { PersistentStore } from '../state/persistent-store.js';
|
|
3
|
+
import { summarizeError } from '../utils/error-display.js';
|
|
4
|
+
import { DaemonBatchError } from './types.js';
|
|
5
|
+
const TERMINAL_JOB_STATUSES = new Set([
|
|
6
|
+
'completed',
|
|
7
|
+
'failed',
|
|
8
|
+
'cancelled',
|
|
9
|
+
'expired',
|
|
10
|
+
'dead_lettered',
|
|
11
|
+
]);
|
|
12
|
+
function now() {
|
|
13
|
+
return Date.now();
|
|
14
|
+
}
|
|
15
|
+
function makeEmptyStore() {
|
|
16
|
+
return { version: 1, jobs: {} };
|
|
17
|
+
}
|
|
18
|
+
function estimateJsonBytes(value) {
|
|
19
|
+
return new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
20
|
+
}
|
|
21
|
+
export class DaemonBatchManager {
|
|
22
|
+
options;
|
|
23
|
+
store;
|
|
24
|
+
data = null;
|
|
25
|
+
interval = null;
|
|
26
|
+
ticking = null;
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.store = new PersistentStore(options.storePath ?? join(options.configManager.getControlPlaneConfigDir(), 'batch-jobs.json'));
|
|
30
|
+
}
|
|
31
|
+
start() {
|
|
32
|
+
if (this.interval !== null)
|
|
33
|
+
return;
|
|
34
|
+
this.interval = setInterval(() => {
|
|
35
|
+
void this.tick().catch(() => undefined);
|
|
36
|
+
}, this.getNumberConfig('batch.tickIntervalMs', 60_000));
|
|
37
|
+
}
|
|
38
|
+
dispose() {
|
|
39
|
+
if (this.interval !== null) {
|
|
40
|
+
clearInterval(this.interval);
|
|
41
|
+
this.interval = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async describeRuntime() {
|
|
45
|
+
return {
|
|
46
|
+
mode: this.getMode(),
|
|
47
|
+
fallback: this.getFallback(),
|
|
48
|
+
queueBackend: this.getQueueBackend(),
|
|
49
|
+
cloudflare: {
|
|
50
|
+
enabled: this.getBooleanConfig('cloudflare.enabled', false),
|
|
51
|
+
freeTierMode: this.getBooleanConfig('cloudflare.freeTierMode', true),
|
|
52
|
+
accountId: this.getStringConfig('cloudflare.accountId', ''),
|
|
53
|
+
workerName: this.getStringConfig('cloudflare.workerName', 'goodvibes-batch-worker'),
|
|
54
|
+
workerBaseUrl: this.getStringConfig('cloudflare.workerBaseUrl', ''),
|
|
55
|
+
daemonBaseUrl: this.getStringConfig('cloudflare.daemonBaseUrl', ''),
|
|
56
|
+
queueName: this.getStringConfig('cloudflare.queueName', 'goodvibes-batch'),
|
|
57
|
+
deadLetterQueueName: this.getStringConfig('cloudflare.deadLetterQueueName', 'goodvibes-batch-dlq'),
|
|
58
|
+
maxQueueOpsPerDay: this.getNumberConfig('cloudflare.maxQueueOpsPerDay', 10_000),
|
|
59
|
+
},
|
|
60
|
+
limits: {
|
|
61
|
+
tickIntervalMs: this.getNumberConfig('batch.tickIntervalMs', 60_000),
|
|
62
|
+
maxDelayMs: this.getNumberConfig('batch.maxDelayMs', 5 * 60 * 1000),
|
|
63
|
+
maxJobsPerProviderBatch: this.getNumberConfig('batch.maxJobsPerProviderBatch', 100),
|
|
64
|
+
maxQueuePayloadBytes: this.getNumberConfig('batch.maxQueuePayloadBytes', 16 * 1024),
|
|
65
|
+
maxQueueMessagesPerDay: this.getNumberConfig('batch.maxQueueMessagesPerDay', 1_000),
|
|
66
|
+
},
|
|
67
|
+
supportedProviders: this.options.providerRegistry
|
|
68
|
+
.listProviders()
|
|
69
|
+
.filter((provider) => Boolean(provider.batch?.endpoints.includes('/v1/chat/completions') ||
|
|
70
|
+
provider.batch?.endpoints.includes('/v1/messages/batches')))
|
|
71
|
+
.map((provider) => provider.name)
|
|
72
|
+
.sort(),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async createJob(input) {
|
|
76
|
+
if (this.getMode() === 'off') {
|
|
77
|
+
throw new DaemonBatchError('Daemon batch mode is off.', 'BATCH_DISABLED', 409);
|
|
78
|
+
}
|
|
79
|
+
if (input.executionMode === 'live') {
|
|
80
|
+
throw new DaemonBatchError('This endpoint only accepts batch jobs. Use the live daemon route for immediate execution.', 'LIVE_REQUEST_NOT_ACCEPTED', 400);
|
|
81
|
+
}
|
|
82
|
+
if (!input.request || !Array.isArray(input.request.messages) || input.request.messages.length === 0) {
|
|
83
|
+
throw new DaemonBatchError('Batch jobs require request.messages.', 'INVALID_BATCH_REQUEST', 400);
|
|
84
|
+
}
|
|
85
|
+
const defaults = this.options.providerRegistry.getCurrentModel();
|
|
86
|
+
const provider = input.provider?.trim() || defaults.provider;
|
|
87
|
+
const model = input.model?.trim() || defaults.id;
|
|
88
|
+
const providerInstance = this.getBatchProvider(model, provider);
|
|
89
|
+
this.requireProviderBatchSupport(providerInstance, provider);
|
|
90
|
+
const payloadBytes = estimateJsonBytes(input);
|
|
91
|
+
if (input.source?.kind === 'cloudflare-queue') {
|
|
92
|
+
const maxPayload = this.getNumberConfig('batch.maxQueuePayloadBytes', 16 * 1024);
|
|
93
|
+
if (payloadBytes > maxPayload) {
|
|
94
|
+
throw new DaemonBatchError(`Cloudflare queue batch signal is ${payloadBytes} bytes, above configured limit ${maxPayload}. Store the payload in the daemon and queue only a signal.`, 'QUEUE_PAYLOAD_TOO_LARGE', 413);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const loaded = await this.load();
|
|
98
|
+
const timestamp = now();
|
|
99
|
+
const job = {
|
|
100
|
+
id: `batch-job-${crypto.randomUUID()}`,
|
|
101
|
+
provider,
|
|
102
|
+
model,
|
|
103
|
+
status: 'queued',
|
|
104
|
+
createdAt: timestamp,
|
|
105
|
+
updatedAt: timestamp,
|
|
106
|
+
request: {
|
|
107
|
+
messages: [...input.request.messages],
|
|
108
|
+
...(input.request.tools ? { tools: [...input.request.tools] } : {}),
|
|
109
|
+
...(input.request.systemPrompt ? { systemPrompt: input.request.systemPrompt } : {}),
|
|
110
|
+
...(input.request.maxTokens !== undefined ? { maxTokens: input.request.maxTokens } : {}),
|
|
111
|
+
...(input.request.reasoningEffort ? { reasoningEffort: input.request.reasoningEffort } : {}),
|
|
112
|
+
...(input.request.reasoningSummary !== undefined ? { reasoningSummary: input.request.reasoningSummary } : {}),
|
|
113
|
+
},
|
|
114
|
+
...(input.source ? { source: input.source } : {}),
|
|
115
|
+
...(input.metadata ? { metadata: { ...input.metadata } } : {}),
|
|
116
|
+
attempts: 0,
|
|
117
|
+
};
|
|
118
|
+
loaded.jobs[job.id] = job;
|
|
119
|
+
await this.persist();
|
|
120
|
+
if (input.flush) {
|
|
121
|
+
await this.tick({ forceSubmit: true });
|
|
122
|
+
return (await this.getJob(job.id)) ?? job;
|
|
123
|
+
}
|
|
124
|
+
return job;
|
|
125
|
+
}
|
|
126
|
+
async getJob(jobId) {
|
|
127
|
+
const loaded = await this.load();
|
|
128
|
+
return loaded.jobs[jobId] ?? null;
|
|
129
|
+
}
|
|
130
|
+
async listJobs(limit = 100) {
|
|
131
|
+
const loaded = await this.load();
|
|
132
|
+
return Object.values(loaded.jobs)
|
|
133
|
+
.sort((a, b) => b.createdAt - a.createdAt)
|
|
134
|
+
.slice(0, Math.max(1, Math.min(limit, 1000)));
|
|
135
|
+
}
|
|
136
|
+
async cancelJob(jobId) {
|
|
137
|
+
const loaded = await this.load();
|
|
138
|
+
const job = loaded.jobs[jobId];
|
|
139
|
+
if (!job)
|
|
140
|
+
throw new DaemonBatchError(`Batch job '${jobId}' was not found.`, 'BATCH_JOB_NOT_FOUND', 404);
|
|
141
|
+
if (TERMINAL_JOB_STATUSES.has(job.status))
|
|
142
|
+
return job;
|
|
143
|
+
if (job.status !== 'queued') {
|
|
144
|
+
throw new DaemonBatchError('Submitted provider batches are cancelled at provider-batch granularity; wait for the result or cancel the provider batch outside this per-job route.', 'BATCH_JOB_ALREADY_SUBMITTED', 409);
|
|
145
|
+
}
|
|
146
|
+
const updated = { ...job, status: 'cancelled', updatedAt: now(), completedAt: now() };
|
|
147
|
+
loaded.jobs[jobId] = updated;
|
|
148
|
+
await this.persist();
|
|
149
|
+
return updated;
|
|
150
|
+
}
|
|
151
|
+
async tick(options = {}) {
|
|
152
|
+
if (this.ticking)
|
|
153
|
+
return this.ticking;
|
|
154
|
+
this.ticking = this.runTick(options).finally(() => {
|
|
155
|
+
this.ticking = null;
|
|
156
|
+
});
|
|
157
|
+
return this.ticking;
|
|
158
|
+
}
|
|
159
|
+
async runTick(options) {
|
|
160
|
+
const result = {
|
|
161
|
+
submittedProviderBatches: 0,
|
|
162
|
+
submittedJobs: 0,
|
|
163
|
+
polledProviderBatches: 0,
|
|
164
|
+
completedJobs: 0,
|
|
165
|
+
failedJobs: 0,
|
|
166
|
+
};
|
|
167
|
+
if (this.getMode() === 'off')
|
|
168
|
+
return result;
|
|
169
|
+
const loaded = await this.load();
|
|
170
|
+
await this.submitQueuedJobs(loaded, result, options.forceSubmit === true);
|
|
171
|
+
await this.pollProviderBatches(loaded, result);
|
|
172
|
+
await this.persist();
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
async submitQueuedJobs(data, result, forceSubmit) {
|
|
176
|
+
const queued = Object.values(data.jobs).filter((job) => job.status === 'queued');
|
|
177
|
+
if (queued.length === 0)
|
|
178
|
+
return;
|
|
179
|
+
const maxDelayMs = this.getNumberConfig('batch.maxDelayMs', 5 * 60 * 1000);
|
|
180
|
+
const maxJobs = this.getNumberConfig('batch.maxJobsPerProviderBatch', 100);
|
|
181
|
+
const grouped = new Map();
|
|
182
|
+
for (const job of queued) {
|
|
183
|
+
const ageMs = now() - job.createdAt;
|
|
184
|
+
if (!forceSubmit && maxDelayMs > 0 && ageMs < maxDelayMs)
|
|
185
|
+
continue;
|
|
186
|
+
const key = `${job.provider}\u0000${job.model}`;
|
|
187
|
+
const bucket = grouped.get(key) ?? [];
|
|
188
|
+
bucket.push(job);
|
|
189
|
+
grouped.set(key, bucket);
|
|
190
|
+
}
|
|
191
|
+
for (const jobs of grouped.values()) {
|
|
192
|
+
for (let i = 0; i < jobs.length; i += maxJobs) {
|
|
193
|
+
const slice = jobs.slice(i, i + maxJobs);
|
|
194
|
+
if (slice.length === 0)
|
|
195
|
+
continue;
|
|
196
|
+
await this.submitProviderBatch(data, slice, result);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async submitProviderBatch(data, jobs, result) {
|
|
201
|
+
const first = jobs[0];
|
|
202
|
+
if (!first)
|
|
203
|
+
return;
|
|
204
|
+
try {
|
|
205
|
+
const provider = this.getBatchProvider(first.model, first.provider);
|
|
206
|
+
this.requireProviderBatchSupport(provider, first.provider);
|
|
207
|
+
const created = await provider.batch.createChatBatch({
|
|
208
|
+
requests: jobs.map((job) => ({
|
|
209
|
+
customId: job.id,
|
|
210
|
+
params: {
|
|
211
|
+
model: job.model,
|
|
212
|
+
messages: [...job.request.messages],
|
|
213
|
+
...(job.request.tools ? { tools: [...job.request.tools] } : {}),
|
|
214
|
+
...(job.request.systemPrompt ? { systemPrompt: job.request.systemPrompt } : {}),
|
|
215
|
+
...(job.request.maxTokens !== undefined ? { maxTokens: job.request.maxTokens } : {}),
|
|
216
|
+
...(job.request.reasoningEffort ? { reasoningEffort: job.request.reasoningEffort } : {}),
|
|
217
|
+
...(job.request.reasoningSummary !== undefined ? { reasoningSummary: job.request.reasoningSummary } : {}),
|
|
218
|
+
},
|
|
219
|
+
})),
|
|
220
|
+
metadata: {
|
|
221
|
+
source: 'goodvibes-sdk',
|
|
222
|
+
provider: first.provider,
|
|
223
|
+
model: first.model,
|
|
224
|
+
},
|
|
225
|
+
completionWindow: '24h',
|
|
226
|
+
});
|
|
227
|
+
const timestamp = now();
|
|
228
|
+
for (const job of jobs) {
|
|
229
|
+
data.jobs[job.id] = {
|
|
230
|
+
...job,
|
|
231
|
+
status: created.status === 'completed' ? 'running' : created.status === 'failed' ? 'failed' : 'submitted',
|
|
232
|
+
updatedAt: timestamp,
|
|
233
|
+
attempts: job.attempts + 1,
|
|
234
|
+
providerBatchId: created.providerBatchId,
|
|
235
|
+
providerBatchStatus: created.status,
|
|
236
|
+
submittedAt: timestamp,
|
|
237
|
+
...(created.status === 'failed'
|
|
238
|
+
? { completedAt: timestamp, error: { message: 'Provider failed to create batch.', raw: created.raw } }
|
|
239
|
+
: {}),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
result.submittedProviderBatches += 1;
|
|
243
|
+
result.submittedJobs += jobs.length;
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
const timestamp = now();
|
|
247
|
+
for (const job of jobs) {
|
|
248
|
+
data.jobs[job.id] = {
|
|
249
|
+
...job,
|
|
250
|
+
status: 'dead_lettered',
|
|
251
|
+
updatedAt: timestamp,
|
|
252
|
+
completedAt: timestamp,
|
|
253
|
+
attempts: job.attempts + 1,
|
|
254
|
+
error: { message: summarizeError(error) },
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
result.failedJobs += jobs.length;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async pollProviderBatches(data, result) {
|
|
261
|
+
const pendingByProviderBatch = new Map();
|
|
262
|
+
for (const job of Object.values(data.jobs)) {
|
|
263
|
+
if (!job.providerBatchId || TERMINAL_JOB_STATUSES.has(job.status))
|
|
264
|
+
continue;
|
|
265
|
+
const key = `${job.provider}\u0000${job.model}\u0000${job.providerBatchId}`;
|
|
266
|
+
const bucket = pendingByProviderBatch.get(key) ?? [];
|
|
267
|
+
bucket.push(job);
|
|
268
|
+
pendingByProviderBatch.set(key, bucket);
|
|
269
|
+
}
|
|
270
|
+
for (const jobs of pendingByProviderBatch.values()) {
|
|
271
|
+
const first = jobs[0];
|
|
272
|
+
if (!first?.providerBatchId)
|
|
273
|
+
continue;
|
|
274
|
+
try {
|
|
275
|
+
const provider = this.getBatchProvider(first.model, first.provider);
|
|
276
|
+
this.requireProviderBatchSupport(provider, first.provider);
|
|
277
|
+
const polled = await provider.batch.retrieveBatch(first.providerBatchId);
|
|
278
|
+
result.polledProviderBatches += 1;
|
|
279
|
+
const timestamp = now();
|
|
280
|
+
for (const job of jobs) {
|
|
281
|
+
data.jobs[job.id] = {
|
|
282
|
+
...job,
|
|
283
|
+
status: polled.status === 'running' || polled.status === 'submitted' ? 'running' : job.status,
|
|
284
|
+
updatedAt: timestamp,
|
|
285
|
+
providerBatchStatus: polled.status,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
if (polled.resultAvailable || polled.status === 'completed') {
|
|
289
|
+
const providerResults = await provider.batch.getResults(first.providerBatchId);
|
|
290
|
+
this.applyProviderResults(data, providerResults, result);
|
|
291
|
+
}
|
|
292
|
+
else if (polled.status === 'failed' || polled.status === 'cancelled' || polled.status === 'expired') {
|
|
293
|
+
for (const job of jobs) {
|
|
294
|
+
const status = polled.status === 'cancelled' ? 'cancelled' : polled.status === 'expired' ? 'expired' : 'failed';
|
|
295
|
+
data.jobs[job.id] = {
|
|
296
|
+
...data.jobs[job.id],
|
|
297
|
+
status,
|
|
298
|
+
updatedAt: timestamp,
|
|
299
|
+
completedAt: timestamp,
|
|
300
|
+
error: status === 'failed' ? { message: 'Provider batch failed.', raw: polled.raw } : data.jobs[job.id].error,
|
|
301
|
+
};
|
|
302
|
+
if (status === 'failed')
|
|
303
|
+
result.failedJobs += 1;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
const timestamp = now();
|
|
309
|
+
for (const job of jobs) {
|
|
310
|
+
data.jobs[job.id] = {
|
|
311
|
+
...job,
|
|
312
|
+
status: 'dead_lettered',
|
|
313
|
+
updatedAt: timestamp,
|
|
314
|
+
completedAt: timestamp,
|
|
315
|
+
error: { message: summarizeError(error) },
|
|
316
|
+
};
|
|
317
|
+
result.failedJobs += 1;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
applyProviderResults(data, providerResults, tickResult) {
|
|
323
|
+
const timestamp = now();
|
|
324
|
+
for (const providerResult of providerResults) {
|
|
325
|
+
const job = data.jobs[providerResult.customId];
|
|
326
|
+
if (!job || TERMINAL_JOB_STATUSES.has(job.status))
|
|
327
|
+
continue;
|
|
328
|
+
if (providerResult.status === 'succeeded' && providerResult.response) {
|
|
329
|
+
data.jobs[job.id] = {
|
|
330
|
+
...job,
|
|
331
|
+
status: 'completed',
|
|
332
|
+
updatedAt: timestamp,
|
|
333
|
+
completedAt: timestamp,
|
|
334
|
+
result: providerResult.response,
|
|
335
|
+
};
|
|
336
|
+
tickResult.completedJobs += 1;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
const status = providerResult.status === 'cancelled'
|
|
340
|
+
? 'cancelled'
|
|
341
|
+
: providerResult.status === 'expired'
|
|
342
|
+
? 'expired'
|
|
343
|
+
: 'failed';
|
|
344
|
+
data.jobs[job.id] = {
|
|
345
|
+
...job,
|
|
346
|
+
status,
|
|
347
|
+
updatedAt: timestamp,
|
|
348
|
+
completedAt: timestamp,
|
|
349
|
+
error: providerResult.error ?? { message: `Provider batch request ${status}.`, raw: providerResult.raw },
|
|
350
|
+
};
|
|
351
|
+
if (status === 'failed')
|
|
352
|
+
tickResult.failedJobs += 1;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
getBatchProvider(model, providerId) {
|
|
356
|
+
if (providerId === 'openai')
|
|
357
|
+
return this.options.providerRegistry.getRegistered('openai');
|
|
358
|
+
return this.options.providerRegistry.getForModel(model, providerId);
|
|
359
|
+
}
|
|
360
|
+
requireProviderBatchSupport(provider, providerId) {
|
|
361
|
+
if (!provider.batch) {
|
|
362
|
+
throw new DaemonBatchError(`Provider '${providerId}' does not expose a provider Batch API adapter.`, 'BATCH_PROVIDER_UNSUPPORTED', 409);
|
|
363
|
+
}
|
|
364
|
+
if (typeof provider.isConfigured === 'function' && !provider.isConfigured()) {
|
|
365
|
+
throw new DaemonBatchError(`Provider '${providerId}' is not configured for Batch API use. Batch API routes require provider API-key credentials.`, 'BATCH_PROVIDER_NOT_CONFIGURED', 409);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async load() {
|
|
369
|
+
if (this.data)
|
|
370
|
+
return this.data;
|
|
371
|
+
this.data = await this.store.load() ?? makeEmptyStore();
|
|
372
|
+
if (this.data.version !== 1 || !this.data.jobs)
|
|
373
|
+
this.data = makeEmptyStore();
|
|
374
|
+
return this.data;
|
|
375
|
+
}
|
|
376
|
+
async persist() {
|
|
377
|
+
if (this.data)
|
|
378
|
+
await this.store.persist(this.data);
|
|
379
|
+
}
|
|
380
|
+
getMode() {
|
|
381
|
+
const value = this.options.configManager.get('batch.mode');
|
|
382
|
+
return value === 'explicit' || value === 'eligible-by-default' ? value : 'off';
|
|
383
|
+
}
|
|
384
|
+
getFallback() {
|
|
385
|
+
const value = this.options.configManager.get('batch.fallback');
|
|
386
|
+
return value === 'fail' ? 'fail' : 'live';
|
|
387
|
+
}
|
|
388
|
+
getQueueBackend() {
|
|
389
|
+
const value = this.options.configManager.get('batch.queueBackend');
|
|
390
|
+
return value === 'cloudflare' ? 'cloudflare' : 'local';
|
|
391
|
+
}
|
|
392
|
+
getNumberConfig(key, fallback) {
|
|
393
|
+
const value = this.options.configManager.get(key);
|
|
394
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
|
|
395
|
+
}
|
|
396
|
+
getBooleanConfig(key, fallback) {
|
|
397
|
+
const value = this.options.configManager.get(key);
|
|
398
|
+
return typeof value === 'boolean' ? value : fallback;
|
|
399
|
+
}
|
|
400
|
+
getStringConfig(key, fallback) {
|
|
401
|
+
const value = this.options.configManager.get(key);
|
|
402
|
+
return typeof value === 'string' ? value : fallback;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { ChatRequest, ChatResponse, ProviderBatchStatus, ProviderMessage } from '../providers/interface.js';
|
|
2
|
+
import type { ToolDefinition } from '../types/tools.js';
|
|
3
|
+
export type DaemonBatchMode = 'off' | 'explicit' | 'eligible-by-default';
|
|
4
|
+
export type DaemonBatchFallback = 'live' | 'fail';
|
|
5
|
+
export type DaemonBatchQueueBackend = 'local' | 'cloudflare';
|
|
6
|
+
export type DaemonBatchJobStatus = 'queued' | 'submitted' | 'running' | 'completed' | 'failed' | 'cancelled' | 'expired' | 'dead_lettered';
|
|
7
|
+
export interface DaemonBatchChatRequest {
|
|
8
|
+
readonly messages: readonly ProviderMessage[];
|
|
9
|
+
readonly tools?: readonly ToolDefinition[];
|
|
10
|
+
readonly systemPrompt?: string;
|
|
11
|
+
readonly maxTokens?: number;
|
|
12
|
+
readonly reasoningEffort?: ChatRequest['reasoningEffort'];
|
|
13
|
+
readonly reasoningSummary?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface CreateDaemonBatchJobInput {
|
|
16
|
+
readonly provider?: string;
|
|
17
|
+
readonly model?: string;
|
|
18
|
+
readonly request: DaemonBatchChatRequest;
|
|
19
|
+
readonly executionMode?: 'batch' | 'live';
|
|
20
|
+
readonly source?: {
|
|
21
|
+
readonly kind: 'daemon-api' | 'cloudflare-worker' | 'cloudflare-queue' | 'automation' | 'client';
|
|
22
|
+
readonly id?: string;
|
|
23
|
+
};
|
|
24
|
+
readonly metadata?: Record<string, string>;
|
|
25
|
+
readonly flush?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface DaemonBatchJob {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly provider: string;
|
|
30
|
+
readonly model: string;
|
|
31
|
+
readonly status: DaemonBatchJobStatus;
|
|
32
|
+
readonly createdAt: number;
|
|
33
|
+
readonly updatedAt: number;
|
|
34
|
+
readonly request: DaemonBatchChatRequest;
|
|
35
|
+
readonly source?: CreateDaemonBatchJobInput['source'];
|
|
36
|
+
readonly metadata?: Record<string, string>;
|
|
37
|
+
readonly attempts: number;
|
|
38
|
+
readonly providerBatchId?: string;
|
|
39
|
+
readonly providerBatchStatus?: ProviderBatchStatus;
|
|
40
|
+
readonly submittedAt?: number;
|
|
41
|
+
readonly completedAt?: number;
|
|
42
|
+
readonly result?: ChatResponse;
|
|
43
|
+
readonly error?: {
|
|
44
|
+
readonly message: string;
|
|
45
|
+
readonly code?: string;
|
|
46
|
+
readonly raw?: unknown;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface DaemonBatchTickResult {
|
|
50
|
+
submittedProviderBatches: number;
|
|
51
|
+
submittedJobs: number;
|
|
52
|
+
polledProviderBatches: number;
|
|
53
|
+
completedJobs: number;
|
|
54
|
+
failedJobs: number;
|
|
55
|
+
}
|
|
56
|
+
export interface DaemonBatchRuntimeSnapshot {
|
|
57
|
+
readonly mode: DaemonBatchMode;
|
|
58
|
+
readonly fallback: DaemonBatchFallback;
|
|
59
|
+
readonly queueBackend: DaemonBatchQueueBackend;
|
|
60
|
+
readonly cloudflare: {
|
|
61
|
+
readonly enabled: boolean;
|
|
62
|
+
readonly freeTierMode: boolean;
|
|
63
|
+
readonly accountId: string;
|
|
64
|
+
readonly workerName: string;
|
|
65
|
+
readonly workerBaseUrl: string;
|
|
66
|
+
readonly daemonBaseUrl: string;
|
|
67
|
+
readonly queueName: string;
|
|
68
|
+
readonly deadLetterQueueName: string;
|
|
69
|
+
readonly maxQueueOpsPerDay: number;
|
|
70
|
+
};
|
|
71
|
+
readonly limits: {
|
|
72
|
+
readonly tickIntervalMs: number;
|
|
73
|
+
readonly maxDelayMs: number;
|
|
74
|
+
readonly maxJobsPerProviderBatch: number;
|
|
75
|
+
readonly maxQueuePayloadBytes: number;
|
|
76
|
+
readonly maxQueueMessagesPerDay: number;
|
|
77
|
+
};
|
|
78
|
+
readonly supportedProviders: readonly string[];
|
|
79
|
+
}
|
|
80
|
+
export interface DaemonBatchStoreData extends Record<string, unknown> {
|
|
81
|
+
version: 1;
|
|
82
|
+
jobs: Record<string, DaemonBatchJob>;
|
|
83
|
+
}
|
|
84
|
+
export declare class DaemonBatchError extends Error {
|
|
85
|
+
readonly status: number;
|
|
86
|
+
readonly code: string;
|
|
87
|
+
constructor(message: string, code: string, status?: number);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/batch/types.ts"],"names":[],"mappings":"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"}
|