Skip to content

refactor(workflow): strengthen contracts and zod boundaries - #100

Merged
Waishnav merged 57 commits into
pr/dw-6-native-schemafrom
pr/dw-7-typed-contracts-zod
Jul 27, 2026
Merged

refactor(workflow): strengthen contracts and zod boundaries#100
Waishnav merged 57 commits into
pr/dw-6-native-schemafrom
pr/dw-7-typed-contracts-zod

Conversation

@Waishnav

@Waishnav Waishnav commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Workflow values crossed script, provider, database, replay, CLI, and MCP boundaries with several loosely typed JSON and event shapes. Invalid persisted data or provider capabilities could therefore travel too far before failing, and TypeScript could not preserve useful output and tuple types across the public API.

Define shared JSON-safe values and schema contracts, validate metadata, options, states, events, providers, and persisted payloads with Zod, and make event and capability handling exhaustive. Schema-derived agent() output types, tuple-preserving parallel results, and typed pipeline overloads make the public API match the runtime contract.

Stack

Based on #99 and merged into #94 before operational error normalization in #101.

Summary by CodeRabbit

  • New Features
    • Added consistent validation for workflow metadata, arguments, events, statuses, and structured outputs.
    • Added provider capability awareness for native structured-output support.
    • Improved workflow APIs with clearer provider, JSON value, and schema handling.
    • Enhanced resume, replay, sandbox, and tool workflows with safer JSON processing.
  • Bug Fixes
    • Invalid or non-JSON workflow inputs now produce clearer, more reliable errors.
    • Persisted workflow data and event payloads are validated before use.
  • Tests
    • Added comprehensive contract coverage for workflow schemas, providers, events, and JSON values.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e5b99541-94fb-4a43-8b0a-197c63083ac8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr/dw-7-typed-contracts-zod

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/workflow-types.ts (1)

13-44: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Consolidate the duplicate provider ID aliases.

AgentProviderId is defined here and WorkflowProviderId is defined in workflow-contracts.ts, both as LocalAgentProvider. Either import/export the consolidated WorkflowProviderId here and reuse it at WorkflowAgentCallRecord.provider, AgentCacheKeyInput.provider, and buildAgentCacheKeyInput(provider: ...), or export AgentProviderId from workflow-contracts.ts if callers should depend on the single contract alias.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workflow-types.ts` around lines 13 - 44, Consolidate the provider ID
aliases by using a single contract-level alias: import and re-export
WorkflowProviderId from workflow-contracts.ts, then update
WorkflowAgentCallRecord.provider, AgentCacheKeyInput.provider, and the
buildAgentCacheKeyInput(provider: ...) parameter to use it consistently. Remove
the duplicate AgentProviderId definition rather than maintaining parallel
aliases.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/json-types.ts`:
- Around line 40-42: Update parseJsonText to catch JSON.parse failures and
convert malformed input into the same clear validation-error type used by
parseJsonValue, while preserving normal parsing and validation behavior for
valid JSON.

In `@src/workflow-script.ts`:
- Around line 186-201: Update validateMeta to enable Zod's reportInput option
when calling workflowMetaSchema.safeParse, so issue.input is available for
distinguishing missing values from present values with invalid types. Preserve
the existing required-field handling for undefined input and allow present
wrong-type fields such as meta.concurrency to use the normal validation error
path.

In `@src/workflow-store.ts`:
- Around line 566-572: Update the bulk mapping paths in listRuns() and
listAgentCalls(), including rowToRun, rowToEvent, and rowToAgentCall, so invalid
persisted enum-like values are handled per row with safe parsing and corrupted
rows are skipped or flagged rather than aborting the entire list operation.
Preserve strict .parse() behavior for single-record getRun() and getAgentCall()
lookups.

---

Nitpick comments:
In `@src/workflow-types.ts`:
- Around line 13-44: Consolidate the provider ID aliases by using a single
contract-level alias: import and re-export WorkflowProviderId from
workflow-contracts.ts, then update WorkflowAgentCallRecord.provider,
AgentCacheKeyInput.provider, and the buildAgentCacheKeyInput(provider: ...)
parameter to use it consistently. Remove the duplicate AgentProviderId
definition rather than maintaining parallel aliases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0546af15-0cb2-4c3c-ad46-41c0315e5417

📥 Commits

