@tanstack/ai-preact 0.9.12 → 0.9.14

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-preact",
3
- "version": "0.9.12",
3
+ "version": "0.9.14",
4
4
  "description": "Preact hooks for TanStack AI streaming chat and typed messages.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -42,7 +42,7 @@
42
42
  "tool-calling"
43
43
  ],
44
44
  "dependencies": {
45
- "@tanstack/ai-client": "0.18.3"
45
+ "@tanstack/ai-client": "0.18.5"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@testing-library/preact": "^3.2.4",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "peerDependencies": {
55
55
  "preact": ">=10.11.0",
56
- "@tanstack/ai": "^0.34.1"
56
+ "@tanstack/ai": "^0.36.0"
57
57
  },
58
58
  "scripts": {
59
59
  "clean": "premove ./build ./dist",
@@ -1,3 +0,0 @@
1
- export { useChat } from './use-chat.js';
2
- export type { UseChatOptions, UseChatReturn, UIMessage, ChatRequestBody, } from './types.js';
3
- export { fetchServerSentEvents, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, createChatClientOptions, type ConnectionAdapter, type ConnectConnectionAdapter, type SubscribeConnectionAdapter, type RunAgentInputContext, type FetchConnectionOptions, type XhrConnectionOptions, type InferChatMessages, } from '@tanstack/ai-client';
package/dist/esm/index.js DELETED
@@ -1,13 +0,0 @@
1
- import { useChat } from "./use-chat.js";
2
- import { createChatClientOptions, fetchHttpStream, fetchServerSentEvents, rpcStream, stream, xhrHttpStream, xhrServerSentEvents } from "@tanstack/ai-client";
3
- export {
4
- createChatClientOptions,
5
- fetchHttpStream,
6
- fetchServerSentEvents,
7
- rpcStream,
8
- stream,
9
- useChat,
10
- xhrHttpStream,
11
- xhrServerSentEvents
12
- };
13
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,106 +0,0 @@
1
- import { AnyClientTool, ModelMessage, SchemaInput } from '@tanstack/ai';
2
- import { AIDevtoolsDisplayOptions, ChatClientOptions, ChatClientState, ChatRequestBody, ClientContextOptionFromTools, ConnectionStatus, DistributedOmit, InferredClientContext, MultimodalContent, UIMessage } from '@tanstack/ai-client';
3
- export type { ChatRequestBody, MultimodalContent, UIMessage };
4
- /**
5
- * Options for the useChat hook.
6
- *
7
- * This extends ChatClientOptions but omits the state change callbacks that are
8
- * managed internally by Preact state:
9
- * - `onMessagesChange` - Managed by Preact state (exposed as `messages`)
10
- * - `onLoadingChange` - Managed by Preact state (exposed as `isLoading`)
11
- * - `onErrorChange` - Managed by Preact state (exposed as `error`)
12
- * - `onStatusChange` - Managed by Preact state (exposed as `status`)
13
- *
14
- * All other callbacks (onResponse, onChunk, onFinish, onError) are
15
- * passed through to the underlying ChatClient and can be used for side effects.
16
- *
17
- * Note: Connection and body changes will recreate the ChatClient instance.
18
- * To update these options, remount the component or use a key prop.
19
- */
20
- export type UseChatOptions<TTools extends ReadonlyArray<AnyClientTool> = any, TContext = InferredClientContext<TTools>> = DistributedOmit<ChatClientOptions<TTools, TContext>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange' | 'context' | 'devtools'> & {
21
- live?: boolean;
22
- /** Display options for TanStack AI Devtools. */
23
- devtools?: AIDevtoolsDisplayOptions;
24
- /**
25
- * Standard-schema-compatible schema used to identify structured-output chat
26
- * hooks in devtools. Preact currently exposes structured-output parts via
27
- * `messages`; typed `partial` / `final` sugar is implemented in the other
28
- * framework adapters.
29
- */
30
- outputSchema?: SchemaInput;
31
- } & ClientContextOptionFromTools<TTools, TContext>;
32
- export interface UseChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any> {
33
- /**
34
- * Current messages in the conversation
35
- */
36
- messages: Array<UIMessage<TTools>>;
37
- /**
38
- * Send a message and get a response.
39
- * Can be a simple string or multimodal content with images, audio, etc.
40
- */
41
- sendMessage: (content: string | MultimodalContent) => Promise<void>;
42
- /**
43
- * Append a message to the conversation
44
- */
45
- append: (message: ModelMessage | UIMessage<TTools>) => Promise<void>;
46
- /**
47
- * Add the result of a client-side tool execution
48
- */
49
- addToolResult: (result: {
50
- toolCallId: string;
51
- tool: string;
52
- output: unknown;
53
- state?: 'output-available' | 'output-error';
54
- errorText?: string;
55
- }) => Promise<void>;
56
- /**
57
- * Respond to a tool approval request
58
- */
59
- addToolApprovalResponse: (response: {
60
- id: string;
61
- approved: boolean;
62
- }) => Promise<void>;
63
- /**
64
- * Reload the last assistant message
65
- */
66
- reload: () => Promise<void>;
67
- /**
68
- * Stop the current response generation
69
- */
70
- stop: () => void;
71
- /**
72
- * Whether a response is currently being generated
73
- */
74
- isLoading: boolean;
75
- /**
76
- * Current error, if any
77
- */
78
- error: Error | undefined;
79
- /**
80
- * Set messages manually
81
- */
82
- setMessages: (messages: Array<UIMessage<TTools>>) => void;
83
- /**
84
- * Clear all messages
85
- */
86
- clear: () => void;
87
- /**
88
- * Current generation status
89
- */
90
- status: ChatClientState;
91
- /**
92
- * Whether the subscription loop is currently active
93
- */
94
- isSubscribed: boolean;
95
- /**
96
- * Current connection lifecycle status
97
- */
98
- connectionStatus: ConnectionStatus;
99
- /**
100
- * Whether the shared session is actively generating.
101
- * Derived from stream run events (RUN_STARTED / RUN_FINISHED / RUN_ERROR).
102
- * Unlike `isLoading` (request-local), this reflects shared generation
103
- * activity visible to all subscribers (e.g. across tabs/devices).
104
- */
105
- sessionGenerating: boolean;
106
- }
@@ -1,4 +0,0 @@
1
- import { InferredClientContext } from '@tanstack/ai-client';
2
- import { AnyClientTool } from '@tanstack/ai';
3
- import { UseChatOptions, UseChatReturn } from './types.js';
4
- export declare function useChat<TTools extends ReadonlyArray<AnyClientTool> = any, TContext = InferredClientContext<TTools>>(options: UseChatOptions<TTools, TContext>): UseChatReturn<TTools>;
@@ -1,224 +0,0 @@
1
- import { ChatClient } from "@tanstack/ai-client";
2
- import { createChatDevtoolsBridge } from "@tanstack/ai-client/devtools";
3
- import { useId, useState, useRef, useEffect, useMemo, useCallback } from "preact/hooks";
4
- function useChat(options) {
5
- const hookId = useId();
6
- const clientId = options.id || hookId;
7
- const [messages, setMessages] = useState(
8
- options.initialMessages || []
9
- );
10
- const [isLoading, setIsLoading] = useState(false);
11
- const [error, setError] = useState(void 0);
12
- const [status, setStatus] = useState("ready");
13
- const [isSubscribed, setIsSubscribed] = useState(false);
14
- const [connectionStatus, setConnectionStatus] = useState("disconnected");
15
- const [sessionGenerating, setSessionGenerating] = useState(false);
16
- const messagesRef = useRef(
17
- options.initialMessages || []
18
- );
19
- const isFirstMountRef = useRef(true);
20
- const activeClientRef = useRef(null);
21
- const cleanupInvalidationRef = useRef(
22
- null
23
- );
24
- const optionsRef = useRef(options);
25
- optionsRef.current = options;
26
- useEffect(() => {
27
- messagesRef.current = messages;
28
- }, [messages]);
29
- const client = useMemo(() => {
30
- const messagesToUse = options.initialMessages || [];
31
- isFirstMountRef.current = false;
32
- const initialOptions = optionsRef.current;
33
- const transport = initialOptions.connection ? { connection: initialOptions.connection } : { fetcher: initialOptions.fetcher };
34
- const instance = new ChatClient({
35
- devtoolsBridgeFactory: createChatDevtoolsBridge,
36
- ...transport,
37
- id: clientId,
38
- initialMessages: messagesToUse,
39
- ...initialOptions.body !== void 0 && { body: initialOptions.body },
40
- ...initialOptions.threadId !== void 0 && {
41
- threadId: initialOptions.threadId
42
- },
43
- ...initialOptions.forwardedProps !== void 0 && {
44
- forwardedProps: initialOptions.forwardedProps
45
- },
46
- ...initialOptions.persistence !== void 0 && {
47
- persistence: initialOptions.persistence
48
- },
49
- ...initialOptions.context !== void 0 && {
50
- context: initialOptions.context
51
- },
52
- devtools: {
53
- ...initialOptions.devtools,
54
- framework: "preact",
55
- hookName: "useChat",
56
- outputKind: initialOptions.outputSchema ? "structured" : "chat"
57
- },
58
- // Wrap every callback so the latest options are read at call time.
59
- // Capturing the function reference directly would freeze it to whatever
60
- // the parent passed on the first render.
61
- onResponse: (response) => {
62
- if (activeClientRef.current !== instance) return;
63
- return optionsRef.current.onResponse?.(response);
64
- },
65
- onChunk: (chunk) => {
66
- if (activeClientRef.current !== instance) return;
67
- optionsRef.current.onChunk?.(chunk);
68
- },
69
- onFinish: (message) => {
70
- if (activeClientRef.current !== instance) return;
71
- optionsRef.current.onFinish?.(message);
72
- },
73
- onError: (err) => {
74
- if (activeClientRef.current !== instance) return;
75
- optionsRef.current.onError?.(err);
76
- },
77
- onCustomEvent: (eventType, data, context) => {
78
- if (activeClientRef.current !== instance) return;
79
- optionsRef.current.onCustomEvent?.(eventType, data, context);
80
- },
81
- ...initialOptions.tools !== void 0 && {
82
- tools: initialOptions.tools
83
- },
84
- ...options.streamProcessor !== void 0 && {
85
- streamProcessor: options.streamProcessor
86
- },
87
- onMessagesChange: (newMessages) => {
88
- if (activeClientRef.current !== instance) return;
89
- setMessages(newMessages);
90
- },
91
- onLoadingChange: (newIsLoading) => {
92
- if (activeClientRef.current !== instance) return;
93
- setIsLoading(newIsLoading);
94
- },
95
- onStatusChange: (newStatus) => {
96
- if (activeClientRef.current !== instance) return;
97
- setStatus(newStatus);
98
- },
99
- onErrorChange: (newError) => {
100
- if (activeClientRef.current !== instance) return;
101
- setError(newError);
102
- },
103
- onSubscriptionChange: (nextIsSubscribed) => {
104
- if (activeClientRef.current !== instance) return;
105
- setIsSubscribed(nextIsSubscribed);
106
- },
107
- onConnectionStatusChange: (nextStatus) => {
108
- if (activeClientRef.current !== instance) return;
109
- setConnectionStatus(nextStatus);
110
- },
111
- onSessionGeneratingChange: (isGenerating) => {
112
- if (activeClientRef.current !== instance) return;
113
- setSessionGenerating(isGenerating);
114
- }
115
- });
116
- activeClientRef.current = instance;
117
- return instance;
118
- }, [clientId]);
119
- useEffect(() => {
120
- const clientMessages = client.getMessages();
121
- if (clientMessages !== messagesRef.current) {
122
- setMessages(clientMessages);
123
- }
124
- }, [client]);
125
- useEffect(() => {
126
- client.updateOptions({
127
- body: options.body,
128
- ...options.forwardedProps !== void 0 && {
129
- forwardedProps: options.forwardedProps
130
- },
131
- context: options.context
132
- });
133
- }, [client, options.body, options.forwardedProps, options.context]);
134
- useEffect(() => {
135
- if (options.live) {
136
- client.subscribe();
137
- } else {
138
- client.unsubscribe();
139
- }
140
- }, [client, options.live]);
141
- useEffect(() => {
142
- if (cleanupInvalidationRef.current) {
143
- clearTimeout(cleanupInvalidationRef.current);
144
- cleanupInvalidationRef.current = null;
145
- }
146
- activeClientRef.current = client;
147
- client.mountDevtools();
148
- return () => {
149
- cleanupInvalidationRef.current = setTimeout(() => {
150
- if (activeClientRef.current === client) {
151
- activeClientRef.current = null;
152
- }
153
- cleanupInvalidationRef.current = null;
154
- }, 0);
155
- if (optionsRef.current.live) {
156
- client.unsubscribe();
157
- } else {
158
- client.stop();
159
- }
160
- client.dispose();
161
- };
162
- }, [client]);
163
- const sendMessage = useCallback(
164
- async (content) => {
165
- await client.sendMessage(content);
166
- },
167
- [client]
168
- );
169
- const append = useCallback(
170
- async (message) => {
171
- await client.append(message);
172
- },
173
- [client]
174
- );
175
- const reload = useCallback(async () => {
176
- await client.reload();
177
- }, [client]);
178
- const stop = useCallback(() => {
179
- client.stop();
180
- }, [client]);
181
- const clear = useCallback(() => {
182
- client.clear();
183
- }, [client]);
184
- const setMessagesManually = useCallback(
185
- (newMessages) => {
186
- client.setMessagesManually(newMessages);
187
- },
188
- [client]
189
- );
190
- const addToolResult = useCallback(
191
- async (result) => {
192
- await client.addToolResult(result);
193
- },
194
- [client]
195
- );
196
- const addToolApprovalResponse = useCallback(
197
- async (response) => {
198
- await client.addToolApprovalResponse(response);
199
- },
200
- [client]
201
- );
202
- const renderedMessages = client.getMessages();
203
- return {
204
- messages: renderedMessages,
205
- sendMessage,
206
- append,
207
- reload,
208
- stop,
209
- isLoading,
210
- error,
211
- status,
212
- isSubscribed,
213
- connectionStatus,
214
- sessionGenerating,
215
- setMessages: setMessagesManually,
216
- clear,
217
- addToolResult,
218
- addToolApprovalResponse
219
- };
220
- }
221
- export {
222
- useChat
223
- };
224
- //# sourceMappingURL=use-chat.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-chat.js","sources":["../../src/use-chat.ts"],"sourcesContent":["import { ChatClient } from '@tanstack/ai-client'\nimport { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools'\nimport {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'preact/hooks'\nimport type {\n ChatClientState,\n ConnectionStatus,\n InferredClientContext,\n} from '@tanstack/ai-client'\nimport type { AnyClientTool, ModelMessage } from '@tanstack/ai'\n\nimport type {\n MultimodalContent,\n UIMessage,\n UseChatOptions,\n UseChatReturn,\n} from './types'\n\nexport function useChat<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n TContext = InferredClientContext<TTools>,\n>(options: UseChatOptions<TTools, TContext>): UseChatReturn<TTools> {\n const hookId = useId()\n const clientId = options.id || hookId\n\n const [messages, setMessages] = useState<Array<UIMessage<TTools>>>(\n options.initialMessages || [],\n )\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<Error | undefined>(undefined)\n const [status, setStatus] = useState<ChatClientState>('ready')\n const [isSubscribed, setIsSubscribed] = useState(false)\n const [connectionStatus, setConnectionStatus] =\n useState<ConnectionStatus>('disconnected')\n const [sessionGenerating, setSessionGenerating] = useState(false)\n\n // Track current messages in a ref to preserve them when client is recreated\n const messagesRef = useRef<Array<UIMessage<TTools>>>(\n options.initialMessages || [],\n )\n const isFirstMountRef = useRef(true)\n const activeClientRef = useRef<ChatClient | null>(null)\n const cleanupInvalidationRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n )\n const optionsRef = useRef<UseChatOptions<TTools, TContext>>(options)\n\n optionsRef.current = options\n\n useEffect(() => {\n messagesRef.current = messages\n }, [messages])\n\n const client = useMemo(() => {\n const messagesToUse = options.initialMessages || []\n isFirstMountRef.current = false\n\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 initialOptions = optionsRef.current\n const transport = initialOptions.connection\n ? { connection: initialOptions.connection }\n : { fetcher: initialOptions.fetcher }\n\n const instance = new ChatClient<TTools, TContext>({\n devtoolsBridgeFactory: createChatDevtoolsBridge,\n ...transport,\n id: clientId,\n initialMessages: messagesToUse,\n ...(initialOptions.body !== undefined && { body: initialOptions.body }),\n ...(initialOptions.threadId !== undefined && {\n threadId: initialOptions.threadId,\n }),\n ...(initialOptions.forwardedProps !== undefined && {\n forwardedProps: initialOptions.forwardedProps,\n }),\n ...(initialOptions.persistence !== undefined && {\n persistence: initialOptions.persistence,\n }),\n ...(initialOptions.context !== undefined && {\n context: initialOptions.context,\n }),\n devtools: {\n ...initialOptions.devtools,\n framework: 'preact',\n hookName: 'useChat',\n outputKind: initialOptions.outputSchema ? 'structured' : 'chat',\n },\n // Wrap every callback so the latest options are read at call time.\n // Capturing the function reference directly would freeze it to whatever\n // the parent passed on the first render.\n onResponse: (response) => {\n if (activeClientRef.current !== instance) return\n return optionsRef.current.onResponse?.(response)\n },\n onChunk: (chunk) => {\n if (activeClientRef.current !== instance) return\n optionsRef.current.onChunk?.(chunk)\n },\n onFinish: (message) => {\n if (activeClientRef.current !== instance) return\n optionsRef.current.onFinish?.(message)\n },\n onError: (err) => {\n if (activeClientRef.current !== instance) return\n optionsRef.current.onError?.(err)\n },\n onCustomEvent: (eventType, data, context) => {\n if (activeClientRef.current !== instance) return\n optionsRef.current.onCustomEvent?.(eventType, data, context)\n },\n ...(initialOptions.tools !== undefined && {\n tools: initialOptions.tools,\n }),\n ...(options.streamProcessor !== undefined && {\n streamProcessor: options.streamProcessor,\n }),\n onMessagesChange: (newMessages: Array<UIMessage<TTools>>) => {\n if (activeClientRef.current !== instance) return\n setMessages(newMessages)\n },\n onLoadingChange: (newIsLoading: boolean) => {\n if (activeClientRef.current !== instance) return\n setIsLoading(newIsLoading)\n },\n onStatusChange: (newStatus: ChatClientState) => {\n if (activeClientRef.current !== instance) return\n setStatus(newStatus)\n },\n onErrorChange: (newError: Error | undefined) => {\n if (activeClientRef.current !== instance) return\n setError(newError)\n },\n onSubscriptionChange: (nextIsSubscribed: boolean) => {\n if (activeClientRef.current !== instance) return\n setIsSubscribed(nextIsSubscribed)\n },\n onConnectionStatusChange: (nextStatus: ConnectionStatus) => {\n if (activeClientRef.current !== instance) return\n setConnectionStatus(nextStatus)\n },\n onSessionGeneratingChange: (isGenerating: boolean) => {\n if (activeClientRef.current !== instance) return\n setSessionGenerating(isGenerating)\n },\n })\n activeClientRef.current = instance\n return instance\n }, [clientId])\n\n useEffect(() => {\n const clientMessages = client.getMessages()\n if (clientMessages !== messagesRef.current) {\n setMessages(clientMessages)\n }\n }, [client])\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 useEffect(() => {\n // Conditional spread: `updateOptions` declares strict-optional\n // fields and rejects explicit `undefined` under EOPT.\n client.updateOptions({\n body: options.body,\n ...(options.forwardedProps !== undefined && {\n forwardedProps: options.forwardedProps,\n }),\n context: options.context,\n })\n }, [client, options.body, options.forwardedProps, options.context])\n\n useEffect(() => {\n if (options.live) {\n client.subscribe()\n } else {\n client.unsubscribe()\n }\n }, [client, options.live])\n\n // Cleanup on unmount: stop any in-flight requests\n // Note: We only cleanup when client changes or component unmounts.\n // DO NOT include isLoading in dependencies - that would cause the cleanup\n // to run when isLoading changes, aborting continuation requests.\n useEffect(() => {\n if (cleanupInvalidationRef.current) {\n clearTimeout(cleanupInvalidationRef.current)\n cleanupInvalidationRef.current = null\n }\n activeClientRef.current = client\n client.mountDevtools()\n\n return () => {\n cleanupInvalidationRef.current = setTimeout(() => {\n if (activeClientRef.current === client) {\n activeClientRef.current = null\n }\n cleanupInvalidationRef.current = null\n }, 0)\n // Subscribe/unsubscribe on `options.live` is owned by the dedicated\n // effect above. This cleanup only fires on unmount or client swap,\n // so read `live` through the ref to avoid disposing the client every\n // time `live` toggles.\n if (optionsRef.current.live) {\n client.unsubscribe()\n } else {\n client.stop()\n }\n client.dispose()\n }\n }, [client])\n\n // All callback options are read through optionsRef at call time, so fresh\n // closures from each render are picked up without recreating the client.\n const sendMessage = useCallback(\n async (content: string | MultimodalContent) => {\n await client.sendMessage(content)\n },\n [client],\n )\n\n const append = useCallback(\n async (message: ModelMessage | UIMessage) => {\n await client.append(message)\n },\n [client],\n )\n\n const reload = useCallback(async () => {\n await client.reload()\n }, [client])\n\n const stop = useCallback(() => {\n client.stop()\n }, [client])\n\n const clear = useCallback(() => {\n client.clear()\n }, [client])\n\n const setMessagesManually = useCallback(\n (newMessages: Array<UIMessage<TTools>>) => {\n client.setMessagesManually(newMessages)\n },\n [client],\n )\n\n const addToolResult = useCallback(\n async (result: {\n toolCallId: string\n tool: string\n output: unknown\n state?: 'output-available' | 'output-error'\n errorText?: string\n }) => {\n await client.addToolResult(result)\n },\n [client],\n )\n\n const addToolApprovalResponse = useCallback(\n async (response: { id: string; approved: boolean }) => {\n await client.addToolApprovalResponse(response)\n },\n [client],\n )\n\n const renderedMessages = client.getMessages()\n\n return {\n messages: renderedMessages,\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 }\n}\n"],"names":[],"mappings":"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"}