relay

module
v0.9.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: Apache-2.0

README

Wyolet Relay

Wyolet Relay

One endpoint in front of every LLM provider.
Self-hosted, bring-your-own-keys, built for scale.

Docs Docker image Discord Follow on X

Quickstart · Docs · Discord · X · LinkedIn · Bluesky · Reddit


Wyolet Relay puts a single OpenAI- and Anthropic-compatible endpoint in front of every provider you use. Pool your own API keys for automatic failover and higher effective rate limits, see exactly what every request costs, and run the whole thing on your own infrastructure — a drop-in for the SDK code you already have.

Quickstart

Start a full relay — API, admin UI, database, and a pre-seeded model catalog — in one command:

docker run -p 8080:8080 -p 8081:8081 wyolet/relay:standalone

Open the admin UI at http://localhost:8081, then let the setup wizard walk you through adding a provider key and minting a relay key. Now call it like the OpenAI API:

curl http://localhost:8080/openai/v1/chat/completions \
  -H "Authorization: Bearer <your-relay-key>" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hello"}]}'

That's it. The full walkthrough, configuration, and production deployment guides live at docs.wyolet.com.

Features

  • One API, every provider. OpenAI- and Anthropic-shape endpoints in front of OpenAI, Anthropic, Bedrock, Vertex, Azure, Ollama, Groq — anything speaking either wire format. No code changes to switch upstreams.
  • Disposable, rate-limited keys. Mint relay keys scoped to whatever limits you set. Hand them out freely — even if one leaks, the damage is capped at those limits and your real provider keys are never exposed.
  • Pool accounts and providers. Combine many keys, accounts, or providers into one pool behind a single endpoint. Relay load-balances and fails over across them, so per-account rate limits stop being your ceiling.
  • Per-key access control. Decide exactly which models and providers each relay key may reach — allow or deny at the key level via policies.
  • 400+ models, open catalog. Ships knowing 400+ models out of the box, and the catalog is open and extensible — we add hosts and models on demand.
  • Batch processing (in progress). Batch requests against any provider — Relay simulates batching where there's no native API, and routes through the native one (OpenAI, Gemini, Anthropic) where it exists, passing the cost discount straight through. Configure a webhook to fire when a batch completes.
  • Proxy mode. Point Relay at a provider with your own upstream key and use it as a transparent proxy — no policy enforcement, just full usage, cost, and payload logging.
  • Usage & cost tracking. Every request is metered and stored in Postgres or ClickHouse. Optional full request/response payload capture (off by default).
  • Metrics & logs. First-class Prometheus /metrics and structured JSON logs. (OpenTelemetry tracing is on the way.)
  • Self-hostable, built for scale. Bring your own keys; nothing phones home. Sub-2 ms added latency, thousands of requests/sec per pod, Kubernetes-native.

How it works

Relay runs two listeners: a data plane that accepts your inference requests and a control plane that serves the admin UI and API. Each request is authenticated by a relay key, matched to a policy that decides which models and providers it may reach, rate-limited, and routed to a healthy upstream key from the pool — then streamed straight back to you. Provider, model, and pricing data comes from an open, versioned catalog, so a fresh container already knows hundreds of models.

Want the full architecture, API reference, and configuration? → docs.wyolet.com

Commercial support

Relay is Apache-2.0 — free to use, self-host, and build on, in commercial and closed-source products alike. Want managed hosting, enterprise builds, or priority support instead of running it yourself? We're happy to talk: business@wyolet.com.

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md for the build, test, and PR workflow.

License

Apache-2.0. Use it in anything — commercial, closed-source, hosted, or embedded — no copyleft strings attached. See Commercial support if you'd rather we run or support it for you.

Directories

