Skip to content

fix(memory): add workflow state parity for SQL adapters#1082

Merged
omeraplak merged 2 commits into
mainfrom
fix/workflow-state-parity-1080
Feb 19, 2026
Merged

fix(memory): add workflow state parity for SQL adapters#1082
omeraplak merged 2 commits into
mainfrom
fix/workflow-state-parity-1080

Conversation

@omeraplak

@omeraplak omeraplak commented Feb 19, 2026

Copy link
Copy Markdown
Member

PR Checklist

Please check if your PR fulfills the following requirements:

Bugs / Features

What is the current behavior?

Workflow state persistence is inconsistent across SQL adapters. getWorkflowState and queryWorkflowRuns can return only partial execution state, and getSuspendedWorkflowStates may omit fields like events, output, and cancellation. Top-level input, context, and workflowState are not fully persisted/read in these adapters.

What is the new behavior?

This PR brings workflow state parity for SQL adapters:

  • Persists and returns input, context, and top-level workflowState
  • Ensures getSuspendedWorkflowStates includes events, output, and cancellation
  • Adds schema/migration support for missing workflow state columns where needed
  • Updates adapter tests to cover the full workflow state contract

fixes #1080

Notes for reviewers

Validated with targeted checks:

  • pnpm -C packages/postgres test -- src/memory-adapter.spec.ts
  • pnpm -C packages/supabase test -- src/memory-adapter.spec.ts
  • pnpm -C packages/libsql test -- src/memory-v2-adapter.spec.ts
  • pnpm -C packages/cloudflare-d1 build

Summary by cubic

Ensures full workflow state persistence and parity across SQL adapters (Postgres, Supabase, LibSQL, Cloudflare D1) so reads and queries return complete data. Fixes Linear #1080.

  • Bug Fixes

    • Persist and return input, context, and workflowState in getWorkflowState, queryWorkflowRuns, and suspended-state reads across all adapters.
    • Include events, output, and cancellation in getSuspendedWorkflowStates; tests updated across adapters, including normalized cancellation timestamp for Postgres.
  • Migration

    • Adapters auto-add missing columns (input, context, workflow_state, events, output, cancellation); Supabase migration detection now checks these fields. No manual steps.

Written for commit 30d008a. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes

    • Workflow state persistence now consistently stores and returns input, context, and workflow state across SQL adapters; suspended-state queries include events, output, and cancellation.
  • Chores

    • Database migrations and schema updates applied across adapters to support the expanded persisted workflow state fields.

@changeset-bot

changeset-bot Bot commented Feb 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 30d008a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@voltagent/postgres Patch
@voltagent/libsql Patch
@voltagent/supabase Patch
@voltagent/cloudflare-d1 Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ghost

This comment has been minimized.

@coderabbitai

coderabbitai Bot commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This PR adds persistent parity for workflow state across SQL adapters by adding input, context, and workflow_state columns and wiring them into reads/writes and runtime migrations for PostgreSQL, LibSQL, Supabase, and Cloudflare D1. Tests were updated to validate round-trip behavior.

Changes

Cohort / File(s) Summary
Changeset
\.changeset/workflow-state-parity-adapters.md
Patch bumps and changelog entry describing workflow-state persistence parity across SQL adapters.
PostgreSQL Adapter
packages/postgres/src/memory-adapter.ts, packages/postgres/src/memory-adapter.spec.ts, packages/postgres/src/index.integration.test.ts
Adds input, context, workflow_state JSONB columns; updates INSERT/UPSERT and SELECT mappings; includes runtime migrations; extends setWorkflowState, getWorkflowState, queryWorkflowRuns, getSuspendedWorkflowStates; tests updated to assert new fields.
LibSQL Adapter
packages/libsql/src/memory-core.ts, packages/libsql/src/memory-v2-adapter.spec.ts
Adds input, context, workflow_state text columns; persists JSON-stringified values; deserializes on reads; updates table creation/migrations and tests to verify parsed fields.
Supabase Adapter
packages/supabase/src/memory-adapter.ts, packages/supabase/src/memory-adapter.spec.ts
Adds input, context, workflow_state JSONB columns in fresh-install and migration SQL; updates upsert/read paths to include these fields; tests updated to validate mapping and persistence.
Cloudflare D1 Adapter
packages/cloudflare-d1/src/memory-adapter.ts
Adds input, context, workflow_state columns; updates INSERT/UPDATE and SELECT mappings; initializes missing columns at runtime and parses JSON fields on read.

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant Client as Client
participant Adapter as SQL Adapter
participant DB as Database
Client->>Adapter: setWorkflowState(executionId, state{input,context,workflowState,...})
Adapter->>DB: INSERT ... (input, context, workflow_state, events, output, cancellation) ON CONFLICT DO UPDATE
DB-->>Adapter: OK / persisted row
Adapter-->>Client: acknowledgement
Client->>Adapter: getWorkflowState(executionId)
Adapter->>DB: SELECT ... including input, context, workflow_state, events, output, cancellation
DB-->>Adapter: row with JSON fields
Adapter->>Adapter: parse JSON fields -> WorkflowStateEntry
Adapter-->>Client: WorkflowStateEntry (includes input, context, workflowState, events, output, cancellation)

Note: colored rectangles not used because sequence flow is simple and component boxes suffice.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • lzj960515

Poem

🐰 Hop hop, I patch the ground so neat,
New columns sprout on every seat,
Input, context, top-state in store,
Round-trips hum and tests adore,
A carrot-coded cheer — schema complete! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(memory): add workflow state parity for SQL adapters' accurately describes the main change in the PR, which adds workflow state parity across SQL adapters.
Description check ✅ Passed The PR description comprehensively covers the template requirements with current behavior, new behavior, linked issues, tests, changesets, and validation details.
Linked Issues check ✅ Passed The PR fully addresses all coding requirements from issue #1080: adds missing columns (input, context, workflow_state), persists/reads these fields across all adapter methods, includes events/output/cancellation in suspended states, and updates tests.
Out of Scope Changes check ✅ Passed All changes are directly related to the workflow state parity objective. Modifications are limited to schema additions, adapter implementations, and comprehensive test updates across all four SQL adapters.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/workflow-state-parity-1080

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/postgres/src/memory-adapter.spec.ts (1)

844-943: ⚠️ Potential issue | 🟡 Minor

getSuspendedWorkflowStates test is missing assertions for input and entirely skips context.

input is present in the fixture objects (lines 851, 876) and mock DB rows (lines 906, 923) but is never asserted in the final expect block (lines 940–943). context is absent from the suspended-state fixtures and mock rows altogether, leaving the context round-trip completely untested for this retrieval path — unlike getWorkflowState (lines 730/777) and queryWorkflowRuns (lines 957/984) which cover it fully.

🛠️ Suggested additions
  expect(suspended[0]?.events).toEqual(states[0].events);
  expect(suspended[0]?.output).toEqual(states[0].output);
  expect(suspended[0]?.cancellation).toEqual(states[0].cancellation);
  expect(suspended[0]?.workflowState).toEqual(states[0].workflowState);
+ expect(suspended[0]?.input).toEqual(states[0].input);

And add context to the first suspended-state fixture + mock row:

  {
    id: "wf-susp-1",
    ...
    input: { task: 1 },
+   context: [["tenantId", "acme"]] as Array<[string, unknown]>,
    workflowState: { phase: "s1" },
  {
    id: "wf-susp-1",
    ...
    input: states[0].input,
+   context: states[0].context,
    workflow_state: states[0].workflowState,
+ expect(suspended[0]?.context).toEqual(states[0].context);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/postgres/src/memory-adapter.spec.ts` around lines 844 - 943, The
test for getSuspendedWorkflowStates is missing assertions for the state's input
and omits testing context entirely; update the suspended-state fixtures (the
entries in the states array used in this test) to include a context value for at
least the first suspended fixture, add the same context to the corresponding
mockPoolQueryResult row, then add assertions after calling
adapter.getSuspendedWorkflowStates to expect suspended[0].input toEqual the
fixture input and suspended[0].context toEqual the fixture context (and add
similar checks for suspended[1] if you add context there) so the round-trip for
input and context is covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/postgres/src/memory-adapter.spec.ts`:
- Around line 844-943: The test for getSuspendedWorkflowStates is missing
assertions for the state's input and omits testing context entirely; update the
suspended-state fixtures (the entries in the states array used in this test) to
include a context value for at least the first suspended fixture, add the same
context to the corresponding mockPoolQueryResult row, then add assertions after
calling adapter.getSuspendedWorkflowStates to expect suspended[0].input toEqual
the fixture input and suspended[0].context toEqual the fixture context (and add
similar checks for suspended[1] if you add context there) so the round-trip for
input and context is covered.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Feb 19, 2026

Copy link
Copy Markdown

Deploying voltagent with  Cloudflare Pages  Cloudflare Pages

Latest commit: 30d008a
Status: ✅  Deploy successful!
Preview URL: https://3684eeec.voltagent.pages.dev
Branch Preview URL: https://fix-workflow-state-parity-10.voltagent.pages.dev

View logs

@omeraplak
omeraplak merged commit 73cf1d3 into main Feb 19, 2026
23 checks passed
@omeraplak
omeraplak deleted the fix/workflow-state-parity-1080 branch February 19, 2026 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] getWorkflowState should return full workflow state (workflowState + events)

1 participant