Session
Session is the main runtime context for chat and API interactions. If your handler needs to know “who is talking?”, “what happened earlier?”, or “where should I send the reply?”, the answer is usually on Session.
In hosted apps, that identity is app-scoped. Session is not telling you about some global Capsule user. It is telling you about the current user of this deployed app.
Worked example
This is the kind of session-aware flow you see in a real app:Session gives you:
- the live conversation history for the model call
- a reply target for text and structured blocks
- a way to surface background work back into the chat UI
Core fields
| Field | Meaning |
|---|---|
id | Unique session id |
user | UserInfo for the current app user |
channel | SessionChannel describing the transport |
history | Recent message history |
data | Per-session persistent key-value store |
integrations | Connected runtime credentials |
db | Scoped database proxy for collection access |
session.user comes from the app’s sign-in flow. The same email can appear in another Capsule app too, but it is still a separate app user in that other app’s context.
Common methods
| Method | Purpose |
|---|---|
await reply(text) | Send a complete response |
await notify(text) | Send a lightweight status update |
await stream(chunks) | Pipe an async iterator of strings |
stream_reply() | Open a streaming reply context manager |
await stream_reply_from(stream) | Pipe a model stream and return the final text |
chat_messages(current, cls=None) | Build merged user/assistant chat history |
await show(block) | Render a structured block |
await show_task(handle_or_id, message=None) | Show a live task card |
await show_integration(type, reason="") | Show a non-blocking integration card |
await show_image(source, alt="", width=None) | Render an image inline |
await prompt_file(...) | Block until the user uploads a file |
await prompt_integration(...) | Block until the user connects an integration |
session.chat_messages(msg) is useful because it already merges Capsule history into the alternating user / assistant format most LLM APIs expect.
Streaming helpers
stream_reply()
stream_reply_from(stream)
async with session.stream_reply() loop over and over.
Structured UI helpers
TheSession object is also how chat handlers render richer UI.
show_task(...)
show_integration(...)
prompt_file(...)
RequestContext
Use RequestContext in @app.data() and @app.endpoint() handlers when you need caller metadata outside chat.
Fields
| Field | Meaning |
|---|---|
user | UserInfo for the caller as an app user |
integrations | Connected integrations available to the caller |
authenticated | Boolean auth state |
request | Underlying request object when available |
RequestContext is the right abstraction. If a chat turn needs to know who is calling it, you already have Session.
Messages and attachments
Message
| Field | Meaning |
|---|---|
text | Message body |
sender | "user" or "app" |
channel_type | Transport type |
timestamp | Unix epoch seconds |
attachments | Optional list of Attachment |
Attachment
Attachment represents a file attached to a user message.
Useful fields:
namecontent_typeurlsize
await attachment.download(path) to save it locally.
Blocks and uploads
Block
Block(type, payload) is the low-level structured UI primitive used by helpers like show_task() and show_integration().
If you are writing normal app code, prefer the higher-level helpers first. Reach for raw Block(...) only when you need a custom block type.
FileUpload
Returned by prompt_file(...).
Useful fields:
namecontent_typeurlsizepathwhen auto-downloaded
await upload.download(path) if you want to save it manually.
Identity types
UserInfo
Common fields:
idemailorg_idowner_idproperty for owner-scoped runtime identity
SessionChannel
Describes the transport, such as chat or Telegram.
Exceptions
These are part of the public session-facing API:IntegrationTimeoutIntegrationDeclinedFileUploadTimeout
current_session()
Session when one exists. In scheduled handlers and some background contexts, this may be a synthetic session with identity and integrations but no live reply target.
Example: