Anchorage API reference
    Preparing search index...

    Interface FlowsafeWorkerConfig<Env>

    interface FlowsafeWorkerConfig<Env extends FlowsafeWorkerEnv> {
        artifactStore?: (env: Env) => RunArtifactPurger | undefined;
        backgroundTasks?: BackgroundTasksCleanupConfig;
        beforeResume?: (
            context: ActorContext,
            env: Env,
            workflowId: string,
            runId: string,
            body: unknown,
        ) => Promise<void>;
        beforeStart?: (
            context: ActorContext,
            env: Env,
            workflowId: string,
            inputData: unknown,
        ) => Promise<void>;
        buildAgentRouter?: (
            resolve: ActorResolver,
            env: Env,
        ) => AgentRouter | undefined;
        buildObjectiveRouter?: (
            resolve: ActorResolver,
            env: Env,
        ) => ((request: Request) => Promise<Response | null>) | undefined;
        buildResumeRun?: (fallback: ResumeRunFn, env: Env) => ResumeRunFn;
        buildScheduleRouter?: (
            resolve: ActorResolver,
            env: Env,
        ) => ((request: Request) => Promise<Response | null>) | undefined;
        buildSignalRouter?: (
            resolve: ActorResolver,
            env: Env,
        ) => ((request: Request) => Promise<Response | null>) | undefined;
        buildVerifier: (env: Env) => TokenVerifier;
        extraPurgeDuties?: (env: Env) => Promise<Record<string, unknown>>;
        maintenance: {
            deadlineIntervalMs?: number;
            deadlineLimit?: number;
            purgeIntervalMs: number;
            sweepIntervalMs: number;
            tickIntervalMs?: number;
        };
        notify?: (env: Env) => ApprovalNotificationSink | undefined;
        preRoutes?: (
            request: Request,
            env: Env,
            ctx: FlowsafeWorkerContext,
            kit: { resolve: ActorResolver; topology: DoRunTopology },
        ) => Promise<Response | null>;
        scheduleTick?: (env: Env) => (() => Promise<unknown>) | undefined;
        storageTablePrefix?: string;
        systemPrincipalId: string;
        workflows: readonly WorkflowMeta[];
    }

    Type Parameters

    Hierarchy (View Summary)

    Index

    Properties

    artifactStore?: (env: Env) => RunArtifactPurger | undefined

    Builds the artifact purger from the current invocation's environment. When set, the retention purge deletes each expired run's R2 artifacts WITH its snapshot row. The snapshot row is the only enumerable record of a run's artifact keys, so a retention purge without this pairing strands artifacts until deployment teardown. Return the same R2-backed store used for runtime writes, or undefined for row-only purge. NOT via extraPurgeDuties: that hook runs after the rows are deleted, when the keys are already unenumerable.

    Opt-in background-task TTL cleanup. When present, the purge duty reaps terminal mastra_background_tasks rows past the TTL as its OWN failure-isolated duty — the storage-layer belt to a hosting DO's manager cleanup (which needs the DO alive). Absent => no duty, byte-identical (background tasks are opt-in). NOT via extraPurgeDuties: this needs its own try/catch and its own log fields, like every sibling purge duty.

    beforeResume?: (
        context: ActorContext,
        env: Env,
        workflowId: string,
        runId: string,
        body: unknown,
    ) => Promise<void>

    Host policy immediately before a validated raw resume reaches the run DO.

    beforeStart?: (
        context: ActorContext,
        env: Env,
        workflowId: string,
        inputData: unknown,
    ) => Promise<void>

    Host policy immediately before a validated start reaches the run DO.

    buildAgentRouter?: (resolve: ActorResolver, env: Env) => AgentRouter | undefined

    Opt-in authenticated agent catalog/run router. Structurally typed so this module does not import the server-only agent-host subpath.

    buildObjectiveRouter?: (
        resolve: ActorResolver,
        env: Env,
    ) => ((request: Request) => Promise<Response | null>) | undefined

    Opt-in goal-objective stage. Mirrors buildSignalRouter: the host builds its createObjectiveRouter (which needs the thread-state store from its D1 domains, plus its audit/maxRuns config) and returns it here, closed over the request's ActorResolver; the composer mounts it after the signal stage. Both live under /api/threads/* but do not overlap — goals use the /goal segment, signals the channel segments. INJECTED rather than built here because createObjectiveRouter lives in goals/, which imports host-kit — host-kit importing it back would cycle. Absent (or returns undefined) ⇒ no goal stage, byte-identical.

    buildResumeRun?: (fallback: ResumeRunFn, env: Env) => ResumeRunFn

    Compose approval-driven resume handling, including agent-thread targets.

    buildScheduleRouter?: (
        resolve: ActorResolver,
        env: Env,
    ) => ((request: Request) => Promise<Response | null>) | undefined

    Opt-in schedule CRUD facade. Mirrors buildSignalRouter/ buildObjectiveRouter: the host builds its createScheduleRouter (which needs the schedules store from its D1 domains + its audit/cap config) and returns it here, closed over the request's ActorResolver; the composer mounts it after the goal stage. Its /api/schedules/* routes don't overlap the others. INJECTED (not built here, typed structurally) because createScheduleRouter lives in schedules/, which transitively imports host-kit — importing it back would cycle. Absent (or returns undefined) ⇒ no schedule surface, byte-identical.

    buildSignalRouter?: (
        resolve: ActorResolver,
        env: Env,
    ) => ((request: Request) => Promise<Response | null>) | undefined

    Opt-in signal-ingestion stage. The host builds its createSignalRouter (which needs its per-thread DO namespace via createThreadTopology, plus its audit/rate/allowlist config) and returns it here, closed over the request's ActorResolver; the composer mounts it after preRoutes, ahead of approvals/runs (its /api/threads/* routes don't overlap). INJECTED rather than built here because createSignalRouter lives in signals/, which imports host-kit — host-kit importing it back would cycle. Absent (or returns undefined) => no signal stage, byte-identical.

    buildVerifier: (env: Env) => TokenVerifier

    The identity seam: env -> TokenVerifier. Called once per fetch, so hosts keep their own per-isolate memoization — re-parsing a token map on every request is pure waste, but that is the host's trade to make.

    extraPurgeDuties?: (env: Env) => Promise<Record<string, unknown>>

    Extra purge duties. The returned fields fold into the ONE combined {type:'maintenance'} log line. A throw reports the purge attempt as failed while the worker still contains it, logs a maintenance-error, and emits the combined log.

    maintenance: {
        deadlineIntervalMs?: number;
        deadlineLimit?: number;
        purgeIntervalMs: number;
        sweepIntervalMs: number;
        tickIntervalMs?: number;
    }

    Recurrence intervals for the singleton maintenance Durable Object. Every duty receives its own alarm invocation; tickIntervalMs is required when scheduleTick is configured and omitted otherwise.

    Type Declaration

    • OptionaldeadlineIntervalMs?: number

      Deadline duty cadence. Defaults to sweepIntervalMs.

    • OptionaldeadlineLimit?: number

      Maximum runs per deadline pass. Default 100.

    • purgeIntervalMs: number
    • sweepIntervalMs: number
    • OptionaltickIntervalMs?: number
    notify?: (env: Env) => ApprovalNotificationSink | undefined

    Reviewer-facing notification transport used by the same service.

    preRoutes?: (
        request: Request,
        env: Env,
        ctx: FlowsafeWorkerContext,
        kit: { resolve: ActorResolver; topology: DoRunTopology },
    ) => Promise<Response | null>

    Deployment-specific routes tried AFTER /healthz and BEFORE the approval and run routers (the showcase mounts its demo sign-in here). kit hands over the request's already-built resolver and DO topology so a pre-route can share them. Return null to fall through.

    scheduleTick?: (env: Env) => (() => Promise<unknown>) | undefined

    Opt-in schedule tick. The host builds its createScheduleTick (which needs the schedules store, its run-start seam — topology.start — and the run-cap + audit config) and returns the closure here. The composer runs it as its OWN failure-isolated alarm duty (own try/catch, own schedule-tick log line). INJECTED (not built here, structurally typed as () => Promise<unknown>) because createScheduleTick lives in schedules/, which transitively imports host-kit — host-kit importing it back would cycle. Absent (or tickIntervalMs unset) ⇒ no tick invocation.

    storageTablePrefix?: string

    Prefix used by the runner's existing Mastra snapshot table.

    systemPrincipalId: string

    System-principal id for bridge bookkeeping and alarm maintenance attribution. Requester kind is persisted separately, so ids may overlap across principal kinds.

    workflows: readonly WorkflowMeta[]

    The catalog createRunRouter serves and gates (hosts pass their metas).