AGENT FORGE

Learns Who To Ask

One workspace, many AI models. Agent Forge picks the right one for each job — and every result it sees makes the next pick better.

See It Running → Request a Demo →

Built by Prashant Dimri — see the evaluation work behind it →

LIVE IN PRIVATE PREVIEW  ·  DEMOS ON REQUEST  ·  SELF-SERVE SIGNUP NOT OPEN YET
SCROLL

Most routers guess.
This one remembers.

Choosing which model handles a job is the whole problem. Agent Forge makes that call three ways — and only the first one is obvious. Each one below is written twice: plainly, then with the actual mechanism, because “we route intelligently” is a claim and the code underneath it is the evidence.

01

It checks what is actually up

Before anything runs, every model you have connected gets ranked on what it can do, whether it is healthy right now, how close it is to a rate limit, and how fast it has been answering.

Mechanism Health is not inferred from the last failed call. A background prober (karma/health_probe.py) polls every backend independently with its own failure and recovery thresholds, and fires status-change callbacks into the alert manager. Rate-limit headroom is scored on a rolling 50-call window — each 429 costs 0.15, each clean call recovers 0.05 — so a provider that just throttled you is de-prioritised for a while, then earns its way back instead of being blacklisted.
capability · health · limits · latency
02

Karma — it remembers

Every call is scored on how it actually turned out, and those scores decide who gets the next similar job. A model that botched this kind of work before gets passed over. Most routers pick on what a model claims it can do; this one picks on what it has already done here.

Mechanism Karma is not a log file — it is a closed feedback loop. Every model carries a dense 8-dimensional capability vector (code_generation, tool_calling, reasoning, vision, long_context, speed, general, overall) rebuilt from real outcomes. A new task is embedded and matched by cosine similarity to the model whose measured history sits closest to it — semantic matching against evidence, not a lookup table. Sampler settings are tuned per (task_type, model, backend) by epsilon-greedy exploration, so the system keeps testing alternatives instead of locking onto a local optimum. And Karma keys on the model, not the slot — reassign a model to a different backend slot and its earned record follows it rather than resetting.
outcomes scored · fed back into routing
03

Trimurti — three reviewers, opposing jobs

Before risky work runs, three reviewers look at it at the same time: one argues for building it, one for protecting what already works, one for tearing it down. They advise — they never decide; the orchestrator makes the call. Three independent reads catch what a single pass misses, and they run on a small model rather than your best one — so the check costs a fraction of the work it protects.

Mechanism A deliberation engine, not a prompt with three personalities. The three reviewers are named for what they are each responsible for asking: Bodha (“awakening”) argues for what should be created — Dharma (“what upholds”) argues for what must not break — Tapas (“burning away”) argues for what should be removed. Each is a separate model call with its own prompt, and they execute concurrently on a thread pool, so three opposed readings cost roughly what one costs in wall time. The council is model-agnostic by design, so this check can run on a cheap 2B model while your expensive one does the actual work. It never mutates state: it returns structured advice and the orchestrator is the single synthesis point.

The part worth noticing: it learns to skip itself. A “virtual council” replays stored deliberations when a new goal is ≥0.95 cosine-similar to a past one with ≥5 supporting records at ≥0.85 average confidence — reaching a verdict with zero model calls. An episodic LRU cache (128 entries) evicts any learned pattern whose success rate falls under 0.75, so a shortcut that stops working stops being taken.
parallel review · advisory only · caches its own verdicts
04

None of this is a prompt in a config file

In most tools, an “agent” is a block of instructions in a YAML file and a framework that passes it to a model. Agent Forge has nineteen of those — but they are templates, not the roster. At dispatch the orchestrator builds a specific worker from them for one subtask, and if none of the nineteen fits the job, it writes a new specialist, checks it, and loads it while the turn is still running.

