> ## Documentation Index
> Fetch the complete documentation index at: https://docs.enconvo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Workflows

> Author agent-workflow/v1 YAML in the editor, with help from the built-in editing assistant

## Overview

You build a workflow by writing an `agent-workflow/v1` YAML document. This guide
covers the editor, the editing assistant, the anatomy of the DSL, and each
executor with a working snippet. For branching, loops, and end-to-end examples,
continue to [Advanced Workflows](/workflows/advanced-workflows).

## The workflow editor

Open **Settings → Workflows** and click **New workflow** to create one — it opens
immediately in the editor with a starter template you can shape. The editor has:

* **YAML source** on the left, with live validation. A **Valid / Invalid** badge
  and inline error messages tell you the moment something is off.
* **Flow preview** on the right — a read-only graph of your tasks and their
  dependencies, updated as you type.
* **Inputs** panel — provide values for a test run.
* **Run** — execute the workflow and watch each task's status and output. Click a
  node in the graph to inspect that step's output; the result pane shows the
  final output by default.
* **Runs** — recent run history for the workflow, so you can reopen a past run's
  output when debugging.

<Note>
  Saving writes the file to `~/.enconvo/workflows/<id>.yaml`. Keep the id (file
  name) stable — run history is keyed to it, so renaming orphans past runs.
</Note>

## The editing assistant

Below the YAML source is an **editing assistant**. Describe the change you want
in plain language — "add a step that searches the web for the topic and feed it
into the summary", "switch the summary to Claude Haiku", "wrap the last step in a
retry" — and the assistant edits the document for you.

The assistant knows the full DSL and can discover the APIs of your installed
plugins, so it wires up the right `tool:` paths and parameters. Its edits update
the YAML and flow graph live, leaving the changes **unsaved** so you can review
them before clicking **Save**.

<Tip>
  The assistant is the fastest way to learn the DSL: ask it to build the first
  version, then read the YAML it produced and tweak from there.
</Tip>

## Anatomy of a workflow

Every workflow has a small metadata header and a `tasks` map:

```yaml theme={null}
version: agent-workflow/v1     # required — must be exactly this
title: Quick Summary           # required — shown in SmartBar and the list
description: Summarize the given text into three bullet points.  # required
inputs:                        # optional — defaults, overridable per run
  text: ""
tasks:
  summarize:
    prompt: "Summarize into 3 bullets:\n{{ inputs.text }}"
```

<Warning>
  `version`, `title`, and `description` are all required and `title`/`description`
  must be non-empty. Each task must define **exactly one** executor.
</Warning>

### Inputs

Declare `inputs` with default values. Callers override them per run — the run
merges provided inputs over the file's defaults. When a workflow is launched from
SmartBar, the typed text arrives as `inputs.input_text`:

```yaml theme={null}
inputs:
  topic: AI news
  input_text: ""     # populated by SmartBar's typed query
tasks:
  research:
    prompt: "Give me 3 facts about {{ inputs.input_text or inputs.topic }}"
```

## Executors

### Shell — `run` / `command`

Runs a command in your login shell. `command:` is an alias of `run:`. The output
is an object, so reference `.stdout`, `.stderr`, `.exitCode`, or `.text`:

```yaml theme={null}
tasks:
  files:
    run: "ls -1 ~/Downloads | head -5"
  count:
    uses: transform
    value: "{{ tasks.files.output.stdout | trim }}"
```

Optional shell settings: `cwd`, `shell`, `timeoutMs`, and `env` (a map of
string/number/boolean values).

<Warning>
  Shell tasks run with your real shell and permissions. Prefer idempotent
  commands, and never write secrets into a workflow file.
</Warning>

### Prompt — one-shot LLM

A single LLM call. The output is the reply text (or parsed JSON when you attach
an `output_schema`, covered in [Advanced Workflows](/workflows/advanced-workflows)):

```yaml theme={null}
tasks:
  tagline:
    prompt: "Write a punchy one-line tagline for: {{ inputs.product }}"
```

### Agent — full agent delegation

Delegates to an agent that can use tools, read files, and browse. Provide the
agent command key and a `message`:

```yaml theme={null}
tasks:
  investigate:
    agent: agent/main
    message: "Find the current weather in {{ inputs.city }} and report it."
```

### Tool — call a plugin API

Calls any installed plugin's Local API endpoint by its slash path, with `params`.
You can discover the exact path and parameters for any plugin under
**Settings → Plugins** (open a plugin and copy an endpoint's path), or ask the
editing assistant:

```yaml theme={null}
tasks:
  search:
    tool: web_search/web_search
    params:
      search_query: "{{ inputs.topic }} latest news"
      limit: 5
```

### Transform — reshape data

Pure template evaluation with no side effects — useful for assembling a final
result from earlier task outputs:

```yaml theme={null}
tasks:
  report:
    uses: transform
    value: |
      # {{ inputs.topic }}
      {{ tasks.search.output.content }}
```

### Subworkflow — compose workflows

Run another workflow as a step, either by id or inline. Its output is the child
run result; reference the child's task outputs via `output.outputs.<taskId>`:

```yaml theme={null}
tasks:
  slugify:
    uses: workflow
    inputs:
      text: "{{ inputs.title }}"
    workflow:
      tasks:
        slug:
          run: "printf '%s' '{{ inputs.text }}' | tr ' A-Z' '-a-z'"
  use:
    uses: transform
    value: "slug is {{ tasks.slugify.output.outputs.slug.stdout }}"
```

## Referencing data with templates

Workflows use Nunjucks templates. The values available in any task:

| Reference                    | Available                                                  |
| ---------------------------- | ---------------------------------------------------------- |
| `{{ inputs.x }}`             | Workflow inputs                                            |
| `{{ tasks.<id>.output }}`    | An upstream task's output                                  |
| `{{ item }}` / `{{ index }}` | The current item/index inside a `foreach`                  |
| `{{ round }}` / `{{ last }}` | The round number / previous round's output inside a `loop` |
| `{{ now }}`                  | Current timestamp                                          |
| `{{ env.HOME }}`             | Process environment variables                              |

<Note>
  Shell output is an object — use `tasks.x.output.stdout`, not the bare
  `tasks.x.output`. Plugin tool tasks often return an assistant-message object; run
  the workflow once and inspect the real output shape before referencing nested
  fields.
</Note>

## Run, inspect, and save

<Steps>
  <Step title="Validate">
    The editor validates continuously. Fix any inline errors until the badge
    reads **Valid**.
  </Step>

  <Step title="Set inputs">
    Open the **Inputs** panel and provide test values.
  </Step>

  <Step title="Run">
    Click **Run**. Watch each task's status in the flow graph, and click a node
    to see that step's output.
  </Step>

  <Step title="Debug from history">
    If a run fails, open **Runs** and reopen it — the failing task's `error`,
    `stdout`, and `stderr` are recorded. Read them before editing.
  </Step>

  <Step title="Save">
    Click **Save** to write the file. It's now runnable from SmartBar and
    available as an `@` mention in chat.
  </Step>
</Steps>

## Related

<CardGroup cols={2}>
  <Card title="Advanced workflows" icon="wand-magic-sparkles" href="/workflows/advanced-workflows">
    Branching, loops, output schemas, subworkflows, and per-task models.
  </Card>

  <Card title="Plugins" icon="puzzle-piece" href="/extensions/overview">
    The plugins whose APIs you call from `tool:` tasks.
  </Card>
</CardGroup>
