mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: remove omitempty from required ChatMessagePart fields (#23250)
ChatMessagePart uses a flat struct with omitempty on all fields, but some fields are required in their TypeScript variant (no ? suffix in the variants struct tag). When Go omits a zero-valued required field, the frontend receives undefined where it expects a concrete value. Remove omitempty from fields that are required in at least one variant: Text, URL, MediaType, FileName, StartLine, EndLine, Content. Fields where all variants use ? keep omitempty. Add a sub-test to TestChatMessagePartVariantTags that enforces this invariant via reflection so future additions cannot reintroduce the mismatch. Supersedes #23249
This commit is contained in:
Generated
+10
-1
@@ -1320,6 +1320,15 @@ export interface ChatMessage {
|
||||
* name = required, ? suffix = optional. Fields without a variants
|
||||
* tag are excluded from the generated union. See
|
||||
* scripts/apitypings/main.go for the codegen that reads these.
|
||||
*
|
||||
* omitempty rules (enforced by TestChatMessagePartVariantTags):
|
||||
* - If a field is required (no ? suffix) in ANY variant, it
|
||||
* must NOT use omitempty. Go would silently drop zero values
|
||||
* that TypeScript expects to always be present.
|
||||
* - If a field is optional (? suffix) in ALL of its variants,
|
||||
* it MUST use omitempty. Sending zero values for fields that
|
||||
* the frontend does not expect adds noise to the wire format
|
||||
* and wastes space in persisted chat_messages rows.
|
||||
*/
|
||||
export type ChatMessagePart =
|
||||
| ChatTextPart
|
||||
@@ -1682,7 +1691,7 @@ export interface ChatQueuedMessage {
|
||||
// From codersdk/chats.go
|
||||
export interface ChatReasoningPart {
|
||||
readonly type: "reasoning";
|
||||
readonly text?: string;
|
||||
readonly text: string;
|
||||
}
|
||||
|
||||
// From codersdk/chats.go
|
||||
|
||||
@@ -131,9 +131,8 @@ export const parseMessageContent = (
|
||||
break;
|
||||
}
|
||||
case "reasoning": {
|
||||
const text = part.text ?? "";
|
||||
parsed.reasoning = appendText(parsed.reasoning, text);
|
||||
parsed.blocks = appendTextBlock(parsed.blocks, "thinking", text);
|
||||
parsed.reasoning = appendText(parsed.reasoning, part.text);
|
||||
parsed.blocks = appendTextBlock(parsed.blocks, "thinking", part.text);
|
||||
break;
|
||||
}
|
||||
case "tool-call": {
|
||||
|
||||
Reference in New Issue
Block a user