Inference.
- STATUS
- Testnet
- CRATE
- tenzro-model
- STABILITY
- Stable
- TYPE
- Component
Strategies
price cheapest provider
latency fastest provider
reputation highest-reputation provider
weighted blended score (price + latency + reputation)Intent routing
The strategies above select a provider once the model is known. Intent routing is the tier above: the caller states a use-case, a budget, a quality floor, and where to sit on the cost-quality axis, and the network selects the model — no model id required. Model selection then hands off to provider selection unchanged.
use_case chat | code | reasoning | research | summarize | extract | embed
budget per-request cost cap, in wei (pre-filters candidates)
optimize 0.0 cheapest ... 1.0 strongest, continuous
quality_floor cheap | strong (refuses to route below the floor)
payer_did DID whose rolling-window spend cap is enforced
payer_address wallet whose on-chain balance is the hard ceilingThe research use-case biases toward the strong tier for open-ended synthesis. Three budget scopes apply independently: budget bounds the single call at discovery time; payer_did bounds the DID's aggregate spend over its policy window at admission; and payer_address checks the selected model's estimated cost against the payer's on-chain wallet balance, rejecting an unaffordable request at discovery time — before any provider is dialed or any spend recorded. tenzro_routeIntent returns the selection without running inference — a model_id, its tier, an estimated_cost, an ordered fallback_chain, a reason, and the winning provider address and endpoint when the offer came from another operator. tenzro_chatByIntent resolves the same way and dispatches the prompt in one call, pinned to the offer that was scored — the price quoted is the price settled, and the provider share goes to the address that offer named.
Selection also accounts for how hard the request is. When the node has an embedding model loaded it embeds the prompt, places it in a difficulty cluster, and factors each candidate's observed error rate in that cluster into the score; the decision carries the cluster it landed in and the chosen model's expected_error there. Resolved and failed outcomes are recorded from the dispatch itself. tenzro_recordRouteOutcome is for the one outcome only the caller knows — escalated, meaning the answer was taken to a stronger model. tenzro_routeDifficultyStats reads the cluster map and a model's per-cluster counters as an operator diagnostic; enabled: false means the node has no embedding model and routes on declared metadata alone.
tenzro inference route --use-case code --budget 500000000000000 --optimize 0.3
tenzro inference route --use-case research --message "compare BFT and Nakamoto consensus"
tenzro chat --use-case chat --optimize 0.6All four operations reach the same handlers from MCP, A2A, the CLI, and both SDKs: the MCP tools route_by_intent, chat_by_intent, record_route_outcome and route_difficulty_stats; four prompt branches on the A2A inference skill; the CLI above plus tenzro inference record-outcome and tenzro inference difficulty-stats; the Rust SDK inference().route_intent(¶ms) / chat_by_intent(¶ms, messages) / record_route_outcome(..) / route_difficulty_stats(..) and their TypeScript camelCase equivalents; and the same four as Python functions in the OpenClaw skill. chat_completion and tenzro chat also accept a use_case with no model, resolving the offer at dispatch rather than pinning it. Naming a model directly skips intent routing entirely.
Orchestration
One tier above model selection: tenzro_orchestrate takes a natural-language goal instead of a use-case and plans an ordered set of capabilities — models, registered skills, registered tools, and agent/swarm delegation — then runs them, reusing the same inference, skill, tool, and settlement paths as a direct call. A planner turns the intent, the live capability catalog (models + skills + tools + swarm registry), the payer's wallet balance, and per-model usage/reputation into a plan. A deterministic planner is always available as a guardrail; an LLM planner routes its own plan-generation call through the model router and falls back to the deterministic planner on any failure, so orchestration stays available even when no model can be reached. Plans are bounded to eight steps; re-planning iterations clamp to one through six.
When payer_address is set, the plan's aggregate estimated cost across all model steps is summed and checked against the payer's wallet balance before any step runs — an over-budget plan is rejected up front, never partially executed. The result carries the final plan (steps + rationale + which planner ran), one {kind, output, detail} per executed step, the aggregate estimated_cost, and the iteration count.
tenzro inference orchestrate --intent "research decentralized-training results and draft a summary" --use-case researchReachable from MCP, A2A, the CLI, and both SDKs: the MCP orchestrate tool; the A2A inference skill; the CLI above; and the SDKs — Rust inference().orchestrate(&request), TypeScript inference.orchestrate(params).
Modality dispatch
InferenceRouter::route() reads model.modality and dispatches to Chat, Forecast, VisionEmbed, VisionSimilarity, TextEmbed, Segment, Detect, Transcribe, or VideoEmbed runtimes.
Local-first routing
Before scoring remote providers, the router prefers a provider on this node's own local segment when one serves the model — a member discovered via mDNS with local-direct reachability. A model served across a LAN cluster registers as a single logical provider; the router treats it like any other endpoint and the head node fans the request through the layer pipeline. Models served privately are not announced, so the router only reaches them over a direct or LAN connection.
Prefix-affinity routing
Providers advertise a compact radix-tree summary of their warm KV-cache prefixes over the tenzro/providers gossip topic — hashes of the fixed-length prompt runs they have recently served, never any KV bytes. When the router scores providers for a request, it hashes the incoming prompt the same way and adds a bias proportional to the fraction of the prompt a provider already holds warm. A provider that has the request's prefix cached skips re-prefill, so preferring it cuts time-to-first-token and prefill cost. The bias is capped so it tunes selection among comparable providers rather than overriding price, latency, or reputation, and ties among equally-scored providers break toward the deepest prefix match.
Usage tracking
Every successful inference records a UsageRecord with input tokens, output tokens, cost, and latency. Persisted in CF_MODELS under usage: prefix. Intent routing reads these same records to estimate per-model cost when scoring a budget.
Verified responses (opt-in)
Providers with a response signer stamp each output with a signed tenzro_contentProvenance manifest — a detached Ed25519 signature over the output hash, model id, provider address, timestamp, and content assertion. Verification is opt-in per request: pass require_signed: true in tenzro_chat and the call fails unless the manifest verifies against the provider's registered announce key. By default the field is informational and unsigned providers — including those without TEE hardware — are fully routable.
Verifiable inference (TOPLOC commitments)
Provenance says who produced a response; a TOPLOC commitment proves what was computed. Pass verifiable: true on tenzro_chat, the OpenAI-compatible surface, or tenzro_inferenceRequest and the serving provider records the top-16 raw logits of every generated token. The response carries {hash, k, steps}; the full commitment persists on the provider's node. Anyone holding the same weights re-executes the prompt as a single prefill — about two orders of magnitude cheaper than the original decode — and compares per-step logits, catching model substitution, quantization below the advertised precision, and fabricated output. Prompts are never stored; the verifier supplies the prompt at verification time.
Any party can file a challenge against a stored commitment. Filing draws a stake-weighted committee from the active validator set, seeded by the finalized-block hash so the draw is deterministic per dispute and grinding-resistant. The verdict is decided by that committee — not an operator — through a commit-reveal vote: each member commits a sealed vote, then reveals it, and a 2f+1 stake-weighted majority to uphold decides. An upheld challenge decrements the provider's routing reputation and records a failure against its compute bond. Reputation only increases through settled payments, so self-challenges can't launder a penalty away.
tenzro inference verify-commitment <hash> "<prompt>"
tenzro inference file-challenge <hash> <challenger-did> --reason quantization
tenzro inference commit-vote <id> --voter 0x<validator> --commit-hash <hex>
tenzro inference reveal-vote <id> --voter 0x<validator> --verdict true --salt <hex>
tenzro inference finalize-challenge <id>Commitments come from the local single-token serving path (non-streaming). Externally-fronted engines (vLLM, SGLang) don't expose per-step logits and return no commitment; network-routed requests forward the flag and the commitment anchors to the node that ran the computation.
Jurisdiction-pinned routing
Providers can declare a locality claim — an ISO 3166-1 alpha-2 country code plus optional regulatory-bloc tokens (jurisdiction_country / jurisdiction_blocs in node config). On TEE hardware the claim is bound to the attestation report hash at announcement time; without hardware it is operator-asserted, and the receipt says which. Pass jurisdiction: "DE,EU" on tenzro_chat or the OpenAI-compatible surface and the router hard-filters to providers whose claim matches the pin — fail-closed: a node with no claim never matches, and routing never falls back to unpinned providers. No match returns error -32024 (HTTP 412 on the OpenAI surface).
A response served under a pin carries tenzro_jurisdiction — a signed receipt binding the request hash, response hash, model id, provider address, and the claim it ran under. Set jurisdiction_receipt: "required" to fail the call unless a verifiable receipt comes back; on the network path the receiving node verifies the signature before returning it. A receipt is an attestation-bound locality claim, not cryptographic proof of geographic location — the trust anchor is the provider's stake, its attestation, and the slashing cost of a false declaration. Streams carry no receipts; the pin check runs before the first token.
tenzro chat qwen3-0.6b --jurisdiction DE,EU --require-jurisdiction-receiptTail-latency hedging
Once a strategy picks a primary provider, the router guards against a slow tail by hedging. It selects the next-best provider as a hedge target and starts the primary immediately; if the primary has not answered by a short delay, the router dispatches the same request to the hedge target and returns whichever answers first, dropping the loser. Inference is stateless, so a hedge is a safe duplicate — only the winning response bills the consumer and credits reputation.
The hedge delay is derived from the primary's observed p95 tail latency — each provider keeps a streaming LatencyTail estimator (the P² algorithm, constant memory, no stored samples), clamped to [40 ms, 500 ms]. Racing at the primary's own p95 means a still-pending request is a genuine tail case, not normal variance. At most one hedge per request; a provider whose circuit breaker is Open is never a hedge target. Opt out with params.custom["no_hedge"] = "1".
Per-request deadline
A caller can bound the whole request with a wall-clock deadline. When the deadline elapses before any provider succeeds — primary, hedge, and any failover retries included — the router abandons the request rather than blocking indefinitely on a straggler. A heterogeneous, variably-reachable provider pool means some endpoints will be slow or unreachable; the deadline turns that into a bounded, observable failure.
Router metrics
Live counters over tenzro_getRouterMetrics: requests (total routed), hedges_dispatched (primary still pending past the delay), hedges_won (hedge answered first), and deadline_exceeded (abandoned on the wall-clock deadline). A high hedges_won / hedges_dispatched ratio means hedging is rescuing tail requests; a rising deadline_exceeded means providers are missing the deadline outright.
tenzro inference router-metrics
tenzro inference router-metrics --format jsonRevenue split
The consumer pays the price the offer advertised. The network's share is carved out of that price rather than added to it, and is set by the serving node's economic mode — a private node keeps the whole payment, a public validating node pays the treasury leg, a public node that does not validate also pays the RPC provider validating on its behalf. network_wei + provider_wei equals the quoted cost. A response reports both, plus the provider address actually paid, in its settlement object.
A developer margin runs the other direction. Pass a registered app_id and that app's margin is added on top of the network cost and routed to the app's wallet as margin_wei. An unknown or deactivated app_id fails the call rather than silently dropping the margin.
Settlement runs on the node the request arrived at. When that node forwards to a peer, the gateway settles the peer's leg — the forwarded request carries no payer, and every node shares one ledger, so the node holding the payer relationship is the one that can move funds. Pricing for that leg comes from the announcement the routing decision scored, never from the provider's response, so a provider cannot re-price after serving. Pin a call to one provider with provider: "0x…"; if that offer is no longer announced the call fails with -32004 instead of serving someone else at a price the consumer never priced against.
On a micropayment channel, per-update settlement reports network_wei: 0 — the network share and developer margin are carved once at channel finalize rather than on every update.
Request
tenzro inference request qwen3-0.6b "hello"
tenzro chat qwen3-0.6b
# Interactive REPL on the chosen model