Adds ~110 more words across new domains: creatures (tiger→warm horizontal stripes, zebra→vertical, peacock/jellyfish→radial, dragon/phoenix, swan/raven/wolf/whale…), food & drink (wine/honey/coffee/cherry/mango/saffron/matcha/blueberry…), gems (opal/pearl/onyx/quartz/topaz/garnet/obsidian/moonstone…), architecture (city/cathedral/temple/tower/dome/labyrinth/maze/spire…), abstract concepts (love/passion/harmony/energy/freedom/infinity/eternity/zen/echo…), cosmic/sci-fi (plasma/quasar/pulsar/supernova/blackhole/matrix/circuit/hologram/wormhole…), botanical (lotus/orchid/daisy/sunflower/poppy/tulip/lily…), seasons (autumn/spring/summer/winter/harvest/solstice…) and synesthetic music (rhythm/melody/pulse/bass/jazz/blues/resonance…). Shape-bearing words carry the right primitive — supernova/pulsar/lotus→radial, cathedral/maze/matrix→mirror, blackhole/blues→gradient. Data-only: generate.rs + architecture unchanged (wasm unchanged), and the conformance prompt still matches only calm+horizon, so the pin is UNCHANGED (4bd80c0ef51bb843) — no test churn. Verified: tiger→horizontal stripes, supernova→radial rings, cathedral→symmetry, all byte-exact. Co-Authored-By: Claude Opus 4.8 <[email protected]>
134 lines
4.9 KiB
Rust
134 lines
4.9 KiB
Rust
//! End-to-end Mesh demo: mint a JCP grant, serve a metered inference through the
|
|
//! cheapest-sufficient backend, and print the sealed JCR-1 receipt.
|
|
//!
|
|
//! Run with the always-available estimator meter (honest `Estimator`
|
|
//! provenance):
|
|
//!
|
|
//! ```text
|
|
//! cargo run -p mesh-core --example demo
|
|
//! ```
|
|
//!
|
|
//! On Linux with RAPL (or a CUDA box with NVML), enable a hardware meter to get
|
|
//! a measured `HwShunt` span instead:
|
|
//!
|
|
//! ```text
|
|
//! cargo run -p mesh-core --example demo --features hw-meter-rapl
|
|
//! ```
|
|
|
|
use ed25519_dalek::SigningKey;
|
|
use jcp_schema::{Capability, Did, Grant};
|
|
use mesh_core::{Mesh, INFER_ACTION};
|
|
use mesh_engine::ReferenceEngine;
|
|
use mesh_meter::Meter;
|
|
use mesh_router::BackendSpec;
|
|
use mesh_schema::{ContentId, Fidelity, ServeRequest};
|
|
|
|
fn main() {
|
|
// --- the steward (the mesh endpoint that seals receipts) ---
|
|
let steward_sk = SigningKey::from_bytes(&[7u8; 32]);
|
|
let steward = Did::from_verifying_key(&steward_sk.verifying_key()).to_did_key();
|
|
|
|
// --- the meter: hardware-backed when a feature selects one, else estimator ---
|
|
#[cfg(feature = "hw-meter")]
|
|
let meter = mesh_meter::HwMeter::detect();
|
|
#[cfg(not(feature = "hw-meter"))]
|
|
let meter = mesh_meter::EstimatorMeter::new(15.0);
|
|
println!("meter: {}", meter.name());
|
|
|
|
// --- build the mesh: a fidelity cascade of backends ---
|
|
let mut mesh = Mesh::new(&meter, steward_sk, steward.clone());
|
|
mesh.register(
|
|
BackendSpec::new("cache", "result-lut", Fidelity::F0, 10),
|
|
Box::new(ReferenceEngine::new("cache", "result-lut", Fidelity::F0, 10, 8)),
|
|
);
|
|
mesh.register(
|
|
BackendSpec::new("tiny", "ssm-1b", Fidelity::F1, 50_000),
|
|
Box::new(ReferenceEngine::new("tiny", "ssm-1b", Fidelity::F1, 50_000, 4096)),
|
|
);
|
|
mesh.register(
|
|
BackendSpec::new("merge", "evo-merge-8b", Fidelity::F2, 200_000),
|
|
Box::new(ReferenceEngine::new(
|
|
"merge", "evo-merge-8b", Fidelity::F2, 200_000, 8192,
|
|
)),
|
|
);
|
|
mesh.register(
|
|
BackendSpec::new("frontier", "wire-rpc", Fidelity::F4, 5_000_000),
|
|
Box::new(ReferenceEngine::new(
|
|
"frontier", "wire-rpc", Fidelity::F4, 5_000_000, 16384,
|
|
)),
|
|
);
|
|
|
|
// --- the request: 64 output tokens, must be at least F1, ≤ 8 J ---
|
|
let req = ServeRequest {
|
|
prompt_hash: ContentId::of_bytes(b"What is the capital of France?"),
|
|
prompt_tokens: 7,
|
|
max_tokens: 64,
|
|
fidelity_floor: Fidelity::F1,
|
|
joule_ceiling_uj: 8_000_000, // 8 J
|
|
};
|
|
|
|
// --- the caller mints a JCP grant: capability(infer over this request) ⊗ budget ---
|
|
let caller_sk = SigningKey::from_bytes(&[42u8; 32]);
|
|
let caller = Did::from_verifying_key(&caller_sk.verifying_key());
|
|
let grant = Grant {
|
|
issuer: caller,
|
|
subject: Did::from_verifying_key(&SigningKey::from_bytes(&[7u8; 32]).verifying_key()),
|
|
capability: Capability::new(req.id(), [INFER_ACTION]),
|
|
budget_uj: 8_000_000,
|
|
expiry: 0,
|
|
parent: None,
|
|
delegate_depth: None,
|
|
nonce: [0u8; 16],
|
|
};
|
|
let signed = jcp_grant::issue(&caller_sk, grant).expect("issue grant");
|
|
|
|
// --- serve ---
|
|
// The prompt token payload travels with the serve call (here a small fixed
|
|
// stand-in) but is never sealed into the receipt — only `prompt_hash` is.
|
|
let prompt_tokens: Vec<u32> = vec![1, 2, 3, 4, 5, 6, 7];
|
|
let resp = mesh.serve(&req, &prompt_tokens, Some(&signed)).expect("serve");
|
|
|
|
println!("\nroute: {}", resp.route.justification);
|
|
for c in &resp.route.candidates {
|
|
let mark = if Some(&c.backend) == resp.route.chosen.as_ref() {
|
|
"→"
|
|
} else if c.admissible {
|
|
" "
|
|
} else {
|
|
"✗"
|
|
};
|
|
println!(
|
|
" {mark} {:<9} {} est {} µJ{}",
|
|
c.backend.0,
|
|
c.fidelity.label(),
|
|
c.est_total_uj,
|
|
c.reason.as_ref().map(|r| format!(" ({r})")).unwrap_or_default()
|
|
);
|
|
}
|
|
|
|
println!(
|
|
"\nserved: {} tokens, fidelity_met={}, provenance={}",
|
|
resp.outcome.tokens_out,
|
|
resp.receipt.fidelity_met,
|
|
resp.energy.provenance.jcr1_label()
|
|
);
|
|
println!("energy: {} µJ ({} J)", resp.energy.uj(), resp.energy.uj() as f64 / 1e6);
|
|
match resp.uj_per_accepted_token() {
|
|
Some(jpt) => println!("WEDGE: {jpt} µJ per accepted token"),
|
|
None => println!("WEDGE: no tokens accepted"),
|
|
}
|
|
|
|
// --- the sealed JCR-1 receipt (mesh/1 profile) ---
|
|
let wire = resp.receipt.to_jcr1_wire(mesh.steward());
|
|
println!("\nreceipt (mesh/1):\n{}", serde_json::to_string_pretty(&wire).unwrap());
|
|
|
|
// --- verify the seal ---
|
|
let ok = resp
|
|
.receipt
|
|
.verify_envelope(&resp.envelope, mesh.steward(), &mesh.verifying_key())
|
|
.is_ok();
|
|
println!(
|
|
"\nsealed envelope: {} bytes, verifies under steward key: {ok}",
|
|
resp.envelope.len()
|
|
);
|
|
}
|