@blocksdiy/react-common 1.46.0 → 1.48.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.
@@ -2,9 +2,9 @@ import { type Message, ToolMessage, type UserMessage } from "@ag-ui/client";
2
2
  import { useRenderToolCall } from "@copilotkit/react-core/v2";
3
3
  import { ReactNode, SetStateAction } from "react";
4
4
  import { type RenderProp } from "../utils/compose-render.js";
5
- import { type MessageRunIds } from "../utils/message-run-ids.js";
5
+ import { type MessageRunIds, type RunStartedAt } from "../utils/message-run-ids.js";
6
6
  export { useTextGrowthAnimating } from "../hooks/text-growth-animation.js";
7
- export { MESSAGE_RUN_IDS_EVENT_NAME, messageIdsOfRun, type MessageRunIds } from "../utils/message-run-ids.js";
7
+ export { MESSAGE_RUN_IDS_EVENT_NAME, messageIdsOfRun, type MessageRunIds, type RunStartedAt, } from "../utils/message-run-ids.js";
8
8
  export { type Message, type AssistantMessage, type UserMessage } from "@ag-ui/client";
9
9
  export { useRenderTool, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
10
10
  export interface Attachment {
@@ -61,12 +61,19 @@ export interface AgentChatContextValue {
61
61
  }[];
62
62
  messageById: Map<string, Message>;
63
63
  /**
64
- * The agent run (turn) that produced each replayed message — the `agentRunId` the rows
65
- * it wrote carry. Filled from the connect replay; messages from before run attribution
66
- * (and live-streamed ones) have no entry. Optional so contexts a host builds by hand
67
- * (previews, stubs) need not state it; absent reads as "no run known".
64
+ * The agent run (turn) that produced each message — the `agentRunId` the rows it wrote
65
+ * carry. Replayed messages come attributed by the connect replay, live ones by the run
66
+ * that streams them; messages from before run attribution have no entry. Optional so
67
+ * contexts a host builds by hand (previews, stubs) need not state it; absent reads as
68
+ * "no run known".
68
69
  */
69
70
  runIdByMessageId?: MessageRunIds;
71
+ /**
72
+ * When each run in `runIdByMessageId` started (epoch ms) — the time of a turn, which is
73
+ * what a chat shows under a message. A live run is stamped as it starts; a replayed
74
+ * one comes with the server's time. Runs from before run times have no entry.
75
+ */
76
+ runStartedAt?: RunStartedAt;
70
77
  toolMessages: ToolMessage[];
71
78
  renderToolCall: ReturnType<typeof useRenderToolCall>;
72
79
  sendMessage: (message: Omit<UserMessage, "id" | "role">) => Promise<void>;
@@ -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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"}
@@ -6,9 +6,9 @@ import { useCopilotKit, useRenderToolCall } from "@copilotkit/react-core/v2";
6
6
  import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
7
7
  import { useStickToBottom } from "use-stick-to-bottom";
8
8
  import { ComposeRender } from "../utils/compose-render.js";
9
- import { EMPTY_MESSAGE_RUN_IDS, findMessageGroupElement, mergeMessageRunIds, MESSAGE_IDS_ATTRIBUTE, messageIdsOfRun, readMessageRunIdsEvent, } from "../utils/message-run-ids.js";
9
+ import { claimRunInput, EMPTY_MESSAGE_RUN_IDS, EMPTY_RUN_STARTED_AT, findMessageGroupElement, mergeEntries, MESSAGE_IDS_ATTRIBUTE, messageIdsOfRun, readMessageRunIdsEvent, readRunStartedAtEvent, } from "../utils/message-run-ids.js";
10
10
  export { useTextGrowthAnimating } from "../hooks/text-growth-animation.js";
11
- export { MESSAGE_RUN_IDS_EVENT_NAME, messageIdsOfRun } from "../utils/message-run-ids.js";
11
+ export { MESSAGE_RUN_IDS_EVENT_NAME, messageIdsOfRun, } from "../utils/message-run-ids.js";
12
12
  export { useRenderTool, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
13
13
  // Client-only `useLayoutEffect`, falls back to `useEffect` during SSR.
14
14
  // Needed so the `agent.threadId` mirror commits before CopilotKit's
@@ -311,22 +311,69 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
311
311
  });
312
312
  return groups;
313
313
  }, [copilotMessages]);
