PR-B3 (ADR 0008 Phase B): Generate server-streaming RPC + greedy session-aware decoding - #46
Merged
FluffyAIcode merged 2 commits intoJun 1, 2026
Conversation
…ion-aware decoding
First Phase-B PR with mandatory Mac M4 integration test report
under \u00a79 (Linux CI is necessary but not sufficient).
Design choice: PR-B3 ships **greedy decoding only**. Speculative-
decoding integration (DLM proposer + AR verifier rejection sampling)
is reserved for a later PR. The wire contract is algorithm-agnostic
(GenerateResponse oneof on token_id / done / truncated), so the
upgrade path lands without breaking clients.
Three deliverables:
1. inference_engine/session/generator.py (new, ~240 lines)
- VerifierProtocol-driven GenerationCoordinator.
- Yields TokenEvent / HistoryTruncatedEvent / DoneEvent.
- Strict v0.3 validation: temperature/top_p/top_k must be in
greedy no-op defaults; max_tokens must be >= 1; session must
have prior AppendTokens. Per \u00a72.10 'no graceful degradation',
any deviation raises ValueError -> INVALID_ARGUMENT.
- HistoryTruncated emitted at most once per call, BEFORE any
TokenEvent, when the cache is in sink+window-truncated state
(matches the runtime.proto contract exactly).
- INV-1 / INV-2 enforced via SessionStore at every step.
- INV-3 byte-exact under greedy: same (session_id, history)
-> bit-identical token stream. Tested with FakeVerifier on
Linux and asserted in TestDeterminism.
2. inference_engine/server/grpc_app.py (modified, +119 lines)
- RuntimeServiceServicer.__init__ takes optional
generation_coordinator: GenerationCoordinator. None = PR-B2
UNIMPLEMENTED default preserved (regression-tested).
- Generate RPC implements server-streaming with the four typed
error mappings:
SessionNotFoundError -> NOT_FOUND
ValueError -> INVALID_ARGUMENT
InvariantViolation -> FAILED_PRECONDITION
Plus the success path streams TokenEvent -> token_id,
HistoryTruncatedEvent -> truncated, DoneEvent -> done.
- Cancellation: polls context.cancelled() between events; on
True, emits a final GenerateDone(STOP_REASON_CANCELLED) and
returns. Cancellation latency is bounded by one generation
step (the in-flight forward pass finishes before the next
poll).
- create_grpc_server factory plumbed with the new keyword.
3. tests/inference_engine/session/test_generator.py (new, 31 tests)
- TestGreedyHappyPath: 4 tests on token-then-done emission,
max_tokens cap, single Done event, total_seconds reporting.
- TestGreedyAdvancesVerifier: 4 tests confirming verifier
state mirrored onto session after every step.
- TestEos: 3 tests on EOS detection + STOP_REASON_EOS.
- TestHistoryTruncated: 3 tests on at-start emission + at-most-
once contract.
- TestValidation: 9 tests on max_tokens, sampling params, and
no-AppendTokens-prior rejection.
- TestInvariants: 2 tests on INV-1 / INV-2 propagation.
- TestDeterminism: 1 test on byte-exact greedy output across
parallel sessions.
- TestConstructorAndEventDataclasses: 4 tests on frozen dataclass
contract and constructor.
+ tests/inference_engine/server/test_grpc_app.py (extended, +11 tests)
- Generate streams tokens then done.
- EOS triggers STOP_REASON_EOS.
- HistoryTruncated frame emitted before tokens.
- Unknown session -> NOT_FOUND.
- No AppendTokens prior -> INVALID_ARGUMENT.
- max_tokens=0 -> INVALID_ARGUMENT.
- temperature=0.7 -> INVALID_ARGUMENT.
- seed accepted on the wire.
- InvariantViolation during generation -> FAILED_PRECONDITION.
- Cancellation -> STOP_REASON_CANCELLED Done frame (direct
Servicer invocation with FakeContext; cancellation latency
bounded as documented).
- Factory accepts generation_coordinator keyword.
Mac M4 reviewer aids:
scripts/smoke_grpc_generator.py
10-scenario smoke walking Generate scenarios with Append +
Generate coordinators wired against FakeVerifier.
scripts/review_pr_b3_on_mac.sh
One-shot Mac M4 reviewer producing 5 JSON artifacts:
pr-b3-mac-generator-tests-<unix>.json (31 tests, 100% on
generator.py)
pr-b3-mac-grpc-tests-<unix>.json (39 tests after PR-B3
additions, 100% on grpc_app.py)
pr-b3-mac-grpc-runtime-smoke-<unix>.json (PR-B1 regression)
pr-b3-mac-grpc-appender-smoke-<unix>.json (PR-B2 regression)
pr-b3-mac-grpc-generator-smoke-<unix>.json (PR-B3 new)
Local verification (Linux VM, py3.12):
Linux CI gate: 629 passed (was 587 + 31 generator + 11 grpc
generate). Coverage 100.00% on 1521 stmts (was
1428 + 63 generator + 30 grpc_app additions
- 0 deletions).
Per ADR 0008 \u00a79: this PR introduces a NEW MLX-reachable runtime
path (verifier.forward_block + commit_or_truncate driven by the
coordinator's per-token loop). Even though FakeVerifier covers the
Linux-side dispatch logic exhaustively, the v0.3 GA contract
requires a Mac M4 integration test report on the PR branch before
merge. The carve-out paragraph does NOT apply here. PR is opened as
Draft pending the report.
Mac M4 verification command for the PR branch:
bash scripts/review_pr_b3_on_mac.sh
The script writes 5 JSON artifacts under results/platform-tests/;
the user commits them back to this branch and the PR description is
updated to quote the smoke summary line.
Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
✅ Mac M4 §9 integration test report — landed (commit
16196be)First Phase-B PR with mandatory ADR 0008 §9 Mac M4 report; carve-out
NOT applicable. All 5 artifacts pass.
pr-b3-mac-generator-tests-1780323650.jsoninference_engine/session/generator.py(63 / 63 lines)pr-b3-mac-grpc-tests-1780323650.jsoninference_engine/server/grpc_app.py(88 / 88 lines)pr-b3-mac-grpc-runtime-smoke-1780323650.jsonpr-b3-mac-grpc-appender-smoke-1780323650.jsonpr-b3-mac-grpc-generator-smoke-1780323650.jsonGenerator smoke per-step (PR-B3 wire behavior on Apple Silicon)
CreateSessionokokAppendTokens (cold prefill)okokGenerate (max_tokens=3, no EOS)okokGenerate (EOS triggers, max_tokens=10)okokGenerate (no AppendTokens prior)INVALID_ARGUMENTINVALID_ARGUMENTGenerate (max_tokens=0)INVALID_ARGUMENTINVALID_ARGUMENTGenerate (temperature=0.7, non-greedy rejected)INVALID_ARGUMENTINVALID_ARGUMENTGenerate (unknown session)NOT_FOUNDNOT_FOUNDGenerate (truncated state → truncated frame)okokGenerate (no coordinator wired)UNIMPLEMENTEDUNIMPLEMENTED10 / 10 step times in 0.31 – 1.50 ms, similar order to Linux (0.27 – 1.55 ms) — confirms gRPC streaming behavior is platform-equivalent on Apple Silicon.
Design choice: greedy first, speculative later
PR-B3 ships greedy decoding only. Speculative-decoding integration
(DLM proposer + AR verifier rejection sampling — Kakeya's
distinguishing feature) is reserved for a later PR. Two reasons:
GenerateResponseoneof ontoken_id/done/truncatedworks for any decoding algorithm.Switching to speculative is a coordinator-internal refactor, not a
protocol break.
adding speculative would couple two large changes. Greedy is the
minimum surface that satisfies §9; speculative integration can land
independently with its own integration test pass.
temperature/top_p/top_kMUST be in their greedy no-opdefaults. Setting any non-default raises
ValueError → INVALID_ARGUMENTper §2.10 "no graceful degradation" — the runtime refuses to silently
downgrade.
Three deliverables
1.
inference_engine/session/generator.py(new, ~240 lines)TokenEvent/HistoryTruncatedEvent/DoneEventSTOP_REASON_*runtime_pb2.GenerateDone.StopReasonGenerationCoordinator(store, verifier)GenerateEventper stepPer-step contract:
2.
RuntimeServiceServicer.Generate(new)generation_coordinatorUNIMPLEMENTEDSessionNotFoundErrorNOT_FOUNDValueErrorINVALID_ARGUMENTInvariantViolationFAILED_PRECONDITIONcontext.cancelled()mid-streamGenerateDone(STOP_REASON_CANCELLED), then returntoken_id(+ optional initialtruncated), terminated bydoneHistoryTruncatedframe: emitted at most once per call, before anytoken_id, when the session is in sink+window-truncated state at
Generate's start. Matches
runtime.protocontract exactly.3. INV-3 byte-exact unit tests via
FakeVerifierTestDeterminism.test_two_runs_with_same_history_produce_same_tokensdrives two parallel sessions with identical history through Generate
and asserts byte-identical token streams under greedy decoding.
The 31-test generator suite covers every code path on
generator.py(63 / 63 lines) including:
Files
inference_engine/session/generator.py(~240 lines)tests/inference_engine/session/test_generator.py(31 tests)scripts/smoke_grpc_generator.py(10-scenario smoke)scripts/review_pr_b3_on_mac.sh(5-artifact reviewer)results/platform-tests/pr-b3-mac-*-1780323650.*(Mac M4 evidence: 5 JSON + 2 junit.xml + 2 coverage.xml)inference_engine/server/grpc_app.py(+119: Generate RPC + factory keyword + cancellation)inference_engine/session/__init__.py(re-exports)tests/inference_engine/server/test_grpc_app.py(+11 tests including direct cancellation invocation)Linux verification
Reviewer checklist
16196be), all expected counts match.INVALID_ARGUMENT. Verified Mac M4 step Engine E2: OpenAI-compatible HTTP API with SSE streaming #7.STOP_REASON_CANCELLEDDone frame.TestDeterminismpasses.forward_block+commit_or_truncate(these are NOT new — they were exercised by AppendTokens in PR-B2; Generate uses them in a per-token loop).PooledVerifier/inference_engine.memory/untouched.Next PR
PR-B4: ship
sdks/python/—kakeya.Client,kakeya.Session,100% unit-test coverage against an in-process gRPC server. First
external-facing API surface; Linux-only path.