Skip to main content

AI Workflow Generator

Instead of building a workflow node-by-node, describe it in plain English and let an LLM generate a complete, valid WorkflowDSL.

POST /api/v1/workflows/generate
{
"description": "Every morning at 9am, fetch the top 5 Hacker News stories and post a summary to Slack",
"provider": "anthropic",
"api_key": "{{ optional override }}",
"model": "claude-sonnet-4-6"
}
FieldDescription
descriptionNatural-language description of the desired automation.
provideranthropic (default), openai, nvidia, or custom (any OpenAI-compatible endpoint via base_url).
api_keyOptional — falls back to the platform's configured key (ANTHROPIC_API_KEY/OPENAI_API_KEY) if omitted.
modelOptional model override.
base_urlRequired when provider: "custom".

The response is a ready-to-save WorkflowDSL (trigger, steps, connector configs, prompts, expressions) — review it, then POST /api/v1/workflows to save and PUT /api/v1/workflows/{id}/enable to activate it.

How it works

generateWorkflowDSL sends a large system prompt (buildGeneratorSystemPrompt, ~200 lines) that documents:

  • Every node type and its config schema (http, llm, agent, condition, loop, connector, human-approval, etc.) with realistic examples — e.g.:
    llm: { "provider": "anthropic|openai|nvidia", "model": "claude-sonnet-4-6", "api_key": "{{ secret.ANTHROPIC_KEY }}", "prompt": "...", "system": "..." }
    agent: { "provider": "anthropic", "model": "claude-sonnet-4-6", "api_key": "{{ secret.ANTHROPIC_KEY }}", "prompt": "...", "max_turns": 10, "tools": [] }
    human-approval: { "message": "Please review", "notify_type": "slack", "notify_to": "#approvals", "notify_token": "{{ secret.SLACK_TOKEN }}" }
  • Available trigger types and connector tool schemas.
  • Expression syntax ({{steps.*}}, {{secret.*}}, {{vars.*}}, {{trigger.*}}).
  • The exact JSON shape expected for WorkflowDSL.

The model's response is parsed for a JSON object (extractJSON strips any surrounding prose/markdown fences) and returned as json.RawMessage. Generation typically takes 1-3 minutes depending on model and complexity, so the request uses an extended timeout.

Tips for good results

  • Mention the trigger explicitly ("every morning at 9am", "when a webhook is received", "when a new GitHub issue is opened").
  • Name the services involved ("Slack", "Gmail", "Postgres") so the generator picks the right connector types.
  • Describe conditions/branches explicitly ("if the amount is over $1000, require approval before...").
  • Treat the result as a draft — review credentials ({{ secret.* }} placeholders need real secrets created), connector connector_type values, and any approval/notification targets before enabling.

Next