API reference
Look up methods for inference, funding, session management and recovery.
On this page
Client API
Import Client from mppi_agent. Calls are synchronous; the network client owns a background asyncio thread. Use it as a context manager. The examples below assume retained onboarding and a real provider; capability examples require your own integration objects.
Client.from_config
Client.from_config(provider: str | int, *,
config_path: Path = Path(".mppi/agent.json"),
initial_session_tokens: int | None = None,
ca_file: str | None = None, testnet: bool = True,
profile: DeploymentProfile | None = None,
max_age_ms: int = 60_000,
poll_interval_ms: int | None = None) -> Client- Inputs
- Provider HTTPS origin or ERC-8004 ID; retained config; explicit network. A positive initial token budget is needed when choosing new funding.
ca_fileand an independently trusted profile are optional. - Returns
- A Client configured with the built-in wallet and verified deployment capabilities.
- Behavior
- Rejects incompatible retained identity, signer, provider or deployment. Creating a client is not a substitute for confirmed funding and readiness. No error implies an automatic replacement deposit.
client = Client.from_config("https://YOUR_PROVIDER",
testnet=True, initial_session_tokens=10_000)Client
Client(provider, *, wallet, signer, chain, contract,
checkpoint_path, signer_reference, initial_session_tokens=None,
agent_id=None, ca_file=None, timeout_ms=10_000,
request_timeout_ms=None, queue_wait_ms=1_000,
queue_messages=64, queue_bytes=16 << 20,
on_low_credit=None, on_funding_notice=None, hooks=None)- Inputs
- Supply compatible FundingWallet, fixed SessionSigner, ChainFollower and ContractCalls, plus a durable Path and signer reference. Provider is str/int; timing values are milliseconds; queue limits are messages/bytes.
- Returns
- A Client using your explicit capabilities. Each runtime needs a follower on its own event loop.
- Behavior
- Retains payment intents before signing/submission. Credentials and wallet idempotency belong to your adapter. Uncertain work keeps original identifiers; it is not replayed.
client = Client(provider, wallet=wallet, signer=signer,
chain=chain, contract=contract, checkpoint_path=state_path,
signer_reference=signer_reference, initial_session_tokens=10_000)Client.accept_catalog
client.accept_catalog(rate_card_hash: bytes) -> Catalog- Inputs
- The reviewed 32-byte catalogue hash.
- Returns
- The accepted canonical Catalog.
- Behavior
- Explicitly accepts prices for subsequent runs. Historical runs retain their signed prices. Invalid/unavailable evidence fails; a PRICE_CHANGED error does not itself grant acceptance.
catalog = client.accept_catalog(reviewed_hash)Client.close
client.close() -> ShutdownResult- Inputs
- No inputs; also used by the Client context lifetime.
- Returns
- Unresolved session IDs, runs and pending operations retained in a ShutdownResult.
- Behavior
- Releases local resources and preserves unresolved evidence. It does not close escrow or prove provider termination.
shutdown = client.close()
print(shutdown.pending_operations)Inference and stream API
chat.completions.create
client.chat.completions.create(*, model: str,
messages: list[object], stream: bool = False,
**fields: object) -> CompletionStream | bytes- Inputs
- Exact model ID, messages and supported provider fields.
streamdefaults to False. - Returns
- Original JSON bytes for a non-streaming request, or a context-managed CompletionStream yielding JSON bytes.
- Behavior
- Validates/binds model and stream mode. Requires payment admission. Non-streaming success follows a valid terminal and gRPC OK; failures do not authorize a replay.
response = client.chat.completions.create(
model="YOUR_PROVIDER/MODEL",
messages=[{"role": "user", "content": "Hello"}])chat.completions.create_raw
client.chat.completions.create_raw(payload: bytes, *,
model: str, stream: bool) -> CompletionStream | bytes- Inputs
- Original UTF-8 JSON object bytes. Required model and stream arguments must agree with the JSON.
- Returns
- The same response types as create, preserving the input's original numeric text.
- Behavior
- Rejects malformed/mismatched input before it can establish valid work. Provider capabilities still determine accepted inference fields.
response = client.chat.completions.create_raw(
payload, model="YOUR_PROVIDER/MODEL", stream=False)CompletionStream
iter(stream) -> Iterator[bytes]
stream.terminal -> Terminal | None
stream.receipt -> Receipt | None
stream.close() -> None- Inputs
- Read each yielded JSON object. Terminal/receipt are properties; close takes no arguments.
- Returns
- Original payload bytes and validated final records when available. Missing final delivery can remain uncertain.
- Behavior
- Use a context manager for cleanup. Closing cancels the local request; it does not establish actual engine termination, final usage or a session refund.
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, stream.receipt)Agent session API
Access synchronous methods through client.sessions. Session IDs are 32-byte values from retained results, not display hex strings. Economic results use the state model below. Never treat a returned operation reference alone as confirmation.
sessions.open
open(provider: str | int, *, model: str,
initial_session_tokens: int | None = None) -> OpenResult- Inputs
- Same selected provider, model and a deliberate positive initial funding budget, or the Client's configured budget.
- Returns
operation: OperationResultandsession: SessionView | None. A non-null session requires confirmed funding and ready attachment.- Behavior
- Explicitly funds/pre-warms. Can continue an original never-submitted opening intent. Once submission is uncertain, reconcile its original reference rather than create new funding.
opened = client.sessions.open("https://YOUR_PROVIDER",
model="YOUR_PROVIDER/MODEL", initial_session_tokens=10_000)sessions.topUp
topUp(session_id: bytes, amount: int) -> OperationResult- Inputs
- Session ID and positive integer six-decimal USDC base units. 1_000_000 means 1 USDC.
- Returns
- Original funding operation state and canonical evidence when confirmed.
- Behavior
- Adds deposit without changing run prices. Pending/unknown does not add usable funding; retain and reconcile the same operation.
result = client.sessions.topUp(session_id, 1_000_000)sessions.close
close(session_id: bytes) -> OperationResult- Inputs
- Retained session ID; cooperative close requires authenticated Control.
- Returns
- The retained close operation; confirmation requires the actual canonical close/refund effect.
- Behavior
- Stops new grants and accounts for final work. Repeat this method to inspect the same pending close. CloseAccountingError retains confirmed discrepant collection; do not resubmit it as failed.
result = client.sessions.close(session_id)
print(result.state, result.operation_ref)sessions.requestClose
requestClose(session_id: bytes) -> OperationResult- Inputs
- Retained session ID; funding-wallet authority and an eligible open session.
- Returns
- Transaction result for entering on-chain Closing.
- Behavior
- Starts the one-hour closing collection window when eligible before idle expiry. Repeating a confirmed request cannot extend it. Pause and ordinary contract predicates still apply.
result = client.sessions.requestClose(session_id)sessions.withdraw
withdraw(session_id: bytes) -> OperationResult- Inputs
- Retained session ID and funding-wallet authority after the closing deadline.
- Returns
- The withdrawal result and evidence of the refund when confirmed.
- Behavior
- Requires current eligibility; elapsed local time alone does not execute a refund. Reconcile pending/unknown submission using its original reference.
result = client.sessions.withdraw(session_id)sessions.releaseIdle
releaseIdle(session_id: bytes) -> OperationResult- Inputs
- Retained session ID with satisfied idle predicate and applicable pause checks.
- Returns
- Operation result for the eligible refund to the funding wallet.
- Behavior
- The contract operation is permissionless; the refund destination remains fixed. It cannot collect additional expired usage.
result = client.sessions.releaseIdle(session_id)sessions.get
get(session_id: bytes) -> SessionView- Inputs
- Known retained session ID.
- Returns
- Observed deposit, capture, authorization/usage when known, status, chain observation, freshness and readiness.
- Behavior
- Inspection can use local evidence and chain state without a live provider. Unknown usage remains unknown; missing local state is not proof that no session exists.
view = client.sessions.get(session_id)sessions.list
list(*, cursor: str | None = None, limit: int = 100) -> SessionPage- Inputs
- Leave cursor as None; any other value is rejected by the built-in Client. Checked limit 1–1,000.
- Returns
sessions: tuple[SessionView, ...]with zero or one retained session, andnext_cursor=None.- Behavior
- Inspection only. The built-in Client does not paginate or enumerate other configuration directories; retain each provider/configuration pair separately.
page = client.sessions.list(limit=100)sessions.reconcile
reconcile(operation_ref: str) -> OperationResult- Inputs
- Original retained wallet-operation reference.
- Returns
- Updated observation of that operation; unknown can remain unknown.
- Behavior
- Reconciliation does not create a replacement transaction. Use repeated sessions.close for cooperative-close intent. Lost Circle transaction identity cannot be inferred from similar history.
result = client.sessions.reconcile(operation_ref)sessions.terms
terms(session_id: bytes) -> SessionTerms- Inputs
- Retained session ID.
- Returns
- The accepted catalogs by rate-card hash, the initial one and the provider's current one;
rates(model)reads one. - Behavior
- Reads no chain. A new run uses the current catalog only if it is accepted; an admitted run keeps the prices it signed.
terms = client.sessions.terms(session_id)
print(terms.rates("YOUR_PROVIDER/MODEL"))sessions.run
run(session_id: bytes, run_id: bytes) -> RunOutcome- Inputs
- Retained session ID and a run ID this session signed.
- Returns
- Its model, rate card, accepted counts, final charge and status: PENDING, COMPLETED, FAILED, CANCELLED or NOT_ADMITTED.
- Behavior
- Reads no chain. NOT_ADMITTED means the provider never held the run. A finished, proven run is eventually forgotten; its usage stays in the session totals.
outcome = client.sessions.run(session_id, run_id)sessions.recover
recover(session_id: bytes) -> SessionView- Inputs
- Retained session ID, signer and complete payment checkpoint; requires the provider for authenticated Control.
- Returns
- Validated recovered session view after attachment/reconciliation checks.
- Behavior
- Authenticates a new Control generation without new funding or inference replay. It cannot recreate lost output or invent missing accounting evidence.
view = client.sessions.recover(session_id)Results, identifiers and units
Result / Fields to inspect
OpenResult· agentoperation, optionalsession. Usable session requires confirmed opening and readiness.OperationResultoperation_ref,state, optionalwallet_operation_id,tx_hash,observation, orderedsessionsoutcomes.SessionViewsession_id,descriptor,deposit,settled_cumulative, optionalaccepted_authorization/usage_amount,status,observation,fresh,readiness.SessionPagesessionsandnext_cursor. Provider listing can paginate; the built-in agent returns zero or one session and no cursor.Readinessreadyand structuredfailures.ShutdownResultunresolved_session_ids,unresolved_runs,pending_operations.RunContext- Session/run IDs, Control generation, model and accepted price hash; not an execution grant.
AccountingResult- Context, cumulative counts, meter sequence, session usage amount and duplicate flag.
Operation state / Interpretation
pending- Original operation is unresolved; retain its reference.
confirmed- Canonical transaction and block evidence establish its effect; still inspect per-session outcomes.
failed- Recorded failure; inspect its cause and evidence before any new action.
unknown- Submission/effect cannot be established. Reconcile original intent; do not assume no payment.
MPPI money is uint64 in six-decimal USDC base units. Rates are base units per million tokens; raw catalogue rates are canonical decimal strings. Token counts are exact uint64 integers, cache is a subset of input. Use arbitrary-precision or checked wide intermediate arithmetic; floats and booleans are not money.
Python IDs/hashes are bytes: session/run/catalogue hashes are 32 bytes and wallet addresses are 20 bytes in typed records. Hex is a display encoding. Contract SessionStatus uses Open=0, Closing=1, Closed=2; protobuf includes an unspecified value and uses 1, 2, 3. Convert explicitly.
Agent CLI
Install the agent package and activate its Python environment first. Replace the address with the funded Arc testnet wallet selected during Circle login. Run from the application folder where you will retain .mppi/.
mppi-agent onboard --testnet --wallet YOUR_WALLET_ADDRESSFlag / Purpose
--testnet/--mainnet- Explicit network for built-in setup; mutually exclusive.
--wallet ADDRESS- Existing authenticated and funded Circle Agent Wallet.
--config PATH- Private configuration path; default
.mppi/agent.json. --agent-id ID- Adopt an existing identity after ownership/binding verification.
--rpc-env NAME- Read a trusted RPC URL from the named environment variable.
--profile FILE- Independently trusted profile override matching the network.
--wallet-factory MODULE:FUNCTION- Advanced trusted Python code; requires an explicit profile and is incompatible with --wallet.
Output is JSON. Exit 0 means complete; 2 means the original operation is unresolved; 1 means setup failed. Retain state and rerun the original command to reconcile. Built-in setup requires the supported Circle CLI 1.1.4.
Discovery and wire API
Surface / Purpose
GET /discover- Provider registration document on the declared HTTPS origin.
GET /.well-known/agent-registration.json- The corresponding agent registration document.
GET /models- Advisory model capabilities checked against the confirmed catalogue.
/mppi.v1.Chat/Completions- Server-streaming CompleteRequest → ChatChunk stream.
/mppi.v1.Control/Session- Bidirectional ControlMessage stream for the authenticated payment session.
Wire family / Important fields and interpretation
- CompleteRequest
- Model, stream flag, session/run IDs, Control generation, rate_card_hash, auth_signature and original payload bytes. Presence, widths and payload bindings are validated.
- ChatChunk
- One of original JSON payload, Terminal or UpstreamError.
- Terminal
- Final token counts, informative amount, session/run/model/price binding, status and final meter sequence; optional attributable settlement reference.
- ChallengeRequest / Challenge
- Unpaid, correlated request/model and provider/deployment/catalogue evidence; no inference execution.
- SessionOpen / ReconnectChallenge / ReconnectRequest / SessionState
- Canonical funding evidence and signed attachment, fixed authority and current Control generation.
- Voucher / Meter
- Session-wide signed cumulative authorization and provider-reported cumulative usage; off-chain, not deposits or payouts.
- TopUpNotice / LowCredit / Drain
- Funding observation/guidance and termination coordination; no automatic deposit or job pause/resume.
- Receipt
- Final accounting and required confirmed session chain observation, with attributable settlement reference when available.
- CloseRequest / CloseResult
- Signed cooperative close intent and canonically confirmed close/refund result.
The protobuf schema fixes field names, widths, presence and oneof choices; the protocol profile fixes validation and meaning. Control never carries prompts/output. A provider's internal HTTP inference API is separate from MPPI's native gRPC surface. There is no released Responses RPC.
Contract operations and authority
The SDK normally prepares and verifies these operations. All application calls are nonpayable and use the fixed Arc USDC ERC-20 interface. The descriptor binds funding wallet, immutable session signer, provider identity, recipient, operator, token and salt.
Call / Authority / effect
open(d, deposit, expectedRateCardHash, auth)- Funding wallet; positive authorized USDC deposit creates the session.
topUp(d, amount, auth)- Funding wallet; positive additional deposit; existing descriptor and opening hash stay fixed.
settle(d, cumulativeAmount, captureAmount, voucherSig)- Frozen operator or recipient; eligible increasing capture to the fixed recipient.
settleBatch(d[], cumulativeAmounts[], captureAmounts[], voucherSigs[])- Same per-item authority, equal array lengths and isolated item failure.
close(d, cumulativeAmount, captureAmount, voucherSig)- Operator or recipient; eligible final capture and refund to the funding wallet.
requestClose(d)- Funding wallet; start the closing interval while eligible.
withdraw(d)- Funding wallet; refund after the closing predicate is satisfied.
releaseIdle(d)- Permissionless eligible idle exit; funding wallet receives the refund.
getSession,computeSessionId,voucherDigest,pauseLevel- Views/helpers. Computing a session ID does not establish its existence.
The contract enforces amount/authority/deadline predicates, not the truth of token counts. The protocol team's guardian, safe and timelock control the defined pause/administration operations; these are not provider integration methods. Payments pause blocks funding/capture/provider close but permits eligible wallet exits. All pause blocks session mutations. USDC restrictions may independently block transfers.
Errors and limits
Failure / Action
INSUFFICIENT_DEPOSIT· RESOURCE_EXHAUSTED- Inspect the current deposit. A deliberate top-up may fund future work; the failed request does not revive.
SESSION_NOT_FOUND· NOT_FOUND- Only fresh confirmed zero deposit establishes absence. Pending funding or missing private state is not absence.
SESSION_NOT_READY / PRICE_CHANGED- Review the requested/current hashes and explicitly accept new prices before a fresh request.
SESSION_NOT_READY / AUTHORIZATION_REQUIRED- The bounded pre-admission authorization wait expired. Resolve readiness before choosing a fresh request.
CONTRACT_PAUSED / CLAIM_DEADLINE / CHAIN_STATE_STALE- Stop new grants; inspect pause, collection eligibility and fresh canonical chain evidence.
STATE_UNAVAILABLE / INCONSISTENT_STATE / INCONSISTENT_USAGE- Preserve valid state and restore/inspect complete evidence. Do not manufacture zero usage.
CONTROL_NOT_READY / CLOSE_PENDING / SESSION_CLOSED- Authenticate when eligible or continue the original close/exit. Do not reopen closed or closing work.
INVALID_ARGUMENT / UNAUTHENTICATED / ALREADY_EXISTS- Correct input, authority or duplicate run identity; do not replay an uncertain run.
CANCELLED / DEADLINE_EXCEEDED / UNAVAILABLE- Retain run and payment evidence. A transport outcome alone does not establish execution or payment outcome.
Payment not-ready errors use FAILED_PRECONDITION with a required reason; unknown reasons remain not-ready. Reserved VOUCHER_STALE has no duplicate-voucher producer. Rich payment details are google.rpc.Status with one mppi.v1.PaymentError in grpc-status-details-bin; these are not HTTP 402 responses.
Python exposes ClientError, PaymentError.failure, InferenceError.body/http_status and CloseAccountingError.operation/capture_amount/usage_amount. An admitted upstream failure can retain valid final accounting. A confirmed discrepant close is not an unknown transaction to retry.
Configurable default bound / Value
- Decompressed protobuf / SessionState
- 16 MiB
- Ordinary Control message
- 64 KiB
- Catalogue bytes
- 1 MiB
- JSON nesting
- 128 containers
- Reconnect pending run IDs
- 1,024
- Application send/receive queue
- 64 messages and 16 MiB
- Rich error Status
- 2 KiB
These are implementation resource bounds, not pricing plans or performance guarantees. A deployment can set tighter bounds. Enforce decompressed limits, fail explicitly at capacity and never truncate recovery evidence. No automatic inference replay follows a failed RPC.
Lifecycle hooks
Import Hooks from your role's Python package. Synchronous callbacks receive owned record snapshots and return None. Configure them on explicit Client composition or provider construction/from_config; Rust uses runtime Hooks with Arc callbacks and runtime options.
Callback / Observation
on_challenge/on_session_open- Verified/enqueued setup or confirmed opening and attachment boundaries.
on_voucher/on_meter- Authorization and usage observation; neither is a payout.
on_low_credit/on_drain- Guidance and lifecycle instructions; no automatic funding.
on_receipt- Run accounting checked against the run's accepted terms, with no chain read. Its settled total and observation are the provider's report; the SDK proves the settled total at close.
on_error- Structured boundary failures without prompts, secrets or raw upstream bodies.
from mppi_agent import Hooks
hooks = Hooks(on_meter=lambda meter: print(meter.session_id.hex()))
# Pass hooks to explicit Client composition or provider construction.
# client.hook_stats exposes delivered/dropped/failed/queued counts.Delivery is best effort, bounded to 64 records and 1 MiB plus one in progress. The newest observation is dropped at capacity. Callbacks can repeat; shutdown drops pending observations. Hand off quickly to your own logs/metrics. Callback counts are not payment evidence or a durable event log.
Log each HookError's operation, code and detail together; detail carries the SDK's own reason when there is one. A failed background chain refresh, for example, reports background refresh: <reason>.
Supporting types and local testing
Family / Use and canonical reference
- Rates, TokenCounts, Catalog / CatalogRow
- Exact counts, rates and canonical accepted catalogue bytes. SDKs do not tokenize inference.
- funding_amount, required_coverage, cumulative_usage
- Checked funding, reservation and billing arithmetic in mppi-protocol.
- parse_catalog / publish_catalog
- Validate or create canonical model-price evidence; parsing is not identity verification.
- RunAccounting / report_transition
- Pure accounting transitions; not an execution grant, durable commit or chain confirmation.
- FundingWallet, SessionSigner, LocalSessionSigner
- Advanced wallet and signing capabilities with explicitly retained authority.
- discover, verify_challenge, onboard
- Advanced integration entry points described by the public onboarding/runtime guides.
The loopback MockProvider supports local client practice. It performs no escrow, wallet operations, signature verification or real token accounting and must not be presented as a public provider. Unpaid endpoint verification and a real funded exchange establish different things.