feat(workflow-executor): ai-assisted action forms, ai pre-fills then human submits (PRD-511)#1693
Conversation
…human submits (PRD-511) When a Trigger Action step's action has a form, AI-assisted mode (AutomatedWithConfirmation) pre-fills the form from the workflow context, then pauses for the user to review/edit/submit natively. The executor does NOT execute in this mode — the front does. - shared AI fill loop (fillFormWithAi): bounded by max iterations + no-progress detection, re-applies values each pass so dynamic-form change hooks reveal dependent fields; strict "leave empty if unsure" prompt; returns values in fill order so the front replays sequentially. Reused by Full AI (PRD-512). - mode branching: formless unchanged; form+Manual pauses with NO prefill; form+FullyAutomated still throws UnsupportedActionFormError (PRD-512); form+AutomatedWithConfirmation fills then pauses. - schema: TriggerAction executionType accepts Manual + drops the .catch that silently coerced manual into AI-assisted (anti-coercion, regression-tested). - pending payload carries the form + ordered AI prefill; confirmation payload gains submittedValues + submissionOutcome (executed or pending-approval); a pending-approval submission is persisted distinctly (no actionResult). fixes PRD-511 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 new issue
|
|
Coverage Impact Unable to calculate total coverage change because base branch coverage was not found. Modified Files with Diff Coverage (2)
🤖 Increase coverage with AI coding...🚦 See full report on Qlty Cloud » 🛟 Help
|
…thoritative (PRD-511) The fill system prompt framed the workflow context (record data) as the only source and forbade "inventing amounts", which conflicted with an explicit instruction like "set the price to 35" — that value comes from the request, not the record. The AI oscillated between the requested value and echoing the field's current default. Clarified that an explicit value stated in the request must be applied (not guessing), and that "current" is just a default to override. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds Debug-level traces around the AI form-fill so support can diagnose a client's under-/mis-filled form: the context handed to the AI (request, fields, full message list), the raw values the AI returned, and the net values retained after the drop-stale pass (+ canExecute). Off by default — turned on per client with LOG_LEVEL=Debug. Client-side logs only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| for (const [field, value] of Object.entries(aiValues)) { | ||
| const isEmpty = value === undefined || value === null || value === ''; | ||
| const exists = form.fields.some(f => f.name === field); | ||
| const isNew = accumulator[field] !== value; |
There was a problem hiding this comment.
🟢 Low executors/trigger-record-action-step-executor.ts:202
The isNew check on line 202 uses !== (reference comparison), so when the AI returns a structurally identical object or array value across iterations (same content, different reference), it is treated as "new." This pushes duplicate entries into ordered, inflating the aiFilledValues audit trail and triggering unnecessary sequential replays on the frontend. Consider using a value-based comparison such as JSON.stringify.
| const isNew = accumulator[field] !== value; | |
| const isNew = JSON.stringify(accumulator[field]) !== JSON.stringify(value); |
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/workflow-executor/src/executors/trigger-record-action-step-executor.ts around line 202:
The `isNew` check on line 202 uses `!==` (reference comparison), so when the AI returns a structurally identical object or array value across iterations (same content, different reference), it is treated as "new." This pushes duplicate entries into `ordered`, inflating the `aiFilledValues` audit trail and triggering unnecessary sequential replays on the frontend. Consider using a value-based comparison such as `JSON.stringify`.
Evidence trail:
packages/workflow-executor/src/executors/trigger-record-action-step-executor.ts lines 190-213 (loop with `accumulator[field] !== value` on line 202); lines 244-305 (`askAiToFillForm` returns `Record<string, unknown>`, schema uses `z.unknown()` at line 267); packages/workflow-executor/src/ports/agent-port.ts lines 61-68 (ActionFormField type is `string`, value is `unknown`); packages/workflow-executor/src/adapters/agent-client-agent-port.ts lines 300-311 (field types include 'Enum' and others via `field.getType()`); packages/workflow-executor/src/types/step-execution-data.ts lines 84-89 (AiFilledFormValue interface with `value: unknown`).

What
AI-assisted mode of the AI-assisted & Full AI action forms epic (PRD-57), built on PRD-509. "AI-assisted" = the existing
AutomatedWithConfirmationmode (no new enum). The executor pre-fills the form server-side then pauses; the front executes natively.Changes
fillFormWithAi) — bounded by max iterations (3) + no-progress detection; re-applies values each pass so dynamic-form change hooks reveal dependent fields; strict "leave empty if unsure" prompt; returns values in fill order so the front replays sequentially. Reused by Full AI (PRD-512).UnsupportedActionFormError(PRD-512 implements); form + AutomatedWithConfirmation → fill then pause.TriggerAction.executionTypeacceptsManualand drops.catch(which silently coercedmanual→ AI-assisted). Regression-tested via the mapper.server-typesalso accepts Manual.pendingData.form = { fields, aiFilledValues: ordered {field,value}[] }.submittedValues+submissionOutcome(executed|pending-approval). Branch A accepts apending-approvalconfirmation with noactionResultand persists outcome + submitted values + AI prefill (audit / downstream-AI context).Tests
1099 tests pass (48 suites). New: Manual no-prefill, AI-assisted ordered fill (leaves no-context field empty), pending-approval persistence, manual-not-coerced.
fixes PRD-511
Note
Add AI-assisted form pre-fill with human review to trigger-action workflow steps
Manualexecution type to trigger-action steps, which pauses the workflow and presents the form to the user without AI involvement.AutomatedWithConfirmationpath for form-bearing actions: the executor runs an iterative AI loop (fillFormWithAi) to pre-fill form fields using workflow context, then pauses for human review before submission.FullyAutomatedon form-bearing actions is explicitly rejected withUnsupportedActionFormError.TriggerActionPendingDataand execution result types to carryfields,aiFilledValues,submittedValues, andsubmissionOutcome(executed|pending-approval).submittedValuesandsubmissionOutcomefrom the frontend via an extendedtriggerActionPatchSchema..catch(AutomatedWithConfirmation)coercion means any existing step definition with an unrecognizedexecutionTypewill no longer silently fall back.📊 Macroscope summarized 8a4cc02. 1 file reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
🗂️ Filtered Issues
No issues evaluated.