Layered DAG in crates/: types(L0) → config,store(L1) → auth,translate(L2) → provider,proto(L3) → proxy(L4). daemon sits outside the DAG and is consumed only by the CLI binary (src/main.rs, bin=byokey).
- types — core traits (
TokenStore,UsageStore,ProviderExecutor,RequestTranslator,ResponseTranslator),ByokError,OAuthToken,ProviderId - store — SQLite token/usage persistence via
sea-orm v2+sea-orm-migration;InMemoryTokenStorefor tests - auth — per-provider OAuth flows +
AuthManager(token lifecycle, 30s refresh cooldown, background refresh loop: 60s interval / 5min lead) - translate — pure OpenAI↔Claude↔Gemini format conversion (no auth dependency)
- provider — executor impls per provider + model registry +
CredentialRouter(round-robin) +VersionStore(runtime-fetched UA/fingerprint strings fromassets.byokey.io/versions/{provider}.json) - proto — ConnectRPC service definitions generated from
crates/proto/proto/*.protoviaconnectrpc-build+buffa. Owns the management API schema:byokey.status.StatusService,byokey.accounts.AccountsService,byokey.amp.AmpService. Build-time dep onprotoc. Isolated from the workspaceunsafe_code = "forbid"lint because buffa's generated code usesunsafe implfor marker traits. - proxy — axum HTTP server, SSE streaming, single listener on
:8018. Serves three kinds of traffic from one port: REST AI proxy (/v1/chat/completionsetc.), amp CLI compatibility (/api/provider/*, amp redirects, ampcode.com proxy), and ConnectRPC management as the fallback service (/byokey.status.StatusService/{Method},/byokey.accounts.AccountsService/{Method},/byokey.amp.AmpService/{Method}). The amp sub-router is wrapped inforward_headers_middlewarescoped via.layer()before.merge(). - daemon — PID/process management, Unix control socket (
~/.byokey/control.sock, tarpc), OS service registration (launchd/systemd/Windows SCM); not in the DAG, only used by the CLI binary - Key constraint:
translatemust NOT depend onauth;authmust NOT depend ontranslateorprovider;typeshas zero workspace deps;protoowns only protobuf-generated types (no business logic).
unsafe_code = "forbid",clippy::pedantic = "warn", edition 2024, async traits viaasync-traitmacro (ConnectRPC handlers use plainasync fn)- HTTP client is
rquest(NOT reqwest); HTTP server isaxum 0.8; config viafigment; errors:thiserrorcross-crate (ByokError),anyhowcrate-internal - OAuth credentials fetched at runtime. (see
crates/auth/src/credentials.rs) - Don't call
unwrap_err()on Results (Box<dyn ProviderExecutor>isn'tDebug); useis_err()or pattern match - Socket activation supported:
serveadopts an inherited fd vialistenfd(systemfd/systemd/launchd) if one is passed in; otherwise binds fresh - Build-time dep on
protoc— needed bybyokey-proto's build.rs. Install viabrew install protobuf/apt-get install protobuf-compiler. - See
CLAUDE.mdfor full provider OAuth details, dependency tables, and API endpoint docs