What is actually underneath Six subsystems, each owning one job and none of them a prompt: the orchestrator owns the turn and is the only thing that decides; the tool dispatcher runs the execute-and-check loop and enforces the stop conditions; the router picks the backend; Karma scores what happened; Trimurti deliberates; and Ṛta sets the strategy. The nineteen YAML entries are role definitions these draw from, not the set of things that can run.

The orchestrator does not paste a role into a prompt. It instantiates workers — each with its own runtime id, bound to one subtask, typed for the dispatcher (reasoning, code, data), given its own tools and its own backend selection, and registered in a live agent pool that tracks its lifecycle and emits its spans. Several run at once, against different models.

Most of those workers are generic specialists matched to the subtask rather than one of the nineteen by name. The named identities are wired to specific operations — planner to project planning, code_writer to file generation, code_editor to edits, tester to test runs — and the council can also request one by name.

If no definition fits, the Auto-Agent Pipeline writes a new one: generates the spec, checks it for integrity, for overlap against every existing agent, and for whether it fills a real gap — then hot-loads it mid-turn and persists it to MongoDB, deliberately separate from the YAML. The roster grows at runtime.

Underneath all of it sits the Ṛta engineṛta is the Vedic word for the order that holds things in motion, and it is the part that decides how a turn should run before anything is asked of a model: direct answer, council, decomposition, or swarm. It also tracks each backend through a lifecycle (newborn → healthy → degrading → dead → reborn) and filters out the dead ones before scoring the rest. It makes zero model calls doing any of this — deterministic Python, state machines and arithmetic. The layer deciding how much model non-determinism you are exposed to does not itself depend on a model behaving.
engines, not prompts · roster grows at runtime

What happens when
you hit send.

Six stages. Not every request needs all of them — simple questions take the short path.

01
Understand
Request Intake
Works out what kind of job this is — code, reasoning, research, a quick answer — and how confident it is about that.
classify_task_type() → type + confidence, from a local embedding. No keyword fallback.
02
Context
Memory Probe
Finds related history and documents by meaning — an earlier session on the same problem surfaces even when it was worded differently.
BGE-M3Atlas vector search. Local, offline, weights in the image.
03
Route
Candidate Ranking
Each routable model is scored on three learned signals — its recent momentum, how it affects overall load, and how truthful its past answers measured — then capped by how healthy it is.
100 × capacity, then +gati (momentum) +mitra (load harmony) +satya (truthfulness).
04
Coordinate
Review + Agents
Complex work gets the three-reviewer pass, then splits into a dependency graph. Independent pieces run at the same time. Simple work skips all of it.
should_deliberate() → DAG → Kahn's algorithm, 4 concurrent.
05
Execute
Selected Runtime
The chosen model runs it. If it stalls, fails, or hits a limit, the next healthy backend picks the job up instead of the turn hanging.
GPU → Cloud → Local, pool last. Hard stops: 120s with no event ends the turn; repeated tool-loops trip a guard.
06
Observe
Trace + Feedback
What happened gets recorded — timings, errors, corrections, your rating. That is what sharpens the next decision.
record_outcome() feeds all 5 scoring layers + rebuilds that model's capability vector. Stage 03 scores differently next turn.

Not a mockup.

This is the running workspace. Everything above is describing what you are looking at here.

