@springbrand/chat-client 0.1.3-alpha.13 → 0.1.3-alpha.16

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": "@springbrand/chat-client",
3
- "version": "0.1.3-alpha.13",
3
+ "version": "0.1.3-alpha.16",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src",
@@ -25,7 +25,7 @@
25
25
  "@types/react-dom": "^19.2.3",
26
26
  "react-dom": "^19.2.7",
27
27
  "typescript": "^7.0.2",
28
- "@springbrand/agent-runtime": "0.2.0-alpha.22"
28
+ "@springbrand/agent-runtime": "0.2.0-alpha.23"
29
29
  },
30
30
  "scripts": {
31
31
  "typecheck": "tsc --noEmit"
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export {
2
+ UniversalAgentChatProvider,
2
3
  useUniversalAgentChat,
3
4
  type AgentToolRun,
4
5
  type ChatConnectionOptions,
@@ -1,4 +1,15 @@
1
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
1
+ import {
2
+ createContext,
3
+ createElement,
4
+ Suspense,
5
+ useCallback,
6
+ useContext,
7
+ useEffect,
8
+ useMemo,
9
+ useRef,
10
+ useState,
11
+ type ReactNode,
12
+ } from "react";
2
13
  import { nanoid } from "nanoid";
3
14
  import type { ChatStatus, FileUIPart, UIMessage } from "ai";
4
15
  import type { AgentToolRunState } from "agents";
@@ -157,6 +168,51 @@ export type ChatConnectionOptions = SharedChatConnectionOptions & (
157
168
  | { inboxName?: never; basePath?: string }
158
169
  );
159
170
 
171
+ type SessionAgentConnection = ReturnType<typeof useAgent<RuntimeState>>;
172
+ type UniversalAgentChatContextValue = {
173
+ chatId: string;
174
+ connection: ChatConnectionOptions;
175
+ agent: SessionAgentConnection;
176
+ };
177
+
178
+ const UniversalAgentChatContext = createContext<UniversalAgentChatContextValue | null>(null);
179
+
180
+ export function UniversalAgentChatProvider({
181
+ chatId,
182
+ connection = {},
183
+ fallback = null,
184
+ children,
185
+ }: {
186
+ chatId: string;
187
+ connection?: ChatConnectionOptions;
188
+ fallback?: ReactNode;
189
+ children: ReactNode;
190
+ }) {
191
+ const inboxAgent = connection.inboxAgent ?? "Inbox";
192
+ const agent = useAgent<RuntimeState>({
193
+ agent: inboxAgent,
194
+ ...(connection.inboxName === undefined
195
+ ? { basePath: connection.basePath ?? CURRENT_INBOX_AGENT_PATH }
196
+ : { name: connection.inboxName }),
197
+ ...(connection.host === undefined ? {} : { host: connection.host }),
198
+ ...(connection.protocols === undefined ? {} : { protocols: connection.protocols }),
199
+ connectionTimeout: 6_000,
200
+ sub: [{
201
+ agent: connection.sessionAgent ?? "UniversalAgent",
202
+ name: chatId,
203
+ }],
204
+ });
205
+ const value = useMemo(
206
+ () => ({ chatId, connection, agent }),
207
+ [agent, chatId, connection],
208
+ );
209
+ return createElement(
210
+ UniversalAgentChatContext.Provider,
211
+ { value },
212
+ createElement(Suspense, { fallback }, children),
213
+ );
214
+ }
215
+
160
216
  type ChatTurnTiming = {
161
217
  chatId: string;
162
218
  messageId: string;
@@ -284,10 +340,12 @@ function loadInitialMessages(
284
340
  * sub 数组由客户端 kebab 化;服务端按 ctx.exports 反解回 CamelCase className,
285
341
  * 与 Inbox.onBeforeSubAgent 的严格门卫(hasSubAgent)对齐。
286
342
  */
287
- export function useUniversalAgentChat(
288
- chatId: string,
289
- connection: ChatConnectionOptions = {},
290
- ): ChatRuntime {
343
+ export function useUniversalAgentChat(): ChatRuntime {
344
+ const context = useContext(UniversalAgentChatContext);
345
+ if (!context) {
346
+ throw new Error("useUniversalAgentChat must be used within UniversalAgentChatProvider");
347
+ }
348
+ const { chatId, connection, agent } = context;
291
349
  const [optimisticMessages, setOptimisticMessages] =
292
350
  useState<ChatMessage[]>([]);
293
351
  const [optimisticQueued, setOptimisticQueued] =
@@ -296,19 +354,6 @@ export function useUniversalAgentChat(
296
354
  const [canRetry, setCanRetry] = useState(false);
297
355
  const failedDispatchRef = useRef<FailedDispatch | undefined>(undefined);
298
356
  const activeSubmissionIdRef = useRef<string | undefined>(undefined);
299
- const inboxAgent = connection.inboxAgent ?? "Inbox";
300
- const agent = useAgent<RuntimeState>({
301
- agent: inboxAgent,
302
- ...(connection.inboxName === undefined
303
- ? { basePath: connection.basePath ?? CURRENT_INBOX_AGENT_PATH }
304
- : { name: connection.inboxName }),
305
- ...(connection.host === undefined ? {} : { host: connection.host }),
306
- ...(connection.protocols === undefined ? {} : { protocols: connection.protocols }),
307
- sub: [{
308
- agent: connection.sessionAgent ?? "UniversalAgent",
309
- name: chatId,
310
- }],
311
- });
312
357
  const chatAgent = useMemo(
313
358
  () => createSafeUIMessageAgentConnection(agent),
314
359
  [agent],