Skip to content

[Protocol] Host-served raw-proxy path publishes no openai.exchange.v1 terminal event — and terminal-envelope enrichment (usage, digests, serving provenance): options + a recommendation #1702

Description

@StevenMih

Companion to #1669 (the routed-to-peer gap). This is about the other uncovered branch — the raw-proxy host-served path — plus the shape of what the terminal envelope should carry. Raising it as a design read before opening PRs, so what follows is small merges rather than a design argument in a PR thread. Everything below exists and is tested on a public fork; nothing here is hypothetical.

What's covered today

#1437 landed openai.exchange.v1 terminal events for exchanges a node serves, on the typed-frontend seam and the raw-proxy plugin-served path. #1668 adds the routed-to-peer path (#1669's gap). The remaining uncovered branch is the raw-proxy host-served path (real weights, route_ingressroute_model_request): it publishes nothing. On a serving node that's most exchanges — so a lifecycle-hook plugin sees every exchange except the ones the host itself served.

What a downstream consumer needs, and why (one line each)

Field Host already computes it? Why it's useful
publish on the host-served path yes — same publish pattern as plugin-served otherwise served exchanges are invisible to a plugin
usage {prompt, completion, total} yes — RespondedWithUsage carries it the honest denominator for anything billing- or audit-shaped
request_digest, response_digest bytes are in hand at the publish site binds a record to what was asked / answered without carrying text
served_by_node_id yes — the node's own endpoint id which node served (vs. routed)
model identity (model_identity_hash, canonical_ref, revision, quantization, architecture, context_length, parameter_size, layer_count) yes — ServedModelMetadata / ServedModelIdentity "a model by a name" → a model by what was actually loaded
hardware (gpu, vram_bytes, is_soc, hostname) yes — startup hardware survey which box, as the host itself reports it

Every field is real-or-omitted (skip_serializing_if); nothing is fabricated; no prompt or completion text is ever carried — digests only.

Options

A. One PR, the whole block. Publish on the host-served path + usage + digests + a serving_provenance struct with all of the above.
For: one review, one merge, plugins work on main the next day. Against: ~300 lines touching ingress.rs and the envelope; a 13-field struct lands in one go; reviewers accept the digest construction and the hardware fields together.

B. Three PRs, each independently useful to mesh-llm.

  1. Host-served publish — the same effective/terminal pair the plugin-served path already emits, on the host-served branch. Bare envelope. feat(openai): publish Terminal events on the routing node #1668's pattern applied to the branch that forgot to publish. ~40 lines.
  2. Usage + digestsusage from the dispatch outcome; request_digest/response_digest as SHA-256 over the bytes as transmitted (no canonicalization dependency; a consumer wanting a canonical digest computes its own and labels it separately). ~80 lines.
  3. serving_provenance block — model identity + hardware from descriptors the host already holds. Optional struct, absent when nothing resolved; could be config-gated if you prefer opt-in. ~150 lines.
    For: each reviewable in minutes; 1 and 2 are useful with no plugin at all (billing, logs); 3 is the only one carrying an opinion about what to expose. Against: three review cycles.

C. Generic extension bag. extensions: Map<String, Value> on the envelope; plugins request keys via manifest.
For: you never have to bless fields. Against: an untyped map on a typed envelope; every consumer re-implements the schema; you lose the ability to say what the event means. Listed for completeness; not recommended.

Recommendation: B, in order, with one design ask

Do 1 and 2 as plain PRs now — they fix a real gap (host-served exchanges are invisible) and add facts the host already has; both are useful with no plugin at all. Hold 3 for a short exchange on exactly two questions:

  • Digest construction: raw bytes as transmitted (our recommendation — simplest, no canonicalization for mesh-llm to maintain) vs. a canonical-JSON digest. A downstream consumer can carry its own separately-labeled canonical digest, so the host choosing raw bytes costs nothing downstream and keeps mesh-llm free of an RFC 8785 dependency.
  • Hardware fields: gpu / vram_bytes / is_soc / hostname as the survey reports them, plus a per-field capture_method (this is the fix(system): report the real macOS GPU name (not the CPU brand string) #1625 resolution — provenance of the value, not a different display string). Open question: should hostname default off?

A "looks right / change X" on the shape — especially the digest and hardware questions — is worth more than any merge; it lets 1–3 land as small, uncontroversial PRs. Happy to walk through the record format any time.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions