ADR-003: Literal Types to str Enums (StepType, ModelType)¶
Status: Accepted Date: 2026-03-15 Deciders: Core maintainers
Context¶
StepType (14 trace step types) and ModelType (5 model categories) were defined as Literal type aliases:
StepType = Literal["llm_call", "tool_selection", "tool_execution", ...]
ModelType = Literal["chat", "embedding", "image", "audio", "multimodal"]
These provided type narrowing at check time but no runtime safety. A typo like type="llm_cal" would pass mypy (assignable to str) and fail silently at runtime — the trace step would be created with the wrong type, and trace.filter(type="llm_call") would miss it.
With v0.17.0 (multi-agent orchestration) adding 4+ new step types, the risk of typo-introduced bugs was increasing.
Decision¶
Replace both with class StepType(str, Enum) and class ModelType(str, Enum).
Rationale¶
-
Backward compatible:
str, Enummembers compare equal to their string values.StepType.LLM_CALL == "llm_call"isTrue. Existing code using string comparisons continues to work. -
Fail-fast on typos:
StepType("llm_cal")raisesValueErrorat runtime. IDE autocompletion prevents the typo in the first place. -
Enumerable:
list(StepType)gives all valid values. Architecture fitness tests verify every member appears in at least one test and every ModelType is used in the registry. -
Hashable and serializable:
str, Enummembers work as dict keys, in sets, and serialize to JSON as their string value viadataclasses.asdict().
Consequences¶
- Positive: 30+ string literals in
core.pyreplaced with enum members. IDE autocompletion now works for step types. - Positive: 146
ModelInforecords inmodels.pynow useModelType.CHATetc., preventing invalid model type assignments. - Positive: Architecture tests automatically verify enum coverage.
- Negative: Negligible — enum member access is microscopically slower than string comparison, but trace steps are created ~10 times per agent run, not in hot loops.
- Migration: None required. All string comparisons (
step.type == "llm_call") still work. New code should use enum members (StepType.LLM_CALL).