@blocksdiy/react-common 1.42.0 → 1.43.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.
@@ -122,6 +122,19 @@ export interface AgentChatRootProps {
122
122
  * routed through `sendMessage`, not the auto-sent `initialPrompt`.
123
123
  */
124
124
  onUserMessageSent?: (text: string) => void;
125
+ /**
126
+ * Skip the agent-chat block's `initialPrompt` auto-send. For surfaces that mint a fresh
127
+ * thread per conversation (an inbox's "New chat"): the auto-send fires once PER THREAD,
128
+ * so it would index a ghost turn for every draft. Default off — plain chats keep it.
129
+ */
130
+ disableInitialPrompt?: boolean;
131
+ /**
132
+ * Fires when the agent-chat block or its agent block cannot be loaded — the request
133
+ * failed, or the platform answered with no such block (a 403/404 body). The root renders
134
+ * nothing in that state, so a host that gates its own chrome on the chat resolving
135
+ * (a layout's skeleton) must use this to show an error instead of waiting forever.
136
+ */
137
+ onLoadError?: (error: Error) => void;
125
138
  }
126
139
  export declare const AgentChatRoot: ({ ...props }: AgentChatRootProps) => import("react").JSX.Element | null;
127
140
  export interface AgentChatMessageProps {
@@ -1 +1 @@
1
- {"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"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"}
@@ -243,7 +243,7 @@ const SessionReadables = () => {
243
243
  // });
244
244
  return null;
245
245
  };
246
- const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, components, currentThreadId, setCurrentThreadId, children, onUserMessageSent, }) => {
246
+ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, components, currentThreadId, setCurrentThreadId, children, onUserMessageSent, disableInitialPrompt, }) => {
247
247
  const [agentChat, setAgentChat] = useState(null);
248
248
  const [agent, setAgent] = useState(null);
249
249
  // `isConfigLoaded` covers the (small, parallel) async fetch of the
@@ -586,8 +586,12 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
586
586
  // `isLoading`). Without this guard the optimistic `initialPromptSentRef`
587
587
  // flip below would lock the prompt out forever after a single
588
588
  // dropped call. Re-runs as soon as the gate opens.
589
+ //
590
+ // `disableInitialPrompt` skips the auto-send entirely: an inbox surface mints a fresh
591
+ // thread for every "New chat", and an auto-sent prompt would index a ghost turn for
592
+ // each of them before the user has said anything.
589
593
  useEffect(() => {
590
- if (initialPromptSentRef.current) {
594
+ if (disableInitialPrompt || initialPromptSentRef.current) {
591
595
  return;
592
596
  }
593
597
  if (!isAgentReady || !isConfigLoaded) {
@@ -620,7 +624,7 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
620
624
  content: prompt,
621
625
  });
622
626
  void runAgentWithRetry(copilotAgent, copilotAgent.messages.length).catch(() => undefined);
623
- }, [isAgentReady, isConfigLoaded, agentChat, copilotAgent, canSendMessage, runAgentWithRetry]);
627
+ }, [isAgentReady, isConfigLoaded, agentChat, copilotAgent, canSendMessage, runAgentWithRetry, disableInitialPrompt]);
624
628
  const buildMessageContentFromInput = (currentPrompt = prompt, currentAttachments = attachments) => {
625
629
  if (currentAttachments.length === 0) {
626
630
  return currentPrompt;
@@ -767,7 +771,13 @@ export const AgentChatRoot = ({ ...props
767
771
  // memoryEnabled = false,
768
772
  // shortTermMemory,
769
773
  }) => {
770
- const { appId, token, children, agentId, agentHarness, useAgentBlockDirectChat, agentChatId, componentIds, chatId, defaultThreadId, noPersistency, chatContext, chatContextFiles, selfEditEnabled, supportsServerInterrupt, } = props;
774
+ const { appId, token, children, agentId, agentHarness, useAgentBlockDirectChat, agentChatId, componentIds, chatId, defaultThreadId, noPersistency, chatContext, chatContextFiles, selfEditEnabled, supportsServerInterrupt, onLoadError, } = props;
775
+ // Read at call time via a ref so an inline handler doesn't re-run the block fetch below
776
+ // (the loads are async, so the ref is current by the time a failure is reported).
777
+ const onLoadErrorRef = useRef(onLoadError);
778
+ useEffect(() => {
779
+ onLoadErrorRef.current = onLoadError;
780
+ });
771
781
  const socketId = websocketsService.getSocketId();
772
782
  const headers = useMemo(() => ({
773
783
  ...(token ? { Authorization: `Bearer ${token}` } : {}),
@@ -803,8 +813,10 @@ export const AgentChatRoot = ({ ...props
803
813
  if (!agentChatId) {
804
814
  return null;
805
815
  }
816
+ // getBlock resolves with the response body whatever the status, so a 403/404 error
817
+ // envelope arrives here as a truthy object — a block is only a block when it has an id.
806
818
  const agentChatBlock = await blocksApiService.getBlock(agentChatId, appId, "agent", "agent_chat");
807
- if (!agentChatBlock) {
819
+ if (!agentChatBlock?.id) {
808
820
  throw new Error("Agent chat block not found");
809
821
  }
810
822
  return agentChatBlock;
@@ -814,8 +826,8 @@ export const AgentChatRoot = ({ ...props
814
826
  return null;
815
827
  }
816
828
  const agentBlock = await blocksApiService.getBlock(agentBlockId, appId, "agent", "agent");
817
- if (!agentBlock) {
818
- throw new Error("Agent chat block not found");
829
+ if (!agentBlock?.id) {
830
+ throw new Error("Agent block not found");
819
831
  }
820
832
  return agentBlock;
821
833
  }, [appId, blocksApiService]);
@@ -849,20 +861,39 @@ export const AgentChatRoot = ({ ...props
849
861
  return maybeComponentBlocks.filter((component) => Boolean(component));
850
862
  }, [blocksApiService, componentIds]);
851
863
  useEffect(() => {
852
- getAgentChatBlock().then((agentChatBlock) => {
864
+ // A failed block load leaves the root rendering nothing (below) — report it, or a host
865
+ // waiting on the chat would wait forever. Only the load this effect still owns reports:
866
+ // a superseded one (inputs changed, or the root unmounted) is the newer load's to tell.
867
+ // Its state writes are left as they were (last writer wins) — hosts re-render during
868
+ // loads, and resolution must never depend on them going quiet.
869
+ let superseded = false;
870
+ const reportLoadError = (error) => {
871
+ if (!superseded) {
872
+ onLoadErrorRef.current?.(error instanceof Error ? error : new Error(String(error)));
873
+ }
874
+ };
875
+ getAgentChatBlock()
876
+ .then((agentChatBlock) => {
853
877
  setAgentChatBlock(agentChatBlock);
854
878
  // The chat block's stored agentBlockId is authoritative — sync resolves it
855
879
  // to a real block id, while the `agentId` prop from generated product-types
856
880
  // is a name that can drift from the agent's `block.name`. The prop is only
857
881
  // the fallback for direct agent chats without an agent-chat block.
858
882
  const effectiveAgentId = agentChatBlock?.data?.agentBlockId ?? agentId;
859
- getAgentBlock(effectiveAgentId).then((agentBlock) => {
883
+ getAgentBlock(effectiveAgentId)
884
+ .then((agentBlock) => {
860
885
  setAgentBlock(agentBlock);
861
- });
886
+ })
887
+ .catch(reportLoadError);
888
+ // Never rejects: each component load guards itself and drops to null.
862
889
  getChatComponentBlocks().then((chatComponentBlocks) => {
863
890
  setComponents(chatComponentBlocks);
864
891
  });
865
- });
892
+ })
893
+ .catch(reportLoadError);
894
+ return () => {
895
+ superseded = true;
896
+ };
866
897
  }, [getAgentChatBlock, getAgentBlock, getChatComponentBlocks, agentId]);
867
898
  if (!appId || !agentBlock || !agentChatBlock) {
868
899
  return null;
@@ -885,7 +916,7 @@ export const AgentChatRoot = ({ ...props
885
916
  },
886
917
  // Explicit false: when undefined, CopilotKit auto-enables its inspector
887
918
  // devtools on localhost hostnames.
888
- enableInspector: false, children: [_jsx(SessionReadables, {}), _jsx(ChatInitializer, { agentBlock: agentBlock, agentChatBlock: agentChatBlock, chatId: chatId, noPersistency: noPersistency, token: token, appId: appId, components: components, currentThreadId: currentThreadId, setCurrentThreadId: setCurrentThreadId, onUserMessageSent: props.onUserMessageSent, children: children })] }));
919
+ enableInspector: false, children: [_jsx(SessionReadables, {}), _jsx(ChatInitializer, { agentBlock: agentBlock, agentChatBlock: agentChatBlock, chatId: chatId, noPersistency: noPersistency, token: token, appId: appId, components: components, currentThreadId: currentThreadId, setCurrentThreadId: setCurrentThreadId, onUserMessageSent: props.onUserMessageSent, disableInitialPrompt: props.disableInitialPrompt, children: children })] }));
889
920
  };
890
921
  export function AgentChatMessage({ message, index, ...props }) {
891
922
  if (message.role === "user" && message.name === HIDDEN_INITIAL_PROMPT_MESSAGE_NAME) {
@@ -28,6 +28,13 @@ export declare const isAgentThreadItem: (value: unknown) => value is AgentThread
28
28
  * there's nothing usable (attachment-only sends) — the UI keeps its id-based fallback.
29
29
  */
30
30
  export declare const provisionalThreadTitle: (prompt: string | undefined) => string | null;
31
+ /**
32
+ * The optimistic row for a user send on `thread`, replacing `previous` (its current
33
+ * optimistic entry, if any): the same identity, its recency bumped to `now`, and a title
34
+ * that never regresses — the provisional title already shown, else the row's own, else
35
+ * one from this prompt (null when the prompt has nothing usable).
36
+ */
37
+ export declare const optimisticThreadAfterSend: (thread: AgentThreadItem, previous: AgentThreadItem | undefined, prompt: string | undefined, now: string) => AgentThreadItem;
31
38
  export interface AgentThreadLiveUpdateOptions {
32
39
  /** Active server-side filters — an updated row that stops matching leaves the list. */
33
40
  status?: AgentThreadStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-thread-live-update.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-thread-live-update.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,aAAa,GAAG,OAAO,CAAC;AAEjE,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,CAAC;AAE1F,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,eAAO,MAAM,cAAc,GAAI,QAAQ,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,CAAC,KAAG,MAC9C,CAAC;AAK7C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,eAiB3D,CAAC;AAKF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,IAQ5E,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,uFAAuF;IACvF,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,cAAc,GAAG,WAAW,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAOD;;;;;;;;;;;;;GAaG;AACH,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,GAAI,MAAM,eAAe,EAAE,UAAS,4BAAiC,KAAG,OAGzD,CAAC;AAEtD,eAAO,MAAM,sBAAsB,GACjC,SAAS,eAAe,EAAE,EAC1B,UAAU,eAAe,EACzB,UAAS,4BAAiC,KACzC,eAAe,EAqBjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GACnC,SAAS,eAAe,EAAE,EAC1B,YAAY,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAChD,UAAS,4BAAiC,KACzC,eAAe,EAkBjB,CAAC"}
1
+ {"version":3,"file":"agent-thread-live-update.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-thread-live-update.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,aAAa,GAAG,OAAO,CAAC;AAEjE,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,CAAC;AAE1F,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,eAAO,MAAM,cAAc,GAAI,QAAQ,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,CAAC,KAAG,MAC9C,CAAC;AAK7C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,eAiB3D,CAAC;AAKF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,IAQ5E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GACpC,QAAQ,eAAe,EACvB,UAAU,eAAe,GAAG,SAAS,EACrC,QAAQ,MAAM,GAAG,SAAS,EAC1B,KAAK,MAAM,KACV,eAID,CAAC;AAEH,MAAM,WAAW,4BAA4B;IAC3C,uFAAuF;IACvF,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,cAAc,GAAG,WAAW,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAOD;;;;;;;;;;;;;GAaG;AACH,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,GAAI,MAAM,eAAe,EAAE,UAAS,4BAAiC,KAAG,OAGzD,CAAC;AAEtD,eAAO,MAAM,sBAAsB,GACjC,SAAS,eAAe,EAAE,EAC1B,UAAU,eAAe,EACzB,UAAS,4BAAiC,KACzC,eAAe,EAqBjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GACnC,SAAS,eAAe,EAAE,EAC1B,YAAY,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAChD,UAAS,4BAAiC,KACzC,eAAe,EAkBjB,CAAC"}
@@ -42,6 +42,17 @@ export const provisionalThreadTitle = (prompt) => {
42
42
  ? `${collapsed.slice(0, PROVISIONAL_TITLE_MAX_CHARS - 1).trimEnd()}…`
43
43
  : collapsed;
44
44
  };
45
+ /**
46
+ * The optimistic row for a user send on `thread`, replacing `previous` (its current
47
+ * optimistic entry, if any): the same identity, its recency bumped to `now`, and a title
48
+ * that never regresses — the provisional title already shown, else the row's own, else
49
+ * one from this prompt (null when the prompt has nothing usable).
50
+ */
51
+ export const optimisticThreadAfterSend = (thread, previous, prompt, now) => ({
52
+ ...thread,
53
+ title: previous?.title ?? thread.title ?? provisionalThreadTitle(prompt),
54
+ lastActivityAt: now,
55
+ });
45
56
  const sortTime = (item, sort) => {
46
57
  const parsed = new Date(sort === "firstSeen" ? item.firstSeenAt : item.lastActivityAt).getTime();
47
58
  return Number.isNaN(parsed) ? 0 : parsed;
@@ -22,27 +22,14 @@ export interface UseAgentThreadsOptions {
22
22
  export interface UseAgentThreadsResult {
23
23
  threads: AgentThreadItem[];
24
24
  /**
25
- * The thread the consumer is currently viewing — never null. When nothing is
26
- * selected the hook auto-generates a draft with a fresh (chatId, chatThreadId)
27
- * pair the chat surface can use verbatim; once the draft's first turn is indexed
28
- * and the list refreshes, this resolves to that real row (same key) seamlessly.
29
- * For selected threads it prefers the LIST's row for the same identity — so
30
- * status/turnCount stay fresh after a refresh — falling back to the last set
31
- * item when the row isn't in the loaded pages, so selection never vanishes.
25
+ * Report a user send on a conversation — ChatGPT-style optimistic listing. Pass the
26
+ * conversation's row (the listed one when the index has it, else one the consumer
27
+ * builds from the (chatId, chatThreadId) pair) and the prompt text: a conversation with
28
+ * no server row yet appears in `threads` immediately, titled by the truncated prompt,
29
+ * and every send bumps the row's recency; server rows take over under the same identity
30
+ * as events land. Identity-stable — safe to hand to memoized chat surfaces.
32
31
  */
33
- currentThread: AgentThreadItem;
34
- /** True while currentThread is an auto-generated draft not yet in the index. */
35
- isDraftThread: boolean;
36
- /** Move between threads; null mints a fresh draft ("new chat"). Resets when agentId changes. */
37
- setCurrentThread: (thread: AgentThreadItem | null) => void;
38
- /**
39
- * Report a user send on the current conversation (pass the prompt text) — ChatGPT-style
40
- * optimistic listing. A conversation with no server row yet appears in `threads`
41
- * immediately, titled by the truncated prompt, and every send bumps the row's recency;
42
- * server rows take over under the same identity as events land. Identity-stable — safe
43
- * to hand to memoized chat surfaces (e.g. a chat root's onUserMessageSent).
44
- */
45
- notifyThreadActivity: (prompt?: string) => void;
32
+ notifyThreadActivity: (thread: AgentThreadItem, prompt?: string) => void;
46
33
  /**
47
34
  * Rename a conversation. Optimistic — the list shows the new title immediately and
48
35
  * rolls back on failure (the promise rejects so callers can surface an error).
@@ -86,11 +73,13 @@ export declare const agentThreadDisplayTitle: (thread: Pick<AgentThreadItem, "ch
86
73
  * publishes AGENT_THREAD_UPDATED on the app's Pusher channel and the hook upserts the row,
87
74
  * falling back to the getOne endpoint when a payload lacks the full row. New conversations
88
75
  * list optimistically the moment the first prompt is sent (wire notifyThreadActivity to the
89
- * chat's send seam). Data only — pair it with whatever list UI the host app uses. No
90
- * per-host wiring: both hosts already run the shared websocketsService singleton and
91
- * subscribe the app channel (the platform via its layouts' useWebsockets hooks, a
92
- * boilerplate app via the client SDK's ClientProvider), and listening before the socket
93
- * connects just parks the handler.
76
+ * chat's send seam). The LIST only — which conversation is open is the consumer's (a
77
+ * conversation is addressed by its (chatId, chatThreadId) pair; a new one is a fresh UUID
78
+ * thread id under the surface's chatId — CopilotKit replaces non-UUID ids per load).
79
+ * Pair it with whatever list UI the host app uses. No per-host wiring: both hosts already
80
+ * run the shared websocketsService singleton and subscribe the app channel (the platform
81
+ * via its layouts' useWebsockets hooks, a boilerplate app via the client SDK's
82
+ * ClientProvider), and listening before the socket connects just parks the handler.
94
83
  */
95
84
  export declare const useAgentThreads: (options: UseAgentThreadsOptions) => UseAgentThreadsResult;
96
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":"AAIA,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAMvB,MAAM,4BAA4B,CAAC;AAKpC,cAAc,4BAA4B,CAAC;AAO3C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,cAAc,GAAG,WAAW,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,aAAa,EAAE,eAAe,CAAC;IAC/B,gFAAgF;IAChF,aAAa,EAAE,OAAO,CAAC;IACvB,gGAAgG;IAChG,gBAAgB,EAAE,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3D;;;;;;OAMG;IACH,oBAAoB,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzG,yCAAyC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B;;;;OAIG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AACtD,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,KAAG,MAAgD,CAAC;AAEpG;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,CAAC,KAAG,MAIhG,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,GAAG,OAAO,CAAC,KAAG,MACpD,CAAC;AA8D1D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,sBAAsB,KAAG,qBAsdjE,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"use-agent-threads.d.ts","sourceRoot":"","sources":["../../src/hooks/use-agent-threads.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAMvB,MAAM,4BAA4B,CAAC;AAKpC,cAAc,4BAA4B,CAAC;AAO3C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,cAAc,GAAG,WAAW,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;;;;OAOG;IACH,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzE;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzG,yCAAyC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B;;;;OAIG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AACtD,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,KAAG,MAAgD,CAAC;AAEpG;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,CAAC,KAAG,MAIhG,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,GAAG,OAAO,CAAC,KAAG,MACpD,CAAC;AAuC1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,sBAAsB,KAAG,qBAqYjE,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { getApiHost } from "@blocksdiy/blocks-client-api/envService";
2
2
  import { websocketsService } from "@blocksdiy/blocks-client-api/websocketService";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
- import { agentThreadKey, applyAgentThreadUpdate, isAgentThreadItem, matchesAgentThreadFilters, overlayOptimisticThreads, provisionalThreadTitle, } from "./agent-thread-live-update.js";
4
+ import { agentThreadKey, applyAgentThreadUpdate, isAgentThreadItem, matchesAgentThreadFilters, optimisticThreadAfterSend, overlayOptimisticThreads, } from "./agent-thread-live-update.js";
5
5
  // Wire types, the identity key, and the realtime merge logic live in
6
6
  // ./agent-thread-live-update (dependency-free, unit-testable); re-exported so
7
7
  // consumers keep importing everything from this module.
@@ -62,39 +62,19 @@ const appendPage = (existing, page) => {
62
62
  const seen = new Set(existing.map(agentThreadKey));
63
63
  return [...existing, ...page.filter((thread) => !seen.has(agentThreadKey(thread)))];
64
64
  };
65
- /**
66
- * A not-yet-indexed conversation. chatId is ALWAYS the agent's static inbox id (the
67
- * surface marker — identical for every inbox conversation with this agent); only the
68
- * thread id makes each conversation unique, and it must be a UUID — CopilotKit
69
- * replaces non-UUID thread ids per load, which breaks history. Sharing the chatId
70
- * also means inbox thread switches are pure thread-id changes, the chat stack's
71
- * native reconnect path.
72
- */
73
- const makeDraftThread = (agentId) => {
74
- const now = new Date().toISOString();
75
- return {
76
- agentId: agentId || null,
77
- chatId: agentInboxChatId(agentId),
78
- chatThreadId: crypto.randomUUID(),
79
- source: "direct_chat",
80
- status: "idle",
81
- title: null,
82
- turnCount: 0,
83
- firstSeenAt: now,
84
- lastActivityAt: now,
85
- };
86
- };
87
65
  /**
88
66
  * Headless agent-threads index: fetches an agent's conversation threads from the platform
89
67
  * endpoint with keyset-cursor pagination, then keeps them live — every threads-table write
90
68
  * publishes AGENT_THREAD_UPDATED on the app's Pusher channel and the hook upserts the row,
91
69
  * falling back to the getOne endpoint when a payload lacks the full row. New conversations
92
70
  * list optimistically the moment the first prompt is sent (wire notifyThreadActivity to the
93
- * chat's send seam). Data only — pair it with whatever list UI the host app uses. No
94
- * per-host wiring: both hosts already run the shared websocketsService singleton and
95
- * subscribe the app channel (the platform via its layouts' useWebsockets hooks, a
96
- * boilerplate app via the client SDK's ClientProvider), and listening before the socket
97
- * connects just parks the handler.
71
+ * chat's send seam). The LIST only — which conversation is open is the consumer's (a
72
+ * conversation is addressed by its (chatId, chatThreadId) pair; a new one is a fresh UUID
73
+ * thread id under the surface's chatId — CopilotKit replaces non-UUID ids per load).
74
+ * Pair it with whatever list UI the host app uses. No per-host wiring: both hosts already
75
+ * run the shared websocketsService singleton and subscribe the app channel (the platform
76
+ * via its layouts' useWebsockets hooks, a boilerplate app via the client SDK's
77
+ * ClientProvider), and listening before the socket connects just parks the handler.
98
78
  */
99
79
  export const useAgentThreads = (options) => {
100
80
  const { agentId, status, source, chatId, limit, sort, order, baseUrl } = options;
@@ -121,8 +101,6 @@ export const useAgentThreads = (options) => {
121
101
  const [isLoading, setIsLoading] = useState(Boolean(agentId));
122
102
  const [isLoadingMore, setIsLoadingMore] = useState(false);
123
103
  const [error, setError] = useState(null);
124
- const [selectedThread, setSelectedThread] = useState(null);
125
- const [draftThread, setDraftThread] = useState(() => makeDraftThread(agentId));
126
104
  // ChatGPT-style optimistic rows, keyed by thread identity: conversations listed from
127
105
  // the moment a prompt is sent (see notifyThreadActivity), before/ahead of their server
128
106
  // row. The display overlay hands each one over to its server row as events land.
@@ -133,78 +111,22 @@ export const useAgentThreads = (options) => {
133
111
  optimisticThreadsRef.current = next;
134
112
  setOptimisticThreads(next);
135
113
  }, []);
136
- const setCurrentThread = useCallback((thread) => {
137
- // Null means "new chat": mint a fresh draft so each one is its own conversation.
138
- if (!thread) {
139
- setDraftThread(makeDraftThread(agentId));
140
- }
141
- setSelectedThread(thread);
142
- }, [agentId]);
143
- // Selection follows the agent, not the query: filter changes keep it (the fallback in
144
- // `currentThread` covers rows the new filter drops), but another agent's thread — or
145
- // draft — is meaningless here. Guarded by the previous id so the mount render keeps the
146
- // initial draft (regenerating it would remount a consumer's keyed chat surface for nothing).
147
- const prevAgentIdRef = useRef(agentId);
148
- useEffect(() => {
149
- if (prevAgentIdRef.current === agentId) {
150
- return;
151
- }
152
- prevAgentIdRef.current = agentId;
153
- setSelectedThread(null);
154
- setDraftThread(makeDraftThread(agentId));
155
- applyOptimisticThreads(new Map());
156
- }, [agentId, applyOptimisticThreads]);
157
114
  // The realtime merge's list-shape inputs, shared by the display overlay, the live
158
115
  // event handler, and the walk-result reconciliation in loadFirstPage.
159
116
  const liveUpdateOptions = useMemo(() => ({ status, source, chatId, sort, order }), [status, source, chatId, sort, order]);
160
117
  // What consumers see: the loaded pages with the optimistic rows overlaid.
161
118
  const displayThreads = useMemo(() => overlayOptimisticThreads(threads, optimisticThreads, liveUpdateOptions), [threads, optimisticThreads, liveUpdateOptions]);
162
- // Rows are rewritten server-side every turn, so after a refresh the stored item is stale;
163
- // prefer the list's row with the same identity, keep the stored one if it's not loaded.
164
- // The draft goes through the same lookup: once its row is listed — optimistically on the
165
- // first send, or when its first turn is indexed — that row wins under the same key: the
166
- // draft has materialized, without changing identity.
167
- const currentThread = useMemo(() => {
168
- const stored = selectedThread ?? draftThread;
169
- const storedKey = agentThreadKey(stored);
170
- return displayThreads.find((thread) => agentThreadKey(thread) === storedKey) ?? stored;
171
- }, [displayThreads, selectedThread, draftThread]);
172
- const isDraftThread = !selectedThread && currentThread === draftThread;
173
- // Once the draft's row is listed, it IS the conversation — adopt it as the selection.
174
- // Otherwise a later filter change (which blanks the list before refetching) would flip
175
- // `isDraftThread` back to true for a conversation that has messages, and the consumer's
176
- // draft-only presentation ("New chat" header, empty-state slot) with it.
177
- useEffect(() => {
178
- if (selectedThread) {
179
- return;
180
- }
181
- const draftKey = agentThreadKey(draftThread);
182
- const materialized = displayThreads.find((thread) => agentThreadKey(thread) === draftKey);
183
- if (materialized) {
184
- setSelectedThread(materialized);
185
- }
186
- }, [displayThreads, selectedThread, draftThread]);
187
- // Read at call time via a ref so notifyThreadActivity stays identity-stable for
188
- // memoized chat surfaces (same render-time-assignment pattern as authRef below).
189
- const currentThreadRef = useRef(currentThread);
190
- currentThreadRef.current = currentThread;
191
119
  /**
192
- * Report a user send on the current conversation — ChatGPT-style optimistic listing.
193
- * A conversation with no server row yet appears in `threads` immediately, titled by
194
- * the truncated prompt, and every send bumps the row's recency. Server rows take over
195
- * under the same identity as events land (turn end, title generation), the provisional
196
- * title holding until the generated one arrives.
120
+ * Report a user send on a conversation — ChatGPT-style optimistic listing. A
121
+ * conversation with no server row yet appears in `threads` immediately, titled by the
122
+ * truncated prompt, and every send bumps the row's recency. Server rows take over under
123
+ * the same identity as events land (turn end, title generation), the provisional title
124
+ * holding until the generated one arrives.
197
125
  */
198
- const notifyThreadActivity = useCallback((prompt) => {
199
- const current = currentThreadRef.current;
200
- const key = agentThreadKey(current);
126
+ const notifyThreadActivity = useCallback((thread, prompt) => {
201
127
  const prev = optimisticThreadsRef.current;
202
128
  const next = new Map(prev);
203
- next.set(key, {
204
- ...current,
205
- title: prev.get(key)?.title ?? current.title ?? provisionalThreadTitle(prompt),
206
- lastActivityAt: new Date().toISOString(),
207
- });
129
+ next.set(agentThreadKey(thread), optimisticThreadAfterSend(thread, prev.get(agentThreadKey(thread)), prompt, new Date().toISOString()));
208
130
  applyOptimisticThreads(next);
209
131
  }, [applyOptimisticThreads]);
210
132
  // Auth material is read at request time via refs so an inline `headers` object literal
@@ -237,12 +159,12 @@ export const useAgentThreads = (options) => {
237
159
  const fetchThread = useCallback((threadChatId, threadChatThreadId) => fetchJson(`/agent-threads/${encodeURIComponent(agentId)}/thread?${new URLSearchParams({ chatId: threadChatId, chatThreadId: threadChatThreadId })}`), [agentId, fetchJson]);
238
160
  /**
239
161
  * Rename a conversation — optimistic with rollback, rejecting on failure so callers
240
- * can surface it. The new title is applied to EVERY local title source: the loaded
241
- * row, any optimistic entry (whose snapshot the overlay may currently be showing),
242
- * and the stored selection — `currentThread`'s fallback when a filter change dropped
243
- * the row from the list; without it, a rename of the open-but-unlisted conversation
244
- * would never reach the header. Other tabs get the rename via the pusher event; this
245
- * tab is excluded from the echo (x-socket-id), matching the optimistic apply.
162
+ * can surface it. The new title is applied to every local title source: the loaded
163
+ * row and any optimistic entry (whose snapshot the overlay may currently be showing).
164
+ * A conversation the list does not hold (a filter dropped its row) has no local title
165
+ * here — the consumer keeps its own copy of that row and applies the rename itself.
166
+ * Other tabs get the rename via the pusher event; this tab is excluded from the echo
167
+ * (x-socket-id), matching the optimistic apply.
246
168
  */
247
169
  const renameThread = useCallback(async (thread, title) => {
248
170
  const trimmed = title.trim();
@@ -253,7 +175,7 @@ export const useAgentThreads = (options) => {
253
175
  // `undefined` means "that source held no row when we started" — leave whatever is
254
176
  // there now alone. Collapsing it to null would let a rollback erase a title that
255
177
  // landed from the server while the request was in flight.
256
- const setLocalTitle = (rowTitle, entryTitle, selectedTitle) => {
178
+ const setLocalTitle = (rowTitle, entryTitle) => {
257
179
  const row = threadsRef.current.find((item) => agentThreadKey(item) === key);
258
180
  if (row && rowTitle !== undefined && row.title !== rowTitle) {
259
181
  applyThreads(threadsRef.current.map((item) => (item === row ? { ...item, title: rowTitle } : item)));
@@ -264,18 +186,10 @@ export const useAgentThreads = (options) => {
264
186
  next.set(key, { ...entry, title: entryTitle });
265
187
  applyOptimisticThreads(next);
266
188
  }
267
- setSelectedThread((prev) => prev && agentThreadKey(prev) === key && selectedTitle !== undefined && prev.title !== selectedTitle
268
- ? { ...prev, title: selectedTitle }
269
- : prev);
270
189
  };
271
190
  const previousRowTitle = threadsRef.current.find((item) => agentThreadKey(item) === key)?.title;
272
191
  const previousEntryTitle = optimisticThreadsRef.current.get(key)?.title;
273
- // currentThread IS the stored selection whenever the selection matters as a
274
- // fallback (and the fresher list row otherwise) — either way, the right value
275
- // to restore the selection's title to.
276
- const current = currentThreadRef.current;
277
- const previousSelectedTitle = agentThreadKey(current) === key ? current.title : undefined;
278
- setLocalTitle(trimmed, trimmed, trimmed);
192
+ setLocalTitle(trimmed, trimmed);
279
193
  try {
280
194
  const socketId = websocketsService.getSocketId();
281
195
  const { updated } = await fetchJson(`/agent-threads/${encodeURIComponent(agentId)}/thread`, {
@@ -294,7 +208,7 @@ export const useAgentThreads = (options) => {
294
208
  }
295
209
  }
296
210
  catch (error) {
297
- setLocalTitle(previousRowTitle, previousEntryTitle, previousSelectedTitle);
211
+ setLocalTitle(previousRowTitle, previousEntryTitle);
298
212
  throw error;
299
213
  }
300
214
  }, [agentId, fetchJson, applyThreads, applyOptimisticThreads]);
@@ -494,9 +408,6 @@ export const useAgentThreads = (options) => {
494
408
  }, [agentId, liveUpdateOptions, fetchThread, applyThreads, applyOptimisticThreads]);
495
409
  return {
496
410
  threads: displayThreads,
497
- currentThread,
498
- isDraftThread,
499
- setCurrentThread,
500
411
  notifyThreadActivity,
501
412
  renameThread,
502
413
  isLoading,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocksdiy/react-common",
3
- "version": "1.42.0",
3
+ "version": "1.43.0",
4
4
  "type": "module",
5
5
  "description": "React common",
6
6
  "keywords": [],