Skip to content

Stamp the session's opening user prompt as input.value on the trace - #9

Merged
UsamaAnser1518 merged 2 commits into
masterfrom
usama/trace-detail-upgrade
Aug 18, 2026
Merged

UsamaAnser1518 merged 2 commits into
masterfrom
usama/trace-detail-upgrade

Conversation

@UsamaAnser1518

Copy link
Copy Markdown
Contributor

Summary

The trace plugin now stamps input.value on the session root span with the session's first user prompt. The PromptLayer trace page reads that first for the trace-level Input, so Claude Code sessions show what the user asked instead of an empty headline (the session root is typed WORKFLOW, which has no request-log fallback for Input).

Changes

  • state.py: new session_input field on SessionState (backward-compatible — from_dict defaults missing fields to "", so existing on-disk sessions load fine).
  • stop_parser.py: session_input_from_parsed() — first user message from the parsed turn's gen_ai.prompt.* history (clipped to 4000 chars); session_input_attrs(); build_stop_hook_span_specs accepts session_input and stamps the root spec.
  • handlers.py: the Stop hook records the first prompt into state (later turns never replace it) and stamps the per-turn root re-emit; SessionEnd stamps the final root. Both emits carry it because the backend upserts by span id — last write wins.
  • scripts/e2e_smoke.py: asserts the session root's input.value contains the run's prompt (new _string_attribute helper + session_root_input metric, gates the exit code). Also fixes a pre-existing rot: the hardcoded claude-3-haiku-20240307 no longer exists on the API (not_found_error), so make smoke was already failing on master; the model is now PL_SMOKE_MODEL (default claude-haiku-4-5).

Test Plan

  • make test — manifest validation, shellcheck, 25 pytest (5 new: helper extraction from the real transcript fixture, root-only stamping, no stamp without a prompt, and end-to-end Stop → state → SessionEnd), fixture replay
  • make smoke — real Claude Code session via the Agent SDK against the local OTLP collector; session_root_input = the run's prompt, graph_errors: []
  • Real session exported to a local PromptLayer backend: root Claude Code session carries input.value; trace headline shows Input via root stamp, Output via the LLM call's request log

Follow-up

Re-vendor into python-sdk (vendor_metadata.json sha) and js-sdk (npm run vendor:claude-agents) once merged; both pin this repo by commit.

@UsamaAnser1518
UsamaAnser1518 merged commit 5940192 into master Aug 18, 2026
2 checks passed
@UsamaAnser1518
UsamaAnser1518 deleted the usama/trace-detail-upgrade branch August 18, 2026 16:59
UsamaAnser1518 added a commit that referenced this pull request Aug 19, 2026
…race ids (#11)

## Why
`handle_stop_hook` releases the session lock to parse the transcript,
then re-acquires it and reloaded `state` from disk to persist
`session_input` (added in #9). If `SessionEnd` ran in that unlocked
window it had already emitted the final root and **deleted the session
file**, so the reload returned a blank `SessionState`: the turn's spans
went out with empty ids ->`build_span` generated a fresh random trace id
**per span**, every span became a root, and the deleted session file was
recreated with empty ids.


## What
- `handlers.py`: keep the in-memory `state` (and its trace/span ids)
authoritative for the turn's spans; set `session_input` in memory and
persist through a **separate** loaded object, only if the session file
still exists; never recreate a removed file.
- `tests/test_handlers.py`: regression test that runs `SessionEnd`
inside the parse window and asserts all Stop spans stay on the session
trace (exactly one root), the stamp is present, and the file stays
deleted. Fails on master, passes here.
- Version 1.1.1 → 1.1.2.

## Verified
`make test` (validate + lint + 27 tests + fixture replay) and `make
smoke` (real session, in-process collector) green; live sessions through
both SDKs' vendored copies land as single traces with all children
linked to the root.

Follow-up: re-vendor into python-sdk (#354) and js-sdk (#202) once this
merges.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants