Skip to content

feat(routes): GET /v1/sessions/{id}/cost_data read companion (#4)#5

Merged
rdwj merged 1 commit into
mainfrom
feat/sessions-cost-data-get
Apr 28, 2026
Merged

feat(routes): GET /v1/sessions/{id}/cost_data read companion (#4)#5
rdwj merged 1 commit into
mainfrom
feat/sessions-cost-data-get

Conversation

@rdwj
Copy link
Copy Markdown
Contributor

@rdwj rdwj commented Apr 28, 2026

Summary

  • Adds GET /v1/sessions/{session_id}/cost_data returning {"session_id": ..., "cost_data": {...}}. 404 when the session does not exist; 200 with empty cost_data when the session exists but has no PATCH writes yet.
  • Closes the HTTP-backend cumulative gap that the 0.14.1 cluster smoke surfaced — agent-side HttpSessionStore.get_cost_data previously raised NotImplementedError, so the per-turn accumulator on OpenAIChatServer had nothing cumulative to read and HTTP-backed deployments degraded to last-write-wins per top-level key.
  • Auth identical to the existing GET /v1/sessions/{id}. Uses store.exists() to distinguish missing-session from empty-cost_data (SessionStore.get_cost_data() returns {} for both).
  • Bumps to 0.2.1 + CHANGELOG entry.

Pairs with the agent-side companion at fips-agents/agent-template#TBD (will reference once opened). Older agents (<=0.14.1) never call this route — safe to ship independently.

Closes #4

Test plan

  • pytest tests/test_sessions.py — 22 passing locally (3 new: after-PATCHes merge, empty-no-writes, missing 404).
  • Full suite: 46 passing.
  • Cluster smoke once paired with fipsagents 0.14.2.

Assisted-by: Claude Code (Opus 4.7)

Closes the cumulative-cost gap that the 0.14.1 cluster smoke spotlighted.
Without a read endpoint, agent-side _persist_cost_data could only write
deltas (HttpSessionStore.get_cost_data raised NotImplementedError, so the
accumulator fell back to existing={} every turn). With the GET route in
place, the agent reads existing totals before computing the merge and
HTTP-backed deployments converge on the same cumulative semantics that
SQLite/Postgres provide natively.

Wire shape mirrors the existing /v1/sessions/{id} handler:
{"session_id": ..., "cost_data": {...}}. 404 when the session is missing;
200 with empty cost_data when the session exists but has no PATCH writes
yet. Existence is decided via store.exists() since
SessionStore.get_cost_data() returns {} for both missing-session and
empty-cost_data and the route needs to distinguish the two.

Three new pytest cases against the live ASGI app + SqliteSessionStore
(after-PATCHes merge, empty-no-writes, missing-session 404). Suite
total 43 -> 46.

Closes #4

Assisted-by: Claude Code (Opus 4.7)
@rdwj rdwj merged commit 794e244 into main Apr 28, 2026
2 checks passed
@rdwj rdwj deleted the feat/sessions-cost-data-get branch April 28, 2026 11:09
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.

feat: GET /v1/sessions/{id}/cost_data for cumulative cost-tracking via HttpSessionStore

1 participant