@filigran/chatbot 3.14.0 → 3.15.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.
- package/CHANGELOG.md +277 -0
- package/README.md +542 -290
- package/dist/index.d.ts +468 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts +58 -1
- package/dist/markdown.js +1 -1
- package/dist/markdown.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/workspaces.d.ts +99 -0
- package/dist/workspaces.js +2 -0
- package/dist/workspaces.js.map +1 -0
- package/package.json +7 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
1
2
|
import { FunctionComponent } from 'react';
|
|
2
3
|
|
|
4
|
+
/** The modes the header's view switcher offers. */
|
|
3
5
|
type ChatMode = 'sidebar' | 'floating' | 'fullscreen';
|
|
6
|
+
/**
|
|
7
|
+
* Every mode the panel renders in. `inline` fills the host's container instead
|
|
8
|
+
* of floating over the page, for a host that gives the chat a page of its own.
|
|
9
|
+
*/
|
|
10
|
+
type ChatPanelMode = ChatMode | 'inline';
|
|
4
11
|
/**
|
|
5
12
|
* The host's translation lookup, passed down to every component that renders
|
|
6
13
|
* text. Key in, translated string out — the package never owns a dictionary of
|
|
@@ -71,6 +78,9 @@ interface ApiEndpoints {
|
|
|
71
78
|
* No default, for the same reason as {@link ApiEndpoints.approve}: a proxied
|
|
72
79
|
* host has to expose the route before the panel starts calling it. Unset, the
|
|
73
80
|
* live flow still works and only reload recovery is absent.
|
|
81
|
+
*
|
|
82
|
+
* A voice call also reads its `turn` here when the turn its question waits
|
|
83
|
+
* on has been silent for 120 s: `running` keeps the wait.
|
|
74
84
|
*/
|
|
75
85
|
pendingApprovals?: string | null;
|
|
76
86
|
/** Path for fetching agents. Default: '/chat/agents'. Set to null to disable. */
|
|
@@ -189,6 +199,59 @@ interface ApiEndpoints {
|
|
|
189
199
|
* REST backend only.
|
|
190
200
|
*/
|
|
191
201
|
artifacts?: string | null;
|
|
202
|
+
/**
|
|
203
|
+
* Path that stops the running turn on the backend, POSTed `{ conversation_id }`
|
|
204
|
+
* by Stop. For a backend whose turns outlive their stream: the panel then waits
|
|
205
|
+
* for the stream's `cancelled` frame rather than dropping the stream. Unset,
|
|
206
|
+
* Stop drops the stream.
|
|
207
|
+
*
|
|
208
|
+
* No default. REST backend only.
|
|
209
|
+
*/
|
|
210
|
+
cancel?: string | null;
|
|
211
|
+
/**
|
|
212
|
+
* Path that ends an agent's announced wait (`status: wait_start`) early,
|
|
213
|
+
* POSTed `{ conversation_id }` by the waiting indicator's "Continue now".
|
|
214
|
+
*
|
|
215
|
+
* No default. REST backend only.
|
|
216
|
+
*/
|
|
217
|
+
skipWait?: string | null;
|
|
218
|
+
/**
|
|
219
|
+
* Base path of a conversation's event stream, read as
|
|
220
|
+
* `GET {apiBaseUrl}{events}/{conversation_id}/events?client_id=<panel>`: an
|
|
221
|
+
* SSE stream of the turns this panel did not start (another tab, a reload
|
|
222
|
+
* mid-turn), `user_message`, `conversation_title` and `approval_resolved`.
|
|
223
|
+
* The message `POST` then carries the same id in `X-Chat-Client-Id`, so the
|
|
224
|
+
* backend never relays a panel's own turn back to it.
|
|
225
|
+
*
|
|
226
|
+
* No default. REST backend only.
|
|
227
|
+
*/
|
|
228
|
+
events?: string | null;
|
|
229
|
+
/**
|
|
230
|
+
* Base path of a conversation's older messages, read as
|
|
231
|
+
* `GET {messagesPage}/{conversation_id}/messages?before=<oldest message id>&limit=50&supports_artifacts=true`
|
|
232
|
+
* and answered with `{ messages, has_more }` (entries shaped like a restore's).
|
|
233
|
+
* The restore's own `has_more` says whether there are any; "Load earlier
|
|
234
|
+
* messages" then fetches them a page at a time.
|
|
235
|
+
*
|
|
236
|
+
* No default. REST backend only.
|
|
237
|
+
*/
|
|
238
|
+
messagesPage?: string | null;
|
|
239
|
+
/**
|
|
240
|
+
* Path that deletes every conversation of the history, as `DELETE {clearAll}`:
|
|
241
|
+
* the conversation list then offers "Clear all".
|
|
242
|
+
*
|
|
243
|
+
* No default. REST backend only.
|
|
244
|
+
*/
|
|
245
|
+
clearAll?: string | null;
|
|
246
|
+
/**
|
|
247
|
+
* Path that reads text aloud: `POST {tts}` with `{ text, format: 'mp3' }`,
|
|
248
|
+
* answered with the audio. Read aloud and the voice call
|
|
249
|
+
* (`ChatPanelHandle.startVoiceCall`) then use the backend's voice, and the
|
|
250
|
+
* browser's when the route fails.
|
|
251
|
+
*
|
|
252
|
+
* No default. REST backend only.
|
|
253
|
+
*/
|
|
254
|
+
tts?: string | null;
|
|
192
255
|
}
|
|
193
256
|
/** A reusable prompt the user can insert into the composer. */
|
|
194
257
|
interface ChatPromptTemplate {
|
|
@@ -312,9 +375,11 @@ interface ChatContextBreakdown {
|
|
|
312
375
|
toolResults?: number;
|
|
313
376
|
}
|
|
314
377
|
interface ChatPanelProps {
|
|
315
|
-
mode:
|
|
316
|
-
|
|
317
|
-
|
|
378
|
+
mode: ChatPanelMode;
|
|
379
|
+
/** Shows the close button; inline mode has none. */
|
|
380
|
+
onClose?: () => void;
|
|
381
|
+
/** Shows the view switcher; inline mode has none. */
|
|
382
|
+
onModeChange?: (mode: ChatMode) => void;
|
|
318
383
|
topOffset?: number;
|
|
319
384
|
apiBaseUrl: string;
|
|
320
385
|
/** Custom API endpoint configuration. */
|
|
@@ -322,19 +387,31 @@ interface ChatPanelProps {
|
|
|
322
387
|
/**
|
|
323
388
|
* The XTM One URL: the header's "Browse agents" / "Create agent" links, and
|
|
324
389
|
* the waiting panel's invitation to play the arcade there
|
|
325
|
-
* (`{agentDashboardUrl}/chat?arcade=play
|
|
390
|
+
* (`{agentDashboardUrl}/chat?arcade=play`, unless `waitingGameUrl` says
|
|
391
|
+
* where). Only an http(s) URL is linked.
|
|
326
392
|
*/
|
|
327
393
|
agentDashboardUrl?: string;
|
|
394
|
+
/**
|
|
395
|
+
* Where the waiting panel's invitation to play leads, over
|
|
396
|
+
* `{agentDashboardUrl}/chat?arcade=play`: an http(s) URL or a path of the
|
|
397
|
+
* host's own origin (`/…`); anything else links nothing.
|
|
398
|
+
*/
|
|
399
|
+
waitingGameUrl?: string;
|
|
328
400
|
user: {
|
|
329
401
|
firstName: string;
|
|
330
402
|
};
|
|
403
|
+
/**
|
|
404
|
+
* The host's translations, over the panel's own catalog: a key it returns
|
|
405
|
+
* unchanged falls back to the catalog in `locale`, or to English when no
|
|
406
|
+
* `locale` is passed.
|
|
407
|
+
*/
|
|
331
408
|
t?: Translate;
|
|
332
409
|
accentColor?: string;
|
|
333
410
|
logoIcon?: React.ReactNode;
|
|
334
411
|
promptSuggestions?: string[];
|
|
335
|
-
/**
|
|
412
|
+
/** Accepted, and not shown. */
|
|
336
413
|
draftLabel?: string;
|
|
337
|
-
/**
|
|
414
|
+
/** Color of the line above the composer (e.g. a draft context). */
|
|
338
415
|
draftBorderColor?: string;
|
|
339
416
|
/** Enable resizable sidebar (drag to resize). Only applies when mode is 'sidebar'. */
|
|
340
417
|
resizable?: boolean;
|
|
@@ -430,9 +507,11 @@ interface ChatPanelProps {
|
|
|
430
507
|
*/
|
|
431
508
|
onMessageFeedback?: (messageId: string, feedback: MessageFeedback | null, message: ChatMessage) => void;
|
|
432
509
|
/**
|
|
433
|
-
* The user's language as a BCP 47 tag (`'fr'`, `'en-US'`):
|
|
434
|
-
*
|
|
435
|
-
* the
|
|
510
|
+
* The user's language as a BCP 47 tag (`'fr'`, `'en-US'`): the language the
|
|
511
|
+
* panel speaks (its own catalog: en, es, fr, ja) where `t` does not
|
|
512
|
+
* translate a key, formats the time under each message and is the language
|
|
513
|
+
* answers are read aloud in. Default: the browser's own, except that a host
|
|
514
|
+
* passing `t` and no `locale` gets no catalog.
|
|
436
515
|
*/
|
|
437
516
|
locale?: string;
|
|
438
517
|
/**
|
|
@@ -464,6 +543,318 @@ interface ChatPanelProps {
|
|
|
464
543
|
* to keep in step, only the presence or absence of what a host provides.
|
|
465
544
|
*/
|
|
466
545
|
composerToolbar?: React.ReactNode;
|
|
546
|
+
/**
|
|
547
|
+
* Namespaces every key the panel keeps in browser storage (conversation,
|
|
548
|
+
* agent, drafts, widths), for a host mounting more than one panel.
|
|
549
|
+
*/
|
|
550
|
+
storageKeyPrefix?: string;
|
|
551
|
+
/**
|
|
552
|
+
* The conversation on screen, when the host owns it (a `?c=` URL): `null`
|
|
553
|
+
* is a new chat. Left `undefined`, the panel remembers its own.
|
|
554
|
+
*/
|
|
555
|
+
conversationId?: string | null;
|
|
556
|
+
/** Called whenever the conversation on screen changes, whoever changed it. */
|
|
557
|
+
onConversationChange?: (conversationId: string | null) => void;
|
|
558
|
+
/** Agent selected once the list loads, by id or slug, over the remembered one. */
|
|
559
|
+
initialAgent?: string;
|
|
560
|
+
/** Called when another agent is picked. */
|
|
561
|
+
onAgentChange?: (agent: XtmAgent) => void;
|
|
562
|
+
/** Hides the composer: a conversation the user may read but not write to. */
|
|
563
|
+
readOnly?: boolean;
|
|
564
|
+
/** Shown in place of the composer while `readOnly`. */
|
|
565
|
+
readOnlyNotice?: React.ReactNode;
|
|
566
|
+
/**
|
|
567
|
+
* Fields merged into every REST message body, read at send time: the host's
|
|
568
|
+
* own per-message options (tool selection, run mode). They never override
|
|
569
|
+
* the panel's fields (`content`, `conversation_id`, …).
|
|
570
|
+
*/
|
|
571
|
+
getRequestExtras?: () => Record<string, unknown> | undefined;
|
|
572
|
+
/**
|
|
573
|
+
* Every frame received, on the message stream (`relayed: false`) or the event
|
|
574
|
+
* stream (`relayed: true`), including those the panel does not render: the
|
|
575
|
+
* host's way to react to backend-specific events.
|
|
576
|
+
*/
|
|
577
|
+
onStreamEvent?: (event: Record<string, unknown>, info: ChatStreamEventInfo) => void;
|
|
578
|
+
/**
|
|
579
|
+
* The user's session ended: a `session_expired` frame on either stream, or a
|
|
580
|
+
* `401` whose body's `detail.code` is `session_expired` on any request the
|
|
581
|
+
* panel makes. *reason* is the frame's or the `detail`'s `reason`, when it
|
|
582
|
+
* gives one. Called once per set of `requestHeaders`: again only once they
|
|
583
|
+
* change.
|
|
584
|
+
*/
|
|
585
|
+
onSessionEnded?: (reason: string | undefined) => void;
|
|
586
|
+
/**
|
|
587
|
+
* Cards for the `[[KIND:args]]` markers an answer embeds, by marker name
|
|
588
|
+
* (`WORK_ITEM`, `INVESTIGATION`): rendered where the marker stands. Naming
|
|
589
|
+
* `FILE`, `PRESENTATION`, `REPORT` or `VIDEO` replaces the built-in card. A
|
|
590
|
+
* marker no renderer names stays text.
|
|
591
|
+
*/
|
|
592
|
+
markerRenderers?: Record<string, ChatMarkerRenderer>;
|
|
593
|
+
/**
|
|
594
|
+
* Renderers for fenced code blocks, by the fence's language (```` ```chart ````,
|
|
595
|
+
* matched case-insensitively): the node returned stands in place of the code
|
|
596
|
+
* block (a chart, a diagram, a table drawn from the block's data). The
|
|
597
|
+
* renderer gets the block's text, and `streaming` while the answer is still
|
|
598
|
+
* coming, when the block may be incomplete. One that throws, or whose node
|
|
599
|
+
* does, shows `This item could not be loaded.` and leaves the rest of the
|
|
600
|
+
* answer alone. A language no renderer names stays a code block.
|
|
601
|
+
*/
|
|
602
|
+
codeBlockRenderers?: Record<string, ChatCodeBlockRenderer>;
|
|
603
|
+
/**
|
|
604
|
+
* Rewrites a message's text before it is shown, copied or read aloud: the
|
|
605
|
+
* host's own markup (masking secrets, converting a channel's syntax). One
|
|
606
|
+
* that throws leaves the text as it came.
|
|
607
|
+
*/
|
|
608
|
+
transformMessageText?: (text: string, message: ChatMessage) => string;
|
|
609
|
+
/** Opens a deck, report or video in the host itself, in place of the link to XTM One. */
|
|
610
|
+
onArtifactOpen?: (artifact: ChatArtifact) => void;
|
|
611
|
+
/** Controls added to the header, before New chat. */
|
|
612
|
+
headerActions?: React.ReactNode;
|
|
613
|
+
/** Shown above the thread: notices about the conversation as a whole. */
|
|
614
|
+
banner?: React.ReactNode;
|
|
615
|
+
/** Shown above the composer, inside it: what the next message will act on. */
|
|
616
|
+
composerHeader?: React.ReactNode;
|
|
617
|
+
/** Shown after the last message, inside the thread. */
|
|
618
|
+
transcriptFooter?: React.ReactNode;
|
|
619
|
+
/** Replaces the welcome screen of an empty conversation. */
|
|
620
|
+
welcome?: React.ReactNode;
|
|
621
|
+
/** Rendered under a message's content, before its footer; `context.streaming` while the answer is still coming. */
|
|
622
|
+
renderMessageExtras?: (message: ChatMessage, context: ChatMessageSlotContext) => React.ReactNode;
|
|
623
|
+
/** Controls added to a finished message's footer. */
|
|
624
|
+
messageFooterActions?: (message: ChatMessage, context: ChatMessageSlotContext) => React.ReactNode;
|
|
625
|
+
/** Controls added to a conversation's row in the conversation list. */
|
|
626
|
+
sidebarRowActions?: (conversation: ChatConversationSummary) => React.ReactNode;
|
|
627
|
+
/** Controls added beside New conversation, atop the conversation list. */
|
|
628
|
+
sidebarHeaderActions?: React.ReactNode;
|
|
629
|
+
/** Sections added under the conversation list (conversations shared with the user). */
|
|
630
|
+
sidebarSections?: React.ReactNode;
|
|
631
|
+
/** The status line's text for a status, over the built-in one; `undefined` keeps it. */
|
|
632
|
+
statusLabel?: (status: AgentStatusState) => string | undefined;
|
|
633
|
+
/** The rotating messages of the waiting panel, already translated. */
|
|
634
|
+
waitingMessages?: string[];
|
|
635
|
+
/** Replaces the waiting panel's content (its messages and the invitation to play). */
|
|
636
|
+
renderWaitingPanel?: () => React.ReactNode;
|
|
637
|
+
/** Font of the panel's text; the package's own otherwise. */
|
|
638
|
+
fontFamily?: string;
|
|
639
|
+
/**
|
|
640
|
+
* Called once, when the panel has chosen its agent and read back the
|
|
641
|
+
* conversation on screen. Calls made through the handle before then wait
|
|
642
|
+
* for it, and run in order.
|
|
643
|
+
*/
|
|
644
|
+
onReady?: () => void;
|
|
645
|
+
/**
|
|
646
|
+
* Sees every send first, from the composer or the handle: `false` takes it
|
|
647
|
+
* over (nothing is sent, the composer keeps its text), an object rewords it
|
|
648
|
+
* (`text`), shows the user something other than what is sent (`displayText`)
|
|
649
|
+
* or adds fields to its body (`extras`).
|
|
650
|
+
*/
|
|
651
|
+
onBeforeSend?: (draft: ChatSendDraft) => ChatSendDecision;
|
|
652
|
+
/**
|
|
653
|
+
* What became of a message held until the turn ended (a send that resolved
|
|
654
|
+
* `'held'`): sent, refused, dropped (nothing of it the user typed: Stop ended
|
|
655
|
+
* its turn, or `onBeforeSend` took it over as it leaves), given back to the
|
|
656
|
+
* composer (the same, with what the user typed for it; told once the
|
|
657
|
+
* composer shows it, so `getDraft` reads it), or cancelled (by the user, or
|
|
658
|
+
* a new conversation). A message sent after a stopped turn ended goes out
|
|
659
|
+
* once that turn winds down. Messages held together settle together.
|
|
660
|
+
*/
|
|
661
|
+
onHeldSendSettled?: (text: string, outcome: ChatHeldOutcome) => void;
|
|
662
|
+
/**
|
|
663
|
+
* Called when a turn starts or stops running: on screen (the Stop button and
|
|
664
|
+
* the status line show), or a relayed turn let go of while the page was
|
|
665
|
+
* hidden; the state `ChatSendDraft.turnRunning` reports. True for the
|
|
666
|
+
* panel's own turn from its send, and for a turn the event stream relays;
|
|
667
|
+
* false once it ends - its stream closes after the last `done` (an
|
|
668
|
+
* intermediate one goes on), an `error`, `cancelled` or `session_expired`
|
|
669
|
+
* frame, a Stop, a new conversation - and when the panel unmounts during a
|
|
670
|
+
* turn. A relayed turn let go of with the event stream runs on until the
|
|
671
|
+
* reopened stream replays it, or the conversation read back says how it
|
|
672
|
+
* ended. Called on changes only, never with the value it last gave. With
|
|
673
|
+
* `false` comes how the turn ended (`info.ended`): answered, stopped or
|
|
674
|
+
* failed (see `ChatTurnOutcome`). After a provisional end (an `error` or
|
|
675
|
+
* `cancelled` whose stored end is still to come, from a backend whose turns
|
|
676
|
+
* outlive their stream) `false` comes at once, while the panel still holds
|
|
677
|
+
* sends as the turn winds down: until its stored end or its stream's close,
|
|
678
|
+
* at most 5 s.
|
|
679
|
+
*/
|
|
680
|
+
onTurnRunningChange?: (running: boolean, info?: ChatTurnEnd) => void;
|
|
681
|
+
/**
|
|
682
|
+
* Uploaded files may steer the running turn: the steer route takes
|
|
683
|
+
* `file_ids`. Without it, a message with files waits for the turn to end.
|
|
684
|
+
*/
|
|
685
|
+
steerAttachments?: boolean;
|
|
686
|
+
/**
|
|
687
|
+
* A message that cannot steer the running turn (files that cannot steer,
|
|
688
|
+
* references, mentions, fields of its own, a turn that just ended) is held
|
|
689
|
+
* and sent as the next turn once it ends,
|
|
690
|
+
* rather than waiting in the composer. A turn winding down after a
|
|
691
|
+
* provisional end (until its stored end or its stream's close, at most 5 s;
|
|
692
|
+
* see `onTurnRunningChange`) holds sends with or without it.
|
|
693
|
+
*/
|
|
694
|
+
holdSendsDuringTurn?: boolean;
|
|
695
|
+
/**
|
|
696
|
+
* `@` in the composer also mentions the agents of the agent list (above the
|
|
697
|
+
* conversations, when those are offered): the message carries the ids of
|
|
698
|
+
* the agents it still mentions as `mentioned_agent_ids`, in mention order.
|
|
699
|
+
* A message that mentions an agent never steers the running turn.
|
|
700
|
+
*/
|
|
701
|
+
agentMentions?: boolean;
|
|
702
|
+
/**
|
|
703
|
+
* Hides the conversation list that fullscreen and inline modes show beside
|
|
704
|
+
* the thread, for a panel too narrow for both (a rail, a task pane; the
|
|
705
|
+
* thread, header and composer hold at 320 px). The history stays: the
|
|
706
|
+
* header's history menu lists, opens and deletes conversations and offers
|
|
707
|
+
* Clear all, and a referenced conversation still opens in the panel. The
|
|
708
|
+
* `sidebar*` slots render nothing meanwhile. Default: false.
|
|
709
|
+
*/
|
|
710
|
+
hideConversationList?: boolean;
|
|
711
|
+
}
|
|
712
|
+
/** What a marker card is drawn from. */
|
|
713
|
+
interface ChatMarkerContext {
|
|
714
|
+
message: ChatMessage;
|
|
715
|
+
/** The answer is still streaming. */
|
|
716
|
+
streaming: boolean;
|
|
717
|
+
}
|
|
718
|
+
/** How one kind of `[[KIND:args]]` marker renders. */
|
|
719
|
+
interface ChatMarkerRenderer {
|
|
720
|
+
/** The card for one marker; *args* is everything after `KIND:`. */
|
|
721
|
+
render: (args: string, context: ChatMarkerContext) => React.ReactNode;
|
|
722
|
+
/** Show it while the answer streams; by default it shows once the answer is done. */
|
|
723
|
+
renderWhileStreaming?: boolean;
|
|
724
|
+
/** Give it the thread's full width rather than the prose's. */
|
|
725
|
+
fullWidth?: boolean;
|
|
726
|
+
}
|
|
727
|
+
/** What a code block renderer is drawn from. */
|
|
728
|
+
interface ChatCodeBlockContext {
|
|
729
|
+
/** The answer is still streaming: the block may not be complete yet. */
|
|
730
|
+
streaming: boolean;
|
|
731
|
+
}
|
|
732
|
+
/** Renders one fenced code block of a language (see `ChatPanelProps.codeBlockRenderers`); *code* is the block's text. `null` keeps the block as code. */
|
|
733
|
+
type ChatCodeBlockRenderer = (code: string, context: ChatCodeBlockContext) => React.ReactNode;
|
|
734
|
+
/** What a message slot (`renderMessageExtras`, `messageFooterActions`) is drawn with. */
|
|
735
|
+
interface ChatMessageSlotContext {
|
|
736
|
+
/** The message is the answer still being written. */
|
|
737
|
+
streaming: boolean;
|
|
738
|
+
}
|
|
739
|
+
/** Where a frame passed to `onStreamEvent` came from, and what the panel read in it. */
|
|
740
|
+
interface ChatStreamEventInfo {
|
|
741
|
+
/** True for a turn this panel did not start, relayed by the event stream. */
|
|
742
|
+
relayed: boolean;
|
|
743
|
+
/**
|
|
744
|
+
* The frame ends a turn: `'provisional'` for an `error` or `cancelled` marked
|
|
745
|
+
* `provisional: true` (its stored end follows), `'stored'` for
|
|
746
|
+
* an end carrying the stored answer's `message_id` (a `done` that is not
|
|
747
|
+
* intermediate, a `cancelled` or an `error`). Absent on any other frame.
|
|
748
|
+
*/
|
|
749
|
+
end?: 'provisional' | 'stored';
|
|
750
|
+
/** The frame acknowledges a turn replayed from its start (`thinking` with `resumed`). */
|
|
751
|
+
replayed?: boolean;
|
|
752
|
+
}
|
|
753
|
+
/** What a host can do to a mounted panel, through its `ref`. */
|
|
754
|
+
interface ChatPanelHandle {
|
|
755
|
+
/** Send *text* as the user, leaving the composer's own draft alone; resolves to what became of it. */
|
|
756
|
+
send: (text: string, options?: ChatSendOptions) => Promise<ChatSendOutcome>;
|
|
757
|
+
/** Start a new conversation, in a workspace and with an agent (id or slug) if given. */
|
|
758
|
+
newConversation: (options?: {
|
|
759
|
+
workspaceId?: string;
|
|
760
|
+
agent?: string;
|
|
761
|
+
}) => void;
|
|
762
|
+
selectConversation: (conversationId: string) => void;
|
|
763
|
+
/** Replace the composer's text. */
|
|
764
|
+
setDraft: (text: string) => void;
|
|
765
|
+
/**
|
|
766
|
+
* The composer's text as it stands (what the user typed, or `setDraft` set):
|
|
767
|
+
* e.g. for `onBeforeSend` taking over a held message (`draft.held`), to tell
|
|
768
|
+
* whether the composer still holds what was typed for it.
|
|
769
|
+
*/
|
|
770
|
+
getDraft: () => string;
|
|
771
|
+
focusComposer: () => void;
|
|
772
|
+
/** Same as the Stop button; also cancels the question a voice call awaits, and stops it speaking. */
|
|
773
|
+
stop: () => void;
|
|
774
|
+
/**
|
|
775
|
+
* Start a voice call over the panel: the browser listens, a phrase is sent
|
|
776
|
+
* after a second of silence (`onBeforeSend` sees `source: 'voice'`), and the
|
|
777
|
+
* answer is spoken through {@link ApiEndpoints.tts} (the browser's voice
|
|
778
|
+
* without it), until the user ends the call. Only the final answer of the
|
|
779
|
+
* turn that answers the question is spoken, and only the addressed agent's;
|
|
780
|
+
* the other agents' replies are shown by name. `false` when it cannot
|
|
781
|
+
* start: no speech recognition in this browser (`voiceCallSupported()`), or
|
|
782
|
+
* `readOnly`.
|
|
783
|
+
*/
|
|
784
|
+
startVoiceCall: () => boolean;
|
|
785
|
+
/** Read the agent list again, keeping the agent picked unless it is gone. */
|
|
786
|
+
reloadAgents: () => void;
|
|
787
|
+
/** Scroll to a message on screen (by its server id) and highlight it; false when it is not there. */
|
|
788
|
+
scrollToMessage: (messageId: string) => boolean;
|
|
789
|
+
}
|
|
790
|
+
/** A send about to leave, as `onBeforeSend` sees it. */
|
|
791
|
+
interface ChatSendDraft {
|
|
792
|
+
text: string;
|
|
793
|
+
/** Typed in the composer, sent through the handle, or spoken in a voice call. */
|
|
794
|
+
source: 'composer' | 'host' | 'voice';
|
|
795
|
+
/** A turn is running. */
|
|
796
|
+
turnRunning: boolean;
|
|
797
|
+
/**
|
|
798
|
+
* A message held while a turn ran, asked about again as it leaves, the turn
|
|
799
|
+
* over (`turnRunning: false`), each send held with it on its own. `false`
|
|
800
|
+
* then gives what the user typed for it (its text, files, references and
|
|
801
|
+
* mentions) back to the composer, after what they typed since. A held
|
|
802
|
+
* message every send of which is taken over is settled `'returned'` by
|
|
803
|
+
* `onHeldSendSettled`, or `'dropped'` when the user typed none of it (a
|
|
804
|
+
* host's or a voice call's).
|
|
805
|
+
*/
|
|
806
|
+
held?: boolean;
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* What became of a send: the backend took it as a new turn, it joined the
|
|
810
|
+
* running one, it waits for that turn to end (or for one ended provisionally
|
|
811
|
+
* to wind down, with or without `holdSendsDuringTurn`), it went nowhere, or
|
|
812
|
+
* the backend refused it.
|
|
813
|
+
*/
|
|
814
|
+
type ChatSendOutcome = 'sent' | 'steered' | 'held' | 'dropped' | 'failed';
|
|
815
|
+
/** What became of a held message once its turn ended (see `onHeldSendSettled`). */
|
|
816
|
+
type ChatHeldOutcome = 'sent' | 'failed' | 'dropped' | 'returned' | 'cancelled';
|
|
817
|
+
/**
|
|
818
|
+
* How a turn ended (see `onTurnRunningChange`):
|
|
819
|
+
* - `'answered'`: its last `done` came (not an intermediate one), and nothing
|
|
820
|
+
* after it said otherwise; for a relayed turn that ended out of sight (no
|
|
821
|
+
* replay, or an event stream that could not reopen), the conversation read
|
|
822
|
+
* back holds an answer stored after what was shown;
|
|
823
|
+
* - `'stopped'`: it ended short of its answer - a `cancelled` frame (even
|
|
824
|
+
* after the last `done`), a `session_expired` frame, Stop, a new
|
|
825
|
+
* conversation, the panel unmounting, a stream that closed before its last
|
|
826
|
+
* `done` with no event stream to carry the turn to its end, or a relayed
|
|
827
|
+
* turn that ended out of sight with no answer read back (none stored, or no
|
|
828
|
+
* read-back);
|
|
829
|
+
* - `'failed'`: an `error` frame, or a send the backend refused or could not
|
|
830
|
+
* be reached for, before the turn streamed anything.
|
|
831
|
+
*/
|
|
832
|
+
type ChatTurnOutcome = 'answered' | 'stopped' | 'failed';
|
|
833
|
+
/** What `onTurnRunningChange(false, info)` says of the turn that ended. */
|
|
834
|
+
interface ChatTurnEnd {
|
|
835
|
+
ended: ChatTurnOutcome;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* What `onBeforeSend` decides: `false` takes the send over, an object adjusts it.
|
|
839
|
+
* `text` is what the backend receives; `displayText` is what the user's bubble
|
|
840
|
+
* shows in its place (a prompt wrapped in the host's context, shown as typed).
|
|
841
|
+
* Without `displayText` the bubble shows the text sent. A conversation read
|
|
842
|
+
* back shows what the backend stored.
|
|
843
|
+
*/
|
|
844
|
+
type ChatSendDecision = false | {
|
|
845
|
+
text?: string;
|
|
846
|
+
displayText?: string;
|
|
847
|
+
extras?: Record<string, unknown>;
|
|
848
|
+
} | void;
|
|
849
|
+
/** Per-send options of {@link ChatPanelHandle.send}. */
|
|
850
|
+
interface ChatSendOptions {
|
|
851
|
+
/** Merged into that one message's request body (see `getRequestExtras`). */
|
|
852
|
+
extras?: Record<string, unknown>;
|
|
853
|
+
/**
|
|
854
|
+
* What the user's bubble shows in place of the text sent, as `onBeforeSend`'s
|
|
855
|
+
* `displayText` does (which wins when it gives one).
|
|
856
|
+
*/
|
|
857
|
+
displayText?: string;
|
|
467
858
|
}
|
|
468
859
|
interface ChatToggleButtonProps {
|
|
469
860
|
isOpen: boolean;
|
|
@@ -471,6 +862,8 @@ interface ChatToggleButtonProps {
|
|
|
471
862
|
/** Overrides the built-in label; already translated by the host. */
|
|
472
863
|
label?: string;
|
|
473
864
|
t?: Translate;
|
|
865
|
+
/** BCP 47 tag of the label's language when the host does not translate it (see `ChatPanelProps.locale`). */
|
|
866
|
+
locale?: string;
|
|
474
867
|
accentColor?: string;
|
|
475
868
|
icon?: React.ReactNode;
|
|
476
869
|
}
|
|
@@ -508,12 +901,25 @@ interface ChatMessage {
|
|
|
508
901
|
* back to the conversation's agent, then to the selected one.
|
|
509
902
|
*/
|
|
510
903
|
agentName?: string;
|
|
904
|
+
/**
|
|
905
|
+
* The agent that wrote this answer, as the backend names it (`answered_by`
|
|
906
|
+
* of its `done` frame or restored entry): on a turn several agents answer,
|
|
907
|
+
* each reply names its own. Absent when the backend does not say.
|
|
908
|
+
*/
|
|
909
|
+
answeredBy?: ChatAnsweredBy;
|
|
910
|
+
/**
|
|
911
|
+
* The answer is a note written in place of a mentioned agent that could not
|
|
912
|
+
* answer (`mention_failed`).
|
|
913
|
+
*/
|
|
914
|
+
mentionFailed?: boolean;
|
|
511
915
|
files?: ChatFile[];
|
|
512
916
|
/**
|
|
513
917
|
* The conversations a user message references with `@` (see
|
|
514
918
|
* {@link ApiEndpoints.conversationReferences}), shown as chips.
|
|
515
919
|
*/
|
|
516
920
|
conversationRefs?: ChatConversationRef[];
|
|
921
|
+
/** The turn was stopped while writing this answer. */
|
|
922
|
+
stopped?: boolean;
|
|
517
923
|
/** Agent-generated downloadable files attached to an assistant message. */
|
|
518
924
|
attachments?: ChatAttachment[];
|
|
519
925
|
/** The decks, reports and videos an assistant message made, in marker order. */
|
|
@@ -542,6 +948,21 @@ interface ChatMessage {
|
|
|
542
948
|
* reasoning-details affordance, mirroring the XTM One web chat.
|
|
543
949
|
*/
|
|
544
950
|
isTruncated?: boolean;
|
|
951
|
+
/**
|
|
952
|
+
* The backend's own fields for the message, as it sent them: the restored
|
|
953
|
+
* (or paged, or relayed) entry, or the `done` frame - or the stored end -
|
|
954
|
+
* that closed a live answer. A plain copy, whose fields are the backend's to
|
|
955
|
+
* define; the panel reads none of it. Absent on a message no backend object
|
|
956
|
+
* describes yet (one being written, a user message sent from this panel).
|
|
957
|
+
*/
|
|
958
|
+
raw?: Record<string, unknown>;
|
|
959
|
+
}
|
|
960
|
+
/** The agent an answer names as its author (`answered_by`); either field may be missing. */
|
|
961
|
+
interface ChatAnsweredBy {
|
|
962
|
+
agentId?: string;
|
|
963
|
+
agentName?: string;
|
|
964
|
+
/** An image URL or an emoji, as `XtmAgent.icon`. */
|
|
965
|
+
agentIcon?: string;
|
|
545
966
|
}
|
|
546
967
|
/** A rating as the feedback endpoint stores it. */
|
|
547
968
|
interface ChatMessagePersistedFeedback {
|
|
@@ -609,6 +1030,30 @@ interface ChatArtifact {
|
|
|
609
1030
|
/** The formats it downloads in: `pdf`, `pptx`, `pptx_native`, `mp4`. Empty until a video is rendered. */
|
|
610
1031
|
downloads: string[];
|
|
611
1032
|
}
|
|
1033
|
+
/** What the agent is doing, as the status line shows it. */
|
|
1034
|
+
interface AgentStatusState {
|
|
1035
|
+
status: string;
|
|
1036
|
+
tools?: string[];
|
|
1037
|
+
thinkingContent?: string;
|
|
1038
|
+
/**
|
|
1039
|
+
* Seconds the current tool batch has been executing (from periodic
|
|
1040
|
+
* `tool_heartbeat` events) — rendered as a live elapsed-time indicator
|
|
1041
|
+
* so long executions (background tasks, consults) never look stuck.
|
|
1042
|
+
*/
|
|
1043
|
+
elapsedS?: number;
|
|
1044
|
+
/**
|
|
1045
|
+
* Wall-clock instant (ms) at which the current tool batch started, derived
|
|
1046
|
+
* from `elapsedS` on each heartbeat. Heartbeats only arrive every ~10s, so
|
|
1047
|
+
* rendering `elapsedS` directly makes the timer sit still and then jump.
|
|
1048
|
+
* Anchoring here lets the indicator tick once a second locally and
|
|
1049
|
+
* re-synchronise on every beat.
|
|
1050
|
+
*/
|
|
1051
|
+
elapsedStartMs?: number;
|
|
1052
|
+
/** `wait_start`: how long the agent pauses, why, and since when (ms). */
|
|
1053
|
+
waitSeconds?: number;
|
|
1054
|
+
waitReason?: string;
|
|
1055
|
+
waitStartMs?: number;
|
|
1056
|
+
}
|
|
612
1057
|
interface ChatFile {
|
|
613
1058
|
name: string;
|
|
614
1059
|
type: string;
|
|
@@ -680,11 +1125,19 @@ interface XtmAgent {
|
|
|
680
1125
|
id: string;
|
|
681
1126
|
name: string;
|
|
682
1127
|
slug: string | null;
|
|
1128
|
+
/** An image URL or an emoji; anything else shows the panel's logo. */
|
|
683
1129
|
icon: string | null;
|
|
684
1130
|
description: string | null;
|
|
1131
|
+
/** The heading the agent picker lists it under; ungrouped agents come first. */
|
|
1132
|
+
group?: string;
|
|
685
1133
|
}
|
|
686
1134
|
|
|
687
|
-
|
|
1135
|
+
/**
|
|
1136
|
+
* The panel, its requests reporting the end of the user's session
|
|
1137
|
+
* (`onSessionEnded`): once per set of `requestHeaders`, whichever request or
|
|
1138
|
+
* stream said it first.
|
|
1139
|
+
*/
|
|
1140
|
+
declare const ChatPanel: react.ForwardRefExoticComponent<ChatPanelProps & react.RefAttributes<ChatPanelHandle>>;
|
|
688
1141
|
|
|
689
1142
|
declare const ChatToggleButton: FunctionComponent<ChatToggleButtonProps>;
|
|
690
1143
|
|
|
@@ -693,5 +1146,8 @@ interface TransferredAgent {
|
|
|
693
1146
|
name: string;
|
|
694
1147
|
}
|
|
695
1148
|
|
|
696
|
-
|
|
697
|
-
|
|
1149
|
+
/** Whether this browser can hold a voice call: it needs speech recognition. */
|
|
1150
|
+
declare const voiceCallSupported: () => boolean;
|
|
1151
|
+
|
|
1152
|
+
export { ChatPanel, ChatToggleButton, voiceCallSupported };
|
|
1153
|
+
export type { AgentStatusState, ApiEndpoints, BackendType, ChatAnsweredBy, ChatArtifact, ChatArtifactKind, ChatAttachment, ChatCodeBlockContext, ChatCodeBlockRenderer, ChatContextBreakdown, ChatContextUsage, ChatConversationRef, ChatConversationReferenceCandidate, ChatConversationSummary, ChatFile, ChatHeldOutcome, ChatMarkerContext, ChatMarkerRenderer, ChatMessage, ChatMessagePersistedFeedback, ChatMessageSlotContext, ChatMode, ChatPanelHandle, ChatPanelMode, ChatPanelProps, ChatPromptTemplate, ChatQuotaStatus, ChatSendDecision, ChatSendDraft, ChatSendOptions, ChatSendOutcome, ChatStreamEventInfo, ChatToggleButtonProps, ChatTurnEnd, ChatTurnOutcome, ChatWorkspace, MessageFeedback, ToolApprovalDecision, ToolApprovalProposal, ToolApprovalVerdict, TransferredAgent, Translate, XtmAgent };
|