feat(agent-sdk): add session browser cookbook#480
Conversation
Adds notebook 05 covering the session management primitives that shipped in claude-agent-sdk v0.1.51 (list_sessions, get_session_info, get_session_messages, rename_session, tag_session, fork_session, delete_session). The cookbook walks through building a session browser: generating demo sessions, listing them with pagination, reading messages back, organizing with titles and tags, and forking into a live query() call. This is the sidebar pattern from Claude Code Desktop and the VS Code extension. Also bumps the agent_sdk pyproject pin to >=0.1.51 so the functions are available in the tutorial kernel.
Notebook ChangesThis PR modifies the following notebooks: 📓
|
There was a problem hiding this comment.
PR Review
Recommendation: COMMENT
Summary
This notebook is a well-structured, clear walkthrough of the Agent SDK session management API, covering all key primitives (list, inspect, rename, tag, fork, resume, delete). The writing quality is high and the four-part structure maps cleanly to the stated learning objectives.
Actionable Feedback (4 items)
-
05_Building_a_session_browser.ipynb(all cells) — Notebook was not executed before submission; all cells have empty outputs and null execution counts. Per the project guidelines, outputs must be kept in notebooks as demonstration artifacts. Please run the notebook end-to-end and commit with outputs. -
05_Building_a_session_browser.ipynb(in cell withasync def run_one_turn) — Replaceassert session_id is not Nonewith an explicit check:if session_id is None: raise RuntimeError("No ResultMessage received; check SDK version >=0.1.51 and API key.").assertgives no diagnostic information on failure and is stripped with -O. -
05_Building_a_session_browser.ipynb(in cell withdef visible_sessions) — Add a return type annotation (-> list). Therun_one_turnhelper has-> str; consistency is worth maintaining. -
05_Building_a_session_browser.ipynb(markdown cell "Build the session list") —SDKSessionInfois described by name in prose but never imported. Add it to the relevant import cell so readers have a copy-pasteable example.
Detailed Review
Code Quality
Code is clean and idiomatic. The visible_sessions helper is a good pattern to expose (soft-delete via __hidden tag). Imports are scattered one-per-section, which keeps cell outputs focused but differs from the other notebooks in this series that aggregate imports in the setup cell.
The DEMO_DIR = str(Path("session_browser_demo").resolve()) resolves relative to the kernel cwd at execution time. This works in the expected Jupyter environment but can point to an unexpected location under nbconvert --execute from the repo root. A comment like # Assumes kernel cwd is the claude_agent_sdk/ directory would surface the assumption.
The pagination and up_to_message_id examples are shown only in markdown code fences, never as live cells. Even a minimal live example (e.g., getting a UUID from get_session_messages()[0].uuid) would make the feature tangible for readers.
Security
No concerns. API key is loaded via dotenv, no secrets are hardcoded.
Suggestions
- Convert the inline pagination snippet (
page_2 = list_sessions(...)) from a markdown fence to a live cell; with only 3 demo sessions the result (empty list) is itself instructive. **Required Knowledge**in the prerequisites cell is missing the colon present in the template style.
Positive Notes
- Introduction leads with the user problem ("the sidebar users ask for first"), not the API surface — exactly right for a cookbook.
- Haiku model choice for demo sessions is explicitly justified (token cost), which models good habits for readers.
- The cleanup cell (hard delete) paired with the earlier soft-delete pattern gives readers both options with a clear rationale for each.
- "Where to go next" section is thorough: covers UI wiring, cross-host patterns, and the TypeScript equivalent with correct camelCase names.
Notebook ChangesThis PR modifies the following notebooks: 📓
|
There was a problem hiding this comment.
PR Review
Recommendation: COMMENT
Summary
Adds a well-structured session browser cookbook (notebook 05) demonstrating Agent SDK session management primitives: list, inspect, rename, tag, fork, and delete sessions. The narrative framing is strong and follows project conventions closely.
Actionable Feedback (4 items)
-
05_Building_a_session_browser.ipynb(cleanup cell withfor s in list_sessions(...)) — Snapshot the list before iterating to avoid potential mutation-during-iteration issues:sessions_to_delete = list_sessions(directory=DEMO_DIR)then iterate over that. Teaches a safer pattern that readers will copy. -
05_Building_a_session_browser.ipynb(cell withdef visible_sessions(...)) —SDKSessionInfois used in the function's return type annotation but is only imported in an earlier cell. Addfrom claude_agent_sdk import SDKSessionInfo, tag_sessionto this cell so it's self-contained and won't raiseNameErrorif run standalone. -
session_browser_demo/.gitkeep— Convention is that.gitkeepfiles are empty (their only purpose is to force git to track an empty directory). The comment# Session browser demo workspaceshould be removed; use an empty file or aREADME.mdif a note is needed. -
05_Building_a_session_browser.ipynb(list-sessions cell withdatetime.fromtimestamp(s.last_modified / 1000)) —fromtimestamp()returns a naive local-time datetime. Add a# local timecomment or usedatetime.fromtimestamp(..., tz=timezone.utc)to avoid reader confusion across timezones.
Detailed Review
Code Quality
The notebook follows project conventions well. %%capture is used correctly for pip installation, load_dotenv() is used for API key access, MODEL is defined as a top-level constant, and the structure flows logically from setup → create → list → organize → fork → cleanup. The visible_sessions helper demonstrating soft-delete via __hidden tag is a good real-world pattern worth keeping.
Security
No concerns. API key is loaded via dotenv, no hardcoded credentials, and DEMO_DIR uses an isolated subdirectory to avoid interfering with real sessions.
Suggestions
The markdown comment explaining cwd path resolution ("Note: this path resolves relative to the kernel's working directory") is buried in a code comment. Surfacing it in the adjacent markdown cell would help readers who skim prose but skip code comments.
Positive Notes
- Strong narrative hook — opens with the user problem ("the sidebar") rather than the API machinery.
pyproject.tomlbump is well-justified: the markdown explains why>=0.1.51is needed.- Cleanup cell demonstrates
delete_sessionclearly and explains the soft-delete alternative. - "Where to go next" section includes a TypeScript callout and links to both related notebooks and docs — genuinely useful.
- Model choice (
claude-haiku-4-5) is correct per CLAUDE.md and the reasoning (cheap demo sessions) is explained.
There was a problem hiding this comment.
PR Review
Recommendation: COMMENT
Summary
Adds a well-crafted session browser cookbook (notebook 05) covering all the major Agent SDK session-management primitives — list, inspect, rename, tag, fork, and resume. The code is idiomatic, the narrative is clear, and all project conventions are followed correctly.
Actionable Feedback (3 items)
-
claude_agent_sdk/session_browser_demo/.gitkeep— Remove the comment line (# Session browser demo workspace). A.gitkeepfile should be zero bytes; the convention is broken by adding content, and some tooling checks for empty files to determine if a directory is "pristine". The directory's purpose is already communicated by its name and the notebook prose. -
05_Building_a_session_browser.ipynb(setup cell withDEMO_DIR = str(Path("session_browser_demo").resolve())) — The comment already acknowledges this is fragile, but it will silently break for most users who open the notebook from the repo root (e.g., from VS Code or JupyterLab), resolving to<repo-root>/session_browser_demo/instead of<repo-root>/claude_agent_sdk/session_browser_demo/. Consider usingPath(__file__).resolve().parent / "session_browser_demo"(works in script mode), or for notebooks a__vsc_ipynb_file__-based fallback. At minimum, add a visible warning cell prompting the user to verify the printed path before running further cells. -
05_Building_a_session_browser.ipynb(Part headings using#) — "Part 1/2/3/4" headings use#(H1), the same level as the notebook title. Move them to##and their sub-sections to###to produce a correct document hierarchy in JupyterBook/nbconvert output.
Detailed Review
Code Quality
The code is clean, idiomatic, and follows all project conventions: non-dated model alias (claude-haiku-4-5), load_dotenv() + os.environ for the API key, %%capture on the install cell, and a raise RuntimeError instead of silently returning None when no result arrives. The visible_sessions soft-delete helper is a genuinely useful real-world pattern. The cleanup cell at the end is a thoughtful addition that keeps the demo re-runnable.
Security
No concerns. No hardcoded keys; authentication follows the correct dotenv pattern throughout.
Suggestions
- The timestamp division
/ 1000(milliseconds → seconds) is correct but unexplained. A brief inline comment (# SDK timestamps are Unix milliseconds) would help readers who inspect the raw JSONL. run_one_turnsilently discards non-ResultMessagetypes. A one-line comment noting this is intentional would reduce reader confusion.- The Recap section summarises function signatures more than it closes the loop on the four TLOs stated in the introduction. Restating the TLOs as accomplished outcomes ("You can now list sessions… fork and resume from any point…") would strengthen the conclusion.
- The
pyproject.tomlbump from>=0.0.20to>=0.1.51is a breaking change for environments pinned to older versions. Worth a brief comment noting the constraint is driven by the session-management APIs added in 0.1.51.
Positive Notes
- Excellent opening paragraph — "the first thing users ask for is the sidebar" immediately grounds the notebook in a real product scenario.
- The fork → resume round-trip section is the clearest demonstration of this pattern I've seen in the series.
authors.yamlandregistry.yamlentries are complete and well-formed.- The notebook progresses logically from generating test data → reading → organizing → branching → cleanup, making it easy to follow even without running cells.
Notebook ChangesThis PR modifies the following notebooks: 📓
|
There was a problem hiding this comment.
PR Review
Recommendation: COMMENT
Summary
This PR adds a well-structured session browser cookbook for the Claude Agent SDK, demonstrating list_sessions, get_session_messages, rename_session, tag_session, fork_session, and delete_session. The notebook is pedagogically coherent and follows project standards (correct model ID, dotenv pattern, outputs committed).
Actionable Feedback (4 items)
-
05_Building_a_session_browser.ipynb(in cell withfor m in messages:) — The output shows blank lines for both the user turn and first assistant turn. The text extraction only handles{"type": "text", ...}dicts, but the user message content is likely a plain string, not a list of content blocks. Either guard againstisinstance(content, str)or add a markdown note explaining why the user-turn line is blank, so readers aren't confused. -
05_Building_a_session_browser.ipynb(in cell withDEMO_DIR = str(Path("session_browser_demo").resolve())) — This path resolves relative to the kernel's cwd. If a reader launches Jupyter from the repo root (the common default), it resolves to the wrong location. The inline comment warns about this, but a more prominent callout in the Prerequisites section — e.g. "you must launch Jupyter from theclaude_agent_sdk/directory" — would prevent silent failures. -
05_Building_a_session_browser.ipynb(in cell withdef visible_sessions(...)) — The function unconditionally filters out__hiddensessions before checkingtag_filter. Passingtag_filter="__hidden"(e.g. to build a "trash/recover" view) always returns an empty list. The prose says "the data stays recoverable" but the helper as written makes recovery impossible through the same function. Either fix the guard order or document this limitation. -
05_Building_a_session_browser.ipynb— Verify that the twodocs.claude.comlinks in the "Where to go next" section resolve:https://docs.claude.com/en/agent-sdk/local-session-managementandhttps://docs.claude.com/en/agent-sdk/typescript. These appear to be forward-references to new docs pages; broken links in a published cookbook are a common trust issue.
Detailed Review
Code Quality
Overall high quality. Model ID (claude-haiku-4-5) is correct per project standards. %%capture on pip install, dotenv.load_dotenv(), and imports are all idiomatic. The run_one_turn function correctly raises RuntimeError if no ResultMessage arrives rather than silently returning None. The visible_sessions return type annotation (-> list[SDKSessionInfo]) and the str | None parameter type are good modern Python.
Security
No issues. No hardcoded API keys; keys are loaded via dotenv. No subprocess injection risks.
Suggestions
- The sequential
for p in prompts: await run_one_turn(p)loop could use a comment noting it's intentionally sequential (vs.asyncio.gather) to keep printed output in order. - The fork-resume cell doesn't guard against a missing
ResultMessagethe wayrun_one_turndoes — a small inconsistency. - The
datetime.fromtimestamp(s.last_modified / 1000)pattern (milliseconds → seconds) appears twice without explanation; a brief inline comment# SDK timestamps are millisecondson the first occurrence would help readers.
Positive Notes
- Notebook structure maps cleanly to its stated learning objectives. Each Part has a concrete action goal, and the Recap section ties back to every bullet in the intro.
- The
delete_session()section correctly frames hard-delete vs. soft-delete (__hiddentag) as a UX tradeoff, which is good advice for anyone building a real product on this. - Committed outputs confirm the notebook runs end-to-end.
pyproject.tomlSDK pin bump (>=0.0.20→>=0.1.51) is correctly scoped to theclaude_agent_sdk/subdirectory.
Notebook ChangesThis PR modifies the following notebooks: 📓
|
There was a problem hiding this comment.
PR Review - Recommendation: APPROVE with minor suggestions. Summary: This notebook covers the Agent SDK session management API through a coherent end-to-end demo. Well-structured, idiomatic Python, good pedagogical flow. No critical issues. Actionable feedback: (1) Notebook has empty outputs - per repo rules execute top-to-bottom and commit outputs as done in commit 565110a. (2) pyproject.toml requires-python is >=3.11,<3.13 but notebook metadata shows Python 3.13.12 - either widen to <3.14 or align the kernel metadata. (3) session_browser_demo/.gitkeep has a comment line; convention is empty file. (4) Prerequisites list the Claude Code CLI as required but no notebook cell uses it directly - clarify if truly required or downgrade to Recommended. Code quality is solid: run_one_turn correctly raises on missing ResultMessage, visible_sessions soft-delete pattern is a great teaching point, isinstance guard in get_session_messages is defensive and correct. MODEL=claude-haiku-4-5 uses correct non-dated alias. SDK version bump to >=0.1.51 is correctly a minimum not a pin. Prose is consistently strong throughout.
a8c50fb to
67874c1
Compare
Notebook ChangesThis PR modifies the following notebooks: 📓
|
There was a problem hiding this comment.
PR Review
Recommendation: COMMENT
Summary
Adds a well-structured session browser cookbook (Notebook 05) covering the seven Agent SDK session management primitives. The prose is clear, the four-part structure is logical, and prior review feedback has already been incorporated.
Actionable Feedback (5 items)
-
05_Building_a_session_browser.ipynb(in cell withfor s in list_sessions(directory=DEMO_DIR): delete_session(...)) — Iteration-during-deletion bug: collect sessions into a list first to avoid skipping files. Fix:sessions_to_delete = list(list_sessions(directory=DEMO_DIR))then iterate over that. -
05_Building_a_session_browser.ipynb(in cell withdatetime.fromtimestamp(s.last_modified / 1000)) — Uses timezone-naivedatetime.fromtimestamp(). Preferdatetime.fromtimestamp(..., tz=timezone.utc)— readers will copy this into real products. -
05_Building_a_session_browser.ipynb(in cells with# Part 1:,# Part 2:headings) — Part headings use#(H1), same level as the notebook title. Consider##for parts and###for subsections to establish a clear hierarchy. -
session_browser_demo/.gitkeep— Contains a comment (# Session browser demo workspace) rather than being empty. Conventional.gitkeepfiles are empty. - General: Add a link to the Python session management API reference in "Where to go next" —
up_to_message_idis mentioned inline but never linked, leaving readers without a path to the full parameter details.
Detailed Review
Code Quality
The code is clean and idiomatic. The run_one_turn helper, visible_sessions filter, and fork-then-resume pattern are all good teaching examples. The follow-up commit already addressed the prior review's assert → raise RuntimeError, return type annotation, and SDKSessionInfo import placement — all meaningful improvements.
One remaining bug: the cleanup cell iterates over list_sessions() while calling delete_session() in the same loop. Whether list_sessions() returns an eagerly-evaluated list or a lazy iterator, mutating the directory mid-scan is undefined behavior and may silently skip sessions. Collecting IDs first (sessions_to_delete = list(list_sessions(...))) is the safe fix and sets the right mental model for readers who will copy this pattern.
Security
No issues. load_dotenv() is used correctly, no secrets are hardcoded, and %%capture hides pip noise without suppressing errors.
Suggestions
pandasis imported for a singlepd.DataFrame(rows)display. A brief comment noting it's only for the tabular UI mock would help readers adapting this to production (where they may not want the dependency).- The
forkreturn value type (SDKSessionInfo) is never named in prose. The sentence before Cell 11 could add "fork.session_idis the identifier you pass toresume" to close the loop without requiring readers to inspect the SDK source.
Positive Notes
- Introduction leads with the user problem ("the first thing users ask for is the sidebar") rather than the API surface — exactly the right framing for a cookbook.
MODEL = "claude-haiku-4-5"uses the non-dated alias per project conventions.pyproject.tomlversion bump to>=0.1.51is consistent with the pip install cell, preventing kernel/environment skew.- Soft-delete via
__hiddentag is taught before hard-delete, which is the correct pedagogical order. up_to_message_idis mentioned in prose without a demo cell — the right call for scope control while still surfacing the full API.- Conventional commit format with a substantive body explaining the version bump.
What
Adds notebook 05 to the Agent SDK cookbook series, covering the session management primitives that shipped in
claude-agent-sdkv0.1.51:list_sessions,get_session_info,get_session_messages,rename_session,tag_session,fork_session,delete_session.The cookbook walks through building a session browser — the sidebar pattern from Claude Code Desktop and the VS Code extension:
query()calls withcwdscoped to an isolated demo dir (Haiku, single-turn, no tools, to keep token spend minimal)list_sessions()rendered as a pandas table,get_session_info()for single lookup,get_session_messages()with content-block extractionrename_session(),tag_session(), soft-delete via__hiddentag + a filter helperfork_session()then continue the fork withquery(options=ClaudeAgentOptions(resume=fork.session_id))delete_session()over everything the demo createdWhy
Companion cookbook to session management docs page. The docs page is reference material; this is the hands-on recipe.
Also in this PR
registry.yaml— cookbook entry (category: Claude Agent SDK)authors.yaml— addedqing-antclaude_agent_sdk/pyproject.toml— bumped SDK pin from>=0.0.20to>=0.1.51so the session functions are available in the tutorial kernelclaude_agent_sdk/session_browser_demo/.gitkeep— demo workspace dir forcwd=Testing
ruff check/ruff formatpassverify_registry.pypasses (schema + GitHub handle validation)