Skip to content

SCA-365: route remaining HTTP LLM surfaces through the gateway - #12337

Merged
Git-on-my-level merged 10 commits into
BasedHardware:mainfrom
Git-on-my-level:feat/sca-365-llm-gateway-surfaces
Aug 28, 2026
Merged

SCA-365: route remaining HTTP LLM surfaces through the gateway#12337
Git-on-my-level merged 10 commits into
BasedHardware:mainfrom
Git-on-my-level:feat/sca-365-llm-gateway-surfaces

Conversation

@Git-on-my-level

@Git-on-my-level Git-on-my-level commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

When OMI_LLM_GATEWAY_FEATURE_MODE=gateway, the remaining Omi-paid HTTP LLM surfaces hop backend/llm_gateway so build_accounting_event / gateway metrics are the spend ledger.

  • File-chat completionsomi:auto:file-chat-vision (gpt-5.6-luna) and omi:auto:file-chat-documents (gpt-4.1). OpenAI Files upload/download stays direct (bytes/file_id lifecycle). BYOK OpenAI is not used on this surface because the Files namespace is company-owned.
  • Desktop Vertex PT — company-paid generateContent / streamGenerateContent / embedContent hop generated omi:auto:desktop-vertex-* lanes and omi:auto:gemini-embeddings. desktop_proxy stays the BFF. PT pin/overflow/host policy lives in VertexGeminiProvider via vertex_pt_routing.py (no second policy). Mac Gemini JSON is translated in the BFF; no Desktop Swift change. Gemini BYOK stays thin direct AI Studio.
  • Embeddings — gateway POST /v1/embeddings for OpenAI text-embedding-3-large and Vertex gemini-embedding-001 (:predict). batchEmbedContents stays on AI Studio (Vertex batch wire shape incompatible).

This branch merges open #12284 (Assistants sunset → Chat Completions) so file-chat hops the completions path, not a re-deleted Assistants stack. Do not comment on or reassign SCA-362.

Review follow-ups on top of the OMP implementation:

  • Vertex ADC token refresh stays on wall-clock (time.time); the PT probe clock is monotonic and must not be shared or tokens never expire-refresh.
  • File-chat gateway hops send X-Omi-User-Uid so ledger rows are attributed.
  • Desktop Gemini tool-loop reuses the assistant tool_call_id instead of minting a new ordinal.

Leftover exceptions (intentional)

  • Omni realtime WS (omni_relay.py) remains blocked-when-gateway-on.
  • Gemini BYOK stays thin direct AI Studio (gateway Vertex fail-closes BYOK).
  • OMI_LLM_GATEWAY_FEATURE_MODE=off keeps every legacy direct path (kill switch).
  • No public Vertex/Gemini :generateContent routes on the gateway.

Test plan

  • pytest tests/unit/test_chat_file_gateway_surface.py tests/unit/test_desktop_gemini_gateway.py tests/unit/test_llm_gateway_vertex_provider.py tests/unit/test_embeddings_gateway.py tests/unit/test_llm_gateway_embeddings_route.py tests/unit/test_llm_gateway_coverage_guardrails.py tests/unit/test_desktop_proxy.py — 162 passed
  • pytest tests/unit/test_chat_file_completions.py tests/unit/test_vertex_pt_routing.py tests/unit/test_llm_gateway_validator.py — 84 passed
  • scripts/pr-preflight --suggest then OMI_PR_BODY_FILE=… make preflight

Could not exercise live Vertex/OpenAI hops from this host (no production credentials / no traffic shift).

Closes SCA-365

Product invariants affected

none

Failure class (fixes)

Failure-Class: none

Review in cubic

Git-on-my-level and others added 10 commits August 28, 2026 00:53
OpenAI retired Assistants on 2026-08-26, so every /v1/threads create 404s
and non-vision file chat is down. Stream PDFs as Chat Completions file
parts on gpt-4.1 (documented file-input contract) and keep images on the
verified gpt-5.6-luna vision lane.

Failure-Class: FC-pinned-vendor-request-contract-retired
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
Unpacking a token-budget dict into create() is untyped and fails pyright.

