v0.5.0
0.5.0 - 2026-09-08
Bug Fixes
- providers: Honor the optional API key for keyless custom endpoints in #423 by @njbrake (
5fa80d0) - dashboard: Accessibility and UX polish pass in #435 by @njbrake (
b153949) - dashboard: Address timeline review follow-ups from #445 in #453 by @njbrake (
75556a9) - dashboard: Distinguish a missing /models endpoint from an unreachable provider in #454 by @njbrake (
ab4d3ca) - providers: Gate provider api_base write path behind SSRF check in #444 by @njbrake (
cb5d6ec) - otlp: Price imported cache creation at the 5m rate, not 1h in #468 by @njbrake (
ad4b815) - models: Let a keyless local provider opt into discovery in #471 by @njbrake (
6872df3) - pricing: Follow genai-prices to the live v2 price feed in #466 by @HareeshBahuleyan (
3773675) - dashboard: Clear a provider's connection-test result when it changes in #467 by @njbrake (
2286e0a) - lint: Apply every enclosing layer's rules in the architecture check in #476 by @njbrake (
e4c79d1) - errors: Classify provider billing exhaustion instead of calling it a bad request in #483 by @njbrake (
fc41d02) - hybrid: Prevent pending cost calculations when fallback attempts stop in #498 by @HareeshBahuleyan (
60864af) - dashboard: Correct the routing copy for mid-plan stops and unloaded plans in #507 by @njbrake (
e7edbdf) - dashboard: Open the onboarding quickstart link in a new tab in #508 by @njbrake (
ef9312e) - dashboard: Report a failed provider query on the Overview page in #509 by @njbrake (
7b56ce7) - hybrid: Re-raise CancelledError in platform attempt walker in #511 by @njbrake (
e7d9370) - sdk-codegen: Allow non_snake_case in the generated Rust core in #515 by @njbrake (
65ada5f) - sdk-codegen: Make the gateway the source of truth for endpoint coverage in #516 by @njbrake (
af2137c) - ci: Flag regen PRs on failing checks, not just age in #518 by @njbrake (
f9c59f7) - errors: Return the provider's own message on a caller-fault rejection in #537 by @njbrake (
8b4f2b4) - billing: Record charge lines for embeddings, images, moderations, and rerank in #542 by @AmirF194 (
98cf54f) - router: Match routing-memory scores on canonical model identity in #547 by @njbrake (
f75e5b0) - routing: Fall back on every provider failure in #546 by @njbrake (
0024769) - billing: Audio charge lines, no token defaults on non-token routes in #550 by @njbrake (
1ab8a4b) - dashboard: Stop the expanded table row remounting on every poll in #558 by @njbrake (
ee2aadd) - pricing: Match genai-prices defaults for renamed instances and vendor-prefixed models in #559 by @pss-julien (
c0cff4a) - chat: Forward service_tier to the provider instead of dropping it in #561 by @pss-julien (
17c8a8d) - models: Tolerate a provider that reports no model
createdin #562 by @pss-julien (659fa79) - dashboard: Fit the share card's hero to its value and rebuild the wide layout in #566 by @njbrake (
4c7be2f) - usage: Pin offset-less usage window bounds to UTC in #570 by @njbrake (
cd58170) - web-search: Serialize extraction and return its retained heap in #571 by @njbrake (
1e5e908) - dashboard: Bound and await sign-out so it can't clobber a fresh sign-in in #573 by @champ18ion (
c106d63) - Emit Node-compatible imports in TypeScript SDK codegen in #575 by @Copilot (
9458131) - code-execution: Three wrong verdicts in the conformance check in #602 by @khaledosman (
ead01fc) - e2e: Wait for the provider form to close, not for a button to be relabeled in #612 by @njbrake (
5522263) - auth: Move the API key format check off the verify path in #665 by @njbrake (
49aeeeb) - migrations: Rejoin the two Alembic heads so upgrades run again in #673 by @khaledosman (
e798d3e) - batches: Price a batch one request at a time by @njbrake (
0b40722) - pricing: Round a batch once, and coerce every rate reader by @njbrake (
e44c432) - pricing: Chain the money migration onto the current head by @njbrake (
5c2f348) - pricing: Keep cached tokens in batch pricing, reserve the dearest rate in #683 by @njbrake (
6c4f83a) - mail: Correct three comments that describe code this PR changed by @njbrake (
dbe5cf2) - mail: Make mail readiness independent of startup validation by @njbrake (
8db9ef3) - mail: Use the right article for the role in an invitation by @njbrake (
3472d64) - mail: Sanitize the envelope addresses, and work the review findings by @njbrake (
cdea86c) - pricing: Map the override write race to 409, and agree on the canonical key in #677 by @khaledosman (
f84f3fa) - auth: Match a held address by casing, and revoke a deactivated identity's sessions in #701 by @khaledosman (
97ad75f) - dashboard: Wire the password hints to their inputs, and keep the button focusable by @khaledosman (
3d760e5) - dashboard: Clear the saved line when the password fields are retyped by @khaledosman (
b03016b) - dashboard: Let a claim correct the bootstrap the whole tab reads by @khaledosman (
f1f809e) - dashboard: Open the organization rail inside the mobile drawer by @jigjigjig (
24f970d) - dashboard: Preserve focus across navigation breakpoints in #712 by @jigjigjig (
3464a78) - deps: Cap mcp below 2.0.0, which drops streamablehttp_client in #699 by @champ18ion (
ca12db9) - dashboard: Login design improvements in #733 by @jigjigjig (
d3cd90d) - dashboard: Stop the bulk action bar sliding in from the left in #735 by @jigjigjig (
7d7eb59) - auth: Gate master-key sign-in on the operator's password, not on any in #746 by @njbrake (
2c06b78) - auth: Lock the identity row before redeeming a verify or reset token in #729 by @AmirF194 (
0dfb88d) - usage: Reserve the otari-ai: source prefix in external-usage ingest in #772 by @khaledosman (
38efb1f) - usage: Read a backfilled hosted row as usage this deployment served in #773 by @khaledosman (
cb0c62e) - guardrails: Let a mandated endpoint's failure follow its own on_unavailable setting in #764 by @njbrake (
5a9c152) - gateway: Stop purpose-hint injection from corrupting list-shaped system content in #730 by @shoemoney (
899a8d1) - tools: Address review on the sandbox image and tool-set policy by @njbrake (
6857615) - tools: Make the storable tool rule and the admission rule one rule by @njbrake (
3b705d5) - dashboard: Keep a stale tool policy the deployment is refusing by @njbrake (
1e603eb) - migrations: Re-point onto main's head after the usage-provenance migration in #766 by @njbrake (
111f62c) - dashboard: Stop the pricing alarm from pushing the shell down in #778 by @jigjigjig (
e2f8ed4) - dashboard: End the create-workspace flow inside the new workspace in #780 by @jigjigjig (
e3a5e8c) - api: Expose prompt cache keys in #777 by @HareeshBahuleyan (
1e29bbb) - mcp: Reject duplicate MCP server names before they collapse silently in #792 by @AmirF194 (
6eade83) - gateway: Address Gateway 502s on max_completion_tokens (OpenAI's current field name) in #769 by @aittalam (
e676ced) - dashboard: Repair the text-subtle contrast failure, and retune the type scale in #807 by @jigjigjig (
b37d7b7) - dashboard: Anchor the filter dropdowns under their trigger in #800 by @jigjigjig (
c070c6d) - api: Gate the deployment-wide management plane on operator authority in #821 by @njbrake (
eb900b8) - dashboard: Point hosted request snippets at the data-plane gateway in #825 by @njbrake (
8d225d0) - api: Give hosted mode a management-only posture in #824 by @njbrake (
b4ed34f) - config: Refuse a data_plane_url that already names /v1 in #828 by @njbrake (
1d7bd27) - api: Answer a HEAD probe from the mode stub routers in #831 by @khaledosman (
6ddc8f8) - dashboard: Hand an accepted invitation off to the claim form in #841 by @njbrake (
fb391e8) - dashboard: Take the sidebar's operator answer off the membership context in #852 by @khaledosman (
ae2910e) - dashboard: Report provider-key encryption on a tenant-readable contract in #851 by @khaledosman (
140292b) - dashboard: Serve the Tools pages to non-operators in #864 by @khaledosman (
b00696b) - dashboard: Withhold operator-only budget reads from the workspaces page in #862 by @khaledosman (
01b0d28) - dashboard: Land every signed-in caller on a usage overview in #863 by @khaledosman (
fec213c) - dashboard: Put the last six bare headings on the type scale in #865 by @khaledosman (
4f96eff) - dashboard: Name the person at the foot of the sidebar, not their role in #869 by @njbrake (
6f7cf23) - dashboard: Generate the PWA manifest from the build's base path in #858 by @khaledosman (
e6dd017) - tenancy: Gate the org provider-keys list on organization management in #873 by @khaledosman (
7aa952f) - dashboard: Open Model pricing to organization admins in #872 by @njbrake (
9b0760c) - dashboard: Clear the accessibility debt in the key reveal, confirms, type scale and touch targets in #890 by @khaledosman (
b40c33e) - hybrid: Map PLATFORM_HEALTH_PATH and trust only a 2xx from the platform probe in #888 by @njbrake (
61a670e) - dashboard: Decide the Overview's variant from the organization context in #894 by @khaledosman (
6c6f204) - api: Gate the deployment-wide routers on the router, not per route in #895 by @khaledosman (
d38a633) - api: Refuse to cap a gateway user at an organization's budget in #898 by @khaledosman (
60a5d8c) - db: Hand the request's connection back before the provider call in #911 by @njbrake (
925e115) - migrations: Run otari's chain only against otari's own database in #919 by @khaledosman (
5018b64) - api: Refuse a blank provider narrowing on POST /v1/scoped-budgets in #912 by @champ18ion (
4d767d1) - messages: Preserve Anthropic container field in #916 by @HareeshBahuleyan (
1ca6ac4) - usage: Scope /v1/usage/count to imported rows for the select-all affordance in #840 by @AloysJehwin (
3a8500b) - messages: Adopt any-llm container support in #938 by @HareeshBahuleyan (
70e3544) - streaming: Relax final forwarded-tool timeout in #827 by @HareeshBahuleyan (
0edd6ab) - mcp: Stop managed transport redirects in #948 by @HareeshBahuleyan (
d894843) - dashboard: Correct two sidebar defects and inline the record copy control in #956 by @jigjigjig (
4bf2a88) - files: Document binary download responses in #949 by @Ovvomii (
d5d355b)
Features
- files: Add S3-compatible object storage backend in #411 by @champ18ion (
3f4f8dc) - dashboard: Bundle the operator user guide and serve it at /#/docs in #434 by @njbrake (
8d1c1e9) - auth: Rate-limit dashboard sign-in against brute-force attempts in #437 by @champ18ion (
2657bc9) - providers: Add opt-in SSRF gate for provider api_base in #441 by @njbrake (
a660931) - web-search: Support recency filtering and publish dates in Brave adapter in #442 by @champ18ion (
09fe531) - dashboard: Make the activity histogram the time-range selector in #445 by @njbrake (
ffad6b5) - dashboard: Install the dashboard to a home screen with the Otari icon in #450 by @njbrake (
e646444) - aliases: Scope a model alias to a single user in #455 by @njbrake (
dbbfebc) - dashboard: Surface failing requests so admins see dropped traffic in #449 by @njbrake (
0b37186) - lint: Enforce gateway layer rules via check_architecture.py in #475 by @peteski22 (
f348d60) - observability: Log the remaining gateway-side rejections in #472 by @njbrake (
1a55d9f) - usage: Break spend down by session, endpoint, and provider in #469 by @njbrake (
9d1b3e6) - search: Add a billed POST /v1/search pass-through in #473 by @njbrake (
0e508d9) - usage: Record a status code on usage logs so failures can be classified in #470 by @njbrake (
86e5353) - dashboard: Browsable activity log and rebuilt usage analytics in #474 by @njbrake (
86bf391) - dashboard: Show the failure diagnostic and status code in the activity detail in #482 by @njbrake (
8c35a87) - dashboard: Make ids selectable and copyable in the tables in #485 by @njbrake (
9f436e2) - dashboard: Price a model the catalogue does not list in #490 by @njbrake (
4795754) - routing: Named routing policies with failover, budget tier-down, and enforced guardrails in #492 by @njbrake (
e4ed919) - hybrid: Forward provider-specific extra_params through resolved attempts in #496 by @tbille (
0d78ff6) - tools: Meter and bill gateway-run tool calls in #504 by @njbrake (
d71a9ce) - dashboard: Show what served a routed request in the activity log by @njbrake (
dbf6a51) - messages: Support Anthropic context compaction in #512 by @HareeshBahuleyan (
726eb63) - keys: Add per-key ignore_user_mismatch opt-out in #510 by @njbrake (
19266bd) - dashboard: Edit provider client_args from the Providers page in #520 by @njbrake (
d036f1b) - dashboard: Filter usage views on several models, users, or keys in #521 by @njbrake (
9ef21b1) - tools: Accept natural web_search tool declarations and emit native result blocks in #523 by @njbrake (
611fd62) - sdk-codegen: Queue auto-merge on the regeneration PR in #519 by @njbrake (
197fb33) - streaming: Send SSE keepalives while a provider stream is idle in #528 by @njbrake (
d6d686b) - router: Learned kNN router as a routing-policy backend in #188 by @njbrake (
8b20687) - responses: Preserve context compaction through tool loops in #513 by @HareeshBahuleyan (
1d8af00) - code-execution: Publish the wire contract and type the sandbox client in #544 by @khaledosman (
8b7e1d7) - dashboard: Show requests in flight on the activity page in #549 by @njbrake (
4600ae4) - routing: Weighted policy for load balancing across providers in #553 by @njbrake (
709c794) - dashboard: Share the usage view as an image in #555 by @njbrake (
d864e05) - otlp: Capture coding-agent behavioral events into agent_telemetry in #548 by @arthuursantos (
7bd6546) - routing: Rename policies in place, and stop them hiding candidate prices in #560 by @pss-julien (
e0db77d) - telemetry: Receive OTLP outcome metrics and read them per unit of spend in #567 by @arthuursantos (
4a95bb5) - dashboard: Stop the activity log refreshing itself in #569 by @njbrake (
f32436c) - search: Serve POST /v1/search from a SearXNG backend in #598 by @njbrake (
8eca8f5) - code-execution: Publish the OpenAPI IDL and a backend conformance check in #578 by @khaledosman (
8b9a326) - search: Manage search tools at runtime from the dashboard in #604 by @njbrake (
af26c38) - scripts: Enforce OSS/enterprise boundary in check_architecture.py in #609 by @tbille (
dfffeb3) - dashboard: Select the runtime context from a deployment bootstrap in #618 by @njbrake (
88c24ac) - dashboard: Render the sidebar from a nav registry with an entitlement gate in #619 by @njbrake (
492d156) - dashboard: Rehome the shared design foundation from the platform UI in #620 by @njbrake (
0fb1b24) - dashboard: Rebuild every page on the shared design foundation in #622 by @njbrake (
df9d01a) - dashboard: Boot a hybrid gateway into a data-plane landing page in #623 by @njbrake (
7797e83) - hybrid: Read the platform's optional caller-identity field in #615 by @tbille (
ad3efac) - reprise: Retain the resolved workspace and organization ids in #628 by @dpoulopoulos (
bfaccef) - tenancy: Land the reconciled tenancy schema on an async repository base in #624 by @njbrake (
3ef8ac8) - tenancy: Serve organizations, workspaces, and memberships in #625 by @njbrake (
9a32cc0) - tenancy: Give the tenancy model a request plane in #633 by @njbrake (
5d5ebff) - dashboard: Port the tenancy pages onto the rehomed control plane in #626 by @njbrake (
4812bcf) - tenancy: Add the nullable credential columns to
userin #667 by @njbrake (c9891ef) - dashboard: Port the nav label-override seam in #664 by @njbrake (
b4c5861) - budgets: Let a scoped budget reset on a UTC calendar boundary in #640 by @njbrake (
d37fe93) - dashboard: Bring the navigation shell onto the design in #638 by @jigjigjig (
94ed29c) - platform: Return settled cost inline in #675 by @HareeshBahuleyan (
169a1b4) - pricing: Per-organization model rate overrides in #674 by @khaledosman (
244bec5) - tenancy: Invitations for organization and workspace membership in #668 by @tbille (
dbc3c69) - dashboard: Give dashboard sessions a user identity in #681 by @njbrake (
80f4074) - tenancy: Workspace per-member budget defaults in #671 by @tbille (
4407789) - provider-keys: Add organization-scoped BYO provider keys in #670 by @tbille (
a82cd29) - mail: Make outgoing mail a transport with an honest no-transport mode by @njbrake (
51a6787) - auth: Password sign-in, and the master key retires as the dashboard login in #684 by @njbrake (
015a8ee) - dashboard: Give the dashboard password a page, and open the account menu's row by @khaledosman (
4b9fef7) - activation: Guide a new workspace to its first successful request in #705 by @khaledosman (
c2dfa30) - auth: Signup, email verification, and password reset in #708 by @tbille (
754f830) - dashboard: One budgets page, and a person is a member in #711 by @njbrake (
40e9c90) - dashboard: Give signup, verification, and password reset their pages in #726 by @njbrake (
34741ae) - budgets: Make the spend ledger exact, like the settled rows feeding it in #722 by @njbrake (
d2ba90e) - usage: Record the cached-token convention on usage_logs in #723 by @njbrake (
d80beab) - mcp: Let a workspace configure its own MCP servers in #724 by @njbrake (
a54acfe) - gateway: Give a workspace a code-execution policy over the deployment sandbox in #725 by @njbrake (
0e2634c) - budgets: Close the last two gaps in workspace budget defaults in #745 by @njbrake (
86fff80) - dashboard: Add the intra-page slot seam for the top bar's balance in #748 by @njbrake (
27c0a84) - gateway: Freeze dashboard sign-ins with a maintenance-mode switch in #749 by @njbrake (
4cb3a34) - gateway: Let a workspace configure its own web search in #744 by @njbrake (
62a25c7) - dashboard: Add a no-op telemetry seam an overlay build can replace in #754 by @njbrake (
c3a0343) - architecture: Land the ports package, composition container, and bootstrap hook in #756 by @njbrake (
150c492) - Register and sign in with passkeys in #751 by @khaledosman (
cf3de46) - guardrails: Let an organization mandate guardrails over its workspaces in #752 by @njbrake (
698be2b) - architecture: Resolve captured telemetry through a storage port in #770 by @khaledosman (
c68f3cd) - dashboard: Let a deployment point the Documentation links at its own docs site in #774 by @khaledosman (
ab25543) - usage: Add pricing-provenance columns to usage_logs in #775 by @khaledosman (
c0f1fc6) - tenancy: Create an organization, and switch the active one in #771 by @khaledosman (
c33d68c) - dashboard: Add a seam an overlay resolves entitlements through in #759 by @njbrake (
7f00911) - gateway: Price imported usage at organization rates in #761 by @njbrake (
e42afdf) - dashboard: Manage a workspace's MCP servers from Tools in #760 by @njbrake (
281353e) - gateway: Consult ModelProviderPort when no stored credential serves a candidate in #762 by @njbrake (
26dda60) - tools: Let a workspace pin its sandbox image and exposed tool set by @njbrake (
c3a2335) - Sign in with Google and GitHub, behind a real IdentityProviderPort in #765 by @njbrake (
cc693e0) - budgets: Give reservations a ledger in #767 by @njbrake (
4a2ee91) - tenancy: Scope the gateway survivals to a workspace in #784 by @khaledosman (
a10d46f) - dashboard: Give the shell a seam an overlay mounts a post-sign-in step in in #793 by @njbrake (
124565e) - tenancy: Give an operator a surface over the deployment's accounts in #798 by @njbrake (
065fe51) - dashboard: Add a trend chip for period-over-period change in #801 by @jigjigjig (
66b6537) - dashboard: Render usage deltas as trend chips in #815 by @jigjigjig (
4cd3f5c) - dashboard: Land the organization provider-keys page and a hosted surface set in #820 by @njbrake (
0dd3d6c) - dashboard: Finish the trend-chip migration on the overview page in #830 by @jigjigjig (
240b732) - api: Give a tenant an organization-scoped read of their own usage in #842 by @njbrake (
ec0d1c7) - api: Remove GET /v1/usage/summary.csv in #854 by @njbrake (
884221d) - dashboard: Give members a read-only view of the Build pages in #867 by @khaledosman (
b25554a) - dashboard: Publish the deployment's legal page addresses in #870 by @njbrake (
a40a1ca) - keys: Let members create and manage their own API keys in #866 by @khaledosman (
75bbf68) - budgets: Give an organization its own budgets and spend ceilings in #875 by @khaledosman (
aee4cca) - growth: Resolve GrowthSignalPort at signup and a member's first key in #884 by @njbrake (
aa58b5a) - web-search: Call Tavily and Brave in-process, and serve them to a data plane in #882 by @njbrake (
466284c) - dashboard: Give a member their organization's roster in #893 by @khaledosman (
feae11f) - dashboard: Add an organization-wide usage page for admins in #897 by @khaledosman (
196519b) - dashboard: Give organization admins Edit on the Build pages in #889 by @khaledosman (
ea8c750) - dashboard: Name the setup-guide step in the telemetry vocabulary in #908 by @khaledosman (
bddcc53) - budgets: Cap tokens and requests, not dollars alone in #906 by @khaledosman (
01bdd8b) - tenancy: Give the invitee a membership inbox to list, accept and decline in #914 by @khaledosman (
f2d8363) - tenancy: Email-domain auto-join, claimed and proven by DNS in #915 by @khaledosman (
10c4e6c) - api: Expose managed MCP activity in Messages streams in #795 by @HareeshBahuleyan (
9930c86) - dashboard: Redesign in #934 by @jigjigjig (
12e6770)
Other
Performance
New Contributors
- @Ovvomii made their first contribution in #949
- @jigjigjig made their first contribution in #956
- @HareeshBahuleyan made their first contribution in #948
- @AmirF194 made their first contribution in #792
- @shoemoney made their first contribution in #730
- @dpoulopoulos made their first contribution in #628
- @Copilot made their first contribution in #575
- @arthuursantos made their first contribution in #567
- @pss-julien made their first contribution in #562
Full Changelog: v0.4.0...v0.5.0