Skip to content

Releases: VoltAgent/voltagent

@voltagent/core@2.6.1

23 Feb 05:55
e342e57

Choose a tag to compare

Patch Changes

  • #1103 edd7181 Thanks @omeraplak! - fix: preserve getter-based fullStream tee behavior after startup probing in streamText/streamObject

    This prevents TypeError [ERR_INVALID_STATE]: Invalid state: ReadableStream is locked when SDK consumers iterate result.fullStream while other result accessors (such as result.text or UI stream helpers) are also consuming the stream.

@voltagent/core@2.6.0

23 Feb 02:37
82074b9

Choose a tag to compare

Minor Changes

  • #1100 314ed40 Thanks @omeraplak! - feat: add workflow observer/watch APIs for stream results

    What's New

    • Added run-level observer APIs on WorkflowStreamResult:
      • watch(cb)
      • watchAsync(cb)
      • observeStream()
      • streamLegacy()
    • These APIs are now available on:
      • workflow.stream(...)
      • workflow.timeTravelStream(...)
      • resumed stream results returned from .resume(...)
    • Added test coverage for event ordering, unsubscribe behavior, multiple watchers, callback isolation, and observeStream() close semantics.

    SDK Example

    const stream = workflow.stream({ value: 3 });
    
    const unwatch = stream.watch((event) => {
      console.log("[watch]", event.type, event.from);
    });
    
    const unwatchAsync = await stream.watchAsync(async (event) => {
      if (event.type === "workflow-error") {
        await notifyOps(event);
      }
    });
    
    const reader = stream.observeStream().getReader();
    const observerTask = (async () => {
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        console.log("[observeStream]", value.type);
      }
    })();
    
    for await (const event of stream) {
      console.log("[main iterator]", event.type);
    }
    
    unwatch();
    unwatchAsync();
    await observerTask;
    
    const state = await stream.streamLegacy().getWorkflowState();
    console.log("final status:", state?.status);

    Time Travel Stream Example

    const replayStream = workflow.timeTravelStream({
      executionId: sourceExecutionId,
      stepId: "step-approval",
    });
    
    const stopReplayWatch = replayStream.watch((event) => {
      console.log("[replay]", event.type, event.from);
    });
    
    for await (const event of replayStream) {
      console.log("[replay iterator]", event.type);
    }
    
    stopReplayWatch();
  • #1102 7f923d2 Thanks @omeraplak! - feat: add workflow execution primitives (bail, abort, getStepResult, getInitData)

    What's New

    Step execution context now includes four new primitives:

    • bail(result?): complete the workflow early with a custom final result
    • abort(): cancel the workflow immediately
    • getStepResult(stepId): get a prior step output directly (returns null if not available)
    • getInitData(): get the original workflow input (stable across resume paths)

    These primitives are available in all step contexts, including nested step flows.

    Example: Early Complete with bail

    const workflow = createWorkflowChain({
      id: "bail-demo",
      input: z.object({ amount: z.number() }),
      result: z.object({ status: z.string() }),
    })
      .andThen({
        id: "risk-check",
        execute: async ({ data, bail }) => {
          if (data.amount > 10_000) {
            bail({ status: "rejected" });
          }
          return { status: "approved" };
        },
      })
      .andThen({
        id: "never-runs-on-bail",
        execute: async () => ({ status: "approved" }),
      });

    Example: Cancel with abort

    const workflow = createWorkflowChain({
      id: "abort-demo",
      input: z.object({ requestId: z.string() }),
      result: z.object({ done: z.boolean() }),
    })
      .andThen({
        id: "authorization",
        execute: async ({ abort }) => {
          abort(); // terminal status: cancelled
        },
      })
      .andThen({
        id: "never-runs-on-abort",
        execute: async () => ({ done: true }),
      });

    Example: Use getStepResult + getInitData

    const workflow = createWorkflowChain({
      id: "introspection-demo",
      input: z.object({ userId: z.string(), value: z.number() }),
      result: z.object({ total: z.number(), userId: z.string() }),
    })
      .andThen({
        id: "step-1",
        execute: async ({ data }) => ({ partial: data.value + 1 }),
      })
      .andThen({
        id: "step-2",
        execute: async ({ getStepResult, getInitData }) => {
          const s1 = getStepResult<{ partial: number }>("step-1");
          const init = getInitData();
    
          return {
            total: (s1?.partial ?? 0) + init.value,
            userId: init.userId,
          };
        },
      });

@voltagent/server-core@2.1.8

22 Feb 16:19
bd66b11

Choose a tag to compare

Patch Changes

@voltagent/core@2.5.0

22 Feb 16:19
bd66b11

Choose a tag to compare

