Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add instructions/ferro-labs/ai-gateway/agents-mdgit clone --depth 1 https://github.com/ferro-labs/ai-gatewayWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/instructions/ferro-labs/ai-gateway/agents-md)<a href="https://agentmods.dev/instructions/ferro-labs/ai-gateway/agents-md"><img src="https://agentmods.dev/badge/instructions/ferro-labs/ai-gateway/agents-md.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.21310 | $0.21310 |
| Opus 5 | $0.10655 | $0.10655 |
| Sonnet 5 | $0.04262 | $0.04262 |
| Haiku 4.5 | $0.02131 | $0.02131 |
Grade A, and why
ai-gateway AGENTS.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 1,305 lines — stays where its author put it; the contents beside it link to each section on GitHub.
AGENTS.md
Project Overview
Ferro Labs AI Gateway is a high-performance, open-source AI gateway written in Go. It acts as a unified routing layer between applications and 30 LLM providers (OpenAI, Anthropic, Gemini, Mistral, etc.), offering smart routing, plugin middleware, and API key management — all with an OpenAI-compatible API and transparent pass-through proxy.
- Module:
github.com/ferro-labs/ai-gateway - Go version: 1.25+
- License: Apache 2.0
Current Development Snapshot
- 30 provider subpackages — each provider lives in
providers/<id>/<id>.gowith its own test file, one perProviderEntryinproviders/providers_list.go. (providers/core/andproviders/capabilities/are shared code, not providers.) No root-level constructor shims remain. - Unified factory —
providers/factory.goholds types/constants;providers/providers_list.goholds all built-inProviderEntryrecords. Auto-registration viaAllProviders()meansmain.gonever needs editing for new providers. providers/core/split — interfaces incontracts.go; shared types split intochat.go,stream.go,embedding.go,image.go,model.go,constants.go,errors.go.- Single source of truth for name constants —
providers/names.gore-exportsNameXxxfrom each subpackage'sconst Name. - Model discovery —
providers/coreexposesDiscoverOpenAICompatibleModels/DiscoverModelsWithHeadersfor live/modelsenumeration, shared by many OpenAI-compatible providers (fireworks, xai, moonshot, nvidia-nim, novita, …). - Provider coverage — OpenAI, Anthropic, Gemini, Groq, Bedrock, Vertex AI, Hugging Face, Cerebras, Cloudflare, Databricks, DeepInfra, Moonshot, Novita, NVIDIA NIM, OpenRouter, Qwen, SambaNova, and more.
- Built-in OSS plugins — word filter, max token, response cache, request logger, rate limit, budget.
- Admin API — dashboard, key management, usage stats, request logs, config history/rollback (
internal/admin/handlers/). - Metrics — Prometheus metrics exposed at
/metrics(pkg/metrics/). - Circuit breaker — per-provider circuit breaker in
pkg/circuitbreaker/. - Observability (v1.1.0) — OpenTelemetry tracing. Public
observability/package (stableProvider/Span/Exporter/Eventseam +gen_ai.*/ferro.*attribute constants);internal/otel/wires the OTLP exporter, W3C propagation, and a customIDGeneratorthat unifies the OTeltrace_idwith the logging trace ID /X-Request-ID;internal/redact/redacts error messages. Defaults to a zero-allocation NoOp when no OTLP endpoint and no exporter are configured. - Capability matrix (v1.2.0) —
providers/capabilities/matrix.gois the single source of truth for which OpenAI chat parameters each provider can express. Providers no longer keep private supported-parameter lists;core.EnforceUnsupportedParamsreads the matrix and appliescompatibility.on_unsupported_param(warn | drop | reject). Served byGET /v1/capabilities. - Conformance suite (v1.2.0) —
test/conformance/builds every provider through itsProviderEntry, points it at an httptest stub returning that provider's native payload, and asserts the translatedcore.Response. No build tag, no network: it runs withmake test.TestConformanceCoveragefails on any provider with neither a fixture nor an allowlist reason. - Plugin failure policy (v1.2.0) — a plugin that denies (
Context.Reject) and a plugin that breaks (error/panic) are distinct:RejectionErrorkeeps its 4xx/429,FailureErroris a 500. Logging and metrics plugins fail open; guardrail, auth, ratelimit, transform, and unknown types fail closed.Rejectis honoured for every type. The type that decides this is the one the plugin reports fromType(), notplugins[].typein config. - Env references (v1.2.0) —
internal/envrefresolves${VAR}at component construction, never at config load, so theConfignever carries a materialised secret into the config-history store,GET /admin/config, or a rollback. A bare$is data ($100,pa$$w0rdsurvive); an undefined variable is an error. - Per-target concurrency (v1.2.0) —
targets[].concurrencybounds in-flight requests per provider with a queue; overflow returnsErrProviderSaturated→ 429. The limiter decorates the provider at the call site (innermost, circuit breaker outermost) and never forges capability interfaces. - Health split (v1.2.0) —
/livez(process alive) and/readyz(ready to serve) replace the single/healthsemantics;/healthis retained. - Plugin short-circuiting (Unreleased) —
Context.Skipis removed; code that sets or reads it no longer compiles.Context.SkipProviderreplaces it and skips the provider call only: every remainingbefore_requestplugin and the wholeafter_requeststage still run, so a response-cache hit can no longer disable a guardrail, rate limiter or budget behind it. Only a rejection or a plugin failure ends thebefore_requeststage, and it ends that stage alone —on_errorstill runs, so a request denied by policy is still recorded.SkipProviderstays set throughafter_requestas a fact (cache-served vs provider-served) that cost recording keys off. - Request attribution (Unreleased) —
Context.Targetnames the routing target a request used: the virtual key that served it, or on a failure the last one attempted, empty when none was attempted (denied by a plugin, no target serves the model, or served from cache). It exists because a failure has no response to read a provider from, which lefton_errorrows naming no provider. Request-log rows also carryapi_key_id— the credential's opaque id, never the credential — so usage is attributable, including a request served from cache, which reaches no provider but is still consumed by a credential. (A cached response is only ever served back to the credential that primed it — the response cache keys onapi_key_id— so a row's credential is the one that made the call, not the one that filled the cache.) A cache-served request is priced at a known zero rather than as though the provider had been called. - Unified request pipeline (Unreleased) — chat, streaming, embeddings and image generation all route through
routeTargetsingateway_pipeline.go. Retry, circuit breaker, per-target concurrency, error classification, metrics and request logging live there once, so the four surfaces cannot drift.targets[].retryis honoured under every routing mode, not onlyfallback. - One completion ceiling (Unreleased) —
max_tokensandmax_completion_tokensare resolved to a single value at every entry point,max_completion_tokenswinning when both are present, so a guardrail and the provider read the same number. See Completion length. - Declared models (Unreleased) —
targets[].modelslets an operator name the models a target serves, joined into the routing index alongside the catalog and live discovery and advertised by/v1/models. It is provider-agnostic and additive: it needs no/modelsendpoint, works offline, and never narrows what a target already serves. See Declared models. - Strategy validation at load (Unreleased) — every strategy is validated by
config.ValidateConfig, so an invalid one is aferrogw validate/ startup error rather than a request-time 500. Unknownconditions[].keyandcontent_conditions[].typevalues are load errors;weight: 0means zero traffic, a negative weight is an error, and an all-zero weight set is an error.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago Changed · +64 lines · +1,068 tokens per session dc7456692455
- 6d ago First seen · 1,241 lines · 20,242 tokens per session scan A 60ba0f2c5cf8
ai-gateway AGENTS.md is an instructions file published in the GitHub repository ferro-labs/ai-gateway (248 stars, last pushed 2d ago), licensed Apache-2.0. It adds 21,310 tokens to every session, about $0.1065 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other instructions, from other repositories
litellm AGENTS.md
AGENTS.md instructions for BerriAI/litellm, a project described as: The fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM].
litellm GEMINI.md
Gemini CLI instructions for BerriAI/litellm, a project described as: The fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM].
litellm CLAUDE.md
Claude Code instructions for BerriAI/litellm, covering think before coding and simplicity first.
deltallm AGENTS.md
AGENTS.md instructions for deltawi/deltallm, covering repository instructions, required first step and precedence and maintenance.
portkey-admin-mcp AGENTS.md
AGENTS.md instructions for CodesWhat/portkey-admin-mcp, covering agent instructions and code review.
inferrail CLAUDE.md
Claude Code instructions for domondi1/inferrail, covering inferrail — agent context, before major feature work, read, before implementing something substantial, ask, engineering rules and repo-level conventions.