Changelog¶
All notable changes to Babelagent are documented here. Format follows Keep a Changelog; this project uses semantic versioning.
0.1.3 — 2026-08-27¶
Added¶
- Per-resource concurrency. Tag nodes with
resource="..."and passresource_limits={...}torun(). Nodes sharing a resource share a concurrency limit, so the same graph runs a local model sequentially ({"local": 1}) and a cloud API in parallel ({"cloud": 8}). The per-resource semaphore is acquired before the global one, so a queued node never holds a global slot while waiting.resourceis surfaced intopo_spec/babelagent inspect.
Changed¶
- Dependencies now use bounded ranges (
>=x,<next-major) so a breaking or compromised major can't be pulled in silently, and a hash-pinneduv.lockis committed for reproducible, verified installs. Babelagent does not exact-pin (that belongs in the deploying app's lockfile). Seedocs/SECURITY.md→ Supply chain.
0.1.2 — 2026-08-27¶
Changed¶
.join()always hands its agent a dict keyed by the (surviving) upstream node names, even for a single upstream, since a join is an explicit fan-in. A plain.node()keeps the prior rule (one upstream unwrapped, two or more keyed). This makes a join agent's input shape fully stable.
0.1.1 — 2026-08-27¶
Fixed — behavioural contracts (external code review + a 4-way adversarial repo review)¶
- Join / result input shape is stable. One declared upstream → unwrapped; two or more → a dict keyed by node name. The type never flips based on which branch survived. Pinned both ways.
verdictno longer hides a tolerated crash. A run where a non-terminal branch raised but ak_of_n/optionalbarrier absorbed it now reportsverdict="warn"(withok=True), never a cleanpass. The crashed node is inresult.trace.optionalbarrier skips when no upstream survives (instead of running the node with{}/None).- Cancellation no longer orphans tasks — in-flight nodes are cancelled (and briefly awaited) when a run is cancelled or a REST client disconnects; the cleanup is time-bounded so a cancellation- swallowing agent can't defeat the guillotine.
- Deterministic trace order for siblings completing in the same event-loop wake; uniform trace
record schema (skipped/timeout rows carry the same keys) so REST/MCP clients never
KeyError. - Duplicate dependency and empty graph are rejected at compile with a clear
TopologyError. is_agentis strict (an asyncrun(message, ctx)), so a wrong-shaped object is adapted or rejected up front rather than failing cryptically mid-run.bind_payloadfalls back to a single positional arg for callables with required positional-only params (no broken**kwargsspread).- A sync callable that returns a coroutine is awaited (its result becomes the payload).
HttpAgent.from_openapi: falls back to a GET when a spec has no write operation, rejects templated paths (/items/{id}) with a clear error, and guards a malformedserversentry.- A2A: handles a list JSON-RPC result and de-dups an answer echoed in both an artifact and the status message.
Settingsrejects nonsensical values (non-positive timeout/body/concurrency, out-of-range port).LLMis now importable from the top level; the unwiredinspect <file>argument was removed.- Corrected the scheduler concurrency comment; documented the opt-in guillotine, the plugin dispatch
priority (
BABELAGENT_NO_PLUGINS=1), the join/tolerated-branch contract, and theadapt()A2A step. - +30 tests (107 total).
0.1.0 — 2026-08-27¶
Security¶
- Completed the full security cadence over the REST / MCP / A2A / HTTP surface: a 3-surface audit and
four adversarial red-team rounds (final round found nothing new). Fixed and regression-pinned:
attacker-controlled
deadline_s(DoS), SSRF (allowlist + NAT64/6to4/Teredo normalization, no redirects, response caps, connect-time re-guard), keyword/positional argument injection from untrusted upstream output,_safedepth+width DoS, trace exception-message leakage, REST DNS-rebind (Host pinning), slowloris (body + connection limits), and a hard wall-clock guillotine defeating cancellation-swallowing agents. Seedocs/SECURITY.mdfor the posture, deployment guidance, and the documented residuals. 22 security regression tests intests/security/.
Renamed¶
- Project renamed from the working title BYOA to Babelagent (import + distribution name
babelagent). The framing is now a neutral communication layer that lets heterogeneous agents talk to each other (agent-to-agent), not a factory/assembly line. - API vocabulary re-themed:
Factory→Graph,Line→CompiledGraph,Blueprint→Topology,Station→Node(merged with the old graph-node wrapper),Part→Message,Product→Result, check outcomeResult→Grade;.station()→.node().
Added — core graph engine¶
Graphbuilder with linear chaining (.node(...).node(...)) that compiles to a DAG core supportingafter=dependencies, fan-out, parallel branches, and fan-injoin.- Barrier policies for fan-in:
all,k_of_n(withk), andoptional. - Async scheduler with bounded concurrency, per-node + per-run timeouts, reactive readiness, and failure propagation (unsatisfiable barriers skip downstream nodes).
- Native, dependency-free quality types:
Verdict(pass/warn/fail),Grade,Check, andGateMode(off/warn/strict) for optional per-node gating. Message/Resultenvelopes;Topologyvalidation (cycle + dangling-dep detection).
Added — adapters + adapt()¶
adapt()on-the-fly adapter creator: normalizes callables, HTTP/OpenAPI endpoints, MCP tools, framework agents (LangChain / CrewAI / AutoGen), and LLM providers into the uniformAgentinterface.CallableAgent,HttpAgent(+from_openapi, basic SSRF guard),LLMprovider adapter (lazy, behind extras, defaults to the latest Claude model).- Extensible registry:
register_adapter(...)and thebabelagent.adaptersentry-point group.
Added — A2A adapter¶
A2AAgent/A2ARef: consume a remote Agent2Agent (A2A) agent as a node via themessage/sendJSON-RPC method, with Agent Card discovery. Built on httpx (base wheel, no extra), SSRF-guarded.adapt(A2ARef(url))wires a remote agent into the graph. This is the "consume the protocols, don't compete with them" position: a remote A2A agent becomes just anotherAgent.
Added — interfaces¶
babelagentCLI (Typer):demo,doctor,inspect,serve,mcp,version.- REST service (
babelagent.io.rest,serveextra): serve a graph over HTTP. Hardened from birth — constant-time bearer auth, zero-config on loopback but fail-closed (refuses to bind a non-loopback host without a token), request-body size cap enforced before buffering, a concurrency semaphore, deadline-bounded runs, and sanitized errors. Endpoints:GET /health,GET /graph,POST /run. - MCP server (
babelagent.io.mcp,mcpextra): expose a graph as MCP tools (run_graph,graph_topology) so any MCP client can run a whole graph. Works across MCP SDK 2.x (MCPServer) and 1.x (FastMCP). - Key-free
babelagent demo: a broken agent gated to FAIL, then a fixed one producing a PASS result.