Skip to content

[Feat] Web UI: author, run-with-inputs, approve, and monitor a saved workflow #789

Description

@sujoydc

[Feat] Web UI: author, run-with-inputs, approve, and monitor a saved workflow

Overview

Today the Workflows tab is read-only. WorkflowsPanel.tsx and web/src/api.ts call
GET /workflows/runs, GET /workflows/runs/{id}, /events, /compare, /diagnostics
and DELETE /workflows/runs/{id}, and nothing else. A user who wants to run a saved
workflow has to leave the browser, open a terminal, and type cao workflow run <name> --inputs .... A user who wants to create one has to hand-write a file into
~/.aws/cli-agent-orchestrator/workflows/ (the unguarded path #698 describes), or drive
an agent through the cao-workflow skill.

The server already has every route the UI needs to close that gap: GET /workflows,
GET /workflows/{name} (returns inputs{} with type / required / default),
POST /workflows/validate, POST /workflows/runs:submit (202, non-blocking),
GET /workflows/runs/{id}/plan, POST /workflows/plans/approve, and once #699 lands,
the guarded create/update write path. The run detail view with the live event timeline
already exists too.

This issue proposes making the Workflows tab a complete surface: pick a saved workflow,
fill in its declared inputs from a generated form, submit, approve the frozen plan when
the gate asks for it, and land on the existing run timeline. Then, as a second step, let
the user create and edit the workflow spec from the same tab, using the same guarded
write path and the same validator the CLI uses. The workflow name stays the durable id,
so "run it again" is one click and the same name works from the CLI and from another
agent.

This is where the Profiles work (#510, shipped as #575 / #585 / #692) was heading. Profiles
gave the UI a place to create and validate the workers; this gives it a place to compose
those workers into a saved workflow and run it. The step form's agent picker reads the
same catalog the Profiles tab writes, so the two surfaces close the loop: author a
profile, use it in a step, run the workflow, watch the run. We can say, the UI half of #583.

Parent roadmap: #583. Depends on: #699 (create/update surfaces). Related: #601 (agent
authors the workflow; this issue is the human editing and launching it), #640 (single-step
re-execute, which the run detail view can expose later), #641 (mid-run approval gates; the
plan-approval view here should generalise to those when they land), #356 (Runs dashboard
RFC for sessions; different object, see Alternatives), #519 (AG-UI operator surfaces;
different UI stack, default-off, see Alternatives), #777 / #774 / #780 (CAO 3.0 ownership
and sharing; this issue stays inside the single-user laptop case and does not pre-empt
them), #510 / #692 (Profiles tab, the pattern this follows).

User Stories

  • As a service owner running a recurring end-to-end test against a beta stack, I want to
    open the Workflows tab, pick adsp-ecs-e2e, fill in table_name, entity_id and
    log_group, press Run, and watch the steps go green, so that I do not need a terminal
    or a hand-rolled status page for each service I own.
  • As the same owner, I want to run that exact workflow again next week with different
    input values, without editing any file, so that one saved artifact covers every
    environment.
  • As a workflow author, I want to create a new sequential workflow in the browser by
    choosing agent profiles from the catalog for each step and writing the prompt, and to
    see the validator's findings before the file is saved, so that CAO never writes a spec
    it would refuse to run.
  • As a Python workflow author, I want to paste or edit a .py spec in the browser and
    get the same lint findings cao workflow validate prints, so that I fix
    missing-recovery-policy and non-determinism warnings before the first run.
  • As the human in the loop, when the run stops on plan approval I want to read the frozen
    plan in the UI (steps, profiles, providers, inputs) and approve it there, so that the
    approval stays a deliberate human act but does not require switching to a terminal.
  • As a teammate who was told "run adsp-ecs-e2e on the shared box", I want to open the
    UI, find the workflow by name, and run it with my own inputs, so that the author does
    not have to be present.

Acceptance Criteria

