open-standards/mesh/mesh-rs/crates/mesh-openai/Cargo.toml
Transaction Science ec2b3841ee
All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 12s
standards workspaces build + test / macOS energy backends (pull_request) Has been skipped
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m11s
standards workspaces build + test / mesh-rs (mesh/mesh-rs, -p mesh-engine-gguf -p mesh-openai --features mesh-engine-gguf/gguf,mesh-openai/server, mesh-rs, linux-arm64) (pull_request) Successful in 59s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 1m13s
mesh: a grant rides over the OpenAI-compatible HTTP binding, and a receipt can be shown back as a witness
The grant work (#294, #301, #306) was reachable only through the library.
The reference HTTP server passed no grant to every request, had no way to
learn which steward a grant must name, and no way to witness a receipt
against the journal. Its binaries kept the journal in memory. It also read
whatever request body length a client declared.

- **Grants over HTTP.** A request's body carries its presentation in
  `jcp_presentation` (`presentation_in`). The presentation is signed for a
  request id, so a granted request is served as exactly the `ServeRequest`
  the body alone determines (`granted_serve_request`, plus a
  `_responses` variant). Its prompt-token figure stays the body's estimate
  rather than the server's tokenizer count, which a caller cannot
  reproduce. The body must name its own `metadata.joule_ceiling_uj`,
  since a server default would otherwise enter the id unseen.
- **Endpoints.** `GET /v1/mesh/steward` returns the steward's did:key,
  the subject a grant must name. `POST /v1/mesh/witness`, with the
  `receipt` and `envelope_hex` a response carried, answers 200 when the
  journal holds the receipt and 409 when it does not.
  `Mesh::witness_wire` checks a receipt in that wire form: the envelope
  must verify under this steward and seal exactly that wire receipt.
- **Statuses** (`http_status`): 401 when the caller is not the grant's
  issuer, 403 when the steward refuses the grant, 503 once it has stopped
  honouring grants, 500 for an unwritable journal, 400 otherwise.
- **Journal in the binaries.** With `MESH_JOURNAL` set, the reference
  server example and serve_openai_falcon record to that file and replay
  it before serving, reporting any unresolved serve.
- **Body cap.** A body declared over 4 MiB is refused (413) before it is
  read.
- **Spec.** Mesh SPEC §2.3 describes the binding (informative).

Checked on the build host:
- mesh-rs: 81 tests pass. mesh-openai with the server feature passes 15,
  including an end-to-end socket test: learn the steward, grant to it,
  present over HTTP, witness the receipt, refuse a tampered one, refuse
  an oversize body.
- The gguf and openai server features build, every Cargo.lock is
  current, and clippy is clean.
- Mutations each fail tests: a server that drops the grant, a granted
  path that recounts tokens, a wire witness that skips the seal check,
  and no body cap.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 02:20:35 -04:00

60 lines
2.6 KiB
TOML

[package]
name = "mesh-openai"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
description = "OpenAI-compatible API ingest for Mesh — translate a /v1/chat/completions request into a Mesh ServeRequest (joule ceiling + fidelity floor) and a served result back into an OpenAI chat-completion response carrying the sealed energy receipt as a usage extension. Lets any OpenAI client (vLLM/TGI/Ollama/SDKs) drive energy-metered serving without changing transport. Ingest, not compete."
[dependencies]
mesh-schema = { workspace = true }
mesh-core = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
hex = { workspace = true }
# Only to choose the reference server example's meter (the features below):
# the library itself never meters, it carries what `mesh-core` sealed.
mesh-meter = { workspace = true, optional = true }
# The GPU load for `ProcessMeter`'s liveness probe, with the `metal` feature.
jouleclaw-backend-apple = { workspace = true, optional = true }
[dev-dependencies]
mesh-engine = { workspace = true }
mesh-meter = { workspace = true }
jcp-schema = { workspace = true }
jcp-grant = { workspace = true }
mesh-router = { workspace = true }
mesh-receipt = { workspace = true }
ed25519-dalek = { workspace = true }
[features]
default = []
# A minimal, std-only /v1/chat/completions reference server (no async runtime,
# no extra deps). Routes through mesh-core and returns the sealed receipt.
server = []
# The meter the reference server example serves with (its module docs). With
# none of these it is the load estimator, and every receipt says `Estimator`.
# `hw-meter`: the family's machine meter (`HwMeter::detect`), a hardware
# reading only where a live counter covers the whole request (a RAPL package).
hw-meter = ["dep:mesh-meter", "mesh-meter/hw-meter"]
hw-meter-rapl = ["hw-meter", "mesh-meter/hw-meter-rapl"]
hw-meter-nvml = ["hw-meter", "mesh-meter/hw-meter-nvml"]
hw-meter-apple = ["hw-meter", "mesh-meter/hw-meter-apple"]
# macOS: this process's own CPU and GPU energy over each serve
# (`ProcessMeter`), since the reference engine runs in this process.
metal = ["hw-meter-apple", "dep:jouleclaw-backend-apple"]
# The reference server example uses the `server` module, so it only builds with
# the feature on (keeps the default `--all-targets` build clean).
[[example]]
name = "serve"
required-features = ["server"]
# Drives the example's own meter and mesh through one served request.
[[test]]
name = "serve_example"
required-features = ["server"]
[lints]
workspace = true