- it remembers things across turns
- it can answer simple commands without calling a model
- it can stream output instead of waiting for one big reply
What you are building
You will build a small app that can:- remember notes in
session.data - replay recent conversation history
- stream a reply progressively
- run boot logic when the runtime starts
1. Start with an app skeleton
Createapp.py:
boot hook runs once when the runtime starts. That makes it the right place for things like model warmup, loading a local index, checking environment variables, or creating directories on disk.
2. Add a message handler
Now add the chat loop:session.data.setdefault("notes", [])creates per-session state the first time the user talks to the app.- The
remember,notes, andhistorybranches are ordinary Python control flow. You do not need an LLM for every turn. session.notify("Thinking...")is useful when the next response will take a second or two.session.stream_reply()lets you write output gradually. That is often nicer than building one large string and replying at the end.
3. Run the app locally
remember buy coffeeremember send proposalnoteshistory
session.datapersists within the conversationsession.historycontains recent messagessession.notify()emits lightweight status textsession.stream_reply()writes chunks incrementally and stores the final text in history
4. Understand the session model
Every message handler receives two objects:cpsl.Session, which is the live runtime contextcpsl.Message, which is the inbound user message
Session fields early on are:
session.idfor the conversation identifiersession.userfor the authenticated usersession.historyfor prior messagessession.datafor per-session persistent statesession.integrationsfor connected credentials
Message object carries:
msg.textfor the user textmsg.attachmentswhen the user uploaded filesmsg.channel_typeso you can branch on transport if needed
- put temporary conversational state in
session.data - put real durable records in collections
- read
session.historywhen you need context from earlier turns
5. Add command routing
A useful next cleanup is to move the branching logic into helpers so the handler stays readable:session.chat_messages(msg) is often the easiest way to turn Capsule history into alternating user and assistant messages:
6. Know when to use current_session()
Inside message handlers you already receive a live session, so pass it explicitly.
cpsl.current_session() matters when:
- a scheduled handler needs owner-scoped identity
- a background task runs without a direct
sessionargument - helper code needs to discover the active runtime context
session, prefer using it directly. current_session() is most helpful in lower-level helpers and non-message contexts.
Full example
Next steps
- Move durable data into Collections And Scopes
- Add structured UI with Data Handlers And Pages
- See Session And Request Context Reference for every session helper