Skip to main content

Stage

A Stage represents an intermediate processing step within a Choice. Stages appear as expandable sections in DIAL Chat, showing the user what your application is doing behind the scenes — retrieving documents, calling external APIs, running computations, and so on.

Create stages with choice.create_stage().

from aidial_sdk.chat_completion.enums import Status

Context manager​

Stage implements the context manager protocol. On exit, the stage closes with Status.COMPLETED if no exception occurred, or Status.FAILED if an exception was raised.

with choice.create_stage("Searching knowledge base") as stage:
stage.append_content("Found 5 matching documents.")
stage.add_attachment(type="text/plain", title="results.txt", data="...")
# Stage automatically closes with Status.COMPLETED

with choice.create_stage("Parsing data") as stage:
raise ValueError("bad format")
# Stage automatically closes with Status.FAILED, then the exception propagates

Content​

append_content​

def append_content(self, content: str) -> None

Appends text to the stage's content. In streaming mode, each call sends a chunk immediately.

Raises RuntimeServerError if the stage is not open or already closed.

content_stream​

@property
def content_stream(self) -> ContentStream

Returns a file-like object with a write(str) method. Works the same as Choice.content_stream — you can redirect print(), tqdm, CSV writers, and logging handlers to it.

append_name​

def append_name(self, name: str) -> None

Appends text to the stage's name. Use this to update the stage name incrementally as processing progresses. The name set in create_stage() is the initial value; append_name adds to it.

Raises RuntimeServerError if the stage is not open or already closed.

Attachments​

add_attachment​

# From an Attachment object
def add_attachment(self, attachment: Attachment) -> None

# From individual fields
def add_attachment(
self,
type: str | None = None,
title: str | None = None,
data: str | None = None,
url: str | None = None,
reference_url: str | None = None,
reference_type: str | None = None,
) -> None

Adds a file attachment to the stage. Attachments appear within the expanded stage section in DIAL Chat.

Raises RuntimeServerError if the stage is not open or already closed.

Lifecycle​

open​

def open(self) -> None

Opens the stage. Called automatically when used as a context manager.

close​

def close(self, status: Status = Status.COMPLETED) -> None

Closes the stage with the given status. Called automatically when the context manager exits.

StatusWhen to use
Status.COMPLETEDThe step finished successfully (default).
Status.FAILEDThe step failed. Use this to indicate that a retrieval, API call, or computation did not succeed.

Full example​

async def chat_completion(self, request: Request, response: Response) -> None:
with response.create_single_choice() as choice:
# Stage 1: Retrieve documents
with choice.create_stage("Retrieving documents") as stage:
docs = await self.retrieve(request.messages[-1].text())
stage.append_content(f"Found {len(docs)} documents.")
for doc in docs:
stage.add_attachment(
type="text/plain",
title=doc.title,
data=doc.content,
)

# Stage 2: Generate answer
with choice.create_stage("Generating answer") as stage:
stage.append_content("Synthesizing response from retrieved documents...")

# Final response
answer = await self.generate(docs, request.messages)
choice.append_content(answer)

response.set_usage(prompt_tokens=200, completion_tokens=150)

Further reading​

  • Choice — understand the parent object that owns a stage
  • Response — how an SDK app creates choices and reports usage
  • Custom content in Chat — see how stages appear alongside answer content