314
- // Which run produced each replayed message: the connect replay sends it as a CUSTOM
315
- // event (see utils/message-run-ids). Cleared with the transcript on a conversation swap.
314
+ // Which run produced each message, and when it started (see utils/message-run-ids).
315
+ // Replayed messages: the connect replay sends both as one CUSTOM event, and its word is
316
+ // final — it overwrites what the session recorded. Live messages: RUN_STARTED names the
317
+ // run (the server mints the id, so the one in the event, not the one we sent), times it,
318
+ // and shows the transcript as it stood — the run's input is what sits after the last
319
+ // reply. All of that is recorded with the FIRST message the run streams, and each
320
+ // message it streams is its; first claim wins, as on the server. A run that streams
321
+ // nothing leaves no trace: connect (a reconnect sees the whole transcript, and must not
322
+ // adopt an old unanswered message), or a run that fails before its first token. Cleared
323
+ // with the transcript on a swap.
316
324
  const [runIdByMessageId, setRunIdByMessageId] = useState(EMPTY_MESSAGE_RUN_IDS);
325
+ const [runStartedAt, setRunStartedAt] = useState(EMPTY_RUN_STARTED_AT);
326
+ const liveRunRef = useRef(null);
317
327
  useEffect(() => {
318
328
  if (!copilotAgent) {
319
329
  return;
320
330
  }
331
+ const claimLive = (messageId) => {
332
+ const run = liveRunRef.current;
333
+ if (!run) {
334
+ return;
335
+ }
336
+ const { runId, startedAt, input } = run;
337
+ run.input = null;
338
+ if (input) {
339
+ setRunStartedAt((previous) => mergeEntries(previous, { [runId]: startedAt }));
340
+ }
341
+ setRunIdByMessageId((previous) => {
342
+ const claims = input ? claimRunInput(input, previous, runId) : {};
343
+ if (!previous.has(messageId)) {
344
+ claims[messageId] = runId;
345
+ }
346
+ return mergeEntries(previous, claims);
347
+ });
348
+ };
321
349
  const { unsubscribe } = copilotAgent.subscribe({
350
+ onRunStartedEvent: ({ event, messages }) => {
351
+ liveRunRef.current = { runId: event.runId, startedAt: event.timestamp ?? Date.now(), input: messages };
352
+ },
353
+ onTextMessageStartEvent: ({ event }) => claimLive(event.messageId),
354
+ // A tool-call-only reply is created by its first tool call, under `parentMessageId`
355
+ // when the server names one and the tool call's own id otherwise (the client's rule).
356
+ onToolCallStartEvent: ({ event }) => claimLive(event.parentMessageId ?? event.toolCallId),
357
+ onRunFinalized: () => {
358
+ liveRunRef.current = null;
359
+ },
322
360
  onCustomEvent: ({ event }) => {
323
361
  const runIds = readMessageRunIdsEvent(event);
324
362
  if (runIds) {
325
- setRunIdByMessageId((previous) => mergeMessageRunIds(previous, runIds));
363
+ setRunIdByMessageId((previous) => mergeEntries(previous, runIds));
364
+ }
365
+ const startedAt = readRunStartedAtEvent(event);
366
+ if (startedAt) {
367
+ setRunStartedAt((previous) => mergeEntries(previous, startedAt));
326
368
  }
327
369
  },
328
370
  });
329
- return unsubscribe;
371
+ return () => {
372
+ unsubscribe();
373
+ // A run in flight on the agent we leave finalizes without us; it must not claim
374
+ // the next agent's messages.
375
+ liveRunRef.current = null;
376
+ };
330
377
  }, [copilotAgent]);
331
378
  const interruptAnswersRef = useRef(new Map());
332
379
  // Mirror `currentThreadId` onto the agent instance — the `<CopilotKit>`
@@ -360,6 +407,7 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
360
407
  prevConversationKeyRef.current = conversationKey;
361
408
  copilotAgent?.setMessages?.([]);
362
409
  setRunIdByMessageId(EMPTY_MESSAGE_RUN_IDS);
410
+ setRunStartedAt(EMPTY_RUN_STARTED_AT);
363
411
  setPrompt("");
364
412
  setAttachments([]);
365
413
  // The clear above runs in the layout phase, but the previous conversation's run is
@@ -776,6 +824,7 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
776
824
  renderToolCall,
777
825
  messageById,
778
826
  runIdByMessageId,
827
+ runStartedAt,
779
828
  toolMessages,
780
829
  prompt,
781
830
  attachments,
@@ -1,20 +1,40 @@
1
1
  /**
2
- * Which agent run (turn) produced each message of a conversation.
2
+ * Which agent run (turn) produced each message of a conversation, and when that run
3
+ * started.
3
4
  *
4
5
  * A row an app agent writes records the run that wrote it (`agentRunId`). On
5
6
  * `agent/connect` the server replays the transcript and then sends one AG-UI CUSTOM
6
7
  * event, `blocks.message_run_ids`, carrying `{ runIds: { [messageId]: runId } }` for
7
- * the replayed messages it can attribute (older messages have none). The run id
8
+ * the replayed messages it can attribute (older messages have none), plus
9
+ * `runStartedAt: { [runId]: epochMs }` for the runs it has a time for. The run id
8
10
  * rides in an event rather than on the messages because the AG-UI client validates
9
11
  * snapshot messages against a strict schema that drops unknown fields.
12
+ *
13
+ * A LIVE run is attributed here, from its own events: RUN_STARTED names the run and
14
+ * is its time, the messages it adds are its. The server records the same run id and
15
+ * its own clock, so a reload agrees with what the session showed.
10
16
  */
