Skip to content

Repository files navigation

Afferent

CI

Afferent gives AI agents senses.

An LLM is fluent in text but effectively blind to most of a software system — a 200k-row CSV, a function's real runtime behavior, what a script changed on disk, a distributed trace, an unfamiliar CLI, a sprawling notes corpus. Afferent is a local-first Python toolkit of deterministic instruments that transcode each of those opaque things into a FramePack: a compact, structured, evidence-bearing packet an agent can read, cite, and act on.

Afferent is not an agent. It is the sensory layer that sits underneath one.

In biology, afferent nerves carry sensory signals toward the brain. Afferent does the same for a model: it carries external-world signals into model-native structures.

Status: Alpha · local-first · Python ≥ 3.10 · one runtime dependency (jsonschema) · 29 passing tests. This is a complete local reference implementation, not a hosted service. See Project status.


The problem

The default way to show an agent something non-textual is to dump the raw thing into its context window. That fails three ways at once:

  • Cost — raw substrates are large; you burn tokens and hit limits.
  • Loss — you truncate, and the model still can't see structure (missingness, outliers, causality, timing).
  • No grounding — the model gets data but no evidence or provenance, so it confabulates and you can't audit its conclusions.

The idea: representation arbitrage

For any given substrate there is a deterministic transformation into a representation the model reasons about far better than the raw form — and that transformation is done by ordinary, auditable code, not by the LLM. Cheap, reproducible, trustworthy.

