Repository navigation
Conversation
|
Thank you, @akol1, for preserving admission's HTTP 503 across Chat Completions, Messages and Responses. At a801b9a, the common error mapping is right. One status case remains: Please include closing in the health snapshot and connect the intended backend's nonblocking readiness flag. We can fold these small changes in at landing, keeping the released health identity, memory and authenticated status-only behavior. We'd add route-level health tests with keys on/off, streaming and nonstreaming 503 cases for all three protocols, and rerun the frozen server corpus with its documented differences. This can join the next server-fix batch once those checks pass. Posted by Ash's AI Assistant Synthena |
cwschroeder
left a comment
There was a problem hiding this comment.
Requesting changes on 91f9f4bf: the streamed admission and legacy closing cases still disagree with the new health/503 contract.
- With
stream:true,openai.zigopens output beforechat.generatecalls engine submit. Expanding your admission matrix gives six failures: Closed/Busy across Chat Completions, Messages and Responses each haveopened=true, no whole-reply status, and three events. All six nonstreamed cases return 503. These probes run the request translators and shared handler with recorded output callbacks. Please keep capacity refusal before opening SSE; preserve the separate context-window streaming policy. - The legacy Flash Next host's real
engine.drain()leaves status healthy even though the next submit returns Closed and its queue is empty. ItsstatusFninheritshealthy=true. The diagnostic fails without GPU/model access. Adding.healthy = !h.closingunder its existing status mutex makes the native-only control pass: 43/43 steps, 26 tests passed, one skipped. - The only
host.healthassignment remains inlane_host_health_test.zig. The intended production backend's nonblocking readiness flag requested above still needs wiring.
I also added the missing unavailable-health socket matrix. All four keys-enabled/disabled and valid/missing-authorization cases return the exact minimal 503 body.
The diagnostic tests, one-line closing fix and observed output pin this head. Zig 0.17.0, M5 Max, macOS 26.6.2. The full diagnostic build reports three failed test executions for the two distinct regressions, since the server suite runs through two roots. Current CI is green with its narrower coverage. No device qualification is claimed.
|
Thank you for the concrete regressions. I reproduced both failures before the fixes and preserved your diagnostic tests and native closing fix as separate commits with your authorship. Updated head:
Validation on macOS 26.6.2 arm64 with Zig 0.17.0:
The new regressions are CPU-only. The standard macOS host workflow also exercises its existing Metal tests; no full-model or CUDA device qualification is claimed. |
There was a problem hiding this comment.
At 8f874288, the three earlier source findings are addressed, but one context-stream regression remains after Cortheon research. I have an applicable small patch and actual regression at 393e5c7d, composed on current main 6ee828c2 with your branch merged unchanged.
The scripted engine admits the planner and completes a web search at context windows 2000/2400 with max_tokens:1. When research enlarges the final prompt beyond that window, the new unopened catch returns HTTP 400 with no SSE events. Initial context refusals still use the streamed error policy. The regression fails before the fix and passes afterward in Debug and Fast. Only Refused + context_length needs streamedContext before unsent; capacity errors retain HTTP 503.
Independent current-head checks pass: CPU server 377/377, CUDA-host 647/649 (two skips), native host 26/27 (one skip). Restoring the old streaming implementation reproduces the six admission failures; removing only the closing-health assignment reproduces the drain failure. With the offered fix, the CPU server passes 378/378. Whole-tree format, whitespace and lean (517/517, zero new) pass; Astra reviewed the bounded fix with no further finding. Your four current-head CI checks are separately green.
Complete candidate CI is green at 393e5c7d: the Linux No GPU workflow ran zig build test, test-kernel-contract, test-golden, fuzz-cortheon and lean (517/517, zero new). Whole-tree format and both app/mobile workflows also pass. The draft validation PR isolates these two files on f622d935; it is an adoption aid for this PR.
The first PR desktop run failed in the unchanged guest.test.ts output-limit case with Operation not permitted; its failed-job rerun passed without source changes. The same commit’s push desktop run and the unchanged composition base’s app workflow had passed already. Thirty focused base probes did not reproduce that error, so its cause remains undiagnosed.
Scope correction to the older linked diagnostic: its full macOS zig build test command includes existing Metal device tests. Only the individual probes are CPU-only. The README now says so. This current recheck used the selected host targets above, with no model, CUDA/Metal device workload or deployment.
| const sink: chat.Sink = .{ .ctx = &sink_state, .call = StreamSink.call }; | ||
| const sink: chat.Sink = .{ .ctx = &sink_state, .call = StreamSink.call, .begin = StreamSink.begin }; | ||
| var reply = (if (r.turn) |t| cortheon.loop.stream(t, r.srv, &cx, &r.plan.input, prepared, sink, gone) else chat.generate(r.srv, &cx, prepared, sink, gone)) catch |e| { | ||
| if (!sink_state.opened) return r.unsent(&cx, e, field); |
There was a problem hiding this comment.
[P2] Preserve the streamed context refusal after research
The unopened catch sends every failure to unsent. Research can enlarge the final prompt after the initial prepare: with the existing scripted Cortheon Rig at a 2000/2400 window and max_tokens 1, the planner and search complete, but final prepare produces context_length and the request becomes HTTP 400 instead of the documented context_length_exceeded stream. The attached actual regression fails here. Before unsent, route only Refused + context_length through streamedContext; keep Closed/Busy on the HTTP 503 path.
|
@ashhart — closing the two items from your 2026-10-16 comment, plus the review question about HTTP 503 versus a streamed refusal. Health reports the intended backend, not just the lane. A drained Flash Next host now reports unhealthy ( The rule for 503 versus a streamed refusal is admission. Closed and busy admission are refused before any stream opens, so Chat Completions, Messages and Responses return HTTP 503 for both states, streaming or not; the preflight test runs both reasons across all three routes and both body kinds, and requires 503, no opened sink and a zero Authorship. Receipts at the head. Not covered. No CUDA, Linux or |
…h reports a closing or unready engine as unavailable
|
Thank you, @akol1, for exercising admission and health through the actual server boundaries. We merged your work for 1.1.0 in 56cce23. Requests are admitted before a streaming response opens, cancellation cleanup is installed first, and closing hosts report unavailable. The native CUDA host forwards a family's optional readiness callback. The current health/auth/memory schema stays in place; each family still owns connecting its fatal state to readiness. Posted by Ash's AI Assistant Synthena |
3bb0b75 to
bf75629
Compare
|
Rebased onto That is all of #912 the 1.1.0 merge did not take. At the new head: |
|
|
|
Thanks @akol1 for isolating the unlanded change, and @cwschroeder for the fix and regression. The late research context-window refusal now follows the existing streamed error path; other unopened failures keep their HTTP status. This is a source-ready 1.1.2 candidate, and the PR stays open until it lands. Its merge must preserve the current pre-token keepalives. Please rerun the server/preflight and translated-protocol golden checks on that merged source, including streaming and nonstreaming refusals, cancellation and preparing-count cleanup. The reported Mac host result is useful; no new GPU or model qualification is needed for this routing-only change. Posted by Ash's AI Assistant Synthena |
A streamed research turn can start, prepare a compressed context and then refuse at the final context-window check before the response sink opens. The run's catch block treated every unopened failure as a whole-reply error, so that refusal came back as a JSON status even though the request was a stream and the same refusal on the opened path is streamed. Route error.Refused with a context-window depth through the streamed context error when the sink has not opened. Every other unopened failure keeps the existing whole-reply path. The regression drives both research windows that prepare a compressed prompt against the stub engine: the search runs, the response opens, no whole-reply status or body follows, the stream carries context_length_exceeded, and the preparing count drains to zero. With the openai.zig hunk removed the test fails at cortheon_test.zig:369 on `try std.testing.expect(got.opened)`, so it covers the failure it corrects.
bf75629 to
8009df4
Compare
Post-rebase gates on
|
…d health reports a closing or unready engine as unavailable
Carry #912 with the existing live cancellation and pre-token keepalives. Retain the two-window stub-engine regression and preparing-count ownership. Source-only proposed increment; final CPU/device gates remain owed. Co-authored-by: Christian Schröder <1188270+cwschroeder@users.noreply.github.com> Co-authored-by: akol1 <15747200+akol1@users.noreply.github.com>
|
The remaining streaming research fix is included in 1.1.2 (https://github.com/ashhart/TensorFold/releases/tag/v1.1.2): late context-length refusals stay on the response stream, including while waiting for the first token. The earlier health reporting and HTTP 503 admission behavior remain in place. Closing this as carried, with both contributors credited as coauthors. Thank you both. It landed as 27dc69b. - Synthema, Ash's AI Assistant. |
What this changes
One invariant, one change: a research-context refusal that arrives after a stream has been admitted stays a streamed error event, instead of being answered as a whole reply because the sink had not opened yet. On an unopened sink,
error.Refusedfor a context-window overrun now goes throughr.streamedContext; every other error still goes throughr.unsent.The branch is rebased onto
d1018b318and carries only8009df42a(author Christian Schröder). The only delta from the reviewedbf756299cis adopting main's pre-token keepalive sink:live.out,live.every_nsand theliveargument tocortheon.loop.streamandchat.generateare preserved, and the guard plus the regression are unchanged (git range-diff 76aafcf27..bf756299c d1018b318..8009df42a).Receipt
.zig-version,-Dcpu=apple_m1, macOS 26.6.2 on an Apple M3 Ultra (80-core GPU, 512 GB). Based1018b318, head8009df42a. No checkpoint, weights, GPU kernel or inference path is involved; the regression and the goldens drive the server's stub engine.zig build test test-golden- 356/356 steps, 4924/4945 tests passed (21 skipped). The server module alone is 507/507.zig fmt --check zigandgit diff --checkclean.python3 tools/zig/lean_check.py- 3339 files, 444 findings at bothd1018b318and8009df42a, the identical set (0 added).zig/tests/server/golden/cases.json-306/319 equal to server goldens, 0 unexpected differences, with 13 declaredKNOWN-DIFFERcases, the same set as at base. Native HTTP security goldens -26/26 equal to server goldens, 0 unexpected differences.errors/stream-context.json(200 + SSE begin +context_length_exceededevent); nonstreaming viaerrors/context-prompt.jsonanderrors/context-reply.json(400 JSON, unchanged path). Cancellation viacancel/client-leaves.jsonandcancel/metrics-after.json, plus the research cancellation tests; the preparing count returns to zero.test "research expansion keeps a context-window refusal streamed"drives 2000 and 2400 reply-token windows. With only the guard hunk reverted in the same tree,zig build testfails exactly atcortheon_test.zig:369ontry std.testing.expect(got.opened); with the guard the module is 507/507.dist(no CUDA host here); any GPU kernel or whole-model/checkpoint qualification (no kernel or model-path change).Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. Not applicable: no model, lane, cache or draft logic changed, and the suite runs unchanged.-Dcpu=apple_m1) and what I could not run (CUDA, Linux,dist).