@webority/mobile-chat 0.0.0-stage → 0.4.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.
Files changed (71) hide show
  1. package/LICENSE.txt +9 -0
  2. package/README.md +146 -2
  3. package/lib/commonjs/client.js +1 -0
  4. package/lib/commonjs/components/ActionCard.js +1 -0
  5. package/lib/commonjs/components/ChatComposer.js +1 -0
  6. package/lib/commonjs/components/ChatConversationList.js +1 -0
  7. package/lib/commonjs/components/ChatLauncher.js +1 -0
  8. package/lib/commonjs/components/ChatMarkdown.js +1 -0
  9. package/lib/commonjs/components/ChatMessage.js +1 -0
  10. package/lib/commonjs/components/ChatScreen.js +1 -0
  11. package/lib/commonjs/components/ChatThread.js +1 -0
  12. package/lib/commonjs/components/ReplyRating.js +1 -0
  13. package/lib/commonjs/index.js +1 -0
  14. package/lib/commonjs/labels.js +1 -0
  15. package/lib/commonjs/markdownParse.js +1 -0
  16. package/lib/commonjs/package.json +1 -0
  17. package/lib/commonjs/sse.js +1 -0
  18. package/lib/commonjs/types.js +1 -0
  19. package/lib/commonjs/useChat.js +1 -0
  20. package/lib/module/client.js +1 -0
  21. package/lib/module/components/ActionCard.js +1 -0
  22. package/lib/module/components/ChatComposer.js +1 -0
  23. package/lib/module/components/ChatConversationList.js +1 -0
  24. package/lib/module/components/ChatLauncher.js +1 -0
  25. package/lib/module/components/ChatMarkdown.js +1 -0
  26. package/lib/module/components/ChatMessage.js +1 -0
  27. package/lib/module/components/ChatScreen.js +1 -0
  28. package/lib/module/components/ChatThread.js +1 -0
  29. package/lib/module/components/ReplyRating.js +1 -0
  30. package/lib/module/index.js +1 -0
  31. package/lib/module/labels.js +1 -0
  32. package/lib/module/markdownParse.js +1 -0
  33. package/lib/module/package.json +1 -0
  34. package/lib/module/sse.js +1 -0
  35. package/lib/module/types.js +1 -0
  36. package/lib/module/useChat.js +1 -0
  37. package/lib/typescript/commonjs/client.d.ts +73 -0
  38. package/lib/typescript/commonjs/components/ActionCard.d.ts +23 -0
  39. package/lib/typescript/commonjs/components/ChatComposer.d.ts +20 -0
  40. package/lib/typescript/commonjs/components/ChatConversationList.d.ts +23 -0
  41. package/lib/typescript/commonjs/components/ChatLauncher.d.ts +22 -0
  42. package/lib/typescript/commonjs/components/ChatMarkdown.d.ts +23 -0
  43. package/lib/typescript/commonjs/components/ChatMessage.d.ts +35 -0
  44. package/lib/typescript/commonjs/components/ChatScreen.d.ts +30 -0
  45. package/lib/typescript/commonjs/components/ChatThread.d.ts +17 -0
  46. package/lib/typescript/commonjs/components/ReplyRating.d.ts +19 -0
  47. package/lib/typescript/commonjs/index.d.ts +28 -0
  48. package/lib/typescript/commonjs/labels.d.ts +63 -0
  49. package/lib/typescript/commonjs/markdownParse.d.ts +59 -0
  50. package/lib/typescript/commonjs/package.json +1 -0
  51. package/lib/typescript/commonjs/sse.d.ts +23 -0
  52. package/lib/typescript/commonjs/types.d.ts +71 -0
  53. package/lib/typescript/commonjs/useChat.d.ts +63 -0
  54. package/lib/typescript/module/client.d.ts +73 -0
  55. package/lib/typescript/module/components/ActionCard.d.ts +23 -0
  56. package/lib/typescript/module/components/ChatComposer.d.ts +20 -0
  57. package/lib/typescript/module/components/ChatConversationList.d.ts +23 -0
  58. package/lib/typescript/module/components/ChatLauncher.d.ts +22 -0
  59. package/lib/typescript/module/components/ChatMarkdown.d.ts +23 -0
  60. package/lib/typescript/module/components/ChatMessage.d.ts +35 -0
  61. package/lib/typescript/module/components/ChatScreen.d.ts +30 -0
  62. package/lib/typescript/module/components/ChatThread.d.ts +17 -0
  63. package/lib/typescript/module/components/ReplyRating.d.ts +19 -0
  64. package/lib/typescript/module/index.d.ts +28 -0
  65. package/lib/typescript/module/labels.d.ts +63 -0
  66. package/lib/typescript/module/markdownParse.d.ts +59 -0
  67. package/lib/typescript/module/package.json +1 -0
  68. package/lib/typescript/module/sse.d.ts +23 -0
  69. package/lib/typescript/module/types.d.ts +71 -0
  70. package/lib/typescript/module/useChat.d.ts +63 -0
  71. package/package.json +93 -4