The Agent Forge workspace: left sidebar listing Projects, Architect, Proposals, Files, Runtimes, Data Grid, Companion, Insurance, Underwriting and Traces; a status bar reading 3/3 core and 26/26 pool; and the main panel offering to scan a codebase, build something new, refactor existing code, or run a system health check.
Top bar: 3/3 core models and 26/26 pool models reachable right now, GPU runtime offline because none is connected. Status line: Trimurti council active, Karma monitoring on. Those are live readings, not decoration — when a provider drops, the counts drop with it.
The model picker: an Auto entry labelled smart routing at the top, then a list of connected models each tagged core or pool — llama 3.2, kimi, a qwen vision model, gemini flash, an Arabic model, two speech models, and groq compound — each with a green health dot.
What it is choosing between. Auto sits at the top — that is the routing doing the picking. Below it, everything currently connected and healthy, split into core slots and the wider pool. Text, vision, Arabic, speech. Adding a model is connecting it, not rewriting anything.
The Agent Forge trace view: a waterfall of API requests with response times on the left, and on the right a single expanded request showing seven nested spans — the orchestrator call, an agent spawn, the tool dispatcher, and three persistence operations — each with its own duration.
One request, opened up. 7 spans, 5.558s total — the orchestrator call, the agent it spawned, the tool dispatcher, and three separate persistence steps, each timed independently. When an answer is slow or wrong, this is where you find out which part did it, rather than guessing at a black box.
Agent Forge executing an approved action: a plan manifest listing the exact file-write it was approved for, the assistant confirming the file was created, and the resulting one-line diff shown inline, with the created file also listed in an artifacts panel above.
Nothing touches a file until you say so. The plan manifest names the exact action approved — one write, one path, one payload — and what comes back is the diff, not a claim that it worked. Note the model on this one: deepseek-v4-pro. Different job, different model, same workspace.
The settings panel: a server block showing MongoDB connected with five collections, and RAG, embedders and ModernBERT all reporting ready; buttons for API docs, diagnostics and downloading training data; and behaviour toggles for plan before execute, auto fix errors, and show diff before write.
And the controls are yours. Plan before execute and show diff before write are switches, not our policy — both are off by default, and turning them on is what makes it stop and ask. The status block settles a question the copy cannot: the embedders are running locally and reporting ready. Those are the small models that turn your request into numbers so it can be compared by meaning to past work — BGE-M3 does that matching, ModernBERT is the faster classifier being trained to take over. Both run inside the container, offline, on weights shipped with the image — your text is not sent anywhere to be embedded.

Want to move around in it rather than look at a picture? Take the interactive tour → — it runs on sample data, no account needed.


The failures
are not hidden.

An agent that quietly gives up and returns something plausible is worse than one that stops. These are real stop messages from the running system — each says what happened, what it did about it, and the exact words to type to carry on.

A stop message reading: Forge stopped after 3 repeated tool-call loop detections before the task completed. Reply continue without repeating completed actions to retry safely. Below it, a warning bar noting the response was cut off because the loop guard triggered.
It caught itself repeating and stopped instead of burning your budget in a circle.
A stop message reading: the model produced no event for 120 seconds, so Forge stopped this turn instead of hanging. No further tools were run. Reply continue to retry from the visible conversation.
A model went quiet for 120 seconds. Rather than hang, it ended the turn and told you so.
A stop message reading: tool iteration budget spent after 12 dispatch iterations, 12 research tool calls and 0 delivery tool calls. No requested artifact was created because no delivery tool ran. Reply build it now to retry the deliverable.
The sharpest one. It researched twelve times and built nothing — and rather than hand you a summary pretending to be the deliverable, it says exactly that, and how to fix it.

One system.
Four clear ways in.

Start with the architecture, follow a workflow, inspect runtime options, or walk through the interface. Each destination has its own purpose.


Want a look
at the real thing?

The tour runs on sample data. For the live system, I will walk you through it myself.

Live walkthrough

Agent Forge is running in production today. I am happy to show it to you on a call — the real system, on real work, not a slide deck.

Self-serve accounts are not open yet, so this is a conversation rather than a signup. Tell me what you are trying to build and I will show you the part that matters to you.

  • Routing that learns — picks the model, remembers how it went, picks better next time
  • Agents and subtasks — big jobs split up, run, and come back together
  • Review before risk — three-reviewer pass, plus your approval on anything that changes files
  • Memory that persists — sessions, projects, and documents stay with the work
  • Your own hardware, optional — connect a GPU box and it becomes another place work can run
Request a Demo →
Usually answered within a few days · No account created · Ask anything, including the parts that do not work yet