ai-gateway: Instructions file for Codex

AGENTS.md

ai-gateway AGENTS.md is an instructions file for Codex, OpenCode from ferro-labs/ai-gateway. It costs 21,998 tokens per session, scanned A, original, Apache-2.0.

A project guide for Ferro Labs AI Gateway, an open-source Go service that routes requests between applications and 30 large-language-model providers through one compatible interface. It describes the project's structure, current development state, and development commands.

In plain words
What is it for?
Use it to understand provider registration, shared gateway packages, project conventions, and the commands for building, testing, and running the service.
Why use it?
It gives coding agents the architectural context needed to change providers and shared code without guessing how the gateway is organized.

Instructions file for CodexOpenCode

Written for Codex and OpenCode: the file is AGENTS.md. Also seen: mentions AGENTS.md.

This is ferro-labs/ai-gateway's own configuration. It tells Codex and OpenCode how to work on ai-gateway itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything ai-gateway configures →

Reuse

Borrowing it

Nothing to install: this file belongs to ferro-labs/ai-gateway. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/ferro-labs/ai-gateway/main/AGENTS.md
Clone the repo
git clone --depth 1 https://github.com/ferro-labs/ai-gateway

Made for: Codex, OpenCode.

Wrote 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.

agentmods badge for ai-gateway AGENTS.md