@@ -0,0 +1,23 @@
1
+ import type React from 'react';
2
+ export interface ChatMarkdownProps<T = string> {
3
+ /** The reply text, possibly still arriving. */
4
+ text: string;
5
+ /**
6
+ * Maps a reply link (`scheme:kind/id`, e.g. `app:requirement/R-12`) to what it opens in the
7
+ * app: a route, a screen and its params, anything `onLinkPress` understands. Return null for a
8
+ * link the app does not know; it then shows as plain text. A web address never reaches it.
9
+ */
10
+ resolveLink?: (href: string) => T | null | undefined;
11
+ /** Opens what `resolveLink` returned. Without it, links show as plain text. */
12
+ onLinkPress?: (target: T) => void;
13
+ testID?: string;
14
+ }
15
+ /**
16
+ * Renders a reply from a small, safe subset of Markdown: paragraphs, bold, italics, inline code,
17
+ * bullet and numbered lists, simple tables (scrolling sideways), headings (as bold lines), code
18
+ * blocks and rules. It never opens a web address: a link shows only when its href has the form
19
+ * `scheme:kind/id` and `resolveLink` maps it. Text still arriving updates the last block in place,
20
+ * and an unclosed `**` shows as typed until its partner arrives.
21
+ */
22
+ export declare function ChatMarkdown<T = string>({ text, resolveLink, onLinkPress, testID }: ChatMarkdownProps<T>): React.ReactElement;
23
+ //# sourceMappingURL=ChatMarkdown.d.ts.map
@@ -0,0 +1,35 @@
1
+ import type React from 'react';
2
+ import { type ChatLabels } from '../labels';
3
+ import type { ChatRating, SupportActionTicket } from '../types';
4
+ import type { ChatTurn } from '../useChat';
5
+ /** The props a thread passes to each of its turns. */
6
+ export interface ChatReplyProps<T = string> {
7
+ /** Shows the rating under a stored reply. */
8
+ onRate?: (turnId: string, rating: ChatRating, note?: string) => Promise<unknown>;
9
+ /** Maps a reply link to what it opens; see `ChatMarkdown`. */
10
+ resolveLink?: (href: string) => T | null | undefined;
11
+ /** Opens what `resolveLink` returned. */
12
+ onLinkPress?: (target: T) => void;
13
+ /** Shows support action cards; see `ActionCard`. */
14
+ confirmAction?: (token: string) => Promise<SupportActionTicket>;
15
+ onViewTicket?: (ticket: SupportActionTicket) => void;
16
+ /**
17
+ * Draws the assistant's answer in place of `ChatMarkdown` (charts, maths). The question, action
18
+ * cards, rating and layout stay the library's.
19
+ */
20
+ renderReply?: (turn: ChatTurn, state: {
21
+ streaming: boolean;
22
+ }) => React.ReactNode;
23
+ labels?: Partial<ChatLabels>;
24
+ }
25
+ export interface ChatMessageProps<T = string> extends ChatReplyProps<T> {
26
+ turn: ChatTurn;
27
+ testID?: string;
28
+ }
29
+ /**
30
+ * One turn: the person's question on the right, the assistant's answer on the left. The answer is
31
+ * a polite live region, so a screen reader reads it as it settles. Support actions show under the
32
+ * answer, and the rating once the reply is stored.
33
+ */
34
+ export declare function ChatMessage<T = string>({ turn, onRate, resolveLink, onLinkPress, confirmAction, onViewTicket, renderReply, labels: labelOverrides, testID }: ChatMessageProps<T>): React.ReactElement;
35
+ //# sourceMappingURL=ChatMessage.d.ts.map
@@ -0,0 +1,30 @@
1
+ import type React from 'react';
2
+ import type { UseChatResult } from '../useChat';
3
+ import type { ChatReplyProps } from './ChatMessage';
4
+ export interface ChatScreenProps<T = string> extends Omit<ChatReplyProps<T>, 'onRate'> {
5
+ /** The `useChat` result. */
6
+ chat: UseChatResult;
7
+ /** Header title. Defaults to the `panelTitle` label. */
8
+ title?: string;
9
+ /** Extra header controls before New chat, e.g. an "All chats" button. */
10
+ headerActions?: React.ReactNode;
11
+ /** Shown before the first question, in place of the default title and text. */
12
+ empty?: React.ReactNode;
13
+ /** The footnote under the question box. Defaults to the `disclaimer` label; null hides it. */
14
+ disclaimer?: string | null;
15
+ /** The server's message limit. Default 4000. */
16
+ maxLength?: number;
17
+ /** Show the questions left once this many or fewer remain. Default 10. */
18
+ allowanceThreshold?: number;
19
+ /** Offer ratings under stored replies. Default true. */
20
+ rating?: boolean;
21
+ testID?: string;
22
+ }
23
+ /**
24
+ * The whole chat for one screen of the app's navigator: a header with New chat, the
25
+ * conversation, the questions left today, the question box and the AI disclaimer. The question
26
+ * box rises with the keyboard. Place it in a stack screen (or a full-height sheet) and keep the
27
+ * `useChat` call above the navigator, so the conversation survives leaving the screen.
28
+ */
29
+ export declare function ChatScreen<T = string>({ chat, title, headerActions, empty, disclaimer, maxLength, allowanceThreshold, rating, testID, ...reply }: ChatScreenProps<T>): React.ReactElement;
30
+ //# sourceMappingURL=ChatScreen.d.ts.map
@@ -0,0 +1,17 @@
1
+ import type React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { ChatTurn } from '../useChat';
4
+ import { type ChatReplyProps } from './ChatMessage';
5
+ export interface ChatThreadProps<T = string> extends ChatReplyProps<T> {
6
+ turns: ChatTurn[];
7
+ /** Shown before the first question. */
8
+ empty?: React.ReactNode;
9
+ style?: StyleProp<ViewStyle>;
10
+ testID?: string;
11
+ }
12
+ /**
13
+ * The conversation, oldest first, in a scroll view that follows the newest text while an answer
14
+ * streams and when a question is added.
15
+ */
16
+ export declare function ChatThread<T = string>({ turns, empty, style, testID, ...reply }: ChatThreadProps<T>): React.ReactElement;
17
+ //# sourceMappingURL=ChatThread.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type React from 'react';
2
+ import { type ChatLabels } from '../labels';
3
+ import type { ChatRating } from '../types';
4
+ export interface ReplyRatingProps {
5
+ /** The rating already saved. */
6
+ rating?: ChatRating | null;
7
+ /** Saves a rating; rejects on failure. */
8
+ onRate: (rating: ChatRating, note?: string) => Promise<unknown>;
9
+ /** The server's note limit. Default 1000. */
10
+ noteMaxLength?: number;
11
+ labels?: Partial<ChatLabels>;
12
+ testID?: string;
13
+ }
14
+ /**
15
+ * Helpful and Not helpful under one reply. Either saves at once; Not helpful then offers an
16
+ * optional note, saved with the same rating. Either choice can be changed.
17
+ */
18
+ export declare const ReplyRating: React.FC<ReplyRatingProps>;
19
+ //# sourceMappingURL=ReplyRating.d.ts.map
@@ -0,0 +1,28 @@
1
+ export type { ChatClient, ChatHttpClient, ChatHttpRequestConfig } from './client';
2
+ export { ChatApiError, createChatClient } from './client';
3
+ export type { ActionCardProps } from './components/ActionCard';
4
+ export { ActionCard } from './components/ActionCard';
5
+ export type { ChatComposerProps } from './components/ChatComposer';
6
+ export { ChatComposer } from './components/ChatComposer';
7
+ export type { ChatConversationListProps } from './components/ChatConversationList';
8
+ export { ChatConversationList } from './components/ChatConversationList';
9
+ export type { ChatLauncherProps } from './components/ChatLauncher';
10
+ export { ChatLauncher } from './components/ChatLauncher';
11
+ export type { ChatMarkdownProps } from './components/ChatMarkdown';
12
+ export { ChatMarkdown } from './components/ChatMarkdown';
13
+ export type { ChatMessageProps, ChatReplyProps } from './components/ChatMessage';
14
+ export { ChatMessage } from './components/ChatMessage';
15
+ export type { ChatScreenProps } from './components/ChatScreen';
16
+ export { ChatScreen } from './components/ChatScreen';
17
+ export type { ChatThreadProps } from './components/ChatThread';
18
+ export { ChatThread } from './components/ChatThread';
19
+ export type { ReplyRatingProps } from './components/ReplyRating';
20
+ export { ReplyRating } from './components/ReplyRating';
21
+ export type { ChatLabels } from './labels';
22
+ export { DEFAULT_CHAT_LABELS } from './labels';
23
+ export type { SseEvent, SseParser } from './sse';
24
+ export { createSseParser } from './sse';
25
+ export type { ChatRating, ChatRatingInput, ChatStreamEventName, ChatStreamOptions, ChatTurnInput, ChatTurnResult, Conversation, ConversationMessage, ConversationSummary, SupportAction, SupportActionTicket } from './types';
26
+ export type { ChatTurn, ChatTurnError, UseChatOptions, UseChatResult } from './useChat';
27
+ export { useChat } from './useChat';
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,63 @@
1
+ export interface ChatLabels {
2
+ launcher: string;
3
+ panelTitle: string;
4
+ newChat: string;
5
+ close: string;
6
+ thread: string;
7
+ you: string;
8
+ assistant: string;
9
+ thinking: string;
10
+ emptyTitle: string;
11
+ emptyText: string;
12
+ composer: string;
13
+ placeholder: string;
14
+ send: string;
15
+ composerHint: string;
16
+ allowance: (count: number) => string;
17
+ disclaimer: string;
18
+ loadingConversation: string;
19
+ rateUp: string;
20
+ rateDown: string;
21
+ rated: string;
22
+ ratingNote: string;
23
+ ratingNoteHint: string;
24
+ ratingNoteSend: string;
25
+ ratingNoteSkip: string;
26
+ ratingFailed: string;
27
+ actionRaiseTicket: string;
28
+ actionReply: (ticketNumber: string) => string;
29
+ actionReopen: (ticketNumber: string) => string;
30
+ actionNote: string;
31
+ actionConfirm: string;
32
+ actionDismiss: string;
33
+ actionDismissed: string;
34
+ actionExpired: string;
35
+ actionFailed: string;
36
+ actionDoneRaiseTicket: (ticketNumber: string) => string;
37
+ actionDoneReply: (ticketNumber: string) => string;
38
+ actionDoneReopen: (ticketNumber: string) => string;
39
+ viewTicket: string;
40
+ conversations: string;
41
+ conversationsEmptyTitle: string;
42
+ conversationsEmptyText: string;
43
+ untitled: string;
44
+ deleteConversation: string;
45
+ deleteConfirmTitle: string;
46
+ deleteConfirmMessage: string;
47
+ deleteConfirm: string;
48
+ deleteFailed: string;
49
+ cancel: string;
50
+ loadMore: string;
51
+ loadFailed: string;
52
+ retry: string;
53
+ }
54
+ /**
55
+ * Every word the chat components show, in English, with the same keys as the web assistant's
56
+ * labels, so a product passes one label set to both. Pass a `labels` object with any subset to a
57
+ * component to change its wording; the rest keep these defaults. The few that take a value are
58
+ * functions. `composerHint` describes a hardware keyboard's Enter key and is not shown on a phone.
59
+ */
60
+ export declare const DEFAULT_CHAT_LABELS: Readonly<ChatLabels>;
61
+ /** The defaults with a component's `labels` laid over them. */
62
+ export declare const mergeLabels: (labels?: Partial<ChatLabels>) => ChatLabels;
63
+ //# sourceMappingURL=labels.d.ts.map
@@ -0,0 +1,59 @@
1
+ type BlockShape = {
2
+ type: 'paragraph';
3
+ lines: string[];
4
+ } | {
5
+ type: 'heading';
6
+ text: string;
7
+ } | {
8
+ type: 'list';
9
+ ordered: boolean;
10
+ start: number;
11
+ items: string[];
12
+ } | {
13
+ type: 'table';
14
+ header: string[];
15
+ rows: string[][];
16
+ } | {
17
+ type: 'code';
18
+ text: string;
19
+ } | {
20
+ type: 'rule';
21
+ };
22
+ export type MarkdownBlock = BlockShape & {
23
+ key: number;
24
+ };
25
+ type InlineShape = {
26
+ type: 'text';
27
+ text: string;
28
+ } | {
29
+ type: 'code';
30
+ text: string;
31
+ } | {
32
+ type: 'strong' | 'em';
33
+ children: InlineToken[];
34
+ } | {
35
+ type: 'link';
36
+ href: string;
37
+ children: InlineToken[];
38
+ };
39
+ export type InlineToken = InlineShape & {
40
+ key: number;
41
+ };
42
+ /**
43
+ * Splits reply text into blocks: paragraphs, headings, bullet and numbered lists, simple tables,
44
+ * code blocks and rules. Each block's `key` is its position, so text arriving at the end of a
45
+ * streaming reply updates the last block in place and never remounts the ones before it.
46
+ */
47
+ export declare const parseBlocks: (text: string | null | undefined) => MarkdownBlock[];
48
+ /**
49
+ * Reads bold (`**` or `__`), italics (`*` or `_`), inline code and `[label](href)` links. A marker
50
+ * with no partner yet (a reply still streaming) shows as the characters typed.
51
+ */
52
+ export declare const parseInline: (text: string) => InlineToken[];
53
+ /**
54
+ * What a reply link opens, or null when it may not open anything. Only `scheme:kind/id` hrefs
55
+ * reach `resolveLink`; a web address never does, so a reply cannot send the person off the app.
56
+ */
57
+ export declare const linkTarget: <T>(href: string, resolveLink: ((href: string) => T | null | undefined) | undefined) => T | null;
58
+ export {};
59
+ //# sourceMappingURL=markdownParse.d.ts.map
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,23 @@
1
+ export interface SseEvent {
2
+ /** The `event:` field, or "message" when the block names none. */
3
+ name: string;
4
+ /** The `data:` lines joined by newlines and parsed as JSON. */
5
+ data: unknown;
6
+ }
7
+ export interface SseParser {
8
+ push: (text: string) => void;
9
+ end: () => void;
10
+ }
11
+ /**
12
+ * An incremental reader for a `text/event-stream` body that arrives in pieces. Each `push` takes
13
+ * the next piece of text; only complete events (ended by a blank line) are handed on, and the
14
+ * incomplete tail waits for the next piece. `end` flushes a final event the stream closed
15
+ * without a blank line after.
16
+ *
17
+ * Line endings may be `\n`, `\r\n` or `\r`, and a `\r\n` pair may be split across two pieces.
18
+ * Comment lines (`:`), `id` and `retry` are ignored. A block whose data is not JSON is reported
19
+ * as an `error` event with the code `invalid-response`, so a caller ends the turn instead of
20
+ * hanging on it.
21
+ */
22
+ export declare const createSseParser: (onEvent: (event: SseEvent) => void) => SseParser;
23
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1,71 @@
1
+ /** An action the assistant prepared for the person to confirm. Nothing happens without the token. */
2
+ export interface SupportAction {
3
+ token: string;
4
+ kind: 'RaiseTicket' | 'Reply' | 'Reopen';
5
+ ticketId: string | null;
6
+ ticketNumber: string | null;
7
+ category: string | null;
8
+ subject: string | null;
9
+ body: string | null;
10
+ expiresDateTimeUtc: string;
11
+ }
12
+ /** The ticket a confirmed support action raised, replied on or reopened. */
13
+ export interface SupportActionTicket {
14
+ id: string;
15
+ number: string;
16
+ }
17
+ export interface ChatTurnInput {
18
+ /** The person's question. */
19
+ message: string;
20
+ /** The conversation to continue; left out or null to start one. */
21
+ conversationId?: string | null;
22
+ /** Product-defined context about the screen, passed through as is. */
23
+ pageContext?: unknown;
24
+ }
25
+ export type ChatStreamEventName = 'delta' | 'reset' | 'actions';
26
+ export interface ChatStreamOptions {
27
+ /** Cancels the request. */
28
+ signal?: AbortSignal;
29
+ /**
30
+ * Called for each event before the end of the turn: `delta { text }` to append, `reset {}` to
31
+ * discard what was shown, `actions { actions }` for support cards.
32
+ */
33
+ onEvent?: (name: ChatStreamEventName, data: unknown) => void;
34
+ }
35
+ /** The `done` event: the turn's outcome of record. */
36
+ export interface ChatTurnResult {
37
+ conversationId: string;
38
+ /** The stored reply's id, for rating; null when storing failed. */
39
+ messageId: string | null;
40
+ /** The reply of record. It replaces whatever was streamed. */
41
+ reply: string;
42
+ /** Null when the person has no daily limit. */
43
+ messagesLeftToday: number | null;
44
+ }
45
+ export interface ConversationSummary {
46
+ publicId: string;
47
+ title: string | null;
48
+ createdDateTimeUtc: string;
49
+ lastMessageDateTimeUtc: string;
50
+ }
51
+ export interface ConversationMessage {
52
+ publicId: string;
53
+ role: 'User' | 'Assistant';
54
+ content: string;
55
+ /** The support actions offered with an assistant reply, as a JSON array. */
56
+ actionsJson: string | null;
57
+ rating: ChatRating | null;
58
+ ratingNote: string | null;
59
+ createdDateTimeUtc: string;
60
+ }
61
+ export interface Conversation {
62
+ publicId: string;
63
+ title: string | null;
64
+ messages: ConversationMessage[];
65
+ }
66
+ export type ChatRating = 'Up' | 'Down';
67
+ export interface ChatRatingInput {
68
+ rating: ChatRating;
69
+ note?: string | null;
70
+ }
71
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,63 @@
1
+ import type { ChatClient } from './client';
2
+ import type { ChatRating, SupportAction } from './types';
3
+ export interface ChatTurnError {
4
+ code: string;
5
+ /** Written for the person. */
6
+ message: string;
7
+ resetsAtUtc: string | null;
8
+ }
9
+ /** One question and its answer. */
10
+ export interface ChatTurn {
11
+ /** Local key; for a reopened conversation, the stored message's id. */
12
+ id: string;
13
+ question: string;
14
+ /** What is shown: the streamed text, then the reply of record. */
15
+ answer: string;
16
+ streaming: boolean;
17
+ error: ChatTurnError | null;
18
+ actions: SupportAction[];
19
+ /** The stored reply's id; rating needs it. */
20
+ messageId: string | null;
21
+ rating: ChatRating | null;
22
+ ratingNote: string | null;
23
+ }
24
+ export interface UseChatOptions {
25
+ /** From `createChatClient`. */
26
+ client: ChatClient;
27
+ /** Sent with each question; read at the moment of sending. */
28
+ pageContext?: unknown;
29
+ }
30
+ export interface UseChatResult {
31
+ /** Oldest first. */
32
+ turns: ChatTurn[];
33
+ /** The conversation being continued, or null. */
34
+ conversationId: string | null;
35
+ /** From the last answer or `refreshAllowance()`; null with no daily limit. */
36
+ messagesLeftToday: number | null;
37
+ /** An answer is arriving. */
38
+ streaming: boolean;
39
+ /** `openConversation` is loading. */
40
+ loading: boolean;
41
+ /** `openConversation` failed. */
42
+ loadError: ChatTurnError | null;
43
+ /** Asks a question. Ignored while an answer is still arriving. */
44
+ submit: (message: string) => Promise<void>;
45
+ /** Replaces the thread with a stored conversation. */
46
+ openConversation: (id: string) => Promise<void>;
47
+ /** Clears the thread; the next question starts a conversation. */
48
+ newConversation: () => void;
49
+ /** Saves a rating, shown at once; a failed save puts the old one back and rejects. */
50
+ rate: (turnId: string, rating: ChatRating, note?: string) => Promise<void>;
51
+ /** Reads the questions left today. */
52
+ refreshAllowance: () => Promise<void>;
53
+ /** Clears everything, for sign-out or an account switch. */
54
+ reset: () => void;
55
+ }
56
+ /**
57
+ * The chat's state and actions, with no store of its own: it lives in the component that calls
58
+ * it. Call `reset()` when the signed-in person or account changes so nothing of one person's chat
59
+ * shows to the next. An answer still streaming is cancelled on `reset`, `newConversation`,
60
+ * `openConversation` and unmount.
61
+ */
62
+ export declare const useChat: ({ client, pageContext }: UseChatOptions) => UseChatResult;
63
+ //# sourceMappingURL=useChat.d.ts.map
@@ -0,0 +1,73 @@
1
+ import type { ChatRatingInput, ChatStreamOptions, ChatTurnInput, ChatTurnResult, Conversation, ConversationSummary } from './types.js';
2
+ /** A failed chat request. `message` is written for the person and is safe to show as is. */
3
+ export declare class ChatApiError extends Error {
4
+ /**
5
+ * The server's code (`daily-limit`, `assistant-unavailable`, ...), `network` when no response
6
+ * arrived, `aborted` when the request was cancelled, `invalid-response`, or `unknown`.
7
+ */
8
+ readonly code: string;
9
+ /** The HTTP status, when a response arrived. */
10
+ readonly status: number | undefined;
11
+ /** For `daily-limit`: when the allowance comes back, in UTC. */
12
+ readonly resetsAtUtc: string | null;
13
+ constructor(code: string, message: string, status?: number, resetsAtUtc?: string | null);
14
+ }
15
+ /** The axios config fields the chat client sets. */
16
+ export interface ChatHttpRequestConfig {
17
+ headers?: Record<string, string>;
18
+ responseType?: 'text';
19
+ signal?: AbortSignal;
20
+ onDownloadProgress?: (progress: unknown) => void;
21
+ }
22
+ /**
23
+ * The slice of an HTTP client the chat client needs. The app's signed-in axios instance
24
+ * (mobile-core's `userClient`, or its own) satisfies it as is, so the bearer token, tenant header
25
+ * and refresh on 401 apply to chat calls too. Declared structurally so no axios type leaks into
26
+ * this package's declarations.
27
+ */
28
+ export interface ChatHttpClient {
29
+ get(url: string, config?: ChatHttpRequestConfig): Promise<{
30
+ data: unknown;
31
+ }>;
32
+ post(url: string, body?: unknown, config?: ChatHttpRequestConfig): Promise<{
33
+ data: unknown;
34
+ status?: number;
35
+ }>;
36
+ put(url: string, body?: unknown, config?: ChatHttpRequestConfig): Promise<{
37
+ data: unknown;
38
+ }>;
39
+ delete(url: string, config?: ChatHttpRequestConfig): Promise<{
40
+ data: unknown;
41
+ }>;
42
+ }
43
+ export interface ChatClient {
44
+ /** `POST {base}/chat`, streamed; resolves with the `done` event. */
45
+ sendMessage(input: ChatTurnInput, options?: ChatStreamOptions): Promise<ChatTurnResult>;
46
+ /** `GET {base}/allowance`. */
47
+ getAllowance(): Promise<{
48
+ messagesLeftToday: number | null;
49
+ }>;
50
+ /** `GET {base}/conversations?skip=&take=`, newest first. */
51
+ listConversations(query?: {
52
+ skip?: number;
53
+ take?: number;
54
+ }): Promise<ConversationSummary[]>;
55
+ /** `GET {base}/conversations/{id}`. */
56
+ getConversation(id: string): Promise<Conversation>;
57
+ /** `DELETE {base}/conversations/{id}`. */
58
+ deleteConversation(id: string): Promise<void>;
59
+ /** `PUT {base}/conversations/{conversationId}/messages/{messageId}/rating`. */
60
+ rateMessage(conversationId: string, messageId: string, input: ChatRatingInput): Promise<void>;
61
+ }
62
+ /**
63
+ * Binds the chat HTTP contract to the app's own signed-in axios instance. The package never
64
+ * handles auth: tokens, tenant headers and refresh stay in the instance.
65
+ *
66
+ * @param http The app's axios instance, e.g. mobile-core's `userClient`.
67
+ * @param options `base` is the prefix the API maps the chat endpoints under, e.g.
68
+ * `/api/assistant` for `POST /api/assistant/chat`.
69
+ */
70
+ export declare const createChatClient: (http: ChatHttpClient, { base }: {
71
+ base: string;
72
+ }) => ChatClient;
73
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1,23 @@
1
+ import type React from 'react';
2
+ import { type ChatLabels } from '../labels.js';
3
+ import type { SupportAction, SupportActionTicket } from '../types.js';
4
+ export interface ActionCardProps {
5
+ action: SupportAction;
6
+ /**
7
+ * Sends the person's yes, e.g. mobile-support's `supportClient.confirmAction`; resolves to the
8
+ * ticket raised, replied on or reopened. A rejection's `message` is shown when present.
9
+ */
10
+ confirmAction: (token: string) => Promise<SupportActionTicket>;
11
+ /** Shows a View ticket button once confirmed. */
12
+ onViewTicket?: (ticket: SupportActionTicket) => void;
13
+ labels?: Partial<ChatLabels>;
14
+ testID?: string;
15
+ }
16
+ /**
17
+ * One support action the assistant prepared, shown under its reply. Nothing reaches support until
18
+ * the person confirms. The card moves from ready to sending to done (with View ticket), or to
19
+ * dismissed on Not now. An expired action (a reopened conversation) still shows what was offered,
20
+ * without a button that could only fail.
21
+ */
22
+ export declare const ActionCard: React.FC<ActionCardProps>;
23
+ //# sourceMappingURL=ActionCard.d.ts.map
@@ -0,0 +1,20 @@
1
+ import type React from 'react';
2
+ import { type ChatLabels } from '../labels.js';
3
+ export interface ChatComposerProps {
4
+ /** Called with the trimmed question; the box clears once it is handed over. */
5
+ onSubmit: (message: string) => unknown;
6
+ /** An answer is arriving: the question can be typed but not sent. */
7
+ busy?: boolean;
8
+ /** No question can be asked, e.g. none left today. */
9
+ disabled?: boolean;
10
+ /** The server's message limit. Default 4000. */
11
+ maxLength?: number;
12
+ labels?: Partial<ChatLabels>;
13
+ testID?: string;
14
+ }
15
+ /**
16
+ * The question box and its send button. The return key adds a new line, as phone keyboards
17
+ * expect; only the button sends.
18
+ */
19
+ export declare const ChatComposer: React.FC<ChatComposerProps>;
20
+ //# sourceMappingURL=ChatComposer.d.ts.map
@@ -0,0 +1,23 @@
1
+ import type React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { ChatClient } from '../client.js';
4
+ import { type ChatLabels } from '../labels.js';
5
+ import type { ConversationSummary } from '../types.js';
6
+ export interface ChatConversationListProps {
7
+ client: ChatClient;
8
+ /** E.g. go to the chat and call `chat.openConversation(conversation.publicId)`. */
9
+ onOpen: (conversation: ConversationSummary) => void;
10
+ /** Called after a chat is deleted, e.g. to start a new chat when the open one was deleted. */
11
+ onDeleted?: (id: string) => void;
12
+ /** Default 20. */
13
+ pageSize?: number;
14
+ labels?: Partial<ChatLabels>;
15
+ style?: StyleProp<ViewStyle>;
16
+ testID?: string;
17
+ }
18
+ /**
19
+ * The person's past chats, newest first. It pages with Show more, refreshes on pull, opens one
20
+ * through `onOpen`, and deletes one after a confirm.
21
+ */
22
+ export declare const ChatConversationList: React.FC<ChatConversationListProps>;
23
+ //# sourceMappingURL=ChatConversationList.d.ts.map
@@ -0,0 +1,22 @@
1
+ import type React from 'react';
2
+ import { type ChatLabels } from '../labels.js';
3
+ export interface ChatLauncherProps {
4
+ onPress: () => void;
5
+ /** `end` (the default) or `start`: the bottom corner it sits in. */
6
+ position?: 'end' | 'start';
7
+ /**
8
+ * Distance above the bottom safe area, so it clears a tab bar or another floating control.
9
+ * Defaults to the theme's floating action button offset.
10
+ */
11
+ bottomOffset?: number;
12
+ /** Show only the icon, with the label as its accessible name. */
13
+ compact?: boolean;
14
+ labels?: Partial<ChatLabels>;
15
+ testID?: string;
16
+ }
17
+ /**
18
+ * An optional floating button that opens the chat. A phone app usually opens the chat from a
19
+ * header action or a Help row instead; use this where a floating entry point fits the screen.
20
+ */
21
+ export declare const ChatLauncher: React.FC<ChatLauncherProps>;
22
+ //# sourceMappingURL=ChatLauncher.d.ts.map
@@ -0,0 +1,23 @@
1
+ import type React from 'react';
2
+ export interface ChatMarkdownProps<T = string> {
3
+ /** The reply text, possibly still arriving. */
4
+ text: string;
5
+ /**
6
+ * Maps a reply link (`scheme:kind/id`, e.g. `app:requirement/R-12`) to what it opens in the
7
+ * app: a route, a screen and its params, anything `onLinkPress` understands. Return null for a
8
+ * link the app does not know; it then shows as plain text. A web address never reaches it.
9
+ */
10
+ resolveLink?: (href: string) => T | null | undefined;
11
+ /** Opens what `resolveLink` returned. Without it, links show as plain text. */
12
+ onLinkPress?: (target: T) => void;
13
+ testID?: string;
14
+ }
15
+ /**
16
+ * Renders a reply from a small, safe subset of Markdown: paragraphs, bold, italics, inline code,
17
+ * bullet and numbered lists, simple tables (scrolling sideways), headings (as bold lines), code
18
+ * blocks and rules. It never opens a web address: a link shows only when its href has the form
19
+ * `scheme:kind/id` and `resolveLink` maps it. Text still arriving updates the last block in place,
20
+ * and an unclosed `**` shows as typed until its partner arrives.
21
+ */
22
+ export declare function ChatMarkdown<T = string>({ text, resolveLink, onLinkPress, testID }: ChatMarkdownProps<T>): React.ReactElement;
23
+ //# sourceMappingURL=ChatMarkdown.d.ts.map