Skip to content

feat(workflows): runtime workflow variables — allow users to supply model and other parameters at dispatch time #1127

@fcamblor

Description

@fcamblor

Problem

  • When triggering a workflow, the model used for each node is fixed at authoring time (in the YAML) or falls back to the global default in ~/.archon/config.yaml.
  • The person who triggers a workflow is often the best judge of which model to use: a quick question warrants sonnet, a complex architectural plan warrants opus.
  • Today, to change the model for a run, the user must either edit the YAML, change the global config, or maintain multiple workflow copies — all heavyweight solutions for a routine decision.
  • Affected: CLI, Web UI, all chat platforms (Slack, Telegram, GitHub).

Proposed Solution

Introduce a workflow-level variables system (inputs: block in the YAML) that allows workflow authors to declare named parameters with optional defaults. These variables can be referenced via $VAR_NAME substitution anywhere the current variable system is accepted — including model:, systemPrompt:, node prompt:, when: conditions, etc.

Variables can be populated from three sources (in priority order):

  1. User-supplied at dispatch time — via CLI flags, Web UI form fields, or chat platform arguments.
  2. Node output — a bash: or script: node can emit a value that a downstream node reads via $nodeId.output, already supported today.
  3. Default value — declared in the inputs: block.

Example YAML

name: plan
description: "Generate an implementation plan"

inputs:
  PLAN_MODEL:
    description: "Claude model to use for the planning step"
    default: sonnet
    # future: type: model | string | bool

nodes:
  plan:
    prompt: plan.md
    model: $PLAN_MODEL

Dispatch examples

# CLI — override at dispatch time
bun run cli workflow run plan --set PLAN_MODEL=opus "Add dark mode"

# CLI — use default (sonnet)
bun run cli workflow run plan "Add dark mode"

In the Web UI, declared inputs: would render as a small form before the workflow is launched (similar to GitHub Actions' workflow_dispatch inputs).

User Flow

Before (current)

User wants to run "plan" workflow with opus for a complex task.
[!] Must edit .archon/workflows/plan.yaml → change model: sonnet to model: claude-opus-4-6
[!] Or change ~/.archon/config.yaml global default (affects all workflows)
[!] Or maintain plan-opus.yaml and plan-sonnet.yaml duplicates

After (proposed)

[+] Workflow declares: inputs: { PLAN_MODEL: { default: sonnet } }
[+] CLI: bun run cli workflow run plan --set PLAN_MODEL=opus "Add dark mode"
[+] Web UI: shows a "PLAN_MODEL" input field pre-filled with "sonnet" before launch
[+] Chat: bun run cli workflow run plan model=opus "Add dark mode"  (syntax TBD)
    No YAML edits needed. Each invocation is independent.

Alternatives Considered

Alternative Pros Cons Why not chosen
Duplicate workflow YAMLs (plan-opus.yaml, plan-sonnet.yaml) Zero new infrastructure Maintenance burden, diverge over time Doesn't scale
Edit global config before each run Simple Affects all workflows, error-prone, not concurrent-safe Too coarse-grained
Per-run model flag on the CLI (--model opus) Simple UX Only covers model, not other params; ambiguous which node it applies to Too narrow
Environment variable substitution (already exists via $VAR) Already supported Env vars are global, not workflow-scoped; no schema/defaults No dispatch-time UX

Scope

  • Package(s) likely affected: workflows, cli, web, server
  • Breaking change? No (additive — inputs: block is optional, existing YAMLs unaffected)
  • Database changes needed? Possibly — storing per-run input values in workflow_events or workflow_runs.metadata for replay/resume
  • New external dependencies? No

Security Considerations

  • New permissions/capabilities? No — variables only control already-supported parameters (model names, prompt text, etc.)
  • New external network calls? No
  • Secrets/tokens handling? No — variables should NOT be used to inject API keys (the env-vars system handles secrets separately)
  • If any Yes, describe: N/A

Definition of Done

  • inputs: block parsed and validated by loader.ts (Zod schema, unknown keys rejected)
  • Variable substitution in model:, prompt:, systemPrompt:, when: fields
  • CLI: --set KEY=VALUE flag(s) passed through to executor
  • Web UI: inputs: fields rendered as a form before workflow dispatch
  • Undeclared --set keys produce a warning (not a hard error) for forward-compatibility
  • Missing required inputs (no default, not supplied) fail fast with a clear error
  • Per-run input values recorded in run metadata (enables resume/audit)
  • Tests: substitution, default fallback, missing-required error, unknown-key warning
  • Documentation updated

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium priority - Backlog, when time permitsarea: cliCLI commands and interfacearea: webWeb UI (packages/web) - React frontendarea: workflowsWorkflow engineeffort/highCross-cutting changes, multiple domains, requires design decisionsfeatureNew functionality (planned)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions