Models and unions¶
Responses are pydantic v2 models, defined in opencode.types. Attributes are
snake_case; the wire names stay available as aliases, so a model validates server JSON and serializes back to it
unchanged.
from opencode.types import ModelRef
session = client.session.create(model=ModelRef(id="claude-sonnet-5-5", provider_id="anthropic"))
session.project_id # (1)!
session.to_dict() # (2)!
session.to_json(indent=2)
- Attribute access in
snake_case. {"id": "...", "projectID": "...", ...}: wire names, unset fields left out.
Requests accept either model instances or plain dicts with wire names.
Discriminated unions¶
Unions are discriminated on their type field, so isinstance and match narrow them, and type checkers follow:
from opencode.types import SessionMessageAssistant, SessionMessageUser
for message in client.message.list(session.id):
match message:
case SessionMessageUser(text=text):
print("user:", text)
case SessionMessageAssistant():
print("assistant replied")
case _:
pass # (1)!
- Always keep a fallback arm: it also catches variants added by newer servers.
Forward compatibility¶
A client generated from an older contract keeps working against a newer server:
- New fields are kept on the model and available as attributes and through
model_extra. - New enum values are accepted as plain strings.
- New union variants are parsed into an
Unknown...fallback model with all their fields, rather than failing. - New event types arrive as
UnknownEvent.
Validation errors on a response are raised as APIResponseValidationError, and report field locations and reasons
without values.