Skip to content

fix(workflow-executor): Full AI load-related — reference field + empty-list skip (PRD-751)#1751

Merged
matthv merged 5 commits into
mainfrom
feature/prd-751-full-ai-reference-field
Jul 17, 2026
Merged

fix(workflow-executor): Full AI load-related — reference field + empty-list skip (PRD-751)#1751
matthv merged 5 commits into
mainfrom
feature/prd-751-full-ai-reference-field

Conversation

@matthv

@matthv matthv commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

Two PRD-751 fixes to the Full AI Load Related Record path in the executor (both in load-related-record-step-executor.ts).

1. Keep the reference field on loaded records

In Full AI, the run's record dropdown showed the raw recordId instead of the record's reference field label (Full-AI-only — AI-assisted already carried the candidates through its await-then-confirm flow). The auto-load path called persistAndReturn with no pendingData, so the completed step had no availableRecordIds for the front to read. Now the candidates' pendingData (with referenceFieldValue) is persisted on the auto-load path too.

2. Auto-skip when the candidate list is empty

Per the sync with Brice (documented on PRD-751): in Full AI, an empty candidate list (no related record at all) now continues without a record (skip) instead of handing off to AI-assisted — a human couldn't pick one either. Unchanged: a non-empty list with no confident pick (ambiguous, or the AI judged none relevant) still degrades to the AI-assisted confirmation.

Testing

  • Extended/updated the executor tests: Full AI persists pendingData.availableRecordIds on auto-load; empty-list (BelongsTo / HasMany / BelongsToMany) now skips (executionResult: { skipped: true }, success); AI-assisted empty-list and "AI judged none relevant" cases still await input. 102 tests green.
  • Manual E2E: a Full AI Load Related step (account → store) shows the store's reference field ("Bradtke - Donnelly") in the record dropdown.

fixes PRD-751

🤖 Generated with Claude Code

Note

Fix empty-list skip and reference field handling in LoadRelatedRecordStepExecutor for full AI mode

  • When no candidate related records are found in fully automated execution, the step now persists a skip (executionResult.skipped=true) via a new persistSkip method and returns success instead of awaiting input.
  • When a confident record is auto-loaded, the saved step execution now includes pendingData (candidate list, suggested field, available fields via the new followableRelationFields helper) so candidate labels are preserved.
  • Extracts a followableRelationFields helper to avoid duplicate inline computation across persistAwaitInput and resolveAndLoadAutomatic.
  • Behavioral Change: fully automated workflows with empty related-record lists no longer stall awaiting input — they skip the step and continue.

Macroscope summarized d8ca5a9.

…cords (PRD-751)

Full AI's auto-load called persistAndReturn with no pendingData, so the completed
step only carried executionResult.record (a bare recordId). The front's record
dropdown then fell back to the raw recordId instead of the reference field label
(the issue was Full-AI-only; AI-assisted carries pendingData through its
await-then-confirm flow). Persist the candidates' pendingData on the auto-load
path too. Extracted followableRelationFields to share the availableFields build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Jul 10, 2026

Copy link
Copy Markdown

PRD-751

@qltysh

qltysh Bot commented Jul 10, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

This PR will not change total coverage.

Modified Files with Diff Coverage (1)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
...ow-executor/src/executors/load-related-record-step-executor.ts100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

…idate list is empty (PRD-751)

Per the PRD-751 sync: in Full AI, an empty candidate list (no related record at
all) now continues without a record (skip) instead of handing off to
AI-assisted — a human couldn't pick one either. A non-empty list with no
confident pick (ambiguous, or the AI judged none relevant) still degrades to the
AI-assisted confirmation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@matthv matthv changed the title fix(workflow-executor): keep the reference field on Full AI loaded records (PRD-751) fix(workflow-executor): Full AI load-related — reference field + empty-list skip (PRD-751) Jul 10, 2026
// confirmation — "No X to load" pre-checked when nothing fits, else its best guess pre-selected.
// Full AI with no candidate at all: a human couldn't pick one either, so continue without a
// record (skip) instead of handing off to AI-assisted (PRD-751 decision).
if (availableRecordIds.length === 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium executors/load-related-record-step-executor.ts:439

In Full AI mode, when the AI-selected relation has zero linked records but another eligible relation does have records, resolveAndLoadAutomatic() now calls persistSkip(target) and marks the step successful with executionResult: { skipped: true }. The step silently completes without loading a record instead of degrading to the confirmation flow, where the user could switch relations via the existing relation-switch UI and recover the loadable path. The new availableRecordIds.length === 0 short-circuit in resolveAndLoadAutomatic() skips the degradation that the old code performed, and persistSkip writes a success outcome. Consider routing an empty candidate list to persistAwaitInput (as other non-confident paths already do) rather than persistSkip, so the user can still pick a different relation.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/workflow-executor/src/executors/load-related-record-step-executor.ts around line 439:

In Full AI mode, when the AI-selected relation has zero linked records but another eligible relation does have records, `resolveAndLoadAutomatic()` now calls `persistSkip(target)` and marks the step successful with `executionResult: { skipped: true }`. The step silently completes without loading a record instead of degrading to the confirmation flow, where the user could switch relations via the existing relation-switch UI and recover the loadable path. The new `availableRecordIds.length === 0` short-circuit in `resolveAndLoadAutomatic()` skips the degradation that the old code performed, and `persistSkip` writes a success outcome. Consider routing an empty candidate list to `persistAwaitInput` (as other non-confident paths already do) rather than `persistSkip`, so the user can still pick a different relation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is intentional per the PRD-751 decision (documented on the ticket): in Full AI, an empty candidate list continues without a record (skip) rather than handing off to AI-assisted. There's no human in Full AI to switch relations — the confirmation flow is exactly the fallback the PO chose to drop for this case.

The sub-case you raise (the AI picks an empty relation while another has records) is about the relation choice (selectRelationToFollow), not the skip — routing back to a human confirmation would reintroduce the fallback the decision removed. If we ever want the AI to prefer relations that actually have records, that'd be a separate enhancement. Note it only applies to non-deterministic Full AI anyway: deterministic steps pin the relation, so there's a single eligible relation.

matthv and others added 2 commits July 10, 2026 17:50
- drop the stale/duplicated JSDoc left on persistSkip when it was inserted above
  persistAndReturn (it described the wrong method); the names are self-documenting
- log the Full AI auto-skip so an unexpectedly empty relation is auditable
  (consistent with the other anomaly logs in this executor)
- tests: assert referenceFieldValue is carried on the auto-load pendingData (the
  point of the reference-field fix), and that persistSkip records executionParams
  + selectedRecordRef for downstream steps

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

@christophebrun-forest christophebrun-forest left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Manual tests OK
Tests OK
LGTM

@matthv
matthv merged commit 646a058 into main Jul 17, 2026
37 checks passed
@matthv
matthv deleted the feature/prd-751-full-ai-reference-field branch July 17, 2026 09:45
forest-bot added a commit that referenced this pull request Jul 17, 2026
## @forestadmin/workflow-executor [1.17.3](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/workflow-executor@1.17.2...@forestadmin/workflow-executor@1.17.3) (2026-07-17)

### Bug Fixes

* **workflow-executor:** Full AI load-related — reference field + empty-list skip (PRD-751) ([#1751](#1751)) ([646a058](646a058))
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