Minor Changes

  • #1097 e15bb6e Thanks @omeraplak! - Add startAsync() to workflow and workflow chain APIs for fire-and-forget execution.

    startAsync() starts a workflow run in the background and returns { executionId, workflowId, startAt } immediately. The run keeps existing execution semantics, respects provided executionId, and persists terminal states in memory for later inspection.

    Also adds workflow documentation updates with startAsync() usage examples in the workflow overview and streaming docs.

  • #1099 160e60b Thanks @omeraplak! - Add workflow time-travel and deterministic replay APIs.

    New APIs:

    • workflow.timeTravel(options)
    • workflow.timeTravelStream(options)
    • workflowChain.timeTravel(options)
    • workflowChain.timeTravelStream(options)

    timeTravel replays a historical execution from a selected step with a new execution ID, preserving the original execution history. Replay runs can optionally override selected-step input (inputData), resume payload (resumeData), and shared workflow state (workflowStateOverride).

    Replay lineage metadata is now persisted on workflow state records:

    • replayedFromExecutionId
    • replayFromStepId

    New public type exports from @voltagent/core include WorkflowTimeTravelOptions.

    Also adds workflow documentation and usage examples for deterministic replay in overview, suspend/resume, and streaming docs.

    Adds REST API documentation for replay endpoint POST /workflows/:id/executions/:executionId/replay, including request/response details and both cURL and JavaScript (fetch) code examples for default replay and replay with overrides (inputData, resumeData, workflowStateOverride).

  • #1098 b610ec6 Thanks @omeraplak! - Add workflow restart and crash-recovery APIs.

    New APIs:

    • workflow.restart(executionId, options?)
    • workflow.restartAllActive()
    • workflowChain.restart(executionId, options?)
    • workflowChain.restartAllActive()
    • WorkflowRegistry.restartWorkflowExecution(workflowId, executionId, options?)
    • WorkflowRegistry.restartAllActiveWorkflowRuns(options?)

    The workflow runtime now persists running checkpoints during execution, including step progress, shared workflow state, context, and usage snapshots, so interrupted runs in running state can be recovered deterministically.

    New public types are now exported from @voltagent/core for consumer annotations, including WorkflowRestartAllResult and WorkflowRestartCheckpoint.

    Also adds docs for restart/crash-recovery usage under workflow overview and suspend/resume docs.

@voltagent/supabase@2.1.3

19 Feb 22:49
24eeb6f

Choose a tag to compare

Patch Changes

  • #1082 73cf1d3 Thanks @omeraplak! - Fix workflow state persistence parity across SQL adapters.

    This update persists and returns input, context, and top-level workflowState in workflow state operations. It also ensures suspended workflow state queries include events, output, and cancellation, and adds adapter migrations/column additions where needed.

@voltagent/serverless-hono@2.0.9

19 Feb 22:49
24eeb6f

Choose a tag to compare

Patch Changes

  • #1084 95ad610 Thanks @omeraplak! - Add stream attach support for in-progress workflow executions.

    • Add GET /workflows/:id/executions/:executionId/stream to attach to an active workflow SSE stream.
    • Add replay support for missed SSE events via fromSequence and Last-Event-ID.
    • Keep POST /workflows/:id/stream behavior unchanged for starting new executions.
    • Ensure streamed workflow resume uses a fresh suspend controller so attach clients continue receiving events after resume.
  • Updated dependencies [f275daf, 95ad610]:

    • @voltagent/server-core@2.1.7

@voltagent/server-hono@2.0.7

19 Feb 22:49
24eeb6f

Choose a tag to compare

Patch Changes

  • #1084 95ad610 Thanks @omeraplak! - Add stream attach support for in-progress workflow executions.

    • Add GET /workflows/:id/executions/:executionId/stream to attach to an active workflow SSE stream.
    • Add replay support for missed SSE events via fromSequence and Last-Event-ID.
    • Keep POST /workflows/:id/stream behavior unchanged for starting new executions.
    • Ensure streamed workflow resume uses a fresh suspend controller so attach clients continue receiving events after resume.
  • Updated dependencies [f275daf, 95ad610]:

    • @voltagent/core@2.4.4
    • @voltagent/server-core@2.1.7

@voltagent/server-elysia@2.0.6

19 Feb 22:48
24eeb6f

Choose a tag to compare

Patch Changes

  • #1084 95ad610 Thanks @omeraplak! - Add stream attach support for in-progress workflow executions.

    • Add GET /workflows/:id/executions/:executionId/stream to attach to an active workflow SSE stream.
    • Add replay support for missed SSE events via fromSequence and Last-Event-ID.
    • Keep POST /workflows/:id/stream behavior unchanged for starting new executions.
    • Ensure streamed workflow resume uses a fresh suspend controller so attach clients continue receiving events after resume.
  • Updated dependencies [f275daf, 95ad610]:

    • @voltagent/core@2.4.4
    • @voltagent/server-core@2.1.7

@voltagent/server-core@2.1.7

19 Feb 22:48
24eeb6f

Choose a tag to compare

Patch Changes

  • #1085 f275daf Thanks @omeraplak! - Fix workflow execution filtering by persisted metadata across adapters.

    • Persist options.metadata on workflow execution state so /workflows/executions filters can match tenant/user metadata.
    • Preserve existing execution metadata when updating cancelled/error workflow states.
    • Accept options.metadata in server workflow execution request schema.
    • Fix LibSQL and Cloudflare D1 JSON metadata query comparisons for metadata and metadata.<key> filters.
  • #1084 95ad610 Thanks @omeraplak! - Add stream attach support for in-progress workflow executions.

    • Add GET /workflows/:id/executions/:executionId/stream to attach to an active workflow SSE stream.
    • Add replay support for missed SSE events via fromSequence and Last-Event-ID.
    • Keep POST /workflows/:id/stream behavior unchanged for starting new executions.
    • Ensure streamed workflow resume uses a fresh suspend controller so attach clients continue receiving events after resume.
  • Updated dependencies [f275daf, 95ad610]:

    • @voltagent/core@2.4.4

@voltagent/postgres@2.1.2

19 Feb 22:48
24eeb6f

Choose a tag to compare

Patch Changes

  • #1082 73cf1d3 Thanks @omeraplak! - Fix workflow state persistence parity across SQL adapters.

    This update persists and returns input, context, and top-level workflowState in workflow state operations. It also ensures suspended workflow state queries include events, output, and cancellation, and adds adapter migrations/column additions where needed.