Path Synopsis
app
actor
Package actor carries the identity of the caller making a request.
Package actor carries the identity of the caller making a request.
adapter
Package adapter provides the generic adapter framework: a Spec type that bundles wire-shape metadata (inbound URL paths, upstream URL path, auth strategy, canonical translator, token extractor), a generic pipeline.Adapter implementation parameterised by path and auth strategy, a Registry of Specs, and a generic route mounter that iterates registered specs.
Package adapter provides the generic adapter framework: a Spec type that bundles wire-shape metadata (inbound URL paths, upstream URL path, auth strategy, canonical translator, token extractor), a generic pipeline.Adapter implementation parameterised by path and auth strategy, a Registry of Specs, and a generic route mounter that iterates registered specs.
adapters
Package adapters names the wire protocol the relay speaks to an upstream.
Package adapters names the wire protocol the relay speaks to an upstream.
authz
Package authz answers "can this actor perform this action on this resource?" — a deliberate seam so the v1 always-allow implementation can later be swapped for Casbin / OpenFGA / Keto without touching call sites.
Package authz answers "can this actor perform this action on this resource?" — a deliberate seam so the v1 always-allow implementation can later be swapped for Casbin / OpenFGA / Keto without touching call sites.
batch
Package batch is the batch subsystem: it accepts bulk inference submissions, runs each item as a background job (via the jobq module), and exposes submit/poll/cancel/results over the customer-facing /v1 surface.
Package batch is the batch subsystem: it accepts bulk inference submissions, runs each item as a background job (via the jobq module), and exposes submit/poll/cancel/results over the customer-facing /v1 surface.
binding
Package binding is the domain layer for the HostBinding entity — the first-class join that declares "Model M is served by Host H, via wire adapter A, under upstream name U, priced by Pricing P."
Package binding is the domain layer for the HostBinding entity — the first-class join that declares "Model M is served by Host H, via wire adapter A, under upstream name U, priced by Pricing P."
catalog
Snapshot assembly.
Snapshot assembly.
catalogembed
Package catalogembed composes manifest YAML into the SDK catalog embed schema.
Package catalogembed composes manifest YAML into the SDK catalog embed schema.
catalogvalidate
Package catalogvalidate is the cross-entity graph linter for the catalog repo's `data/` tree.
Package catalogvalidate is the cross-entity graph linter for the catalog repo's `data/` tree.
catalogview
Package catalogview builds consumer-facing read projections of catalog data for the admin/UX surface ("API UX"): a model's hosts, its pricing per host, the policies that grant it.
Package catalogview builds consumer-facing read projections of catalog data for the admin/UX surface ("API UX"): a model's hosts, its pricing per host, the policies that grant it.
host
Package host is the domain layer for the Host entity — a serving endpoint the relay forwards requests to.
Package host is the domain layer for the Host entity — a serving endpoint the relay forwards requests to.
hosthealth
Package hosthealth records and reads per-host runtime reachability — the observed-state counterpart to host.Spec.
Package hosthealth records and reads per-host runtime reachability — the observed-state counterpart to host.Spec.
hostkey
Package hostkey is the domain layer for the HostKey entity — a credential the relay uses to authenticate to a Host (a serving endpoint).
Package hostkey is the domain layer for the HostKey entity — a credential the relay uses to authenticate to a Host (a serving endpoint).
httpapi
Package httpapi holds the HTTP layer for both Relay planes.
Package httpapi holds the HTTP layer for both Relay planes.
httpapi/control
OIDC login for the control plane: GET /auth/oidc/start redirects to the configured provider's hosted login; GET /auth/oidc/callback exchanges the authorization code and mints the same scs session password login mints, so everything downstream of login is identical for both paths.
OIDC login for the control plane: GET /auth/oidc/start redirects to the configured provider's hosted login; GET /auth/oidc/callback exchanges the authorization code and mints the same scs session password login mints, so everything downstream of login is identical for both paths.
httpapi/inference
Package inference's Dispatch is the shape-agnostic per-request flow.
Package inference's Dispatch is the shape-agnostic per-request flow.
keypool
Package keypool implements per-key circuit-breaker state and configurable Pool selection over healthy keys.
Package keypool implements per-key circuit-breaker state and configurable Pool selection over healthy keys.
manifest
Package wire handles conversion between the operator-facing YAML/JSON wire format and the domain structs in the app/* entity packages.
Package wire handles conversion between the operator-facing YAML/JSON wire format and the domain structs in the app/* entity packages.
meta
Package meta holds the identity primitives every domain entity carries: UUIDv7 id, DNS-1123 slug name, free-text display name, and provenance.
Package meta holds the identity primitives every domain entity carries: UUIDv7 id, DNS-1123 slug name, free-text display name, and provenance.
metricslog
Package metricslog is the Prometheus observer on the lifecycle spine.
Package metricslog is the Prometheus observer on the lifecycle spine.
model
Package model is the domain layer for the Model entity — a container for a family of dated checkpoints (Snapshots).
Package model is the domain layer for the Model entity — a container for a family of dated checkpoints (Snapshots).
modelref
Package modelref parses the catalog reference DSL used by Policy grants and the /catalog/resolve admin endpoint.
Package modelref parses the catalog reference DSL used by Policy grants and the /catalog/resolve admin endpoint.
overlay
Package overlay is the domain layer for catalog overlays: user-owned sparse spec patches applied on top of pristine catalog TEMPLATE rows to produce the EFFECTIVE rows the snapshot serves.
Package overlay is the domain layer for catalog overlays: user-owned sparse spec patches applied on top of pristine catalog TEMPLATE rows to produce the EFFECTIVE rows the snapshot serves.
payloadlog
Package payloadlog is the second lifecycle observer (after app/usagelog): it captures the full request + response bodies of opted-in requests for audit, debug, and replay, and pushes them to a Sink (file today, S3 next) off the hot path.
Package payloadlog is the second lifecycle observer (after app/usagelog): it captures the full request + response bodies of opted-in requests for audit, debug, and replay, and pushes them to a Sink (file today, S3 next) off the hot path.
pipeline
Package pipeline orchestrates one inference request: reserve inbound budget, acquire an upstream key (and its upstream reservation) via policy.Service, call the adapter, stream back, commit in post-flight.
Package pipeline orchestrates one inference request: reserve inbound budget, acquire an upstream key (and its upstream reservation) via policy.Service, call the adapter, stream back, commit in post-flight.
policy
Package policy is the domain layer for the Policy entity — the named group that bundles Models (m:n), ProviderKeys (m:n), and an optional single RateLimit (m:1, the one rule set that applies to traffic through this Policy).
Package policy is the domain layer for the Policy entity — the named group that bundles Models (m:n), ProviderKeys (m:n), and an optional single RateLimit (m:1, the one rule set that applies to traffic through this Policy).
pricing
Package pricing is the domain layer for the Pricing entity — a named rate sheet owned by a Host and applied to one or more Models.
Package pricing is the domain layer for the Pricing entity — a named rate sheet owned by a Host and applied to one or more Models.
provider
Package provider is the domain layer for the Provider entity — the vendor / author of a Model.
Package provider is the domain layer for the Provider entity — the vendor / author of a Model.
proxy
Package proxy is the second inference flow: transparent forwarding of caller-supplied upstream credentials.
Package proxy is the second inference flow: transparent forwarding of caller-supplied upstream credentials.
ratelimit
Package ratelimit is the domain layer for the RateLimit entity — a named rule set (requests / tokens / concurrency caps) attachable to a Policy, ProviderKey, or Model.
Package ratelimit is the domain layer for the RateLimit entity — a named rule set (requests / tokens / concurrency caps) attachable to a Policy, ProviderKey, or Model.
relaykey
Package relaykey is the domain layer for the RelayKey entity — an inbound API key the relay issues to a client.
Package relaykey is the domain layer for the RelayKey entity — an inbound API key the relay issues to a client.
routing
PolicyAllows answers "is this Model reachable through this Policy?" without picking a binding or a key — the question /v1/models needs to answer.
PolicyAllows answers "is this Model reachable through this Policy?" without picking a binding or a key — the question /v1/models needs to answer.
secret
agent.go implements pipeline.KeyAgent: the out-of-band handler for failed upstream keys.
agent.go implements pipeline.KeyAgent: the out-of-band handler for failed upstream keys.
seed
Package seed orchestrates loading YAML config into Postgres for the app/ arch.
Package seed orchestrates loading YAML config into Postgres for the app/ arch.
session
Package session wraps alexedwards/scs/v2 with a kv.Store-backed session store and the small amount of glue that turns scs payloads into our app/actor.Actor.
Package session wraps alexedwards/scs/v2 with a kv.Store-backed session store and the small amount of glue that turns scs payloads into our app/actor.Actor.
settings
Package settings is the typed-sectioned config layer.
Package settings is the typed-sectioned config layer.
settingswatch
Package settingswatch applies a value-typed settings section to a live consumer, re-applying whenever the section changes.
Package settingswatch applies a value-typed settings section to a live consumer, re-applying whenever the section changes.
transport/ws
Package ws is a customer-facing WebSocket transport for the inference data plane.
Package ws is a customer-facing WebSocket transport for the inference data plane.
usagelog
Package usagelog is the first consumer of pkg/lifecycle's Hook + Collector surface.
Package usagelog is the first consumer of pkg/lifecycle's Hook + Collector surface.
user
store.go is the data-access layer for User.
store.go is the data-access layer for User.
cmd
catalog-embed command
catalog-embed reads the public catalog YAML tree and writes sdk/catalog/catalog.json.
catalog-embed reads the public catalog YAML tree and writes sdk/catalog/catalog.json.
catalog-schemas command
catalog-schemas dumps JSON Schema files for every catalog wire kind, one file per kind under <out>/.
catalog-schemas dumps JSON Schema files for every catalog wire kind, one file per kind under <out>/.
catalog-validate command
catalog-validate runs the schema-generic graph linter (catalogvalidate.ValidateGraph) against a directory of YAML manifests and prints findings.
catalog-validate runs the schema-generic graph linter (catalogvalidate.ValidateGraph) against a directory of YAML manifests and prints findings.
icon-import command
icon-import downloads provider icons from OpenRouter's events/all-providers.json into a target directory (typically the relay-ui repo's public/provider/ folder).
icon-import downloads provider icons from OpenRouter's events/all-providers.json into a target directory (typically the relay-ui repo's public/provider/ folder).
modelsdev-import command
modelsdev-import fetches the models.dev dataset (https://models.dev/api.json) and writes relay-catalog YAML — Provider, Host, Model, HostBinding, and Pricing — for an allowlist of providers.
modelsdev-import fetches the models.dev dataset (https://models.dev/api.json) and writes relay-catalog YAML — Provider, Host, Model, HostBinding, and Pricing — for an allowlist of providers.
payload-migrate command
Command payload-migrate backfills a JSONL file-backend payload dump (relay-payloads.jsonl) into the ClickHouse payload_logs table, so historical request/response bodies become queryable through the same reader the relay uses — after which the multi-GB local file can be deleted.
Command payload-migrate backfills a JSONL file-backend payload dump (relay-payloads.jsonl) into the ClickHouse payload_logs table, so historical request/response bodies become queryable through the same reader the relay uses — after which the multi-GB local file can be deleted.
relay command
Command relay is the wyolet-relay data + control plane binary.
Command relay is the wyolet-relay data + control plane binary.
relay-stats command
relay-stats — thin HTTP client for the relay control plane's /usage/events + /usage/summary endpoints.
relay-stats — thin HTTP client for the relay control plane's /usage/events + /usage/summary endpoints.
relay/web
Package web embeds the relay-ui single-page app and serves it from the control plane.
Package web embeds the relay-ui single-page app and serves it from the control plane.
internal
config
Package config centralizes all RELAY_* env var parsing for the relay binary.
Package config centralizes all RELAY_* env var parsing for the relay binary.
identity
Package identity owns the User catalog kind and the SecretRef resolution machinery used to pull credential material out of the environment, files, or (discouraged) inline literals — pydantic-SecretStr style.
Package identity owns the User catalog kind and the SecretRef resolution machinery used to pull credential material out of the environment, files, or (discouraged) inline literals — pydantic-SecretStr style.
storage
Package storage owns the Postgres connection pool and runs migrations.
Package storage owns the Postgres connection pool and runs migrations.
jobq module
migrations
postgres
Package pgmigrations embeds the postgres migration SQL files.
Package pgmigrations embeds the postgres migration SQL files.
pkg
crypto
Package crypto provides AES-GCM-256 encryption primitives and master-key helpers for Relay's stored-secret subsystem.
Package crypto provides AES-GCM-256 encryption primitives and master-key helpers for Relay's stored-secret subsystem.
filter
Package filter is a declarative, allowlist-based query engine for list endpoints.
Package filter is a declarative, allowlist-based query engine for list endpoints.
ids
Package ids generates immutable resource identifiers.
Package ids generates immutable resource identifiers.
kv
lifecycle
Package lifecycle is the in-process hook registry every request-runner (pipeline, proxy, future ws/batch) fires events into.
Package lifecycle is the in-process hook registry every request-runner (pipeline, proxy, future ws/batch) fires events into.
metrics
Package metrics owns the Prometheus registry and the /metrics HTTP handler.
Package metrics owns the Prometheus registry and the /metrics HTTP handler.
payload
Package payload is the storage contract for request/response body capture: the Record shape and the Sink/Reader interfaces its backends satisfy.
Package payload is the storage contract for request/response body capture: the Record shape and the Sink/Reader interfaces its backends satisfy.
payload/clickhouse
Package clickhouse provides a ClickHouse-backed implementation of payload.Sink, payload.Reader, and payload.Closer — the Langfuse-style "text bodies in ClickHouse" backend for the Logs view.
Package clickhouse provides a ClickHouse-backed implementation of payload.Sink, payload.Reader, and payload.Closer — the Langfuse-style "text bodies in ClickHouse" backend for the Logs view.
payload/file
Package file is the JSONL file backend for payload logging: one Record per line.
Package file is the JSONL file backend for payload logging: one Record per line.
payload/s3
Package s3 is the object-store backend for payload logging: one JSON object per Record.
Package s3 is the object-store backend for payload logging: one JSON object per Record.
ratelimit
Package ratelimit implements a sliding-window-counter rate limiter with a two-phase Reserve/Commit API.
Package ratelimit implements a sliding-window-counter rate limiter with a two-phase Reserve/Commit API.
secret
Package secret is the relay's unified secret-resolution layer: a backend-agnostic Ref pointing at a credential, and a Resolver that turns it into plaintext.
Package secret is the relay's unified secret-resolution layer: a backend-agnostic Ref pointing at a credential, and a Resolver that turns it into plaintext.
secret/aws
Package aws resolves secret.KindAWS refs by fetching from AWS Secrets Manager.
Package aws resolves secret.KindAWS refs by fetching from AWS Secrets Manager.
secret/azure
Package azure resolves secret.KindAzure refs by fetching from Azure Key Vault.
Package azure resolves secret.KindAzure refs by fetching from Azure Key Vault.
secret/bitwarden
Package bitwarden resolves KindBitwarden secrets by fetching encrypted vault data from Vaultwarden/Bitwarden and decrypting client-side.
Package bitwarden resolves KindBitwarden secrets by fetching encrypted vault data from Vaultwarden/Bitwarden and decrypting client-side.
secret/gcp
Package gcp resolves secret.KindGCP refs by fetching from GCP Secret Manager.
Package gcp resolves secret.KindGCP refs by fetching from GCP Secret Manager.
secret/oauth
Package oauth resolves OAuth credentials for the relay's secret layer.
Package oauth resolves OAuth credentials for the relay's secret layer.
secret/onepassword
Package onepassword resolves secret.KindOnePassword refs via the official 1Password Go SDK and a service-account token.
Package onepassword resolves secret.KindOnePassword refs via the official 1Password Go SDK and a service-account token.
slug
Package slug derives DNS-1123-compatible identifiers from free-text display names, with deterministic collision suffixes.
Package slug derives DNS-1123-compatible identifiers from free-text display names, with deterministic collision suffixes.
usage/clickhouse
Package clickhouse provides a ClickHouse-backed implementation of usage.Sink, usage.Reader, and usage.Closer.
Package clickhouse provides a ClickHouse-backed implementation of usage.Sink, usage.Reader, and usage.Closer.
usage/file
Package file is the JSONL file backend for usage logging: a Sink that appends one event per line and a Reader that scans the same file.
Package file is the JSONL file backend for usage logging: a Sink that appends one event per line and a Reader that scans the same file.
usage/postgres
Package postgres implements usage.Sink, usage.Reader, and usage.Closer backed by PostgreSQL.
Package postgres implements usage.Sink, usage.Reader, and usage.Closer backed by PostgreSQL.
usage/valkey
Package valkey is a TTL-bounded usage Sink + Reader backed by pkg/kv.
Package valkey is a TTL-bounded usage Sink + Reader backed by pkg/kv.
sdk module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL