@blocksdiy/react-common 1.62.1 → 1.63.0
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/components/new-agent-chat.d.ts +10 -0
- package/dist/components/new-agent-chat.d.ts.map +1 -1
- package/dist/components/new-agent-chat.js +62 -36
- package/dist/hooks/agent-conversation-context.d.ts +2 -2
- package/dist/hooks/agent-conversation-context.d.ts.map +1 -1
- package/dist/hooks/agent-conversation-context.js +11 -2
- package/dist/hooks/agent-thread-live-update.d.ts +18 -5
- package/dist/hooks/agent-thread-live-update.d.ts.map +1 -1
- package/dist/hooks/agent-thread-live-update.js +14 -7
- package/dist/hooks/agent-thread-store.d.ts +5 -2
- package/dist/hooks/agent-thread-store.d.ts.map +1 -1
- package/dist/hooks/agent-thread-store.js +6 -3
- package/dist/hooks/floating-agent-chat.d.ts +1 -4
- package/dist/hooks/floating-agent-chat.d.ts.map +1 -1
- package/dist/hooks/floating-agent-chat.js +2 -5
- package/dist/hooks/use-agent-conversation.d.ts +8 -8
- package/dist/hooks/use-agent-conversation.d.ts.map +1 -1
- package/dist/hooks/use-agent-conversation.js +10 -10
- package/dist/hooks/use-agent-thread.d.ts.map +1 -1
- package/dist/hooks/use-agent-thread.js +3 -6
- package/dist/hooks/use-agent-threads.d.ts +18 -8
- package/dist/hooks/use-agent-threads.d.ts.map +1 -1
- package/dist/hooks/use-agent-threads.js +14 -15
- package/dist/utils/agent-chat-resume.d.ts +3 -0
- package/dist/utils/agent-chat-resume.d.ts.map +1 -0
- package/dist/utils/agent-chat-resume.js +15 -0
- package/dist/utils/legacy-chat-thread-id.d.ts +23 -0
- package/dist/utils/legacy-chat-thread-id.d.ts.map +1 -0
- package/dist/utils/legacy-chat-thread-id.js +83 -0
- package/package.json +1 -1
|
@@ -124,9 +124,19 @@ export interface AgentChatRootProps {
|
|
|
124
124
|
useAgentBlockDirectChat?: boolean;
|
|
125
125
|
agentChatId?: string;
|
|
126
126
|
componentIds?: string[];
|
|
127
|
+
/**
|
|
128
|
+
* The thread to open. Without it (and without the deprecated `chatId`), a signed-in chat
|
|
129
|
+
* resumes the user's most recent thread of the agent, else starts a new one; a chat with
|
|
130
|
+
* `noPersistency` (an anonymous visitor) starts a new one on every mount — an app that wants
|
|
131
|
+
* resume persists the thread id and passes it here.
|
|
132
|
+
*/
|
|
127
133
|
defaultThreadId?: string;
|
|
128
134
|
noPersistency?: boolean;
|
|
129
135
|
children?: ReactNode;
|
|
136
|
+
/**
|
|
137
|
+
* @deprecated Pass `defaultThreadId`. A `chatId` alone (without `noPersistency`) opens the
|
|
138
|
+
* thread derived from it (`legacyChatThreadId`), the one the server derives for the same `chatId`.
|
|
139
|
+
*/
|
|
130
140
|
chatId?: string;
|
|
131
141
|
/**
|
|
132
142
|
* What every run sends the agent as `chatContext`, serialized as the run starts — so a value
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,OAAO,EAAoB,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAI9G,OAAO,EAAiB,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAEL,SAAS,EACT,cAAc,EAQf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -7,9 +7,11 @@ import { createContext, useCallback, useContext, useEffect, useLayoutEffect, use
|
|
|
7
7
|
import { useStickToBottom } from "use-stick-to-bottom";
|
|
8
8
|
import { AgentChatOwnRunsContext } from "../hooks/agent-chat-own-runs.js";
|
|
9
9
|
import { readAgentAdminRoles } from "../utils/agent-admin.js";
|
|
10
|
+
import { resumedThreadId, resumeThreadQuery } from "../utils/agent-chat-resume.js";
|
|
10
11
|
import { answerRouteOf, approvalCardsForToolCall, buildResumeEntries, cancelledResumeEntries, dropStamps, forgetOpenInterrupts, INTERRUPT_NOT_OPEN_ERROR, isApprovalRequest, localStampsByAnchor, mergeStamps, needsReconnectAfter, requestKey, requestsOf, respondMessageOf, singleInterruptResume, stampsAfterInterruptReset, titleOf, toolCallDisplayNameOf, toolCallOf, } from "../utils/agui-interrupts.js";
|
|
11
12
|
import { ComposeRender } from "../utils/compose-render.js";
|
|
12
13
|
import { buildArmedMessageContent, userTextOfContent } from "../utils/composer-message.js";
|
|
14
|
+
import { forwardedLegacyChatId, pinnedLegacyChatThreadId } from "../utils/legacy-chat-thread-id.js";
|
|
13
15
|
import { claimRunInput, EMPTY_MESSAGE_RUN_IDS, EMPTY_RUN_STARTED_AT, findMessageGroupElement, mergeEntries, MESSAGE_IDS_ATTRIBUTE, messageIdsOfRun, readMessageRunIdsEvent, readRunStartedAtEvent, } from "../utils/message-run-ids.js";
|
|
14
16
|
export { useTextGrowthAnimating } from "../hooks/text-growth-animation.js";
|
|
15
17
|
export { FEEDBACK_MESSAGE_NAME, feedbackComposerMeta, feedbackDraftOf, feedbackMessage, feedbackThreadId, isFeedbackMessage, isFeedbackTag, parseFeedbackContent, parseFeedbackTag, } from "../utils/composer-message.js";
|
|
@@ -25,10 +27,6 @@ export const getAgentChatComponentToolName = (name) => {
|
|
|
25
27
|
};
|
|
26
28
|
const MAX_FILE_SIZE_MB = 5;
|
|
27
29
|
const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
|
|
28
|
-
// CopilotKit v2 requires a UUID `thread_id`; non-UUIDs get replaced per
|
|
29
|
-
// load and break history. Fixed UUID is fine — rows are scoped by
|
|
30
|
-
// (appId, chatId, threadId) and chatId is already per-chat unique.
|
|
31
|
-
const DEFAULT_CHAT_THREAD_ID = "8e1c8e4e-7b15-4f2c-a3d8-9e7f6c2b1a3e";
|
|
32
30
|
const HIDDEN_INITIAL_PROMPT_MESSAGE_NAME = "__agent_chat_hidden_initial_prompt__";
|
|
33
31
|
const generateId = (length = 10) => {
|
|
34
32
|
return Math.random()
|
|
@@ -230,7 +228,7 @@ const SessionReadables = () => {
|
|
|
230
228
|
// });
|
|
231
229
|
return null;
|
|
232
230
|
};
|
|
233
|
-
const ChatInitializer = ({ agentBlock, agentChatBlock,
|
|
231
|
+
const ChatInitializer = ({ agentBlock, agentChatBlock, token, appId, components, componentsLoading, currentThreadId, setCurrentThreadId, children, onUserMessageSent, disableInitialPrompt, readChatContext, }) => {
|
|
234
232
|
const [agentChat, setAgentChat] = useState(null);
|
|
235
233
|
const [agent, setAgent] = useState(null);
|
|
236
234
|
// `isConfigLoaded` covers the (small, parallel) async fetch of the
|
|
@@ -243,7 +241,6 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
243
241
|
// Current chat session; the connect effect below and the readiness latch
|
|
244
242
|
// key off it so they reset together on a thread/agent swap.
|
|
245
243
|
const initKey = [
|
|
246
|
-
chatId ?? "",
|
|
247
244
|
currentThreadId ?? "",
|
|
248
245
|
agentBlock?.id ?? "",
|
|
249
246
|
agentChatBlock?.id ?? "",
|
|
@@ -398,7 +395,7 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
398
395
|
const isRunningElsewhere = runningElsewhereRunId !== null && !ownRunInFlight && !ownRunIdsRef.current.has(runningElsewhereRunId);
|
|
399
396
|
const isRunningElsewhereRef = useRef(isRunningElsewhere);
|
|
400
397
|
isRunningElsewhereRef.current = isRunningElsewhere;
|
|
401
|
-
const conversationKey =
|
|
398
|
+
const conversationKey = currentThreadId ?? "";
|
|
402
399
|
const prevConversationKeyRef = useRef(conversationKey);
|
|
403
400
|
useIsomorphicLayoutEffect(() => {
|
|
404
401
|
if (prevConversationKeyRef.current === conversationKey) {
|
|
@@ -424,21 +421,6 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
424
421
|
});
|
|
425
422
|
}
|
|
426
423
|
}, [conversationKey]);
|
|
427
|
-
const prevConnectionRef = useRef({ chatId, threadId: currentThreadId });
|
|
428
|
-
useEffect(() => {
|
|
429
|
-
const previous = prevConnectionRef.current;
|
|
430
|
-
prevConnectionRef.current = { chatId, threadId: currentThreadId };
|
|
431
|
-
const chatIdChanged = previous.chatId !== chatId;
|
|
432
|
-
const threadIdChanged = previous.threadId !== currentThreadId;
|
|
433
|
-
if (!copilotAgent || !chatIdChanged || threadIdChanged) {
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
copilotAgent.setState?.({});
|
|
437
|
-
copilotAgent.clearReplayCursor?.(currentThreadId);
|
|
438
|
-
// Answers and decided-here stamps too; the connect re-sends what is open.
|
|
439
|
-
resetInterrupts();
|
|
440
|
-
void copilotkit.connectAgent({ agent: copilotAgent }).catch(() => undefined);
|
|
441
|
-
}, [chatId, currentThreadId, copilotAgent, copilotkit, resetInterrupts]);
|
|
442
424
|
const [isDraggingFiles, setIsDraggingFiles] = useState(false);
|
|
443
425
|
const attachmentsEnabled = agentChat ? agentChat.disableAttachments !== true : false;
|
|
444
426
|
const canSendMessage = Boolean(agentChatBlock && agentChat && agent && isConfigLoaded && isAgentReady && !isAgentRunning && !isRunningElsewhere);
|
|
@@ -741,7 +723,7 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
741
723
|
initialPromptSentRef.current = false;
|
|
742
724
|
};
|
|
743
725
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
744
|
-
}, [
|
|
726
|
+
}, [currentThreadId, agentBlock?.id, agentChatBlock?.id, token, appId]);
|
|
745
727
|
// After CopilotKit's `connectAgent` resolves, the agent's message list
|
|
746
728
|
// already reflects whatever the backend replayed (history + any
|
|
747
729
|
// seeded initial messages). If the thread is still empty AND the
|
|
@@ -1005,17 +987,24 @@ export const AgentChatRoot = ({ ...props
|
|
|
1005
987
|
...(socketId ? { "x-socket-id": socketId } : {}),
|
|
1006
988
|
...(appId ? { "x-app-id": appId } : {}),
|
|
1007
989
|
}), [token, socketId, appId]);
|
|
1008
|
-
|
|
1009
|
-
//
|
|
990
|
+
// The thread the host names: `defaultThreadId`, else the one a deprecated `chatId` stands for.
|
|
991
|
+
// Not with `noPersistency`: such a chat always ran on a fresh thread per mount, whatever its
|
|
992
|
+
// `chatId` — deriving one would put every anonymous visitor in one shared conversation.
|
|
993
|
+
const legacyThreadId = pinnedLegacyChatThreadId({ chatId, defaultThreadId, noPersistency });
|
|
994
|
+
const pinnedThreadId = defaultThreadId ?? legacyThreadId;
|
|
995
|
+
// CopilotKit v2 needs a UUID `thread_id`, fixed before it connects. Null while a signed-in
|
|
996
|
+
// chat with nothing pinned looks up the thread to resume (the effect below).
|
|
997
|
+
const [currentThreadId, setCurrentThreadId] = useState(() => pinnedThreadId ?? (noPersistency ? crypto.randomUUID() : null));
|
|
998
|
+
// Follow later pinned-thread changes — a mounted chat can be pointed at another
|
|
1010
999
|
// conversation (the agent inbox switches threads without remounting). Adjusted during
|
|
1011
|
-
// render (the React derived-state pattern) so children commit with the new thread
|
|
1012
|
-
//
|
|
1013
|
-
//
|
|
1014
|
-
const [
|
|
1015
|
-
if (
|
|
1016
|
-
|
|
1017
|
-
if (
|
|
1018
|
-
setCurrentThreadId(
|
|
1000
|
+
// render (the React derived-state pattern) so children commit with the new thread at
|
|
1001
|
+
// once; the headless connect effect keys on the configuration threadId and replays the
|
|
1002
|
+
// new transcript. Static-prop consumers never hit this branch.
|
|
1003
|
+
const [prevPinnedThreadId, setPrevPinnedThreadId] = useState(pinnedThreadId);
|
|
1004
|
+
if (pinnedThreadId !== prevPinnedThreadId) {
|
|
1005
|
+
setPrevPinnedThreadId(pinnedThreadId);
|
|
1006
|
+
if (pinnedThreadId && pinnedThreadId !== currentThreadId) {
|
|
1007
|
+
setCurrentThreadId(pinnedThreadId);
|
|
1019
1008
|
}
|
|
1020
1009
|
}
|
|
1021
1010
|
const blocksApiService = useMemo(() => new BlocksApiService({ token }), [token]);
|
|
@@ -1131,9 +1120,45 @@ export const AgentChatRoot = ({ ...props
|
|
|
1131
1120
|
superseded = true;
|
|
1132
1121
|
};
|
|
1133
1122
|
}, [getAgentChatBlock, getAgentBlock, getChatComponentBlocks, agentId, componentsKey]);
|
|
1134
|
-
|
|
1123
|
+
// Nothing pinned, signed in: resume the user's most recent thread of the agent, else start a
|
|
1124
|
+
// new one. The list is the caller's own (`private`); an anonymous caller lists nothing (the
|
|
1125
|
+
// server answers an empty list, or refuses), so any miss or failure starts a new thread —
|
|
1126
|
+
// never a shared one.
|
|
1127
|
+
const resolvedAgentId = agentBlock?.id;
|
|
1128
|
+
// A resumed thread belongs to its agent: pointed at another agent, look up again.
|
|
1129
|
+
const [resumedForAgentId, setResumedForAgentId] = useState(resolvedAgentId);
|
|
1130
|
+
if (resolvedAgentId !== resumedForAgentId) {
|
|
1131
|
+
setResumedForAgentId(resolvedAgentId);
|
|
1132
|
+
if (resumedForAgentId !== undefined && !pinnedThreadId && !noPersistency) {
|
|
1133
|
+
setCurrentThreadId(null);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const needsResume = currentThreadId === null;
|
|
1137
|
+
useEffect(() => {
|
|
1138
|
+
if (!needsResume || !resolvedAgentId) {
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
let cancelled = false;
|
|
1142
|
+
fetch(`${getApiHost()}/agent-threads/${encodeURIComponent(resolvedAgentId)}?${resumeThreadQuery()}`, { headers })
|
|
1143
|
+
.then((response) => (response.ok ? response.json() : null))
|
|
1144
|
+
.catch(() => null)
|
|
1145
|
+
.then((page) => {
|
|
1146
|
+
if (cancelled) {
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
const latest = resumedThreadId(page);
|
|
1150
|
+
setCurrentThreadId((current) => current ?? latest ?? crypto.randomUUID());
|
|
1151
|
+
});
|
|
1152
|
+
return () => {
|
|
1153
|
+
cancelled = true;
|
|
1154
|
+
};
|
|
1155
|
+
// `headers` is read once per lookup: a token refresh must not look up again.
|
|
1156
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1157
|
+
}, [needsResume, resolvedAgentId]);
|
|
1158
|
+
if (!appId || !agentBlock || !agentChatBlock || !currentThreadId) {
|
|
1135
1159
|
return null;
|
|
1136
1160
|
}
|
|
1161
|
+
const legacyChatId = forwardedLegacyChatId(chatId, legacyThreadId, currentThreadId);
|
|
1137
1162
|
return (_jsxs(CopilotKit, { runtimeUrl: `${getApiHost()}/agent-chat-stream`, useSingleEndpoint: true, agent: "default", headers: headers, threadId: currentThreadId,
|
|
1138
1163
|
// debug={true}
|
|
1139
1164
|
properties: {
|
|
@@ -1142,8 +1167,9 @@ export const AgentChatRoot = ({ ...props
|
|
|
1142
1167
|
agentHarness,
|
|
1143
1168
|
useAgentBlockDirectChat,
|
|
1144
1169
|
agentChatId: agentChatBlock.id,
|
|
1145
|
-
chatId,
|
|
1146
1170
|
noPersistency,
|
|
1171
|
+
// Deprecated: lets the server resume this chat's not-yet-backfilled legacy row.
|
|
1172
|
+
...(legacyChatId ? { chatId: legacyChatId } : {}),
|
|
1147
1173
|
chatContext: chatContextStr,
|
|
1148
1174
|
chatContextFiles,
|
|
1149
1175
|
supportsInterruptOutcome: true,
|
|
@@ -1153,7 +1179,7 @@ export const AgentChatRoot = ({ ...props
|
|
|
1153
1179
|
},
|
|
1154
1180
|
// Explicit false: when undefined, CopilotKit auto-enables its inspector
|
|
1155
1181
|
// devtools on localhost hostnames.
|
|
1156
|
-
enableInspector: false, children: [_jsx(SessionReadables, {}), _jsx(ChatInitializer, { agentBlock: agentBlock, agentChatBlock: agentChatBlock,
|
|
1182
|
+
enableInspector: false, children: [_jsx(SessionReadables, {}), _jsx(ChatInitializer, { agentBlock: agentBlock, agentChatBlock: agentChatBlock, noPersistency: noPersistency, token: token, appId: appId, components: components, componentsLoading: componentsLoading, currentThreadId: currentThreadId, setCurrentThreadId: setCurrentThreadId, onUserMessageSent: props.onUserMessageSent, disableInitialPrompt: props.disableInitialPrompt, readChatContext: readChatContext, children: children })] }));
|
|
1157
1183
|
};
|
|
1158
1184
|
export function AgentChatMessage({ message, index, ...props }) {
|
|
1159
1185
|
if (message.role === "user" && message.name === HIDDEN_INITIAL_PROMPT_MESSAGE_NAME) {
|
|
@@ -19,7 +19,7 @@ export interface AgentConversationContextValue {
|
|
|
19
19
|
/** After this client sends on the conversation (the chat root's onUserMessageSent). */
|
|
20
20
|
notifyMessageSent: UseAgentConversationResult["notifyMessageSent"];
|
|
21
21
|
}
|
|
22
|
-
export interface AgentConversationProviderProps extends Pick<UseAgentThreadsOptions, "token" | "headers" | "baseUrl"> {
|
|
22
|
+
export interface AgentConversationProviderProps extends Pick<UseAgentThreadsOptions, "token" | "headers" | "baseUrl" | "private" | "userId"> {
|
|
23
23
|
agentId: string;
|
|
24
24
|
conversation: AgentConversationRef;
|
|
25
25
|
isDraft: boolean;
|
|
@@ -31,7 +31,7 @@ export interface AgentConversationProviderProps extends Pick<UseAgentThreadsOpti
|
|
|
31
31
|
* The Root over the agent's whole index: the sidebar's list under its filters, and the open
|
|
32
32
|
* conversation's bridge to the chat. The agent-layout registry item renders it.
|
|
33
33
|
*/
|
|
34
|
-
export declare function AgentConversationProvider({ agentId, conversation, isDraft, chat, token, headers, baseUrl, children, }: AgentConversationProviderProps): import("react").JSX.Element;
|
|
34
|
+
export declare function AgentConversationProvider({ agentId, conversation, isDraft, chat, token, headers, baseUrl, private: privateOnly, userId, children, }: AgentConversationProviderProps): import("react").JSX.Element;
|
|
35
35
|
export type AgentThreadConversationProviderProps = AgentConversationProviderProps;
|
|
36
36
|
/**
|
|
37
37
|
* The Root over ONE conversation, with no index: the same bridge to the chat, fed by the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-conversation-context.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-conversation-context.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,SAAS,EAAwB,MAAM,OAAO,CAAC;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAEzB,KAAK,0BAA0B,EAChC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAmB,KAAK,sBAAsB,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE/G,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,sBAAsB,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEnF,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,oBAAoB,CAAC;IACnC,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,iHAAiH;IACjH,OAAO,EAAE,qBAAqB,CAAC;IAC/B,gGAAgG;IAChG,GAAG,EAAE,eAAe,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAClD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uFAAuF;IACvF,iBAAiB,EAAE,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;CACpE;AAID,MAAM,WAAW,8BAA+B,SAAQ,IAAI,
|
|
1
|
+
{"version":3,"file":"agent-conversation-context.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-conversation-context.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,SAAS,EAAwB,MAAM,OAAO,CAAC;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAEzB,KAAK,0BAA0B,EAChC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAmB,KAAK,sBAAsB,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE/G,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,sBAAsB,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEnF,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,oBAAoB,CAAC;IACnC,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,iHAAiH;IACjH,OAAO,EAAE,qBAAqB,CAAC;IAC/B,gGAAgG;IAChG,GAAG,EAAE,eAAe,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAClD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uFAAuF;IACvF,iBAAiB,EAAE,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;CACpE;AAID,MAAM,WAAW,8BAA+B,SAAQ,IAAI,CAC1D,sBAAsB,EACtB,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CACvD;IACC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,oBAAoB,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,2EAA2E;IAC3E,IAAI,EAAE,qBAAqB,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,OAAO,EACP,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,QAAQ,GACT,EAAE,8BAA8B,+BAyBhC;AAED,MAAM,MAAM,oCAAoC,GAAG,8BAA8B,CAAC;AAKlF;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,OAAO,EACP,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE,oCAAoC,+BAetC;AA2CD,eAAO,MAAM,2BAA2B,QAAO,6BAQ9C,CAAC"}
|
|
@@ -12,9 +12,18 @@ const AgentConversationContext = createContext(null);
|
|
|
12
12
|
* The Root over the agent's whole index: the sidebar's list under its filters, and the open
|
|
13
13
|
* conversation's bridge to the chat. The agent-layout registry item renders it.
|
|
14
14
|
*/
|
|
15
|
-
export function AgentConversationProvider({ agentId, conversation, isDraft, chat, token, headers, baseUrl, children, }) {
|
|
15
|
+
export function AgentConversationProvider({ agentId, conversation, isDraft, chat, token, headers, baseUrl, private: privateOnly, userId, children, }) {
|
|
16
16
|
const [filters, setFilters] = useState({});
|
|
17
|
-
const threads = useAgentThreads({
|
|
17
|
+
const threads = useAgentThreads({
|
|
18
|
+
agentId,
|
|
19
|
+
status: filters.status,
|
|
20
|
+
source: filters.source,
|
|
21
|
+
private: privateOnly,
|
|
22
|
+
userId,
|
|
23
|
+
token,
|
|
24
|
+
headers,
|
|
25
|
+
baseUrl,
|
|
26
|
+
});
|
|
18
27
|
return (_jsx(AgentConversationRoot, { agentId: agentId, conversation: conversation, isDraft: isDraft, chat: chat, threads: threads, filters: filters, setFilters: setFilters, children: children }));
|
|
19
28
|
}
|
|
20
29
|
const NO_FILTERS = {};
|
|
@@ -4,8 +4,14 @@ declare const THREAD_SOURCES: readonly ["direct_chat", "send_message", "feedback
|
|
|
4
4
|
export type AgentThreadSource = (typeof THREAD_SOURCES)[number] | "agent_call";
|
|
5
5
|
export interface AgentThreadItem {
|
|
6
6
|
agentId: string | null;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated A thread is the agent + `chatThreadId`; `chatId` is filled for old rows only and
|
|
9
|
+
* means nothing — never filter or key on it.
|
|
10
|
+
*/
|
|
11
|
+
chatId?: string | null;
|
|
8
12
|
chatThreadId: string;
|
|
13
|
+
/** The signed-in user who started the thread; null for anonymous visitors, channels and workflows. */
|
|
14
|
+
userId?: string | null;
|
|
9
15
|
source: AgentThreadSource;
|
|
10
16
|
status: AgentThreadStatus;
|
|
11
17
|
title: string | null;
|
|
@@ -18,11 +24,12 @@ export interface AgentThreadItem {
|
|
|
18
24
|
runningSince?: string | null;
|
|
19
25
|
runningRunId?: string | null;
|
|
20
26
|
}
|
|
21
|
-
|
|
27
|
+
/** A thread's identity within its agent: the thread id alone. */
|
|
28
|
+
export declare const agentThreadKey: (thread: Pick<AgentThreadItem, "chatThreadId">) => string;
|
|
22
29
|
export declare const isAgentThreadItem: (value: unknown) => value is AgentThreadItem;
|
|
23
30
|
export declare const provisionalThreadTitle: (prompt: string | undefined) => string | null;
|
|
24
31
|
export declare const optimisticThreadAfterSend: (thread: AgentThreadItem, previous: AgentThreadItem | undefined, prompt: string | undefined, now: string) => AgentThreadItem;
|
|
25
|
-
export type RemovedAgentThread = Pick<AgentThreadItem, "
|
|
32
|
+
export type RemovedAgentThread = Pick<AgentThreadItem, "chatThreadId" | "runningRunId">;
|
|
26
33
|
export declare const removeAgentThread: (threads: AgentThreadItem[], optimistic: ReadonlyMap<string, AgentThreadItem>, removed: RemovedAgentThread) => {
|
|
27
34
|
threads: AgentThreadItem[];
|
|
28
35
|
optimistic: ReadonlyMap<string, AgentThreadItem>;
|
|
@@ -30,7 +37,13 @@ export declare const removeAgentThread: (threads: AgentThreadItem[], optimistic:
|
|
|
30
37
|
export interface AgentThreadLiveUpdateOptions {
|
|
31
38
|
status?: AgentThreadStatus;
|
|
32
39
|
source?: AgentThreadSource;
|
|
33
|
-
|
|
40
|
+
/**
|
|
41
|
+
* The list shows only the current user's threads (`userId`) — a filter, not access control.
|
|
42
|
+
* Without `userId` a live update only refreshes rows already listed; it never adds one.
|
|
43
|
+
*/
|
|
44
|
+
private?: boolean;
|
|
45
|
+
/** The signed-in user's id, for `private`. */
|
|
46
|
+
userId?: string;
|
|
34
47
|
sort?: "lastActivity" | "firstSeen";
|
|
35
48
|
order?: "asc" | "desc";
|
|
36
49
|
hasMore?: boolean;
|
|
@@ -59,7 +72,7 @@ export interface AgentThreadGroupRows {
|
|
|
59
72
|
export declare const groupAgentThreads: (threads: readonly AgentThreadItem[]) => AgentThreadGroupRows[];
|
|
60
73
|
/** A thread the agent opened to act on feedback — by `type`, or by `source` for rows from before the column. */
|
|
61
74
|
export declare const isFeedbackThread: (row: Pick<AgentThreadItem, "type" | "source">) => boolean;
|
|
62
|
-
/** The conversation a feedback thread was opened from, when `threads` lists it (
|
|
75
|
+
/** The conversation a feedback thread was opened from, when `threads` lists it (the row's pointer). */
|
|
63
76
|
export declare const feedbackSourceThread: (row: AgentThreadItem, threads: readonly AgentThreadItem[]) => AgentThreadItem | undefined;
|
|
64
77
|
export {};
|
|
65
78
|
//# sourceMappingURL=agent-thread-live-update.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-thread-live-update.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-thread-live-update.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,eAAe,uEAAwE,CAAC;AAC9F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,QAAA,MAAM,cAAc,uFAAwF,CAAC;AAE7G,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-thread-live-update.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-thread-live-update.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
// Wire types and pure merge logic for the agent-threads index; dependency-free for tests.
|
|
2
2
|
const THREAD_STATUSES = ["idle", "interrupted", "waiting_on_agent", "busy", "error"];
|
|
3
3
|
const THREAD_SOURCES = ["direct_chat", "send_message", "feedback", "self_config_resume", "unknown"];
|
|
4
|
-
|
|
4
|
+
/** A thread's identity within its agent: the thread id alone. */
|
|
5
|
+
export const agentThreadKey = (thread) => thread.chatThreadId;
|
|
5
6
|
export const isAgentThreadItem = (value) => {
|
|
6
7
|
const item = value;
|
|
7
8
|
return (typeof item === "object" &&
|
|
8
9
|
item !== null &&
|
|
9
10
|
(typeof item.agentId === "string" || item.agentId === null) &&
|
|
10
|
-
typeof item.chatId === "string" &&
|
|
11
|
-
item.chatId.length > 0 &&
|
|
12
11
|
typeof item.chatThreadId === "string" &&
|
|
13
12
|
item.chatThreadId.length > 0 &&
|
|
14
13
|
THREAD_SOURCES.includes(item.source) &&
|
|
@@ -63,9 +62,11 @@ const sortTime = (item, sort) => {
|
|
|
63
62
|
const parsed = new Date(sort === "firstSeen" ? item.firstSeenAt : item.lastActivityAt).getTime();
|
|
64
63
|
return Number.isNaN(parsed) ? 0 : parsed;
|
|
65
64
|
};
|
|
65
|
+
// An update with no userId says nothing about whose the thread is (unknown, not "someone
|
|
66
|
+
// else's"), so it never takes a listed row out of a private list; it only cannot add one.
|
|
66
67
|
export const matchesAgentThreadFilters = (item, options = {}) => (!options.status || item.status === options.status) &&
|
|
67
68
|
(!options.source || item.source === options.source) &&
|
|
68
|
-
(!options.
|
|
69
|
+
(!options.private || options.userId === undefined || item.userId == null || item.userId === options.userId);
|
|
69
70
|
export const applyAgentThreadUpdate = (threads, incoming, options = {}) => {
|
|
70
71
|
const key = agentThreadKey(incoming);
|
|
71
72
|
const existing = threads.find((thread) => agentThreadKey(thread) === key);
|
|
@@ -76,6 +77,10 @@ export const applyAgentThreadUpdate = (threads, incoming, options = {}) => {
|
|
|
76
77
|
if (!matchesAgentThreadFilters(incoming, options)) {
|
|
77
78
|
return existing ? threads.filter((thread) => thread !== existing) : threads;
|
|
78
79
|
}
|
|
80
|
+
// A private list that cannot tell whose a new row is leaves it out — it may be another user's.
|
|
81
|
+
if (!existing && options.private && (options.userId === undefined || incoming.userId == null)) {
|
|
82
|
+
return threads;
|
|
83
|
+
}
|
|
79
84
|
const sort = options.sort ?? "lastActivity";
|
|
80
85
|
const direction = options.order === "asc" ? 1 : -1;
|
|
81
86
|
const next = existing ? threads.map((thread) => (thread === existing ? incoming : thread)) : [...threads, incoming];
|
|
@@ -99,11 +104,13 @@ export const overlayOptimisticThreads = (threads, optimistic, options = {}) => {
|
|
|
99
104
|
if (optimistic.size === 0) {
|
|
100
105
|
return threads;
|
|
101
106
|
}
|
|
107
|
+
// Optimistic rows are this client's own sends, so a private list keeps them.
|
|
108
|
+
const own = { ...options, private: false };
|
|
102
109
|
let merged = threads;
|
|
103
110
|
for (const [key, row] of optimistic) {
|
|
104
111
|
const handedOver = threads.some((thread) => agentThreadKey(thread) === key && thread.turnCount > row.turnCount);
|
|
105
112
|
if (!handedOver) {
|
|
106
|
-
merged = applyAgentThreadUpdate(merged, row,
|
|
113
|
+
merged = applyAgentThreadUpdate(merged, row, own);
|
|
107
114
|
}
|
|
108
115
|
}
|
|
109
116
|
return merged;
|
|
@@ -143,7 +150,7 @@ export const groupAgentThreads = (threads) => {
|
|
|
143
150
|
};
|
|
144
151
|
/** A thread the agent opened to act on feedback — by `type`, or by `source` for rows from before the column. */
|
|
145
152
|
export const isFeedbackThread = (row) => row.type === "feedback" || row.source === "feedback";
|
|
146
|
-
/** The conversation a feedback thread was opened from, when `threads` lists it (
|
|
153
|
+
/** The conversation a feedback thread was opened from, when `threads` lists it (the row's pointer). */
|
|
147
154
|
export const feedbackSourceThread = (row, threads) => row.fromSourceChatThreadId
|
|
148
|
-
? threads.find((candidate) => candidate.
|
|
155
|
+
? threads.find((candidate) => candidate.chatThreadId === row.fromSourceChatThreadId)
|
|
149
156
|
: undefined;
|
|
@@ -16,7 +16,7 @@ export type AgentThreadStoreEvent = {
|
|
|
16
16
|
};
|
|
17
17
|
export type AgentThreadStoreListener = (event: AgentThreadStoreEvent) => void;
|
|
18
18
|
/** Fetch one row by identity — the single-thread read; supplied by the acquiring reader (it holds the auth). */
|
|
19
|
-
export type AgentThreadFetcher = (conversation: Pick<AgentThreadItem, "
|
|
19
|
+
export type AgentThreadFetcher = (conversation: Pick<AgentThreadItem, "chatThreadId">) => Promise<AgentThreadItem>;
|
|
20
20
|
export interface AgentThreadStore {
|
|
21
21
|
readonly agentId: string;
|
|
22
22
|
/** The latest row known for a conversation (`agentThreadKey`), from any reader or the wire. */
|
|
@@ -41,7 +41,10 @@ export interface AgentThreadStoreTransport {
|
|
|
41
41
|
* dropped; equal passes, since renames keep lastActivityAt. The same rule the index applies.
|
|
42
42
|
*/
|
|
43
43
|
export declare const isNewerOrSameRow: (incoming: AgentThreadItem, cached: AgentThreadItem | undefined) => boolean;
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* The wire payload's identity, or null for a payload that names no conversation. The thread id
|
|
46
|
+
* alone: the payload's `chatId` is deprecated and ignored (the store is already the agent's).
|
|
47
|
+
*/
|
|
45
48
|
export declare const agentThreadEventIdentity: (data: unknown) => RemovedAgentThread | null;
|
|
46
49
|
declare const createRegistry: (transport: AgentThreadStoreTransport) => {
|
|
47
50
|
acquire: (agentId: string, options: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-thread-store.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-thread-store.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE;AAClD;;;GAGG;GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEvB,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAE9E,gHAAgH;AAChH,MAAM,MAAM,kBAAkB,GAAG,
|
|
1
|
+
{"version":3,"file":"agent-thread-store.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-thread-store.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE;AAClD;;;GAGG;GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEvB,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAE9E,gHAAgH;AAChH,MAAM,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+FAA+F;IAC/F,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IACjD,gGAAgG;IAChG,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI,CAAC;IAC1D,uFAAuF;IACvF,KAAK,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;CAC/C;AAED,gDAAgD;AAChD,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACjH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1E;AAOD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,UAAU,eAAe,EAAE,QAAQ,eAAe,GAAG,SAAS,KAAG,OACjB,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,MAAM,OAAO,KAAG,kBAAkB,GAAG,IAO7E,CAAC;AA+GF,QAAA,MAAM,cAAc,GAAI,WAAW,yBAAyB;uBAQ/C,MAAM,WACN;QAAE,WAAW,EAAE,kBAAkB,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAC9D;QAAE,KAAK,EAAE,gBAAgB,CAAC;QAAC,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE;;CAoCjG,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAEzE,0GAA0G;AAC1G,eAAO,MAAM,8BAA8B,GAAI,WAAW,yBAAyB,KAAG,wBAC3D,CAAC;AAO5B,eAAO,MAAM,uBAAuB,EAAE,wBAAwB,CAAC,SAAS,CAC7B,CAAC"}
|
|
@@ -17,14 +17,17 @@ const sortTime = (iso) => {
|
|
|
17
17
|
* dropped; equal passes, since renames keep lastActivityAt. The same rule the index applies.
|
|
18
18
|
*/
|
|
19
19
|
export const isNewerOrSameRow = (incoming, cached) => !cached || sortTime(incoming.lastActivityAt) >= sortTime(cached.lastActivityAt);
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* The wire payload's identity, or null for a payload that names no conversation. The thread id
|
|
22
|
+
* alone: the payload's `chatId` is deprecated and ignored (the store is already the agent's).
|
|
23
|
+
*/
|
|
21
24
|
export const agentThreadEventIdentity = (data) => {
|
|
22
25
|
const event = data;
|
|
23
26
|
const raw = event?.thread;
|
|
24
|
-
if (typeof raw?.
|
|
27
|
+
if (typeof raw?.chatThreadId !== "string" || raw.chatThreadId.length === 0) {
|
|
25
28
|
return null;
|
|
26
29
|
}
|
|
27
|
-
return {
|
|
30
|
+
return { chatThreadId: raw.chatThreadId, runningRunId: raw.runningRunId };
|
|
28
31
|
};
|
|
29
32
|
class AgentThreadStoreImpl {
|
|
30
33
|
agentId;
|
|
@@ -7,7 +7,7 @@ export interface FloatingAgentChatHandle {
|
|
|
7
7
|
isAdmin?: boolean;
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
|
-
/** What to open: a conversation (
|
|
10
|
+
/** What to open: a conversation (`{ chatThreadId }`; a deprecated `chatId` on it is ignored), or the new chat. */
|
|
11
11
|
export type FloatingAgentChatTarget = AgentConversationRef | "new";
|
|
12
12
|
/**
|
|
13
13
|
* How the open session shows: the floating prompt — the new chat as a one-line composer, until
|
|
@@ -39,15 +39,12 @@ export interface FloatingAgentChatOpenOptions<Handle extends FloatingAgentChatHa
|
|
|
39
39
|
/** The open options with the ids resolved from the handle. */
|
|
40
40
|
export interface FloatingAgentChatOpenRequest<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> extends Omit<FloatingAgentChatOpenOptions<Handle>, "target" | "face"> {
|
|
41
41
|
agentChatId: string;
|
|
42
|
-
/** The chat the agent's own conversations live under (agentInboxChatId). */
|
|
43
|
-
ownChatId: string;
|
|
44
42
|
target: FloatingAgentChatTarget;
|
|
45
43
|
face: FloatingAgentChatFace;
|
|
46
44
|
}
|
|
47
45
|
export interface FloatingAgentChatState<Handle extends FloatingAgentChatHandle = FloatingAgentChatHandle> {
|
|
48
46
|
agentChat: Handle;
|
|
49
47
|
agentChatId: string;
|
|
50
|
-
ownChatId: string;
|
|
51
48
|
conversation: AgentConversationRef;
|
|
52
49
|
/** The draft's thread id — the new chat, until its first send turns it into a thread. */
|
|
53
50
|
draftThreadId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-agent-chat.d.ts","sourceRoot":"","sources":["../../src/hooks/floating-agent-chat.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"floating-agent-chat.d.ts","sourceRoot":"","sources":["../../src/hooks/floating-agent-chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
// first send; "New chat" on an untouched draft keeps it; a thread opened beside it leaves it
|
|
7
7
|
// standing by. The reducers are pure and tested; the hook is the thin React shell.
|
|
8
8
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
9
|
-
import { agentInboxChatId } from "./use-agent-threads.js";
|
|
10
9
|
/** The panel shows the new chat, nothing sent on it yet. */
|
|
11
10
|
export const isFloatingAgentChatDraft = (state) => state.conversation.chatThreadId === state.draftThreadId && !state.draftSent;
|
|
12
11
|
/**
|
|
@@ -24,7 +23,6 @@ export const floatingAgentChatAfterOpen = (prev, request, mintThreadId) => {
|
|
|
24
23
|
const base = {
|
|
25
24
|
agentChat: request.agentChat,
|
|
26
25
|
agentChatId: request.agentChatId,
|
|
27
|
-
ownChatId: request.ownChatId,
|
|
28
26
|
face: request.face,
|
|
29
27
|
expandHref: request.expandHref,
|
|
30
28
|
newChatHref: request.newChatHref,
|
|
@@ -32,7 +30,7 @@ export const floatingAgentChatAfterOpen = (prev, request, mintThreadId) => {
|
|
|
32
30
|
};
|
|
33
31
|
const target = request.face === "prompt" ? "new" : request.target;
|
|
34
32
|
if (target !== "new") {
|
|
35
|
-
return { ...base, ...draft, conversation: target };
|
|
33
|
+
return { ...base, ...draft, conversation: { chatThreadId: target.chatThreadId } };
|
|
36
34
|
}
|
|
37
35
|
// A sent draft is a thread now; the new chat needs a fresh one.
|
|
38
36
|
const draftThreadId = draft.draftSent ? mintThreadId() : draft.draftThreadId;
|
|
@@ -40,7 +38,7 @@ export const floatingAgentChatAfterOpen = (prev, request, mintThreadId) => {
|
|
|
40
38
|
...base,
|
|
41
39
|
draftThreadId,
|
|
42
40
|
draftSent: false,
|
|
43
|
-
conversation: {
|
|
41
|
+
conversation: { chatThreadId: draftThreadId },
|
|
44
42
|
};
|
|
45
43
|
};
|
|
46
44
|
/**
|
|
@@ -83,7 +81,6 @@ export const useFloatingAgentChatController = () => {
|
|
|
83
81
|
return floatingAgentChatAfterOpen(prev, {
|
|
84
82
|
agentChat: options.agentChat,
|
|
85
83
|
agentChatId,
|
|
86
|
-
ownChatId: agentInboxChatId(agentChatId),
|
|
87
84
|
target: options.target ?? "new",
|
|
88
85
|
face: options.face ?? "panel",
|
|
89
86
|
expandHref: options.expandHref,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type AgentThreadItem } from "./agent-thread-live-update.js";
|
|
2
2
|
import type { UseAgentThreadsResult } from "./use-agent-threads.js";
|
|
3
|
-
/** A conversation is
|
|
4
|
-
export type AgentConversationRef = Pick<AgentThreadItem, "
|
|
3
|
+
/** A conversation is one thread of the agent, named by its thread id. */
|
|
4
|
+
export type AgentConversationRef = Pick<AgentThreadItem, "chatThreadId">;
|
|
5
5
|
/**
|
|
6
6
|
* A new chat is a draft: a thread id minted here, listed nowhere until the first send. "New
|
|
7
7
|
* chat" on an untouched draft keeps it; once sent, the draft is a thread like any other.
|
|
@@ -11,14 +11,14 @@ export interface AgentConversationSelection {
|
|
|
11
11
|
draftThreadId: string;
|
|
12
12
|
draftSent: boolean;
|
|
13
13
|
}
|
|
14
|
-
export declare const newDraftSelection: (
|
|
14
|
+
export declare const newDraftSelection: (draftThreadId?: string) => AgentConversationSelection;
|
|
15
15
|
/** A draft stands by even when the URL opens a thread: "New chat" from there must not mint twice. */
|
|
16
|
-
export declare const initialSelection: (
|
|
16
|
+
export declare const initialSelection: (urlConversation: AgentConversationRef | undefined) => AgentConversationSelection;
|
|
17
17
|
export declare const isDraftSelection: ({ conversation, draftThreadId, draftSent }: AgentConversationSelection) => boolean;
|
|
18
18
|
/** After choosing a thread; the same object when it is already open (no re-render). */
|
|
19
19
|
export declare const selectionWithThread: (prev: AgentConversationSelection, conversation: AgentConversationRef) => AgentConversationSelection;
|
|
20
20
|
/** After "New chat": an untouched draft stays; anything else mints a fresh one. */
|
|
21
|
-
export declare const selectionWithNewChat: (prev: AgentConversationSelection
|
|
21
|
+
export declare const selectionWithNewChat: (prev: AgentConversationSelection) => AgentConversationSelection;
|
|
22
22
|
/** After the first send on the draft; unchanged when the draft is not the open conversation. */
|
|
23
23
|
export declare const selectionAfterDraftSent: (prev: AgentConversationSelection) => AgentConversationSelection;
|
|
24
24
|
/** What the URL names: a thread, the new chat, or no conversation (one of the surface's pages). */
|
|
@@ -26,8 +26,8 @@ export type AgentConversationUrlTarget = AgentConversationRef | "new" | null;
|
|
|
26
26
|
/** Identity of a URL target; the selection follows the URL whenever this changes. */
|
|
27
27
|
export declare const urlSelectionKey: (target: AgentConversationUrlTarget) => string | null;
|
|
28
28
|
export interface UseAgentConversationSelectionOptions {
|
|
29
|
-
/**
|
|
30
|
-
ownChatId
|
|
29
|
+
/** @deprecated Ignored — threads no longer live under a chat. */
|
|
30
|
+
ownChatId?: string;
|
|
31
31
|
urlTarget: AgentConversationUrlTarget;
|
|
32
32
|
}
|
|
33
33
|
export interface UseAgentConversationSelectionResult {
|
|
@@ -41,7 +41,7 @@ export interface UseAgentConversationSelectionResult {
|
|
|
41
41
|
* The open conversation follows the URL — the one source of truth, so choosing a thread is a
|
|
42
42
|
* navigation, never a call here; the draft is local state.
|
|
43
43
|
*/
|
|
44
|
-
export declare const useAgentConversationSelection: ({
|
|
44
|
+
export declare const useAgentConversationSelection: ({ urlTarget, }: UseAgentConversationSelectionOptions) => UseAgentConversationSelectionResult;
|
|
45
45
|
export declare const RUN_STALE_MS: number;
|
|
46
46
|
/** A row for a conversation the index lists nothing for (yet): the draft, or a thread whose row has not landed. */
|
|
47
47
|
export declare const agentThreadStandIn: (agentId: string, conversation: AgentConversationRef, isDraft: boolean) => AgentThreadItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-agent-conversation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-conversation.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,4BAA4B,CAAC;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,
|
|
1
|
+
{"version":3,"file":"use-agent-conversation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,21 +6,21 @@ import { useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
|
6
6
|
import { FEEDBACK_MESSAGE_NAME } from "../utils/composer-message.js";
|
|
7
7
|
import { AgentChatOwnRunsContext } from "./agent-chat-own-runs.js";
|
|
8
8
|
import { agentThreadKey } from "./agent-thread-live-update.js";
|
|
9
|
-
export const newDraftSelection = (
|
|
10
|
-
conversation: {
|
|
9
|
+
export const newDraftSelection = (draftThreadId = crypto.randomUUID()) => ({
|
|
10
|
+
conversation: { chatThreadId: draftThreadId },
|
|
11
11
|
draftThreadId,
|
|
12
12
|
draftSent: false,
|
|
13
13
|
});
|
|
14
14
|
/** A draft stands by even when the URL opens a thread: "New chat" from there must not mint twice. */
|
|
15
|
-
export const initialSelection = (
|
|
16
|
-
const draft = newDraftSelection(
|
|
15
|
+
export const initialSelection = (urlConversation) => {
|
|
16
|
+
const draft = newDraftSelection();
|
|
17
17
|
return urlConversation ? { ...draft, conversation: urlConversation } : draft;
|
|
18
18
|
};
|
|
19
19
|
export const isDraftSelection = ({ conversation, draftThreadId, draftSent }) => conversation.chatThreadId === draftThreadId && !draftSent;
|
|
20
20
|
/** After choosing a thread; the same object when it is already open (no re-render). */
|
|
21
21
|
export const selectionWithThread = (prev, conversation) => agentThreadKey(prev.conversation) === agentThreadKey(conversation) ? prev : { ...prev, conversation };
|
|
22
22
|
/** After "New chat": an untouched draft stays; anything else mints a fresh one. */
|
|
23
|
-
export const selectionWithNewChat = (prev
|
|
23
|
+
export const selectionWithNewChat = (prev) => isDraftSelection(prev) ? prev : newDraftSelection();
|
|
24
24
|
/** After the first send on the draft; unchanged when the draft is not the open conversation. */
|
|
25
25
|
export const selectionAfterDraftSent = (prev) => isDraftSelection(prev) ? { ...prev, draftSent: true } : prev;
|
|
26
26
|
/** Identity of a URL target; the selection follows the URL whenever this changes. */
|
|
@@ -29,9 +29,10 @@ export const urlSelectionKey = (target) => target === null ? null : target === "
|
|
|
29
29
|
* The open conversation follows the URL — the one source of truth, so choosing a thread is a
|
|
30
30
|
* navigation, never a call here; the draft is local state.
|
|
31
31
|
*/
|
|
32
|
-
export const useAgentConversationSelection = ({
|
|
33
|
-
|
|
34
|
-
const
|
|
32
|
+
export const useAgentConversationSelection = ({ urlTarget, }) => {
|
|
33
|
+
// The thread id alone: a caller's deprecated `chatId` on the target is dropped here.
|
|
34
|
+
const urlConversation = urlTarget !== null && urlTarget !== "new" ? { chatThreadId: urlTarget.chatThreadId } : undefined;
|
|
35
|
+
const [selection, setSelection] = useState(() => initialSelection(urlConversation));
|
|
35
36
|
const markDraftSent = useCallback(() => setSelection(selectionAfterDraftSent), []);
|
|
36
37
|
// Synced during render (React's "adjusting state when a prop changes"), so the chat root
|
|
37
38
|
// below never renders a frame on the previous conversation.
|
|
@@ -43,7 +44,7 @@ export const useAgentConversationSelection = ({ ownChatId, urlTarget, }) => {
|
|
|
43
44
|
setSelection((prev) => selectionWithThread(prev, urlConversation));
|
|
44
45
|
}
|
|
45
46
|
else if (urlTarget === "new") {
|
|
46
|
-
setSelection(
|
|
47
|
+
setSelection(selectionWithNewChat);
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
return { conversation: selection.conversation, isDraft: isDraftSelection(selection), markDraftSent };
|
|
@@ -61,7 +62,6 @@ export const agentThreadStandIn = (agentId, conversation, isDraft) => {
|
|
|
61
62
|
const now = new Date().toISOString();
|
|
62
63
|
return {
|
|
63
64
|
agentId,
|
|
64
|
-
chatId: conversation.chatId,
|
|
65
65
|
chatThreadId: conversation.chatThreadId,
|
|
66
66
|
source: "direct_chat",
|
|
67
67
|
status: "idle",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-agent-thread.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-thread.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,KAAK,eAAe,EAKrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAA2B,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1G,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,oBAAoB,CAAC;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IACjE,yGAAyG;IACzG,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;CAChC;AAED,mDAAmD;AACnD,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,gBAAgB,CAAC,CAAC;AAEvF,6DAA6D;AAC7D,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE;AAC7C,yEAAyE;GACvE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;AACnB,uGAAuG;GACrG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,oBAAoB,EAC3B,KAAK,MAAM,EACX,SAAS,OAAO,KACf,qBASF,CAAC;AAEF,mEAAmE;AACnE,MAAM,MAAM,wBAAwB,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,uGAAuG;GACrG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE;AAC1C,0DAA0D;GACxD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,4EAA4E;GAC1E;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,OAAO,qBAAqB,EAC5B,OAAO,oBAAoB,EAC3B,KAAK,MAAM,EACX,eAAe,OAAO,KACrB,wBAeF,CAAC;AAEF,mHAAmH;AACnH,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,OACgB,CAAC;AAIpE,eAAO,MAAM,cAAc,GAAI,8DAO5B,qBAAqB,KAAG,
|
|
1
|
+
{"version":3,"file":"use-agent-thread.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-thread.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,KAAK,eAAe,EAKrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAA2B,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1G,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,oBAAoB,CAAC;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IACjE,yGAAyG;IACzG,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;CAChC;AAED,mDAAmD;AACnD,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,gBAAgB,CAAC,CAAC;AAEvF,6DAA6D;AAC7D,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE;AAC7C,yEAAyE;GACvE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;AACnB,uGAAuG;GACrG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,oBAAoB,EAC3B,KAAK,MAAM,EACX,SAAS,OAAO,KACf,qBASF,CAAC;AAEF,mEAAmE;AACnE,MAAM,MAAM,wBAAwB,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,uGAAuG;GACrG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE;AAC1C,0DAA0D;GACxD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,4EAA4E;GAC1E;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,OAAO,qBAAqB,EAC5B,OAAO,oBAAoB,EAC3B,KAAK,MAAM,EACX,eAAe,OAAO,KACrB,wBAeF,CAAC;AAEF,mHAAmH;AACnH,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,OACgB,CAAC;AAIpE,eAAO,MAAM,cAAc,GAAI,8DAO5B,qBAAqB,KAAG,oBAsJ1B,CAAC"}
|
|
@@ -50,12 +50,9 @@ export const isMissingRowError = (error) => error instanceof AgentThreadsRequest
|
|
|
50
50
|
const noop = async () => undefined;
|
|
51
51
|
export const useAgentThread = ({ agentId, conversation, isDraft = false, token, headers, baseUrl, }) => {
|
|
52
52
|
const key = agentThreadKey(conversation);
|
|
53
|
-
// Keyed by identity, not by object: a caller handing a fresh `{
|
|
54
|
-
//
|
|
55
|
-
const target = useMemo(() => ({
|
|
56
|
-
chatId: conversation.chatId,
|
|
57
|
-
chatThreadId: conversation.chatThreadId,
|
|
58
|
-
}), [conversation.chatId, conversation.chatThreadId]);
|
|
53
|
+
// Keyed by identity, not by object: a caller handing a fresh `{ chatThreadId }` each render
|
|
54
|
+
// must not re-acquire the store and refetch each render.
|
|
55
|
+
const target = useMemo(() => ({ chatThreadId: conversation.chatThreadId }), [conversation.chatThreadId]);
|
|
59
56
|
const [thread, setThread] = useState(null);
|
|
60
57
|
// The optimistic row after this client's own send, overlaid until the server's row shows the
|
|
61
58
|
// run — the index's rule, applied to a list of one (the same helpers).
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type AgentThreadItem, type AgentThreadSource, type AgentThreadStatus } from "./agent-thread-live-update.js";
|
|
2
2
|
import { type AgentThreadStore } from "./agent-thread-store.js";
|
|
3
3
|
export * from "./agent-thread-live-update.js";
|
|
4
|
+
export { LEGACY_CHAT_THREAD_NAMESPACE, legacyChatThreadId } from "../utils/legacy-chat-thread-id.js";
|
|
4
5
|
export { type AgentAdminCaller, BUILD_PERMISSION, isAgentAdmin, readAgentAdminRoles } from "../utils/agent-admin.js";
|
|
5
6
|
export { type AgentConversationChat, type AgentConversationRef, type AgentConversationUrlTarget, agentThreadStandIn, nextRunStaleAt, RUN_STALE_MS, useAgentConversation, type UseAgentConversationOptions, type UseAgentConversationResult, useAgentConversationSelection, type UseAgentConversationSelectionOptions, type UseAgentConversationSelectionResult, } from "./use-agent-conversation.js";
|
|
6
7
|
export { type AgentConversationContextValue, AgentConversationProvider, type AgentConversationProviderProps, AgentThreadConversationProvider, type AgentThreadConversationProviderProps, type AgentThreadFilters, useAgentConversationContext, } from "./agent-conversation-context.js";
|
|
@@ -31,14 +32,14 @@ export declare const agentThreadsFetchJson: <T>(baseUrl: string | undefined, aut
|
|
|
31
32
|
export declare const useAgentThreadsFetchJson: ({ baseUrl, token, headers, }: AgentThreadsAuth & {
|
|
32
33
|
baseUrl?: string;
|
|
33
34
|
}) => (<T>(path: string, init?: RequestInit) => Promise<T>);
|
|
34
|
-
/** The single-thread read: one row
|
|
35
|
-
export declare const agentThreadPath: (agentId: string, conversation: Pick<AgentThreadItem, "
|
|
35
|
+
/** The single-thread read: one row of the agent, by its thread id. */
|
|
36
|
+
export declare const agentThreadPath: (agentId: string, conversation: Pick<AgentThreadItem, "chatThreadId">) => string;
|
|
36
37
|
/**
|
|
37
38
|
* The rename, as the server applies it. The `x-socket-id` lets the publish skip this tab — the
|
|
38
39
|
* caller already shows the new title optimistically — so, that publish never coming back, the
|
|
39
40
|
* renamed row is handed to the agent's shared store here, for every other reader of it.
|
|
40
41
|
*/
|
|
41
|
-
export declare const postAgentThreadRename: (fetchJson: <T>(path: string, init?: RequestInit) => Promise<T>, agentId: string, thread: Pick<AgentThreadItem, "
|
|
42
|
+
export declare const postAgentThreadRename: (fetchJson: <T>(path: string, init?: RequestInit) => Promise<T>, agentId: string, thread: Pick<AgentThreadItem, "chatThreadId">, title: string, store?: Pick<AgentThreadStore, "getRow" | "prime">) => Promise<void>;
|
|
42
43
|
export interface AgentThreadsPage {
|
|
43
44
|
items: AgentThreadItem[];
|
|
44
45
|
nextCursor: string | null;
|
|
@@ -47,7 +48,13 @@ export interface UseAgentThreadsOptions {
|
|
|
47
48
|
agentId: string;
|
|
48
49
|
status?: AgentThreadStatus;
|
|
49
50
|
source?: AgentThreadSource;
|
|
50
|
-
|
|
51
|
+
/** Show only the current user's threads — a filter, not access control. */
|
|
52
|
+
private?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* The signed-in user's id. With `private`, a live update for a thread this list has not
|
|
55
|
+
* loaded is shown only when it is this user's; without it, such a thread waits for a refresh.
|
|
56
|
+
*/
|
|
57
|
+
userId?: string;
|
|
51
58
|
limit?: number;
|
|
52
59
|
sort?: "lastActivity" | "firstSeen";
|
|
53
60
|
order?: "asc" | "desc";
|
|
@@ -58,7 +65,7 @@ export interface UseAgentThreadsOptions {
|
|
|
58
65
|
export interface UseAgentThreadsResult {
|
|
59
66
|
threads: AgentThreadItem[];
|
|
60
67
|
notifyThreadActivity: (thread: AgentThreadItem, prompt?: string) => void;
|
|
61
|
-
renameThread: (thread: Pick<AgentThreadItem, "
|
|
68
|
+
renameThread: (thread: Pick<AgentThreadItem, "chatThreadId">, title: string) => Promise<void>;
|
|
62
69
|
isLoading: boolean;
|
|
63
70
|
isLoadingMore: boolean;
|
|
64
71
|
error: Error | null;
|
|
@@ -66,10 +73,13 @@ export interface UseAgentThreadsResult {
|
|
|
66
73
|
loadMore: () => Promise<void>;
|
|
67
74
|
refresh: () => Promise<void>;
|
|
68
75
|
}
|
|
69
|
-
|
|
76
|
+
/**
|
|
77
|
+
* @deprecated Threads no longer live under a chat; the value means nothing. Kept only because
|
|
78
|
+
* agent-layout copies already installed in apps call it (they run against this package).
|
|
79
|
+
*/
|
|
70
80
|
export declare const agentInboxChatId: (agentId: string) => string;
|
|
71
|
-
export declare const agentThreadShortLabel: (thread: Pick<AgentThreadItem, "
|
|
72
|
-
export declare const agentThreadDisplayTitle: (thread: Pick<AgentThreadItem, "
|
|
81
|
+
export declare const agentThreadShortLabel: (thread: Pick<AgentThreadItem, "chatThreadId">) => string;
|
|
82
|
+
export declare const agentThreadDisplayTitle: (thread: Pick<AgentThreadItem, "chatThreadId" | "title">) => string;
|
|
73
83
|
/** Agent-threads index with pagination, realtime upserts, and optimistic send listing. */
|
|
74
84
|
export declare const useAgentThreads: (options: UseAgentThreadsOptions) => UseAgentThreadsResult;
|
|
75
85
|
export default useAgentThreads;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-agent-threads.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-threads.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"use-agent-threads.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-threads.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
|
4
4
|
import { agentThreadKey, applyAgentThreadUpdate, matchesAgentThreadFilters, optimisticThreadAfterSend, overlayOptimisticThreads, reconcileWalkWithLive, removeAgentThread, retireOptimisticThreadsTakenOver, } from "./agent-thread-live-update.js";
|
|
5
5
|
import { acquireAgentThreadStore } from "./agent-thread-store.js";
|
|
6
6
|
export * from "./agent-thread-live-update.js";
|
|
7
|
+
export { LEGACY_CHAT_THREAD_NAMESPACE, legacyChatThreadId } from "../utils/legacy-chat-thread-id.js";
|
|
7
8
|
export { BUILD_PERMISSION, isAgentAdmin, readAgentAdminRoles } from "../utils/agent-admin.js";
|
|
8
9
|
export { agentThreadStandIn, nextRunStaleAt, RUN_STALE_MS, useAgentConversation, useAgentConversationSelection, } from "./use-agent-conversation.js";
|
|
9
10
|
export { AgentConversationProvider, AgentThreadConversationProvider, useAgentConversationContext, } from "./agent-conversation-context.js";
|
|
@@ -50,9 +51,8 @@ export const useAgentThreadsFetchJson = ({ baseUrl, token, headers, }) => {
|
|
|
50
51
|
});
|
|
51
52
|
return useCallback((path, init) => agentThreadsFetchJson(baseUrl, authRef.current, path, init), [baseUrl]);
|
|
52
53
|
};
|
|
53
|
-
/** The single-thread read: one row
|
|
54
|
+
/** The single-thread read: one row of the agent, by its thread id. */
|
|
54
55
|
export const agentThreadPath = (agentId, conversation) => `/agent-threads/${encodeURIComponent(agentId)}/thread?${new URLSearchParams({
|
|
55
|
-
chatId: conversation.chatId,
|
|
56
56
|
chatThreadId: conversation.chatThreadId,
|
|
57
57
|
})}`;
|
|
58
58
|
/**
|
|
@@ -68,7 +68,7 @@ export const postAgentThreadRename = async (fetchJson, agentId, thread, title, s
|
|
|
68
68
|
"Content-Type": "application/json",
|
|
69
69
|
...(socketId ? { "x-socket-id": socketId } : {}),
|
|
70
70
|
},
|
|
71
|
-
body: JSON.stringify({
|
|
71
|
+
body: JSON.stringify({ chatThreadId: thread.chatThreadId, title }),
|
|
72
72
|
});
|
|
73
73
|
if (!updated) {
|
|
74
74
|
throw new Error("Thread rename was not applied");
|
|
@@ -78,13 +78,12 @@ export const postAgentThreadRename = async (fetchJson, agentId, thread, title, s
|
|
|
78
78
|
store.prime([{ ...cached, title }]);
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
};
|
|
81
|
+
/**
|
|
82
|
+
* @deprecated Threads no longer live under a chat; the value means nothing. Kept only because
|
|
83
|
+
* agent-layout copies already installed in apps call it (they run against this package).
|
|
84
|
+
*/
|
|
85
|
+
export const agentInboxChatId = (agentId) => `agent-inbox-${agentId}`;
|
|
86
|
+
export const agentThreadShortLabel = (thread) => thread.chatThreadId.slice(0, 8);
|
|
88
87
|
export const agentThreadDisplayTitle = (thread) => thread.title ?? `Chat ${agentThreadShortLabel(thread)}`;
|
|
89
88
|
const buildQuery = (filters, cursor) => {
|
|
90
89
|
const params = new URLSearchParams();
|
|
@@ -94,8 +93,8 @@ const buildQuery = (filters, cursor) => {
|
|
|
94
93
|
if (filters.source) {
|
|
95
94
|
params.set("source", filters.source);
|
|
96
95
|
}
|
|
97
|
-
if (filters.
|
|
98
|
-
params.set("
|
|
96
|
+
if (filters.private) {
|
|
97
|
+
params.set("private", "true");
|
|
99
98
|
}
|
|
100
99
|
if (filters.limit) {
|
|
101
100
|
params.set("limit", String(filters.limit));
|
|
@@ -118,7 +117,7 @@ const appendPage = (existing, page) => {
|
|
|
118
117
|
};
|
|
119
118
|
/** Agent-threads index with pagination, realtime upserts, and optimistic send listing. */
|
|
120
119
|
export const useAgentThreads = (options) => {
|
|
121
|
-
const { agentId, status, source,
|
|
120
|
+
const { agentId, status, source, private: privateOnly, userId, limit, sort, order, baseUrl } = options;
|
|
122
121
|
const [optimisticThreads, setOptimisticThreads] = useState(new Map());
|
|
123
122
|
const optimisticThreadsRef = useRef(optimisticThreads);
|
|
124
123
|
const applyOptimisticThreads = useCallback((next) => {
|
|
@@ -144,7 +143,7 @@ export const useAgentThreads = (options) => {
|
|
|
144
143
|
const [isLoading, setIsLoading] = useState(Boolean(agentId));
|
|
145
144
|
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
146
145
|
const [error, setError] = useState(null);
|
|
147
|
-
const liveUpdateOptions = useMemo(() => ({ status, source,
|
|
146
|
+
const liveUpdateOptions = useMemo(() => ({ status, source, private: privateOnly, userId, sort, order }), [status, source, privateOnly, userId, sort, order]);
|
|
148
147
|
const displayThreads = useMemo(() => overlayOptimisticThreads(threads, optimisticThreads, liveUpdateOptions), [threads, optimisticThreads, liveUpdateOptions]);
|
|
149
148
|
const notifyThreadActivity = useCallback((thread, prompt) => {
|
|
150
149
|
const prev = optimisticThreadsRef.current;
|
|
@@ -154,7 +153,7 @@ export const useAgentThreads = (options) => {
|
|
|
154
153
|
}, [applyOptimisticThreads]);
|
|
155
154
|
const fetchJson = useAgentThreadsFetchJson({ baseUrl, token: options.token, headers: options.headers });
|
|
156
155
|
const requestSeqRef = useRef(0);
|
|
157
|
-
const fetchPage = useCallback((cursor) => fetchJson(`/agent-threads/${encodeURIComponent(agentId)}${buildQuery({ status, source,
|
|
156
|
+
const fetchPage = useCallback((cursor) => fetchJson(`/agent-threads/${encodeURIComponent(agentId)}${buildQuery({ status, source, private: privateOnly, limit, sort, order }, cursor)}`), [agentId, status, source, privateOnly, limit, sort, order, fetchJson]);
|
|
158
157
|
// The agent's shared store: one live subscription and one row cache for every reader in the
|
|
159
158
|
// app. This index is its priming reader — its pages land in the cache, so a single-conversation
|
|
160
159
|
// reader beside it (the floating agent chat over a mini-app page) never fetches what the index
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-chat-resume.d.ts","sourceRoot":"","sources":["../../src/utils/agent-chat-resume.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,QAAO,eAC6E,CAAC;AAKnH,eAAO,MAAM,eAAe,GAAI,MAAM,OAAO,KAAG,MAAM,GAAG,SAOxD,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// The lookup a signed-in chat with nothing pinned resumes from: the caller's own (`private`)
|
|
2
|
+
// most recent ordinary chat thread of the agent. `source=direct_chat` leaves out feedback and
|
|
3
|
+
// fork threads, which also carry the user who started them.
|
|
4
|
+
export const resumeThreadQuery = () => new URLSearchParams({ private: "true", source: "direct_chat", limit: "1", sort: "lastActivity", order: "desc" });
|
|
5
|
+
// The thread to resume from that lookup's page, or undefined to start a new one. An item without
|
|
6
|
+
// a `userId` field came from a server that predates `private` and ignored it, so the page may hold
|
|
7
|
+
// another user's thread: not resumed.
|
|
8
|
+
export const resumedThreadId = (page) => {
|
|
9
|
+
const latest = page?.items?.[0];
|
|
10
|
+
if (typeof latest !== "object" || latest === null || !("userId" in latest)) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const { chatThreadId } = latest;
|
|
14
|
+
return typeof chatThreadId === "string" && chatThreadId ? chatThreadId : undefined;
|
|
15
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const LEGACY_CHAT_THREAD_NAMESPACE = "6f1c2a4e-9b3d-5e7f-8a1b-2c3d4e5f6a7b";
|
|
2
|
+
/** RFC 4122 version-5 UUID of `name` in `namespace`. */
|
|
3
|
+
export declare const uuidV5: (namespace: string, name: string) => string;
|
|
4
|
+
/**
|
|
5
|
+
* The thread a deprecated `chatId` names. A chat opened by `chatId` alone (an old link, an old
|
|
6
|
+
* app's prop) resumes the thread the server derived for it with the same function.
|
|
7
|
+
*/
|
|
8
|
+
export declare const legacyChatThreadId: (chatId: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* The thread a chat's deprecated `chatId` pins: none when the host names `defaultThreadId`, or
|
|
11
|
+
* with `noPersistency` (such a chat runs on a fresh thread per mount, whatever its `chatId`).
|
|
12
|
+
*/
|
|
13
|
+
export declare const pinnedLegacyChatThreadId: ({ chatId, defaultThreadId, noPersistency, }: {
|
|
14
|
+
chatId?: string;
|
|
15
|
+
defaultThreadId?: string;
|
|
16
|
+
noPersistency?: boolean;
|
|
17
|
+
}) => string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* The raw `chatId` a run forwards: only while the chat is on the thread derived from it, so the
|
|
20
|
+
* server can still find that chat's not-yet-backfilled legacy row (it looks one up only then).
|
|
21
|
+
*/
|
|
22
|
+
export declare const forwardedLegacyChatId: (chatId: string | undefined, legacyThreadId: string | undefined, threadId: string | null) => string | undefined;
|
|
23
|
+
//# sourceMappingURL=legacy-chat-thread-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-chat-thread-id.d.ts","sourceRoot":"","sources":["../../src/utils/legacy-chat-thread-id.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,4BAA4B,yCAAyC,CAAC;AAyDnF,wDAAwD;AACxD,eAAO,MAAM,MAAM,GAAI,WAAW,MAAM,EAAE,MAAM,MAAM,KAAG,MAUxD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,KAAG,MAAsD,CAAC;AAE3G;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,6CAItC;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,KAAG,MAAM,GAAG,SACiF,CAAC;AAE/F;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,MAAM,GAAG,SAAS,EAC1B,gBAAgB,MAAM,GAAG,SAAS,EAClC,UAAU,MAAM,GAAG,IAAI,KACtB,MAAM,GAAG,SAA2F,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// The thread id a legacy `chatId` stands for — the client twin of wf-actions-py's
|
|
2
|
+
// normalization: uuidv5(LEGACY_CHAT_THREAD_NAMESPACE, chatId). Both sides pin the same
|
|
3
|
+
// namespace and share a fixture test, so a chat a client opens by `chatId` lands on the very
|
|
4
|
+
// thread the server derived for it. Synchronous (a hand-rolled SHA-1): CopilotKit fixes the
|
|
5
|
+
// thread id before it connects, so it cannot wait on crypto.subtle.
|
|
6
|
+
export const LEGACY_CHAT_THREAD_NAMESPACE = "6f1c2a4e-9b3d-5e7f-8a1b-2c3d4e5f6a7b";
|
|
7
|
+
const rotl = (value, bits) => (value << bits) | (value >>> (32 - bits));
|
|
8
|
+
const sha1 = (message) => {
|
|
9
|
+
const bitLength = message.length * 8;
|
|
10
|
+
const paddedLength = Math.ceil((message.length + 9) / 64) * 64;
|
|
11
|
+
const padded = new Uint8Array(paddedLength);
|
|
12
|
+
padded.set(message);
|
|
13
|
+
padded[message.length] = 0x80;
|
|
14
|
+
const view = new DataView(padded.buffer);
|
|
15
|
+
view.setUint32(paddedLength - 8, Math.floor(bitLength / 0x100000000));
|
|
16
|
+
view.setUint32(paddedLength - 4, bitLength >>> 0);
|
|
17
|
+
const h = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
|
|
18
|
+
const w = new Array(80);
|
|
19
|
+
for (let offset = 0; offset < paddedLength; offset += 64) {
|
|
20
|
+
for (let i = 0; i < 16; i++) {
|
|
21
|
+
w[i] = view.getUint32(offset + i * 4);
|
|
22
|
+
}
|
|
23
|
+
for (let i = 16; i < 80; i++) {
|
|
24
|
+
w[i] = rotl(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
|
|
25
|
+
}
|
|
26
|
+
let [a, b, c, d, e] = h;
|
|
27
|
+
for (let i = 0; i < 80; i++) {
|
|
28
|
+
const [f, k] = i < 20
|
|
29
|
+
? [(b & c) | (~b & d), 0x5a827999]
|
|
30
|
+
: i < 40
|
|
31
|
+
? [b ^ c ^ d, 0x6ed9eba1]
|
|
32
|
+
: i < 60
|
|
33
|
+
? [(b & c) | (b & d) | (c & d), 0x8f1bbcdc]
|
|
34
|
+
: [b ^ c ^ d, 0xca62c1d6];
|
|
35
|
+
const temp = (rotl(a, 5) + f + e + k + w[i]) >>> 0;
|
|
36
|
+
e = d;
|
|
37
|
+
d = c;
|
|
38
|
+
c = rotl(b, 30) >>> 0;
|
|
39
|
+
b = a;
|
|
40
|
+
a = temp;
|
|
41
|
+
}
|
|
42
|
+
h[0] = (h[0] + a) >>> 0;
|
|
43
|
+
h[1] = (h[1] + b) >>> 0;
|
|
44
|
+
h[2] = (h[2] + c) >>> 0;
|
|
45
|
+
h[3] = (h[3] + d) >>> 0;
|
|
46
|
+
h[4] = (h[4] + e) >>> 0;
|
|
47
|
+
}
|
|
48
|
+
const digest = new Uint8Array(20);
|
|
49
|
+
const out = new DataView(digest.buffer);
|
|
50
|
+
h.forEach((word, i) => out.setUint32(i * 4, word));
|
|
51
|
+
return digest;
|
|
52
|
+
};
|
|
53
|
+
const uuidBytes = (uuid) => {
|
|
54
|
+
const hex = uuid.replace(/-/g, "");
|
|
55
|
+
return Uint8Array.from({ length: 16 }, (_, i) => parseInt(hex.slice(i * 2, i * 2 + 2), 16));
|
|
56
|
+
};
|
|
57
|
+
/** RFC 4122 version-5 UUID of `name` in `namespace`. */
|
|
58
|
+
export const uuidV5 = (namespace, name) => {
|
|
59
|
+
const nameBytes = new TextEncoder().encode(name);
|
|
60
|
+
const input = new Uint8Array(16 + nameBytes.length);
|
|
61
|
+
input.set(uuidBytes(namespace));
|
|
62
|
+
input.set(nameBytes, 16);
|
|
63
|
+
const bytes = sha1(input).slice(0, 16);
|
|
64
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x50;
|
|
65
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
66
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
67
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* The thread a deprecated `chatId` names. A chat opened by `chatId` alone (an old link, an old
|
|
71
|
+
* app's prop) resumes the thread the server derived for it with the same function.
|
|
72
|
+
*/
|
|
73
|
+
export const legacyChatThreadId = (chatId) => uuidV5(LEGACY_CHAT_THREAD_NAMESPACE, chatId);
|
|
74
|
+
/**
|
|
75
|
+
* The thread a chat's deprecated `chatId` pins: none when the host names `defaultThreadId`, or
|
|
76
|
+
* with `noPersistency` (such a chat runs on a fresh thread per mount, whatever its `chatId`).
|
|
77
|
+
*/
|
|
78
|
+
export const pinnedLegacyChatThreadId = ({ chatId, defaultThreadId, noPersistency, }) => defaultThreadId == null && chatId && !noPersistency ? legacyChatThreadId(chatId) : undefined;
|
|
79
|
+
/**
|
|
80
|
+
* The raw `chatId` a run forwards: only while the chat is on the thread derived from it, so the
|
|
81
|
+
* server can still find that chat's not-yet-backfilled legacy row (it looks one up only then).
|
|
82
|
+
*/
|
|
83
|
+
export const forwardedLegacyChatId = (chatId, legacyThreadId, threadId) => (chatId && legacyThreadId && threadId === legacyThreadId ? chatId : undefined);
|