plungeai-workflows
Workflows — execute_workflow, get_workflow_status, list_workflows, workflow, build_workflow, executions
Workflows are CNL YAML run by the platform engine.
Workflows are CNL YAML run by the platform engine. Authoring guidance (task types, recipes, validation rules) lives in this plungeai-workflows skill — this file covers the MCP tools that run, manage, and observe them. Everything these tools create syncs live to Studio and peer apps (one account, same data, every surface).
plungeai_execute_workflow
Purpose: execute a CNL workflow — either a saved one (workflow_id) or
ad-hoc YAML (workflow_yaml). One of the two is required.
Parameters
| Param | Type | Notes |
|---|---|---|
workflow_yaml | string ≤256 KiB | Ad-hoc CNL. The workflow: wrapper is optional — bare top-level name:/tasks: is wrapped automatically. |
workflow_id | string | A saved workflow the caller owns (from plungeai_list_workflows). |
input | string ≤65536 | Fills {input} placeholders; also becomes the run's display title. |
inputs | map string→string (values ≤8192) | Named inputs for multi-input workflows. |
mode | sync | async | Sync (default) streams progress and returns the result. Async returns an execution_id immediately — use for runs that could exceed ~3 minutes. |
Example (ad-hoc, sync)
{"user_request": "get me the latest AI news",
"workflow_yaml": "name: quick\ntasks:\n - agent: brave-agent\n prompt: \"{input}\"\n",
"input": "latest AI news"}Example (saved, async)
{"user_request": "run my due diligence workflow on Acme",
"workflow_id": "wf-1234...", "input": "Acme Corp", "mode": "async"}Returns: an outcome envelope. Sync ok → the final output + execution-id
footer; a paused run → needs_approval/needs_input with the ⏸ block.
Async → "Started execution <id> (async). Poll plungeai_get_workflow_status
..., then fetch output with plungeai_get_result. If the status reports
⏸ AWAITING USER APPROVAL or AWAITING USER, relay it to the user and continue
with plungeai_continue." — follow that script literally.
Failures & fixes
- Neither
workflow_yamlnorworkflow_id→needs_input; provide one. - "No saved workflow with id ... on this account." → list with
plungeai_list_workflowsand use a real id (ownership is enforced). - Ad-hoc YAML naming an unknown/inactive agent →
unavailablerefusal BEFORE dispatch (the fence walks nestedparallel/sequentialblocks too). Re-discover the agent id; a refusal writes no execution row. - "Invalid YAML" → the envelope carries a repair tip: quote any value
containing a colon (
prompt: "DD: memo"), write long strings as block scalars (prompt: |) and never hard-wrap a value — or compose withplungeai_build_workflowinstead. - Timeout in sync mode → remediation says
retry_with {mode: "async"}; do that rather than re-running sync.
plungeai_get_workflow_status
Purpose: check one of the caller's executions. Self-heals stuck rows: a
"running" row whose result already landed flips to completed; a run silent
for over 15 minutes flips to failed ("Interrupted") — so a dead async run
never reads "running" forever. Read-only.
Parameters: execution_id (required). Engine ids (exec-..., hyphen)
resolve too; scheduler run ids (exec_..., underscore) are redirected to
plungeai_schedule {action: "runs"}.
Example
{"user_request": "is my report done yet?", "execution_id": "d3adb33f-..."}Returns: markdown (workflow, status, error if failed, started, duration,
final task) plus structuredContent a machine mirror:
{"execution_id": "...", "status": "running|completed|failed",
"error_message": null, "workflow_name": "...", "started_at": "...",
"duration_ms": 1234, "final_task_id": "...",
"continuation": {"status": "needs_approval", "agent": "...",
"question": null, "pending_action": {"summary": "...", "price": "..."}}}continuation is non-null when the run is PAUSED awaiting the user (async
pollers meet approvals here first). Its status is one of two values:
"needs_approval" (the ⏸ AWAITING USER APPROVAL block; pending_action
carries the summary/price) or "question" (the ⏸ AWAITING USER block;
question carries the text). Either way: relay it and use
plungeai_continue. status: completed → fetch output with
plungeai_get_result. Full conversation/HITL protocol: plungeai-results-traces.
Failures & fixes: "No execution found for ID" → wrong/foreign id (take it from a footer or the executions list). "Status storage is temporarily unavailable" → transient, retry in a moment.
Polling etiquette: poll every few seconds for short runs, backing off for
missions; stop on completed/failed or a non-null continuation.
plungeai_list_workflows
Purpose: the user's SAVED workflows — what users usually mean by "my agents". Read-only.
Parameters: search (name contains), folder (folder name contains),
limit (1–100, default 50).
Behavior: with no filters, the answer opens with a folder overview
(non-empty folders only, with counts) and a recency-ordered table — Name,
Kind (workflow/agent/bot), Folder, ID, Description. With filters, just
the matching table.
Example: {"user_request": "show my agents in the finance folder", "folder": "Finance"}
Failures & fixes: "No workflows found." → offer plungeai_workflow {action: "create"}, plungeai_build_workflow, or plungeai_templates. "No
workflows matched." → list without filters to see real folder names.
plungeai_workflow (CRUD + versioning)
Purpose: manage saved workflows directly. Every write syncs live to Studio and peer apps.
Actions & required params
| Action | Requires | Notes |
|---|---|---|
create | name, yaml | Server-side CNL validation first — a refusal lists field errors; fix exactly those. Optional description, folder (filed via create-then-move), kind (workflow | agent | bot — the sidebar section). |
get | workflow_id | Returns name, description, and the full YAML block. |
update | workflow_id | Any of name, description, yaml (re-validated), folder (move; "none" or "" clears), kind. |
delete | workflow_id | Removes it everywhere. |
save_version | workflow_id | Snapshot (optional version_description) — do this before big edits. |
list_versions | workflow_id | Version table (V#, id, when, note). |
get_version | workflow_id, version_id | That version's YAML. |
restore_version | workflow_id, version_id | Restores as a NEW version. |
Example
{"user_request": "save this as a workflow called Daily Brief",
"action": "create", "name": "Daily Brief",
"yaml": "name: daily-brief\ntasks:\n - agent: brave-agent\n prompt: \"{input}\"\n",
"description": "Morning news brief", "folder": "News"}Failures & fixes: "Workflow YAML failed CNL validation: <field errors>" →
fix exactly the named fields (see this skill's CNL rules), retry once.
"Workflow not found." → not this user's id — re-list.
Folder misses split by action: on create the miss is non-fatal (⚠️ "…
created without a folder." — fix later with update); on update a folder
miss FAILS the whole update — No folder matched "<name>". Your folders: <list> — and NONE of the other patch fields (name/yaml/kind/description) are
applied. The error lists your real folder names: pick one and re-send the
full update. Validation ⚠️ warnings are non-fatal — surface them.
plungeai_build_workflow
Purpose: have the platform builder generate (or refine) a workflow from natural language. It picks REAL registry agents, validates, self-repairs, and saves — the fastest correct path when the user describes an outcome rather than YAML.
Parameters: either goal (new workflow) or workflow_id + instruction
(regenerate an existing one with a change applied).
Example: {"user_request": "build me a workflow that researches a company and drafts an outreach email", "goal": "Research a company from its name, then draft a personalized outreach email"}
Returns: "Created workflow <name> (<id>). Synced to all apps. Run
it with plungeai_execute_workflow." plus the full generated YAML. Expect
30–60s (a single generation call with an internal self-repair loop) —
progress notifications cover the wait; don't re-call mid-generation.
Failures & fixes: "Generated workflow failed CNL validation: ..." (rare —
includes the YAML) → retry once with a sharper goal, or hand-fix the YAML
and save via plungeai_workflow {action: "create"}. "Workflow not found" on
refine → wrong workflow_id.
plungeai_executions
Purpose: browse and manage the caller's execution history. Outputs are final user-ready markdown — relay tables and threads verbatim.
Actions
| Action | Requires | Returns |
|---|---|---|
list | — (optional workflow_id filter, limit default 20, offset) | Table: ID · Question (the run's own input) · Workflow · Status · When (newest first). |
get | execution_id | Same view as plungeai_get_workflow_status. |
output | execution_id | Same as plungeai_get_result. |
conversation | execution_id | The run's follow-up thread (all User/Agent turns). |
delete | execution_id | Removes the run row and its stored result (the run's follow-up conversation thread is not purged). |
Example: {"user_request": "show my last 10 runs", "action": "list", "limit": 10}
Failures & fixes: "Execution not found." → foreign/wrong id. "No
conversation thread for this execution yet." → the run had no follow-ups —
offer plungeai_followup. "Conversation storage is temporarily unavailable"
→ transient, retry.
Numbered references: when the user says "show me #2", resolve against the
exact list YOU displayed earlier in the conversation and use that row's ID —
never against a fresh list, because new runs shift the numbering.
plungeai_templates — instantiating a template as a workflow (action: "use")
Purpose: the workflow-template gallery — browse, inspect, and turn a
template into your own saved workflow. Browsing (action: "list"/"get") is
documented in the plungeai-discovery skill
(references/list-and-contract.md); this section covers action: "use",
which is workflow authoring, not discovery — it creates a saved workflow you
then run and iterate like any other.
Parameters
| Param | Type | Notes |
|---|---|---|
action | "list" | "get" | "use" | list/get — see plungeai-discovery. |
template_id | string, required | The template to instantiate (from a list/get call). |
name | string ≤512 | The new workflow's name. Default <template name> (copy) — except a bot-kind template, which defaults to the template's own name with no "(copy)" suffix. |
folder | string | Files the new workflow into a folder by name. A miss is non-fatal — the workflow is still created, with a ⚠️ "created without a folder" note. |
Example
{"user_request": "start from a research template", "action": "use",
"template_id": "tpl-...", "name": "My research pipeline", "folder": "Research"}Returns: creates a saved workflow that carries the template's kind
(workflow/agent/bot) and its full YAML content, bumps the template's
usage count, and replies "Created workflow <name> (<id>) from template
<template>. ... Run it with plungeai_execute_workflow." Iterate the
result afterward with plungeai_workflow {action: "update"} like any other
saved workflow — use does not create a special kind of object.
Failures & fixes: use without template_id → "template_id is required
for this action." — supply the id from a list call. Unknown template_id
→ "Template not found: <id>" — re-list, ids can go stale. "Template content
missing from storage." → a platform-side gap; report it rather than
retrying.