Intermediate case
Level: Intermediate — your data / a real job, less guided. Time: 45–60 min.
Context#
A rail beside your own pages is the shape copilot_rail() is built for: examples/backlog_desk/ (file/JSON-backed, no SQL) and examples/bi_to_semantic/ (Tableau/Power BI → semantic view) both wire it into an existing multipage app rather than replacing the app with a chat window. This case asks you to do the same against a real workflow, with checkpoints instead of click-by-click instructions.
Goal#
Configure a CocoOptions with require_approval_for for a workflow that actually mutates something, and embed copilot_rail() as a right column next to an existing (or the bundled) multipage app.
Data#
Yours, or a stand-in. If you have a multipage Streamlit app you already run, use it. If not, use examples/backlog_desk/ as the stand-in "your data": file-backed tickets, epics, and releases under examples/backlog_desk/data/{epics,tickets,releases,policies} — real files you can inspect with git diff after CoCo edits them. examples/bi_samples/ (MIT-licensed Tableau/Power BI fixture packs) is the alternative stand-in if you would rather follow the BI → Semantic shape.
Checkpoints#
- Pick your surface. Identify one page in your app (or
examples/backlog_desk/'s Ticket page) where a mutating action currently has no human-in-the-loop safeguard, or where you want an agent to draft something a person reviews before it lands. - Define
CocoOptionsfor that workflow. Separate the tools that canrun unattended (read-only exploration:
Read,Glob,Grep) from the tools that must pause (Edit,Write,Bash, andSQLif your workflow touches Snowflake). Put the first set inallowed_toolsand the second inrequire_approval_for— they should not overlap for the same tool. *Checkpoint: you can state, for each tool your workflow could invoke, which list it belongs in and why.* - Scope one session to the page. Use `get_or_create_session(opts,
key=...)` with a key specific to this workflow, and decide when it should reset —
copilot_rail()does not reset itself on acwdor schema change; the caller owns that lifecycle decision. *Checkpoint: you know exactly which user action should triggerreset_session(...).* - Wire
copilot_rail()in. Add it as the right column of your layout,following the
examples/backlog_desk/pattern (opened from a header button, closed with Close) or theexamples/bi_to_semantic/pattern (a connection popover next to the rail). Referencedoc/features/copilot-rail/copilot-rail.mdin the repo for the full parameter list (job=,on_job_sent=,on_job_finished=,example_questions=,toml_file=). *Checkpoint: the rail opens and closes without rerunning the rest of your page.* - Queue a real job and watch it get gated. Trigger the mutating action
from your page (a
status="queued"job, or a direct chat prompt) and confirmrequire_approval_forpauses it with Approve once / **Always allow / Deny**, not with a silent write. *Checkpoint: you can point at the exact line in yourCocoOptionsthat caused the pause.* - Keep the transcript usable. Open the rail's Display config popover
(
:material/display_settings:) and adjust Last messages / **First n characters** so a long session stays readable in the rail's width.
Expected result#
- Copilot sits in a right column beside your existing page content — the
page itself is never replaced by a full-screen chat.
- The mutating action you picked in step 1 now pauses for an explicit
Approve/Deny decision before it runs.
- You can explain, without re-reading the code, why each tool in your
workflow is either auto-run or approval-gated.
Where to look if stuck#
- Approval gate not firing, or firing for the wrong tool:
- Approval banner sitting unanswered until it times out:
- Something in the workflow behaves unexpectedly and the tool cards alone
do not explain why: enable
STREAMLIT_COCO_DEBUG=1and re-run — seehelp.html#debug-mode-not-showing-payloadsif the raw payload still does not appear.