@foris/ai-agent 1.0.8 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-agent.es.js +9340 -9130
- package/dist/ai-agent.umd.js +60 -60
- package/dist/api/chatStream.types.d.ts +14 -5
- package/dist/api/chatStreamAdapter.d.ts +10 -0
- package/dist/components/ai-elements/message-code-block.d.ts +11 -0
- package/dist/components/chat-panel/chat-panel/ChatPanel.d.ts +9 -7
- package/dist/components/chat-panel/chat-panel/chatPanel.types.d.ts +9 -2
- package/dist/components/chat-panel/error-connection-inline/errorConnectionInline.type.d.ts +5 -2
- package/dist/components/chat-panel/footer/Footer.test.d.ts +0 -0
- package/dist/components/chat-panel/footer/footer.type.d.ts +8 -1
- package/dist/components/chat-panel/locale/en.json.d.ts +5 -1
- package/dist/components/chat-panel/locale/es.json.d.ts +5 -1
- package/dist/components/chat-panel/message-item/MessageItem.d.ts +4 -0
- package/dist/components/chat-panel/not-front-error-boundary/NotFrontErrorBoundary.d.ts +16 -0
- package/dist/components/chat-panel/not-front-error-boundary/NotFrontErrorBoundary.test.d.ts +0 -0
- package/dist/components/chat-panel/not-front-error-boundary/index.d.ts +2 -0
- package/dist/hooks/chat.constants.d.ts +9 -1
- package/dist/hooks/chat.utils.d.ts +11 -0
- package/dist/hooks/chat.utils.test.d.ts +1 -0
- package/dist/hooks/useChat.d.ts +18 -2
- package/dist/hooks/useChat.test.d.ts +1 -0
- package/dist/hooks/useConnectivityPing.d.ts +5 -4
- package/dist/hooks/useConnectivityPing.test.d.ts +1 -0
- package/dist/hooks/useMessageProcessor.test.d.ts +1 -0
- package/dist/hooks/useSplitChunks.d.ts +28 -1
- package/dist/hooks/useThinkingPhase.d.ts +3 -1
- package/dist/index.d.ts +2 -0
- package/dist/style.css +1 -1
- package/package.json +10 -5
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Raw event shapes as sent by the backend over the SSE stream.
|
|
3
|
-
* Update this type when the backend contract changes, then adjust
|
|
4
|
-
* chatStreamAdapter.ts accordingly — nothing else needs to change.
|
|
5
|
-
*/
|
|
6
1
|
export type RawBackendEvent = {
|
|
7
2
|
type: 'message_chunk';
|
|
8
3
|
content: string;
|
|
@@ -20,4 +15,18 @@ export type RawBackendEvent = {
|
|
|
20
15
|
tool_call_id?: string;
|
|
21
16
|
display_name?: string;
|
|
22
17
|
message?: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: 'render_not_front';
|
|
20
|
+
id: string;
|
|
21
|
+
display: unknown;
|
|
22
|
+
} | {
|
|
23
|
+
type: 'stop';
|
|
24
|
+
chat_id?: string;
|
|
25
|
+
references: Record<string, unknown>;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'remove_not_front';
|
|
28
|
+
id: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'error';
|
|
31
|
+
error: 'resume_timeout' | (string & {});
|
|
23
32
|
};
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import type { ChatMessage } from '../types/chat';
|
|
2
2
|
import type { RawBackendEvent } from './chatStream.types';
|
|
3
3
|
export type MessageListUpdater = (prev: ChatMessage[]) => ChatMessage[];
|
|
4
|
+
/**
|
|
5
|
+
* Updater that removes the not-front payload with the given id from any
|
|
6
|
+
* assistant message. Shared by the `remove_not_front` SSE event and the
|
|
7
|
+
* pause-expiry path (which dismisses the stale card locally using the
|
|
8
|
+
* `render_id` carried in the `stop` references).
|
|
9
|
+
*/
|
|
10
|
+
export declare function removeNotFrontPayload(id: string): MessageListUpdater;
|
|
4
11
|
/**
|
|
5
12
|
* Maps a raw backend event to a pure state updater function.
|
|
6
13
|
* Returns null for events that require no state change.
|
|
14
|
+
*
|
|
15
|
+
* `stop` is NOT handled here: it is a flow-control event resolved by
|
|
16
|
+
* `useSplitChunks` (like `[DONE]`), not a message-list update.
|
|
7
17
|
*/
|
|
8
18
|
export declare function adaptBackendEvent(event: RawBackendEvent): MessageListUpdater | null;
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { CodeBlockLanguage } from './code-block';
|
|
2
3
|
export declare const PreWrapper: ({ children }: {
|
|
3
4
|
children: React.ReactNode;
|
|
4
5
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export type ChatCodeBlockProps = {
|
|
7
|
+
code: string;
|
|
8
|
+
language: CodeBlockLanguage;
|
|
9
|
+
className?: string;
|
|
10
|
+
bodyClassName?: string;
|
|
11
|
+
showCopy?: boolean;
|
|
12
|
+
copyDisabled?: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** Styled code block shared by markdown messages and tool trace panels. */
|
|
15
|
+
export declare const ChatCodeBlock: React.MemoExoticComponent<({ code, language, className, bodyClassName, showCopy, copyDisabled, }: ChatCodeBlockProps) => import("react/jsx-runtime").JSX.Element>;
|
|
5
16
|
/** Props from react-markdown for the code component */
|
|
6
17
|
export type MessageCodeBlockProps = React.ComponentProps<'code'>;
|
|
7
18
|
/**
|
|
@@ -2,6 +2,7 @@ import type { FC } from 'react';
|
|
|
2
2
|
import { type AiAgentTheme, type ResolveSyntaxAppearanceFn } from '@/context/AiAgentThemeContext';
|
|
3
3
|
import type { SuggestionType } from '../../../types/chat';
|
|
4
4
|
import type { DataSource } from '../../../types/dataSource';
|
|
5
|
+
import type { RenderNotFront } from '../../../types/notFront';
|
|
5
6
|
import type { ChatPanelTranslations } from './chatPanel.types';
|
|
6
7
|
interface ChatPanelProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
8
|
dataSource: DataSource;
|
|
@@ -14,15 +15,16 @@ interface ChatPanelProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
14
15
|
theme?: AiAgentTheme;
|
|
15
16
|
/** Optional mapper from theme id to syntax appearance (incl. CodeBlock Shiki light/dark). */
|
|
16
17
|
resolveSyntaxAppearance?: ResolveSyntaxAppearanceFn;
|
|
17
|
-
/**
|
|
18
|
+
/** Fired when the user toggles expand/collapse. Use to drive `isExpanded` on a containing Drawer. */
|
|
18
19
|
onExpandedChange?: (expanded: boolean) => void;
|
|
19
|
-
/**
|
|
20
|
-
* When `true`, constrains width to the same formula as Drawer `contentWidth="default"`:
|
|
21
|
-
* `max-width: min(30vw, 507px)` and `min-width: 448px` (desktop). Does not change Drawer; use for standalone previews or hosts that do not wrap the panel in Drawer.
|
|
22
|
-
*
|
|
23
|
-
* @default false
|
|
24
|
-
*/
|
|
20
|
+
/** Constrains width to `min(30vw, 507px)` — same formula as Drawer default. For standalone use outside a Drawer. */
|
|
25
21
|
viewportColumnWidth?: boolean;
|
|
22
|
+
/** Component that renders `render_not_front` SSE payloads. Import `renderNotFront` from `@foris/avocado-not-front`. */
|
|
23
|
+
renderNotFront?: RenderNotFront;
|
|
24
|
+
/** Stable session id sent with every stream POST. Omit to let the panel generate one internally. */
|
|
25
|
+
chatId?: string;
|
|
26
|
+
/** Called after the user clears the conversation; receives the new session id. */
|
|
27
|
+
onChatIdChange?: (nextChatId: string) => void;
|
|
26
28
|
}
|
|
27
29
|
export declare const ChatPanel: FC<ChatPanelProps>;
|
|
28
30
|
export default ChatPanel;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolCall } from '../../../types/chat';
|
|
2
|
-
|
|
2
|
+
import type { NotFrontPayload } from '../../../types/notFront';
|
|
3
|
+
export type ErrorMessageKind = 'connection' | 'response' | 'expired';
|
|
3
4
|
export interface ChatPanelTranslations {
|
|
4
5
|
title?: string;
|
|
5
6
|
welcomeTitle?: string;
|
|
@@ -8,7 +9,9 @@ export interface ChatPanelTranslations {
|
|
|
8
9
|
placeholder?: string;
|
|
9
10
|
placeholderProcessing?: string;
|
|
10
11
|
placeholderDisconnected?: string;
|
|
12
|
+
placeholderWaiting?: string;
|
|
11
13
|
processingTooltip?: string;
|
|
14
|
+
waitingTooltip?: string;
|
|
12
15
|
sendMessageAriaLabel?: string;
|
|
13
16
|
disclaimer?: string;
|
|
14
17
|
clearChatTitle?: string;
|
|
@@ -29,6 +32,7 @@ export interface ChatPanelTranslations {
|
|
|
29
32
|
errorConnectionInlineRetry?: string;
|
|
30
33
|
errorResponseTitle?: string;
|
|
31
34
|
errorResponseRetry?: string;
|
|
35
|
+
pauseExpiredMessage?: string;
|
|
32
36
|
thinkingStep1?: string;
|
|
33
37
|
thinkingStep2?: string;
|
|
34
38
|
thinkingUsingTool?: string;
|
|
@@ -37,6 +41,7 @@ export interface ChatPanelTranslations {
|
|
|
37
41
|
reasoningTracePlural?: string;
|
|
38
42
|
reasoningTraceParameters?: string;
|
|
39
43
|
reasoningTraceResult?: string;
|
|
44
|
+
notFrontErrorLabel?: string;
|
|
40
45
|
}
|
|
41
46
|
export interface UserMessage {
|
|
42
47
|
key: string;
|
|
@@ -73,12 +78,14 @@ export interface AssistantMessage {
|
|
|
73
78
|
duration: number;
|
|
74
79
|
};
|
|
75
80
|
tools?: ToolCall[];
|
|
81
|
+
notFront?: NotFrontPayload[];
|
|
76
82
|
}
|
|
77
83
|
export interface ErrorMessage {
|
|
78
84
|
key: string;
|
|
79
85
|
from: 'error';
|
|
80
86
|
kind: ErrorMessageKind;
|
|
81
|
-
|
|
87
|
+
/** Absent for `expired` notices — there is no message to retry. */
|
|
88
|
+
failedUserMessageKey?: string;
|
|
82
89
|
}
|
|
83
90
|
export type MessageType = UserMessage | AssistantMessage | ErrorMessage;
|
|
84
91
|
export declare const isErrorMessage: (message: MessageType) => message is ErrorMessage;
|
|
@@ -3,8 +3,11 @@ export interface ErrorConnectionInlineTranslations {
|
|
|
3
3
|
retryLabel?: string;
|
|
4
4
|
}
|
|
5
5
|
export interface ErrorConnectionInlineProps {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/** Absent for non-retryable notices (e.g. pause expiry). */
|
|
7
|
+
failedUserMessageKey?: string;
|
|
8
|
+
onRetry?: (failedUserMessageKey?: string) => Promise<void> | void;
|
|
8
9
|
translations?: ErrorConnectionInlineTranslations;
|
|
9
10
|
className?: string;
|
|
11
|
+
/** Hides the retry action — for informational notices like pause expiry. */
|
|
12
|
+
hideRetry?: boolean;
|
|
10
13
|
}
|
|
File without changes
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* `waiting`: the agent paused mid-turn (stop → resume) and is waiting for the
|
|
4
|
+
* user to interact with a card in the conversation — input locked like
|
|
5
|
+
* `processing`, with its own placeholder.
|
|
6
|
+
*/
|
|
7
|
+
export type FooterState = 'idle' | 'processing' | 'disconnected' | 'waiting';
|
|
3
8
|
export interface FooterTranslations {
|
|
4
9
|
placeholderIdle: string;
|
|
5
10
|
placeholderProcessing: string;
|
|
6
11
|
placeholderDisconnected: string;
|
|
12
|
+
placeholderWaiting?: string;
|
|
7
13
|
processingTooltip: string;
|
|
14
|
+
waitingTooltip?: string;
|
|
8
15
|
sendMessageAriaLabel: string;
|
|
9
16
|
}
|
|
10
17
|
export interface FooterProps {
|
|
@@ -6,7 +6,9 @@ declare const _default: {
|
|
|
6
6
|
"placeholder": "Ask or create something...",
|
|
7
7
|
"placeholderProcessing": "Processing request...",
|
|
8
8
|
"placeholderDisconnected": "Not available",
|
|
9
|
+
"placeholderWaiting": "Waiting for your confirmation...",
|
|
9
10
|
"processingTooltip": "You have a request in progress",
|
|
11
|
+
"waitingTooltip": "Respond to the pending request to continue",
|
|
10
12
|
"sendMessageAriaLabel": "Send message",
|
|
11
13
|
"disclaimer": "Foris AI may make mistakes. Verify the responses.",
|
|
12
14
|
"clearChatTitle": "Clear current conversation",
|
|
@@ -27,6 +29,7 @@ declare const _default: {
|
|
|
27
29
|
"errorResponseRetry": "Retry",
|
|
28
30
|
"errorConnectionInlineTitle": "We couldn't send your message. Check your connection and try again.",
|
|
29
31
|
"errorConnectionInlineRetry": "Retry",
|
|
32
|
+
"pauseExpiredMessage": "The request expired. You can keep chatting.",
|
|
30
33
|
"thinkingStep1": "Thinking...",
|
|
31
34
|
"thinkingStep2": "Understanding your request...",
|
|
32
35
|
"thinkingUsingTool": "Using: {tool}",
|
|
@@ -34,7 +37,8 @@ declare const _default: {
|
|
|
34
37
|
"reasoningTraceSingular": "Reasoning · 1 tool used",
|
|
35
38
|
"reasoningTracePlural": "Reasoning · {count} tools used",
|
|
36
39
|
"reasoningTraceParameters": "Parameters",
|
|
37
|
-
"reasoningTraceResult": "Result"
|
|
40
|
+
"reasoningTraceResult": "Result",
|
|
41
|
+
"notFrontErrorLabel": "Unable to display this content."
|
|
38
42
|
}
|
|
39
43
|
;
|
|
40
44
|
|
|
@@ -6,7 +6,9 @@ declare const _default: {
|
|
|
6
6
|
"placeholder": "Pregunta o crea algo...",
|
|
7
7
|
"placeholderProcessing": "Procesando solicitud...",
|
|
8
8
|
"placeholderDisconnected": "No disponible",
|
|
9
|
+
"placeholderWaiting": "Esperando tu confirmación...",
|
|
9
10
|
"processingTooltip": "Tienes una solicitud en curso",
|
|
11
|
+
"waitingTooltip": "Responde la solicitud pendiente para continuar",
|
|
10
12
|
"sendMessageAriaLabel": "Enviar mensaje",
|
|
11
13
|
"disclaimer": "Foris AI puede cometer errores. Verifica sus respuestas.",
|
|
12
14
|
"clearChatTitle": "Limpiar conversación actual",
|
|
@@ -27,6 +29,7 @@ declare const _default: {
|
|
|
27
29
|
"errorResponseRetry": "Reintentar",
|
|
28
30
|
"errorConnectionInlineTitle": "No pudimos enviar tu mensaje. Verifica tu conexión e intenta de nuevo.",
|
|
29
31
|
"errorConnectionInlineRetry": "Reintentar",
|
|
32
|
+
"pauseExpiredMessage": "La solicitud expiró. Puedes seguir conversando.",
|
|
30
33
|
"thinkingStep1": "Pensando...",
|
|
31
34
|
"thinkingStep2": "Entendiendo tu solicitud...",
|
|
32
35
|
"thinkingUsingTool": "Usando: {tool}",
|
|
@@ -34,7 +37,8 @@ declare const _default: {
|
|
|
34
37
|
"reasoningTraceSingular": "Razonamiento · 1 herramienta utilizada",
|
|
35
38
|
"reasoningTracePlural": "Razonamiento · {count} herramientas utilizadas",
|
|
36
39
|
"reasoningTraceParameters": "Parámetros",
|
|
37
|
-
"reasoningTraceResult": "Resultado"
|
|
40
|
+
"reasoningTraceResult": "Resultado",
|
|
41
|
+
"notFrontErrorLabel": "No se pudo mostrar este contenido."
|
|
38
42
|
}
|
|
39
43
|
;
|
|
40
44
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FC } from 'react';
|
|
2
2
|
import type { MessageType } from '../chat-panel/chatPanel.types';
|
|
3
|
+
import type { RenderNotFront } from '../../../types/notFront';
|
|
3
4
|
interface MessageItemProps {
|
|
4
5
|
message: MessageType;
|
|
5
6
|
locale?: 'en' | 'es';
|
|
@@ -10,10 +11,13 @@ interface MessageItemProps {
|
|
|
10
11
|
errorConnectionInlineRetry?: string;
|
|
11
12
|
errorResponseTitle?: string;
|
|
12
13
|
errorResponseRetry?: string;
|
|
14
|
+
pauseExpiredMessage?: string;
|
|
13
15
|
reasoningTraceSingular?: string;
|
|
14
16
|
reasoningTracePlural?: string;
|
|
15
17
|
reasoningTraceParameters?: string;
|
|
16
18
|
reasoningTraceResult?: string;
|
|
19
|
+
renderNotFront?: RenderNotFront;
|
|
20
|
+
notFrontErrorLabel?: string;
|
|
17
21
|
}
|
|
18
22
|
declare const MessageItem: FC<MessageItemProps>;
|
|
19
23
|
export default MessageItem;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
2
|
+
export interface NotFrontErrorBoundaryProps {
|
|
3
|
+
payloadId: string;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
label?: string;
|
|
6
|
+
}
|
|
7
|
+
interface NotFrontErrorBoundaryState {
|
|
8
|
+
hasError: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare class NotFrontErrorBoundary extends Component<NotFrontErrorBoundaryProps, NotFrontErrorBoundaryState> {
|
|
11
|
+
state: NotFrontErrorBoundaryState;
|
|
12
|
+
static getDerivedStateFromError(): NotFrontErrorBoundaryState;
|
|
13
|
+
componentDidCatch(error: Error, _errorInfo: ErrorInfo): void;
|
|
14
|
+
render(): ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
File without changes
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Default chat stream identifier.
|
|
3
|
+
*
|
|
4
|
+
* @deprecated Use {@link generateChatId} from `./chat.utils` (or import
|
|
5
|
+
* `generateChatId` from `@foris/ai-agent`) to mint a unique id per chat
|
|
6
|
+
* session. This constant remains exported for backwards compatibility with
|
|
7
|
+
* external consumers but is no longer used inside `useChat` or
|
|
8
|
+
* `useConnectivityPing`.
|
|
9
|
+
*/
|
|
2
10
|
export declare const DEFAULT_CHAT_STREAM_ID = "demo-123";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a unique chat session identifier.
|
|
3
|
+
*
|
|
4
|
+
* Format: `chat-{base36-timestamp}-{6-char-random-suffix}`
|
|
5
|
+
* Example: `chat-lqz8kx-a3f9b2`
|
|
6
|
+
*
|
|
7
|
+
* Not cryptographic — for UI identity only. Collision probability is
|
|
8
|
+
* sufficient for distinguishing concurrent chat sessions in the same
|
|
9
|
+
* browser; do NOT use as a security primitive.
|
|
10
|
+
*/
|
|
11
|
+
export declare const generateChatId: () => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/hooks/useChat.d.ts
CHANGED
|
@@ -1,16 +1,32 @@
|
|
|
1
1
|
import { ApiManager } from '@foris/mango-core';
|
|
2
2
|
import type { ChatMessage } from '../types/chat';
|
|
3
3
|
import { DEFAULT_CHAT_STREAM_ID } from './chat.constants';
|
|
4
|
+
import { generateChatId } from './chat.utils';
|
|
4
5
|
export interface OnSubmitProps {
|
|
5
6
|
params?: Record<string, unknown>;
|
|
6
7
|
input: string;
|
|
7
8
|
}
|
|
8
9
|
export { DEFAULT_CHAT_STREAM_ID };
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
export { generateChatId };
|
|
11
|
+
/**
|
|
12
|
+
* When apiManager is passed, streaming uses mango (fetch or axios depending on delegate).
|
|
13
|
+
*
|
|
14
|
+
* `chatId` identifies the chat session in the stream POST body and is shared
|
|
15
|
+
* with `useConnectivityPing` so the backend can correlate ping ↔ stream
|
|
16
|
+
* traffic. When omitted, an id is generated lazily once per hook instance.
|
|
17
|
+
*
|
|
18
|
+
* `resumeUrl` (typically `dataSource.resumeUrl` from the host's ChatPanel
|
|
19
|
+
* config) enables the pause/resume protocol: when a stream leg ends with
|
|
20
|
+
* a `stop` control event, a blocking SSE POST `{ chat_id, references }` is
|
|
21
|
+
* sent there and its continuation flows through the same pipeline. Without
|
|
22
|
+
* it, a `stop` degrades to an immediate pause expiry (notice + local card
|
|
23
|
+
* removal) so the conversation stays usable.
|
|
24
|
+
*/
|
|
25
|
+
export declare const useChat: (api: string, headers?: Record<string, string>, apiManager?: ApiManager, chatId?: string, resumeUrl?: string) => {
|
|
11
26
|
onSubmit: ({ params, input }: OnSubmitProps) => Promise<void>;
|
|
12
27
|
messages: ChatMessage[];
|
|
13
28
|
isLoading: boolean;
|
|
29
|
+
isWaiting: boolean;
|
|
14
30
|
retryLastMessage: (key?: string) => Promise<void>;
|
|
15
31
|
clearMessages: () => void;
|
|
16
32
|
initialLoadError: boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const CONNECTIVITY_PROBE_MESSAGE = "[connectivity-probe]";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Build the JSON body for a connectivity probe with a specific `chat_id`.
|
|
8
|
+
* Matches the streaming chat payload shape (`chat_id` + `message`) so the
|
|
9
|
+
* backend can use the same endpoint contract.
|
|
9
10
|
*/
|
|
10
|
-
export declare const
|
|
11
|
+
export declare const buildConnectivityProbeBody: (chatId: string) => string;
|
|
11
12
|
/**
|
|
12
13
|
* Stable string for cache keys so the same logical headers map to the same entry.
|
|
13
14
|
* Exported for tests that reset or assert cache behaviour.
|
|
@@ -24,4 +25,4 @@ export interface UseConnectivityPingResult {
|
|
|
24
25
|
* Body matches the streaming chat payload (`chat_id` + `message`) because many backends
|
|
25
26
|
* reject `HEAD` (405). Replace with a dedicated ping payload when the API supports it.
|
|
26
27
|
*/
|
|
27
|
-
export declare const useConnectivityPing: (pingUrl?: string, headers?: Record<string, string
|
|
28
|
+
export declare const useConnectivityPing: (pingUrl?: string, headers?: Record<string, string>, chatId?: string) => UseConnectivityPingResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { StreamResponse } from '@foris/mango-core';
|
|
3
3
|
import type { ChatMessage } from '../types/chat';
|
|
4
|
+
/**
|
|
5
|
+
* Terminal state of a stream leg:
|
|
6
|
+
* - `done`: saw the explicit `[DONE]` sentinel.
|
|
7
|
+
* - `stopped`: saw a `stop` control event — the agent paused waiting for user
|
|
8
|
+
* interaction; `references` must be forwarded to the resume endpoint.
|
|
9
|
+
* - `resume_timeout`: saw `{ type: "error", error: "resume_timeout" }` on a
|
|
10
|
+
* resume leg — the pause expired waiting for user interaction.
|
|
11
|
+
* - `closed`: EOF without `[DONE]`, `stop`, or `resume_timeout`. Success on
|
|
12
|
+
* the primary leg (some backends never send `[DONE]`); also success on a
|
|
13
|
+
* resume leg that completed normally after user interaction.
|
|
14
|
+
*/
|
|
4
15
|
export type SplitChunksResult = {
|
|
5
16
|
ok: true;
|
|
17
|
+
end: 'done' | 'closed';
|
|
18
|
+
} | {
|
|
19
|
+
ok: true;
|
|
20
|
+
end: 'stopped';
|
|
21
|
+
references: Record<string, unknown>;
|
|
22
|
+
} | {
|
|
23
|
+
ok: true;
|
|
24
|
+
end: 'resume_timeout';
|
|
6
25
|
} | {
|
|
7
26
|
ok: false;
|
|
8
27
|
error: Error;
|
|
9
28
|
};
|
|
29
|
+
export type SplitChunksOptions = {
|
|
30
|
+
/**
|
|
31
|
+
* Fired once when the first event in this leg produces a message-list
|
|
32
|
+
* update (or plain-text fallback). Used by the resume leg to leave the
|
|
33
|
+
* user-interaction wait state before the turn finishes.
|
|
34
|
+
*/
|
|
35
|
+
onContinuationStart?: () => void;
|
|
36
|
+
};
|
|
10
37
|
export declare const useSplitChunks: (setMessages: React.Dispatch<React.SetStateAction<ChatMessage[]>>) => {
|
|
11
|
-
splitChunks: (res: StreamResponse) => Promise<SplitChunksResult>;
|
|
38
|
+
splitChunks: (res: StreamResponse, options?: SplitChunksOptions) => Promise<SplitChunksResult>;
|
|
12
39
|
};
|
|
@@ -2,6 +2,8 @@ import type { ToolCall } from '../types/chat';
|
|
|
2
2
|
export type ThinkingPhase = 'idle' | 'thinking' | 'tool' | 'preparing' | 'done';
|
|
3
3
|
interface UseThinkingPhaseOptions {
|
|
4
4
|
isLoading: boolean;
|
|
5
|
+
/** True while the agent paused for user interaction on a not-front card. */
|
|
6
|
+
isWaiting?: boolean;
|
|
5
7
|
streamingTools: ToolCall[];
|
|
6
8
|
streamingContent: string;
|
|
7
9
|
labels: {
|
|
@@ -15,5 +17,5 @@ interface UseThinkingPhaseResult {
|
|
|
15
17
|
phase: ThinkingPhase;
|
|
16
18
|
label: string;
|
|
17
19
|
}
|
|
18
|
-
export declare const useThinkingPhase: ({ isLoading, streamingTools, streamingContent, labels, }: UseThinkingPhaseOptions) => UseThinkingPhaseResult;
|
|
20
|
+
export declare const useThinkingPhase: ({ isLoading, isWaiting, streamingTools, streamingContent, labels, }: UseThinkingPhaseOptions) => UseThinkingPhaseResult;
|
|
19
21
|
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { ChatPanel, type ChatPanelTranslations, type SuggestionType, type AiAgentTheme, type SyntaxAppearance, type ResolveSyntaxAppearanceFn, } from './components/chat-panel';
|
|
2
|
+
export type { NotFrontPayload, RenderNotFront, } from './types/notFront';
|
|
3
|
+
export { generateChatId } from './hooks/chat.utils';
|
|
2
4
|
export { ChatSessionProvider, useChatSession, useChatSessionOptional, type ChatSessionContextValue, type ChatSessionProviderProps, } from './context/ChatSessionContext';
|
|
3
5
|
export { ChatPanelMenu } from './components/ui/ai-chat-panel-menu';
|
|
4
6
|
export { SummaryCard, type SummaryCardProps, type SummaryCardTranslations, type SupportedLocale, } from './components/summary-card';
|