11
17
  export declare const MESSAGE_RUN_IDS_EVENT_NAME = "blocks.message_run_ids";
12
18
  export type MessageRunIds = ReadonlyMap<string, string>;
19
+ /** Run id → when the run started, in epoch ms. */
20
+ export type RunStartedAt = ReadonlyMap<string, number>;
13
21
  export declare const EMPTY_MESSAGE_RUN_IDS: MessageRunIds;
22
+ export declare const EMPTY_RUN_STARTED_AT: RunStartedAt;
14
23
  /** The `{ messageId: runId }` payload of a run-ids CUSTOM event, or null for any other event. */
15
24
  export declare const readMessageRunIdsEvent: (event: unknown) => Record<string, string> | null;
25
+ /** The `{ runId: epochMs }` payload of a run-ids CUSTOM event, or null when it carries none. */
26
+ export declare const readRunStartedAtEvent: (event: unknown) => Record<string, number> | null;
16
27
  /** `previous` plus `incoming`; returns `previous` itself when nothing changes (no re-render). */
17
- export declare const mergeMessageRunIds: (previous: MessageRunIds, incoming: Record<string, string>) => MessageRunIds;
28
+ export declare const mergeEntries: <V>(previous: ReadonlyMap<string, V>, incoming: Record<string, V>) => ReadonlyMap<string, V>;
29
+ /**
30
+ * The messages a run that just started takes as its input — the unattributed ones after
31
+ * the last assistant message (the user's message, a tool's answer). Unattributed messages
32
+ * before that are older history and stay so. The server's `claim_run_input` rule.
33
+ */
34
+ export declare const claimRunInput: (messages: readonly {
35
+ id: string;
36
+ role: string;
37
+ }[], known: MessageRunIds, runId: string) => Record<string, string>;
18
38
  /** Ids of the messages `runId` produced, in transcript order (empty when the run isn't in it). */
