Skip to content

Commit ea20121

Browse files
committed
fix: latch is_sidechain independently of created_at; update list_sessions_from_store docstring
1 parent 2a16b47 commit ea20121

3 files changed

Lines changed: 23 additions & 8 deletions

File tree

src/claude_agent_sdk/_internal/session_summary.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ def fold_session_summary(
140140
if ms is not None and ms > summary["mtime"]:
141141
summary["mtime"] = ms
142142

143-
if "created_at" not in summary:
144-
if ms is not None:
145-
summary["created_at"] = ms
143+
if "is_sidechain" not in summary:
146144
summary["is_sidechain"] = entry.get("isSidechain") is True
145+
if "created_at" not in summary and ms is not None:
146+
summary["created_at"] = ms
147147

148148
if "cwd" not in summary:
149149
cwd = entry.get("cwd")

src/claude_agent_sdk/_internal/sessions.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,11 +1548,11 @@ async def list_sessions_from_store(
15481548
the store path — the store operates on a single ``project_key``.
15491549
15501550
.. note::
1551-
This performs one full ``store.load()`` per session in the listing
1552-
to derive summaries. On remote backends with many or large sessions
1553-
this can be expensive (e.g., S3 egress, Postgres large-row reads).
1554-
Consider denormalizing summary metadata into your adapter's
1555-
``list_sessions()`` index.
1551+
If the store implements ``list_session_summaries``, this is a single
1552+
store call. Otherwise falls back to one ``store.load()`` per session
1553+
(bounded at 16 concurrent), which on remote backends with many or
1554+
large sessions can be expensive (e.g., S3 egress, Postgres large-row
1555+
reads).
15561556
"""
15571557
project_path = _canonicalize_path(str(directory) if directory is not None else ".")
15581558
project_key = _sanitize_path(project_path)

tests/test_session_summary.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ def test_sidechain_from_first_entry(self) -> None:
153153
)
154154
assert s["is_sidechain"] is True
155155

156+
def test_sidechain_latched_when_first_entry_lacks_timestamp(self) -> None:
157+
"""Regression: is_sidechain must latch on entry 0 even if its timestamp
158+
is absent/unparseable, so entry 1 cannot overwrite it to False."""
159+
s = fold_session_summary(
160+
None,
161+
KEY,
162+
[
163+
{"type": "user", "isSidechain": True},
164+
{"type": "x", "timestamp": "2024-01-01T00:00:00Z"},
165+
],
166+
)
167+
assert s["is_sidechain"] is True
168+
# created_at still picks up the first parseable timestamp.
169+
assert s["created_at"] == 1704067200000
170+
156171
def test_first_prompt_skips_meta_tool_result_and_compact(self) -> None:
157172
s = fold_session_summary(
158173
None,

0 commit comments

Comments
 (0)