Skip to content

Commit 274f10a

Browse files
committed
chore(deps): migrate to zod 4
- bump zod 3.25 -> 4.4.3 (AI SDK v6 supports zod 4; dedupes with json-render's zod so they share one instance, removing the cross-instance type mismatch) - v4 breaking changes fixed in app code: required_error/invalid_type_error -> error (extensions/news/persona models); ZodError.errors -> .issues (5 services) - genui: import z from 'zod'. Catalog still cast `as any` because json-render's defineCatalog types props as a branded SchemaType, stricter than its public z.object() usage (unrelated to the zod instance, so zod 4 doesn't remove it) - route: drop today/isoDate from the system prompt (main #135 moved time to a tool; the ported get_current_time tool now provides it) next build passes. The vitest suite has pre-existing + new zod-4 type errors to clean up before merging to main.
1 parent aad5509 commit 274f10a

12 files changed

Lines changed: 29 additions & 38 deletions

File tree

src/app/(authenticated)/api/chat/route.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ import {
3636
unregisterPublisher,
3737
} from "@/features/chat-page/chat-services/chat-api/stream-publisher";
3838
import { enforceSameOriginRequest } from "@/features/chat-page/chat-services/chat-api/same-origin";
39-
import {
40-
buildSystemMessage,
41-
isoDate,
42-
} from "@/features/chat-page/chat-services/chat-api/prompt-builder";
39+
import { buildSystemMessage } from "@/features/chat-page/chat-services/chat-api/prompt-builder";
4340
import { CHAT_DEFAULT_SYSTEM_PROMPT } from "@/features/theme/theme-config";
4441
import {
4542
FindAllExtensionForCurrentUserAndIds,
@@ -194,7 +191,6 @@ export async function POST(req: Request) {
194191
buildSystemMessage({
195192
staticSystemPrompt: CHAT_DEFAULT_SYSTEM_PROMPT,
196193
personaMessage: ctx.thread.personaMessage ?? "",
197-
today: isoDate(),
198194
documentHint: ctx.documentHint,
199195
}) +
200196
// Generative UI: GPT-5.5 reliably declines a UI *tool* under tool_choice

src/components/ai-elements/genui.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import * as React from 'react';
1616
import { defineCatalog } from '@json-render/core';
1717
import { createRenderer } from '@json-render/react';
1818
import { schema } from '@json-render/react/schema';
19-
import { z } from 'zod/v4';
19+
import { z } from 'zod';
2020
import {
2121
Card,
2222
CardContent,
@@ -127,7 +127,11 @@ export const genuiCatalog = defineCatalog(schema, {
127127
}),
128128
},
129129
},
130-
});
130+
// json-render's defineCatalog types `props` as a branded SchemaType<"zod">,
131+
// not a raw z.object() — its public docs pass z.object() directly, so the
132+
// type is stricter than the supported usage. Components render untyped (see
133+
// readProps), so loosen the catalog input type. (Unrelated to the zod version.)
134+
} as any);
131135

