{"version":3,"sources":["../src/client.ts"],"sourcesContent":["/**\n * Client for dispatching background worker jobs.\n *\n * In production, dispatching happens via the workers HTTP API:\n *   POST /workers/trigger  -> enqueues message to SQS on the workers service side\n *\n * This avoids requiring AWS credentials in your Next.js app.\n */\n\nimport * as crypto from 'crypto';\n\nimport type { ZodType, z } from 'zod';\nimport type { WorkerQueueConfig } from './queue.js';\n\nimport type { ChainContext, HitlResumeContext, LoopContext } from './queue.js';\n\nexport interface WorkerQueueRegistry {\n  getQueueById(queueId: string): WorkerQueueConfig | undefined;\n  getStepAt?(queueId: string, stepIndex: number): {\n    workerId?: string;\n    requiresApproval?: boolean;\n    hasChain?: boolean;\n    hasResume?: boolean;\n    hasLoop?: boolean;\n    hitl?: unknown;\n  } | undefined;\n  /** Build next-step input during normal chain advancement (no HITL). */\n  invokeChain?: (\n    queueId: string,\n    stepIndex: number,\n    ctx: ChainContext\n  ) => Promise<unknown> | unknown;\n  /** Build domain input when a HITL step resumes after human approval. */\n  invokeResume?: (\n    queueId: string,\n    stepIndex: number,\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    ctx: HitlResumeContext<any>\n  ) => Promise<unknown> | unknown;\n  /** Evaluate whether a looping step should run again after its output. */\n  invokeLoop?: (\n    queueId: string,\n    stepIndex: number,\n    ctx: LoopContext\n  ) => Promise<boolean> | boolean;\n}\n\nexport interface DispatchOptions {\n  /**\n   * Optional webhook callback URL to notify when the job finishes.\n   * Only called when provided. Default: no webhook (use job store / MongoDB only).\n   */\n  webhookUrl?: string;\n  /**\n   * Controls how dispatch executes.\n   * - \"auto\" (default): local inline execution in development unless WORKERS_LOCAL_MODE=false.\n   * - \"local\": force inline execution (no SQS).\n   * - \"remote\": force SQS/Lambda dispatch even in development.\n   */\n  mode?: 'auto' | 'local' | 'remote';\n  jobId?: string;\n  /**\n   * The ID of the user who triggered this job.\n   * Call getClientId() in your API route and pass the result here.\n   * If omitted, userId is not stored and not logged.\n   */\n  userId?: string;\n  metadata?: Record<string, any>;\n  /**\n   * In-memory queue registry for dispatchQueue. Required when using dispatchQueue.\n   * Pass a registry that imports from your .queue.ts definitions (works on Vercel/serverless).\n   */\n  registry?: WorkerQueueRegistry;\n  /**\n   * Optional callback to create a queue job record before dispatching.\n   * Called with queueJobId (= first worker's jobId), queueId, and firstStep.\n   */\n  onCreateQueueJob?: (params: {\n    queueJobId: string;\n    queueId: string;\n    firstStep: { workerId: string; workerJobId: string };\n    metadata?: Record<string, unknown>;\n  }) => Promise<void>;\n  /**\n   * Maximum total tokens (input + output) allowed for this job.\n   * The worker must call ctx.reportTokenUsage() after each LLM call.\n   * Throws TokenBudgetExceededError when the limit is reached.\n   * For queues, applies per-step unless overridden on the queue step config.\n   */\n  maxTokens?: number;\n}\n\nexport interface DispatchResult {\n  messageId: string;\n  status: 'queued';\n  jobId: string;\n}\n\nexport interface DispatchQueueResult extends DispatchResult {\n  queueId: string;\n}\n\nexport interface SerializedContext {\n  requestId?: string;\n  userId?: string;\n  traceId?: string;\n  [key: string]: any;\n}\n\n\n/**\n * Derives the full /workers/trigger URL from env.\n * Exported for use by local dispatchWorker (worker-to-worker in dev).\n * Server-side only; clients should use useWorkflowJob with your app's /api/workflows routes.\n *\n * Env vars:\n * - WORKER_BASE_URL: base URL of the workers service (e.g. https://.../prod)\n * - WORKERS_TRIGGER_API_URL / WORKERS_CONFIG_API_URL: legacy, still supported\n */\nexport function getWorkersTriggerUrl(): string {\n  const raw =\n    process.env.WORKER_BASE_URL ||\n    process.env.WORKERS_TRIGGER_API_URL ||\n    process.env.WORKERS_CONFIG_API_URL;\n\n  if (!raw) {\n    throw new Error(\n      'WORKER_BASE_URL is required for background workers. Set it server-side only.'\n    );\n  }\n\n  const url = new URL(raw);\n  url.search = '';\n  url.hash = '';\n\n  const path = url.pathname || '';\n\n  // If the user pointed at a specific endpoint, normalize back to the service root.\n  url.pathname = path.replace(/\\/?workers\\/(trigger|config)\\/?$/, '');\n\n  const basePath = url.pathname.replace(/\\/+$/, '');\n  url.pathname = `${basePath}/workers/trigger`.replace(/\\/+$/, '');\n\n  return url.toString();\n}\n\n/**\n * URL for the queue start endpoint (dispatch proxy). Use this so queue starts\n * go through the queue handler Lambda for easier debugging (one log stream per queue).\n */\nexport function getQueueStartUrl(queueId: string): string {\n  const raw =\n    process.env.WORKER_BASE_URL ||\n    process.env.WORKERS_TRIGGER_API_URL ||\n    process.env.WORKERS_CONFIG_API_URL;\n\n  if (!raw) {\n    throw new Error(\n      'WORKER_BASE_URL is required for background workers. Set it server-side only.'\n    );\n  }\n\n  const url = new URL(raw);\n  url.search = '';\n  url.hash = '';\n\n  const path = url.pathname || '';\n  url.pathname = path.replace(/\\/?workers\\/(trigger|config)\\/?$/, '');\n  const basePath = url.pathname.replace(/\\/+$/, '');\n  const safeSegment = encodeURIComponent(queueId);\n  url.pathname = `${basePath}/queues/${safeSegment}/start`.replace(/\\/+$/, '');\n\n  return url.toString();\n}\n\n/**\n * Derives a stable worker API key from a projectId.\n *\n * This is the zero-config fallback used when no explicit `WORKERS_API_KEY`\n * (or legacy `WORKERS_TRIGGER_API_KEY` / `WORKERS_CONFIG_API_KEY`) is set. The\n * same formula is used by `@microfox/ai-worker-cli` at build time when it writes\n * the key into the deployed Lambda env, so both sides resolve the same value.\n *\n * The raw projectId is never sent as the header value — only this hash.\n */\nexport function deriveWorkersApiKey(projectId: string): string {\n  return crypto\n    .createHash('sha256')\n    .update('microfox-workers:' + projectId)\n    .digest('hex');\n}\n\n/**\n * Resolve the key to send on `x-workers-trigger-key` for /workers/trigger and\n * /queues/{id}/start. Precedence: explicit per-endpoint key → unified\n * `WORKERS_API_KEY` → projectId-derived (MICROFOX_PROJECT_ID). Returns undefined\n * when nothing resolves (the deployed endpoints are then public).\n */\nexport function resolveWorkersTriggerKey(): string | undefined {\n  const explicit =\n    process.env.WORKERS_TRIGGER_API_KEY || process.env.WORKERS_API_KEY;\n  if (explicit && explicit.trim()) return explicit.trim();\n  const projectId = process.env.MICROFOX_PROJECT_ID;\n  if (projectId && projectId.trim()) return deriveWorkersApiKey(projectId.trim());\n  return undefined;\n}\n\n/**\n * Resolve the key to send on `x-workers-config-key` for /workers/config.\n * Same precedence as {@link resolveWorkersTriggerKey} but with the config key.\n */\nexport function resolveWorkersConfigKey(): string | undefined {\n  const explicit =\n    process.env.WORKERS_CONFIG_API_KEY || process.env.WORKERS_API_KEY;\n  if (explicit && explicit.trim()) return explicit.trim();\n  const projectId = process.env.MICROFOX_PROJECT_ID;\n  if (projectId && projectId.trim()) return deriveWorkersApiKey(projectId.trim());\n  return undefined;\n}\n\n/**\n * Serializes context data for transmission to Lambda.\n * Only serializes safe, JSON-compatible properties.\n */\nfunction serializeContext(ctx: any): SerializedContext {\n  const serialized: SerializedContext = {};\n\n  if (ctx.requestId) {\n    serialized.requestId = ctx.requestId;\n  }\n\n  if (ctx.userId) {\n    serialized.userId = ctx.userId;\n  }\n\n  // Extract any additional serializable metadata\n  if (ctx.metadata && typeof ctx.metadata === 'object') {\n    Object.assign(serialized, ctx.metadata);\n  }\n\n  // Allow custom context serialization via a helper property\n  if (ctx._serializeContext && typeof ctx._serializeContext === 'function') {\n    const custom = ctx._serializeContext();\n    Object.assign(serialized, custom);\n  }\n\n  return serialized;\n}\n\n\n/**\n * Dispatches a background worker job to SQS.\n *\n * @param workerId - The ID of the worker to dispatch\n * @param input - The input data for the worker (will be validated against inputSchema)\n * @param inputSchema - Zod schema for input validation\n * @param options - Dispatch options including webhook URL\n * @param ctx - Optional context object (only serializable parts will be sent)\n * @returns Promise resolving to dispatch result with messageId and jobId\n */\nexport async function dispatch<INPUT_SCHEMA extends ZodType<any>>(\n  workerId: string,\n  input: z.input<INPUT_SCHEMA>,\n  inputSchema: INPUT_SCHEMA,\n  options: DispatchOptions,\n  ctx?: any\n): Promise<DispatchResult> {\n  // Validate input against schema\n  const validatedInput = inputSchema.parse(input);\n\n  // Generate job ID if not provided\n  const jobId =\n    options.jobId || `job-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n  // Resolve /workers/trigger endpoint URL\n  const triggerUrl = getWorkersTriggerUrl();\n\n  // Serialize context (only safe, JSON-compatible parts)\n  const serializedContext = ctx ? serializeContext(ctx) : {};\n\n  // Attach userId if explicitly provided in options or context.\n  const userId = options.userId ?? (ctx?.userId as string | undefined);\n  if (userId) serializedContext.userId = userId;\n\n  // Job updates use MongoDB only; never pass jobStoreUrl/origin URL.\n  const messageBody = {\n    workerId,\n    jobId,\n    input: validatedInput,\n    context: serializedContext,\n    webhookUrl: options.webhookUrl,\n    metadata: options.metadata || {},\n    timestamp: new Date().toISOString(),\n    ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n  };\n\n  const headers: Record<string, string> = {\n    'Content-Type': 'application/json',\n  };\n  const triggerKey = resolveWorkersTriggerKey();\n  if (triggerKey) {\n    headers['x-workers-trigger-key'] = triggerKey;\n  }\n\n  const response = await fetch(triggerUrl, {\n    method: 'POST',\n    headers,\n    body: JSON.stringify({\n      workerId,\n      body: messageBody,\n    }),\n  });\n\n  if (!response.ok) {\n    const text = await response.text().catch(() => '');\n    throw new Error(\n      `Failed to trigger worker \"${workerId}\": ${response.status} ${response.statusText}${text ? ` - ${text}` : ''}`\n    );\n  }\n\n  const data = (await response.json().catch(() => ({}))) as any;\n  const messageId = data?.messageId ? String(data.messageId) : `trigger-${jobId}`;\n\n  return {\n    messageId,\n    status: 'queued',\n    jobId,\n  };\n}\n\n/**\n * Dispatch a worker by ID without importing the worker module.\n * Sends to the workers trigger API (WORKER_BASE_URL). No input schema validation at call site.\n *\n * @param workerId - The worker ID (e.g. 'echo', 'data-processor')\n * @param input - Input payload (object or undefined)\n * @param options - Optional jobId, webhookUrl, metadata\n * @param ctx - Optional context (serializable parts sent in the request)\n * @returns Promise resolving to { messageId, status: 'queued', jobId }\n */\nexport async function dispatchWorker(\n  workerId: string,\n  input?: Record<string, unknown>,\n  options: DispatchOptions = {},\n  ctx?: any\n): Promise<DispatchResult> {\n  const jobId =\n    options.jobId || `job-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  const triggerUrl = getWorkersTriggerUrl();\n  const serializedContext = ctx ? serializeContext(ctx) : {};\n  const userId = options.userId ?? (ctx?.userId as string | undefined);\n  if (userId) serializedContext.userId = userId;\n  const messageBody = {\n    workerId,\n    jobId,\n    input: input ?? {},\n    context: serializedContext,\n    webhookUrl: options.webhookUrl,\n    metadata: options.metadata || {},\n    timestamp: new Date().toISOString(),\n    ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n  };\n  const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n  const triggerKey = resolveWorkersTriggerKey();\n  if (triggerKey) headers['x-workers-trigger-key'] = triggerKey;\n  const response = await fetch(triggerUrl, {\n    method: 'POST',\n    headers,\n    body: JSON.stringify({ workerId, body: messageBody }),\n  });\n  if (!response.ok) {\n    const text = await response.text().catch(() => '');\n    throw new Error(\n      `Failed to trigger worker \"${workerId}\": ${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-${jobId}`;\n  return { messageId, status: 'queued', jobId };\n}\n\n/**\n * Local development mode: runs the handler immediately in the same process.\n * This bypasses SQS and Lambda for faster iteration during development.\n *\n * @param handler - The worker handler function\n * @param input - The input data\n * @param ctx - The context object\n * @returns The handler result\n */\nexport async function dispatchLocal<INPUT, OUTPUT>(\n  handler: (params: { input: INPUT; ctx: any }) => Promise<OUTPUT>,\n  input: INPUT,\n  ctx?: any\n): Promise<OUTPUT> {\n  return handler({ input, ctx: ctx || {} });\n}\n\n/**\n * Dispatches a queue by ID. POSTs to the queue-start API; the queue-start handler creates the queue job.\n * Pass the first worker's input directly (no registry required).\n */\nexport async function dispatchQueue<InitialInput = any>(\n  queueId: string,\n  initialInput?: InitialInput,\n  options: DispatchOptions = {},\n  _ctx?: any\n): Promise<DispatchQueueResult> {\n  const jobId =\n    options.jobId || `job-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  const queueStartUrl = getQueueStartUrl(queueId);\n  const normalizedInput =\n    initialInput !== null && typeof initialInput === 'object'\n      ? (initialInput as Record<string, unknown>)\n      : { value: initialInput };\n  const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n  const triggerKey = resolveWorkersTriggerKey();\n  if (triggerKey) headers['x-workers-trigger-key'] = triggerKey;\n  const userId = options.userId ?? (_ctx?.userId as string | undefined);\n  const response = await fetch(queueStartUrl, {\n    method: 'POST',\n    headers,\n    body: JSON.stringify({\n      input: normalizedInput,\n      initialInput: normalizedInput,\n      metadata: options.metadata ?? {},\n      jobId,\n      ...(userId ? { userId } : {}),\n      ...(options.webhookUrl ? { webhookUrl: options.webhookUrl } : {}),\n    }),\n  });\n  if (!response.ok) {\n    const text = await response.text().catch(() => '');\n    throw new Error(\n      `Failed to start queue \"${queueId}\": ${response.status} ${response.statusText}${text ? ` - ${text}` : ''}`\n    );\n  }\n  const data = (await response.json().catch(() => ({}))) as any;\n  const messageId = data?.messageId ?? data?.jobId ?? `queue-${jobId}`;\n  return { queueId, messageId, status: 'queued', jobId };\n}\n\n"],"mappings":"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","names":[]}