Failure-Class: FC-pinned-vendor-request-contract-retired
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
CI ran each unit file in its own process; incomplete BYOK/LLM stubs and a
duration-guard race on desktop transcribe failed the backend suite.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
Upstream 7c900a9 moved the Soniox client into utils.stt.soniox but left
SafeSonioxSocket / process_audio_soniox imported in streaming.py without a
re-export marker; receiver.py and test_soniox_streaming.py import them through
utils.stt.streaming, so strict pyright fails main and every PR merge ref.

Carry the one-line marker so this backend CI lane can go green; matches the
existing SafeDeepgramSocket compat re-export convention on the previous line.

Co-authored-by: multica-agent <github@multica.ai>
…-365-llm-gateway-surfaces

# Conflicts:
#	backend/tests/unit/test_byok_security.py
#	backend/tests/unit/test_chat_file_upload_unsupported.py
#	backend/tests/unit/test_chat_quota.py
#	backend/tests/unit/test_desktop_transcribe.py
#	backend/tests/unit/test_paywall_reconnect_gate.py
#	backend/utils/stt/streaming.py
File-chat completions, company-paid desktop Vertex traffic (text + single
embed), and both embedding surfaces now hop backend/llm_gateway so
accounting (build_accounting_event / gateway metrics) is the single
spend ledger when OMI_LLM_GATEWAY_FEATURE_MODE=gateway:

- gateway: OpenAI-shaped /v1/embeddings surface (omi:auto:openai-embeddings,
  omi:auto:gemini-embeddings) with accounting; desktop-vertex-* chat lanes
  generated from vertex_pt_routing; VertexGeminiProvider owns the PT policy
  (pin, promotion latch, overflow ladder, reachability, capacity header,
  regional vs multi-region host split) and gains tools/toolConfig translation
  plus :predict embeddings; validator accepts file parts, json_object, and
  the extra_body-style google options field.
- backend: chat_file streams/sync completions through the file-chat lanes
  (OpenAI Files upload/download stays direct by design); the OpenAI
  embeddings proxy and gemini_embed_query hop the gateway lanes with BYOK
  kept on documented thin direct paths; desktop_proxy stays the BFF
  (auth/metering/limits) and translates Gemini JSON via
  utils/llm/desktop_gemini_gateway.py, keeping BYOK and batchEmbedContents
  direct.
- FEATURE_MODE=off keeps every legacy direct path (kill switch unchanged);
  inventory + guardrails updated; omni WS stays blocked.
…ut of the ratcheted files

providers.py and desktop_proxy.py grew past the product line-count ratchet;
the vertex adapter's pure wire translation (vertex_wire.py), the PT policy
mixin (vertex_pt_policy.py), shared provider types (provider_types.py), and
the desktop BFF's gateway hop + Gemini body sanitization
(utils/llm/desktop_gemini_gateway.py) move into focused modules with the
original call sites and test seams preserved via re-exports.
…ile-chat spend

The gateway Vertex provider was sharing the PT monotonic clock with ADC
token expiry, so tokens never refreshed after the first fetch. File-chat
hops also omitted the user uid, leaving ledger rows unattributed, and the
desktop tool-loop minted a new tool_call_id after the ordinal advanced.

Failure-Class: none
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
…t stubs

Direct-path aembed_query/aembed_documents now notify and fall back to the
Omi key on BYOK 401 like the sync methods. Hermetic app-integration
harnesses stub utils.llm.temporal so collection survives the main merge
that imports current_date_for_uid.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
Live probe confirmed Luna accepts the Chat Completions file-part
contract, so the documents lane leaves gpt-4.1. Keep the separate
file-chat-documents lane because the request shape still differs.

Failure-Class: none
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
@Git-on-my-level
Git-on-my-level merged commit fe3df5a into BasedHardware:main Aug 28, 2026
31 checks passed
Git-on-my-level added a commit that referenced this pull request Aug 28, 2026
…12374)

## What

The Auto Deploy Desktop Backend to Development promotion gate
fail-closed on every candidate since #12337: the probe's
`REAL_GEMINI_PROVIDER_ROUTES` did not admit the `llm_gateway` provider
route the desktop proxy now stamps on `X-Omi-Provider` for company-paid
Gemini traffic (run
[33219770852](https://github.com/BasedHardware/omi/actions/runs/33219770852),
step "Prove candidate chat compatibility", `gemini_proxy: response did
not come from an admitted provider route`). Dev stayed 100% on the stale
revision `desktop-backend-cdca0c865fd1-33169706190-1`; the candidate was
correctly held tag-only.

This PR admits the real post-gateway route in the probe allowlist. No
backend behavior changes.

## Why this is a real route, not a weakened gate

The probed surface is `POST
/v1/proxy/gemini/models/gemini-2.5-flash:generateContent`. Post-#12337,
that request hops the gateway:

- `backend/routers/desktop_proxy.py` → `company_paid_via_gateway` →
`proxy_company_paid_via_gateway` stamps `telemetry.provider =
'llm_gateway'` → `X-Omi-Provider: llm_gateway`
(`backend/utils/llm/desktop_gemini_gateway.py:595`).
- `gemini-2.5-flash` maps to lane `omi:auto:desktop-vertex-flash`
(`utils/llm/vertex_pt_routing.py` DESKTOP_TEXT_LANES), whose route pins
primary provider `gemini` = `VertexGeminiProvider` with **no fallbacks**
(`backend/llm_gateway/gateway/config_loader.py:330`) — real
Gemini-on-Vertex.
- `offline_stub`, `desktop_llm_stub`, unknown, and empty header values
remain rejected fail-closed; the existing offline-stub rejection test is
unchanged.

## Test plan

- `python3 .github/scripts/test_desktop_backend_candidate_probe.py` — 19
tests OK locally, including:
- updated `test_gemini_probe_rejects_stub_or_unknown_provider_routes`:
rejects `offline_stub` / `desktop_llm_stub` / `unknown` / `""`, admits
`vertex_ai` / `ai_studio` / `ai_studio_byok`;
- new `test_gemini_probe_admits_post_gateway_llm_gateway_route`: a
gateway-served response (`x-omi-provider: llm_gateway`) passes
`_gemini_request` end to end and reports `provider_route: llm_gateway` —
the exact live failure mode, now pinned as passing.
- After merge: Auto Deploy Desktop Backend to Development must build,
probe, and shift 100% dev traffic to the merge-SHA revision; `gcloud run
services describe desktop-backend --project=based-hardware-dev
--region=us-central1` is the independent serving proof (tracked on
SCA-368).

## Product invariants

none (per `scripts/pr-preflight --suggest`)

## Failure-Class

Failure-Class: FC-client-model-outside-proxy-allowlist

#12337 retargeted the desktop proxy at a new provider route without
widening the gate that admits it in the same change, so the promotion
gate rejected a value it did not know instead of degrading. This PR
widens the admission set in data and pins both directions (real route
admitted, stub class still rejected) in the probe's test file.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/BasedHardware/omi/pull/12374?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
pull Bot pushed a commit to codingwatching/omi that referenced this pull request Aug 29, 2026
BasedHardware#12337 routed company-paid desktop Gemini traffic through the LLM
gateway; since then the desktop proxy stamps X-Omi-Provider:
llm_gateway (backend/utils/llm/desktop_gemini_gateway.py), a value the
Auto Deploy candidate probe's REAL_GEMINI_PROVIDER_ROUTES did not
admit, so "Prove candidate chat compatibility" fail-closed on every
promotion (run 33219770852) and dev desktop-backend stayed on the
stale revision.

Admit llm_gateway: the probed surface (gemini-2.5-flash
generateContent) maps to the gateway's desktop-vertex-flash lane,
whose primary provider is VertexGeminiProvider with no fallbacks
(config_loader.py), so the hop is real Gemini-on-Vertex. Stubs,
unknown, and empty routes stay rejected fail-closed; the offline-stub
rejection test is unchanged and a new test pins the post-gateway
route as admitted end to end through _gemini_request.

Verification: python3 .github/scripts/test_desktop_backend_candidate_probe.py
19 tests OK (incl. test_gemini_probe_admits_post_gateway_llm_gateway_route).

Failure-Class: FC-client-model-outside-proxy-allowlist
Co-authored-by: multica-agent <github@multica.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant