agentleFS
NayjestNayjest/lm-proxy/AGENTS.md

lm-proxy

AGENTS.md154 starsChanged 3 months agoMITView on GitHub

LM-Proxy is a lightweight, OpenAI-compatible HTTP proxy/gateway (FastAPI + MicroCore) that unifies access to multiple LLM providers (OpenAI, Anthropic, Google, local PyTorch inference) behind a single OpenAI-format API. It runs as a standalone server or as an importable Python library. Run a single test: pytest tests/test_core.py::test_name -v pytest config lives in pyproject.toml: asyncio_mode = "auto" (async tests need no decorator), testpaths = ["tests"]. Optional provider deps are extras: pip install -e .[anthropic,google] or .[all]; .[test] for the test toolchain. The…

  • Reads credentials
  • Installs packages
  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repositoryOne other file it gives its agents.

The file

We split this AGENTS.md into the rules it gives an agent

3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Run a single test: pytest tests/test_core.py::test_name -v

    line 21
  2. Very specific:

    Never attribute work to an AI tool: no assistant/model/vendor names or "AI-generated" markers in branch names, commit messages, PR text, …

    line 61
  3. Distinctive:

    Keep it simple (KISS). Be laconic: minimal code, minimal docs, minimal PR/commit text.

    line 62

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

This file provides guidance to AI coding agents when working with code in this repository.

What this is

LM-Proxy is a lightweight, OpenAI-compatible HTTP proxy/gateway (FastAPI + MicroCore) that unifies access to multiple LLM providers (OpenAI, Anthropic, Google, local PyTorch inference) behind a single OpenAI-format API. It runs as a standalone server or as an importable Python library.

Commands

make install          # pip install -e .
make run              # fastapi run lm_proxy  (or: python -m lm_proxy / lm-proxy)
make test             # pytest --log-cli-level=INFO
make integration-test # pytest tests/test_integration.py -v
make cs               # flake8 .   (lint)
make black            # black .     (format; line-length 100)
make build            # python multi-build.py  (build dist packages)

Run a single test: pytest tests/test_core.py::test_name -v

pytest config lives in pyproject.toml: asyncio_mode = "auto" (async tests need no decorator), testpaths = ["tests"].

Optional provider deps are extras: pip install -e .[anthropic,google] or .[all]; .[test] for the test toolchain.

The server loads config.toml from the cwd by default (lm-proxy --config <path> to override; --env to pick a .env file). The repo-root config.toml is the dev/reference config; more samples live in examples/.

Architecture

Request flow for POST /v1/chat/completions (lm_proxy/core.py:chat_completions):

  1. fail_if_service_disabled() → check() validates the virtual/client API key via config.api_key_check, returning a group name (and optional user_info).
  2. resolve_connection_and_model() matches the requested model against config.routing patterns (fnmatch wildcards). Rule values are "connection.model" or "connection.*" (* passes the requested model name through unchanged).
  3. Group allowed_connections is enforced (comma-separated connection names or "*"; groups also hold the api_keys list checked by the default validator).
  4. before handlers (middleware) run sequentially, each receiving a RequestContext.
  5. The resolved connection — a MicroCore llm_async_function — is invoked. Streaming requests go through process_stream() (SSE text/event-stream); non-streaming return a JSON choices array.
  6. log_non_blocking() fires all configured loggers as async tasks.

GET /v1/models (models_endpoint.py) lists config.routing keys filtered by the caller group's allowed connections; model_listing_mode controls wildcard-pattern handling and model_info merges extra metadata per model.

Key modules:

  • app.py — Typer CLI (cli_app) + FastAPI factory (web_app). Endpoints registered under config.api_prefix (default /v1).
  • bootstrap.py — bootstrap() loads .env, sets up logging/debug, then Env.init() builds the env runtime singleton: resolves connections (into MicroCore async LLM functions), components, loggers, and before handlers. Most runtime code reads global env.config, env.connections, etc.
  • config.py — Pydantic Config model (extra="forbid"). Config.load() dispatches by file extension to a loader registered as a config.loaders entry point (see pyproject.toml), supporting TOML / YAML / JSON / Python configs. Env-var refs (env:VAR_NAME) are expanded via replace_env_strings_recursive.
  • base_types.py — ChatCompletionRequest (the OpenAI-shaped request) and RequestContext (the per-request object threaded through handlers and loggers).
  • utils.py:resolve_instance_or_callable — the central extensibility primitive: turns a config value (dotted string "my.module.fn", dict with class/function key + kwargs, or callable) into a live object. Used for connections, api_key_check, handlers, loggers, components.

Extension points (all configured by reference, no core changes needed):

  • Connections ([connections]) — a MicroCore config dict (api_type, keys) OR a custom async callable. See strategies/fallback.py for an example custom connection.
  • api_key_check — api_key_check/ has check_api_key_in_config (default), CheckAPIKeyWithRequest (external HTTP/OIDC validation), and allow_all. A validator returns a group name (or (group, user_info) tuple), or falsy to reject.
  • Handlers / middleware ([[before]]) — handlers/ ships RateLimiter and HTTPHeadersForwarder. Any callable taking a RequestContext.
  • Loggers ([[loggers]]) — loggers.py (BaseLogger, JsonLogWriter, LogEntryTransformer). Run non-blocking.

Conventions

  • Errors surfaced to clients use OpenAI's error envelope ({"error": {"message","type","param","code"}}); see errors.py:OpenAIHTTPException.
  • Debug mode (LM_PROXY_DEBUG env or --debug) raises full tracebacks and sets DEBUG logging; otherwise exceptions are logged and a sanitized error returned. CLI flags override env.
  • Streaming errors are not HTTP errors: they arrive as a final SSE chunk carrying an error object and finish_reason: "error", followed by data: [DONE].
  • config.encryption_key salts the MD5 api_key_id hash used to identify keys in logs — client API keys are never logged raw.
  • Supported Python: 3.11–3.13.
  • Never attribute work to an AI tool: no assistant/model/vendor names or "AI-generated" markers in branch names, commit messages, PR text, comments, or docs.
  • Keep it simple (KISS). Be laconic: minimal code, minimal docs, minimal PR/commit text.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.