Skip to content
published Visibility internal Owner erik@uvilo.com Approver _ Created _ Updated _

Forge Agents User Guide

How to use Forge’s multi-agent orchestration system — running workflows, creating new ones, and scheduling agent execution.


Current Workflows

Project Workflow

The Project Runner agent is the single project-aware entry point. It operates in two modes:

  • Interactive Mode — You hand off from Forge Chat to Project Runner under your account. You can approve phase transitions, ask questions, and make decisions in real-time.
  • Autonomous Mode — Runs hourly via cron. Reconciles stalled projects, catches orphaned completions, and confirms blocked projects have todo entries.

How agents hand off:

  1. When an SRP agent completes a phase and no human gate is required, it calls spawnAgent directly to invoke the next Bot — immediate, no waiting (happy path)
  2. When a human gate is required, the agent creates a todo item for you and stops — you review the persisted report and decide
  3. Project Runner runs hourly to catch anything the happy path missed: stalled agents, orphaned completions, missing todo entries
  4. For interactive work, you hand off from Forge Chat to Project Runner, which handles approvals and questions in conversation

Starting a project:

  1. Tell Forge Chat what you want to build (e.g., “Create a new project for adding quiz features”)
  2. Forge Chat hands off to Project Runner, which sets up the project and spawns the first agent
  3. From there, agents hand off to each other automatically via spawnAgent
  4. You only intervene when a human gate triggers a todo item

Manual trigger:

Spawn the Project Runner via spawnAgent to check all active projects for phase completions.

When you’ll see todo items:

  • A plan needs approval before implementation
  • A phase transition requires a human decision
  • A project is stuck or in an unexpected state
  • A blocking issue needs escalation

Task Workflow

The Task Runner agent checks agent todo items via the todos tool group for incomplete items and dispatches the correct SRP agent to handle each one.

How it works:

  1. Task Runner reads agent todo items via findTodoItems for incomplete items (⬜ or 🟨)
  2. For each task, determines the correct SRP agent:
    • Page creation/move/delete → Page Manager
    • Project implementation → Project Worker
    • Project evaluation → Project Evaluator
    • Planning/spec/requirements → Project Thinker
  3. Spawns the agent via spawnAgent (async mode for simple tasks, sync mode for complex ones)
  4. Updates the todo item with the conversationId for tracking
  5. On completion: marks ✅; on failure: marks 🚫 and creates a todo item for escalation

Adding tasks to the workflow:

Create agent todo items using createTodoItem:

createTodoItem({
  todoListId: "<todoListId>",
  name: "Create the new Onboarding page in the Product department",
  body: "Project: Onboarding, Phase: Execute, Action: Create page"
})

Task Runner will pick them up on its next hourly run.

Manual trigger:

Spawn the Task Runner via spawnAgent to process all incomplete agent todo items.


Agent Reference

AgentPurposeWhen to use
Project RunnerInteractive project entry point + hourly reconciliationVia Forge Chat handoff, or automated (hourly cron)
Task RunnerDispatches SRP agents for todo itemsAutomated (hourly cron) or on-demand
Page ManagerCreate/rename/move/delete pages + sidebarSpawned by Task Runner, or directly
Project WorkerExecute project phases (implement, extract, etc.)Spawned by completing agent via spawnAgent
Project EvaluatorEvaluate project phasesSpawned by completing agent via spawnAgent
Project ThinkerPlanning, spec creation, architectural reasoningSpawned by completing agent via spawnAgent

Which agents you interact with

AgentDirect interaction?How
Project Runner✅ YesVia Forge Chat handoff (Interactive Mode)
Forge Chat✅ YesGeneral requests, project creation, one-off tasks
Task Runner❌ NoRuns autonomously
Page Manager❌ NoSpawned by other agents
Project Worker❌ NoSpawned by other agents
Project Evaluator❌ NoSpawned by other agents
Project Thinker❌ NoSpawned by other agents

How Agents Hand Off

Happy path (agent-to-agent): When an agent completes a phase and no human gate is needed, it immediately spawns the next Bot via spawnAgent. This is the normal flow — no idle time between phases.

