Skip to content

fix(web): recognize loop and approval node types in DAG builder (closes #1336)#1722

Closed
nhiendohao wants to merge 2 commits into
coleam00:mainfrom
nhiendohao:fix/web-loop-approval-node-type
Closed

fix(web): recognize loop and approval node types in DAG builder (closes #1336)#1722
nhiendohao wants to merge 2 commits into
coleam00:mainfrom
nhiendohao:fix/web-loop-approval-node-type

Conversation

@nhiendohao

Copy link
Copy Markdown
Contributor

Problem

resolveNodeDisplay() in dag-layout.ts only handled bash and command node types, falling through to a prompt fallback for everything else. This meant loop and approval nodes were assigned nodeType: 'prompt' with no promptText, triggering a false-positive validation error in useBuilderValidation.ts:

Node "analyze-and-fix": prompt cannot be empty
Node "confirm-push": prompt cannot be empty

The YAML is valid — these nodes correctly use loop: and approval: — but the web UI builder raised errors and rendered them incorrectly.

Closes #1336.

Root Cause

// dag-layout.ts — before
resolveNodeDisplay(dn):
  bash   → nodeType: 'bash'    ✓
  command → nodeType: 'command' ✓
  *      → nodeType: 'prompt'  ✗ loop and approval fall here

useBuilderValidation.ts then checked nodeType === 'prompt' && !promptText?.trim() and fired for both misclassified node types.

Fix

dag-layout.ts

Added explicit loop and approval cases to resolveNodeDisplay(). Loop nodes receive nodeType: 'loop' with promptText set to loop.prompt (used for content preview). Approval nodes receive nodeType: 'approval'.

DagNodeComponent.tsx

  • Extended DagNodeData.nodeType union: 'command' | 'prompt' | 'bash' | 'loop' | 'approval'
  • Added TYPE_CONFIG entries (teal badge for LOOP, amber for APPROVAL)
  • Updated getContentPreview switch to handle both new types

index.css

Added --node-loop (teal, oklch(0.62 0.18 170)) and --node-approval (amber, oklch(0.72 0.17 40)) CSS custom properties and @theme inline mappings.

Before / After

Before: Any workflow with a loop: or approval: node showed errors in the Problems panel and rendered the node with a purple PROMPT badge and an empty prompt preview.

Problems panel (before):
  ● Node "analyze-and-fix": prompt cannot be empty
  ● Node "confirm-push": prompt cannot be empty

After: Loop and approval nodes render with distinct colored badges (LOOP in teal, APPROVAL in amber), no validation errors, and the loop prompt text is shown as a content preview.

Problems panel (after):
  (empty — 0 errors)

DAG graph (after):
  [LOOP analyze-and-fix]    ← teal badge, shows first line of loop.prompt
  [APPROVAL confirm-push]   ← amber badge

Testing

  1. Open any workflow containing a loop: or approval: node in the builder
  2. Verify the Problems panel shows no false-positive "prompt cannot be empty" errors
  3. Verify the node renders with the correct LOOP / APPROVAL badge and color stripe

resolveNodeDisplay() fell through to the 'prompt' fallback for loop and
approval nodes, giving them nodeType='prompt' with no promptText.
useBuilderValidation then raised false-positive "prompt cannot be empty"
errors for both node types.

Changes:
- dag-layout.ts: add loop and approval cases to resolveNodeDisplay()
- DagNodeComponent.tsx: extend nodeType union; add TYPE_CONFIG entries
  and getContentPreview cases for loop and approval
- index.css: add --node-loop (teal) and --node-approval (amber) tokens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 19, 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1d109251-3679-48f2-b0fb-929a108f94a9

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

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.

@Wirasm

Wirasm commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Review Summary

Verdict: minor-fixes-needed

Your PR adds UI support for two new workflow node types (loop and approval) in the workflow builder. The code itself is clean, well-structured, and CLAUDE.md-compliant — no bugs detected. However, tests are missing for the new behavior.

Blocking issues

None — code is clean and ready to merge once tests are added.

Suggested fixes

  • packages/web/src/lib/dag-layout.ts:67-72 — Add unit tests for resolveNodeDisplay() covering loop and approval inputs. Verify it returns { label: 'Loop', nodeType: 'loop', promptText: dn.loop.prompt } for loop nodes and { label: 'Approval', nodeType: 'approval' } for approval nodes.

  • packages/web/src/lib/dag-layout.ts:77-86 — Add integration test for dagNodesToReactFlow([loopNode, approvalNode]) asserting that resulting nodes have data.nodeType === 'loop' and data.nodeType === 'approval'.

  • packages/web/src/components/workflows/DagNodeComponent.tsx:40-51 — Add unit tests for getContentPreview():

    • getContentPreview({ nodeType: 'loop', promptText: 'iterate\nagain' })'iterate'
    • getContentPreview({ nodeType: 'approval' })''

Minor / nice-to-have

None.

Compliments

  • Clean CSS variable pattern for the new node types (--node-loop, --node-approval) — consistent with existing node color conventions.
  • TypeScript switch exhaustiveness handled correctly for the new loop and approval branches.

Reviewed via maintainer-review-pr workflow (Pi/Minimax). Aspects run: code-review, test-coverage.

…types

Tests requested by Wirasm for PR coleam00#1722:
- resolveNodeDisplay(): loop node → { label, nodeType, promptText }, approval → { label, nodeType }
- dagNodesToReactFlow() integration: asserts loop and approval nodes have correct nodeType in output
- getContentPreview(): loop multi-line prompt returns first line; approval returns empty string
- Exports getContentPreview from DagNodeComponent.tsx to make it testable
- Extends test script to cover src/components/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nhiendohao

Copy link
Copy Markdown
Contributor Author

@Wirasm — tests added as requested. Three suites now cover the loop/approval changes:

  • src/lib/dag-layout.test.ts — unit tests for resolveNodeDisplay(): loop node returns { label: 'Loop', nodeType: 'loop', promptText }, approval returns { label: 'Approval', nodeType: 'approval' }
  • Same file — integration test for dagNodesToReactFlow([loopNode, approvalNode]): asserts data.nodeType === 'loop' and data.nodeType === 'approval'
  • src/components/workflows/DagNodeComponent.test.ts — unit tests for getContentPreview(): loop multi-line prompt returns first line only, approval returns empty string

getContentPreview was exported to make it directly testable. The test script in package.json was extended to cover src/components/. All 5 new tests pass alongside the existing 158. Ready for re-review.

@Wirasm

Wirasm commented May 21, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the fix @nhiendohao! Closing this so it can be reopened against the right base.

This PR targets main, but Archon's working branch is devmain is the release branch that only receives squash-merges from dev via the /release workflow (see CLAUDE.md § Git Workflow and Releases). Re-target this against dev and we'll get it reviewed and merged.

Easiest path: open a new PR from fix/web-loop-approval-node-typedev (same branch, just change the base). Once the new PR lands, this one can stay closed.

@Wirasm Wirasm closed this May 21, 2026
Wirasm pushed a commit that referenced this pull request May 25, 2026
* fix(web): recognize loop and approval node types in DAG builder

resolveNodeDisplay() fell through to the 'prompt' fallback for loop and
approval nodes, giving them nodeType='prompt' with no promptText.
useBuilderValidation then raised false-positive "prompt cannot be empty"
errors for both node types.

Changes:
- dag-layout.ts: add loop and approval cases to resolveNodeDisplay()
- DagNodeComponent.tsx: extend nodeType union; add TYPE_CONFIG entries
  and getContentPreview cases for loop and approval
- index.css: add --node-loop (teal) and --node-approval (amber) tokens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(web): add unit and integration tests for loop/approval DAG node types

Tests requested by Wirasm for PR #1722:
- resolveNodeDisplay(): loop node → { label, nodeType, promptText }, approval → { label, nodeType }
- dagNodesToReactFlow() integration: asserts loop and approval nodes have correct nodeType in output
- getContentPreview(): loop multi-line prompt returns first line; approval returns empty string
- Exports getContentPreview from DagNodeComponent.tsx to make it testable
- Extends test script to cover src/components/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: robby_kei <robby_kei@linecorp.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

2 participants