Repository navigation
feat(live): wire LeChef proposals and bounded session privacy into the live gateway - #161
Conversation
…e live gateway The live WebSocket gateway now runs the LeChef tool surface: the four legacy read tools plus the 15 registered LeChef tools (six reads, nine proposal tools), with mutate_inventory removed — the backend never writes to the phone's truth; it proposes and the phone executes. - per-connection LeChefRuntime + LivePhoneExecutor: reads answer from the phone's once-per-session bounded snapshot; proposals route over the socket and the tool call stays open until the phone's receipt resolves it (executed/rejected/expired), never a claimed success - protocol: session ids minted server-side (client-supplied ids are logged and ignored); client tool_response frames are rejected; proposal receipts resolve pending calls at most once - privacy: camera frames live in an in-process TTL+LRU cache and only their metadata reaches the store; no transcript is persisted; client-supplied latestConfidence is dropped (the exact-mode gate is server-computed); confirmed ingredient lines are trimmed to 50 and coarse grams; sessions are deleted on close and TTL-swept - system prompt rewritten for LeChef (confidence policy, proposal rules, no safety verdicts from camera looks) Verified: bunx tsc --noEmit clean; bun test src/__tests__ 321 pass / 0 fail (new liveSessionGateway.test.ts covers session-id minting, client-authority stripping, metadata-only frame storage, snapshot trimming, and the proposal->receipt round trip); LeChef suite 65/65 job successes, 0 unsafe answers, 0 unauthorized actions. Co-authored-by: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
|
Important Review skippedThis PR was authored by a bot without an assigned CodeRabbit review seat. Ask an organization administrator to assign a seat to the bot. See the seat-assignment guide. After the seat is assigned, request a review again. ⚙️ Run configuration
You can disable this status message by setting the
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
|
Independent review (Obvious, Autobuild + Max) Verdict: ready (as a draft) — the PR does what its body claims, every runnable claim reproduced exactly, and the new tests demonstrably bite. No blocking defect found. One decision worth making before merge is finding 1. Findings (ranked by severity)1. Medium —
2. Low —
3. Low — a pending proposal tool call can block for up to 300 s.
4. Low — the once-per-session bounded snapshot is silently dropped if it arrives before the Gemini session opens.
5. Low — frame bytes moved into process memory with no per-frame size bound.
What I verified (commands and results)All on PR head
What I could not verify
Scope is right: nine files, all in the live-wiring slice the body names ( 🔗 Obvious Project · 🧵 Obvious Thread · 🔀 Obvious PR Artifact |
What changed and why
Wires the LeChef tool layer into the Gemini Live session, per the live-wiring slice of
docs/spec/lechef/SPEC.md(§8.3, §9, §15).Tool surface. The live gateway now binds the four legacy read tools plus the 15 registered LeChef tools (six reads, nine
propose*tools).mutate_inventoryis gone: the backend never writes to the phone's truth — it proposes, the phone approves and executes, and the receipt is what the model sees. The system prompt is rewritten accordingly (confidence policy, proposal rules, meal-log always explicit, camera looks can never yield a safety verdict).Proposal routing. Each connection gets its own
LivePhoneExecutor(the phone mirror) andLeChefRuntime. Reads answer from the phone's once-per-session bounded snapshot; proposals are routed to the phone over the socket and the tool call stays open until the phone's receipt resolves it (executed/rejected/expired) — the model can never claim an execution the phone did not confirm. Receipts resolve at most once; an unknown-proposal receipt is a no-op.Session privacy (SPEC §9).
latestConfidenceis rejected — the exact-mode gate is computed server-side only.confirmedIngredientsare trimmed to 50 lines with grams coarsened to 10 g.tool_responseframes are rejected at the protocol layer.How I checked it
bunx tsc --noEmit -p tsconfig.json— clean.bun test src/__tests__— 321 pass / 0 fail (was 318; stalemutate_inventoryand 5-tool-count expectations updated to the new surface).src/__tests__/liveSessionGateway.test.ts(6 end-to-end tests over a real WebSocket with a fake Live session): server-side session-id minting, client-authority stripping, metadata-only frame storage + delete-on-close, snapshot trimming/confidence rejection, and the full proposal → receipt → resolved-tool-response round trip. All pass.bun src/run/lechef-suite.ts— 65/65 job successes, 0 unsafe answers, 0 unauthorized actions.What I could not check
ai.live.connect, so real model sessions (audio modality, interruptibility, real tool-call shapes) are unverified.Assumptions
session_contextingredient lines are trimmed (name + coarse grams) rather than rejected outright — the store keeps a hint, not a measurement.obv/burst5-fridgeluck-lechef-tools(the tools packet), continuing that slice.🤖 Generated with Obvious