Reconciliation (Project Runner hourly): Project Runner scans for problems the happy path missed — stalled agents, orphaned completions, missing todo entries. It does not handle happy-path dispatch.

Interactive (Forge Chat → Project Runner): When you need to approve a plan, make a decision, or start a project, you interact with Project Runner via Forge Chat handoff. Project Runner handles the approval in conversation.

Spawning an Agent Directly

Use the spawnAgent tool to invoke any Bot:

Async mode (fire-and-forget — returns a job ID immediately):

spawnAgent(
  botGroup: "forge",
  botHandle: "project-worker",
  message: "Implement Plan 2 of the Taxonomy project",
  mode: "async"
)

After spawning in async mode, check results in a later turn with checkAgentJob:

checkAgentJob(jobId: "<jobId returned by spawnAgent>")

Sync mode (blocks until the Bot completes and returns the full result):

spawnAgent(
  botGroup: "forge",
  botHandle: "page-manager",
  message: "Create the Onboarding page and update the sidebar",
  mode: "sync"
)

Use sync mode when:

  • The task is complex or risky and you need the result before continuing
  • You need to verify the outcome in the same turn

Use async mode when:

  • The task is simple and well-defined
  • You’ll check on results later
  • You want to dispatch multiple tasks in parallel

Checking Job Status

checkAgentJob(jobId: "...")

Returns the AgentJob state (running, completed, failed, aborted) along with result, error, steps, and usage. Set includeMessages: true to retrieve the full conversation history and token usage after completion.

Aborting a Job

abortAgent(jobId: "...")

Stops the running sub-agent at the next opportunity. Partial results or in-progress tool calls may be discarded. The AgentJob status is updated to aborted.


Human Gates

Human gates are points in the project lifecycle where your approval is required before proceeding:

GateTriggerWho notifies you
Plan approvalPlan_Eval passesProject Evaluator creates a todo item for you
Execute issuesExecute_Eval finds problemsProject Evaluator creates a todo item for you
Verify issuesVerify finds unresolved problemsProject Evaluator creates a todo item for you
Phase blockedAgent encounters a blockerCompleting agent creates a todo item for you

How to respond:

  1. Check your pending todo items (ask Forge Chat or use findTodoItems)
  2. Click the link to review the persisted report file
  3. Tell Forge Chat your decision (approve, request changes, or reject)
  4. Forge Chat hands off to Project Runner, which applies your decision and advances the phase

Creating New Workflows

A workflow is a sequence of agent invocations triggered by a schedule or an event. To create a new workflow:

1. Define the Trigger

Scheduled (cron): Add an entry to schedules.ts in the orchestrator source (orchestrator/src/):

{
  name: "your_workflow_daily",
  schedule: "0 8 * * *",  // cron expression
  botId: "<botId>",
  message: "Your task prompt here",
  mode: "async",
}

Then add the corresponding Inngest function. The orchestrator will POST to itself on the schedule, which triggers the agent.

Event-driven: Add a new endpoint in the dispatcher (Hono routes in orchestrator/src/):

app.post('/orchestrator/run', async (c) => {
  const { botId, message, mode } = await c.req.json();
  // dispatch logic
});

Any system that can make HTTP requests can trigger the workflow.

2. Choose the Agent

  • Runner agent — if the workflow needs to coordinate multiple sub-agents (like Project/Task Runner)
  • SRP agent — if the task fits a single responsibility (page management, project work, evaluation, planning)
  • New Bot — if no existing Bot covers the responsibility. Create it:
    1. Create or update a Bot record with a system prompt, model selection, and tool assignments
    2. Configure the Bot’s prompt (modular: Bots have multiple ChildPrompts up to 3 levels deep)
    3. Assign the appropriate model (e.g., openai:gpt-5-mini) and temperature
    4. Assign the tool set the Bot needs (e.g., forge-filesystem, forge-bash, forge-discovery)
    5. Test by spawning the Bot with spawnAgent in sync mode