19
39
  export declare const messageIdsOfRun: (messages: readonly {
20
40
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"message-run-ids.d.ts","sourceRoot":"","sources":["../../src/utils/message-run-ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AAEnE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExD,eAAO,MAAM,qBAAqB,EAAE,aAAyB,CAAC;AAK9D,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAehF,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,kBAAkB,GAAI,UAAU,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,aAU9F,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,eAAe,GAC1B,UAAU,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EACnC,QAAQ,aAAa,EACrB,OAAO,MAAM,GAAG,SAAS,KACxB,MAAM,EAKR,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,GAAI,MAAM,UAAU,GAAG,IAAI,EAAE,WAAW,MAAM,KAAG,WAAW,GAAG,IAYlG,CAAC"}
1
+ {"version":3,"file":"message-run-ids.d.ts","sourceRoot":"","sources":["../../src/utils/message-run-ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AAEnE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxD,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,qBAAqB,EAAE,aAAyB,CAAC;AAC9D,eAAO,MAAM,oBAAoB,EAAE,YAAwB,CAAC;AA0B5D,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IACqB,CAAC;AAEvG,gGAAgG;AAChG,eAAO,MAAM,qBAAqB,GAAI,OAAO,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IACsC,CAAC;AAEvH,iGAAiG;AACjG,eAAO,MAAM,YAAY,GAAI,CAAC,EAC5B,UAAU,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,EAChC,UAAU,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,KAC1B,WAAW,CAAC,MAAM,EAAE,CAAC,CAUvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,UAAU,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EACjD,OAAO,aAAa,EACpB,OAAO,MAAM,KACZ,MAAM,CAAC,MAAM,EAAE,MAAM,CAYvB,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,eAAe,GAC1B,UAAU,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EACnC,QAAQ,aAAa,EACrB,OAAO,MAAM,GAAG,SAAS,KACxB,MAAM,EAKR,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,GAAI,MAAM,UAAU,GAAG,IAAI,EAAE,WAAW,MAAM,KAAG,WAAW,GAAG,IAYlG,CAAC"}
@@ -1,45 +1,77 @@
1
1
  /**
2
- * Which agent run (turn) produced each message of a conversation.
2
+ * Which agent run (turn) produced each message of a conversation, and when that run
3
+ * started.
3
4
  *
4
5
  * A row an app agent writes records the run that wrote it (`agentRunId`). On
5
6
  * `agent/connect` the server replays the transcript and then sends one AG-UI CUSTOM
6
7
  * event, `blocks.message_run_ids`, carrying `{ runIds: { [messageId]: runId } }` for
7
- * the replayed messages it can attribute (older messages have none). The run id
8
+ * the replayed messages it can attribute (older messages have none), plus
9
+ * `runStartedAt: { [runId]: epochMs }` for the runs it has a time for. The run id
8
10
  * rides in an event rather than on the messages because the AG-UI client validates
9
11
  * snapshot messages against a strict schema that drops unknown fields.
12
+ *
13
+ * A LIVE run is attributed here, from its own events: RUN_STARTED names the run and
14
+ * is its time, the messages it adds are its. The server records the same run id and
15
+ * its own clock, so a reload agrees with what the session showed.
10
16
  */
11
17
  export const MESSAGE_RUN_IDS_EVENT_NAME = "blocks.message_run_ids";
12
18
  export const EMPTY_MESSAGE_RUN_IDS = new Map();
19
+ export const EMPTY_RUN_STARTED_AT = new Map();
13
20
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
14
- /** The `{ messageId: runId }` payload of a run-ids CUSTOM event, or null for any other event. */
15
- export const readMessageRunIdsEvent = (event) => {
21
+ /**
22
+ * One map of the run-ids CUSTOM event, keeping the entries whose value `isValue`; null for
23
+ * any other event, or when the event lacks that map (a server, or a thread, from before it).
24
+ */
25
+ const readEventMap = (event, key, isValue) => {
16
26
  if (!isRecord(event) || event.name !== MESSAGE_RUN_IDS_EVENT_NAME || !isRecord(event.value)) {
17
27
  return null;
18
28
  }
19
- const runIds = event.value.runIds;
20
- if (!isRecord(runIds)) {
29
+ const entries = event.value[key];
30
+ if (!isRecord(entries)) {
21
31
  return null;
22
32
  }
23
33
  const out = {};
24
- for (const [messageId, runId] of Object.entries(runIds)) {
25
- if (messageId && typeof runId === "string" && runId) {
26
- out[messageId] = runId;
34
+ for (const [entryKey, value] of Object.entries(entries)) {
35
+ if (entryKey && isValue(value)) {
36
+ out[entryKey] = value;
27
37
  }
28
38
  }
29
39
  return out;
30
40
  };
41
+ /** The `{ messageId: runId }` payload of a run-ids CUSTOM event, or null for any other event. */
42
+ export const readMessageRunIdsEvent = (event) => readEventMap(event, "runIds", (value) => typeof value === "string" && value !== "");
43
+ /** The `{ runId: epochMs }` payload of a run-ids CUSTOM event, or null when it carries none. */
44
+ export const readRunStartedAtEvent = (event) => readEventMap(event, "runStartedAt", (value) => typeof value === "number" && Number.isFinite(value));
31
45
  /** `previous` plus `incoming`; returns `previous` itself when nothing changes (no re-render). */
32
- export const mergeMessageRunIds = (previous, incoming) => {
46
+ export const mergeEntries = (previous, incoming) => {
33
47
  let next = null;
34
- for (const [messageId, runId] of Object.entries(incoming)) {
35
- if (previous.get(messageId) === runId) {
48
+ for (const [key, value] of Object.entries(incoming)) {
49
+ if (previous.get(key) === value) {
36
50
  continue;
37
51
  }
38
52
  next ??= new Map(previous);
39
- next.set(messageId, runId);
53
+ next.set(key, value);
40
54
  }
41
55
  return next ?? previous;
42
56
  };
57
+ /**
58
+ * The messages a run that just started takes as its input — the unattributed ones after
59
+ * the last assistant message (the user's message, a tool's answer). Unattributed messages
60
+ * before that are older history and stay so. The server's `claim_run_input` rule.
61
+ */
62
+ export const claimRunInput = (messages, known, runId) => {
63
+ const out = {};
64
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
65
+ const message = messages[index];
66
+ if (message.role === "assistant") {
67
+ break;
68
+ }
69
+ if (!known.has(message.id)) {
70
+ out[message.id] = runId;
71
+ }
72
+ }
73
+ return out;
74
+ };
43
75
  /** Ids of the messages `runId` produced, in transcript order (empty when the run isn't in it). */
44
76
  export const messageIdsOfRun = (messages, runIds, runId) => {
45
77
  if (!runId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocksdiy/react-common",
3
- "version": "1.46.0",
3
+ "version": "1.48.0",
4
4
  "type": "module",
5
5
  "description": "React common",
6
6
  "keywords": [],
@@ -39,7 +39,7 @@
39
39
  "penpal": "^8.0.0",
40
40
  "react": "^19.2.8",
41
41
  "use-stick-to-bottom": "1.1.4",
42
- "@blocksdiy/blocks-client-api": "1.24.0"
42
+ "@blocksdiy/blocks-client-api": "1.5.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/react": "^19.2.18",