Skip to content

Commit fc1685e

Browse files
committed
make StructuredObject from @ai-sdk/svelte accept zod v4 schemas
1 parent 7ed3ff4 commit fc1685e

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

packages/svelte/src/structured-object.svelte.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ const server = createTestServer({
1212
});
1313

1414
describe('text stream', () => {
15-
let structuredObject: StructuredObject<{ content: string }>;
15+
const schema = z.object({ content: z.string() });
16+
let structuredObject: StructuredObject<typeof schema>;
1617

1718
beforeEach(() => {
1819
structuredObject = new StructuredObject({
1920
api: '/api/object',
20-
schema: z.object({ content: z.string() }),
21+
schema,
2122
});
2223
});
2324

packages/svelte/src/structured-object.svelte.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
isAbortError,
44
safeValidateTypes,
55
type FetchFunction,
6+
type InferSchema,
67
} from '@ai-sdk/provider-utils';
78
import {
89
asSchema,
@@ -11,15 +12,19 @@ import {
1112
type DeepPartial,
1213
type Schema,
1314
} from 'ai';
14-
import { type z } from 'zod';
15+
import type * as z3 from 'zod/v3';
16+
import type * as z4 from 'zod/v4/core';
1517
import {
1618
getStructuredObjectContext,
1719
hasStructuredObjectContext,
1820
KeyedStructuredObjectStore,
1921
type StructuredObjectStore,
2022
} from './structured-object-context.svelte.js';
2123

22-
export type Experimental_StructuredObjectOptions<RESULT> = {
24+
export type Experimental_StructuredObjectOptions<
25+
SCHEMA extends z3.Schema | z4.$ZodType | Schema,
26+
RESULT = InferSchema<SCHEMA>,
27+
> = {
2328
/**
2429
* The API endpoint. It should stream JSON that matches the schema as chunked text.
2530
*/
@@ -28,7 +33,7 @@ export type Experimental_StructuredObjectOptions<RESULT> = {
2833
/**
2934
* A Zod schema that defines the shape of the complete object.
3035
*/
31-
schema: z.Schema<RESULT, z.ZodTypeDef, unknown> | Schema<RESULT>;
36+
schema: SCHEMA;
3237

3338
/**
3439
* An unique identifier. If not provided, a random one will be
@@ -82,9 +87,13 @@ export type Experimental_StructuredObjectOptions<RESULT> = {
8287
credentials?: RequestCredentials;
8388
};
8489

85-
export class StructuredObject<RESULT, INPUT = unknown> {
86-
#options: Experimental_StructuredObjectOptions<RESULT> =
87-
{} as Experimental_StructuredObjectOptions<RESULT>;
90+
export class StructuredObject<
91+
SCHEMA extends z3.Schema | z4.$ZodType | Schema,
92+
RESULT = InferSchema<SCHEMA>,
93+
INPUT = unknown,
94+
> {
95+
#options: Experimental_StructuredObjectOptions<SCHEMA, RESULT> =
96+
{} as Experimental_StructuredObjectOptions<SCHEMA, RESULT>;
8897
readonly #id = $derived(this.#options.id ?? generateId());
8998
readonly #keyedStore = $state<KeyedStructuredObjectStore>()!;
9099
readonly #store = $derived(
@@ -114,7 +123,7 @@ export class StructuredObject<RESULT, INPUT = unknown> {
114123
return this.#store.loading;
115124
}
116125

117-
constructor(options: Experimental_StructuredObjectOptions<RESULT>) {
126+
constructor(options: Experimental_StructuredObjectOptions<SCHEMA, RESULT>) {
118127
if (hasStructuredObjectContext()) {
119128
this.#keyedStore = getStructuredObjectContext();
120129
} else {

0 commit comments

Comments
 (0)