Reviewing files that changed from the base of the PR and between 3343404 and 4cb4007.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (24)
  • package.json
  • src/json-types.ts
  • src/local-agent-adapters.test.ts
  • src/local-agent-adapters.ts
  • src/local-agent-capabilities.ts
  • src/local-agent-profiles.ts
  • src/local-agent-runtime.ts
  • src/workflow-api.ts
  • src/workflow-cli.ts
  • src/workflow-contracts.test.ts
  • src/workflow-contracts.ts
  • src/workflow-engine.ts
  • src/workflow-files.ts
  • src/workflow-replay.ts
  • src/workflow-sandbox.test.ts
  • src/workflow-sandbox.ts
  • src/workflow-schema.test.ts
  • src/workflow-schema.ts
  • src/workflow-script.test.ts
  • src/workflow-script.ts
  • src/workflow-store.test.ts
  • src/workflow-store.ts
  • src/workflow-tools.ts
  • src/workflow-types.ts

Comment thread src/json-types.ts
Comment on lines +40 to +42
export function parseJsonText(text: string): JsonValue {
return parseJsonValue(JSON.parse(text) as unknown);
}

@coderabbitai coderabbitai Bot Jul 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

parseJsonText lets raw JSON.parse errors escape uncaught.

JSON.parse throws a native SyntaxError (not a Zod validation error) on malformed text. Since this helper is used to reload persisted state (e.g. workflow run args/JSON blobs), a corrupted persisted value would surface as an unstructured SyntaxError rather than a clear validation failure at the call site.

🛡️ Proposed fix
 export function parseJsonText(text: string): JsonValue {
-  return parseJsonValue(JSON.parse(text) as unknown);
+  let parsed: unknown;
+  try {
+    parsed = JSON.parse(text);
+  } catch (error) {
+    throw new Error(`Invalid JSON text: ${error instanceof Error ? error.message : String(error)}`);
+  }
+  return parseJsonValue(parsed);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function parseJsonText(text: string): JsonValue {
return parseJsonValue(JSON.parse(text) as unknown);
}
export function parseJsonText(text: string): JsonValue {
let parsed: unknown;
try {
parsed = JSON.parse(text);
} catch (error) {
throw new Error(`Invalid JSON text: ${error instanceof Error ? error.message : String(error)}`);
}
return parseJsonValue(parsed);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/json-types.ts` around lines 40 - 42, Update parseJsonText to catch
JSON.parse failures and convert malformed input into the same clear
validation-error type used by parseJsonValue, while preserving normal parsing
and validation behavior for valid JSON.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Not included in the finalized hardening stack. Persisted-state call sites already wrap malformed JSON with contextual WorkflowStoredDataError or explicitly treat it as a replay miss; this comment concerns the generic helper’s standalone error wording. It remains reasonable cleanup, but is not a blocker for cross-harness workflow orchestration.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@Waishnav, acknowledged. Given the existing call-site handling, this is non-blocking for the workflow hardening scope. I’ll treat helper-level parse-error normalization as optional follow-up cleanup rather than a required change for this PR.

Would you like me to open a follow-up issue for the standalone parseJsonText error consistency improvement?


✏️ Learnings added
Learnt from: Waishnav
Repo: Waishnav/devspace PR: 100
File: src/json-types.ts:40-42
Timestamp: 2026-07-26T21:01:08.221Z
Learning: In `src/json-types.ts`, `parseJsonText` may expose native `JSON.parse` errors, but persisted workflow-state consumers already either wrap malformed JSON with contextual `WorkflowStoredDataError` or treat it as a replay miss. Helper-level error normalization is optional cleanup, not a blocker for cross-harness workflow orchestration.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread src/workflow-script.ts
Comment thread src/workflow-store.ts
Waishnav added 28 commits July 27, 2026 12:43
refactor(agents): unify provider resolution and subagent guidance
feat(workflow): support agent profiles and project workflows
fix(workflow): replay deterministic call prefixes
fix(workflow): supervise cancellation and terminal lifecycle
feat(workflow): isolate workflow script execution
feat(ui): live workspace and workflow dashboards
feat(workflow): read-only project workflow TUI
feat(workflow): script iteration, replay provenance, and call inspection
refactor(workflow): model operational failures with better-result
@Waishnav
Waishnav merged commit d052520 into pr/dw-6-native-schema Jul 27, 2026
3 of 4 checks passed
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.

1 participant