Skip to content

Type the agent NDJSON events and HF /splits parsing with Pydantic#157

Merged
alexkroman merged 2 commits into
mainfrom
claude/pydantic-usage-optimization-zykcz0
Jun 13, 2026
Merged

Type the agent NDJSON events and HF /splits parsing with Pydantic#157
alexkroman merged 2 commits into
mainfrom
claude/pydantic-usage-optimization-zykcz0

Conversation

@alexkroman

Copy link
Copy Markdown
Collaborator

Two stringly-typed boundaries now carry typed models, following the
auth/flow.py + account.py precedent:

  • agent/events.py: the assembly agent --json event stream was hand-built
    {"type": …} dicts the type checker only saw as dict[str, str]. Each
    event is now a closed, frozen Pydantic model whose type literal and payload
    are pinned at type-check time, so a renamed key or mistyped type can't drift
    onto the wire. AgentRenderer emits via model_dump(); the wire shapes are
    byte-identical (existing render goldens unchanged).

  • evaluate/_hf_api.py: split_entries() returned bare dicts and subset/split
    selection read str(entry.get("config")). A _SplitEntry model (validated
    via a module-level TypeAdapter) gives pick_subset/pick_split typed fields
    and turns a malformed /splits payload into a clean APIError instead of a
    stringified "None".

https://claude.ai/code/session_01AzkXsmPQSoUJjPgJY6qvGB

claude added 2 commits June 13, 2026 20:30
Two stringly-typed boundaries now carry typed models, following the
auth/flow.py + account.py precedent:

- agent/events.py: the `assembly agent --json` event stream was hand-built
  `{"type": …}` dicts the type checker only saw as `dict[str, str]`. Each
  event is now a closed, frozen Pydantic model whose `type` literal and payload
  are pinned at type-check time, so a renamed key or mistyped `type` can't drift
  onto the wire. AgentRenderer emits via `model_dump()`; the wire shapes are
  byte-identical (existing render goldens unchanged).

- evaluate/_hf_api.py: `split_entries()` returned bare dicts and subset/split
  selection read `str(entry.get("config"))`. A `_SplitEntry` model (validated
  via a module-level TypeAdapter) gives `pick_subset`/`pick_split` typed fields
  and turns a malformed /splits payload into a clean APIError instead of a
  stringified "None".

https://claude.ai/code/session_01AzkXsmPQSoUJjPgJY6qvGB
Extends the agent-events pattern to `assembly stream --json`. The begin/turn/
termination records were hand-built dicts assembled with `jsonshape.compact` +
`_with_source`; each is now a closed, frozen Pydantic model whose `type` literal
and payload are pinned at type-check time.

The two presence rules are preserved in a shared `wire()`: the optional
annotations `source` (parallel system/you streams) and `speaker`
(--speaker-labels diarization) drop out of the record when absent, while the
core payload (`id`, `audio_duration_seconds`) stays present even when null. The
`id` field is `session_id` in Python with a serialization_alias so the model
stays self-contained (no flake8-builtins A003 carve-out). Wire output is
byte-identical; the existing render goldens are unchanged.

https://claude.ai/code/session_01AzkXsmPQSoUJjPgJY6qvGB
@alexkroman alexkroman enabled auto-merge June 13, 2026 20:44
@alexkroman alexkroman added this pull request to the merge queue Jun 13, 2026
Merged via the queue into main with commit fd862da Jun 13, 2026
16 checks passed
@alexkroman alexkroman deleted the claude/pydantic-usage-optimization-zykcz0 branch June 13, 2026 20:51
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