@trigger.dev/sdk 4.4.6 → 4.5.0-rc.1
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/dist/commonjs/v3/agentSkillsRuntime.d.ts +28 -0
- package/dist/commonjs/v3/agentSkillsRuntime.js +163 -0
- package/dist/commonjs/v3/agentSkillsRuntime.js.map +1 -0
- package/dist/commonjs/v3/ai-shared.d.ts +173 -0
- package/dist/commonjs/v3/ai-shared.js +25 -0
- package/dist/commonjs/v3/ai-shared.js.map +1 -0
- package/dist/commonjs/v3/ai.d.ts +2823 -5
- package/dist/commonjs/v3/ai.js +6197 -13
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/auth.d.ts +9 -0
- package/dist/commonjs/v3/auth.js.map +1 -1
- package/dist/commonjs/v3/chat-client.d.ts +301 -0
- package/dist/commonjs/v3/chat-client.js +624 -0
- package/dist/commonjs/v3/chat-client.js.map +1 -0
- package/dist/commonjs/v3/chat-react.d.ts +155 -0
- package/dist/commonjs/v3/chat-react.js +330 -0
- package/dist/commonjs/v3/chat-react.js.map +1 -0
- package/dist/commonjs/v3/chat-server.d.ts +206 -0
- package/dist/commonjs/v3/chat-server.js +737 -0
- package/dist/commonjs/v3/chat-server.js.map +1 -0
- package/dist/commonjs/v3/chat-server.test.d.ts +1 -0
- package/dist/commonjs/v3/chat-server.test.js +518 -0
- package/dist/commonjs/v3/chat-server.test.js.map +1 -0
- package/dist/commonjs/v3/chat-tab-coordinator.d.ts +65 -0
- package/dist/commonjs/v3/chat-tab-coordinator.js +235 -0
- package/dist/commonjs/v3/chat-tab-coordinator.js.map +1 -0
- package/dist/commonjs/v3/chat-tab-coordinator.test.d.ts +1 -0
- package/dist/commonjs/v3/chat-tab-coordinator.test.js +140 -0
- package/dist/commonjs/v3/chat-tab-coordinator.test.js.map +1 -0
- package/dist/commonjs/v3/chat.d.ts +437 -0
- package/dist/commonjs/v3/chat.js +968 -0
- package/dist/commonjs/v3/chat.js.map +1 -0
- package/dist/commonjs/v3/chat.test.d.ts +1 -0
- package/dist/commonjs/v3/chat.test.js +1180 -0
- package/dist/commonjs/v3/chat.test.js.map +1 -0
- package/dist/commonjs/v3/createStartSessionAction.test.d.ts +1 -0
- package/dist/commonjs/v3/createStartSessionAction.test.js +113 -0
- package/dist/commonjs/v3/createStartSessionAction.test.js.map +1 -0
- package/dist/commonjs/v3/deployments.d.ts +26 -0
- package/dist/commonjs/v3/deployments.js +37 -0
- package/dist/commonjs/v3/deployments.js.map +1 -0
- package/dist/commonjs/v3/index.d.ts +6 -3
- package/dist/commonjs/v3/index.js +7 -1
- package/dist/commonjs/v3/index.js.map +1 -1
- package/dist/commonjs/v3/runs.d.ts +22 -7
- package/dist/commonjs/v3/runs.js +1 -0
- package/dist/commonjs/v3/runs.js.map +1 -1
- package/dist/commonjs/v3/sessions.d.ts +228 -0
- package/dist/commonjs/v3/sessions.js +664 -0
- package/dist/commonjs/v3/sessions.js.map +1 -0
- package/dist/commonjs/v3/sessions.test.d.ts +1 -0
- package/dist/commonjs/v3/sessions.test.js +154 -0
- package/dist/commonjs/v3/sessions.test.js.map +1 -0
- package/dist/commonjs/v3/shared.d.ts +24 -2
- package/dist/commonjs/v3/shared.js +189 -1
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/skill.d.ts +99 -0
- package/dist/commonjs/v3/skill.js +155 -0
- package/dist/commonjs/v3/skill.js.map +1 -0
- package/dist/commonjs/v3/skills.d.ts +2 -0
- package/dist/commonjs/v3/skills.js +6 -0
- package/dist/commonjs/v3/skills.js.map +1 -0
- package/dist/commonjs/v3/streams.js +127 -19
- package/dist/commonjs/v3/streams.js.map +1 -1
- package/dist/commonjs/v3/tasks.d.ts +2 -1
- package/dist/commonjs/v3/tasks.js +1 -0
- package/dist/commonjs/v3/tasks.js.map +1 -1
- package/dist/commonjs/v3/test/index.d.ts +3 -0
- package/dist/commonjs/v3/test/index.js +18 -0
- package/dist/commonjs/v3/test/index.js.map +1 -0
- package/dist/commonjs/v3/test/mock-chat-agent.d.ts +259 -0
- package/dist/commonjs/v3/test/mock-chat-agent.js +468 -0
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -0
- package/dist/commonjs/v3/test/setup-catalog.d.ts +1 -0
- package/dist/commonjs/v3/test/setup-catalog.js +18 -0
- package/dist/commonjs/v3/test/setup-catalog.js.map +1 -0
- package/dist/commonjs/v3/test/test-session-handle.d.ts +53 -0
- package/dist/commonjs/v3/test/test-session-handle.js +256 -0
- package/dist/commonjs/v3/test/test-session-handle.js.map +1 -0
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/agentSkillsRuntime.d.ts +28 -0
- package/dist/esm/v3/agentSkillsRuntime.js +136 -0
- package/dist/esm/v3/agentSkillsRuntime.js.map +1 -0
- package/dist/esm/v3/ai-shared.d.ts +173 -0
- package/dist/esm/v3/ai-shared.js +22 -0
- package/dist/esm/v3/ai-shared.js.map +1 -0
- package/dist/esm/v3/ai.d.ts +2823 -5
- package/dist/esm/v3/ai.js +6187 -14
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/auth.d.ts +9 -0
- package/dist/esm/v3/auth.js.map +1 -1
- package/dist/esm/v3/chat-client.d.ts +301 -0
- package/dist/esm/v3/chat-client.js +619 -0
- package/dist/esm/v3/chat-client.js.map +1 -0
- package/dist/esm/v3/chat-react.d.ts +155 -0
- package/dist/esm/v3/chat-react.js +325 -0
- package/dist/esm/v3/chat-react.js.map +1 -0
- package/dist/esm/v3/chat-server.d.ts +206 -0
- package/dist/esm/v3/chat-server.js +734 -0
- package/dist/esm/v3/chat-server.js.map +1 -0
- package/dist/esm/v3/chat-server.test.d.ts +1 -0
- package/dist/esm/v3/chat-server.test.js +516 -0
- package/dist/esm/v3/chat-server.test.js.map +1 -0
- package/dist/esm/v3/chat-tab-coordinator.d.ts +65 -0
- package/dist/esm/v3/chat-tab-coordinator.js +231 -0
- package/dist/esm/v3/chat-tab-coordinator.js.map +1 -0
- package/dist/esm/v3/chat-tab-coordinator.test.d.ts +1 -0
- package/dist/esm/v3/chat-tab-coordinator.test.js +138 -0
- package/dist/esm/v3/chat-tab-coordinator.test.js.map +1 -0
- package/dist/esm/v3/chat.d.ts +437 -0
- package/dist/esm/v3/chat.js +961 -0
- package/dist/esm/v3/chat.js.map +1 -0
- package/dist/esm/v3/chat.test.d.ts +1 -0
- package/dist/esm/v3/chat.test.js +1178 -0
- package/dist/esm/v3/chat.test.js.map +1 -0
- package/dist/esm/v3/createStartSessionAction.test.d.ts +1 -0
- package/dist/esm/v3/createStartSessionAction.test.js +111 -0
- package/dist/esm/v3/createStartSessionAction.test.js.map +1 -0
- package/dist/esm/v3/deployments.d.ts +26 -0
- package/dist/esm/v3/deployments.js +34 -0
- package/dist/esm/v3/deployments.js.map +1 -0
- package/dist/esm/v3/index.d.ts +6 -3
- package/dist/esm/v3/index.js +4 -1
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/esm/v3/runs.d.ts +15 -0
- package/dist/esm/v3/runs.js +1 -0
- package/dist/esm/v3/runs.js.map +1 -1
- package/dist/esm/v3/sessions.d.ts +228 -0
- package/dist/esm/v3/sessions.js +656 -0
- package/dist/esm/v3/sessions.js.map +1 -0
- package/dist/esm/v3/sessions.test.d.ts +1 -0
- package/dist/esm/v3/sessions.test.js +152 -0
- package/dist/esm/v3/sessions.test.js.map +1 -0
- package/dist/esm/v3/shared.d.ts +24 -2
- package/dist/esm/v3/shared.js +188 -1
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/skill.d.ts +99 -0
- package/dist/esm/v3/skill.js +128 -0
- package/dist/esm/v3/skill.js.map +1 -0
- package/dist/esm/v3/skills.d.ts +2 -0
- package/dist/esm/v3/skills.js +2 -0
- package/dist/esm/v3/skills.js.map +1 -0
- package/dist/esm/v3/streams.js +127 -20
- package/dist/esm/v3/streams.js.map +1 -1
- package/dist/esm/v3/tasks.d.ts +2 -1
- package/dist/esm/v3/tasks.js +2 -1
- package/dist/esm/v3/tasks.js.map +1 -1
- package/dist/esm/v3/test/index.d.ts +3 -0
- package/dist/esm/v3/test/index.js +13 -0
- package/dist/esm/v3/test/index.js.map +1 -0
- package/dist/esm/v3/test/mock-chat-agent.d.ts +259 -0
- package/dist/esm/v3/test/mock-chat-agent.js +465 -0
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -0
- package/dist/esm/v3/test/setup-catalog.d.ts +1 -0
- package/dist/esm/v3/test/setup-catalog.js +16 -0
- package/dist/esm/v3/test/setup-catalog.js.map +1 -0
- package/dist/esm/v3/test/test-session-handle.d.ts +53 -0
- package/dist/esm/v3/test/test-session-handle.js +251 -0
- package/dist/esm/v3/test/test-session-handle.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/package.json +87 -6
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { TriggerChatTransport, type TriggerChatTransportOptions } from "./chat.js";
|
|
2
|
+
import type { AnyTask, TaskIdentifier } from "@trigger.dev/core/v3";
|
|
3
|
+
import { type InferChatClientData, type InferChatUIMessage } from "./ai-shared.js";
|
|
4
|
+
import type { UIMessage, ChatRequestOptions } from "ai";
|
|
5
|
+
/**
|
|
6
|
+
* Options for `useTriggerChatTransport`, with a type-safe `task` field.
|
|
7
|
+
*
|
|
8
|
+
* Pass a task type parameter to get compile-time validation of the task ID:
|
|
9
|
+
* ```ts
|
|
10
|
+
* useTriggerChatTransport<typeof myTask>({ task: "my-task", ... })
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export type UseTriggerChatTransportOptions<TTask extends AnyTask = AnyTask> = Omit<TriggerChatTransportOptions<InferChatClientData<TTask>>, "task"> & {
|
|
14
|
+
/** The task ID. Strongly typed when a task type parameter is provided. */
|
|
15
|
+
task: TaskIdentifier<TTask>;
|
|
16
|
+
};
|
|
17
|
+
export type { InferChatUIMessage };
|
|
18
|
+
/**
|
|
19
|
+
* React hook that creates and memoizes a `TriggerChatTransport` instance.
|
|
20
|
+
*
|
|
21
|
+
* The transport is created once on first render and reused for the lifetime
|
|
22
|
+
* of the component. This avoids the need for `useMemo` and ensures the
|
|
23
|
+
* transport's internal session state (run IDs, lastEventId, etc.)
|
|
24
|
+
* is preserved across re-renders.
|
|
25
|
+
*
|
|
26
|
+
* For dynamic access tokens, pass a function — it will be called on each
|
|
27
|
+
* request without needing to recreate the transport.
|
|
28
|
+
*
|
|
29
|
+
* The `onSessionChange` callback is kept in a ref so the transport always
|
|
30
|
+
* calls the latest version without needing to be recreated.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* import { useChat } from "@ai-sdk/react";
|
|
35
|
+
* import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
|
|
36
|
+
* import type { chat } from "@/trigger/chat";
|
|
37
|
+
*
|
|
38
|
+
* function Chat() {
|
|
39
|
+
* const transport = useTriggerChatTransport<typeof chat>({
|
|
40
|
+
* task: "ai-chat",
|
|
41
|
+
* accessToken: ({ chatId }) => fetchToken(chatId),
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* const { messages, sendMessage } = useChat({ transport });
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function useTriggerChatTransport<TTask extends AnyTask = AnyTask>(options: UseTriggerChatTransportOptions<TTask>): TriggerChatTransport;
|
|
49
|
+
/**
|
|
50
|
+
* Sync chat messages across browser tabs.
|
|
51
|
+
*
|
|
52
|
+
* Requires `multiTab: true` on the transport. Handles:
|
|
53
|
+
* - Tracking read-only state (`isReadOnly`) when another tab is active
|
|
54
|
+
* - Broadcasting messages from the active tab to other tabs
|
|
55
|
+
* - Receiving messages from other tabs and updating local state via `setMessages`
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* const transport = useTriggerChatTransport({ task: "my-chat", multiTab: true, accessToken });
|
|
60
|
+
* const { messages, setMessages } = useChat({ id: chatId, transport });
|
|
61
|
+
* const { isReadOnly } = useMultiTabChat(transport, chatId, messages, setMessages);
|
|
62
|
+
*
|
|
63
|
+
* <input disabled={isReadOnly} placeholder={isReadOnly ? "Active in another tab" : "Type a message..."} />
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function useMultiTabChat<T = unknown>(transport: TriggerChatTransport, chatId: string, messages: T[], setMessages: (messages: T[]) => void): {
|
|
67
|
+
isReadOnly: boolean;
|
|
68
|
+
};
|
|
69
|
+
/** A pending message tracked by `usePendingMessages`. */
|
|
70
|
+
export type PendingMessage = {
|
|
71
|
+
id: string;
|
|
72
|
+
text: string;
|
|
73
|
+
/** How this message is being handled. */
|
|
74
|
+
mode: "steering" | "queued";
|
|
75
|
+
/** Whether the backend confirmed this message was injected mid-response. */
|
|
76
|
+
injected: boolean;
|
|
77
|
+
};
|
|
78
|
+
/** Options for `usePendingMessages`. */
|
|
79
|
+
export type UsePendingMessagesOptions<TUIMessage extends UIMessage = UIMessage> = {
|
|
80
|
+
/** The chat transport instance. */
|
|
81
|
+
transport: TriggerChatTransport;
|
|
82
|
+
/** The chat session ID. */
|
|
83
|
+
chatId: string;
|
|
84
|
+
/** The current useChat status. */
|
|
85
|
+
status: string;
|
|
86
|
+
/** The current messages from useChat. */
|
|
87
|
+
messages: TUIMessage[];
|
|
88
|
+
/** The setMessages function from useChat. */
|
|
89
|
+
setMessages: (fn: TUIMessage[] | ((prev: TUIMessage[]) => TUIMessage[])) => void;
|
|
90
|
+
/** The sendMessage function from useChat. */
|
|
91
|
+
sendMessage: (message: {
|
|
92
|
+
text: string;
|
|
93
|
+
}, options?: ChatRequestOptions) => void;
|
|
94
|
+
/** Metadata to include when sending (e.g. `{ model }` for model selection). */
|
|
95
|
+
metadata?: Record<string, unknown>;
|
|
96
|
+
};
|
|
97
|
+
/** A message embedded in an injection point data part. */
|
|
98
|
+
export type InjectedMessage = {
|
|
99
|
+
id: string;
|
|
100
|
+
text: string;
|
|
101
|
+
};
|
|
102
|
+
/** Return value of `usePendingMessages`. */
|
|
103
|
+
export type UsePendingMessagesReturn = {
|
|
104
|
+
/** Current pending messages with their mode and injection status. */
|
|
105
|
+
pending: PendingMessage[];
|
|
106
|
+
/** Send a steering message during streaming, or a normal message when ready. */
|
|
107
|
+
steer: (text: string) => void;
|
|
108
|
+
/** Queue a message for the next turn (sent after current response finishes). */
|
|
109
|
+
queue: (text: string) => void;
|
|
110
|
+
/** Promote a queued message to a steering message (sends via input stream immediately). */
|
|
111
|
+
promoteToSteering: (id: string) => void;
|
|
112
|
+
/** Check if an assistant message part is an injection point. */
|
|
113
|
+
isInjectionPoint: (part: unknown) => boolean;
|
|
114
|
+
/** Get the injected message IDs from an injection point part. */
|
|
115
|
+
getInjectedMessageIds: (part: unknown) => string[];
|
|
116
|
+
/** Get the injected messages (id + text) from an injection point part. Self-contained — works after turn complete. */
|
|
117
|
+
getInjectedMessages: (part: unknown) => InjectedMessage[];
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* React hook for managing pending messages (steering) during streaming.
|
|
121
|
+
*
|
|
122
|
+
* Handles:
|
|
123
|
+
* - Sending messages via input stream during streaming (bypassing useChat)
|
|
124
|
+
* - Tracking which messages were injected mid-response vs queued for next turn
|
|
125
|
+
* - Inserting injected messages into the conversation on turn complete
|
|
126
|
+
* - Auto-sending non-injected messages as the next turn
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```tsx
|
|
130
|
+
* const pending = usePendingMessages({
|
|
131
|
+
* transport, chatId, status, messages, setMessages, sendMessage,
|
|
132
|
+
* metadata: { model },
|
|
133
|
+
* });
|
|
134
|
+
*
|
|
135
|
+
* // In the form:
|
|
136
|
+
* <form onSubmit={(e) => {
|
|
137
|
+
* e.preventDefault();
|
|
138
|
+
* pending.send(input);
|
|
139
|
+
* setInput("");
|
|
140
|
+
* }}>
|
|
141
|
+
*
|
|
142
|
+
* // Render pending messages:
|
|
143
|
+
* {pending.pending.map(msg => (
|
|
144
|
+
* <div key={msg.id}>{msg.text} — {msg.injected ? "Injected" : "Pending"}</div>
|
|
145
|
+
* ))}
|
|
146
|
+
*
|
|
147
|
+
* // Render injection points inline in assistant messages:
|
|
148
|
+
* {msg.parts.map((part, i) =>
|
|
149
|
+
* pending.isInjectionPoint(part)
|
|
150
|
+
* ? <InjectionMarker key={i} ids={pending.getInjectedMessageIds(part)} />
|
|
151
|
+
* : <Part key={i} part={part} />
|
|
152
|
+
* )}
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export declare function usePendingMessages<TUIMessage extends UIMessage = UIMessage>(options: UsePendingMessagesOptions<TUIMessage>): UsePendingMessagesReturn;
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* @module @trigger.dev/sdk/chat/react
|
|
4
|
+
*
|
|
5
|
+
* React hooks for AI SDK chat transport integration.
|
|
6
|
+
* Use alongside `@trigger.dev/sdk/chat` for a type-safe, ergonomic DX.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { useChat } from "@ai-sdk/react";
|
|
11
|
+
* import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
|
|
12
|
+
* import type { chat } from "@/trigger/chat";
|
|
13
|
+
*
|
|
14
|
+
* function Chat() {
|
|
15
|
+
* const transport = useTriggerChatTransport<typeof chat>({
|
|
16
|
+
* task: "ai-chat",
|
|
17
|
+
* accessToken: ({ chatId }) => fetchToken(chatId),
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* const { messages, sendMessage } = useChat({ transport });
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
25
|
+
import { TriggerChatTransport } from "./chat.js";
|
|
26
|
+
import { PENDING_MESSAGE_INJECTED_TYPE, } from "./ai-shared.js";
|
|
27
|
+
/**
|
|
28
|
+
* React hook that creates and memoizes a `TriggerChatTransport` instance.
|
|
29
|
+
*
|
|
30
|
+
* The transport is created once on first render and reused for the lifetime
|
|
31
|
+
* of the component. This avoids the need for `useMemo` and ensures the
|
|
32
|
+
* transport's internal session state (run IDs, lastEventId, etc.)
|
|
33
|
+
* is preserved across re-renders.
|
|
34
|
+
*
|
|
35
|
+
* For dynamic access tokens, pass a function — it will be called on each
|
|
36
|
+
* request without needing to recreate the transport.
|
|
37
|
+
*
|
|
38
|
+
* The `onSessionChange` callback is kept in a ref so the transport always
|
|
39
|
+
* calls the latest version without needing to be recreated.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* import { useChat } from "@ai-sdk/react";
|
|
44
|
+
* import { useTriggerChatTransport } from "@trigger.dev/sdk/chat/react";
|
|
45
|
+
* import type { chat } from "@/trigger/chat";
|
|
46
|
+
*
|
|
47
|
+
* function Chat() {
|
|
48
|
+
* const transport = useTriggerChatTransport<typeof chat>({
|
|
49
|
+
* task: "ai-chat",
|
|
50
|
+
* accessToken: ({ chatId }) => fetchToken(chatId),
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* const { messages, sendMessage } = useChat({ transport });
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function useTriggerChatTransport(options) {
|
|
58
|
+
const ref = useRef(null);
|
|
59
|
+
if (ref.current === null) {
|
|
60
|
+
ref.current = new TriggerChatTransport(options);
|
|
61
|
+
}
|
|
62
|
+
// Keep callbacks up to date without recreating the transport.
|
|
63
|
+
const { onSessionChange, clientData } = options;
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
ref.current?.setOnSessionChange(onSessionChange);
|
|
66
|
+
}, [onSessionChange]);
|
|
67
|
+
// Keep `clientData` up to date so the transport's per-turn merge and
|
|
68
|
+
// `startSession` callback both see the latest value without
|
|
69
|
+
// reconstructing the transport.
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
ref.current?.setClientData(clientData);
|
|
72
|
+
}, [clientData]);
|
|
73
|
+
// Note: dispose() is NOT called in effect cleanup because React strict mode
|
|
74
|
+
// runs cleanup+re-setup, but the transport lives in a ref and isn't recreated.
|
|
75
|
+
// Calling dispose() would permanently close the BroadcastChannel.
|
|
76
|
+
// The coordinator's beforeunload handler handles tab close cleanup instead.
|
|
77
|
+
return ref.current;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Sync chat messages across browser tabs.
|
|
81
|
+
*
|
|
82
|
+
* Requires `multiTab: true` on the transport. Handles:
|
|
83
|
+
* - Tracking read-only state (`isReadOnly`) when another tab is active
|
|
84
|
+
* - Broadcasting messages from the active tab to other tabs
|
|
85
|
+
* - Receiving messages from other tabs and updating local state via `setMessages`
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* const transport = useTriggerChatTransport({ task: "my-chat", multiTab: true, accessToken });
|
|
90
|
+
* const { messages, setMessages } = useChat({ id: chatId, transport });
|
|
91
|
+
* const { isReadOnly } = useMultiTabChat(transport, chatId, messages, setMessages);
|
|
92
|
+
*
|
|
93
|
+
* <input disabled={isReadOnly} placeholder={isReadOnly ? "Active in another tab" : "Type a message..."} />
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export function useMultiTabChat(transport, chatId, messages, setMessages) {
|
|
97
|
+
const [isReadOnly, setIsReadOnly] = useState(() => transport.isReadOnly(chatId));
|
|
98
|
+
// Track read-only state
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
const listener = (id, readOnly) => {
|
|
101
|
+
if (id === chatId)
|
|
102
|
+
setIsReadOnly(readOnly);
|
|
103
|
+
};
|
|
104
|
+
transport.addReadOnlyListener(listener);
|
|
105
|
+
setIsReadOnly(transport.isReadOnly(chatId));
|
|
106
|
+
return () => transport.removeReadOnlyListener(listener);
|
|
107
|
+
}, [transport, chatId]);
|
|
108
|
+
// Active tab: broadcast messages to other tabs on change.
|
|
109
|
+
// Only broadcast when THIS tab holds the claim (is the current sender).
|
|
110
|
+
// Deferred via requestIdleCallback so the structured clone in
|
|
111
|
+
// BroadcastChannel.postMessage never blocks rendering during streaming.
|
|
112
|
+
const idleRef = useRef(null);
|
|
113
|
+
const latestMessagesRef = useRef(messages);
|
|
114
|
+
latestMessagesRef.current = messages;
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (!transport.hasClaim(chatId) || messages.length === 0)
|
|
117
|
+
return;
|
|
118
|
+
if (idleRef.current !== null)
|
|
119
|
+
return; // Already scheduled
|
|
120
|
+
const schedule = typeof requestIdleCallback === "function"
|
|
121
|
+
? requestIdleCallback
|
|
122
|
+
: (fn) => setTimeout(fn, 50);
|
|
123
|
+
idleRef.current = schedule(() => {
|
|
124
|
+
idleRef.current = null;
|
|
125
|
+
if (transport.hasClaim(chatId)) {
|
|
126
|
+
transport.broadcastMessages(chatId, latestMessagesRef.current);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}, [transport, chatId, messages]);
|
|
130
|
+
// Flush final state when claim is released (turn complete)
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (!transport.hasClaim(chatId) && latestMessagesRef.current.length > 0) {
|
|
133
|
+
if (idleRef.current !== null) {
|
|
134
|
+
const cancel = typeof cancelIdleCallback === "function"
|
|
135
|
+
? cancelIdleCallback
|
|
136
|
+
: clearTimeout;
|
|
137
|
+
cancel(idleRef.current);
|
|
138
|
+
idleRef.current = null;
|
|
139
|
+
}
|
|
140
|
+
transport.broadcastMessages(chatId, latestMessagesRef.current);
|
|
141
|
+
}
|
|
142
|
+
}, [transport, chatId, isReadOnly]);
|
|
143
|
+
// Read-only tab: receive messages from the active tab
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
const listener = (id, msgs) => {
|
|
146
|
+
if (id === chatId) {
|
|
147
|
+
setMessages(msgs);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
transport.addMessagesListener(listener);
|
|
151
|
+
return () => transport.removeMessagesListener(listener);
|
|
152
|
+
}, [transport, chatId, setMessages]);
|
|
153
|
+
return { isReadOnly };
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* React hook for managing pending messages (steering) during streaming.
|
|
157
|
+
*
|
|
158
|
+
* Handles:
|
|
159
|
+
* - Sending messages via input stream during streaming (bypassing useChat)
|
|
160
|
+
* - Tracking which messages were injected mid-response vs queued for next turn
|
|
161
|
+
* - Inserting injected messages into the conversation on turn complete
|
|
162
|
+
* - Auto-sending non-injected messages as the next turn
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```tsx
|
|
166
|
+
* const pending = usePendingMessages({
|
|
167
|
+
* transport, chatId, status, messages, setMessages, sendMessage,
|
|
168
|
+
* metadata: { model },
|
|
169
|
+
* });
|
|
170
|
+
*
|
|
171
|
+
* // In the form:
|
|
172
|
+
* <form onSubmit={(e) => {
|
|
173
|
+
* e.preventDefault();
|
|
174
|
+
* pending.send(input);
|
|
175
|
+
* setInput("");
|
|
176
|
+
* }}>
|
|
177
|
+
*
|
|
178
|
+
* // Render pending messages:
|
|
179
|
+
* {pending.pending.map(msg => (
|
|
180
|
+
* <div key={msg.id}>{msg.text} — {msg.injected ? "Injected" : "Pending"}</div>
|
|
181
|
+
* ))}
|
|
182
|
+
*
|
|
183
|
+
* // Render injection points inline in assistant messages:
|
|
184
|
+
* {msg.parts.map((part, i) =>
|
|
185
|
+
* pending.isInjectionPoint(part)
|
|
186
|
+
* ? <InjectionMarker key={i} ids={pending.getInjectedMessageIds(part)} />
|
|
187
|
+
* : <Part key={i} part={part} />
|
|
188
|
+
* )}
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export function usePendingMessages(options) {
|
|
192
|
+
const { transport, chatId, status, messages, setMessages, sendMessage, metadata } = options;
|
|
193
|
+
const [pendingMsgs, setPendingMsgs] = useState([]);
|
|
194
|
+
const injectedIdsRef = useRef(new Set());
|
|
195
|
+
const prevStatusRef = useRef(status);
|
|
196
|
+
// Watch for injection confirmation chunks in streaming messages
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
if (status !== "streaming")
|
|
199
|
+
return;
|
|
200
|
+
let newlyInjected = false;
|
|
201
|
+
for (const msg of messages) {
|
|
202
|
+
if (msg.role !== "assistant")
|
|
203
|
+
continue;
|
|
204
|
+
for (const part of msg.parts ?? []) {
|
|
205
|
+
if (part.type === PENDING_MESSAGE_INJECTED_TYPE) {
|
|
206
|
+
const messageIds = part.data?.messageIds;
|
|
207
|
+
if (Array.isArray(messageIds)) {
|
|
208
|
+
for (const id of messageIds) {
|
|
209
|
+
if (!injectedIdsRef.current.has(id)) {
|
|
210
|
+
injectedIdsRef.current.add(id);
|
|
211
|
+
newlyInjected = true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Remove injected steering messages from the pending overlay immediately
|
|
219
|
+
if (newlyInjected) {
|
|
220
|
+
setPendingMsgs((prev) => prev.filter((m) => !injectedIdsRef.current.has(m.id)));
|
|
221
|
+
}
|
|
222
|
+
}, [status, messages]);
|
|
223
|
+
// Handle turn completion
|
|
224
|
+
useEffect(() => {
|
|
225
|
+
const turnCompleted = prevStatusRef.current === "streaming" && status === "ready";
|
|
226
|
+
prevStatusRef.current = status;
|
|
227
|
+
if (!turnCompleted)
|
|
228
|
+
return;
|
|
229
|
+
// Auto-send non-injected messages as the next turn.
|
|
230
|
+
// This includes queued messages AND steering messages that weren't
|
|
231
|
+
// injected (arrived too late, no prepareStep boundary, etc.).
|
|
232
|
+
// Note: steering messages were also sent via sendPendingMessage to
|
|
233
|
+
// the backend's wire buffer, so the backend may already have them.
|
|
234
|
+
// Calling sendMessage here ensures useChat subscribes to the response.
|
|
235
|
+
const toSend = pendingMsgs.filter((m) => !injectedIdsRef.current.has(m.id));
|
|
236
|
+
// Clean up
|
|
237
|
+
setPendingMsgs([]);
|
|
238
|
+
injectedIdsRef.current.clear();
|
|
239
|
+
promotedIdsRef.current.clear();
|
|
240
|
+
// Auto-send as next turn
|
|
241
|
+
if (toSend.length > 0) {
|
|
242
|
+
const text = toSend.map((m) => m.parts?.[0]?.text ?? "").join("\n");
|
|
243
|
+
sendMessage({ text }, metadata ? { metadata } : undefined);
|
|
244
|
+
}
|
|
245
|
+
}, [status, pendingMsgs, sendMessage, metadata, messages]);
|
|
246
|
+
// Send a steering message (injected mid-response via prepareStep)
|
|
247
|
+
const steer = useCallback((text) => {
|
|
248
|
+
if (status === "streaming") {
|
|
249
|
+
const msg = {
|
|
250
|
+
id: crypto.randomUUID(),
|
|
251
|
+
role: "user",
|
|
252
|
+
parts: [{ type: "text", text }],
|
|
253
|
+
_mode: "steering",
|
|
254
|
+
};
|
|
255
|
+
transport.sendPendingMessage(chatId, msg, metadata);
|
|
256
|
+
setPendingMsgs((prev) => [...prev, msg]);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
// Not streaming — just send normally
|
|
260
|
+
sendMessage({ text }, metadata ? { metadata } : undefined);
|
|
261
|
+
}
|
|
262
|
+
}, [status, transport, chatId, sendMessage, metadata]);
|
|
263
|
+
// Queue a message for the next turn (no injection attempt)
|
|
264
|
+
const queue = useCallback((text) => {
|
|
265
|
+
if (status === "streaming") {
|
|
266
|
+
const msg = {
|
|
267
|
+
id: crypto.randomUUID(),
|
|
268
|
+
role: "user",
|
|
269
|
+
parts: [{ type: "text", text }],
|
|
270
|
+
_mode: "queued",
|
|
271
|
+
};
|
|
272
|
+
setPendingMsgs((prev) => [...prev, msg]);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
sendMessage({ text }, metadata ? { metadata } : undefined);
|
|
276
|
+
}
|
|
277
|
+
}, [status, sendMessage, metadata]);
|
|
278
|
+
// Promote a queued message to steering (send via input stream immediately)
|
|
279
|
+
const promotedIdsRef = useRef(new Set());
|
|
280
|
+
const promoteToSteering = useCallback((id) => {
|
|
281
|
+
// Guard against double-click — ref check is synchronous
|
|
282
|
+
if (promotedIdsRef.current.has(id)) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
promotedIdsRef.current.add(id);
|
|
286
|
+
setPendingMsgs((prev) => {
|
|
287
|
+
const msg = prev.find((m) => m.id === id);
|
|
288
|
+
if (!msg || msg._mode !== "queued")
|
|
289
|
+
return prev;
|
|
290
|
+
transport.sendPendingMessage(chatId, msg, metadata);
|
|
291
|
+
return prev.map((m) => (m.id === id ? { ...m, _mode: "steering" } : m));
|
|
292
|
+
});
|
|
293
|
+
}, [transport, chatId, metadata]);
|
|
294
|
+
const isInjectionPoint = useCallback((part) => typeof part === "object" &&
|
|
295
|
+
part !== null &&
|
|
296
|
+
part.type === PENDING_MESSAGE_INJECTED_TYPE, []);
|
|
297
|
+
const getInjectedMessageIds = useCallback((part) => {
|
|
298
|
+
if (!isInjectionPoint(part))
|
|
299
|
+
return [];
|
|
300
|
+
const ids = part.data?.messageIds;
|
|
301
|
+
return Array.isArray(ids) ? ids : [];
|
|
302
|
+
}, [isInjectionPoint]);
|
|
303
|
+
const getInjectedMessages = useCallback((part) => {
|
|
304
|
+
if (!isInjectionPoint(part))
|
|
305
|
+
return [];
|
|
306
|
+
const msgs = part.data?.messages;
|
|
307
|
+
return Array.isArray(msgs) ? msgs : [];
|
|
308
|
+
}, [isInjectionPoint]);
|
|
309
|
+
const pending = pendingMsgs.map((m) => ({
|
|
310
|
+
id: m.id,
|
|
311
|
+
text: m.parts?.[0]?.text ?? "",
|
|
312
|
+
mode: m._mode,
|
|
313
|
+
injected: injectedIdsRef.current.has(m.id),
|
|
314
|
+
}));
|
|
315
|
+
return {
|
|
316
|
+
pending,
|
|
317
|
+
steer,
|
|
318
|
+
queue,
|
|
319
|
+
promoteToSteering,
|
|
320
|
+
isInjectionPoint,
|
|
321
|
+
getInjectedMessageIds,
|
|
322
|
+
getInjectedMessages,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=chat-react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-react.js","sourceRoot":"","sources":["../../../src/v3/chat-react.ts"],"names":[],"mappings":"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"}
|