-
Notifications
You must be signed in to change notification settings - Fork 3.7k
refactor: Migrate message block types from interfaces/enums to Zod schemas #12867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
EurFelux
wants to merge
51
commits into
main
Choose a base branch
from
refactor/message-block-type
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,329
−983
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Replace manual type definition with Zod schema using z.lazy() - Add SerializableSchema export for runtime validation - Add assertSerializable() and tryParseSerializable() helpers - Fix error.ts to use safeSerialize() for response field - Remove FIXME comment about TS2589 recursion Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Circular references cause JSON.stringify to throw, so returning true was misleading. Now correctly returns false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Break circular dependency: file.ts → @types (index.ts) → knowledge.ts → file.ts by moving objectKeys, objectEntries, objectEntriesStrict, objectValues, strip, AtLeast, RequireSome, NotUndefined, NotNull to a dedicated typeUtils.ts module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What this PR does
Before this PR:
Message block types (
MessageBlock,ToolMessageBlock,CitationMessageBlock, etc.) were defined as plain TypeScript interfaces and enums. Model-related types (ModelPricing,ModelType,Model, etc.) used manual interface definitions. Enum values likeMessageBlockType,MessageBlockStatus, andWebSearchSourcewere TypeScript enums.After this PR:
z.infer<>MESSAGE_BLOCK_TYPE,MESSAGE_BLOCK_STATUS,WEB_SEARCH_SOURCE)Serializable,SerializedError,FileMetadata,KnowledgeReference, tool types, etc.) are also migrated to Zod schemasanytypes in metadata fields are narrowed tounknownMessageBlockis now a Zod discriminated union on thetypefieldPart of #12846 — this PR completes the Zod schema migration for
Message,MessageBlock(all discriminated union variants), and related types. Runtime validation (safeParse()at DB boundaries) will follow in subsequent PRs.Why we need it and why it was done in this way
This is foundational work for adding runtime type validation as described in #12846. By defining types as Zod schemas first (without changing runtime behavior), we establish the schema definitions that can later be used for
.parse()/.safeParse()validation at system boundaries (e.g.,sessionMessageRepository.serializeMessage()).The following tradeoffs were made:
@ts-ignorecomments are added in a few places where existing untyped data flows (e.g.,toolResponse.response) don't yet match the stricter schema types. These are marked withFIXMEfor follow-up work.metadatafields usez.record(z.string(), z.unknown())rather than a fully typed schema — this matches the previousanybehavior while being slightly stricter. Further narrowing toSerializableis planned as follow-up.The following alternatives were considered:
io-tsortypiainstead of Zod — Zod was chosen for its ecosystem adoption, ergonomic API, and existing usage in the codebase.Breaking changes
None. This PR is a pure type-level refactoring with no runtime behavior changes. All enum values are preserved as const object equivalents.
Special notes for your reviewer
@ts-ignore FIXMEcomments are intentional markers for follow-up work (runtime validation layer).Serializabletype now has a custom Zod schema with unit tests (serialize.test.ts).Checklist
Release note
🤖 Generated with Claude Code