CSV             → schema + missingness + outlier profile   (agent can judge data quality)
before/after FS → semantic diff vs expectations            (agent can see consequences)
OTel-like trace → service storyboard                        (agent can watch services talk)
OpenAPI spec    → endpoint cards + risks + safe probe plan  (agent can use an API safely)
directory       → inventory + project markers               (agent can orient in a repo)
text/policy     → sections + obligations + questions        (agent can reason over documents)
unknown input   → sniffed substrate kind + features         (agent knows what it's looking at)

What a FramePack actually is

A FramePack is not prettified data — it is a sensory packet with a chain of custody. Every one carries:

  • Frames — ordered views in the right modality (table, mermaid, diff, json, metric, state, graph).
  • Observations — findings, each with a severity and a confidence.
  • Evidence — every claim tied to a source with a selector/quote, so conclusions are citable and checkable, not asserted.
  • Expectations — things that should be true, marked met / missing / violatedfalsifiable.
  • Affordances — safe next actions with preconditions, effects, success signals, risks, and rollback, so an agent knows what it can do next and how to tell if it worked.
  • Provenance — every source carries a sha256 + trust zone (user_supplied, tool_output, third_party, generated…), so tainted input is distinguishable from trusted.
  • Relationsderived_from / supports / contradicts / follows — an evidence graph.

Each instrument emits the pack twice: framepack.json for tool use and framepack.md for the model to read straight into context. Same content, two doors.

Install

python -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
python -m pytest -q          # 29 passing

No network is required and there are no heavy dependencies (only jsonschema).

Quickstart

# 0. See the built-in senses.
afferent list

# 1. Run one instrument over one substrate → framepack.json + framepack.md
afferent run-instrument dataset.microscope examples/sample.csv --out out/dataset

# 2. The v1.0 capstone: describe a GOAL, let the OS choose the senses, run them,
#    synthesize one OS-level FramePack, and emit a receipt + system map.
afferent universal-run \
  --goal "profile data quality" \
  --target examples/sample.csv \
  --out out/run --no-workbench --no-compile

# 3. End-to-end showcase over the bundled examples.
afferent os-demo --out out/demo

Feed out/**/framepack.md into your agent's context, or load framepack.json for tool use. Export to MCP/Skill to wire it into a stack (afferent mcp-manifest, afferent skill).

Python API:

from afferent.universal import UniversalInstrumentOS

os_ = UniversalInstrumentOS()
plan   = os_.plan("profile data quality", ["examples/sample.csv"], options={"workbench": False})
result = os_.run(plan, "out/universal", overwrite=True)
assert result.ok

Built-in instruments

Instrument Substrate Turns it into
dataset.microscope CSV schema, missingness, uniqueness, type hints, outliers
diff.oracle before/after filesystem semantic diff + missing expected consequences
trace.comic span traces service storyboard / incident sequence
api.aquarium OpenAPI spec endpoint cards, risks, safe probe plans
directory.inventory a directory file inventory, suffix counts, project markers
text.structure text / policy sections, obligations, questions, salient terms
forge.sniffer anything unknown detected substrate kind + features

When no built-in lens fits, the forge can generate a conservative fallback instrument for the substrate (afferent os-forge).

The Universal Instrument OS (v1.0)

The capstone that runs the whole loop from a single goal:

goal + targets
  → infer which senses are needed
  → plan (ordered OS nodes, risk budget)
  → discover / sniff substrates
  → render each target with the best instrument (or forge a fallback)
  → synthesize child FramePacks into one OS-level FramePack
  → add falsifier hints + recommendations
  → optional Workbench (browsable UI)
  → optional capability package (reusable skill/MCP/CLI/OpenAPI)
  → universal receipt + system map

The CLI exposes the full stack (afferent --help): plan/compose, run-instrument, runtime-run + safe-registry (safe execution & supply chain), falsifier-* / worldline-* (verification), workbench-* (observability), drift-* (regression & self-repair), capability-* (compile a workflow into a reusable package), universal-* / os-* (the OS loop).

Repository map

src/afferent/
  core/          FramePack + SourceRef/Evidence/Observation/Expectation/Affordance models, schemas
  kernel/        instrument ABI, built-in registry, passive runtime policy
  instruments/   the built-in senses (dataset, diff, trace, api, directory, text, sniffer)
  forge/         detect an unknown substrate and generate a fitting instrument
  composition/   goal + targets → multi-instrument DAG → linked FramePacks
  safe/          policy-gated command runner + content-addressed registry (supply chain)
  falsification/ + falsifier/   adversarial checks against claims
  worldline/     branchable "what-if" experiments in isolated workspace copies
  workbench/     browsable timeline/graph/search UI over artifacts
  drift/         golden snapshots, drift detection, conservative self-repair
  capability/    compile a successful workflow into a reusable capability package
  universal/     the v1.0 Universal Instrument OS orchestrator
  exporters/     MCP manifest + Skill folder emitters
  cli.py         the `afferent` command surface
tests/           self-contained pytest suite (no network, uses tmp dirs)
examples/        input fixtures for the quickstart and docs
docs/            per-subsystem design notes

Who / why / when

Who — agent & tool builders who need reliable perception over non-text substrates; AI engineers wiring MCP servers or Skills (Afferent exports both); teams doing agent evals/debugging that must be reproducible and citable; security-conscious teams that need provenance and policy gating; researchers studying agent capability scaffolding.

Why — deterministic, cited, provenance-tracked, falsifiable artifacts with safe, pre-described next actions. Built for agents to cite, replay, and act on with an audit trail, not just skim.

When to reach for it — you're about to dump a big/opaque artifact into context and it's going badly (cost, hallucination, no grounding); the agent's conclusions must be auditable; you want reproducible preprocessing instead of "eyeball the raw data"; you want to package a working agent workflow into something reusable; or you need to detect drift/regression over time.

When not to — you need a hosted service, hardened isolation for hostile untrusted code, or a full agent runtime. Afferent is the sensory layer under your agent, not the agent.

Glossary

  • FramePack — the universal output packet (frames + observations + evidence + expectations + affordances + provenance + relations).
  • Instrument — a deterministic transform from one substrate type → a FramePack.
  • Substrate — the opaque input (CSV, filesystem, trace, OpenAPI spec, directory, text).
  • Affordance — a described safe next action with preconditions/effects/rollback.
  • Forge / Sniffer — machinery that detects an unknown substrate and generates a fitting instrument for it.
  • Worldline — a branched "what-if" run in an isolated workspace copy, to compare outcomes.
  • Falsifier — an adversarial check that tries to break a claim rather than confirm it.
  • Receipt — a human-readable record of what a run did and whether checks passed.
  • Drift — divergence of current artifacts from a stored golden snapshot.
  • Capability — a compiled, packaged, reusable workflow with skill/MCP/CLI/OpenAPI entry points.
  • Universal Instrument OS — the v1.0 orchestrator that runs the whole sense → act → receipt loop from a single goal.

Safety posture

Afferent is local-first and read-only by default. It does not grant ambient authority and does not silently execute untrusted tools. The exceptions are explicit and gated:

  • Side-effectful execution goes through the safe runtime (command allowlists, cwd roots, timeouts, output caps, env allowlists, secret redaction, structured receipts).
  • Packages flow through a content-addressed registry with local signatures, a transparency log, and a revocation list.

This is a development safety layer, not an OS-level sandbox. Treat any target code/CLI as trusted-or-sandboxed; use containers/VM/WASI for hostile code.

Project status

Complete local reference implementation at v1.0. Production deployment should add hardened container/WASI isolation, external auth for hosted Workbenches, secret-broker integration, signed remote registries, and stronger model-based capability evals.

Afferent is developed under an agent-driven self-improvement loop — an agent runs the tests, makes a focused change, keeps the suite green, and commits. If you are that agent, start with AGENTS.md.

Further reading

  • AGENTS.md — operating manual for agents contributing to this repo.
  • HISTORY.md — the v0.1 → v1.0 capability-unlock story.
  • docs/ — per-subsystem design notes (architecture, safety, worldlines, capability compiler, universal OS, …).

License

MIT. See LICENSE.

About

Give AI agents senses — a local-first Python toolkit that transcodes opaque substrates (CSV, traces, filesystems, OpenAPI, code) into deterministic, evidence-bearing FramePacks agents can read, cite, and act on.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages