Skip to main content

Low-code framework for generating agentic AI systems from a prompt or spec

Project description

AgentForge

A low-code framework for generating agentic AI systems from a prompt or spec. You describe what you want; meta-agents design the system and emit runnable LangGraph code. The LLM runs through OpenRouter — no local GPU required.

Runtime backend: LangGraph only for now. CrewAI is a planned second backend (the DSL and compiler are structured to add it without touching the meta-agents).


The core idea: separate generation from compilation

User prompt
   ↓  (LLM via OpenRouter, meta-agents)
DSL (SystemSpec)            ← humans can read & edit this; it's the contract
   ↓  (deterministic compiler — NO LLM)
LangGraph Python            ← reproducible, byte-identical for a given DSL
   ↓
Running agentic system (SQLite-checkpointed, resumable)

LLM creativity is confined to producing the DSL. Turning DSL into code is pure, testable machinery — so generated systems are reproducible and debuggable.


Quick start

# 1. Install dependencies
pip install -r requirements.txt

# 2. Set your OpenRouter API key
echo "OPENROUTER_API_KEY=sk-or-..." > .env

# 3. Generate a spec from a prompt
python -m agentforge.cli generate "Build a research assistant that reads docs and summarises them"

# 4. Validate the generated spec
python -m agentforge.cli validate research_assistant.yaml

# 5. Compile to a runnable LangGraph app
python -m agentforge.cli compile research_assistant.yaml -o research_app.py

# 6. Run it
python research_app.py "What is retrieval-augmented generation?"

CLI reference

Command Description Needs API key?
generate "<prompt>" [-o spec.yaml] [--model MODEL] [--no-review] Run meta-pipeline: prompt → DSL spec
compile <spec.yaml> [-o out.py] Deterministically compile a DSL to LangGraph Python
validate <spec.yaml> Static-check a DSL (reachability, routing, tools)
# Override the model (any OpenRouter model ID)
python -m agentforge.cli generate "..." --model qwen/qwen3-coder:free

# Skip human review checkpoints (fully autonomous)
python -m agentforge.cli generate "..." --no-review

Pipeline stages

generate runs six stages automatically. Three pause for human review.

Stage What it does Human checkpoint
parse prompt → structured requirements + open questions
architect choose topology, agent roles, patterns
design concrete agents, prompts, graph wiring
resolve_tools map capabilities to local tool registry, flag gaps
compile DSL → LangGraph (deterministic)
validate static checks + convergence smoke test

At each checkpoint the full intermediate artifact is printed as YAML. Paste edited YAML then press Enter twice to override, or just Enter to accept.


The DSL

name: research_assistant          # snake_case system identifier
runtime: langgraph

llm:
  provider: openrouter            # "openrouter" (default) or "ollama"
  model: qwen/qwen3-coder:free    # any model available on the provider
  temperature: 0.1
  base_url: https://openrouter.ai/api/v1

agents:
  - id: researcher                # snake_case node name
    role: "Gather information and draft a summary."
    tools: [doc_loader]           # names from the tool registry
    memory: vector                # none | buffer | vector
    model: null                   # optional per-agent model override

  - id: critic
    role: >
      Review the draft for accuracy and gaps.
      If revision is needed, emit 'ROUTE: needs_revision'.
      If the draft is good, emit 'ROUTE: approved'.
    memory: buffer

graph:
  entry: researcher
  edges:
    - { from: researcher, to: critic }
    - { from: critic, to: researcher, condition: needs_revision }
    - { from: critic, to: END,        condition: approved }

success_criteria:
  - "Final answer addresses the user's question"
  - "Critic approved the draft"

DSL fields

llm (system-wide default; overridable per agent via model:)

Field Default Notes
provider openrouter "openrouter" or "ollama"
model qwen/qwen3-coder:free Any model ID valid for the provider
temperature 0.1 0.0 – 2.0
base_url https://openrouter.ai/api/v1 Override for self-hosted or Ollama

agents[]

Field Required Notes
id [a-z][a-z0-9_]*
role Natural-language role; becomes the system prompt seed
tools Names from the tool registry (see below)
memory none (default) | buffer | vector
model Per-agent model override; falls back to llm.model

graph

Field Notes
entry Starting agent ID
edges[].from Source agent ID
edges[].to Target agent ID or END
edges[].condition Routing signal (optional). Matches ROUTE: <signal> emitted by a router agent. The ROUTE: prefix is stripped automatically.

Graph validation (enforced at load time)

  • No duplicate agent IDs
  • entry must name a defined agent
  • All edge sources/targets must be defined agents or END
  • All agents must be reachable from entry (no orphans)
  • At least one path to END (the graph must be able to terminate)

Routing

Conditional control flow uses a lightweight signal convention:

Router agent output:  "... ROUTE: needs_revision ..."
Matching edge:        { from: critic, to: researcher, condition: needs_revision }

