@microfox/ai-worker 1.0.2 → 1.0.3
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/CHANGELOG.md +8 -0
- package/README.md +1 -2
- package/dist/{chunk-BJPQY2NJ.mjs → chunk-72XGFZCE.mjs} +61 -84
- package/dist/chunk-72XGFZCE.mjs.map +1 -0
- package/dist/{chunk-4WU5ZCHS.mjs → chunk-7LQNS2SG.mjs} +78 -334
- package/dist/chunk-7LQNS2SG.mjs.map +1 -0
- package/dist/chunk-AOXGONGI.mjs +351 -0
- package/dist/chunk-AOXGONGI.mjs.map +1 -0
- package/dist/{client-D25XR0V8.d.mts → client-BqSJQ9mZ.d.mts} +34 -18
- package/dist/{client-D25XR0V8.d.ts → client-BqSJQ9mZ.d.ts} +34 -18
- package/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +62 -83
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +5 -1
- package/dist/handler.d.mts +32 -2
- package/dist/handler.d.ts +32 -2
- package/dist/handler.js +73 -24
- package/dist/handler.js.map +1 -1
- package/dist/handler.mjs +4 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +136 -107
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -2
- package/dist/index.mjs.map +1 -1
- package/dist/queueJobStore.d.mts +53 -0
- package/dist/queueJobStore.d.ts +53 -0
- package/dist/queueJobStore.js +378 -0
- package/dist/queueJobStore.js.map +1 -0
- package/dist/queueJobStore.mjs +14 -0
- package/dist/queueJobStore.mjs.map +1 -0
- package/package.json +7 -2
- package/dist/chunk-4WU5ZCHS.mjs.map +0 -1
- package/dist/chunk-BJPQY2NJ.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -2,8 +2,10 @@ import {
|
|
|
2
2
|
dispatch,
|
|
3
3
|
dispatchLocal,
|
|
4
4
|
dispatchQueue,
|
|
5
|
+
dispatchWorker,
|
|
6
|
+
getQueueStartUrl,
|
|
5
7
|
getWorkersTriggerUrl
|
|
6
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-72XGFZCE.mjs";
|
|
7
9
|
import {
|
|
8
10
|
clearWorkersConfigCache,
|
|
9
11
|
getWorkersConfig,
|
|
@@ -12,8 +14,10 @@ import {
|
|
|
12
14
|
import {
|
|
13
15
|
SQS_MAX_DELAY_SECONDS,
|
|
14
16
|
createLambdaHandler,
|
|
17
|
+
createWorkerLogger,
|
|
15
18
|
wrapHandlerForQueue
|
|
16
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-7LQNS2SG.mjs";
|
|
20
|
+
import "./chunk-AOXGONGI.mjs";
|
|
17
21
|
import {
|
|
18
22
|
__require
|
|
19
23
|
} from "./chunk-BJTO5JO5.mjs";
|
|
@@ -366,6 +370,7 @@ function createWorker(config) {
|
|
|
366
370
|
const handlerContext = {
|
|
367
371
|
...baseContext,
|
|
368
372
|
...jobStore ? { jobStore } : {},
|
|
373
|
+
logger: createWorkerLogger(localJobId, id),
|
|
369
374
|
dispatchWorker: createLocalDispatchWorker(
|
|
370
375
|
localJobId,
|
|
371
376
|
id,
|
|
@@ -452,10 +457,13 @@ export {
|
|
|
452
457
|
createLambdaEntrypoint,
|
|
453
458
|
createLambdaHandler,
|
|
454
459
|
createWorker,
|
|
460
|
+
createWorkerLogger,
|
|
455
461
|
defineWorkerQueue,
|
|
456
462
|
dispatch,
|
|
457
463
|
dispatchLocal,
|
|
458
464
|
dispatchQueue,
|
|
465
|
+
dispatchWorker,
|
|
466
|
+
getQueueStartUrl,
|
|
459
467
|
getWorkersConfig,
|
|
460
468
|
getWorkersTriggerUrl,
|
|
461
469
|
resolveQueueUrl,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/queue.ts","../src/index.ts"],"sourcesContent":["/**\n * Queue definition and context types for worker queues.\n *\n * These types are used at code-time by .queue.ts files and at runtime\n * by the client and generated registry/queue wrappers.\n */\n\nexport interface WorkerQueueStep {\n /** Worker ID for this step. Must match an existing worker id. */\n workerId: string;\n /**\n * Optional delay (in seconds) before this step is executed.\n * Implemented via SQS DelaySeconds (0–900).\n */\n delaySeconds?: number;\n /**\n * Optional name of a mapping function exported from the .queue.ts file\n * that derives this step's input from the previous step's output and\n * the original initial input.\n */\n mapInputFromPrev?: string;\n}\n\nexport interface WorkerQueueConfig<InitialInput = any, StepOutput = any> {\n /** Stable queue identifier, e.g. \"cost-usage\". */\n id: string;\n /** Ordered list of workers forming the queue. */\n steps: WorkerQueueStep[];\n /**\n * Optional schedule for the queue (cron or rate).\n * When set, the CLI generates a queue-starter Lambda triggered by this schedule.\n * Example: 'cron(0 3 * * ? *)' for daily at 03:00 UTC.\n */\n schedule?: string | { rate: string; enabled?: boolean; input?: Record<string, any> };\n // The generic parameters are reserved for future typing improvements and\n // are intentionally unused here (config is structural at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _initialInputType?: InitialInput;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _stepOutputType?: StepOutput;\n}\n\n/**\n * Queue execution context that is embedded into job input/metadata so\n * queue-aware wrappers can determine where they are in the queue.\n */\nexport interface WorkerQueueContext<InitialInput = any> {\n id: string;\n stepIndex: number;\n initialInput: InitialInput;\n /** Queue job ID (same as first worker's jobId) for tracking progress. */\n queueJobId?: string;\n}\n\n/**\n * Identity helper for defining worker queues in .queue.ts files.\n * This is primarily for type safety and CLI discovery.\n */\nexport function defineWorkerQueue<T extends WorkerQueueConfig>(config: T): T {\n return config;\n}\n\n","/**\n * @microfox/ai-worker\n * Worker runtime for ai-router - SQS-based async agent execution\n */\n\nimport { dispatch, dispatchLocal, getWorkersTriggerUrl, type DispatchOptions, type DispatchResult } from './client.js';\nimport { createLambdaHandler, type WorkerHandler, type JobStore, type DispatchWorkerOptions, SQS_MAX_DELAY_SECONDS } from './handler.js';\nimport type { ZodType, z } from 'zod';\n\nexport * from './client.js';\nexport * from './handler.js';\nexport * from './config.js';\nexport * from './queue.js';\n\n/**\n * Schedule event configuration for a worker.\n * Supports both simple rate/cron strings and full configuration objects.\n * \n * @example Simple rate/cron\n * ```typescript\n * schedule: 'rate(2 hours)'\n * // or\n * schedule: 'cron(0 12 * * ? *)'\n * ```\n * \n * @example Full configuration\n * ```typescript\n * schedule: {\n * rate: 'rate(10 minutes)',\n * enabled: true,\n * input: { key1: 'value1' }\n * }\n * ```\n * \n * @example Multiple schedules\n * ```typescript\n * schedule: [\n * 'rate(2 hours)',\n * { rate: 'cron(0 12 * * ? *)', enabled: false }\n * ]\n * ```\n */\nexport interface ScheduleEventConfig {\n /**\n * Schedule rate using either rate() or cron() syntax.\n * Can be a string or array of strings for multiple schedules.\n * \n * @example 'rate(2 hours)' or 'cron(0 12 * * ? *)'\n * @example ['cron(0 0/4 ? * MON-FRI *)', 'cron(0 2 ? * SAT-SUN *)']\n */\n rate: string | string[];\n /**\n * Whether the schedule is enabled (default: true).\n */\n enabled?: boolean;\n /**\n * Input payload to pass to the function.\n */\n input?: Record<string, any>;\n /**\n * JSONPath expression to select part of the event data as input.\n */\n inputPath?: string;\n /**\n * Input transformer configuration for custom input mapping.\n */\n inputTransformer?: {\n inputPathsMap?: Record<string, string>;\n inputTemplate?: string;\n };\n /**\n * Name of the schedule event.\n */\n name?: string;\n /**\n * Description of the schedule event.\n */\n description?: string;\n /**\n * Method to use: 'eventBus' (default) or 'scheduler'.\n * Use 'scheduler' for higher limits (1M events vs 300).\n */\n method?: 'eventBus' | 'scheduler';\n /**\n * Timezone for the schedule (only used with method: 'scheduler').\n * @example 'America/New_York'\n */\n timezone?: string;\n}\n\nexport type ScheduleConfig = \n | string \n | ScheduleEventConfig \n | (string | ScheduleEventConfig)[];\n\n/**\n * Configuration for a worker's Lambda function deployment.\n * \n * **Best Practice**: Export this as a separate const from your worker file:\n * ```typescript\n * export const workerConfig: WorkerConfig = {\n * timeout: 900,\n * memorySize: 2048,\n * layers: ['arn:aws:lambda:${aws:region}:${aws:accountId}:layer:ffmpeg:1'],\n * schedule: 'rate(2 hours)',\n * };\n * ```\n * \n * The CLI will automatically extract it from the export. You do not need to pass it to `createWorker()`.\n */\nexport interface WorkerConfig {\n /**\n * Lambda function timeout in seconds (max 900).\n */\n timeout?: number;\n /**\n * Lambda function memory size in MB (128-10240).\n */\n memorySize?: number;\n /**\n * Optional Lambda layers ARNs to attach to this worker function.\n *\n * This is primarily used by @microfox/ai-worker-cli when generating serverless.yml.\n * Supports CloudFormation pseudo-parameters like ${aws:region} and ${aws:accountId}.\n *\n * Example:\n * layers: ['arn:aws:lambda:${aws:region}:${aws:accountId}:layer:ffmpeg:1']\n */\n layers?: string[];\n /**\n * Schedule events configuration for this worker.\n * Allows multiple schedule events to be attached to the same function.\n * \n * @example Simple rate\n * ```typescript\n * schedule: 'rate(2 hours)'\n * ```\n * \n * @example Multiple schedules\n * ```typescript\n * schedule: [\n * 'rate(2 hours)',\n * { rate: 'cron(0 12 * * ? *)', enabled: true, input: { key: 'value' } }\n * ]\n * ```\n * \n * @example Using scheduler method with timezone\n * ```typescript\n * schedule: {\n * method: 'scheduler',\n * rate: 'cron(0 0/4 ? * MON-FRI *)',\n * timezone: 'America/New_York',\n * input: { key1: 'value1' }\n * }\n * ```\n */\n schedule?: ScheduleConfig;\n\n /**\n * SQS queue settings for this worker (used by @microfox/ai-worker-cli when generating serverless.yml).\n *\n * Notes:\n * - To effectively disable retries, set `maxReceiveCount: 1` (requires DLQ; the CLI will create one).\n * - SQS does not support `maxReceiveCount: 0`.\n * - `messageRetentionPeriod` is in seconds (max 1209600 = 14 days).\n */\n sqs?: {\n /**\n * How many receives before sending to DLQ.\n * Use 1 to avoid retries.\n */\n maxReceiveCount?: number;\n /**\n * How long messages are retained in the main queue (seconds).\n */\n messageRetentionPeriod?: number;\n /**\n * Visibility timeout for the main queue (seconds).\n * If not set, CLI defaults to (worker timeout + 60s).\n */\n visibilityTimeout?: number;\n /**\n * DLQ message retention period (seconds).\n * Defaults to `messageRetentionPeriod` (or 14 days).\n */\n deadLetterMessageRetentionPeriod?: number;\n };\n}\n\nexport interface WorkerAgentConfig<INPUT_SCHEMA extends ZodType<any>, OUTPUT> {\n id: string;\n inputSchema: INPUT_SCHEMA;\n outputSchema: ZodType<OUTPUT>;\n handler: WorkerHandler<z.infer<INPUT_SCHEMA>, OUTPUT>;\n /**\n * @deprecated Prefer exporting `workerConfig` as a separate const from your worker file.\n * The CLI will automatically extract it from the export. This parameter is kept for backward compatibility.\n */\n workerConfig?: WorkerConfig;\n}\n\nexport interface WorkerAgent<INPUT_SCHEMA extends ZodType<any>, OUTPUT> {\n id: string;\n dispatch: (\n input: z.input<INPUT_SCHEMA>,\n options: DispatchOptions\n ) => Promise<DispatchResult>;\n handler: WorkerHandler<z.infer<INPUT_SCHEMA>, OUTPUT>;\n inputSchema: INPUT_SCHEMA;\n outputSchema: ZodType<OUTPUT>;\n workerConfig?: WorkerConfig;\n}\n\n/**\n * Creates a worker agent that can be dispatched to SQS/Lambda.\n *\n * In development mode (NODE_ENV === 'development' and WORKERS_LOCAL_MODE !== 'false'),\n * dispatch() will run the handler immediately in the same process.\n *\n * In production, dispatch() sends a message to SQS which triggers a Lambda function.\n *\n * @template INPUT_SCHEMA - The Zod schema type (e.g., `typeof InputSchema`).\n * Used to derive both:\n * - Pre-parse input type via `z.input<INPUT_SCHEMA>` for `dispatch()` (preserves optional fields)\n * - Parsed input type via `z.infer<INPUT_SCHEMA>` for handler (defaults applied)\n * @template OUTPUT - The output type returned by the handler. Use `z.infer<typeof OutputSchema>`.\n *\n * @param config - Worker agent configuration\n * @returns A worker agent object with a dispatch method\n *\n * @example\n * ```typescript\n * const InputSchema = z.object({\n * url: z.string().url(),\n * timeout: z.number().optional().default(5000), // optional with default\n * });\n *\n * export const worker = createWorker<typeof InputSchema, Output>({\n * // dispatch() accepts { url: string, timeout?: number } (pre-parse, optional preserved)\n * // handler receives { url: string, timeout: number } (parsed, default applied)\n * });\n * ```\n */\nexport function createWorker<INPUT_SCHEMA extends ZodType<any>, OUTPUT>(\n config: WorkerAgentConfig<INPUT_SCHEMA, OUTPUT>\n): WorkerAgent<INPUT_SCHEMA, OUTPUT> {\n const { id, inputSchema, outputSchema, handler } = config;\n\n const agent: WorkerAgent<INPUT_SCHEMA, OUTPUT> = {\n id,\n handler,\n inputSchema,\n outputSchema,\n\n async dispatch(input: z.input<INPUT_SCHEMA>, options: DispatchOptions): Promise<DispatchResult> {\n const mode = options.mode ?? 'auto';\n const envWantsLocal =\n process.env.NODE_ENV === 'development' &&\n process.env.WORKERS_LOCAL_MODE !== 'false';\n // Check if we're in local development mode\n const isLocal = mode === 'local' || (mode === 'auto' && envWantsLocal);\n\n if (isLocal) {\n // Local mode: run handler immediately\n // Parse input to apply defaults and get the final parsed type\n const parsedInput = inputSchema.parse(input);\n const localJobId = options.jobId || `local-${Date.now()}`;\n \n // Try to get direct job store access in local mode (same process as Next.js app)\n // This allows direct DB updates without needing HTTP/webhook URLs\n let directJobStore: {\n updateJob: (jobId: string, data: any) => Promise<void>;\n setJob?: (jobId: string, data: any) => Promise<void>;\n } | null = null;\n\n // Path constants for job store imports\n const nextJsPathAlias = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n\n // Reliable approach: try Next.js path alias first, then explicit env var\n // The @/ alias works at runtime in Next.js context\n const resolveJobStore = async () => {\n // Option 1: Try Next.js path alias (works in Next.js runtime context)\n try {\n const module = await import(nextJsPathAlias);\n if (module?.updateJob) {\n return { updateJob: module.updateJob, setJob: module.setJob };\n }\n } catch {\n // Path alias not available (not in Next.js context or alias not configured)\n }\n\n // Option 2: Use explicit env var if provided (for custom setups)\n if (explicitPath) {\n try {\n const module = await import(explicitPath).catch(() => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n return require(explicitPath);\n });\n if (module?.updateJob) {\n return { updateJob: module.updateJob, setJob: module.setJob };\n }\n } catch {\n // Explicit path failed\n }\n }\n\n return null;\n };\n\n directJobStore = await resolveJobStore();\n if (directJobStore) {\n console.log('[Worker] Using direct job store in local mode (no HTTP needed)');\n }\n\n // Derive job store URL from webhook URL or environment (fallback for HTTP mode)\n let jobStoreUrl: string | undefined;\n if (options.webhookUrl) {\n try {\n const webhookUrlObj = new URL(options.webhookUrl);\n jobStoreUrl = webhookUrlObj.pathname.replace(/\\/webhook$/, '');\n jobStoreUrl = `${webhookUrlObj.origin}${jobStoreUrl}`;\n } catch {\n // Invalid URL, skip job store URL\n }\n }\n jobStoreUrl = jobStoreUrl || process.env.WORKER_JOB_STORE_URL;\n\n // Create job store interface for local mode\n // Prefer direct DB access, fallback to HTTP calls if needed\n const createLocalJobStore = (\n directStore: typeof directJobStore,\n httpUrl?: string\n ): JobStore | undefined => {\n // If we have direct job store access, use it (no HTTP needed)\n if (directStore) {\n return {\n update: async (update) => {\n try {\n // Build update payload\n const updatePayload: any = {};\n \n if (update.status !== undefined) {\n updatePayload.status = update.status;\n }\n if (update.metadata !== undefined) {\n updatePayload.metadata = update.metadata;\n }\n if (update.progress !== undefined) {\n // Merge progress into metadata\n updatePayload.metadata = {\n ...updatePayload.metadata,\n progress: update.progress,\n progressMessage: update.progressMessage,\n };\n }\n if (update.output !== undefined) {\n updatePayload.output = update.output;\n }\n if (update.error !== undefined) {\n updatePayload.error = update.error;\n }\n\n await directStore.updateJob(localJobId, updatePayload);\n console.log('[Worker] Local job updated (direct DB):', {\n jobId: localJobId,\n workerId: id,\n updates: Object.keys(updatePayload),\n });\n } catch (error: any) {\n console.warn('[Worker] Failed to update local job (direct DB):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n }\n },\n get: async () => {\n try {\n // Use the same direct store that has updateJob - it should also have getJob\n if (directStore) {\n // Try to import getJob from the same module\n const nextJsPath = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n \n for (const importPath of [nextJsPath, explicitPath].filter(Boolean)) {\n try {\n const module = await import(importPath!);\n if (module?.getJob) {\n return await module.getJob(localJobId);\n }\n } catch {\n // Continue\n }\n }\n }\n return null;\n } catch (error: any) {\n console.warn('[Worker] Failed to get local job (direct DB):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n return null;\n }\n },\n appendInternalJob: async (entry: { jobId: string; workerId: string }) => {\n try {\n const nextJsPath = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n for (const importPath of [nextJsPath, explicitPath].filter(Boolean)) {\n try {\n const module = await import(importPath!);\n if (typeof module?.appendInternalJob === 'function') {\n await module.appendInternalJob(localJobId, entry);\n return;\n }\n } catch {\n // Continue\n }\n }\n } catch (error: any) {\n console.warn('[Worker] Failed to appendInternalJob (direct DB):', { localJobId, error: error?.message || String(error) });\n }\n },\n getJob: async (otherJobId: string) => {\n try {\n const nextJsPath = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n for (const importPath of [nextJsPath, explicitPath].filter(Boolean)) {\n try {\n const module = await import(importPath!);\n if (typeof module?.getJob === 'function') {\n return await module.getJob(otherJobId);\n }\n } catch {\n // Continue\n }\n }\n } catch (error: any) {\n console.warn('[Worker] Failed to getJob (direct DB):', { otherJobId, error: error?.message || String(error) });\n }\n return null;\n },\n };\n }\n\n // Fallback to HTTP calls if no direct access\n if (!httpUrl) {\n return undefined;\n }\n\n // Use HTTP calls to update job store\n return {\n update: async (update) => {\n try {\n // Build update payload\n const updatePayload: any = { jobId: localJobId, workerId: id };\n \n if (update.status !== undefined) {\n updatePayload.status = update.status;\n }\n if (update.metadata !== undefined) {\n updatePayload.metadata = update.metadata;\n }\n if (update.progress !== undefined) {\n // Merge progress into metadata\n updatePayload.metadata = {\n ...updatePayload.metadata,\n progress: update.progress,\n progressMessage: update.progressMessage,\n };\n }\n if (update.output !== undefined) {\n updatePayload.output = update.output;\n }\n if (update.error !== undefined) {\n updatePayload.error = update.error;\n }\n\n const response = await fetch(`${httpUrl}/update`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(updatePayload),\n });\n if (!response.ok) {\n throw new Error(`Job store update failed: ${response.status} ${response.statusText}`);\n }\n console.log('[Worker] Local job updated (HTTP):', {\n jobId: localJobId,\n workerId: id,\n updates: Object.keys(updatePayload),\n });\n } catch (error: any) {\n console.warn('[Worker] Failed to update local job (HTTP):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n }\n },\n get: async () => {\n try {\n // GET /api/workflows/workers/:workerId/:jobId\n const response = await fetch(`${httpUrl}/${id}/${localJobId}`, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n return null;\n }\n throw new Error(`Job store get failed: ${response.status} ${response.statusText}`);\n }\n\n return await response.json();\n } catch (error: any) {\n console.warn('[Worker] Failed to get local job (HTTP):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n return null;\n }\n },\n };\n };\n\n const jobStore = createLocalJobStore(directJobStore, jobStoreUrl);\n\n const DEFAULT_POLL_INTERVAL_MS = 2000;\n const DEFAULT_POLL_TIMEOUT_MS = 15 * 60 * 1000;\n\n const createLocalDispatchWorker = (\n parentJobId: string,\n parentWorkerId: string,\n parentContext: Record<string, any>,\n store: JobStore | undefined\n ): ((\n workerId: string,\n input: unknown,\n options?: DispatchWorkerOptions\n ) => Promise<{ jobId: string; messageId?: string; output?: unknown }>) => {\n return async (\n calleeWorkerId: string,\n input: unknown,\n options?: DispatchWorkerOptions\n ): Promise<{ jobId: string; messageId?: string; output?: unknown }> => {\n const childJobId =\n options?.jobId ||\n `job-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n const metadata = options?.metadata ?? {};\n const serializedContext: Record<string, any> = {};\n if (parentContext.requestId) serializedContext.requestId = parentContext.requestId;\n const messageBody = {\n workerId: calleeWorkerId,\n jobId: childJobId,\n input: input ?? {},\n context: serializedContext,\n webhookUrl: options?.webhookUrl,\n metadata,\n timestamp: new Date().toISOString(),\n };\n let triggerUrl: string;\n try {\n triggerUrl = getWorkersTriggerUrl();\n } catch (e: any) {\n throw new Error(\n `Local dispatchWorker requires WORKER_BASE_URL (or similar) for worker \"${calleeWorkerId}\": ${e?.message ?? e}`\n );\n }\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n const triggerKey = process.env.WORKERS_TRIGGER_API_KEY;\n if (triggerKey) headers['x-workers-trigger-key'] = triggerKey;\n\n // Fire-and-forget with delay: schedule trigger after delay, return immediately (no computation/wait in caller).\n if (options?.await !== true && options?.delaySeconds != null && options.delaySeconds > 0) {\n const sec = Math.min(SQS_MAX_DELAY_SECONDS, Math.max(0, Math.floor(options.delaySeconds)));\n const storeRef = store;\n setTimeout(() => {\n fetch(triggerUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({ workerId: calleeWorkerId, body: messageBody }),\n })\n .then(async (response) => {\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error(\n `[Worker] Delayed trigger failed for \"${calleeWorkerId}\": ${response.status} ${response.statusText}${text ? ` - ${text}` : ''}`\n );\n return;\n }\n if (storeRef?.appendInternalJob) {\n await storeRef.appendInternalJob({ jobId: childJobId, workerId: calleeWorkerId });\n }\n })\n .catch((err) => {\n console.error('[Worker] Delayed trigger error:', { calleeWorkerId, jobId: childJobId, error: err?.message ?? err });\n });\n }, sec * 1000);\n return { jobId: childJobId, messageId: undefined };\n }\n\n const response = await fetch(triggerUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({ workerId: calleeWorkerId, body: messageBody }),\n });\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(\n `Failed to trigger worker \"${calleeWorkerId}\": ${response.status} ${response.statusText}${text ? ` - ${text}` : ''}`\n );\n }\n const data = (await response.json().catch(() => ({}))) as any;\n const messageId = data?.messageId ? String(data.messageId) : `trigger-${childJobId}`;\n\n if (store?.appendInternalJob) {\n await store.appendInternalJob({ jobId: childJobId, workerId: calleeWorkerId });\n }\n\n if (options?.await && store?.getJob) {\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const pollTimeoutMs = options.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n const deadline = Date.now() + pollTimeoutMs;\n while (Date.now() < deadline) {\n const child = await store.getJob(childJobId);\n if (!child) {\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n continue;\n }\n if (child.status === 'completed') {\n return { jobId: childJobId, messageId, output: child.output };\n }\n if (child.status === 'failed') {\n const err = child.error;\n throw new Error(err?.message ?? `Child worker ${calleeWorkerId} failed`);\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n throw new Error(\n `Child worker ${calleeWorkerId} (${childJobId}) did not complete within ${pollTimeoutMs}ms`\n );\n }\n\n return { jobId: childJobId, messageId };\n };\n };\n\n // Create initial job record if we have job store access\n if (directJobStore?.setJob) {\n try {\n await directJobStore.setJob(localJobId, {\n jobId: localJobId,\n workerId: id,\n status: 'queued',\n input: parsedInput,\n metadata: options.metadata || {},\n });\n } catch (error: any) {\n console.warn('[Worker] Failed to create initial job record:', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n // Continue - job will still be created when status is updated\n }\n }\n\n const baseContext = { jobId: localJobId, workerId: id };\n const handlerContext = {\n ...baseContext,\n ...(jobStore ? { jobStore } : {}),\n dispatchWorker: createLocalDispatchWorker(\n localJobId,\n id,\n baseContext,\n jobStore\n ),\n };\n\n try {\n // Update status to running before execution\n if (jobStore) {\n await jobStore.update({ status: 'running' });\n }\n\n const output = await dispatchLocal(handler, parsedInput, handlerContext);\n\n // Update status to completed before webhook\n if (jobStore) {\n await jobStore.update({ status: 'completed', output });\n }\n\n // Only send webhook if webhookUrl is provided\n if (options.webhookUrl) {\n try {\n await fetch(options.webhookUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jobId: localJobId,\n workerId: id,\n status: 'success',\n output,\n metadata: options.metadata,\n }),\n });\n } catch (error) {\n console.warn('[Worker] Local webhook call failed:', error);\n }\n }\n\n return {\n messageId: `local-${Date.now()}`,\n status: 'queued',\n jobId: localJobId,\n };\n } catch (error: any) {\n // Update status to failed before webhook\n if (jobStore) {\n await jobStore.update({\n status: 'failed',\n error: {\n message: error.message || 'Unknown error',\n stack: error.stack,\n name: error.name || 'Error',\n },\n });\n }\n\n // Only send error webhook if webhookUrl is provided\n if (options.webhookUrl) {\n try {\n await fetch(options.webhookUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jobId: localJobId,\n workerId: id,\n status: 'error',\n error: {\n message: error.message || 'Unknown error',\n stack: error.stack,\n name: error.name || 'Error',\n },\n metadata: options.metadata,\n }),\n });\n } catch (webhookError) {\n console.warn('[Worker] Local error webhook call failed:', webhookError);\n }\n }\n throw error;\n }\n }\n\n // Production mode: dispatch to SQS\n return dispatch(id, input, inputSchema, options);\n },\n };\n\n return agent;\n}\n\n/**\n * Creates a Lambda handler entrypoint for a worker agent.\n * This is used by the deployment script to generate Lambda entrypoints.\n *\n * @param agent - The worker agent\n * @returns A Lambda handler function\n */\nexport function createLambdaEntrypoint<INPUT_SCHEMA extends ZodType<any>, OUTPUT>(\n agent: WorkerAgent<INPUT_SCHEMA, OUTPUT>\n) {\n return createLambdaHandler(agent.handler, agent.outputSchema);\n}\n"],"mappings":"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","names":["explicitPath","input","options","response"]}
|
|
1
|
+
{"version":3,"sources":["../src/queue.ts","../src/index.ts"],"sourcesContent":["/**\n * Queue definition and context types for worker queues.\n *\n * These types are used at code-time by .queue.ts files and at runtime\n * by the client and generated registry/queue wrappers.\n */\n\nexport interface WorkerQueueStep {\n /** Worker ID for this step. Must match an existing worker id. */\n workerId: string;\n /**\n * Optional delay (in seconds) before this step is executed.\n * Implemented via SQS DelaySeconds (0–900).\n */\n delaySeconds?: number;\n /**\n * Optional name of a mapping function exported from the .queue.ts file.\n * The function is called with (initialInput, previousOutputs):\n * - initialInput: original input passed to dispatchQueue (always first, for best DX).\n * - previousOutputs: array of { stepIndex, workerId, output } for steps 0..current-1.\n * Use any prior step's output; the immediate previous step is previousOutputs[previousOutputs.length - 1]?.output.\n */\n mapInputFromPrev?: string;\n}\n\nexport interface WorkerQueueConfig<InitialInput = any, StepOutput = any> {\n /** Stable queue identifier, e.g. \"cost-usage\". */\n id: string;\n /** Ordered list of workers forming the queue. */\n steps: WorkerQueueStep[];\n /**\n * Optional schedule for the queue (cron or rate).\n * When set, the CLI generates a queue-starter Lambda triggered by this schedule.\n * Example: 'cron(0 3 * * ? *)' for daily at 03:00 UTC.\n */\n schedule?: string | { rate: string; enabled?: boolean; input?: Record<string, any> };\n // The generic parameters are reserved for future typing improvements and\n // are intentionally unused here (config is structural at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _initialInputType?: InitialInput;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _stepOutputType?: StepOutput;\n}\n\n/**\n * Queue execution context that is embedded into job input/metadata so\n * queue-aware wrappers can determine where they are in the queue.\n */\nexport interface WorkerQueueContext<InitialInput = any> {\n id: string;\n stepIndex: number;\n initialInput: InitialInput;\n /** Queue job ID (same as first worker's jobId) for tracking progress. */\n queueJobId?: string;\n}\n\n/**\n * Identity helper for defining worker queues in .queue.ts files.\n * This is primarily for type safety and CLI discovery.\n */\nexport function defineWorkerQueue<T extends WorkerQueueConfig>(config: T): T {\n return config;\n}\n\n","/**\n * @microfox/ai-worker\n * Worker runtime for ai-router - SQS-based async agent execution\n */\n\nimport { dispatch, dispatchLocal, getWorkersTriggerUrl, type DispatchOptions, type DispatchResult } from './client.js';\nimport { createLambdaHandler, createWorkerLogger, type WorkerHandler, type JobStore, type DispatchWorkerOptions, SQS_MAX_DELAY_SECONDS } from './handler.js';\nimport type { ZodType, z } from 'zod';\n\nexport * from './client.js';\nexport * from './handler.js';\nexport * from './config.js';\nexport * from './queue.js';\n\n/**\n * Schedule event configuration for a worker.\n * Supports both simple rate/cron strings and full configuration objects.\n * \n * @example Simple rate/cron\n * ```typescript\n * schedule: 'rate(2 hours)'\n * // or\n * schedule: 'cron(0 12 * * ? *)'\n * ```\n * \n * @example Full configuration\n * ```typescript\n * schedule: {\n * rate: 'rate(10 minutes)',\n * enabled: true,\n * input: { key1: 'value1' }\n * }\n * ```\n * \n * @example Multiple schedules\n * ```typescript\n * schedule: [\n * 'rate(2 hours)',\n * { rate: 'cron(0 12 * * ? *)', enabled: false }\n * ]\n * ```\n */\nexport interface ScheduleEventConfig {\n /**\n * Schedule rate using either rate() or cron() syntax.\n * Can be a string or array of strings for multiple schedules.\n * \n * @example 'rate(2 hours)' or 'cron(0 12 * * ? *)'\n * @example ['cron(0 0/4 ? * MON-FRI *)', 'cron(0 2 ? * SAT-SUN *)']\n */\n rate: string | string[];\n /**\n * Whether the schedule is enabled (default: true).\n */\n enabled?: boolean;\n /**\n * Input payload to pass to the function.\n */\n input?: Record<string, any>;\n /**\n * JSONPath expression to select part of the event data as input.\n */\n inputPath?: string;\n /**\n * Input transformer configuration for custom input mapping.\n */\n inputTransformer?: {\n inputPathsMap?: Record<string, string>;\n inputTemplate?: string;\n };\n /**\n * Name of the schedule event.\n */\n name?: string;\n /**\n * Description of the schedule event.\n */\n description?: string;\n /**\n * Method to use: 'eventBus' (default) or 'scheduler'.\n * Use 'scheduler' for higher limits (1M events vs 300).\n */\n method?: 'eventBus' | 'scheduler';\n /**\n * Timezone for the schedule (only used with method: 'scheduler').\n * @example 'America/New_York'\n */\n timezone?: string;\n}\n\nexport type ScheduleConfig = \n | string \n | ScheduleEventConfig \n | (string | ScheduleEventConfig)[];\n\n/**\n * Configuration for a worker's Lambda function deployment.\n * \n * **Best Practice**: Export this as a separate const from your worker file:\n * ```typescript\n * export const workerConfig: WorkerConfig = {\n * timeout: 900,\n * memorySize: 2048,\n * layers: ['arn:aws:lambda:${aws:region}:${aws:accountId}:layer:ffmpeg:1'],\n * schedule: 'rate(2 hours)',\n * };\n * ```\n * \n * The CLI will automatically extract it from the export. You do not need to pass it to `createWorker()`.\n */\nexport interface WorkerConfig {\n /**\n * Lambda function timeout in seconds (max 900).\n */\n timeout?: number;\n /**\n * Lambda function memory size in MB (128-10240).\n */\n memorySize?: number;\n /**\n * Optional Lambda layers ARNs to attach to this worker function.\n *\n * This is primarily used by @microfox/ai-worker-cli when generating serverless.yml.\n * Supports CloudFormation pseudo-parameters like ${aws:region} and ${aws:accountId}.\n *\n * Example:\n * layers: ['arn:aws:lambda:${aws:region}:${aws:accountId}:layer:ffmpeg:1']\n */\n layers?: string[];\n /**\n * Schedule events configuration for this worker.\n * Allows multiple schedule events to be attached to the same function.\n * \n * @example Simple rate\n * ```typescript\n * schedule: 'rate(2 hours)'\n * ```\n * \n * @example Multiple schedules\n * ```typescript\n * schedule: [\n * 'rate(2 hours)',\n * { rate: 'cron(0 12 * * ? *)', enabled: true, input: { key: 'value' } }\n * ]\n * ```\n * \n * @example Using scheduler method with timezone\n * ```typescript\n * schedule: {\n * method: 'scheduler',\n * rate: 'cron(0 0/4 ? * MON-FRI *)',\n * timezone: 'America/New_York',\n * input: { key1: 'value1' }\n * }\n * ```\n */\n schedule?: ScheduleConfig;\n\n /**\n * SQS queue settings for this worker (used by @microfox/ai-worker-cli when generating serverless.yml).\n *\n * Notes:\n * - To effectively disable retries, set `maxReceiveCount: 1` (requires DLQ; the CLI will create one).\n * - SQS does not support `maxReceiveCount: 0`.\n * - `messageRetentionPeriod` is in seconds (max 1209600 = 14 days).\n */\n sqs?: {\n /**\n * How many receives before sending to DLQ.\n * Use 1 to avoid retries.\n */\n maxReceiveCount?: number;\n /**\n * How long messages are retained in the main queue (seconds).\n */\n messageRetentionPeriod?: number;\n /**\n * Visibility timeout for the main queue (seconds).\n * If not set, CLI defaults to (worker timeout + 60s).\n */\n visibilityTimeout?: number;\n /**\n * DLQ message retention period (seconds).\n * Defaults to `messageRetentionPeriod` (or 14 days).\n */\n deadLetterMessageRetentionPeriod?: number;\n };\n}\n\nexport interface WorkerAgentConfig<INPUT_SCHEMA extends ZodType<any>, OUTPUT> {\n id: string;\n inputSchema: INPUT_SCHEMA;\n outputSchema: ZodType<OUTPUT>;\n handler: WorkerHandler<z.infer<INPUT_SCHEMA>, OUTPUT>;\n /**\n * @deprecated Prefer exporting `workerConfig` as a separate const from your worker file.\n * The CLI will automatically extract it from the export. This parameter is kept for backward compatibility.\n */\n workerConfig?: WorkerConfig;\n}\n\nexport interface WorkerAgent<INPUT_SCHEMA extends ZodType<any>, OUTPUT> {\n id: string;\n dispatch: (\n input: z.input<INPUT_SCHEMA>,\n options: DispatchOptions\n ) => Promise<DispatchResult>;\n handler: WorkerHandler<z.infer<INPUT_SCHEMA>, OUTPUT>;\n inputSchema: INPUT_SCHEMA;\n outputSchema: ZodType<OUTPUT>;\n workerConfig?: WorkerConfig;\n}\n\n/**\n * Creates a worker agent that can be dispatched to SQS/Lambda.\n *\n * In development mode (NODE_ENV === 'development' and WORKERS_LOCAL_MODE !== 'false'),\n * dispatch() will run the handler immediately in the same process.\n *\n * In production, dispatch() sends a message to SQS which triggers a Lambda function.\n *\n * @template INPUT_SCHEMA - The Zod schema type (e.g., `typeof InputSchema`).\n * Used to derive both:\n * - Pre-parse input type via `z.input<INPUT_SCHEMA>` for `dispatch()` (preserves optional fields)\n * - Parsed input type via `z.infer<INPUT_SCHEMA>` for handler (defaults applied)\n * @template OUTPUT - The output type returned by the handler. Use `z.infer<typeof OutputSchema>`.\n *\n * @param config - Worker agent configuration\n * @returns A worker agent object with a dispatch method\n *\n * @example\n * ```typescript\n * const InputSchema = z.object({\n * url: z.string().url(),\n * timeout: z.number().optional().default(5000), // optional with default\n * });\n *\n * export const worker = createWorker<typeof InputSchema, Output>({\n * // dispatch() accepts { url: string, timeout?: number } (pre-parse, optional preserved)\n * // handler receives { url: string, timeout: number } (parsed, default applied)\n * });\n * ```\n */\nexport function createWorker<INPUT_SCHEMA extends ZodType<any>, OUTPUT>(\n config: WorkerAgentConfig<INPUT_SCHEMA, OUTPUT>\n): WorkerAgent<INPUT_SCHEMA, OUTPUT> {\n const { id, inputSchema, outputSchema, handler } = config;\n\n const agent: WorkerAgent<INPUT_SCHEMA, OUTPUT> = {\n id,\n handler,\n inputSchema,\n outputSchema,\n\n async dispatch(input: z.input<INPUT_SCHEMA>, options: DispatchOptions): Promise<DispatchResult> {\n const mode = options.mode ?? 'auto';\n const envWantsLocal =\n process.env.NODE_ENV === 'development' &&\n process.env.WORKERS_LOCAL_MODE !== 'false';\n // Check if we're in local development mode\n const isLocal = mode === 'local' || (mode === 'auto' && envWantsLocal);\n\n if (isLocal) {\n // Local mode: run handler immediately\n // Parse input to apply defaults and get the final parsed type\n const parsedInput = inputSchema.parse(input);\n const localJobId = options.jobId || `local-${Date.now()}`;\n \n // Try to get direct job store access in local mode (same process as Next.js app)\n // This allows direct DB updates without needing HTTP/webhook URLs\n let directJobStore: {\n updateJob: (jobId: string, data: any) => Promise<void>;\n setJob?: (jobId: string, data: any) => Promise<void>;\n } | null = null;\n\n // Path constants for job store imports\n const nextJsPathAlias = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n\n // Reliable approach: try Next.js path alias first, then explicit env var\n // The @/ alias works at runtime in Next.js context\n const resolveJobStore = async () => {\n // Option 1: Try Next.js path alias (works in Next.js runtime context)\n try {\n const module = await import(nextJsPathAlias);\n if (module?.updateJob) {\n return { updateJob: module.updateJob, setJob: module.setJob };\n }\n } catch {\n // Path alias not available (not in Next.js context or alias not configured)\n }\n\n // Option 2: Use explicit env var if provided (for custom setups)\n if (explicitPath) {\n try {\n const module = await import(explicitPath).catch(() => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n return require(explicitPath);\n });\n if (module?.updateJob) {\n return { updateJob: module.updateJob, setJob: module.setJob };\n }\n } catch {\n // Explicit path failed\n }\n }\n\n return null;\n };\n\n directJobStore = await resolveJobStore();\n if (directJobStore) {\n console.log('[Worker] Using direct job store in local mode (no HTTP needed)');\n }\n\n // Derive job store URL from webhook URL or environment (fallback for HTTP mode)\n let jobStoreUrl: string | undefined;\n if (options.webhookUrl) {\n try {\n const webhookUrlObj = new URL(options.webhookUrl);\n jobStoreUrl = webhookUrlObj.pathname.replace(/\\/webhook$/, '');\n jobStoreUrl = `${webhookUrlObj.origin}${jobStoreUrl}`;\n } catch {\n // Invalid URL, skip job store URL\n }\n }\n jobStoreUrl = jobStoreUrl || process.env.WORKER_JOB_STORE_URL;\n\n // Create job store interface for local mode\n // Prefer direct DB access, fallback to HTTP calls if needed\n const createLocalJobStore = (\n directStore: typeof directJobStore,\n httpUrl?: string\n ): JobStore | undefined => {\n // If we have direct job store access, use it (no HTTP needed)\n if (directStore) {\n return {\n update: async (update) => {\n try {\n // Build update payload\n const updatePayload: any = {};\n \n if (update.status !== undefined) {\n updatePayload.status = update.status;\n }\n if (update.metadata !== undefined) {\n updatePayload.metadata = update.metadata;\n }\n if (update.progress !== undefined) {\n // Merge progress into metadata\n updatePayload.metadata = {\n ...updatePayload.metadata,\n progress: update.progress,\n progressMessage: update.progressMessage,\n };\n }\n if (update.output !== undefined) {\n updatePayload.output = update.output;\n }\n if (update.error !== undefined) {\n updatePayload.error = update.error;\n }\n\n await directStore.updateJob(localJobId, updatePayload);\n console.log('[Worker] Local job updated (direct DB):', {\n jobId: localJobId,\n workerId: id,\n updates: Object.keys(updatePayload),\n });\n } catch (error: any) {\n console.warn('[Worker] Failed to update local job (direct DB):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n }\n },\n get: async () => {\n try {\n // Use the same direct store that has updateJob - it should also have getJob\n if (directStore) {\n // Try to import getJob from the same module\n const nextJsPath = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n \n for (const importPath of [nextJsPath, explicitPath].filter(Boolean)) {\n try {\n const module = await import(importPath!);\n if (module?.getJob) {\n return await module.getJob(localJobId);\n }\n } catch {\n // Continue\n }\n }\n }\n return null;\n } catch (error: any) {\n console.warn('[Worker] Failed to get local job (direct DB):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n return null;\n }\n },\n appendInternalJob: async (entry: { jobId: string; workerId: string }) => {\n try {\n const nextJsPath = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n for (const importPath of [nextJsPath, explicitPath].filter(Boolean)) {\n try {\n const module = await import(importPath!);\n if (typeof module?.appendInternalJob === 'function') {\n await module.appendInternalJob(localJobId, entry);\n return;\n }\n } catch {\n // Continue\n }\n }\n } catch (error: any) {\n console.warn('[Worker] Failed to appendInternalJob (direct DB):', { localJobId, error: error?.message || String(error) });\n }\n },\n getJob: async (otherJobId: string) => {\n try {\n const nextJsPath = '@/app/api/workflows/stores/jobStore';\n const explicitPath = process.env.WORKER_JOB_STORE_MODULE_PATH;\n for (const importPath of [nextJsPath, explicitPath].filter(Boolean)) {\n try {\n const module = await import(importPath!);\n if (typeof module?.getJob === 'function') {\n return await module.getJob(otherJobId);\n }\n } catch {\n // Continue\n }\n }\n } catch (error: any) {\n console.warn('[Worker] Failed to getJob (direct DB):', { otherJobId, error: error?.message || String(error) });\n }\n return null;\n },\n };\n }\n\n // Fallback to HTTP calls if no direct access\n if (!httpUrl) {\n return undefined;\n }\n\n // Use HTTP calls to update job store\n return {\n update: async (update) => {\n try {\n // Build update payload\n const updatePayload: any = { jobId: localJobId, workerId: id };\n \n if (update.status !== undefined) {\n updatePayload.status = update.status;\n }\n if (update.metadata !== undefined) {\n updatePayload.metadata = update.metadata;\n }\n if (update.progress !== undefined) {\n // Merge progress into metadata\n updatePayload.metadata = {\n ...updatePayload.metadata,\n progress: update.progress,\n progressMessage: update.progressMessage,\n };\n }\n if (update.output !== undefined) {\n updatePayload.output = update.output;\n }\n if (update.error !== undefined) {\n updatePayload.error = update.error;\n }\n\n const response = await fetch(`${httpUrl}/update`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(updatePayload),\n });\n if (!response.ok) {\n throw new Error(`Job store update failed: ${response.status} ${response.statusText}`);\n }\n console.log('[Worker] Local job updated (HTTP):', {\n jobId: localJobId,\n workerId: id,\n updates: Object.keys(updatePayload),\n });\n } catch (error: any) {\n console.warn('[Worker] Failed to update local job (HTTP):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n }\n },\n get: async () => {\n try {\n // GET /api/workflows/workers/:workerId/:jobId\n const response = await fetch(`${httpUrl}/${id}/${localJobId}`, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n return null;\n }\n throw new Error(`Job store get failed: ${response.status} ${response.statusText}`);\n }\n\n return await response.json();\n } catch (error: any) {\n console.warn('[Worker] Failed to get local job (HTTP):', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n return null;\n }\n },\n };\n };\n\n const jobStore = createLocalJobStore(directJobStore, jobStoreUrl);\n\n const DEFAULT_POLL_INTERVAL_MS = 2000;\n const DEFAULT_POLL_TIMEOUT_MS = 15 * 60 * 1000;\n\n const createLocalDispatchWorker = (\n parentJobId: string,\n parentWorkerId: string,\n parentContext: Record<string, any>,\n store: JobStore | undefined\n ): ((\n workerId: string,\n input: unknown,\n options?: DispatchWorkerOptions\n ) => Promise<{ jobId: string; messageId?: string; output?: unknown }>) => {\n return async (\n calleeWorkerId: string,\n input: unknown,\n options?: DispatchWorkerOptions\n ): Promise<{ jobId: string; messageId?: string; output?: unknown }> => {\n const childJobId =\n options?.jobId ||\n `job-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n const metadata = options?.metadata ?? {};\n const serializedContext: Record<string, any> = {};\n if (parentContext.requestId) serializedContext.requestId = parentContext.requestId;\n const messageBody = {\n workerId: calleeWorkerId,\n jobId: childJobId,\n input: input ?? {},\n context: serializedContext,\n webhookUrl: options?.webhookUrl,\n metadata,\n timestamp: new Date().toISOString(),\n };\n let triggerUrl: string;\n try {\n triggerUrl = getWorkersTriggerUrl();\n } catch (e: any) {\n throw new Error(\n `Local dispatchWorker requires WORKER_BASE_URL (or similar) for worker \"${calleeWorkerId}\": ${e?.message ?? e}`\n );\n }\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n const triggerKey = process.env.WORKERS_TRIGGER_API_KEY;\n if (triggerKey) headers['x-workers-trigger-key'] = triggerKey;\n\n // Fire-and-forget with delay: schedule trigger after delay, return immediately (no computation/wait in caller).\n if (options?.await !== true && options?.delaySeconds != null && options.delaySeconds > 0) {\n const sec = Math.min(SQS_MAX_DELAY_SECONDS, Math.max(0, Math.floor(options.delaySeconds)));\n const storeRef = store;\n setTimeout(() => {\n fetch(triggerUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({ workerId: calleeWorkerId, body: messageBody }),\n })\n .then(async (response) => {\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error(\n `[Worker] Delayed trigger failed for \"${calleeWorkerId}\": ${response.status} ${response.statusText}${text ? ` - ${text}` : ''}`\n );\n return;\n }\n if (storeRef?.appendInternalJob) {\n await storeRef.appendInternalJob({ jobId: childJobId, workerId: calleeWorkerId });\n }\n })\n .catch((err) => {\n console.error('[Worker] Delayed trigger error:', { calleeWorkerId, jobId: childJobId, error: err?.message ?? err });\n });\n }, sec * 1000);\n return { jobId: childJobId, messageId: undefined };\n }\n\n const response = await fetch(triggerUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({ workerId: calleeWorkerId, body: messageBody }),\n });\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(\n `Failed to trigger worker \"${calleeWorkerId}\": ${response.status} ${response.statusText}${text ? ` - ${text}` : ''}`\n );\n }\n const data = (await response.json().catch(() => ({}))) as any;\n const messageId = data?.messageId ? String(data.messageId) : `trigger-${childJobId}`;\n\n if (store?.appendInternalJob) {\n await store.appendInternalJob({ jobId: childJobId, workerId: calleeWorkerId });\n }\n\n if (options?.await && store?.getJob) {\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const pollTimeoutMs = options.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n const deadline = Date.now() + pollTimeoutMs;\n while (Date.now() < deadline) {\n const child = await store.getJob(childJobId);\n if (!child) {\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n continue;\n }\n if (child.status === 'completed') {\n return { jobId: childJobId, messageId, output: child.output };\n }\n if (child.status === 'failed') {\n const err = child.error;\n throw new Error(err?.message ?? `Child worker ${calleeWorkerId} failed`);\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n throw new Error(\n `Child worker ${calleeWorkerId} (${childJobId}) did not complete within ${pollTimeoutMs}ms`\n );\n }\n\n return { jobId: childJobId, messageId };\n };\n };\n\n // Create initial job record if we have job store access\n if (directJobStore?.setJob) {\n try {\n await directJobStore.setJob(localJobId, {\n jobId: localJobId,\n workerId: id,\n status: 'queued',\n input: parsedInput,\n metadata: options.metadata || {},\n });\n } catch (error: any) {\n console.warn('[Worker] Failed to create initial job record:', {\n jobId: localJobId,\n workerId: id,\n error: error?.message || String(error),\n });\n // Continue - job will still be created when status is updated\n }\n }\n\n const baseContext = { jobId: localJobId, workerId: id };\n const handlerContext = {\n ...baseContext,\n ...(jobStore ? { jobStore } : {}),\n logger: createWorkerLogger(localJobId, id),\n dispatchWorker: createLocalDispatchWorker(\n localJobId,\n id,\n baseContext,\n jobStore\n ),\n };\n\n try {\n // Update status to running before execution\n if (jobStore) {\n await jobStore.update({ status: 'running' });\n }\n\n const output = await dispatchLocal(handler, parsedInput, handlerContext);\n\n // Update status to completed before webhook\n if (jobStore) {\n await jobStore.update({ status: 'completed', output });\n }\n\n // Only send webhook if webhookUrl is provided\n if (options.webhookUrl) {\n try {\n await fetch(options.webhookUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jobId: localJobId,\n workerId: id,\n status: 'success',\n output,\n metadata: options.metadata,\n }),\n });\n } catch (error) {\n console.warn('[Worker] Local webhook call failed:', error);\n }\n }\n\n return {\n messageId: `local-${Date.now()}`,\n status: 'queued',\n jobId: localJobId,\n };\n } catch (error: any) {\n // Update status to failed before webhook\n if (jobStore) {\n await jobStore.update({\n status: 'failed',\n error: {\n message: error.message || 'Unknown error',\n stack: error.stack,\n name: error.name || 'Error',\n },\n });\n }\n\n // Only send error webhook if webhookUrl is provided\n if (options.webhookUrl) {\n try {\n await fetch(options.webhookUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jobId: localJobId,\n workerId: id,\n status: 'error',\n error: {\n message: error.message || 'Unknown error',\n stack: error.stack,\n name: error.name || 'Error',\n },\n metadata: options.metadata,\n }),\n });\n } catch (webhookError) {\n console.warn('[Worker] Local error webhook call failed:', webhookError);\n }\n }\n throw error;\n }\n }\n\n // Production mode: dispatch to SQS\n return dispatch(id, input, inputSchema, options);\n },\n };\n\n return agent;\n}\n\n/**\n * Creates a Lambda handler entrypoint for a worker agent.\n * This is used by the deployment script to generate Lambda entrypoints.\n *\n * @param agent - The worker agent\n * @returns A Lambda handler function\n */\nexport function createLambdaEntrypoint<INPUT_SCHEMA extends ZodType<any>, OUTPUT>(\n agent: WorkerAgent<INPUT_SCHEMA, OUTPUT>\n) {\n return createLambdaHandler(agent.handler, agent.outputSchema);\n}\n"],"mappings":"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","names":["explicitPath","input","options","response"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue job store for worker queues (MongoDB or Upstash Redis).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the worker_jobs pattern but optimized for queues:
|
|
5
|
+
* - MongoDB: collection `queue_jobs` (configurable via MONGODB_QUEUE_JOBS_COLLECTION)
|
|
6
|
+
* - Upstash Redis: JSON blob per queue job with compact step entries
|
|
7
|
+
*
|
|
8
|
+
* This module is runtime-only (used by Lambda workers). Next.js APIs can read
|
|
9
|
+
* the same collections/keys to show queue progress.
|
|
10
|
+
*/
|
|
11
|
+
declare function upsertInitialQueueJob(options: {
|
|
12
|
+
queueJobId: string;
|
|
13
|
+
queueId: string;
|
|
14
|
+
firstWorkerId: string;
|
|
15
|
+
firstWorkerJobId: string;
|
|
16
|
+
metadata?: Record<string, any>;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
declare function updateQueueJobStepInStore(options: {
|
|
19
|
+
queueJobId: string;
|
|
20
|
+
queueId?: string;
|
|
21
|
+
stepIndex: number;
|
|
22
|
+
workerId: string;
|
|
23
|
+
workerJobId: string;
|
|
24
|
+
status: 'running' | 'completed' | 'failed';
|
|
25
|
+
input?: unknown;
|
|
26
|
+
output?: unknown;
|
|
27
|
+
error?: {
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
declare function appendQueueJobStepInStore(options: {
|
|
32
|
+
queueJobId: string;
|
|
33
|
+
queueId?: string;
|
|
34
|
+
workerId: string;
|
|
35
|
+
workerJobId: string;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Load a queue job by ID (for mapping context: previous step outputs).
|
|
39
|
+
* Used by wrapHandlerForQueue when invoking mapInputFromPrev with previousOutputs.
|
|
40
|
+
*/
|
|
41
|
+
declare function getQueueJob(queueJobId: string): Promise<{
|
|
42
|
+
id: string;
|
|
43
|
+
queueId: string;
|
|
44
|
+
status: string;
|
|
45
|
+
steps: Array<{
|
|
46
|
+
workerId: string;
|
|
47
|
+
workerJobId: string;
|
|
48
|
+
status: string;
|
|
49
|
+
output?: unknown;
|
|
50
|
+
}>;
|
|
51
|
+
} | null>;
|
|
52
|
+
|
|
53
|
+
export { appendQueueJobStepInStore, getQueueJob, updateQueueJobStepInStore, upsertInitialQueueJob };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue job store for worker queues (MongoDB or Upstash Redis).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the worker_jobs pattern but optimized for queues:
|
|
5
|
+
* - MongoDB: collection `queue_jobs` (configurable via MONGODB_QUEUE_JOBS_COLLECTION)
|
|
6
|
+
* - Upstash Redis: JSON blob per queue job with compact step entries
|
|
7
|
+
*
|
|
8
|
+
* This module is runtime-only (used by Lambda workers). Next.js APIs can read
|
|
9
|
+
* the same collections/keys to show queue progress.
|
|
10
|
+
*/
|
|
11
|
+
declare function upsertInitialQueueJob(options: {
|
|
12
|
+
queueJobId: string;
|
|
13
|
+
queueId: string;
|
|
14
|
+
firstWorkerId: string;
|
|
15
|
+
firstWorkerJobId: string;
|
|
16
|
+
metadata?: Record<string, any>;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
declare function updateQueueJobStepInStore(options: {
|
|
19
|
+
queueJobId: string;
|
|
20
|
+
queueId?: string;
|
|
21
|
+
stepIndex: number;
|
|
22
|
+
workerId: string;
|
|
23
|
+
workerJobId: string;
|
|
24
|
+
status: 'running' | 'completed' | 'failed';
|
|
25
|
+
input?: unknown;
|
|
26
|
+
output?: unknown;
|
|
27
|
+
error?: {
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
declare function appendQueueJobStepInStore(options: {
|
|
32
|
+
queueJobId: string;
|
|
33
|
+
queueId?: string;
|
|
34
|
+
workerId: string;
|
|
35
|
+
workerJobId: string;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Load a queue job by ID (for mapping context: previous step outputs).
|
|
39
|
+
* Used by wrapHandlerForQueue when invoking mapInputFromPrev with previousOutputs.
|
|
40
|
+
*/
|
|
41
|
+
declare function getQueueJob(queueJobId: string): Promise<{
|
|
42
|
+
id: string;
|
|
43
|
+
queueId: string;
|
|
44
|
+
status: string;
|
|
45
|
+
steps: Array<{
|
|
46
|
+
workerId: string;
|
|
47
|
+
workerJobId: string;
|
|
48
|
+
status: string;
|
|
49
|
+
output?: unknown;
|
|
50
|
+
}>;
|
|
51
|
+
} | null>;
|
|
52
|
+
|
|
53
|
+
export { appendQueueJobStepInStore, getQueueJob, updateQueueJobStepInStore, upsertInitialQueueJob };
|