Anchorage API reference
    Preparing search index...

    Class FlowsafeDurableAgent<TAgentId, TTools, TOutput>

    A DurableAgent whose loop runs through RunnerRuntime rather than the base createRun + run.start. Construct via createFlowsafeDurableAgent so the loop workflow is registered on the runtime.

    Type Parameters

    • TAgentId extends string = string
    • TTools extends ToolsInput = ToolsInput
    • TOutput = undefined

    Hierarchy

    Index

    Constructors

    Properties

    "[RUNTIME_DRIVEN_AGENT]": true

    The runtime-driven brand the thread-Durable-Object signal wake requires (see RUNTIME_DRIVEN_AGENT). A unique symbol field, so it cannot collide with an inherited property and a plain Agent never carries it.

    Methods

    • Refuse declaring schedules. The base forwards them to the wrapped agent, which a Mastra schedule worker fires outside RunnerRuntime: the fourth ground reached by installation.

      Signature caveat: the parameter is unknown rather than core's DeclaredAgentSchedule[], which it satisfies without depending on method bivariance.

      Parameters

      • _schedules: unknown

      Returns never

    • Refuse Mastra registration. Mastra.addAgent calls this first, so the refusal throws before the registry write and before the loop workflow is added to that Mastra.

      Signature caveat: the parameter is unknown rather than core's Mastra, which it satisfies without depending on method bivariance.

      Parameters

      • _mastra: unknown

      Returns never

    • Refuse memory installation after construction under the fifth ground.

      Signature caveat: unknown accepts core's memory parameter without depending on method bivariance.

      Parameters

      • _memory: unknown

      Returns never

    • Refuse pub/sub installation after construction under the fifth ground.

      Signature caveat: unknown accepts core's pub/sub parameter without depending on method bivariance.

      Parameters

      • _pubsub: unknown

      Returns never

    • Refuse the thread-runtime target swap. It sets one private field that the thread-runtime paths resolve their target through, falling back to this; the refusal in BLOCKED_RUN_ENTRIES names those paths, for the core it is written against. So the containment those inherited members rely on is virtual dispatch on this, and one call to this setter moves every run they start, and their replay targets with them, onto an agent with none of these overrides in the chain. That is the fourth ground reached by installing a second execution surface rather than by calling one.

      Signature caveat: the parameter is unknown rather than core's Agent<any, any, any, any>. unknown satisfies that base without depending on method bivariance.

      Parameters

      • _agent: unknown

      Returns never

    • Refuse the network tool-approval resume. It is a one-line forward to FlowsafeDurableAgent.resumeNetwork; blocking it here closes the same door from the side a tool-approval caller reaches for.

      Parameters

      • _options: Omit<MultiPrimitiveExecutionOptions, "runId"> & {}

      Returns Promise<never>

    • Refuse Mastra's own tool-approval resume. Tool approval in FlowSafe is a decided ApprovalRecord resumed through the approval-decision path, which mints the leg's connector grant; approveToolCall() funnels into resumeStream() -> resume() and mints nothing.

      Parameters

      • _options: {} & Record<string, any>

      Returns Promise<never>

    • The 1.53.0 generate-shaped tool-approval entries. They funnel into resumeGenerate() -> resume(), so they are the same entry point with a different return type.

      Signature caveat for each: the base method is GENERIC in its OUTPUT type, which Parameters<> cannot carry, so the parameter type below is hand-written rather than derived. Re-check it against the base on every peer bump — nothing here fails if core changes the shape.

      Type Parameters

      • OUTPUT = undefined

      Parameters

      • _options: {} & Partial<ObservabilityContext> & (
            [NonNullable<OUTPUT>] extends [never] ? {} : OUTPUT extends {} ? {} : {}
        ) & { runId: string; toolCallId?: string }

      Returns Promise<never>

    • The decline half of FlowsafeDurableAgent.approveToolCallGenerate, including its hand-written-signature caveat.

      Type Parameters

      • OUTPUT = undefined

      Parameters

      • _options: {} & Partial<ObservabilityContext> & (
            [NonNullable<OUTPUT>] extends [never] ? {} : OUTPUT extends {} ? {} : {}
        ) & { runId: string; toolCallId?: string }

      Returns Promise<never>

    • Refuse core's terminal snapshot cleanup. Its only call sites are the base executeWorkflow (overridden here), the blocked resume() and the blocked recover(), so nothing this class drives reaches it; blocking keeps the snapshot rows — which deployment-scoped retention purge owns — from being dropped out from under that owner by a future internal caller.

      The override keeps core's best-effort deletion from taking ownership of these rows if an internal execution path reaches the cleanup method.

      Parameters

      • _runId: string

      Returns Promise<never>

    • Drive the durable-agentic-loop through RunnerRuntime instead of the base createRun + run.start. stream()/generate() have already parked the non-serializables (model/tools/messageList) on the in-process run registry keyed by this runId, so the loop the runtime starts resolves them in-isolate while the runtime mints the per-leg grant context. The runId guard here is defense in depth — the public boundary (stream/generate) already enforced the host-owned run-ID rule; this catches any future internal caller.

      Parameters

      • runId: string
      • workflowInput: DurableAgenticWorkflowInput

      Returns Promise<void>

    • Refuse the AI SDK v4 legacy execution path. generateLegacy() forwards into AgentLegacyHandler, which converts and RUNS the agent's tools while bypassing RunnerRuntime entirely, mints its own run id when the caller omits one, and skips requireAgentExecutionFGA — the authorization gate every SUPPORTED entry point calls, so this would run the agent without it. (The network family skips that gate too; neither is unique in doing so.) It persists no workflow run state, which is why it is refused on those grounds rather than as a re-drive.

      Signature caveat: overloaded and generic in OUTPUT on the base, so this signature is hand-derived and must be re-checked on every peer bump.

      Parameters

      • _messages: MessageListInput
      • Optional_args: AgentGenerateOptions<undefined, JSONSchema7 | ZodSchema> & { output?: undefined; experimental_output?: JSONSchema7 | ZodSchema | undefined; model?: DynamicArgument<...> | undefined; }

      Returns Promise<never>

    • Refuse core's recovery discovery API. listActiveRuns() enumerates listWorkflowRuns({ workflowName: 'durable-agentic-loop', status: 'running' }) narrowed by agentId plus the optional threadId/resourceId filters the CALLER supplies, so it never consults the host topology's per-principal run-ownership checks (resourceAccess().owner('run', …)) and hands the caller run ids, thread ids and resource ids for runs it does not own. Host run listing is the topology's job, where ownership is checked.

      Parameters

      • Optional_options: DurableAgentListActiveRunsOptions

      Returns Promise<never>

    • Refuse the thread-level run enumerator. listActiveThreadRuns() takes no arguments and returns a runId plus the resourceId and threadId parsed out of the key for every thread on the pubsub instance with a run in flight, and core keys that state by pubsub instance rather than by agent — so it is the same discovery ground as FlowsafeDurableAgent.listActiveRuns with the last scoping gone. The in-process sibling getActiveThreadRunId() stays inherited because it makes the caller name the (resourceId, threadId) pair it confirms.

      Signature caveat, and the reason this one is not async: the base declares it SYNCHRONOUS (listActiveThreadRuns(): ActiveThreadRun[]), so an async … Promise<never> refusal would not be assignable to it. A re-check for a peer bump.

      Returns never

    • Refuse the Agent-level analogue of FlowsafeDurableAgent.listActiveRuns. listSuspendedRuns() reads the workflows store directly — listWorkflowRuns({ workflowName: 'agentic-loop', status: 'suspended' }) — and narrows by agentId plus the optional threadId/resourceId filters the CALLER supplies, the same scoping listActiveRuns() applies. Same ground too: an unfiltered call returns run, thread and resource ids across every principal that shares the agent.

      Parameters

      • Optional_options: AgentListSuspendedRunsOptions

      Returns Promise<never>

    • Refuse the multi-agent network start. network() does not touch the durable-agentic-loop at all: it compiles a SEPARATE workflow and drives it with createRun + run.stream on the default engine, so the whole collaboration — every sub-agent leg and every tool call inside it — runs with no per-leg grant context, no snapshot provenance and no RunSummary. It also mints options.runId || mastra.generateId() || randomUUID(), the exact unowned fallback this runner forbids: the host mints every run id.

      Signature caveat: the base method is OVERLOADED and generic in OUTPUT, so Parameters<> sees only the LAST overload and is too narrow to satisfy the first. The options parameter is therefore widened to unknown — the one supertype that satisfies every overload at once. Re-check on every peer bump; nothing here fails if core changes the shape.

      Parameters

      • _messages: MessageListInput
      • Optional_options: unknown

      Returns Promise<never>

    • Enforce the caller-owned id before DurableAgent.prepare forwards it to prepareForDurableExecution, which mints an absent id and registers the run. That UUID satisfies downstream path checks and stays live until cleanup.

      Parameters

      • messages: MessageListInput
      • Optionaloptions: AgentExecutionOptions<TOutput>

      Returns Promise<{}>

    • Refuse core's single-run recovery. DurableAgent.recover() loads the persisted durable-agentic-loop snapshot, rebuilds model/memory/processors from it and re-drives the run with createRun + run.restart() — a second execution path that never enters executeWorkflow, so no leg of it is grant-derived, run-owned or snapshot-provenanced. Throw BEFORE the storage read, so a mistaken call cannot even enumerate a run.

      Parameters

      • _runId: string
      • Optional_options: DurableAgentRecoverOptions<TOutput>

      Returns Promise<never>

    • Refuse core's bulk recovery. recoverActiveRuns() is FlowsafeDurableAgent.listActiveRuns plus a recover() per row, and it is what Mastra.recoverAllDurableAgents() calls on every registered durable agent — so a host reaches this blocked entry point without a FlowSafe call site by opting into recovery: { durableAgents: 'auto' }. That loop isolates each agent in its own try/catch, so this refusal is logged there rather than failing boot. Refuse with an explicit runId too: a single target is still a re-drive off RunnerRuntime.

      Parameters

      • Optional_options: DurableAgentRecoverActiveRunsOptions

      Returns Promise<never>

    • Refuse core's durable resume. From 1.53.0 a registry MISS makes it load the persisted durable-agentic-loop snapshot, rehydrate through prepare() with the full application processor chain, and re-drive the run with createRun + run.resume — below executeWorkflow, so the leg carries no minted grant and no snapshot provenance. The runner's resume path is FlowsafeDurableAgent.resumeViaRuntime.

      Parameters

      • _runId: string
      • _resumeData: unknown
      • Optional_options: DurableAgentResumeOptions<TOutput>

      Returns Promise<never>

    • Refuse the drain-to-completion resume. resumeGenerate() forwards straight to resume(), so it inherits the same below-the-seam re-drive.

      Parameters

      • _runId: string
      • _resumeData: unknown
      • Optional_options: DurableAgentResumeOptions<TOutput>

      Returns Promise<never>

    • Refuse the network resume — same loop and same ground as FlowsafeDurableAgent.network, plus one fact of its own: under autoResumeSuspendedTools it RECOVERS a suspended run id out of thread memory, so a caller need not even name the run it re-drives.

      Parameters

      • _resumeData: any
      • _options: Omit<MultiPrimitiveExecutionOptions, "runId"> & {}

      Returns Promise<never>

    • Refuse the base-Agent-shaped resume. Core overrides resumeStream() on DurableAgent precisely so an Agent-API caller lands on the durable resume(); blocking it here closes that same door from the other side.

      Parameters

      • _resumeData: any
      • Optional_streamOptions: any

      Returns Promise<never>

    • Rehydrate a suspended durable-agent run after isolate eviction, restore its active thread registration, then resume through RunnerRuntime so approval grant derivation and snapshot provenance remain authoritative. A resumed leg observes from the current run stream position. Its thread registration completes on the run's terminal outcome, or on a resume failure after rehydration when the wrapper publishes a terminal error: the run is no longer suspended, a cancellation or timeout refused or cut the leg, or the run's status cannot be read. A failure that leaves the run stored suspended with nothing recorded to end it keeps blocking the thread until the next resume, as another suspension does. Hosts expose this only from their trusted approval-decision topology, and spread a decided approval's expectedSuspensionFor(record) into the options, so a decision for an earlier suspension of the step is refused with SuspensionChangedError; without it the resume is unchecked.

      Parameters

      • options: {
            expectedSuspension?: { resumeCount?: number; suspendedAt: number };
            memory?: AgentExecutionOptions<TOutput>["memory"];
            requestedBy: string;
            requestedByKind?: "human" | "service" | "agent" | "system";
            resumeData?: unknown;
            runId: string;
            step?: string | string[];
        }

      Returns Promise<RunSummary>

    • Refuse the thread-level tool approval. The name reads like a resume, but only its tail is one. Called with messages and approved, it routes to the thread runtime's continuation, which falls back to randomUUID() when the caller named no run id and then STARTS a run under it — an unowned id the host-owned run-id guard cannot distinguish from a real one, because it is path-safe. Called with no active thread run, it reaches the blocked suspended-run discovery instead. FlowSafe's own tool approval is a decided ApprovalRecord resumed through the approval-decision path, which mints the leg's grant; this mints nothing and owns nothing.

      Signature caveat: the base method is generic in OUTPUT, which Parameters<> instantiates to its undefined default and so types too narrowly to satisfy the base. The options parameter is widened to unknown so it fits each instantiation. Re-check on a peer bump.

      Parameters

      • _options: unknown

      Returns Promise<never>

    • Refuse binding channels. The base forwards them to the wrapped agent, which becomes their dispatch target outside RunnerRuntime: the fourth ground reached by installation.

      Parameters

      • _agentChannels: unknown

      Returns never

    • Enforce a caller-minted run ID before the inherited durable stream() runs: without this the optional options.runId would let core mint an unowned crypto.randomUUID() upstream. The private run-ID guard rejects a missing or non-path-safe value before delegating to core. A host mints an opaque path-safe id and passes it as options.runId.

      Parameters

      • messages: MessageListInput
      • Optionaloptions: DurableAgentStreamOptions<TOutput>

      Returns Promise<DurableAgentStreamResult<TOutput>>

    • The streaming half of FlowsafeDurableAgent.generateLegacy.

      Parameters

      • _messages: MessageListInput
      • Optional_args: AgentStreamOptions<JSONSchema7 | ZodSchema | undefined, JSONSchema7 | ZodSchema | undefined> & { ...; }

      Returns Promise<never>