Skip to content

cursor_sdk: capture summary (context summarization) messages (1.2.0+) #1044

Closed

Description

Summary

cursor-sdk 1.2.0 adds a summary stream message (SDKSummaryMessage) and the related interaction updates (SummaryStartedUpdate, SummaryUpdate, SummaryCompletedUpdate). Our event dispatcher silently drops them. They look like Cursor's context summarization (compaction) step, which is useful to see in a trace: it explains token-usage drops, and a failed or fallback summary explains degraded answers.

Found while reviewing the weekly dependency bump in #1037 (cursor-sdk 1.0.40 → 1.2.0). Low priority. Confirm the semantics with Cursor's docs or changelog before building on this.

Upstream types (cursor-sdk 1.2.0, cursor_sdk/types.py)

@dataclass(frozen=True)
class SDKSummaryMessage:          # run stream message, type == "summary"
    type: Literal["summary"]
    agent_id: str
    run_id: str
    status: Literal["running", "completed", "error"] | str
    fallback: bool = False

# interaction updates
class SummaryStartedUpdate:   type: Literal["summary-started"]
class SummaryUpdate:          type: Literal["summary"]; summary: str
class SummaryCompletedUpdate: type: Literal["summary-completed"]; failed: bool = False; fallback: bool = False

The stream message carries only status / fallback. The summary text arrives only on the SummaryUpdate interaction update.

Our code

  • Dispatcher: CursorRunTracker.add_event switches on event.sdk_message.type for thinking, assistant, tool_call and usage. Every other type, including summary, is ignored.
  • Interaction updates: not consumed at all, so SummaryUpdate.summary is unreachable today.

Related 1.2.0 change (already safe)

TokenUsage.total_tokens no longer includes cache read/write tokens. We don't depend on it, because _usage_metrics computes its own totals. A regression test would still be cheap.

Suggested approach

  1. Get a real recording that contains a summary. The current latest cassettes (re-recorded in chore(deps): weekly dependency update #1037) have none. A long multi-turn agent run may trigger one. Cursor tests use the bridge VCR scrubber in _test_vcr.py.
  2. Decide the shape. Options:
    • a span event or metadata on the run span (summary_status, summary_fallback, summary_failed);
    • a small child span for the summarization step, if there's timing and text worth showing.
  3. Handle summary in add_event, and gate on the type existing: the 1.0.25 matrix pin doesn't emit it.
  4. Run cd py && nox -s "test_cursor_sdk(latest)" and "test_cursor_sdk(1.0.25)".

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions