@agents24/chat-react 0.1.9 → 0.1.10

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agents24 Chat React
2
2
 
3
- Last Updated: 2026-06-29
3
+ Last Updated: 2026-07-07
4
4
 
5
5
  Headless React primitives for Agents24 chat surfaces.
6
6
 
@@ -19,13 +19,15 @@ The package owns thread hydration, older-page pagination, stream/reattach state,
19
19
  - `isActiveStreamingTextPart(message, part, streamingMessageId)`
20
20
  - `createFetchChatTransport(options)`
21
21
  - `consumeSseResponse(response, onEvent)`
22
+ - `appendStableStreamingTurn(messages, userMessage, assistantMessage)`
23
+ - `upsertStableAssistantMessage(messages, input)`
22
24
  - normalized chat message, part, transport, and storage types
23
25
  - `partsFromResponseBlocks(blocks, fallbackText)`
24
26
  - `renderChatPart(part, message, renderOptions)`
25
- - `@agents24/chat-react/ui` for shared shadcn-derived `Message`, `Bubble`, `Attachment`, `Marker`, `MessageResponse`, and Agents24 message/attachment adapters
27
+ - `@agents24/chat-react/ui` for shared shadcn-derived `Message`, `Bubble`, `Attachment`, `Marker`, `MessageResponse`, `AgentChatMessage`, `AgentChatComposer`, `McpConnectRequiredCard`, and Agents24 message/attachment adapters
26
28
  - `@agents24/chat-react/templates` for the slot-based `AgentChatShell` starter shell
27
29
 
28
- `useAgents24ChatController` exposes reactive `threads`, `activeThreadId`, `activeThread`, `activeRunId`, `isRefreshingThreads`, `loadThreadById(threadId)`, and `startNewThread()` in addition to message and stream state. It hydrates selected threads, detects active runs from `active_run`/`last_run_status`, attaches through the host transport, detaches local SSE streams on navigation, and refreshes history after terminal events.
30
+ `useAgents24ChatController` exposes reactive `threads`, `activeThreadId`, `activeThread`, `activeRunId`, `isRefreshingThreads`, `loadThreadById(threadId)`, `attachRun(runId, threadId)`, and `startNewThread()` in addition to message and stream state. It hydrates selected threads, detects active runs from `active_run`/`last_run_status`, attaches through the host transport, detaches local SSE streams on navigation, and refreshes history after terminal events.
29
31
 
30
32
  Hosts can pass `onRuntimeEvent(event, context)` and `onThreadDetailLoaded(detail)` to layer product-specific runtime UI, trace panels, analytics, or metadata over the shared chat lifecycle without forking stream handling. That surface is enough for running-history badges and read-only live thread inspectors without a separate host-owned reattach state machine.
31
33
 
@@ -35,6 +37,10 @@ Hosts can pass `onRuntimeEvent(event, context)` and `onThreadDetailLoaded(detail
35
37
 
36
38
  Network access is always injected by the host. This browser package never requires platform API keys.
37
39
 
40
+ ## Message Lifecycle
41
+
42
+ Chat surfaces should keep active assistant turns as stable rows in `messages`: append the user row and assistant placeholder together, stream updates into that assistant `messageId`, finalize that same row in place, then clear the streaming marker. `appendStableStreamingTurn` and `upsertStableAssistantMessage` centralize that invariant for custom hosts. Avoid host-side synthetic assistant rows because removing and re-adding the same response can flicker and can make MessageScroller treat the turn as new content.
43
+
38
44
  ## MessageScroller Behavior
39
45
 
40
46
  The package re-exports shadcn `@shadcn/react/message-scroller` and provides `LatestThreadScroller`, a thin native preset around the official primitives. Host chat shells should prefer:
@@ -53,4 +59,10 @@ The preset defaults to `autoScroll`, `defaultScrollPosition="last-anchor"`, `scr
53
59
 
54
60
  `@agents24/chat-react/ui` contains package-owned source adapted from the shadcn CLI `message`, `bubble`, `attachment`, and `marker` components. Base primitive names stay close to shadcn, while Agents24-specific compatibility adapters sit beside them as `Message`, `MessageContent`, `MessageActions`, `MessageAction`, `MessageAttachments`, `MessageAttachment`, and `MessageResponse`.
55
61
 
