Skip to content

Releases

0.1.0-rc.2

0.1.0-rc.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 05 Nov 07:49
v0.1.0-rc.2
7558646

Release Notes

Names settle: config fields, record values, metrics, and CLI flags now use the glossary's terms, and the Claude route has one form. Many changes are breaking (marked below); a 0.1.0-rc.1 config needs the renames listed under "Breaking, config". wye init writes sample policy tests, and every command run with no arguments says what to run next.

  • License: MIT, instead of WTFPL.
  • Breaking: wye init --api-key is now --provider-key, and --team is now --shared. The flags name the two choices a setup makes. --shared with --provider-key is no longer an error, since a shared gateway always holds the provider key.
  • Examples, one directory per use: examples/developer/ (was examples/subscription.toml), examples/team/ (developers through SSO, CI through GitHub Actions tokens, two keys with failover), and examples/app/ (a gateway token per service, aliases with a canary, a second provider for failover, OpenAI), the last two with policy tests that the test suite runs. examples/policy-tests/ is gone; its config trusted a public test key.
  • The sample price tables (README, docs/policy.md, examples/wye.toml) priced cache reads on Opus 5.5 and Sonnet 5.5 at 0.1 times input; Anthropic charges 0.05 times. A table copied from them counts cache reads at twice their cost: set cache_read = "0.20" for Opus 5.5 and "0.10" for Sonnet 5.5.
  • examples/wye.toml sets the [server] and Claude route options live at their defaults instead of in comments, so every option is visible.
  • Docs: the README says what Wye does, who it is for, how it compares with what teams expect of a gateway, and how fast it is; the guide gains how-tos for several upstreams, costs, model aliases and upgrades, and an OpenTelemetry backend.
  • wye-bench --agentgateway runs the benchmark through agentgateway; results in docs/benchmarks.md.
  • Fix: under an output-token ceiling, a body with a second JSON value after the object ({...}{"max_output_tokens":10}) is refused. It passed on the OpenAI routes, and a provider whose parser reads only the first value would have seen no ceiling.
  • Fix: a model name longer than 128 bytes from the provider is no longer kept in records and metrics (Messages and Chat Completions streams).
  • Fix: with OTLP on, a usage log whose reader stalls keeps as many records as without OTLP, and shutdown exports the final metrics even while the usage log is blocked.
  • wye report keeps each count on the line of its name when it wraps.
  • A body sent in chunks so small that it alone passes max_total_held_bytes gets 413 instead of the retryable 529 (503 on the OpenAI APIs), which no retry could clear.
  • The refusal of an output-token value over the ceiling says exceeds the output-token ceiling of N; it said this gateway token's limit even when the ceiling came from [auth] max_output_tokens alone. wye explain shows (ceiling N).
  • Breaking, config: keys renamed so each names what it holds, with no aliases; a config with an old name fails at startup with an unknown-field error. api_key_env → provider_key_env and api_key_file → provider_key_file (in every upstream); [[auth.issuers]] → [[auth.identity_providers]] (and its grants); [[auth.keys]] → [[auth.signing_keys]]; [auth] max_token_ttl_secs → max_gateway_token_ttl_secs; [server] max_held_request_bytes → max_total_held_bytes; [[pricing.models]] → [[pricing.prices]] (and its tiers). The route option failover_max_held_bytes is now [server] max_total_kept_bytes: it always bounded kept bodies across the whole process, so it is set once there, with the same default (256 MiB).
  • Breaking, config: [upstream] is removed, with no alias; the Claude route has one form, [[routes.claude.upstreams]] entries with optional [routes.claude] fields, and a config with [upstream] fails at startup with an unknown-field error. Move its fields into one [[routes.claude.upstreams]] entry. id is optional when a route has one upstream (its records then carry no upstream, as before), and forward_caller_credential = true moves there: allowed on the Claude route's only upstream, still loopback only and not with [auth].
  • Config errors name the field as the config writes it: routes.claude.upstreams "a": provider_key_env for a route's upstream, routes.claude.upstreams[0]: base_url for a route's only upstream written without an id, and routes.openai.select for a route's own options; a file that fails to load at startup is named the same way.
  • Breaking, records: what Wye emits is renamed, with no aliases. Usage records: the outcome gateway_error, which covered Wye's refusals, upstreams that gave no response, and Wye's own faults, splits into refused (Wye's refusal), upstream_error (Wye's 502 or 504), and gateway_error (Wye's own fault only); failed → truncated; headers_ms → response_headers_ms; context_compacted → after_compaction; the usage_status not_observed → none; each failovers entry's status or error → reason (429, 529, or connect); prompt → prompt_hashes; the usage_log_dropped event's count → records, as in otlp_dropped. New: upstream_error says why an upstream gave no usable response (connect, timeout, or reset), and wye report counts it. OTLP logs and spans: gen_ai.system → gen_ai.provider.name, now the provider of the upstream that served the request (aws.bedrock for Bedrock); wye.requested_model → gen_ai.request.model; wye.headers_ms → wye.response_headers_ms; wye.context_compacted → wye.after_compaction; wye.prompt → wye.prompt_hashes; new wye.upstream_error; tool spans tool <name> → execute_tool <name>, with gen_ai.operation.name; a refused request's span leaves its status unset instead of ERROR. Metrics: wye.telemetry.lost → wye.records.dropped; in wye.failovers, wye.upstream → wye.failover.upstream, unit {request} → {failover}; wye.upgrade.issues unit {request} → {issue}. Client errors: an upstream's header timeout (504) is timeout_error (was api_error), and a client body stalled during the hold (408) is invalid_request_error (was timeout_error). wye report still reads older logs.
  • wye service restart rewrites the service definition when this wye or the config's drain_delay_secs and shutdown_grace_secs call for a new one, and has the service manager load it; a restart used to keep the old stop timeout.
  • Breaking, CLI: names say what they hold, with no aliases. The signing key ~/.wye/issuer.key is ~/.wye/signing.key (mv ~/.wye/issuer.key ~/.wye/signing.key keeps yours); wye token issue --key is --signing-key; wye explain --path is --endpoint, and a policy test's path is endpoint. Output: wye explain's steps token: → gateway token: (with key id), route: → selection:, and provider key: the caller's own → credential: the caller's own (passthrough), and a path it does not serve reads not an endpoint Wye serves; wye report's (no hint) class → (unclassified), and its time columns read model and tools under time; wye service's Log and Errors → Usage log and Messages; wye policy-diff names a provider key (not the operator's key), a gateway token, and Wye tokens; wye doctor checks a config's secrets, files, and upstreams.
  • wye init also writes policy-tests/ next to the config: sample requests and the decisions the config it wrote makes (with --shared, a request with a gateway token that forwards and one without, refused with 401), so wye policy-test passes right after wye init. It never writes over a file. Run with no argument, each command does what its name says or fails with one line that says what to run next: wye explain names a sample request, wye policy-test without cases says how to add them, wye token issue and wye policy-diff show an example, wye claude, wye codex, and wye probe say to run wye init when nothing answers and there is no config, wye token issue without a signing key says how to make one, and wye token keygen refuses to replace the key wye token issue signs with. wye service status shows the message log too.
  • Links that the CLI prints or writes (the config wye init writes, its deployment step, wye service's advice on secrets) point at this version's release tag instead of main, so they describe the config keys and commands of the wye that printed them.

Install wye 0.1.0-rc.2

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/askrid/wye/releases/download/v0.1.0-rc.2/wye-installer.sh | sh

Download wye 0.1.0-rc.2

File Platform Checksum
wye-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
wye-x86_64-apple-darwin.tar.xz Intel macOS checksum
wye-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
wye-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

Verifying GitHub Artifact Attestations

The artifacts in this release have attestations gene...

Read more

0.1.0-rc.1

0.1.0-rc.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 31 Oct 06:33
v0.1.0-rc.1
483c083

Release Notes

A prerelease, to prove the release pipeline. Wye is a working prototype: tested
and benchmarked on one machine, used with Claude Code through a claude.ai
subscription. Expect the config format to change before 1.0. wye service has
not run under systemd on a real Linux machine.

What is in it:

  • Anthropic Messages (/v1/messages, count_tokens), OpenAI Responses, and
    OpenAI Chat Completions, forwarded byte for byte, streams relayed event by
    event.
  • Routes with several accounts. Each Claude Code session stays on one account
    (weighted rendezvous hashing on the session id). Failover on 429, 529,
    or a connection refused or cut before the request body was delivered, and
    never after the first response byte.
  • Providers for Claude: Anthropic, Claude Platform on AWS, and Amazon Bedrock,
    with API keys.
  • Gateway tokens: Wye's own Ed25519 tokens, or identity-provider tokens
    (RS256, ES256, EdDSA) with keys pinned in config. Model permissions and
    output-token ceilings, which a token can narrow but never widen.
  • Model aliases with per-subject rollout, and upgrade checks that report
    which requests a target model would reject.
  • Usage records per request (tokens, cost, cache hits and misses, session,
    subagent, request class, tool calls and time), OTLP logs, traces, and
    metrics, and optional cache-miss diagnostics.
  • Cost from a price table in config, in exact integer arithmetic.
  • Commands: init, serve, validate, doctor, explain,
    policy-test, policy-diff, report, probe, claude, codex, and
    token, each with --help. A user's files live in ~/.wye, and a
    command reads ~/.wye/wye.toml unless told otherwise (-c,
    $WYE_CONFIG), never a config it merely finds in the working directory.
    wye claude turns on Claude Code's gateway hints (request class, prompt id,
    tool times), and wye claude --bg starts background sessions that go through
    the gateway too.
  • wye service install, status, restart, and uninstall: the gateway
    as a LaunchAgent (macOS) or systemd user unit (Linux), shown before it is
    written and checked before it starts.
  • Release archives for Linux and macOS (x86_64, arm64) with checksums and
    build provenance attestations.

Not yet checked against the real services:

  • Bedrock and Claude Platform on AWS were built from the providers'
    documentation and tested against mocks. Bedrock's API key header in
    particular is unconfirmed (x-api-key is sent).
  • Codex support was built from Codex's source and tests, not from a real
    session.

Known limits:

  • No Windows build, no published container image, no Vertex AI, no AWS SigV4.
  • Provider keys are read at startup; short-lived keys need a restart to
    refresh.
  • No cumulative budgets or rate limits, by design: those stay with the
    provider.
  • Model permissions read the request's top-level model; a model named
    inside the body (an OpenAI image_generation tool's) is not checked.
  • Findings from review rounds that are still open are listed in
    docs/roadmap.md, "Open findings".

Install wye 0.1.0-rc.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/askrid/wye/releases/download/v0.1.0-rc.1/wye-installer.sh | sh

Download wye 0.1.0-rc.1

File Platform Checksum
wye-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
wye-x86_64-apple-darwin.tar.xz Intel macOS checksum
wye-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
wye-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

Verifying GitHub Artifact Attestations

The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:

gh attestation verify <file-path of downloaded artifact> --repo askrid/wye

You can also download the attestation from GitHub and verify against that directly:

gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>