Skip to content

Request inference

Choose an agent provider and model, then request or stream inference.

On this page

Choose a provider and model

Start with registry discovery below to choose an agent provider. For the request examples, complete wallet setup in the agent quickstart, then insert each fragment inside its with Client.from_config(...) as client: block using the same provider, model and retained configuration.

Choose an agent provider from the ERC-8004 registry. Pass its registered ID as an integer, or its HTTPS origin as a string, to Client.from_config. The SDK resolves the registration, reads the models and verifies their registry bindings.

Agent providers publish their models, prices and capabilities. Choose an exact model ID from that offering. The inference engine determines which payload fields it supports.

Find agent providers through ERC-8004

The registry is the directory. An agent provider publishes an ERC-8004 identity, an MPPI service endpoint and a model catalogue under mppi.catalog. Agents can discover the offering without contacting its operator.

  • Find registered offerings. Index MetadataSet events for the mppi.catalog key in the selected network's ERC-8004 registry to obtain agent provider IDs.
  • Read the current offering. Resolve each ID's agentURI and current mppi.catalog metadata. The registration document identifies the MPPI endpoint; the catalogue supplies model IDs and token prices.
  • Connect with the SDK. Pass the chosen ID to Client.from_config. The SDK reads current registry data and verifies the endpoint and model documents before paid work.

In SDK 0.1.6, your application supplies the registry index and selected ID; the SDK handles that ID's resolution and verification. The mppi-agent CLI provides onboarding. It does not yet include a command to list agent providers.

Understand and accept prices

Rate / Meaning

Input
Uncached input tokens, priced per million tokens.
Output
Generated output tokens, priced per million tokens.
Cache · optional
Cached input, a subset of input. An absent cache price differs from an explicit zero.

Display prices in USDC per million tokens. Raw catalogue rates are decimal strings containing six-decimal USDC base units per million tokens: a display price of 1 USDC is "1000000" in the rate field.

Every signed request binds its model and accepted catalogue hash. Those prices remain fixed for that admitted run. If new work encounters PRICE_CHANGED, inspect the new catalogue and explicitly accept its hash before submitting a fresh request. Existing funded sessions can use a newly accepted catalogue.

Python · after reviewing a new catalogue
# new_hash is the reviewed 32-byte catalogue hash.
accepted = client.accept_catalog(new_hash)

Send a request

Python · after onboarding
from mppi_agent import Client

with Client.from_config(
    "https://YOUR_PROVIDER",
    testnet=True,
    initial_session_tokens=10_000,
) as client:
    response = client.chat.completions.create(
        model="YOUR_PROVIDER/MODEL",
        messages=[{"role": "user", "content": "Hello"}],
    )
    print(response.decode("utf-8"))
Agent SDKProvider SDK

Complete · typed gRPC envelope

Session · run · model · accepted prices · signature

Original inference JSON bytes

Output JSON + Terminal return on Complete. Vouchers, meters and Receipt travel on Control.

The SDK envelope adds payment context. The provider’s inference JSON remains intact.

create serializes the request fields to JSON. The typed envelope binds model and stream mode to that payload. Responses remain original JSON bytes; the SDK does not replace them with a proprietary response object.

Read streaming output

Python · inside a configured Client context
with client.chat.completions.create(
    model="YOUR_PROVIDER/MODEL",
    messages=[{"role": "user", "content": "Hello"}],
    stream=True,
) as stream:
    for payload in stream:
        print(payload.decode("utf-8"))
    print(stream.terminal)
    print(stream.receipt)

Each payload is an original JSON object after the provider consumes any upstream framing. The MPPI wire is not SSE. Successful iterator completion requires a valid COMPLETED Terminal and gRPC OK trailers. Receipt and Terminal travel on separate streams, so their delivery has no cross-stream ordering guarantee.

Closing the stream cancels that request and releases its local resources. It neither proves the provider stopped immediately nor closes the funded session. Final usage still needs a definitive provider report.

Preserve an existing JSON payload

Python · inside a configured Client context
payload = b'{"model":"YOUR_PROVIDER/MODEL","stream":false,"messages":[{"role":"user","content":"Hello"}]}'
response = client.chat.completions.create_raw(
    payload, model="YOUR_PROVIDER/MODEL", stream=False,
)

create_raw preserves the original UTF-8 JSON bytes. Its explicit model and stream values must match the JSON. Supply a valid JSON object with supported provider fields; validation rejects ambiguous or malformed input.

Handle failures and uncertainty

A failure before admission creates no usage for that run, even if a voucher already authorized a ceiling. An admitted upstream error with definitive usage can have a FAILED Terminal and valid payment accounting; gRPC OK in that case means the transport delivered the application outcome.

A timeout, disconnect or missing final record does not prove that no work occurred. Retain the original run and operation evidence. Recover accounting through the same session when possible; recovery does not replay inference or recreate missing output.

If the provider restarts or the Control stream is lost, nothing reattaches in the background. The next request, or sessions.open, reattaches first; if the provider is still unavailable, that call fails and a later one tries again. sessions.get only reports readiness, so send the next request instead of waiting for it.

Request inference | Agents | MPPI Docs