56
- `@agents24/chat-react/templates` exposes `AgentChatShell`, a convenience shell that composes `LatestThreadScroller`, the outline rail, latest button, composer overlay spacing, older-history trigger, and message slots. Product apps still own transport, citations, TTS, source panes, artifact actions, and row-specific rendering.
62
+ `AgentChatMessage` and `AgentChatComposer` provide the default customer starter UI used by `AgentChatShell` consumers that want a platform-playground-like baseline without importing platform internals. Hosts can still replace assistant/user message bodies, actions, HITL side effects, and toolbar controls through composition slots.
63
+
64
+ `AgentChatMessage` collapses long user messages by default to keep bubbles compact. The default user bubble shows a four-line preview with `Show more` / `Show less` controls, and hosts can tune the threshold, visible lines, or labels through the `userMessage*` props.
65
+
66
+ `@agents24/chat-react/templates` exposes `AgentChatShell`, a convenience shell that composes `LatestThreadScroller`, the outline rail, latest button, composer overlay spacing, older-history trigger, scroll-state reporting, and message slots. Product apps still own transport, citations, TTS, source panes, artifact actions, and row-specific rendering.
67
+
68
+ The starter shell is suitable for public/shared chat pages and customer apps. Internal playground/admin controls such as traces, debug actions, source viewers, citations, TTS, artifacts, and approval side effects remain host-owned extensions.
@@ -0,0 +1,45 @@
1
+ import { type Dispatch, type MutableRefObject, type SetStateAction } from "react";
2
+ import type { ChatCitation, ChatMessage, ChatReasoningStep, ChatStorageAdapter, ChatSubmitMessage } from "./types";
3
+ type PagingRef = MutableRefObject<number | null>;
4
+ export declare function useControllerMessageActions(input: {
5
+ activeThreadIdRef: MutableRefObject<string | null>;
6
+ createId: () => string;
7
+ detachActiveStream: () => void;
8
+ disliked: Record<string, boolean>;
9
+ handleSubmit: (message: ChatSubmitMessage) => Promise<void>;
10
+ hasOlderTurnsRef: MutableRefObject<boolean>;
11
+ liked: Record<string, boolean>;
12
+ liveVoiceIdsRef: MutableRefObject<{
13
+ user?: string;
14
+ assistant?: string;
15
+ }>;
16
+ loadedThreadIdRef: MutableRefObject<string | null>;
17
+ messagesRef: MutableRefObject<ChatMessage[]>;
18
+ nextBeforeTurnIndexRef: PagingRef;
19
+ onActiveThreadIdChange?: (threadId: string | null) => void;
20
+ persistThread: (threadId: string, nextMessages: ChatMessage[]) => void;
21
+ requestSeqRef: MutableRefObject<number>;
22
+ setContextStatus: Dispatch<SetStateAction<any>>;
23
+ setCopiedMessageId: Dispatch<SetStateAction<string | null>>;
24
+ setDisliked: Dispatch<SetStateAction<Record<string, boolean>>>;
25
+ setHasOlderTurns: Dispatch<SetStateAction<boolean>>;
26
+ setIsLoadingOlder: Dispatch<SetStateAction<boolean>>;
27
+ setLiked: Dispatch<SetStateAction<Record<string, boolean>>>;
28
+ setLoadingHistory: (value: boolean) => void;
29
+ setMessages: Dispatch<SetStateAction<ChatMessage[]>>;
30
+ storage: ChatStorageAdapter;
31
+ }): {
32
+ handleCopy: (content: string, messageId: string) => void;
33
+ handleDislike: (msg: ChatMessage) => Promise<void>;
34
+ handleLike: (msg: ChatMessage) => Promise<void>;
35
+ handleRetry: (msg: ChatMessage) => Promise<void>;
36
+ startNewThread: () => void;
37
+ upsertLiveVoiceMessage: (payload: {
38
+ role: "user" | "assistant";
39
+ content: string;
40
+ isFinal?: boolean;
41
+ citations?: ChatCitation[];
42
+ reasoningSteps?: ChatReasoningStep[];
43
+ }) => void;
44
+ };
45
+ export {};
@@ -0,0 +1,27 @@
1
+ import type { ChatMessage, ChatReasoningStep, ChatPart, ChatThreadSummaryEvent, StoredChatThread } from "./types";
2
+ export type ChatRuntimeEventContext = {
3
+ mode: "submit" | "attach";
4
+ assistantMessageId: string;
5
+ threadId: string | null;
6
+ runId: string | null;
7
+ startedAt: number;
8
+ };
9
+ export type FinalizeInput = {
10
+ threadId: string | null;
11
+ baseMessages: ChatMessage[];
12
+ assistantText: string;
13
+ reasoning: ChatReasoningStep[];
14
+ thinkingDurationMs: number;
15
+ messageId?: string | null;
16
+ runId?: string | null;
17
+ parts?: ChatPart[];
18
+ error?: string;
19
+ };
20
+ export declare const threadSummaryToStored: (thread: Record<string, unknown>) => StoredChatThread;
21
+ export declare const isThreadNotFoundError: (error: unknown) => boolean;
22
+ export declare const isAbortError: (error: unknown) => boolean;
23
+ export declare const abortDetachedStream: (controller: AbortController | null) => void;
24
+ export declare const mergeStoredThreadsForRefresh: (currentThreads: StoredChatThread[], serverThreads: StoredChatThread[]) => StoredChatThread[];
25
+ export declare const hasRunningStoredThreads: (threads: StoredChatThread[]) => boolean;
26
+ export declare const sameStoredThread: (left: StoredChatThread | undefined, right: StoredChatThread | undefined) => boolean;
27
+ export declare const applyThreadSummaryEvent: (currentThreads: StoredChatThread[], event: ChatThreadSummaryEvent) => StoredChatThread[];
@@ -1,11 +1,6 @@
1
+ import { type ChatRuntimeEventContext } from "./controller-helpers";
1
2
  import type { ChatController, ChatMessage, ChatRuntimeEvent, ChatStorageAdapter, ChatTransport } from "./types";
2
- export type ChatRuntimeEventContext = {
3
- mode: "submit" | "attach";
4
- assistantMessageId: string;
5
- threadId: string | null;
6
- runId: string | null;
7
- startedAt: number;
8
- };
3
+ export { mergeStoredThreadsForRefresh } from "./controller-helpers";
9
4
  export type UseAgents24ChatControllerOptions = {
10
5
  transport: ChatTransport;
11
6
  storage: ChatStorageAdapter;