Hermes 284313f908
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
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

14 KiB
Raw Blame History

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 PRDs 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.