@tanstack/ai-solid 0.13.14 → 0.13.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ import { ChatRequestBody, DeepPartial, UIMessage, UseChatOptions, UseChatReturn } from "./types.js";
2
+ import { useChat } from "./use-chat.js";
3
+ import { UseGenerationOptions, UseGenerationReturn, useGeneration } from "./use-generation.js";
4
+ import { UseGenerateImageOptions, UseGenerateImageReturn, useGenerateImage } from "./use-generate-image.js";
5
+ import { UseGenerateAudioOptions, UseGenerateAudioReturn, useGenerateAudio } from "./use-generate-audio.js";
6
+ import { UseGenerateSpeechOptions, UseGenerateSpeechReturn, useGenerateSpeech } from "./use-generate-speech.js";
7
+ import { UseTranscriptionOptions, UseTranscriptionReturn, useTranscription } from "./use-transcription.js";
8
+ import { UseSummarizeOptions, UseSummarizeReturn, useSummarize } from "./use-summarize.js";
9
+ import { UseGenerateVideoOptions, UseGenerateVideoReturn, useGenerateVideo } from "./use-generate-video.js";
10
+ import { AudioGenerateInput, ConnectConnectionAdapter, ConnectionAdapter, FetchConnectionOptions, GenerationClientState, ImageGenerateInput, InferChatMessages, RunAgentInputContext, SpeechGenerateInput, SubscribeConnectionAdapter, SummarizeGenerateInput, TranscriptionGenerateInput, VideoGenerateInput, VideoGenerateResult, VideoStatusInfo, XhrConnectionOptions, createChatClientOptions, fetchHttpStream, fetchServerSentEvents, rpcStream, stream, xhrHttpStream, xhrServerSentEvents } from "@tanstack/ai-client";
11
+ export { type AudioGenerateInput, type ChatRequestBody, type ConnectConnectionAdapter, type ConnectionAdapter, type DeepPartial, type FetchConnectionOptions, type GenerationClientState, type ImageGenerateInput, type InferChatMessages, type RunAgentInputContext, type SpeechGenerateInput, type SubscribeConnectionAdapter, type SummarizeGenerateInput, type TranscriptionGenerateInput, type UIMessage, type UseChatOptions, type UseChatReturn, type UseGenerateAudioOptions, type UseGenerateAudioReturn, type UseGenerateImageOptions, type UseGenerateImageReturn, type UseGenerateSpeechOptions, type UseGenerateSpeechReturn, type UseGenerateVideoOptions, type UseGenerateVideoReturn, type UseGenerationOptions, type UseGenerationReturn, type UseSummarizeOptions, type UseSummarizeReturn, type UseTranscriptionOptions, type UseTranscriptionReturn, type VideoGenerateInput, type VideoGenerateResult, type VideoStatusInfo, type XhrConnectionOptions, createChatClientOptions, fetchHttpStream, fetchServerSentEvents, rpcStream, stream, useChat, useGenerateAudio, useGenerateImage, useGenerateSpeech, useGenerateVideo, useGeneration, useSummarize, useTranscription, xhrHttpStream, xhrServerSentEvents };
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ import { useChat } from "./use-chat.js";
2
+ import { useGeneration } from "./use-generation.js";
3
+ import { useGenerateImage } from "./use-generate-image.js";
4
+ import { useGenerateAudio } from "./use-generate-audio.js";
5
+ import { useGenerateSpeech } from "./use-generate-speech.js";
6
+ import { useTranscription } from "./use-transcription.js";
7
+ import { useSummarize } from "./use-summarize.js";
8
+ import { useGenerateVideo } from "./use-generate-video.js";
9
+ import { createChatClientOptions, fetchHttpStream, fetchServerSentEvents, rpcStream, stream, xhrHttpStream, xhrServerSentEvents } from "@tanstack/ai-client";
10
+
11
+ export { createChatClientOptions, fetchHttpStream, fetchServerSentEvents, rpcStream, stream, useChat, useGenerateAudio, useGenerateImage, useGenerateSpeech, useGenerateVideo, useGeneration, useSummarize, useTranscription, xhrHttpStream, xhrServerSentEvents };
@@ -0,0 +1,139 @@
1
+ import { Accessor } from "solid-js";
2
+ import { AIDevtoolsDisplayOptions, ChatClientOptions, ChatClientState, ChatRequestBody, ClientContextOptionFromTools, ConnectionStatus, DistributedOmit, InferredClientContext, MultimodalContent, UIMessage } from "@tanstack/ai-client";
3
+ import { AnyClientTool, InferSchemaType, ModelMessage, SchemaInput } from "@tanstack/ai";
4
+
5
+ //#region src/types.d.ts
6
+
7
+ /**
8
+ * Recursive partial — every property and every nested array element is optional.
9
+ * Used to type the in-flight `partial` accessor while a structured-output
10
+ * stream is still arriving.
11
+ */
12
+ type DeepPartial<T> = T extends ReadonlyArray<infer U> ? Array<DeepPartial<U>> : T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T;
13
+ /**
14
+ * Options for the useChat hook.
15
+ *
16
+ * This extends ChatClientOptions but omits the state change callbacks that are
17
+ * managed internally by Solid signals:
18
+ * - `onMessagesChange` - Managed by Solid signal (exposed as `messages`)
19
+ * - `onLoadingChange` - Managed by Solid signal (exposed as `isLoading`)
20
+ * - `onErrorChange` - Managed by Solid signal (exposed as `error`)
21
+ * - `onStatusChange` - Managed by Solid signal (exposed as `status`)
22
+ *
23
+ * All other callbacks (onResponse, onChunk, onFinish, onError) are
24
+ * passed through to the underlying ChatClient and can be used for side effects.
25
+ *
26
+ * When `outputSchema` is supplied, the hook returns typed `partial` and `final`
27
+ * accessors. The schema is used purely for type inference; server-side
28
+ * validation still runs against the schema passed to `chat({ outputSchema })`
29
+ * on the server route.
30
+ *
31
+ * Note: Connection and body changes will recreate the ChatClient instance.
32
+ * To update these options, remount the component or use a key prop.
33
+ */
34
+ type UseChatOptions<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>> = DistributedOmit<ChatClientOptions<TTools, TContext>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange' | 'context' | 'devtools'> & {
35
+ /** Display options for TanStack AI Devtools. */
36
+ devtools?: AIDevtoolsDisplayOptions;
37
+ live?: boolean;
38
+ /**
39
+ * Standard-schema-compatible schema (Zod, Valibot, ArkType, or plain JSON
40
+ * Schema). Used to infer the shape of `partial` and `final`.
41
+ */
42
+ outputSchema?: TSchema;
43
+ } & ClientContextOptionFromTools<TTools, TContext>;
44
+ /**
45
+ * Discriminated return shape: when `outputSchema` is supplied, the hook adds
46
+ * typed `partial` / `final` accessors; otherwise the return is unchanged.
47
+ */
48
+ type UseChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined> = BaseUseChatReturn<TTools, TSchema extends SchemaInput ? InferSchemaType<TSchema> : unknown> & (TSchema extends SchemaInput ? {
49
+ /**
50
+ * Live progressively-parsed structured output. Derived from the
51
+ * latest assistant message's structured-output part.
52
+ */
53
+ partial: Accessor<DeepPartial<InferSchemaType<TSchema>>>;
54
+ /**
55
+ * Final, schema-validated structured output. `null` until the latest
56
+ * assistant turn's structured-output part transitions to `complete`.
57
+ */
58
+ final: Accessor<InferSchemaType<TSchema> | null>;
59
+ } : Record<never, never>);
60
+ interface BaseUseChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any, TData = unknown> {
61
+ /**
62
+ * Current messages in the conversation. When `outputSchema` is supplied,
63
+ * `messages()[i].parts.find(p => p.type === 'structured-output')` is typed
64
+ * by the schema — `data: T`, `partial: DeepPartial<T>`.
65
+ */
66
+ messages: Accessor<Array<UIMessage<TTools, TData>>>;
67
+ /**
68
+ * Send a message and get a response.
69
+ * Can be a simple string or multimodal content with images, audio, etc.
70
+ */
71
+ sendMessage: (content: string | MultimodalContent) => Promise<void>;
72
+ /**
73
+ * Append a message to the conversation
74
+ */
75
+ append: (message: ModelMessage | UIMessage<TTools, TData>) => Promise<void>;
76
+ /**
77
+ * Add the result of a client-side tool execution
78
+ */
79
+ addToolResult: (result: {
80
+ toolCallId: string;
81
+ tool: string;
82
+ output: any;
83
+ state?: 'output-available' | 'output-error';
84
+ errorText?: string;
85
+ }) => Promise<void>;
86
+ /**
87
+ * Respond to a tool approval request
88
+ */
89
+ addToolApprovalResponse: (response: {
90
+ id: string;
91
+ approved: boolean;
92
+ }) => Promise<void>;
93
+ /**
94
+ * Reload the last assistant message
95
+ */
96
+ reload: () => Promise<void>;
97
+ /**
98
+ * Stop the current response generation
99
+ */
100
+ stop: () => void;
101
+ /**
102
+ * Whether a response is currently being generated
103
+ */
104
+ isLoading: Accessor<boolean>;
105
+ /**
106
+ * Current error, if any
107
+ */
108
+ error: Accessor<Error | undefined>;
109
+ /**
110
+ * Set messages manually
111
+ */
112
+ setMessages: (messages: Array<UIMessage<TTools, TData>>) => void;
113
+ /**
114
+ * Clear all messages
115
+ */
116
+ clear: () => void;
117
+ /**
118
+ * Current generation status
119
+ */
120
+ status: Accessor<ChatClientState>;
121
+ /**
122
+ * Whether the subscription loop is currently active
123
+ */
124
+ isSubscribed: Accessor<boolean>;
125
+ /**
126
+ * Current connection lifecycle status
127
+ */
128
+ connectionStatus: Accessor<ConnectionStatus>;
129
+ /**
130
+ * Whether the shared session is actively generating.
131
+ * Derived from stream run events (RUN_STARTED / RUN_FINISHED / RUN_ERROR).
132
+ * Unlike `isLoading` (request-local), this reflects shared generation
133
+ * activity visible to all subscribers (e.g. across tabs/devices).
134
+ */
135
+ sessionGenerating: Accessor<boolean>;
136
+ }
137
+ //#endregion
138
+ export { type ChatRequestBody, DeepPartial, type UIMessage, UseChatOptions, UseChatReturn };
139
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { UseChatOptions, UseChatReturn } from "./types.js";
2
+ import { InferredClientContext } from "@tanstack/ai-client";
3
+ import { AnyClientTool, SchemaInput } from "@tanstack/ai";
4
+
5
+ //#region src/use-chat.d.ts
6
+ declare function useChat<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>>(options?: UseChatOptions<TTools, TSchema, TContext>): UseChatReturn<TTools, TSchema>;
7
+ //#endregion
8
+ export { useChat };
9
+ //# sourceMappingURL=use-chat.d.ts.map
@@ -0,0 +1,162 @@
1
+ import { createEffect, createMemo, createSignal, createUniqueId, onCleanup, onMount } from "solid-js";
2
+ import { ChatClient } from "@tanstack/ai-client";
3
+ import { createChatDevtoolsBridge } from "@tanstack/ai-client/devtools";
4
+
5
+ //#region src/use-chat.ts
6
+ function useChat(options = {}) {
7
+ const hookId = createUniqueId();
8
+ const clientId = options.id || hookId;
9
+ const [messages, setMessages] = createSignal(options.initialMessages || []);
10
+ const [isLoading, setIsLoading] = createSignal(false);
11
+ const [error, setError] = createSignal(void 0);
12
+ const [status, setStatus] = createSignal("ready");
13
+ const [isSubscribed, setIsSubscribed] = createSignal(false);
14
+ const [connectionStatus, setConnectionStatus] = createSignal("disconnected");
15
+ const [sessionGenerating, setSessionGenerating] = createSignal(false);
16
+ const client = createMemo(() => {
17
+ return new ChatClient({
18
+ devtoolsBridgeFactory: createChatDevtoolsBridge,
19
+ ...options.connection ? { connection: options.connection } : { fetcher: options.fetcher },
20
+ id: clientId,
21
+ ...options.initialMessages !== void 0 && { initialMessages: options.initialMessages },
22
+ ...options.persistence !== void 0 && { persistence: options.persistence },
23
+ body: options.body,
24
+ ...options.threadId !== void 0 && { threadId: options.threadId },
25
+ ...options.forwardedProps !== void 0 && { forwardedProps: options.forwardedProps },
26
+ ...options.context !== void 0 && { context: options.context },
27
+ devtools: {
28
+ ...options.devtools,
29
+ framework: "solid",
30
+ hookName: "useChat",
31
+ outputKind: options.outputSchema ? "structured" : "chat"
32
+ },
33
+ onResponse: (response) => options.onResponse?.(response),
34
+ onChunk: (chunk) => {
35
+ options.onChunk?.(chunk);
36
+ },
37
+ onFinish: (message) => {
38
+ options.onFinish?.(message);
39
+ },
40
+ onError: (err) => {
41
+ options.onError?.(err);
42
+ },
43
+ tools: options.tools,
44
+ onCustomEvent: (eventType, data, context) => options.onCustomEvent?.(eventType, data, context),
45
+ ...options.streamProcessor !== void 0 && { streamProcessor: options.streamProcessor },
46
+ onMessagesChange: (newMessages) => {
47
+ setMessages(newMessages);
48
+ },
49
+ onLoadingChange: (newIsLoading) => {
50
+ setIsLoading(newIsLoading);
51
+ },
52
+ onStatusChange: (newStatus) => {
53
+ setStatus(newStatus);
54
+ },
55
+ onErrorChange: (newError) => {
56
+ setError(newError);
57
+ },
58
+ onSubscriptionChange: (nextIsSubscribed) => {
59
+ setIsSubscribed(nextIsSubscribed);
60
+ },
61
+ onConnectionStatusChange: (nextStatus) => {
62
+ setConnectionStatus(nextStatus);
63
+ },
64
+ onSessionGeneratingChange: (isGenerating) => {
65
+ setSessionGenerating(isGenerating);
66
+ }
67
+ });
68
+ }, [clientId]);
69
+ setMessages(client().getMessages());
70
+ createEffect(() => {
71
+ client().updateOptions({
72
+ ...options.body !== void 0 && { body: options.body },
73
+ ...options.forwardedProps !== void 0 && { forwardedProps: options.forwardedProps },
74
+ context: options.context
75
+ });
76
+ });
77
+ if (options.live) client().subscribe();
78
+ else client().unsubscribe();
79
+ createEffect(() => {
80
+ if (options.live) client().subscribe();
81
+ else client().unsubscribe();
82
+ });
83
+ onMount(() => {
84
+ client().mountDevtools();
85
+ });
86
+ onCleanup(() => {
87
+ if (options.live) client().unsubscribe();
88
+ else client().stop();
89
+ client().dispose();
90
+ });
91
+ const sendMessage = async (content) => {
92
+ await client().sendMessage(content);
93
+ };
94
+ const append = async (message) => {
95
+ await client().append(message);
96
+ };
97
+ const reload = async () => {
98
+ await client().reload();
99
+ };
100
+ const stop = () => {
101
+ client().stop();
102
+ };
103
+ const clear = () => {
104
+ client().clear();
105
+ };
106
+ const setMessagesManually = (newMessages) => {
107
+ client().setMessagesManually(newMessages);
108
+ };
109
+ const addToolResult = async (result) => {
110
+ await client().addToolResult(result);
111
+ };
112
+ const addToolApprovalResponse = async (response) => {
113
+ await client().addToolApprovalResponse(response);
114
+ };
115
+ const activeStructuredPart = createMemo(() => {
116
+ const list = messages();
117
+ let lastUserIndex = -1;
118
+ for (let i = list.length - 1; i >= 0; i--) if (list[i]?.role === "user") {
119
+ lastUserIndex = i;
120
+ break;
121
+ }
122
+ if (lastUserIndex === -1) return null;
123
+ for (let i = list.length - 1; i > lastUserIndex; i--) {
124
+ const m = list[i];
125
+ if (m?.role !== "assistant") continue;
126
+ const part = m.parts.find((p) => p.type === "structured-output");
127
+ if (part) return part;
128
+ }
129
+ return null;
130
+ });
131
+ return {
132
+ messages,
133
+ sendMessage,
134
+ append,
135
+ reload,
136
+ stop,
137
+ isLoading,
138
+ error,
139
+ status,
140
+ isSubscribed,
141
+ connectionStatus,
142
+ sessionGenerating,
143
+ setMessages: setMessagesManually,
144
+ clear,
145
+ addToolResult,
146
+ addToolApprovalResponse,
147
+ partial: createMemo(() => {
148
+ const part = activeStructuredPart();
149
+ if (!part) return {};
150
+ return part.partial ?? part.data ?? {};
151
+ }),
152
+ final: createMemo(() => {
153
+ const part = activeStructuredPart();
154
+ if (!part || part.status !== "complete") return null;
155
+ return part.data;
156
+ })
157
+ };
158
+ }
159
+
160
+ //#endregion
161
+ export { useChat };
162
+ //# sourceMappingURL=use-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-chat.js","names":[],"sources":["../src/use-chat.ts"],"sourcesContent":["import {\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n onCleanup,\n onMount,\n} from 'solid-js'\n\nimport { ChatClient } from '@tanstack/ai-client'\nimport { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools'\nimport type {\n ChatClientState,\n ConnectionStatus,\n InferredClientContext,\n StructuredOutputPart,\n} from '@tanstack/ai-client'\nimport type {\n AnyClientTool,\n InferSchemaType,\n ModelMessage,\n SchemaInput,\n StreamChunk,\n} from '@tanstack/ai'\nimport type {\n DeepPartial,\n MultimodalContent,\n UIMessage,\n UseChatOptions,\n UseChatReturn,\n} from './types'\n\nexport function useChat<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n TSchema extends SchemaInput | undefined = undefined,\n TContext = InferredClientContext<TTools>,\n>(\n options: UseChatOptions<TTools, TSchema, TContext> = {} as UseChatOptions<\n TTools,\n TSchema,\n TContext\n >,\n): UseChatReturn<TTools, TSchema> {\n const hookId = createUniqueId()\n const clientId = options.id || hookId\n\n const [messages, setMessages] = createSignal<Array<UIMessage<TTools>>>(\n options.initialMessages || [],\n )\n const [isLoading, setIsLoading] = createSignal(false)\n const [error, setError] = createSignal<Error | undefined>(undefined)\n const [status, setStatus] = createSignal<ChatClientState>('ready')\n const [isSubscribed, setIsSubscribed] = createSignal(false)\n const [connectionStatus, setConnectionStatus] =\n createSignal<ConnectionStatus>('disconnected')\n const [sessionGenerating, setSessionGenerating] = createSignal(false)\n\n // Structured-output `partial` / `final` are derived from `messages` —\n // specifically from the structured-output part on the latest assistant\n // message (the one after the most recent user message). Per-turn parts\n // keep history coherent without a separate reset signal.\n type Partial = DeepPartial<InferSchemaType<NonNullable<TSchema>>>\n type Final = InferSchemaType<NonNullable<TSchema>>\n\n // Create ChatClient instance with callbacks to sync state.\n // Every user-provided callback is wrapped so the LATEST `options.xxx` value\n // is read at call time. Direct assignment would freeze the callback to the\n // reference we saw at creation; the wrapper lets reactive `options` or\n // in-place mutations propagate. When the user clears a callback (sets it to\n // undefined), `?.` no-ops.\n const client = createMemo(() => {\n // Build options with conditional spreads for fields whose source\n // type is `T | undefined` but the ChatClient target uses a strict\n // optional (`field?: T`) — `exactOptionalPropertyTypes` rejects\n // assigning `undefined` to those, so we omit the key when absent.\n const transport = options.connection\n ? { connection: options.connection }\n : { fetcher: options.fetcher }\n return new ChatClient<TTools, TContext>({\n devtoolsBridgeFactory: createChatDevtoolsBridge,\n ...transport,\n id: clientId,\n ...(options.initialMessages !== undefined && {\n initialMessages: options.initialMessages,\n }),\n ...(options.persistence !== undefined && {\n persistence: options.persistence,\n }),\n body: options.body,\n ...(options.threadId !== undefined && { threadId: options.threadId }),\n ...(options.forwardedProps !== undefined && {\n forwardedProps: options.forwardedProps,\n }),\n ...(options.context !== undefined && { context: options.context }),\n devtools: {\n ...options.devtools,\n framework: 'solid',\n hookName: 'useChat',\n outputKind: options.outputSchema ? 'structured' : 'chat',\n },\n onResponse: (response) => options.onResponse?.(response),\n onChunk: (chunk: StreamChunk) => {\n options.onChunk?.(chunk)\n },\n onFinish: (message) => {\n options.onFinish?.(message)\n },\n onError: (err) => {\n options.onError?.(err)\n },\n tools: options.tools,\n onCustomEvent: (eventType, data, context) =>\n options.onCustomEvent?.(eventType, data, context),\n ...(options.streamProcessor !== undefined && {\n streamProcessor: options.streamProcessor,\n }),\n onMessagesChange: (newMessages: Array<UIMessage<TTools>>) => {\n setMessages(newMessages)\n },\n onLoadingChange: (newIsLoading: boolean) => {\n setIsLoading(newIsLoading)\n },\n onStatusChange: (newStatus: ChatClientState) => {\n setStatus(newStatus)\n },\n onErrorChange: (newError: Error | undefined) => {\n setError(newError)\n },\n onSubscriptionChange: (nextIsSubscribed: boolean) => {\n setIsSubscribed(nextIsSubscribed)\n },\n onConnectionStatusChange: (nextStatus: ConnectionStatus) => {\n setConnectionStatus(nextStatus)\n },\n onSessionGeneratingChange: (isGenerating: boolean) => {\n setSessionGenerating(isGenerating)\n },\n })\n // Only recreate when clientId changes\n // Connection and other options are captured at creation time\n }, [clientId])\n\n setMessages(client().getMessages())\n\n // Sync body / forwardedProps changes to the client.\n // Both populate the same wire payload; `forwardedProps` is preferred\n // and `body` is deprecated but still supported.\n createEffect(() => {\n // Conditional spread: `updateOptions` declares strict-optional\n // fields and rejects explicit `undefined` under EOPT.\n client().updateOptions({\n ...(options.body !== undefined && { body: options.body }),\n ...(options.forwardedProps !== undefined && {\n forwardedProps: options.forwardedProps,\n }),\n context: options.context,\n })\n })\n\n // Apply initial live mode immediately on hook creation.\n if (options.live) {\n client().subscribe()\n } else {\n client().unsubscribe()\n }\n\n createEffect(() => {\n if (options.live) {\n client().subscribe()\n } else {\n client().unsubscribe()\n }\n })\n\n onMount(() => {\n client().mountDevtools()\n })\n\n // Cleanup on unmount: stop any in-flight requests.\n onCleanup(() => {\n if (options.live) {\n client().unsubscribe()\n } else {\n client().stop()\n }\n client().dispose()\n })\n\n // Callback options are read through `options.xxx` at call time, so reactive\n // or mutated options propagate without recreating the client.\n\n const sendMessage = async (content: string | MultimodalContent) => {\n await client().sendMessage(content)\n }\n\n const append = async (message: ModelMessage | UIMessage<TTools>) => {\n await client().append(message)\n }\n\n const reload = async () => {\n await client().reload()\n }\n\n const stop = () => {\n client().stop()\n }\n\n const clear = () => {\n client().clear()\n }\n\n const setMessagesManually = (newMessages: Array<UIMessage<TTools>>) => {\n client().setMessagesManually(newMessages)\n }\n\n const addToolResult = async (result: {\n toolCallId: string\n tool: string\n output: any\n state?: 'output-available' | 'output-error'\n errorText?: string\n }) => {\n await client().addToolResult(result)\n }\n\n const addToolApprovalResponse = async (response: {\n id: string\n approved: boolean\n }) => {\n await client().addToolApprovalResponse(response)\n }\n\n // The \"active\" structured-output part is on the assistant message after\n // the latest user message. When no user message exists yet, return null\n // rather than scanning history — otherwise a stale `final` from\n // `initialMessages` would leak into the value on first render.\n const activeStructuredPart = createMemo<StructuredOutputPart | null>(() => {\n const list = messages()\n let lastUserIndex = -1\n for (let i = list.length - 1; i >= 0; i--) {\n if (list[i]?.role === 'user') {\n lastUserIndex = i\n break\n }\n }\n if (lastUserIndex === -1) return null\n for (let i = list.length - 1; i > lastUserIndex; i--) {\n const m = list[i]\n if (m?.role !== 'assistant') continue\n const part = m.parts.find(\n (p): p is StructuredOutputPart => p.type === 'structured-output',\n )\n if (part) return part\n }\n return null\n })\n\n const partial = createMemo<Partial>(() => {\n const part = activeStructuredPart()\n if (!part) return {} as Partial\n const v = part.partial ?? part.data\n return (v ?? {}) as Partial\n })\n\n const final = createMemo<Final | null>(() => {\n const part = activeStructuredPart()\n if (!part || part.status !== 'complete') return null\n return part.data as Final\n })\n\n // partial / final are runtime-tracked unconditionally; the conditional\n // return type hides them when no `outputSchema` is supplied.\n // eslint-disable-next-line no-restricted-syntax -- primitive return shape diverges from generic UseChatReturn<TTools, TSchema>; TS can't structurally narrow the conditional partial/final fields\n return {\n messages,\n sendMessage,\n append,\n reload,\n stop,\n isLoading,\n error,\n status,\n isSubscribed,\n connectionStatus,\n sessionGenerating,\n setMessages: setMessagesManually,\n clear,\n addToolResult,\n addToolApprovalResponse,\n partial,\n final,\n } as unknown as UseChatReturn<TTools, TSchema>\n}\n"],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import { Accessor } from "solid-js";
2
+ import { AIDevtoolsDisplayOptions, AudioGenerateInput, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput } from "@tanstack/ai-client";
3
+ import { AudioGenerationResult, StreamChunk } from "@tanstack/ai";
4
+
5
+ //#region src/use-generate-audio.d.ts
6
+
7
+ /**
8
+ * Options for the useGenerateAudio hook.
9
+ *
10
+ * @template TOutput - The transformed output type (defaults to AudioGenerationResult)
11
+ */
12
+ interface UseGenerateAudioOptions<TOutput = AudioGenerationResult> {
13
+ /** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
14
+ connection?: ConnectConnectionAdapter;
15
+ /** Direct async function for audio generation */
16
+ fetcher?: GenerationFetcher<AudioGenerateInput, AudioGenerationResult>;
17
+ /** Unique identifier for this generation instance */
18
+ id?: string;
19
+ /** Additional body parameters to send with connect-based adapter requests */
20
+ body?: Record<string, any>;
21
+ /** Display options for TanStack AI Devtools. */
22
+ devtools?: AIDevtoolsDisplayOptions;
23
+ /**
24
+ * Callback when audio is generated. Can optionally return a transformed value.
25
+ *
26
+ * - Return a non-null value to transform and store it as the result
27
+ * - Return `null` to keep the previous result unchanged
28
+ * - Return nothing (`void`) to store the raw result as-is
29
+ */
30
+ onResult?: (result: AudioGenerationResult) => TOutput | null | void;
31
+ /** Callback when an error occurs */
32
+ onError?: (error: Error) => void;
33
+ /** Callback when progress is reported (0-100) */
34
+ onProgress?: (progress: number, message?: string) => void;
35
+ /** Callback for each stream chunk (connect-based adapter mode only) */
36
+ onChunk?: (chunk: StreamChunk) => void;
37
+ }
38
+ /**
39
+ * Return type for the useGenerateAudio hook.
40
+ *
41
+ * @template TOutput - The transformed output type (defaults to AudioGenerationResult)
42
+ */
43
+ interface UseGenerateAudioReturn<TOutput = AudioGenerationResult> {
44
+ /** Trigger audio generation */
45
+ generate: (input: AudioGenerateInput) => Promise<void>;
46
+ /** The generation result containing audio, or null */
47
+ result: Accessor<TOutput | null>;
48
+ /** Whether generation is in progress */
49
+ isLoading: Accessor<boolean>;
50
+ /** Current error, if any */
51
+ error: Accessor<Error | undefined>;
52
+ /** Current state of the generation */
53
+ status: Accessor<GenerationClientState>;
54
+ /** Abort the current generation */
55
+ stop: () => void;
56
+ /** Clear result, error, and return to idle */
57
+ reset: () => void;
58
+ }
59
+ /**
60
+ * Solid hook for generating audio (music, sound effects) using AI models.
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * import { useGenerateAudio } from '@tanstack/ai-solid'
65
+ * import { fetchServerSentEvents } from '@tanstack/ai-client'
66
+ *
67
+ * function AudioGenerator() {
68
+ * const { generate, result, isLoading } = useGenerateAudio({
69
+ * connection: fetchServerSentEvents('/api/generate/audio'),
70
+ * })
71
+ *
72
+ * return (
73
+ * <div>
74
+ * <button onClick={() => generate({ prompt: 'An upbeat electronic track', duration: 10 })}>
75
+ * Generate
76
+ * </button>
77
+ * {result()?.audio.url && <audio src={result()!.audio.url} controls />}
78
+ * </div>
79
+ * )
80
+ * }
81
+ * ```
82
+ */
83
+ declare function useGenerateAudio<TOnResult extends ((result: AudioGenerationResult) => any) | undefined = undefined>(options: Omit<UseGenerateAudioOptions, 'onResult'> & {
84
+ onResult?: TOnResult;
85
+ }): UseGenerateAudioReturn<InferGenerationOutput<AudioGenerationResult, TOnResult>>;
86
+ //#endregion
87
+ export { UseGenerateAudioOptions, UseGenerateAudioReturn, useGenerateAudio };
88
+ //# sourceMappingURL=use-generate-audio.d.ts.map
@@ -0,0 +1,52 @@
1
+ import { useGeneration } from "./use-generation.js";
2
+
3
+ //#region src/use-generate-audio.ts
4
+ /**
5
+ * Solid hook for generating audio (music, sound effects) using AI models.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { useGenerateAudio } from '@tanstack/ai-solid'
10
+ * import { fetchServerSentEvents } from '@tanstack/ai-client'
11
+ *
12
+ * function AudioGenerator() {
13
+ * const { generate, result, isLoading } = useGenerateAudio({
14
+ * connection: fetchServerSentEvents('/api/generate/audio'),
15
+ * })
16
+ *
17
+ * return (
18
+ * <div>
19
+ * <button onClick={() => generate({ prompt: 'An upbeat electronic track', duration: 10 })}>
20
+ * Generate
21
+ * </button>
22
+ * {result()?.audio.url && <audio src={result()!.audio.url} controls />}
23
+ * </div>
24
+ * )
25
+ * }
26
+ * ```
27
+ */
28
+ function useGenerateAudio(options) {
29
+ const devtools = {
30
+ ...options.devtools,
31
+ framework: "solid",
32
+ hookName: "useGenerateAudio",
33
+ outputKind: "audio"
34
+ };
35
+ const { generate, result, isLoading, error, status, stop, reset } = useGeneration({
36
+ ...options,
37
+ devtools
38
+ });
39
+ return {
40
+ generate,
41
+ result,
42
+ isLoading,
43
+ error,
44
+ status,
45
+ stop,
46
+ reset
47
+ };
48
+ }
49
+
50
+ //#endregion
51
+ export { useGenerateAudio };
52
+ //# sourceMappingURL=use-generate-audio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-generate-audio.js","names":[],"sources":["../src/use-generate-audio.ts"],"sourcesContent":["import { useGeneration } from './use-generation'\nimport type { AudioGenerationResult, StreamChunk } from '@tanstack/ai'\nimport type {\n AIDevtoolsDisplayOptions,\n AudioGenerateInput,\n ConnectConnectionAdapter,\n GenerationClientState,\n GenerationFetcher,\n InferGenerationOutput,\n} from '@tanstack/ai-client'\nimport type { Accessor } from 'solid-js'\n\n/**\n * Options for the useGenerateAudio hook.\n *\n * @template TOutput - The transformed output type (defaults to AudioGenerationResult)\n */\nexport interface UseGenerateAudioOptions<TOutput = AudioGenerationResult> {\n /** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */\n connection?: ConnectConnectionAdapter\n /** Direct async function for audio generation */\n fetcher?: GenerationFetcher<AudioGenerateInput, AudioGenerationResult>\n /** Unique identifier for this generation instance */\n id?: string\n /** Additional body parameters to send with connect-based adapter requests */\n body?: Record<string, any>\n /** Display options for TanStack AI Devtools. */\n devtools?: AIDevtoolsDisplayOptions\n /**\n * Callback when audio is generated. Can optionally return a transformed value.\n *\n * - Return a non-null value to transform and store it as the result\n * - Return `null` to keep the previous result unchanged\n * - Return nothing (`void`) to store the raw result as-is\n */\n onResult?: (result: AudioGenerationResult) => TOutput | null | void\n /** Callback when an error occurs */\n onError?: (error: Error) => void\n /** Callback when progress is reported (0-100) */\n onProgress?: (progress: number, message?: string) => void\n /** Callback for each stream chunk (connect-based adapter mode only) */\n onChunk?: (chunk: StreamChunk) => void\n}\n\n/**\n * Return type for the useGenerateAudio hook.\n *\n * @template TOutput - The transformed output type (defaults to AudioGenerationResult)\n */\nexport interface UseGenerateAudioReturn<TOutput = AudioGenerationResult> {\n /** Trigger audio generation */\n generate: (input: AudioGenerateInput) => Promise<void>\n /** The generation result containing audio, or null */\n result: Accessor<TOutput | null>\n /** Whether generation is in progress */\n isLoading: Accessor<boolean>\n /** Current error, if any */\n error: Accessor<Error | undefined>\n /** Current state of the generation */\n status: Accessor<GenerationClientState>\n /** Abort the current generation */\n stop: () => void\n /** Clear result, error, and return to idle */\n reset: () => void\n}\n\n/**\n * Solid hook for generating audio (music, sound effects) using AI models.\n *\n * @example\n * ```tsx\n * import { useGenerateAudio } from '@tanstack/ai-solid'\n * import { fetchServerSentEvents } from '@tanstack/ai-client'\n *\n * function AudioGenerator() {\n * const { generate, result, isLoading } = useGenerateAudio({\n * connection: fetchServerSentEvents('/api/generate/audio'),\n * })\n *\n * return (\n * <div>\n * <button onClick={() => generate({ prompt: 'An upbeat electronic track', duration: 10 })}>\n * Generate\n * </button>\n * {result()?.audio.url && <audio src={result()!.audio.url} controls />}\n * </div>\n * )\n * }\n * ```\n */\nexport function useGenerateAudio<\n TOnResult extends ((result: AudioGenerationResult) => any) | undefined =\n undefined,\n>(\n options: Omit<UseGenerateAudioOptions, 'onResult'> & {\n onResult?: TOnResult\n },\n): UseGenerateAudioReturn<\n InferGenerationOutput<AudioGenerationResult, TOnResult>\n> {\n const devtools = {\n ...options.devtools,\n framework: 'solid',\n hookName: 'useGenerateAudio',\n outputKind: 'audio' as const,\n }\n const { generate, result, isLoading, error, status, stop, reset } =\n useGeneration<AudioGenerateInput, AudioGenerationResult, TOnResult>({\n ...options,\n devtools,\n })\n\n return {\n generate: generate as (input: AudioGenerateInput) => Promise<void>,\n result,\n isLoading,\n error,\n status,\n stop,\n reset,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,SAAgB,iBAId,SAKA;CACA,MAAM,WAAW;EACf,GAAG,QAAQ;EACX,WAAW;EACX,UAAU;EACV,YAAY;EACb;CACD,MAAM,EAAE,UAAU,QAAQ,WAAW,OAAO,QAAQ,MAAM,UACxD,cAAoE;EAClE,GAAG;EACH;EACD,CAAC;AAEJ,QAAO;EACK;EACV;EACA;EACA;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,96 @@
1
+ import { Accessor } from "solid-js";
2
+ import { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, ImageGenerateInput, InferGenerationOutput } from "@tanstack/ai-client";
3
+ import { ImageGenerationResult, StreamChunk } from "@tanstack/ai";
4
+
5
+ //#region src/use-generate-image.d.ts
6
+
7
+ /**
8
+ * Options for the useGenerateImage hook.
9
+ *
10
+ * @template TOutput - The transformed output type (defaults to ImageGenerationResult)
11
+ */
12
+ interface UseGenerateImageOptions<TOutput = ImageGenerationResult> {
13
+ /** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
14
+ connection?: ConnectConnectionAdapter;
15
+ /** Direct async function for image generation */
16
+ fetcher?: GenerationFetcher<ImageGenerateInput, ImageGenerationResult>;
17
+ /** Unique identifier for this generation instance */
18
+ id?: string;
19
+ /** Additional body parameters to send with connect-based adapter requests */
20
+ body?: Record<string, any>;
21
+ /** Display options for TanStack AI Devtools. */
22
+ devtools?: AIDevtoolsDisplayOptions;
23
+ /**
24
+ * Callback when images are generated. Can optionally return a transformed value.
25
+ *
26
+ * - Return a non-null value to transform and store it as the result
27
+ * - Return `null` to keep the previous result unchanged
28
+ * - Return nothing (`void`) to store the raw result as-is
29
+ */
30
+ onResult?: (result: ImageGenerationResult) => TOutput | null | void;
31
+ /** Callback when an error occurs */
32
+ onError?: (error: Error) => void;
33
+ /** Callback when progress is reported (0-100) */
34
+ onProgress?: (progress: number, message?: string) => void;
35
+ /** Callback for each stream chunk (connect-based adapter mode only) */
36
+ onChunk?: (chunk: StreamChunk) => void;
37
+ }
38
+ /**
39
+ * Return type for the useGenerateImage hook.
40
+ *
41
+ * @template TOutput - The transformed output type (defaults to ImageGenerationResult)
42
+ */
43
+ interface UseGenerateImageReturn<TOutput = ImageGenerationResult> {
44
+ /** Trigger image generation */
45
+ generate: (input: ImageGenerateInput) => Promise<void>;
46
+ /** The generation result containing images, or null */
47
+ result: Accessor<TOutput | null>;
48
+ /** Whether generation is in progress */
49
+ isLoading: Accessor<boolean>;
50
+ /** Current error, if any */
51
+ error: Accessor<Error | undefined>;
52
+ /** Current state of the generation */
53
+ status: Accessor<GenerationClientState>;
54
+ /** Abort the current generation */
55
+ stop: () => void;
56
+ /** Clear result, error, and return to idle */
57
+ reset: () => void;
58
+ }
59
+ /**
60
+ * Solid hook for generating images using AI models.
61
+ *
62
+ * Supports two transport modes:
63
+ * - **ConnectConnectionAdapter** -- Streaming transport (SSE, HTTP stream, custom)
64
+ * - **Fetcher** -- Direct async function call
65
+ *
66
+ * @example
67
+ * ```tsx
68
+ * import { useGenerateImage } from '@tanstack/ai-solid'
69
+ * import { fetchServerSentEvents } from '@tanstack/ai-client'
70
+ *
71
+ * function ImageGenerator() {
72
+ * const { generate, result, isLoading, error, reset } = useGenerateImage({
73
+ * connection: fetchServerSentEvents('/api/generate/image'),
74
+ * })
75
+ *
76
+ * return (
77
+ * <div>
78
+ * <button onClick={() => generate({ prompt: 'A sunset over mountains' })}>
79
+ * Generate
80
+ * </button>
81
+ * {isLoading() && <p>Generating...</p>}
82
+ * {error() && <p>Error: {error()!.message}</p>}
83
+ * {result()?.images.map((img, i) => (
84
+ * <img src={img.url || `data:image/png;base64,${img.b64Json}`} />
85
+ * ))}
86
+ * </div>
87
+ * )
88
+ * }
89
+ * ```
90
+ */
91
+ declare function useGenerateImage<TOnResult extends ((result: ImageGenerationResult) => any) | undefined = undefined>(options: Omit<UseGenerateImageOptions, 'onResult'> & {
92
+ onResult?: TOnResult;
93
+ }): UseGenerateImageReturn<InferGenerationOutput<ImageGenerationResult, TOnResult>>;
94
+ //#endregion
95
+ export { UseGenerateImageOptions, UseGenerateImageReturn, useGenerateImage };
96
+ //# sourceMappingURL=use-generate-image.d.ts.map