Forge

Multi-step LLM workflows as directed acyclic graphs.

Workflows

Define multi-step workflows where each step can be an LLM call, a transform, or a tool call. Steps declare dependencies and execute in topological order.

# Create a workflow
curl -X POST http://localhost:4200/api/forge/workflows \
  -d '{
    "slug": "draft-and-critique",
    "name": "Draft + Critique",
    "steps": [
      {"id":"draft","type":"llm","config":{"model":"gpt-4o-mini","prompt":"Write about {{input}}"}},
      {"id":"critique","type":"llm","depends_on":["draft"],
       "config":{"prompt":"Critique: {{steps.draft.output}}"}},
      {"id":"final","type":"transform","depends_on":["draft","critique"],
       "config":{"expression":"concat"}}
    ]
  }'

Running Workflows

# Run it
curl -X POST http://localhost:4200/api/forge/workflows/draft-and-critique/run \
  -d '{"input": "the future of AI"}'

# Check status
curl http://localhost:4200/api/forge/runs/{run_id}

Step Types

Step types: llm (calls the proxy), transform (concat, extract_json, first_line), tool (external tool calls).

Template variables: {{input}} for the run input, {{steps.step_id.output}} for dependency outputs.

Tool Registry

# List registered tools
curl http://localhost:4200/api/forge/tools

See the Forge product page and the visual workflow builder.

Creating Workflows

Forge uses DAG (directed acyclic graph) definitions to chain LLM calls, transforms, and tool invocations:

curl -X POST http://localhost:4200/api/forge/workflows \
  -H "Authorization: Bearer sy_admin_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "summarize-and-translate",
    "steps": [
      {
        "id": "summarize",
        "type": "llm",
        "model": "gpt-4o",
        "prompt": "Summarize: {{input}}"
      },
      {
        "id": "translate",
        "type": "llm",
        "model": "gpt-4o",
        "prompt": "Translate to Spanish: {{summarize.output}}",
        "depends_on": ["summarize"]
      }
    ]
  }'
{
  "id": "wf_abc123",
  "name": "summarize-and-translate",
  "steps": 2,
  "created_at": "2026-02-28T12:00:00Z"
}

Running Workflows

curl -X POST http://localhost:4200/api/forge/workflows/wf_abc123/run \
  -H "Authorization: Bearer sy_admin_..." \
  -H "Content-Type: application/json" \
  -d '{"input": "The quarterly results showed a 15% increase in revenue..."}'
{
  "run_id": "run_xyz789",
  "workflow_id": "wf_abc123",
  "status": "completed",
  "steps": {
    "summarize": {"status": "completed", "output": "Revenue increased 15% quarter-over-quarter..."},
    "translate": {"status": "completed", "output": "Los ingresos aumentaron un 15%..."}
  },
  "total_cost_usd": 0.012,
  "duration_ms": 2400
}

Listing Workflows

curl http://localhost:4200/api/forge/workflows \
  -H "Authorization: Bearer sy_admin_..."

Workflow Detail

curl http://localhost:4200/api/forge/workflows/wf_abc123 \
  -H "Authorization: Bearer sy_admin_..."

Parallel Execution

Steps without dependencies run in parallel. The multicall module handles fan-out:

{
  "name": "multi-model-compare",
  "steps": [
    {"id": "gpt", "type": "llm", "model": "gpt-4o", "prompt": "{{input}}"},
    {"id": "claude", "type": "llm", "model": "claude-sonnet-4-5", "prompt": "{{input}}"},
    {"id": "pick_best", "type": "llm", "model": "gpt-4o",
     "prompt": "Pick the better answer:\nA: {{gpt.output}}\nB: {{claude.output}}",
     "depends_on": ["gpt", "claude"]}
  ]
}

Steps gpt and claude run simultaneously. pick_best waits for both.

Deleting Workflows

curl -X DELETE http://localhost:4200/api/forge/workflows/wf_abc123 \
  -H "Authorization: Bearer sy_admin_..."

Forge Configuration

# stockyard.yaml
apps:
  forge:
    max_workflows: 200
    max_steps_per_workflow: 20
    execution_timeout: 60s
    parallel_limit: 5
Tip: Use the mockllm module during workflow development to get deterministic outputs without burning tokens.

Step Types

Forge supports several step types within a workflow:

TypeDescriptionExample
llmCall an LLM with a promptSummarize, translate, classify
transformApply a data transformationExtract JSON, parse CSV
conditionBranch based on outputRoute based on sentiment
toolCall an external tool or APIWeb search, database lookup

Error Handling

Steps can define fallback behavior when they fail:

{
  "id": "classify",
  "type": "llm",
  "model": "gpt-4o",
  "prompt": "Classify: {{input}}",
  "on_error": {
    "action": "fallback",
    "fallback_model": "gpt-4o-mini",
    "max_retries": 2
  }
}

If the primary model fails, the step retries with the fallback model before reporting an error.

Workflow Tips

Testing: Use mockllm during development to test workflow structure without API calls. Enable it globally or per-step with a test flag.
Cost visibility: Each workflow run reports total_cost_usd so you can track per-workflow spending in Lookout.

Variable References

Steps reference outputs from other steps using {{step_id.output}} syntax. The Forge engine resolves these references and passes data between steps automatically:

# Available variables in each step
{{input}}              # Original workflow input
{{step_id.output}}     # Output from a completed step
{{step_id.status}}     # Step status (completed/failed)
{{step_id.cost_usd}}   # Cost of that step

API Summary

MethodPathDescription
GET/api/forge/workflowsList all workflows
POST/api/forge/workflowsCreate workflow
GET/api/forge/workflows/{id}Workflow detail and step definitions
POST/api/forge/workflows/{id}/runExecute and get results
DELETE/api/forge/workflows/{id}Delete workflow

Limits & Quotas

LimitDefaultConfigurable
Max workflows per instance200Yes
Max steps per workflow20Yes
Execution timeout60 secondsYes
Parallel step limit5Yes
Max input size100KBYes

Adjust limits in stockyard.yaml under apps.forge. Higher limits may increase memory usage during workflow execution.

Explore: Self-hosted proxy · OpenAI-compatible · Model aliasing