Releases: webvictim/prism
Release list
v0.1.21
Added
prism pi [args...]now does the whole Pi setup, likeprism claudeandprism opencodedo for their tools. It starts prism if needed, supplies dummy credentials, rewrites Pi's Anthropic and OpenAI model entries for the current router port, and then launches Pi with every argument passed through. A fresh Pi install is bootstrapped withpi update --models, so there is no longer a separateprism pi config && prism exec pifirst-run ritual.prism pi configkeeps its existing setup-only meaning for scripts and narrowed model lists; useprism exec pi configfor Pi's own unrelated package-configuration screen.prism opencode, alongsideprism claudeandprism codex. OpenCode already worked throughprism exec opencode, but only on machines that had already stored an Anthropic credential: OpenCode offers a provider's models only when one of the environment variables named in its catalog is set, and prism deliberately clearsANTHROPIC_API_KEY. The new command sets it to a dummy value — the router strips it before forwarding, exactly as it already did forOPENAI_API_KEY— so the Anthropic models show up on a fresh install.prism exec opencodegets the same treatment. Note that aprovider.anthropic.options.baseURLin your own OpenCode config still wins over the environment, and would bypass prism entirely.
Fixed
- Pi's Anthropic models no longer fail with
fallbacks: Extra inputs are not permitted. Newer Pi catalogs mark refusal-fallback models, which makes Pi send Anthropic's server-sidefallbacksfield. The Bedrock-backed gateway does not support that beta, so prism now strips the field with the other unsupported top-level Messages fields. - Pi setup now honors
PI_CODING_AGENT_DIR. Bothprism piandprism pi configwrite to the same custom agent directory Pi reads, rather than always modifying~/.pi/agent. prism pi configno longer deletes unrelated custom providers. It used to rewritemodels.jsonwith only the Anthropic and OpenAI entries, so a local provider such as llama-swap disappeared and Pi printedNo models match patternfor its configured default. The command now replaces only the providers it manages and preserves the rest of the file.prism pi configis listed inprism help. It has worked since v0.1.12 but never appeared in the usage text, so the only way to find it was the README. The help text and the dispatch table are now checked against each other, in both directions, so a command can't ship unlisted and the help can't outlive a rename.
Full Changelog: v0.1.20...v0.1.21
v0.1.20
[v0.1.20] — 2026-09-10
Fixed
- Clients that omit the
/v1prefix were half-invisible and, worse, unscrubbed. Prism hands outANTHROPIC_BASE_URLwithout a/v1suffix because the official Anthropic SDKs append/v1/messagesthemselves. The Vercel AI SDK appends only/messages, and the gateway accepts both — so those requests worked while silently skipping every behaviour prism gates on the/v1prefix: path dispatch, request logging, usage accounting and Bedrock scrubbing. In practice an OpenCode session throughprism exec opencodeproxied fine, logged nothing, contributed nothing toprism usage, and sent unscrubbed bodies to a Bedrock-backed gateway — sothinking,metadataand oversized non-streamingmax_tokensreached upstream unmodified, which is exactly the class of request that comes back as an unexplained "the inference provider rejected the request" 400. Prism now canonicalises a version-less API path to its/v1spelling before anything else looks at it. Requests appear inprism logsandprism usageas/v1/..., and are scrubbed like any other. Note that scrubbing stripsthinking, so AI-SDK clients that ask for extended thinking through prism no longer get it — the same as every other client. - Anything prism proxies is now logged. The request log was gated on a
/v1allowlist, so a path prism forwarded but did not recognise left no trace at all. Only prism's own/_prism/endpoints are skipped now, so a future client with an unfamiliar path shape can't go dark. - Forward-proxy usage records named the wrong model. In
claude_forward_proxy_modethe MITM path overwrote the model with whatever the request asked for, discarding the one the gateway reported — so records logged asusage: ?and landed inprism usageunder(unknown)whenever a client omitted the field, and were attributed to the requested alias rather than the served model otherwise. The response is now the authoritative source, matching the direct path. prism logswent silent after midnight. The daemon rotates by creating a new dated log file rather than renaming the current one, so the follower sat on a handle to a file nothing was writing to any more — and once that file was gzipped, to one that no longer existed. It now notices the new file, drains the old one, and switches over, printing a==> daemon-YYYY-MM-DD.log <==marker to stderr. Linux users on systemd were unaffected, sinceprism logsshells out tojournalctl -fthere.
Changed
-
One log line per request. The request line and its token counts used to be printed separately, by two different layers — so under any concurrency they interleaved and couldn't reliably be paired. They are now a single line, which is also about half the log volume:
POST /v1/messages 200 req=747024B resp=2073B model=claude-opus-5 in=2 out=89 cache_read=18807 cache_write=209741 2.721sCache counts are new to the log — worth having, since
in=2on a 747KB request only makes sense next to them. Every field is always present, zeros included, and a model the gateway didn't name shows asmodel=?, so the line can be parsed without checking which fields it happens to carry. Requests that carry no token usage keep the plain request line. -
Response capture moved into a shared
internal/capturepackage used by both the router and the forward proxy, alongside the request-direction scrubbing they already share. The two copies had drifted, which is what let the model-attribution bug above live in one path and not the other.
v0.1.19
Added
- chat/completions → Responses translation. Newer gateways serve OpenAI models only on
/v1/responsesand reject every model on/v1/chat/completionswithmodel ... isn't supported on this route. Prism now translates those requests, streaming included, so OpenAI-compatible clients that only speak chat/completions work again — MacWhisper, Teleport session summaries, and anything else with an "OpenAI-compatible endpoint" box./v1/responsesis passed through untouched, so Codex is unaffected. openai_chat_completions_shimconfig flag. On by default.prism config set openai_chat_completions_shim falserelays/v1/chat/completionsbyte-for-byte instead, so a current prism still works against an older gateway.prism testflags:--format anthropic|openai-responses|openai-completionspicks the wire format,--modelpicks a model,--streamexercises SSE. Omitting--modelsends no model field at all, so the gateway picks its own default and prism reports which one it served.- Translated requests are visible in
prism logs:POST /v1/chat/completions [-> /v1/responses] 200 .... Errors relayed from the gateway are logged too, so a transient upstream 5xx is no longer indistinguishable from one of prism's own.
Changed
- No model names are compiled into prism. The hardcoded reasoning-model list added in v0.1.8 is gone — its prefix matching had silently stopped working once model ids gained an
openai.vendor prefix. Prism now forwards what the client sent, reads the rejected parameter's name out of the gateway's own error, drops it and retries, remembering the rejection per model for the life of the daemon. Deliberately not persisted to disk: a stale cache would keep stripping a parameter after the gateway started accepting it again. prism pi configmirrors Pi's model catalog. Pi's overrides match by model id, so it now reads Pi's own catalog and writes it back with onlybaseUrlrepointed at prism. Every model Pi knows routes through prism, and each entry keeps its cost, context-window and compat metadata.--anthropic-model/--openai-modelnarrow the rewrite to one id. Re-run afterpi updaterefreshes the catalog.
Fixed
- Usage records showed
?instead of a model whenever the client omittedmodelor the gateway aliased it — the request's model was overwriting the response's. The served model now wins. - Direct
/v1/responsestraffic recorded no usage at all: the parser only understood chat/completions'prompt_tokens, not the Responses API'sinput_tokens. Codex traffic through prism was invisible toprism usage. - Tool calling isn't translated; a request carrying
toolsnow gets a clear 400 pointing at/v1/responsesrather than a confusing gateway error.
Full Changelog: v0.1.18...v0.1.19
v0.1.18
Fixed
- Forward-proxy mode served expired leaf certificates after 24 hours or a laptop wake — the MITM cert cache had no expiry check. Certs are now re-issued on demand with a 5-minute buffer.
Full Changelog: v0.1.17...v0.1.18
v0.1.17
Added
- Forward-proxy mode now does request logging and token-usage tracking, so
prism logsandprism usagecover Remote Control traffic the same way they cover the router.
Fixed
- README corrections: Remote Control section rewritten, stale references and example hostnames fixed.
Full Changelog: v0.1.16...v0.1.17
v0.1.16
Fixed
- Headless Remote Control. The Remote Control bridge client doesn't issue
CONNECTwhenHTTPS_PROXYis set — it sends absolute-form plain-HTTP requests straight to the proxy. Prism treated those as ordinary local requests and path-dispatched them to the tunnel, where the gateway's 404 made the CLI report "Remote Control environments are not available for your account". Interactive sessions were unaffected because they useCONNECT.
Changed
- Module renamed to
github.com/webvictim/prism.
Full Changelog: v0.1.15...v0.1.16
v0.1.15
Added
- Forward-proxy mode for Claude Code Remote Control. Claude Code v2.1.196+ disables Remote Control when
ANTHROPIC_BASE_URLpoints at a non-Anthropic host. Enable withprism config set claude_forward_proxy_mode trueand prism setsHTTPS_PROXYinstead, MITM'ing onlyapi.anthropic.commodel calls and blind-tunnelling everything else (Remote Control, telemetry, MCP) with credentials intact. - Tests for usage capture and aggregation, state, and config.
Fixed
- Forward-proxy 400s from the Bedrock gateway, which rejects
cache_controlobjects carrying thescopekey that Claude Code adds when it believes it's talking directly toapi.anthropic.com. Scrubbing is now shared between the router and the MITM proxy (internal/scrub) so requests reach the gateway in an identical shape in both modes. Earlier header-stripping attempts had been chasing the wrong variable. - Panic on startup when forward-proxy mode was disabled (nil handler).
Full Changelog: v0.1.14...v0.1.15
v0.1.14
Fixed
- tbot certificates expired before renewal. Teleport caps bot certs at 12h (
DefaultBotMaxSessionTTL) but prism requested 24h with a 23h renewal interval, so the server silently capped them and every cycle forced a rejoin. Now 12h certs with an 8h renewal interval.prism statuswarns existing installs still carrying the old interval — runprism down && prism up.
Added
- Test suite for the router, log rotation, and path expansion; release builds now run tests first.
Full Changelog: v0.1.13...v0.1.14
v0.1.13
Fixed
~/intbot.dirpaths is expanded, for both--dirflags andprism config set tbot.dir.prism tbot bootstrapsetstbot.dirin config automatically.
Full Changelog: v0.1.12...v0.1.13
v0.1.12
Added
prism pi configwrites~/.pi/agent/models.jsonpointing at the local router. Pi resolves base URLs from its own registry and ignoresANTHROPIC_BASE_URL/OPENAI_BASE_URL, so it needs this file./v1/responsesis routed to the OpenAI backend.prism envexports the full set of environment variables a live beam sets.
Fixed
- 401s from the gateway. The router now strips client
AuthorizationandX-Api-Keyheaders before forwarding; the tunnel authenticates by mTLS, so the dummy tokens from those env vars were being rejected. - Daemon logs moved into
~/.config/prism/logs/to keep the config directory clean.
Full Changelog: v0.1.11...v0.1.12