Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
174 lines
14 KiB
Markdown
174 lines
14 KiB
Markdown
# Scratchpad — Workflow Markdown Text Composer
|
||
|
||
## Context
|
||
|
||
- User wants a standard workflow primitive for composing prompts, email text, summaries, and similar text artifacts.
|
||
- User explicitly does not want prompt-specific composition layered into `ai.infer`.
|
||
- User wants pure string outputs for now, not structured chat/message payloads.
|
||
- User wants multiple outputs per compose step to reduce workflow sprawl and pricing friction.
|
||
- User wants author-facing output names to be freeform.
|
||
- User wants missing references to fail execution explicitly, not silently render empty strings.
|
||
- User wants to invest now in a richer authoring UX using BlockNote, but only as an editor surface.
|
||
- User explicitly does not want BlockNote concepts to leak into persisted workflow config or runtime output strings.
|
||
- User wants markdown value from the editor because markdown is useful both for AI prompts and downstream HTML rendering in email-like consumers.
|
||
- User explicitly does not want media in the editor.
|
||
|
||
## Key Decisions
|
||
|
||
- New primitive: `transform.compose_text`
|
||
- standard transform action
|
||
- not AI-specific
|
||
- dedicated action editor only
|
||
- Output model:
|
||
- multiple outputs per step
|
||
- freeform author labels
|
||
- generated stable reference-safe keys for downstream workflow paths
|
||
- Authoring model:
|
||
- constrained BlockNote-based editor
|
||
- inline reference chips
|
||
- markdown-safe rich text subset only
|
||
- no media, attachments, or heavy document affordances
|
||
- Persistence model:
|
||
- Alga-owned template document structure
|
||
- no stored BlockNote JSON
|
||
- Runtime model:
|
||
- render template document to markdown strings
|
||
- resolve only simple references
|
||
- fail hard if any reference is missing
|
||
|
||
## Important Constraint Discovered
|
||
|
||
- Current downstream reference handling is path-based and assumes identifier-safe segments.
|
||
- Relevant code:
|
||
- `ee/server/src/components/workflow-designer/workflowDataContext.ts`
|
||
- `ee/server/src/components/workflow-designer/WorkflowActionInputSourceMode.tsx`
|
||
- Evidence:
|
||
- `resolveReferenceSchema()` splits paths on `.`
|
||
- `isSimpleFieldReferenceExpression()` only accepts identifier-like dot segments and numeric bracket indexes
|
||
- Consequence:
|
||
- “Freeform output names” cannot be used directly as runtime field keys if they include spaces or punctuation.
|
||
- Plan implication:
|
||
- preserve freeform author labels
|
||
- generate stable reference-safe keys for downstream paths such as `vars.composed.prompt_body`
|
||
- show both label and stable key in the UI
|
||
|
||
## Relevant Existing Files
|
||
|
||
- Runtime transforms:
|
||
- `shared/workflow/runtime/actions/registerTransformActions.ts`
|
||
- `shared/workflow/runtime/actions/__tests__/registerTransformActions.test.ts`
|
||
- Dynamic output schema resolution:
|
||
- `shared/workflow/runtime/actions/actionOutputSchemaResolver.ts`
|
||
- `shared/workflow/runtime/actions/__tests__/actionOutputSchemaResolver.test.ts`
|
||
- Workflow designer data context / reference browsing:
|
||
- `ee/server/src/components/workflow-designer/workflowDataContext.ts`
|
||
- `ee/server/src/components/workflow-designer/workflowReferenceContext.ts`
|
||
- `ee/server/src/components/workflow-designer/workflowReferenceOptions.ts`
|
||
- Existing BlockNote inline-content pattern:
|
||
- `packages/ui/src/editor/Mention.tsx`
|
||
- `packages/ui/src/editor/TextEditor.tsx`
|
||
|
||
## Design Notes
|
||
|
||
- Earlier brainstorming started with “ordered literal/reference segments”.
|
||
- Rich markdown authoring adds one more layer:
|
||
- persisted model likely needs an Alga-owned block/inline template document rather than a flat segment array
|
||
- runtime still emits plain markdown strings
|
||
- Keep the authoring model narrower than a general-purpose document editor.
|
||
- Good default markdown-safe subset for v1:
|
||
- paragraphs
|
||
- headings (possibly limited)
|
||
- bullet/ordered lists
|
||
- blockquote
|
||
- code block
|
||
- bold / italic / code / links
|
||
- Avoid underline-specific storage because it is not naturally markdown-native.
|
||
|
||
## Open Implementation Questions To Revisit
|
||
|
||
- Exact allowed markdown block subset for v1.
|
||
- Whether to expose explicit stable-key regeneration in the first UX pass.
|
||
- Whether to show serialized markdown preview in the editor or rely on the main WYSIWYG surface plus copy-path affordances.
|
||
|
||
## Validation / Commands
|
||
|
||
- Inspect existing transform action patterns:
|
||
- `sed -n '1,430p' shared/workflow/runtime/actions/registerTransformActions.ts`
|
||
- Inspect dynamic output schema resolution:
|
||
- `sed -n '1,220p' shared/workflow/runtime/actions/actionOutputSchemaResolver.ts`
|
||
- Inspect workflow reference-path assumptions:
|
||
- `nl -ba ee/server/src/components/workflow-designer/workflowDataContext.ts | sed -n '406,417p'`
|
||
- `nl -ba ee/server/src/components/workflow-designer/WorkflowActionInputSourceMode.tsx | sed -n '31,36p'`
|
||
- Inspect existing BlockNote inline content example:
|
||
- `sed -n '1,80p' packages/ui/src/editor/Mention.tsx`
|
||
|
||
## Gotchas
|
||
|
||
- Do not promise “freeform runtime field names” unless the workflow reference grammar is expanded; current dot-path resolution does not support arbitrary string keys.
|
||
- Do not let BlockNote JSON become the persisted workflow contract just because it is convenient in the editor.
|
||
- Do not solve prompt composition only inside `ai.infer`; that would recreate the layering problem this plan is meant to avoid.
|
||
- Avoid making compose-text a generic expression engine; user explicitly wants simple references only in this phase.
|
||
|
||
## Implementation Log
|
||
|
||
- 2026-03-14: Completed runtime/schema milestone covering `F001`-`F005`, `F007`-`F011`, `F019`-`F025`.
|
||
- Added shared compose-text runtime/model helpers in `shared/workflow/runtime/actions/composeText.ts`.
|
||
- Registered `transform.compose_text` in `shared/workflow/runtime/actions/registerTransformActions.ts` with Transform metadata and broad string-record output validation.
|
||
- Added `outputs` support plus compose-text config validation to `shared/workflow/runtime/nodes/registerDefaultNodes.ts`.
|
||
- Extended runtime action execution context in `shared/workflow/runtime/registries/actionRegistry.ts` and `shared/workflow/runtime/runtime/workflowRuntimeV2.ts` so compose-text can resolve reference nodes against workflow context at execution time.
|
||
- Extended config-derived output schema resolution in `shared/workflow/runtime/actions/actionOutputSchemaResolver.ts` and downstream vars typing in `ee/server/src/components/workflow-designer/workflowDataContext.ts`.
|
||
- Exported compose-text helpers through `shared/workflow/runtime/index.ts` and `ee/packages/workflows/src/authoring/index.ts`.
|
||
- Decision: keep persisted compose-text outputs on `action.call` config as top-level `outputs`.
|
||
- Rationale: this matches the PRD’s persisted config shape and keeps the stored contract independent from `inputMapping`.
|
||
- Consequence: the runtime action reads `ctx.stepConfig.outputs`, and the generic `action.call` node schema now allows/validates `outputs` for compose-text steps.
|
||
- Decision: resolve compose-text references with a dedicated simple-path resolver instead of full expression evaluation.
|
||
- Rationale: missing paths need deterministic “missing reference” semantics, while full expression evaluation converts `undefined` into a generic serialization error.
|
||
- Consequence: reference nodes stay limited to simple workflow paths and fail with explicit output/reference context.
|
||
- Decision: spread `env.vars` into the action expression context root in `WorkflowRuntimeV2`.
|
||
- Rationale: compose-text simple references and existing designer reference affordances both allow bare variable roots like loop item vars.
|
||
- Consequence: action handlers can resolve `vars.*` and bare saved-variable roots from the same runtime context.
|
||
|
||
## Verification
|
||
|
||
- Runtime/unit tests:
|
||
- `cd shared && pnpm vitest run workflow/runtime/actions/__tests__/composeText.test.ts workflow/runtime/actions/__tests__/registerTransformActions.test.ts workflow/runtime/actions/__tests__/actionOutputSchemaResolver.test.ts`
|
||
- Designer vars-context test:
|
||
- `cd ee/server && pnpm vitest run src/components/workflow-designer/__tests__/workflowDataContext.test.ts`
|
||
- Targeted lint:
|
||
- `pnpm eslint shared/workflow/runtime/actions/composeText.ts shared/workflow/runtime/actions/registerTransformActions.ts shared/workflow/runtime/actions/actionOutputSchemaResolver.ts shared/workflow/runtime/registries/actionRegistry.ts shared/workflow/runtime/runtime/workflowRuntimeV2.ts shared/workflow/runtime/nodes/registerDefaultNodes.ts ee/server/src/components/workflow-designer/workflowDataContext.ts shared/workflow/runtime/actions/__tests__/composeText.test.ts shared/workflow/runtime/actions/__tests__/registerTransformActions.test.ts shared/workflow/runtime/actions/__tests__/actionOutputSchemaResolver.test.ts ee/server/src/components/workflow-designer/__tests__/workflowDataContext.test.ts`
|
||
- Result: warnings only from pre-existing broad files; no new eslint errors in the touched code.
|
||
|
||
## Implementation Log Continued
|
||
|
||
- 2026-03-14: Completed designer/editor milestone covering `F006`, `F012`-`F018`, `F026`-`F028`.
|
||
- Added `ee/server/src/components/workflow-designer/workflowComposeTextUtils.ts` for empty-output creation, stable-key/reference-path helpers, template-document serialization/hydration, and shared authoring validation.
|
||
- Added `ee/server/src/components/workflow-designer/WorkflowComposeTextDocumentEditor.tsx` as a constrained BlockNote authoring surface with a custom inline `workflowReference` chip and a markdown-safe schema subset only.
|
||
- Added `ee/server/src/components/workflow-designer/WorkflowComposeTextSection.tsx` as the dedicated compose-text action editor with output list management, label/key controls, copyable downstream paths, inline validation, and reference insertion from `SourceDataTree`.
|
||
- Wired the dedicated section into `ee/server/src/components/workflow-designer/WorkflowDesigner.tsx` so compose-text remains action-specific and ordinary consumer fields continue using the existing generic reference mode.
|
||
- Updated `ee/server/src/components/workflow-designer/workflowReferenceOptions.ts` so downstream browsing keeps stable-key paths while surfacing author-facing output labels.
|
||
- Updated `ee/server/src/components/workflow-designer/groupedActionSelection.ts` so switching grouped action types clears stale AI-only and compose-text-only config payloads deterministically.
|
||
- Decision: expose manual stable-key editing plus an explicit regenerate affordance, but keep label edits non-destructive by default.
|
||
- Rationale: downstream references must stay stable across label changes, yet authors still need a recovery path when the generated key is poor.
|
||
- Consequence: the UI treats label and stable key as separate fields and only regenerates the key on deliberate author action.
|
||
- Decision: keep reference insertion constrained to the existing workflow source browser instead of supporting arbitrary inline path typing in the editor.
|
||
- Rationale: that preserves the “simple references only” scope, reuses existing browsing UX, and avoids inventing a second validation path.
|
||
- Consequence: invalid reference insertion is limited mostly to unsupported editor locations such as code blocks, which now produce explicit authoring feedback.
|
||
|
||
- 2026-03-14: Completed test milestone covering `T005`, `T011`-`T013`, `T024`, `T026`-`T044`.
|
||
- Added `ee/server/src/components/workflow-designer/__tests__/workflowComposeTextUtils.test.ts` for stable-key preservation, template serialization/hydration, schema-subset enforcement, and persisted-config regression coverage.
|
||
- Added `ee/server/src/components/workflow-designer/__tests__/WorkflowComposeTextSection.test.tsx` for multi-output list UX, add/reorder flows, key/path display, reference insertion/removal serialization, and inline validation coverage.
|
||
- Added `ee/server/src/components/workflow-designer/__tests__/WorkflowComposeTextDocumentEditor.test.tsx` for inline reference insertion and unsupported BlockNote-affordance removal.
|
||
- Extended `shared/workflow/runtime/actions/__tests__/actionOutputSchemaResolver.test.ts` for config-derived schema updates when output labels change but stable keys do not.
|
||
- Extended `ee/server/src/components/workflow-designer/__tests__/groupedActionSelection.test.ts` and `workflowReferenceOptions.test.ts` for grouped-action cleanup and author-label reference browsing behavior.
|
||
- Existing runtime registration/execution tests plus downstream vars-context tests now cover the ordinary-reference integration path for AI/email-like consumers without any consumer-specific compose-text wiring.
|
||
|
||
- Additional targeted verification:
|
||
- `npx vitest run --config shared/vitest.config.ts shared/workflow/runtime/actions/__tests__/composeText.test.ts shared/workflow/runtime/actions/__tests__/registerTransformActions.test.ts shared/workflow/runtime/actions/__tests__/actionOutputSchemaResolver.test.ts`
|
||
- `npx vitest run --config vitest.config.ts src/components/workflow-designer/__tests__/workflowDataContext.test.ts src/components/workflow-designer/__tests__/workflowReferenceOptions.test.ts src/components/workflow-designer/__tests__/groupedActionSelection.test.ts src/components/workflow-designer/__tests__/workflowComposeTextUtils.test.ts src/components/workflow-designer/__tests__/WorkflowComposeTextSection.test.tsx src/components/workflow-designer/__tests__/WorkflowComposeTextDocumentEditor.test.tsx src/components/workflow-designer/__tests__/WorkflowDesigner.smoke.test.tsx`
|
||
- `cd ee/packages/workflows && npx vitest run src/authoring/__tests__/composeTextAuthoring.test.ts --coverage.enabled false`
|
||
- Result: all targeted compose-text runtime and designer tests passed.
|
||
|
||
- 2026-03-14: Folded package-level authoring helpers into the final checkpoint.
|
||
- Kept `ee/packages/workflows/src/authoring/composeTextAuthoring.ts` exported from `ee/packages/workflows/src/authoring/index.ts` so non-server authoring consumers can use the same compose-text helper/model conversions.
|
||
- Verified `ee/packages/workflows/src/authoring/__tests__/composeTextAuthoring.test.ts` passes from the package root.
|