PAIPAI

Runtime Pipeline

What happens after a client sends a message or action.

Every server, client, and transport eventually reaches the same runtime operation path.

Mutation

Mutation is the moment the runtime accepts or rejects a thread operation.

An operation is accepted only after:

  • request body and contract validation pass;
  • scope is resolved and validated;
  • addressed thread state is loaded by scope;
  • thread status allows the operation or queues it.

thread.send() resolves to a RunHandle after the message is committed or queued, not after the model finishes.

Execution

Runners claim runnable work from storage. This keeps execution independent from client connections.

If the request that submitted a message disconnects, the run can still finish because the message or queued-item state, the run lifecycle record, and the active run lease are durable.

Execution is a model/tool loop. Each completed assistant model step commits its own assistant message. A run is the lifecycle of the accepted work; it is not the same thing as a message and may contain multiple assistant step messages.

The model call itself uses the AI SDK LanguageModel surface directly. Before the primary model loop, PAI normalizes the configured model or ModelSelection. It spreads the selection's portable modelSettings into the AI SDK streamText() call and passes providerOptions separately.

The runtime converts persisted PAI thread messages into AI SDK model messages, then normalizes AI SDK text/tool output back into PAI message parts before committing state. This keeps providers and test mocks standard while keeping PAI's persisted thread model independent of raw AI SDK stream chunks.

See Lifecycle Phases for the hook boundaries inside the runner.

Commit

Runtime code computes domain transitions. Providers mechanically apply one version-checked root/child/lease write set and enforce scope, strict JSON, and atomic compare-and-swap guarantees.

The store should not invent agent behavior. It should guarantee that committed state is ordered and scoped correctly.

On this page