132136
// ---------------------------------------------------------------------------
133137
// Registry — maps each catalog component to a real Bühler shadcn component.
@@ -158,10 +162,10 @@ const genuiComponents = {
158162
const p = readProps(a);
159163
return (
160164
<Card>
161-
{(p.title || p.description) && (
165+
{(!!p.title || !!p.description) && (
162166
<CardHeader>
163-
{p.title && <CardTitle className="text-base">{String(p.title)}</CardTitle>}
164-
{p.description && <CardDescription>{String(p.description)}</CardDescription>}
167+
{!!p.title && <CardTitle className="text-base">{String(p.title)}</CardTitle>}
168+
{!!p.description && <CardDescription>{String(p.description)}</CardDescription>}
165169
</CardHeader>
166170
)}
167171
<CardContent className="space-y-3">{a.children}</CardContent>
@@ -217,7 +221,7 @@ const genuiComponents = {
217221
},
218222
Text: (a: any) => {
219223
const p = readProps(a);
220-
return <p className={cn('text-sm', p.muted && 'text-muted-foreground')}>{String(p.content ?? '')}</p>;
224+
return <p className={cn('text-sm', !!p.muted && 'text-muted-foreground')}>{String(p.content ?? '')}</p>;
221225
},
222226
Chart: (a: any) => {
223227
const p = readProps(a);
@@ -227,7 +231,7 @@ const genuiComponents = {
227231
const height = 220;
228232
return (
229233
<div className="flex flex-col gap-2">
230-
{p.title && <span className="text-sm font-medium">{String(p.title)}</span>}
234+
{!!p.title && <span className="text-sm font-medium">{String(p.title)}</span>}
231235
<div ref={ref} className="w-full" style={{ height }}>
232236
{width > 0 &&
233237
(isBar ? (

src/features/common/services/news-service/news-model.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ export const NewsArticleModelSchema = z.object({
88
id: z.string(),
99
title: z
1010
.string({
11-
invalid_type_error: "Invalid title",
11+
error: "Invalid title",
1212
})
1313
.min(1, "Title cannot be empty") // Ensuring title is not empty
1414
.refine(refineFromEmpty, "Title cannot be empty"),
1515
description: z
1616
.string({
17-
invalid_type_error: "Invalid description",
17+
error: "Invalid description",
1818
})
1919
.min(1, "Description cannot be empty") // Ensuring description is not empty
2020
.refine(refineFromEmpty, "Description cannot be empty"),
2121
link: z
2222
.string({
23-
invalid_type_error: "Invalid link",
23+
error: "Invalid link",
2424
})
2525
.url("Link must be a valid URL"), // Ensuring link is a valid URL
2626
createdAt: z.date(),

src/features/extensions-page/extension-services/extension-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ const validateSchema = (model: ExtensionModel): ServerActionResponse => {
464464
if (!validatedFields.success) {
465465
return {
466466
status: "ERROR",
467-
errors: zodErrorsToServerActionErrors(validatedFields.error.errors),
467+
errors: zodErrorsToServerActionErrors(validatedFields.error.issues),
468468
};
469469
}
470470

src/features/extensions-page/extension-services/models.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const EndpointTypeSchema = z.enum([
3434
]);
3535

3636
export const ExtensionFunctionSchema = z.object({
37-
id: z.string({ required_error: "Function ID is required" }),
37+
id: z.string({ error: "Function ID is required" }),
3838
functionName: z
3939
.string()
4040
.min(1, {

src/features/persona-page/persona-services/models.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,19 @@ export const PersonaModelSchema = z.object({
7575
userId: z.string(),
7676
name: z
7777
.string({
78-
invalid_type_error: "Invalid title",
78+
error: "Invalid title",
7979
})
8080
.min(1)
8181
.refine(refineFromEmpty, "Title cannot be empty"),
8282
description: z
8383
.string({
84-
invalid_type_error: "Invalid description",
84+
error: "Invalid description",
8585
})
8686
.min(1)
8787
.refine(refineFromEmpty, "Description cannot be empty"),
8888
personaMessage: z
8989
.string({
90-
invalid_type_error: "Invalid agent message",
90+
error: "Invalid agent message",
9191
})
9292
.min(1)
9393
.refine(refineFromEmpty, "System message cannot be empty"),

src/features/persona-page/persona-services/persona-ci-documents-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ const ValidatePersonaCIDocumentSchema = (
140140
if (!validatedFields.success) {
141141
return {
142142
status: "ERROR",
143-
errors: zodErrorsToServerActionErrors(validatedFields.error.errors),
143+
errors: zodErrorsToServerActionErrors(validatedFields.error.issues),
144144
};
145145
}
146146
}

src/features/persona-page/persona-services/persona-documents-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ const ValidatePersonaDocumentSchema = (
683683

684684
if (!validatedFields.success) {
685685
errors.push(
686-
...zodErrorsToServerActionErrors(validatedFields.error.errors)
686+
...zodErrorsToServerActionErrors(validatedFields.error.issues)
687687
);
688688
} else {
689689
validModels.push(validatedFields.data);

src/features/persona-page/persona-services/persona-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ const ValidateSchema = (model: PersonaModel): ServerActionResponse => {
536536
if (!validatedFields.success) {
537537
return {
538538
status: "ERROR",
539-
errors: zodErrorsToServerActionErrors(validatedFields.error.errors),
539+
errors: zodErrorsToServerActionErrors(validatedFields.error.issues),
540540
};
541541
}
542542

src/features/prompt-page/prompt-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ const ValidateSchema = (model: PromptModel): ServerActionResponse => {
286286
if (!validatedFields.success) {
287287
return {
288288
status: "ERROR",
289-
errors: zodErrorsToServerActionErrors(validatedFields.error.errors),
289+
errors: zodErrorsToServerActionErrors(validatedFields.error.issues),
290290
};
291291
}
292292

0 commit comments

Comments
 (0)