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.
| Status | When to use |
|---|---|
Status.COMPLETED | The step finished successfully (default). |
Status.FAILED | The 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