Run (PR A)

  • The Workflows tab lists saved workflows from GET /workflows (name, tier, description,
    declared inputs) next to the existing run list.
  • Selecting a workflow shows a Run form generated from GET /workflows/{name}'s inputs:
    one control per declared input, typed by InputDecl.type (string, int, bool,
    path), required inputs marked, defaults pre-filled. No hand-written per-workflow form.
  • Submit calls POST /workflows/runs:submit with {name_or_path, inputs, run_id?} and
    navigates to the existing RunDetail for the returned run_id. The UI never uses the
    blocking POST /workflows/runs.
  • A 422 from input validation is shown next to the offending field, not as a toast.
  • A 403 PlanApprovalRequiredError opens a plan view fed by
    GET /workflows/runs/{run_id}/plan, with an Approve action that calls
    POST /workflows/plans/approve. A 503 PlanIdentityUnavailableError shows "retry",
    not an approval prompt (the two causes feat(workflow): conversational authoring — create/update surfaces, approval on by default (#583 Bolt 3) #699 separated must stay separate in the UI).
  • The Run action is disabled with an explanatory title when the token lacks
    cao:write; Approve is disabled without cao:write or cao:admin. The UI adds no
    approval path an agent could call; it only renders the existing human route.
  • A visible note on the form: inputs are journaled in plaintext and replayed on resume;
    do not enter secrets (mirrors R2 of the cao-workflow skill).
  • Delete workflow (DELETE /workflows/{name}, cao:admin) behind a confirm modal.

Author (PR B)

  • Create and Edit open a schema-driven form for the YAML sequential tier: name,
    description, inputs (add/remove typed declarations), ordered steps with
    provider, agent (picker fed by the profiles catalog), prompt, on_failure,
    retries. Object-valued or reserved fields are not invented in the UI; anything the
    form does not model is left to the raw editor.
  • A raw editor tab for the Python tier with the lint findings from
    POST /workflows/validate rendered by the existing ValidationFindings component.
    Save is blocked while any error-severity finding is present; warnings are shown and
    do not block.
  • Save goes through the feat(workflow): conversational authoring — create/update surfaces, approval on by default (#583 Bolt 3) #699 create/update route only. The UI never writes to the
    workflows directory itself and never bypasses the tier-collision check.
  • Editing a workflow that has runs shows a note that the change affects future runs
    only; existing runs keep their frozen manifest.

Both

  • No change to AgentPanel, Profiles, Flows or the mcp-apps surface.
  • tsc -b and the existing web tests pass; new components have unit tests for the form
    generator (each InputDecl.type, required, default) and for the 403 / 503 / 422
    branches.

Proposed solution

Frontend (web/src/)

  • components/workflow/WorkflowCatalog.tsx: list of saved workflows, select to open Run
    or Edit. Sits left of the existing run list inside WorkflowsPanel.tsx.
  • components/workflow/RunWorkflowModal.tsx: form generated from inputs{}; submit,
    422 field errors, secret warning.
  • components/workflow/PlanApprovalModal.tsx: renders the frozen plan, Approve button,
    distinguishes 403 from 503.
  • components/workflow/WorkflowEditorModal.tsx (PR B): schema-driven YAML form plus raw
    editor, wired to POST /workflows/validate and the create/update route; reuses
    ValidationFindings.tsx and the profile catalog fetch already used by ProfilesPanel.
  • api.ts: add listWorkflows, getWorkflow, validateWorkflow, submitWorkflowRun,
    getRunPlan, approvePlan, deleteWorkflow, and (after feat(workflow): conversational authoring — create/update surfaces, approval on by default (#583 Bolt 3) #699) createWorkflow /
    updateWorkflow.
  • Store slice: workflowCatalog alongside the existing workflowRuns slice; no change
    to the runs slice.

Backend

Sequencing

  1. PR A, run-with-inputs plus plan approval plus delete. Backend-complete today, small,
    independently useful.
  2. PR B, create/edit. After feat(workflow): conversational authoring — create/update surfaces, approval on by default (#583 Bolt 3) #699 merges.
  3. Out of scope here: sharing. The CAO 3.0 vision ([Vision] CAO 3.0 — run anywhere, shared by your whole organisation as a multi-tenant SaaS #777) already owns this. [Feat] Sign in with SAML or Entra ID, and give every resource an owner #774 gives
    every workflow an owner, [Feat] Sharing and visibility within a tenant (schema in 3.0, experience after) #780 adds the visibility schema in 3.0 and defers the sharing
    experience to after 3.0. So this issue does not propose an export bundle or a run-only
    token; when [Feat] Sharing and visibility within a tenant (schema in 3.0, experience after) #780's "experience after" phase arrives, the catalog and run form here are
    the surface a Share control would attach to. One thing PR A should do now so it does
    not fight 3.0 later: treat the workflow identity as whatever GET /workflows returns,
    not as a bare global name, since [Vision] CAO 3.0 — run anywhere, shared by your whole organisation as a multi-tenant SaaS #777 makes Alice's deploy and Bob's deploy two
    different records.

Additional context

Is your feature request related to a problem? Please describe.

I built a supervisor-plus-workers integration test for a service on CAO v2.2.0 (a
test-supervisor profile doing sequential handoffs, a STATUS_FILE written with jq,
a tmux cleanup loop, and a Flask plus React page to watch it). Every piece of that is now
a CAO workflow feature: journal, resume, plan approval, per-step recovery policy, and the
Workflows tab timeline. I want to rebuild it for two new services as saved workflows, but
the last mile is the terminal: cao workflow run for every run, and a hand-written file
for every edit. For a teammate who is not the author, that is the difference between
"open the tab and press Run" and "learn the CLI first". The Profiles tab was the first
half of fixing this (workers you can create and validate in the browser); the workflow
that uses them is the second half, and the part I actually set out to build.

Describe alternatives you've considered

Additional context

Questions I would like a nod on before opening PR A:

  1. PR split as A (run/approve/delete) then B (author), or one PR?
  2. Does plan approval belong in the UI at all? My reading of feat(workflow): conversational authoring — create/update surfaces, approval on by default (#583 Bolt 3) #699 is that FR-8 forbids an
    agent granting approval, not a human clicking a button that calls the same route
    cao workflow approve uses. If the maintainers want approval to stay CLI-only, PR A
    will show the plan read-only with the exact CLI command to run.
  3. Placement: inside the existing Workflows tab (my preference, no new tab), or a
    separate tab?
  4. For PR B, YAML form plus Python raw editor, or Python raw editor only?

Evidence from main at 29b235c (2026-09-14): web/src/components/WorkflowsPanel.tsx
and web/src/api.ts contain only the read routes listed above; POST /workflows/runs
and POST /workflows/runs:submit require cao:write or cao:admin;
POST /workflows/plans/approve accepts cao:write or cao:admin;
DELETE /workflows/{name} requires cao:admin; WorkflowSpec.inputs is
Dict[str, InputDecl] with type: Literal["string","int","bool","path"],
required, default.

I am happy to take PR A as soon as the split and placement are agreed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions