{"version":3,"file":"engine.mjs","names":[],"sources":["../../../../../../../ai/src/workflow/engine.ts"],"sourcesContent":["import { log } from \"@warlock.js/logger\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport type { StepSnapshot } from \"../contracts/result/step-result.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport type {\n  WorkflowReport,\n  WorkflowResult,\n} from \"../contracts/result/workflow-result.type\";\nimport type { StepDefinition } from \"../contracts/workflow/step.contract\";\nimport type { WorkflowContext } from \"../contracts/workflow/workflow-context.type\";\nimport type { WorkflowSnapshot } from \"../contracts/workflow/workflow-snapshot.type\";\nimport type {\n  WorkflowDefinition,\n  WorkflowEventHandlers,\n} from \"../contracts/workflow/workflow.contract\";\nimport {\n  AIError,\n  MaxStepsExceededError,\n  RoutingError,\n  SchemaValidationError,\n  WorkflowCancelledError,\n  WorkflowError,\n} from \"../errors\";\nimport { stampReportLineage } from \"../utils\";\nimport { createCancelledError } from \"./cancellation\";\nimport type { WorkflowEmitter } from \"./emitter\";\nimport { mapNextStep, nextDeclaredStep, resolveNextStep } from \"./router\";\nimport { runScopedEmitter } from \"./run-scoped-emitter\";\nimport { persistSnapshot } from \"./snapshot\";\nimport { cloneState, deepFreeze } from \"./state\";\nimport { executeStep, finalizeSnapshot, toAIError } from \"./step-runner\";\n\nexport { loadSnapshotForResume } from \"./snapshot\";\n\nconst DEFAULT_MAX_STEPS = 100;\nconst DEFAULT_LOOP_WARN = 5;\nconst LOG_MODULE_BASE = \"ai.workflow\";\n\ntype EngineParams<TOutput> = {\n  definition: WorkflowDefinition<any, TOutput, any, any>;\n  signature: string;\n  emitter: WorkflowEmitter;\n  input: unknown;\n  /**\n   * Request-scoped envelope, frozen and exposed as `ctx.context` to\n   * every step. Never persisted in snapshots; resume callers supply\n   * it fresh via `WorkflowResumeOptions.context`. Defaults to a\n   * frozen empty object when caller omits it.\n   */\n  context?: unknown;\n  runId: string;\n  signal?: AbortSignal;\n  executionHandlers?: WorkflowEventHandlers;\n  resumeFrom?: WorkflowSnapshot;\n  /**\n   * Opaque session identifier propagated onto every report node this\n   * run produces — including agent reports from child steps. Threaded\n   * from `WorkflowRunOptions.sessionId`. Omitted leaves the field\n   * undefined throughout the tree.\n   */\n  sessionId?: string;\n};\n\n/**\n * Main workflow driver. Walks the declared steps, handling routing,\n * cancellation, retries, parallel execution, and snapshot\n * persistence. Delegates the step lifecycle to `step-runner.ts`,\n * routing to `router.ts`, persistence to `snapshot.ts`. Never throws\n * — every failure funnels into `result.error`.\n */\nexport async function runWorkflow<TOutput>(\n  params: EngineParams<TOutput>,\n): Promise<WorkflowResult<TOutput>> {\n  const { definition, signature, input, runId, signal } = params;\n  // Bind the factory-scoped emitter to THIS run's identity. Every\n  // `emitter.emit(...)` below — and the one threaded into\n  // `executeStep` — now stamps `runId` / `rootRunId` automatically.\n  const emitter = runScopedEmitter(params.emitter, {\n    runId,\n    rootRunId: runId,\n  });\n\n  // Freeze the envelope once at run start. Default to `{}` so step\n  // code can always read `ctx.context` without an undefined guard.\n  const context = Object.freeze(params.context ?? {});\n  const maxSteps = definition.maxSteps ?? DEFAULT_MAX_STEPS;\n  const loopWarnAfter = definition.loopWarnAfter ?? DEFAULT_LOOP_WARN;\n\n  const logger = log;\n  const logModule = `${LOG_MODULE_BASE}.${definition.name}`;\n\n  const stepByName = new Map<string, StepDefinition>();\n  for (const s of definition.steps) stepByName.set(s.name, s);\n\n  const state: Record<string, unknown> = params.resumeFrom\n    ? { ...params.resumeFrom.state }\n    : {};\n  const steps: Record<string, StepSnapshot> = params.resumeFrom\n    ? { ...params.resumeFrom.steps }\n    : {};\n  const enteredCount = new Map<string, number>();\n  const usage: Usage = { input: 0, output: 0, total: 0 };\n\n  const startedAt = params.resumeFrom?.startedAt ?? new Date().toISOString();\n  const startedAtDate = new Date(startedAt);\n  const runStartPerf = performance.now();\n\n  let error: AIError | undefined;\n  let status: \"completed\" | \"failed\" | \"cancelled\" = \"completed\";\n  let cancelledAt: string | undefined;\n  let lastGoto: string | null = null;\n  // Captured when a step throws after retries exhaust (and `onFailure`\n  // didn't recover). Used to point the final snapshot's `next` at the\n  // failed step so `resume()` re-runs it after the cause is fixed.\n  let failedStepName: string | undefined;\n\n  const buildContext = (current?: {\n    state: Record<string, unknown>;\n    agentResult?: unknown;\n  }): WorkflowContext => ({\n    input,\n    context,\n    steps: steps as Readonly<Record<string, StepSnapshot>>,\n    state: current?.state ?? state,\n    agentResult: current?.agentResult as WorkflowContext[\"agentResult\"],\n    runId,\n    signal,\n    startedAt: startedAtDate,\n  });\n\n  emitter.emit(\n    \"workflow.starting\",\n    { workflowName: definition.name, input },\n    params.executionHandlers,\n  );\n  logger.info(logModule, \"starting\", \"workflow starting\", { runId });\n\n  let currentName: string | null = resolveInitialStep(\n    definition,\n    params.resumeFrom,\n  );\n  let stepCount = 0;\n\n  try {\n    while (currentName !== null) {\n      if (signal?.aborted) throw createCancelledError(signal);\n\n      stepCount += 1;\n      if (stepCount > maxSteps) {\n        throw new MaxStepsExceededError(\n          `workflow \"${definition.name}\" exceeded maxSteps=${maxSteps}`,\n          { maxSteps },\n        );\n      }\n\n      const entered = (enteredCount.get(currentName) ?? 0) + 1;\n      enteredCount.set(currentName, entered);\n      if (entered === loopWarnAfter) {\n        emitter.emit(\n          \"workflow.loop.warning\",\n          { step: currentName, enteredCount: entered, lastGoto },\n          params.executionHandlers,\n        );\n        logger.warn(logModule, \"loop.warning\", \"loop warning\", {\n          step: currentName,\n          enteredCount: entered,\n        });\n      }\n\n      const step = stepByName.get(currentName);\n      if (!step) {\n        throw new RoutingError(\n          `workflow \"${definition.name}\": unknown step \"${currentName}\"`,\n          { stepName: currentName },\n        );\n      }\n\n      const snapshot = await executeStep({\n        step,\n        state,\n        emitter,\n        executionHandlers: params.executionHandlers,\n        logger,\n        logModule,\n        signal,\n        buildContext,\n        usage,\n        workflowDefaultRetry: definition.defaultRetry,\n        runId,\n        sessionId: params.sessionId,\n      });\n\n      Object.assign(state, snapshot.state);\n      steps[step.name] = finalizeSnapshot(snapshot);\n      // Parallel children — flat-path addressing alongside nested.\n      if (snapshot.steps) {\n        for (const [childName, childSnap] of Object.entries(snapshot.steps)) {\n          steps[childName] = childSnap;\n        }\n      }\n\n      // Failure path: retries exhausted. Give `onFailure` a chance to\n      // recover; otherwise checkpoint at the failed step (so resume\n      // re-runs it) and throw — workflow halts.\n      if (snapshot.status === \"failed\" && snapshot.error) {\n        const failureRoute = await resolveFailureRoute({\n          step,\n          definition,\n          error: snapshot.error,\n          ctx: buildContext({ state, agentResult: snapshot.executionResult }),\n        });\n\n        if (failureRoute === undefined) {\n          // No recovery — persist with `next: step.name` so resume\n          // re-runs this step after the user fixes the cause.\n          const persistOutcome = await persistSnapshot({\n            definition,\n            signature,\n            runId,\n            startedAt,\n            input,\n            state,\n            steps,\n            next: step.name,\n            status: \"running\",\n          });\n          if (!persistOutcome.ok) {\n            const persistErr = toAIError(persistOutcome.error);\n            emitter.emit(\n              \"workflow.error\",\n              { error: persistErr },\n              params.executionHandlers,\n            );\n            logger.error(\n              logModule,\n              \"persist.failed\",\n              \"snapshot persist failed\",\n              {\n                step: step.name,\n                code: persistErr.code,\n                message: persistErr.message,\n              },\n            );\n          }\n          failedStepName = step.name;\n          throw snapshot.error;\n        }\n\n        // onFailure routed — workflow continues. Checkpoint at the\n        // routed target (or `null` for `end`) so resume picks up there.\n        const failureNext = failureRoute === \"end\" ? null : failureRoute;\n        if (failureNext !== null && !stepByName.has(failureNext)) {\n          throw new RoutingError(\n            `workflow \"${definition.name}\": step \"${step.name}\" onFailure routed to unknown target \"${failureNext}\"`,\n            { stepName: step.name, targetName: failureNext },\n          );\n        }\n\n        const failurePersist = await persistSnapshot({\n          definition,\n          signature,\n          runId,\n          startedAt,\n          input,\n          state,\n          steps,\n          next: failureNext,\n          status: \"running\",\n        });\n        if (!failurePersist.ok) {\n          const persistErr = toAIError(failurePersist.error);\n          emitter.emit(\n            \"workflow.error\",\n            { error: persistErr },\n            params.executionHandlers,\n          );\n          logger.error(\n            logModule,\n            \"persist.failed\",\n            \"snapshot persist failed\",\n            {\n              step: step.name,\n              code: persistErr.code,\n              message: persistErr.message,\n            },\n          );\n        }\n\n        if (signal?.aborted) throw createCancelledError(signal);\n\n        if (failureRoute === \"end\") {\n          currentName = null;\n          break;\n        }\n\n        lastGoto = failureRoute;\n        currentName = failureRoute;\n        continue;\n      }\n\n      // Resolve next step for checkpoint accuracy BEFORE routing errors\n      // bubble — so the snapshot records where resume should resume from.\n      const resolved = await resolveNextStep({\n        step,\n        definition,\n        ctx: buildContext({ state, agentResult: snapshot.executionResult }),\n      });\n\n      const nextName =\n        resolved === \"end\"\n          ? null\n          : typeof resolved === \"string\"\n            ? resolved\n            : nextDeclaredStep(definition, step.name);\n\n      // Checkpoint after every step with the resolved `next`.\n      const outcome = await persistSnapshot({\n        definition,\n        signature,\n        runId,\n        startedAt,\n        input,\n        state,\n        steps,\n        next: nextName,\n        status: \"running\",\n      });\n      if (!outcome.ok) {\n        const persistErr = toAIError(outcome.error);\n        emitter.emit(\n          \"workflow.error\",\n          { error: persistErr },\n          params.executionHandlers,\n        );\n        logger.error(logModule, \"persist.failed\", \"snapshot persist failed\", {\n          step: step.name,\n          code: persistErr.code,\n          message: persistErr.message,\n        });\n      }\n\n      if (signal?.aborted) throw createCancelledError(signal);\n\n      if (resolved === \"end\") {\n        currentName = null;\n        break;\n      }\n\n      if (typeof resolved === \"string\") {\n        if (!stepByName.has(resolved)) {\n          throw new RoutingError(\n            `workflow \"${definition.name}\": step \"${step.name}\" goto unknown target \"${resolved}\"`,\n            { stepName: step.name, targetName: resolved },\n          );\n        }\n        lastGoto = resolved;\n        currentName = resolved;\n        continue;\n      }\n\n      currentName = nextName;\n      lastGoto = currentName;\n    }\n  } catch (err) {\n    if (err instanceof WorkflowCancelledError) {\n      status = \"cancelled\";\n      cancelledAt = err.cancelledAt;\n      error = err;\n    } else if (err instanceof AIError) {\n      status = \"failed\";\n      error = err;\n    } else {\n      status = \"failed\";\n      error = new WorkflowError(\n        err instanceof Error ? err.message : String(err),\n        { cause: err },\n      );\n    }\n  }\n\n  // Note: a `failed` step always throws (caught above) unless its\n  // `onFailure` recovered the run. A `completed` workflow may still\n  // contain `failed` step snapshots — those are the recovered cases\n  // and are intentionally preserved for forensic trace.\n\n  const endedAt = new Date().toISOString();\n  const duration = performance.now() - runStartPerf;\n\n  let data: TOutput | undefined;\n  if (status === \"completed\" && definition.output) {\n    try {\n      const extracted = await definition.output.extract(\n        buildContext({ state }),\n      );\n      data = (await validateWorkflowOutput(\n        definition.output.schema,\n        extracted,\n      )) as TOutput;\n    } catch (err) {\n      status = \"failed\";\n      error =\n        err instanceof AIError\n          ? err\n          : new WorkflowError(\n              err instanceof Error ? err.message : String(err),\n              { cause: err },\n            );\n    }\n  }\n\n  // Collect child executable reports from every step that produced one —\n  // either the declarative `step.agent` field's own report, or whatever\n  // a `run` callback's ambient run-frame captured from a direct\n  // `agent.execute(...)` call (step-runner.ts's `withRunFrame` around\n  // `step.run`). Order matches step declaration; within a step, the\n  // agentReport (if any) precedes its run-captured children.\n  const children: BaseReport[] = [];\n  for (const stepName in steps) {\n    const snap = steps[stepName];\n    if (snap.agentReport) {\n      children.push(snap.agentReport);\n    }\n    if (snap.children) {\n      children.push(...snap.children);\n    }\n  }\n\n  const report: WorkflowReport = {\n    runId,\n    rootRunId: runId,\n    name: definition.name,\n    version: definition.version,\n    type: \"workflow\",\n    workflowName: definition.name,\n    signature,\n    status,\n    // Stamp the terminal error onto the report so it travels with the tree\n    // (observe path has no result envelope to fall back on). A failed `run`\n    // step's cause lives in `steps[name].error`, but the workflow-level\n    // error is what a consumer reads off the root span. Absent on success.\n    ...(error ? { error } : {}),\n    startedAt,\n    endedAt,\n    duration,\n    cancelledAt,\n    usage,\n    children,\n    steps,\n    state: deepFreeze(cloneState(state)),\n  };\n\n  // Stamp lineage on the assembled tree exactly once. Walker rewrites\n  // any inner self-roots that nested agent reports brought in (each\n  // agent's `buildResult` set its own runId as root), propagates\n  // sessionId, and writes `reportSchemaVersion` on the root.\n  stampReportLineage(report, {\n    rootRunId: runId,\n    sessionId: params.sessionId,\n  });\n\n  // On a failed run with a captured `failedStepName`, point `next` at\n  // the failed step so `resume()` re-runs it. The pre-throw checkpoint\n  // already wrote this value, but the final snapshot would otherwise\n  // overwrite it with `null` and force resume to fall back to the\n  // first non-completed step (which is the same step in practice, but\n  // less informative for tooling reading the snapshot).\n  const finalNext = status === \"failed\" ? failedStepName ?? null : null;\n\n  const finalOutcome = await persistSnapshot({\n    definition,\n    signature,\n    runId,\n    startedAt,\n    input,\n    state,\n    steps,\n    next: finalNext,\n    status,\n  });\n  if (!finalOutcome.ok) {\n    const persistErr = toAIError(finalOutcome.error);\n    emitter.emit(\n      \"workflow.error\",\n      { error: persistErr },\n      params.executionHandlers,\n    );\n    logger.error(logModule, \"persist.failed\", \"final snapshot persist failed\", {\n      code: persistErr.code,\n      message: persistErr.message,\n    });\n  }\n\n  const result: WorkflowResult<TOutput> = {\n    type: \"workflow\",\n    data,\n    report,\n    usage,\n    error,\n  };\n\n  if (status === \"cancelled\") {\n    emitter.emit(\n      \"workflow.cancelled\",\n      {\n        cancelledAt: cancelledAt ?? endedAt,\n        reason: (error as WorkflowCancelledError | undefined)?.reason ?? \"\",\n      },\n      params.executionHandlers,\n    );\n    logger.warn(logModule, \"cancelled\", \"workflow cancelled\", { runId });\n  }\n\n  if (status === \"failed\" && error) {\n    emitter.emit(\"workflow.error\", { error }, params.executionHandlers);\n    logger.error(logModule, \"error\", \"workflow failed\", {\n      runId,\n      code: error.code,\n      message: error.message,\n    });\n  }\n\n  emitter.emit(\n    \"workflow.completed\",\n    { result: result as WorkflowResult<unknown> },\n    params.executionHandlers,\n  );\n  logger.info(logModule, \"completed\", \"workflow completed\", {\n    runId,\n    status,\n    duration,\n  });\n\n  return result;\n}\n\n/**\n * Run a failed step's `onFailure` hook (if present) and translate its\n * result into a route. Returns `undefined` when the workflow should\n * halt with the original error; `\"end\"` for clean termination; or a\n * step name to redirect to. A throw inside `onFailure` is wrapped in\n * `RoutingError` — routing is authoritative, never retried.\n */\nasync function resolveFailureRoute<T>(params: {\n  step: StepDefinition;\n  definition: WorkflowDefinition<any, T, any, any>;\n  error: AIError;\n  ctx: WorkflowContext;\n}): Promise<\"end\" | string | undefined> {\n  const { step, definition, error, ctx } = params;\n  if (!step.onFailure) return undefined;\n\n  let outcome;\n  try {\n    outcome = await step.onFailure(ctx, error);\n  } catch (err) {\n    throw new RoutingError(\n      `workflow \"${definition.name}\": step \"${step.name}\" onFailure threw`,\n      { stepName: step.name, cause: err },\n    );\n  }\n  return mapNextStep(outcome);\n}\n\nfunction resolveInitialStep<T>(\n  definition: WorkflowDefinition<any, T, any, any>,\n  resumeFrom: WorkflowSnapshot | undefined,\n): string | null {\n  if (!resumeFrom) return definition.steps[0]?.name ?? null;\n\n  // Prefer the explicitly-recorded `next` (now populated on every\n  // checkpoint). Falls back to first step whose snapshot is missing\n  // or not in a terminal-success state — covers older snapshots\n  // written before `next` was wired.\n  if (\n    resumeFrom.next &&\n    definition.steps.some(s => s.name === resumeFrom.next)\n  ) {\n    return resumeFrom.next;\n  }\n\n  for (const step of definition.steps) {\n    const snap = resumeFrom.steps[step.name];\n    if (!snap || (snap.status !== \"completed\" && snap.status !== \"skipped\")) {\n      return step.name;\n    }\n  }\n\n  return null;\n}\n\nasync function validateWorkflowOutput(\n  schema: unknown,\n  value: unknown,\n): Promise<unknown> {\n  if (!schema) return value;\n\n  const result = await (\n    schema as {\n      \"~standard\": { validate: (v: unknown) => Promise<unknown> | unknown };\n    }\n  )[\"~standard\"].validate(value);\n\n  if (\n    result &&\n    typeof result === \"object\" &&\n    \"issues\" in result &&\n    (result as { issues: unknown }).issues\n  ) {\n    throw new SchemaValidationError(\n      \"workflow output failed schema validation\",\n      {\n        issues: (result as { issues: any }).issues,\n      },\n    );\n  }\n\n  return (result as { value: unknown }).value;\n}\n"],"mappings":"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"}