Skip to main content

Generations

One model loop each — the record every agent, session and conversation run is polled, audited and purged through.

Overview​

A generation is created for you: running an agent, posting to a session, or generating into a conversation each produce one. What you get back immediately is its id, because generation is background by default — so this module is where a run's status, result, transcript and cost attribution are read from afterwards.

This module is a verbatim mirror of the runtime: every field, method, status code and error shape is the runtime's own, re-rooted under the project in the path.

See the OpenAPI spec for the full endpoint and schema reference, or browse it rendered under API Reference → Generations.

Data Model​

Generation (selected fields)​

The full field set is in the reference; these are the ones a caller usually acts on.

FieldTypeDescription
idstringPublic generation ID — the polling handle a 202 hands back.
agent_idstringThe agent that ran.
statusstringin_progress, requires_action, completed, failed.
stop_reasonstring, nullableWhy it stopped: a model provider finish reason relayed unchanged (stop, tool-calls, length, …), or one the platform names itself — max_steps, depth_guard, chain_limit (see Continuation chains) — or error.
errorobject, nullableStructured payload when status is failed; carries at least message.
agent_versionintegerThe agent config version that served this run — see Versioning and staged rollout.
routingobject, nullableWhat the model route did: which target answered, and what fell through. Absent for an agent with a pinned provider.
metadataobject, nullableCaller-owned annotations, set at create time or attached later.
retrievalarray, nullableWhat knowledge_config retrieval injected this turn, in order: a document chunk (document_id, document_version, chunk_id, page, similarity_score) or a memory (memory_store_id, memory_id, similarity_score). null when no retrieval ran, [] when it matched nothing. Kept by a content purge.
initiator_generation_idstring, nullableThe generation that triggered this one, for nested agent calls.
chain_idstring, nullableThe continuation chain this generation belongs to — set on the root and every continuation, null otherwise.
content_redacted_atstring (date-time), nullableNon-null once the content was purged.
trace_idstringThe trace this generation belongs to.
orchestration_run_idstring, nullableThe orchestration run that dispatched this generation, if any.
node_idstring, nullableThe orchestration node that dispatched it.
node_attemptinteger, nullableThe node's 1-based retry attempt — what tells two attempts of the same node apart.
session_idstring, nullableThe session this generation was dispatched through, or null when it was started outside one.
actor_idstring, nullableThe actor the generation was attributed to, or null when none was.

Key Concepts​

Background by default​

A generate call answers 202 Accepted with a generation_id unless you pass wait=true. Poll GET /v1/projects/{project_id}/generations/{generation_id} until status leaves in_progress:

  • completed — the result is on the generation, and on the conversation or session it ran in.
  • requires_action — a client-type tool is waiting on you; submit its output to resume the run.
  • failed — read error.message.

Your first agent generation polls one to completed; Run tools in your own code parks one at requires_action and resumes it.

Passing wait=true holds the request open and returns the finished result instead. Streaming (stream: true) implies waiting, and cannot be combined with the background mode.

Reading a run back, step by step​

GET /v1/projects/{project_id}/generations/{generation_id}/transcript returns the turn as an ordered sequence of steps — what the model was asked, each step's tool calls and their results, and how it ended. It is the answer to "why did the agent do that", and it is the natural companion to a failed status. Debug a failed run uses it to name the tool call that broke a run whose status still reads completed.

Filtering the log​

GET /v1/projects/{project_id}/generations filters by agent, trace and status, so "every failed run of this agent" is one call. Roll out an agent version filters by agent to see which version served each run.

It also filters by orchestration_run_id and node_id, which is how an orchestration run is traced back to what its agent nodes actually generated: a node execution record carries no generation id, so the pointer lives on the generation. A node that was retried returns one generation per node_attempt.

Filtering by chain_id is how a continuation chain is expanded into its members — the chain record itself carries only their count.

session_id and actor_id narrow the same way: the turns behind one conversation, or every run one end user started across every session they appear in. Either naming nothing in the project yields an empty page rather than the unfiltered log. A session's own cost is read directly off GET /v1/projects/{project_id}/sessions/{session_id} — these filters are for the runs behind that figure.

Continuation chains​

A requires_action resumption, and a react approval expiry, each start a new generation rather than mutating the one that paused — but both stay part of the same continuation chain as the generation they continue. Every member shares one chain_id; a generation outside any chain has it null. Gate a tool with guardrails finds the continuation an approval starts.

An agent's max_chain_generations stop condition bounds a chain's length below the deployment's own ceiling. Reaching it ends the chain with stop_reason: "chain_limit", and files a matching chain_limit exception.

Purging content​

DELETE /v1/projects/{project_id}/generations/{generation_id}/content clears the run's content — metadata, error, extraction, and the internal recovery state of a paused run — and stamps content_redacted_at together with the principal that did it. The usage and cost records survive: what was spent stays auditable after what was said is gone. To stop content being recorded in the first place, set trace_content_mode on the agent; Run a zero-retention agent shows the usage that survives.

Purging the trace instead — DELETE /v1/projects/{project_id}/traces/{trace_id}/content — erases the steps object this generation's content lives in and cascades to every generation under it, so that is the call to reach for when a whole run must go.

Response messages​

output.response_messages carries the full message list the model produced — tool calls, tool results, and the final text — as the shape the underlying SDK returns it in.

One field is removed on the way out: providerOptions, the SDK's per-vendor bag. Its keys name the vendor serving the request, which for a naturali-managed provider would disclose infrastructure the managed offering exists to abstract away. It is stripped for every provider, so the shape does not differ between a managed model and your own credentials.

Nothing you can act on is lost: the field is not part of this API's contract, and no message shape POST /v1/projects/{project_id}/agents/{agent_id}/generate accepts could send it back.

A generation is one node of a run

trace_id is the trace this generation belongs to: fetch its tree to see the sub-agent calls around it, and this generation's transcript to see what it did.

Examples​

Poll a background generation​

naturali get-generation \
--project-id proj_V1StGXR8Z5jdHi6B \
--generation-id gen_V1StGXR8Z5jdHi6B

List an agent's failed runs​

naturali list-generations \
--project-id proj_V1StGXR8Z5jdHi6B \
--agent-id agent_V1StGXR8Z5jdHi6B \
--status failed

Read the transcript of one run​

naturali get-generation-transcript \
--project-id proj_V1StGXR8Z5jdHi6B \
--generation-id gen_V1StGXR8Z5jdHi6B

Purge a run's content​

naturali purge-generation-content \
--project-id proj_V1StGXR8Z5jdHi6B \
--generation-id gen_V1StGXR8Z5jdHi6B