3. Write the Task Prompt

The task prompt is the most important parameter. It must be:

  • Self-contained — the agent has no prior context
  • Specific — include exact file paths, project names, and expected outcomes
  • Constrained — tell the agent what NOT to do as well as what to do

Example:

Check all active projects in the Forge department using forge-discovery.
For any project with a completed phase, read the State file and determine
the next phase. If the next phase can proceed automatically, update the
Phase file. If human approval is needed, create a todo item for the user via
`createTodoItem` with project, phase, blocker details, and work-product link.
Do NOT modify projects that are in progress.

4. Test the Workflow

  1. Test the agent manually first: spawn it in monitor mode and observe behavior
  2. If the agent works correctly, add the schedule to schedules.ts
  3. Verify the Inngest function fires correctly (check Inngest dashboard)
  4. Monitor the first few automated runs for issues

Scheduling Agent Execution

Inngest Schedules

Inngest is the scheduling engine. It POSTs to the orchestrator’s HTTP endpoint on each configured schedule.

Current schedules:

JobCronAgent
Project Runner0 * * * * (hourly)Project Runner (reconciliation)
Task Runner0 * * * * (hourly)Task Runner
Memory Compaction0 3 * * * (daily 3am)TBD
Infrastructure Check0 10 1 * * (monthly)TBD

Prerequisite: An Inngest Cloud account is required. Without it, INNGEST_DEV=1 mode only works with a local dev server — scheduled functions won’t fire in production.

Setup:

  1. Create an Inngest Cloud account at inngest.com
  2. Create a new app and obtain the signing key + event key
  3. Set INNGEST_SIGNING_KEY and INNGEST_EVENT_KEY in the orchestrator’s Railway environment
  4. Set INNGEST_DEV=false (or remove the variable)
  5. Redeploy the orchestrator service
  6. In the Inngest dashboard, connect the app to the orchestrator’s sync endpoint: https://<orchestrator-url>/api/inngest

On-Demand Execution

Trigger any agent immediately via the orchestrator’s HTTP endpoint:

curl -X POST https://<orchestrator-url>/orchestrator/run \
  -H "Content-Type: application/json" \
  -d '{
    "botId": "<botId>",
    "message": "Your task here",
    "mode": "async"
  }'

Or ask Forge to spawn the agent directly using spawnAgent.

Monitoring and Troubleshooting

Check running jobs:

checkAgentJob(jobId: "...")  — for a specific AgentJob

Stuck jobs: The AgentJob reaper runs periodically and auto-completes jobs that have exceeded their timeout or are no longer active. You can also abort a stuck job directly:

abortAgent(jobId: "...")

Reviewing agent output: All AgentJob results are persisted. Use checkAgentJob with includeMessages: true to review the full conversation history. Project reports are persisted to the filesystem for later review.

Todo items: When agents encounter issues they can’t resolve, they create 🚫 todo items for you via the todos tool group. Check your pending items regularly when automated workflows are active.


Architectural Notes

Context Is a Cache, Not State

Agents must be able to reconstruct their situation from the filesystem and database state alone. If an agent can’t recover from a restart by reading current files, the architecture has a single point of failure. When designing workflows, ensure all state is persisted to files — not held only in the agent’s context.

The Orchestrator Is Thin

The orchestrator dispatches and monitors — it does not implement business logic. When adding workflows, keep the orchestrator’s role minimal: receive trigger → invoke agent → handle failure. All intelligence lives in the agent’s prompt and skills.

Agent-to-Agent Handoff Is the Happy Path

The default flow is completing agents handing off directly to the next agent via spawnAgent. This eliminates idle latency. Project Runner’s hourly reconciliation is a safety net — not the primary dispatch mechanism.

Orchestration Targets the forgentic Runtime

All agent orchestration targets the forgentic runtime and its Bot system. Bots are the execution layer — each Bot has its own model, system prompt, and tool set. The orchestrator dispatches work to Bots via spawnAgent and tracks progress through AgentJob records. There is no external runtime dependency; scheduling and execution are handled within the forgentic stack.