Skip to main content

Module apply

Module apply 

Source
Expand description

The ordered request-shaping pipeline, and the one statement of its order.

§The stages

#StageLives inReads
1Strip prior reasoningsuper::messagesmessages
2Coalesce for capabilitiessuper::messagesmessages
3Truncate stale historysuper::truncationmessages, payload size
4Resolve the sampling hierarchysuper::samplingtop-level keys
5Pin cache_promptsuper::samplingtop-level keys

§The order is load-bearing

1 before 2. Coalescing merges message content. Stripping afterwards would have to find and excise <think> blocks inside text that has already been concatenated with "\n\n" separators from other turns.

2 before 3. Both stages 1 and 2 only ever shrink the body, and stage 3 measures it. Truncating first would size its budget against bytes that were about to be discarded anyway, and trim history that did not need trimming.

3 before 4. Stage 3 measures the payload; stage 4 inserts up to seven sampling keys. Resolving sampling first would have truncation size its budget against keys the client never sent. The margin is small, but it is the difference between measuring the conversation and measuring our own additions to it.

4 before 5. cache_prompt is not an InferenceConfig field, so pinning it last means the resolved sampling patch can never overwrite it.

§Why the seam is &mut Value and not a typed request struct

The proxy forwards requests from arbitrary external clients — IDE extensions, gateways — which send OpenAI parameters this workspace has never heard of. Round-tripping through a typed ChatRequest would silently drop every field the struct does not model: a passthrough regression that is invisible in tests and painful in the field. Mutating a Value in place preserves them by construction. The adapter builds its body with json! and already holds a Value, so this is also the cheaper side for it.

§One pipeline, two callers, no second route

Every request path calls apply. The proxy used to run the stages by hand with its own truncation pass spliced between them, because truncation gated on the payload’s size in wire bytes and could reject the request with an axum response — neither of which fits here. Measuring the serialized Value and returning a domain error removed both obstacles, so there is now exactly one implementation of the order above and nothing to keep in sync.

Functions§

apply
Apply every request-shaping transform, in order, in place.