README.md
[![agentmods](https://agentmods.dev/badge/instructions/ferro-labs/ai-gateway/agents-md/github.svg)](https://agentmods.dev/instructions/ferro-labs/ai-gateway/agents-md)
Your own site
<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/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for ai-gateway AGENTS.md

Your own site · 80×15
<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="Reviewed on agentmods" width="80" height="20"></a>
Per session 21,998 This file is loaded in full into every session.
When invoked 21,998 The same file — it is already loaded in full.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

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.

ModelPer sessionOnce invoked
Fable 5.1 $0.21998 $0.21998
Opus 5.5 $0.08799 $0.08799
Sonnet 5.5 $0.04400 $0.04400
Haiku 4.5 $0.02200 $0.02200

Measured 9d ago against content hash 810f67a01be4, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

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 9d 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.

AGENTS.md · 1,328 lines

How it starts

The opening of the file, as written. The whole thing — 1,328 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.26.10+
  • License: Apache 2.0

Current Development Snapshot

  • 30 provider subpackages — each provider lives in providers/<id>/<id>.go with its own test file, one per ProviderEntry in providers/providers_list.go. (providers/core/ and providers/capabilities/ are shared code, not providers.) No root-level constructor shims remain.
  • Unified factory — providers/factory.go holds types/constants; providers/providers_list.go holds all built-in ProviderEntry records. Auto-registration via AllProviders() means main.go never needs editing for new providers.
  • providers/core/ split — interfaces in contracts.go; shared types split into chat.go, stream.go, embedding.go, image.go, model.go, constants.go, errors.go.
  • Single source of truth for name constants — providers/names.go re-exports NameXxx from each subpackage's const Name.
  • Model discovery — providers/core exposes DiscoverOpenAICompatibleModels/DiscoverModelsWithHeaders for live /models enumeration, 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, regex guard, PII redaction, secret scanning, prompt-injection shield, response schema validation, 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 (stable Provider/Span/Exporter/Event seam + gen_ai.*/ferro.* attribute constants); internal/otel/ wires the OTLP exporter, W3C propagation, and a custom IDGenerator that unifies the OTel trace_id with 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.go is the single source of truth for which OpenAI chat parameters each provider can express. Providers no longer keep private supported-parameter lists; core.EnforceUnsupportedParams reads the matrix and applies compatibility.on_unsupported_param (warn | drop | reject). Served by GET /v1/capabilities.
  • Conformance suite (v1.2.0) — test/conformance/ builds every provider through its ProviderEntry, points it at an httptest stub returning that provider's native payload, and asserts the translated core.Response. No build tag, no network: it runs with make test. TestConformanceCoverage fails 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: RejectionError keeps its 4xx/429, FailureError is a 500. Logging and metrics plugins fail open; guardrail, auth, ratelimit, transform, and unknown types fail closed. Reject is honoured for every type. The type that decides this is the one the plugin reports from Type(), not plugins[].type in config.
  • Env references (v1.2.0) — internal/envref resolves ${VAR} at component construction, never at config load, so the Config never carries a materialised secret into the config-history store, GET /admin/config, or a rollback. A bare $ is data ($100, pa$$w0rd survive); an undefined variable is an error.
  • Per-target concurrency (v1.2.0) — targets[].concurrency bounds in-flight requests per provider with a queue; overflow returns ErrProviderSaturated → 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 /health semantics; /health is retained.
  • Plugin short-circuiting (Unreleased) — Context.Skip is removed; code that sets or reads it no longer compiles. Context.SkipProvider replaces it and skips the provider call only: every remaining before_request plugin and the whole after_request stage 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 the before_request stage, and it ends that stage alone — on_error still runs, so a request denied by policy is still recorded. SkipProvider stays set through after_request as a fact (cache-served vs provider-served) that cost recording keys off.
  • Request attribution (Unreleased) — Context.Target names 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 left on_error rows naming no provider. Request-log rows also carry api_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 on api_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 routeTargets in gateway_pipeline.go. Retry, circuit breaker, per-target concurrency, error classification, metrics and request logging live there once, so the four surfaces cannot drift. targets[].retry is honoured under every routing mode, not only fallback.
  • One completion ceiling (Unreleased) — max_tokens and max_completion_tokens are resolved to a single value at every entry point, max_completion_tokens winning when both are present, so a guardrail and the provider read the same number. See Completion length.
  • Declared models (Unreleased) — targets[].models lets 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 /models endpoint, 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 a ferrogw validate / startup error rather than a request-time 500. Unknown conditions[].key and content_conditions[].type values are load errors; weight: 0 means zero traffic, a negative weight is an error, and an all-zero weight set is an error.
  • Request identity (Unreleased) — observability.RequestIdentity (end-user id, session id, request metadata) is set on the request context by internal/otel.Middleware from X-User-ID, X-Session-ID and the W3C baggage entries user.id / session.id, or by an embedder through observability.ContextWithRequestIdentity; the gateway overlays the OpenAI body user. It is recorded as enduser.id / session.id / ferro.request.metadata.<key> on the request span, on RequestAttrs, Event and RoutingAttempt, and as user_id / session_id on request-log rows. observability.tracing.attempt_spans opens one gateway.routing.attempt CLIENT span per routing attempt through the optional observability.AttemptSpanProvider; observability.tracing.propagate_passthrough (default true) injects traceparent on /v1/* pass-through forwards and on the fixed-target forwards (/v1/responses create and its id sub-routes, /v1/files, /v1/batches). Nothing is inferred and no identity is a body field other than user.

Read the full file on GitHub · 1,328 lines

Changes

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.

  1. 9d ago Changed 810f67a01be4
  2. 19d ago Changed · +2 tokens per session 60b706f422f6
  3. 1mo ago Changed · +2 lines · +138 tokens per session 99dacf325f5d
  4. 1mo ago Changed · +18 lines · +214 tokens per session 2e8d686d3cb4
  5. 1mo ago Changed · +2 tokens per session ec2a9ead2077
  6. 2mo ago Changed · +3 lines · +332 tokens per session 3cb0cedef713
  7. 2mo ago Changed · +64 lines · +1,068 tokens per session dc7456692455
  8. 2mo ago First seen · 1,241 lines · 20,242 tokens per session scan A 60ba0f2c5cf8

Subscribe to this mod's changes

ai-gateway AGENTS.md is an instructions file published in the GitHub repository ferro-labs/ai-gateway (277 stars, last pushed 4d ago), licensed Apache-2.0. It adds 21,998 tokens to every session, about $0.0880 per session on Opus 5.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.

Related

ai-gateway AGENTS.md compared with instructions from other repositories

ai-gateway AGENTS.md next to 6 instructions from other repositories
ModTypeStarsLast pushLicenceScanTokensWorks with
ai-gateway AGENTS.mdferro-labs/ai-gatewayInstructions file2774d agoApache-2.0A21,998Codex, OpenCode
vscode buildNext.instructions.mdmicrosoft/vscodeInstructions file195kyesterdayMITA9,719GitHub Copilot
next.js AGENTS.mdvercel/next.jsInstructions file143ktodayMITA7,461Codex, OpenCode
langchain AGENTS.mdlangchain-ai/langchainInstructions file149kyesterdayMITA4,680Codex, OpenCode
vscode oss-third-party-notices.instructions.mdmicrosoft/vscodeInstructions file195kyesterdayMITA5,516GitHub Copilot
vscode copilot-instructions.mdmicrosoft/vscodeInstructions file195kyesterdayMITA3,093GitHub Copilot
deepseek-harness AGENTS.mddeepseek-ai/deepseek-harnessInstructions file274k2d agoMITA4,313Codex, OpenCode