A router agent just emits a line starting with ROUTE: anywhere in its response. The runtime scans for it and dispatches to the matching edge. The ROUTE: prefix in a condition value is stripped automatically so both needs_revision and ROUTE: needs_revision work as condition strings.


Memory modes

Mode Behaviour
none No persistent memory; each agent sees the shared message history
buffer In-state conversation buffer (full message list in graph state)
vector Hook in build_messages for local Chroma/LanceDB retrieval (wired but not yet fully implemented)

Tool registry

Tools are named capabilities that agents can call. Only registered tools can be referenced in a spec; unknown tools are flagged at the resolve_tools checkpoint.

Built-in tools

Name Signature What it does
doc_loader doc_loader(path: str) → str Reads and returns the contents of a local text/markdown file
calculator calculator(expression: str) → str Evaluates a safe arithmetic expression (AST-based; supports +, -, *, /, **, unary negation)

Adding a custom tool

# agentforge/tools/registry.py
from . import registry

@registry.register
def my_tool(arg: str) -> str:
    """Description shown to the model."""
    ...

Then reference it in the DSL: tools: [my_tool].


LLM provider configuration

OpenRouter (default)

OpenRouter gives access to hundreds of models through one API key.

# .env
OPENROUTER_API_KEY=sk-or-...

The default model is qwen/qwen3-coder:free (free tier, rate-limited). For reliable throughput drop :free and add credit at openrouter.ai:

llm:
  provider: openrouter
  model: qwen/qwen3-coder   # paid — no upstream throttling

Free-tier 429s are handled automatically (up to 5 retries with the server-suggested Retry-After delay).

Ollama (local)

llm:
  provider: ollama
  model: qwen2.5:14b
  base_url: http://localhost:11434

Requires a local Ollama instance. Pass --model <name> on the CLI too if using generate.


What the compiler generates

compile produces a single self-contained Python file:

<name>_app.py
├── State (TypedDict)          messages list + scratch dict + last_agent str
├── agent_<id>(state) → dict   one function per agent (LLM call + tool loop)
├── route_<id>(state) → str    one router per set of conditional edges
├── build_graph() → app        wires StateGraph, adds SQLite checkpointer
└── run(prompt, thread_id)     entry point; initialises state and invokes graph

Key properties:

  • No LLM during compilation → output is byte-identical for the same DSL
  • SQLite checkpointing is automatic; every run is resumable via thread_id
  • Tools are resolved at runtime from the local registry, not hardcoded

Validation and smoke tests

validate runs two layers of checks without calling any LLM:

Static checks (validator.py)

  • Schema integrity (duplicate IDs, orphan agents, missing END)
  • Conditional edge signals match router outputs
  • All referenced tools exist in the registry

Smoke tests (smoke.py)

  • Graph convergence (every path eventually reaches END)
  • Dead-router detection (router emits a signal that no edge handles)
  • Progress-discard warnings (cycles that could loop forever)

Project layout

agentforge/
  cli.py              entry point (compile / validate / generate)
  dsl/
    schema.py         the DSL contract (Pydantic models)
    loader.py         YAML/JSON → validated SystemSpec
  compiler/
    langgraph_compiler.py   deterministic DSL → LangGraph code
  meta_agents/
    pipeline.py       6-stage generation pipeline + human checkpoints
    validator.py      static checks
    smoke.py          convergence + dead-router detection
  runtime/
    support.py        LLM client (_OpenRouterLLM), tool resolution, agent loop
  tools/
    registry.py       built-in tools (doc_loader, calculator)
examples/
  research_assistant.yaml
tests/
  test_core.py        deterministic-core tests (no LLM required)

Extending to CrewAI later

Add a crewai_compiler.py alongside the LangGraph one and switch on spec.runtime. The DSL, meta-agents, and validator stay unchanged — only the compile step branches.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentsynth-0.1.0.tar.gz (29.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentsynth-0.1.0-py3-none-any.whl (31.5 kB view details)

Uploaded Python 3

File details

Details for the file agentsynth-0.1.0.tar.gz.

File metadata

  • Download URL: agentsynth-0.1.0.tar.gz
  • Upload date:
  • Size: 29.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for agentsynth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c52566b7e2dcd9e5442e8a503c67e106b39e3b1bda198c9d8676a28c5e04714b
MD5 f0686189e8ebddc942757dcbe55e943f
BLAKE2b-256 f52e7fe377ab7a283304fa67159d7d55097fbce48f29a1469c40f52bbd971804

See more details on using hashes here.

File details

Details for the file agentsynth-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: agentsynth-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 31.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for agentsynth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 58ba2dcfab515d4f3ca9b4c358a43c6d14d748830f857d4bf185952da1608b33
MD5 256752bf38467054913536ea581ad706
BLAKE2b-256 48810f78d75d7e8384ee0885c60eba8ae489deeabf43e34573fb1f5619fa2510

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page