@filigran/chatbot 3.9.0 → 3.10.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/README.md +220 -46
- package/dist/index.d.ts +27 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/markdown.js +1 -1
- package/dist/markdown.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -71,7 +71,9 @@ import { ChatPanel } from '@filigran/chatbot';
|
|
|
71
71
|
| `apiBaseUrl` | `string` | **required** | Base URL for chat API endpoints |
|
|
72
72
|
| `user` | `{ firstName: string }` | **required** | Current user info |
|
|
73
73
|
| `topOffset` | `number` | `0` | Top offset in pixels (for sidebar/fullscreen with fixed headers) |
|
|
74
|
-
| `agentDashboardUrl` | `string` | — | URL for "Browse agents" / "Create agent" links
|
|
74
|
+
| `agentDashboardUrl` | `string` | — | XTM One URL for the "Browse agents" / "Create agent" links and the waiting panel's "Play Space Invaders in XTM One" link (`{url}/chat?arcade=play`, http(s) only) |
|
|
75
|
+
| `miniGameEnabled` | `boolean` | `true` | Show the waiting panel during longer waits: rotating messages and the invitation to play XTM One's arcade (the package ships no game of its own) |
|
|
76
|
+
| `onPlayWaitingGame` | `() => void` | — | Open the arcade in place instead of linking to XTM One, for a host that runs it itself (the XTM One floating assistant) |
|
|
75
77
|
| `t` | `(key: string) => string` | identity | Translation function for i18n |
|
|
76
78
|
| `accentColor` | `string` | `'#7b5cff'` | Primary accent color (hex) |
|
|
77
79
|
| `logoIcon` | `React.ReactNode` | default icon | Custom logo/icon for the assistant |
|
|
@@ -121,13 +123,14 @@ import { ChatToggleButton } from '@filigran/chatbot';
|
|
|
121
123
|
|
|
122
124
|
#### Props
|
|
123
125
|
|
|
124
|
-
| Prop | Type
|
|
125
|
-
| ------------- |
|
|
126
|
-
| `isOpen` | `boolean`
|
|
127
|
-
| `onToggle` | `() => void`
|
|
128
|
-
| `label` | `string`
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
126
|
+
| Prop | Type | Default | Description |
|
|
127
|
+
| ------------- | ------------------------- | ------------ | -------------------------------------------------------------------------- |
|
|
128
|
+
| `isOpen` | `boolean` | **required** | Whether the chat panel is open |
|
|
129
|
+
| `onToggle` | `() => void` | **required** | Called when button is clicked |
|
|
130
|
+
| `label` | `string` | built-in | Button text, already translated by the host; omit for `t('Ask Assistant')` |
|
|
131
|
+
| `t` | `(key: string) => string` | identity | Translation function, used for the default label |
|
|
132
|
+
| `accentColor` | `string` | `'#7b5cff'` | Button background color |
|
|
133
|
+
| `icon` | `React.ReactNode` | default icon | Custom icon |
|
|
131
134
|
|
|
132
135
|
## API Contract
|
|
133
136
|
|
|
@@ -571,59 +574,230 @@ function App() {
|
|
|
571
574
|
}
|
|
572
575
|
```
|
|
573
576
|
|
|
574
|
-
|
|
577
|
+
`t` is only ever asked for a lookup — key in, translated string out — so any
|
|
578
|
+
i18n library works and the package never carries a dictionary of its own.
|
|
579
|
+
Untranslated hosts can omit it: the default is the identity function, so every
|
|
580
|
+
key is its own English text.
|
|
575
581
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
582
|
+
#### Values inside sentences
|
|
583
|
+
|
|
584
|
+
A key is always a **whole sentence**, with `{placeholder}` slots for the values.
|
|
585
|
+
The panel fills the slots in _after_ the lookup, so a locale is free to move the
|
|
586
|
+
value, and a translator sees the sentence rather than a fragment of one:
|
|
587
|
+
|
|
588
|
+
| Key | Renders as |
|
|
589
|
+
| --- | --- |
|
|
590
|
+
| `'Waiting for {count} background tasks…'` | Waiting for 3 background tasks… |
|
|
591
|
+
| `'Transferred from {agent}'` | Transferred from Threat Analyst |
|
|
592
|
+
| `'{percent}% full'` | 84% full |
|
|
593
|
+
| `'How can {agent} help you, {name}?'` | How can **Threat Analyst** help you, John? |
|
|
594
|
+
|
|
595
|
+
Two consequences worth knowing when writing the locale files:
|
|
596
|
+
|
|
597
|
+
- **Plurals are separate keys** — `'1 tool call'` and `'{count} tool calls'`,
|
|
598
|
+
`'Delegating one task…'` and `'Delegating {count} tasks…'`. A lookup cannot
|
|
599
|
+
select a plural form, so the panel picks the sentence and the locale
|
|
600
|
+
translates it whole; a language with more plural forms than English can route
|
|
601
|
+
the plural key through its own rules.
|
|
602
|
+
- **A missing slot is not fatal** — a translation that drops a `{placeholder}`
|
|
603
|
+
renders the rest of the sentence as it is, and the value is simply absent.
|
|
604
|
+
That includes the greeting, where the agent's name is markup: a locale that
|
|
605
|
+
rewords the sentence without `{agent}` gets the sentence, not a name dangling
|
|
606
|
+
off the end of it.
|
|
607
|
+
|
|
608
|
+
`promptSuggestions` (and any suggestions the backend serves) also go through
|
|
609
|
+
`t`, so a host may pass either keys or final text.
|
|
610
|
+
|
|
611
|
+
#### Translation keys used
|
|
612
|
+
|
|
613
|
+
Every key the package can ask for, grouped by where it appears:
|
|
614
|
+
|
|
615
|
+
**Toggle button**
|
|
616
|
+
|
|
617
|
+
- `'Ask Assistant'`
|
|
618
|
+
|
|
619
|
+
**Header, agent menu and history**
|
|
620
|
+
|
|
621
|
+
- `'Agent switching is not available here'`
|
|
622
|
+
- `'Browse agents'`
|
|
623
|
+
- `'Close'`
|
|
587
624
|
- `'Conversation history'`
|
|
588
|
-
- `'
|
|
589
|
-
- `'
|
|
590
|
-
- `'New conversation'`
|
|
625
|
+
- `'Could not reach the assistant service. Check the connection and try again.'`
|
|
626
|
+
- `'Create agent'`
|
|
591
627
|
- `'Delete conversation'`
|
|
592
|
-
- `'
|
|
593
|
-
- `'
|
|
594
|
-
- `'
|
|
628
|
+
- `'Floating'`
|
|
629
|
+
- `'Full screen'`
|
|
630
|
+
- `'New chat'`
|
|
631
|
+
- `'New conversation'`
|
|
632
|
+
- `'No agent matches'`
|
|
633
|
+
- `'No conversations yet'`
|
|
634
|
+
- `'Search agents...'`
|
|
635
|
+
- `'Sidebar'`
|
|
636
|
+
- `'Switch to'`
|
|
595
637
|
- `'Switch to another agent'`
|
|
596
|
-
- `'
|
|
597
|
-
- `'
|
|
638
|
+
- `'Switch view'`
|
|
639
|
+
- `'Transferred from {agent}'`
|
|
640
|
+
- `'Untitled conversation'`
|
|
641
|
+
|
|
642
|
+
**Conversation sidebar**
|
|
643
|
+
|
|
644
|
+
- `'Conversation title'`
|
|
645
|
+
- `'Hide conversations'`
|
|
646
|
+
- `'No conversation matches'`
|
|
647
|
+
- `'Rename conversation'`
|
|
648
|
+
- `'Search conversations...'`
|
|
649
|
+
- `'Show conversations'`
|
|
650
|
+
|
|
651
|
+
**Welcome screen**
|
|
652
|
+
|
|
653
|
+
- `'Assistant'`
|
|
654
|
+
- `'Help me create a new simulation scenario'`
|
|
655
|
+
- `'How can I help you, {name}?'`
|
|
656
|
+
- `'How can {agent} help you, {name}?'`
|
|
657
|
+
- `'How do I configure detection rules?'`
|
|
658
|
+
- `'Suggestions'`
|
|
659
|
+
- `'Summarize my recent findings'`
|
|
660
|
+
- `'What are the latest attack patterns?'`
|
|
661
|
+
|
|
662
|
+
**Composer**
|
|
663
|
+
|
|
664
|
+
- `'Ask a question...'`
|
|
665
|
+
- `'Attachments wait for the current response'`
|
|
666
|
+
- `'Dictate a message'`
|
|
667
|
+
- `'Enter to send now · Esc to stop'`
|
|
668
|
+
- `'Files uploading...'`
|
|
669
|
+
- `'Insert prompt template'`
|
|
670
|
+
- `'No prompt matches'`
|
|
671
|
+
- `'Search prompts...'`
|
|
672
|
+
- `'Send now'`
|
|
673
|
+
- `'Stop dictation'`
|
|
674
|
+
- `'Stop generating'`
|
|
675
|
+
- `'Uses AI. Verify results.'`
|
|
676
|
+
|
|
677
|
+
**Messages, markdown and files**
|
|
678
|
+
|
|
679
|
+
- `'Bad response'`
|
|
680
|
+
- `'Copied'`
|
|
681
|
+
- `'Copied!'`
|
|
682
|
+
- `'Copy code'`
|
|
683
|
+
- `'Copy response'`
|
|
684
|
+
- `'Download'`
|
|
685
|
+
- `'Expand image'`
|
|
686
|
+
- `'Good response'`
|
|
687
|
+
- `'Image could not be loaded'`
|
|
688
|
+
- `'Image preview'`
|
|
689
|
+
- `'Load earlier messages'`
|
|
690
|
+
- `'Loading image…'`
|
|
598
691
|
- `'Reasoning details'`
|
|
599
692
|
- `'Reasoning details — turn limit reached'`
|
|
693
|
+
|
|
694
|
+
**Agent status**
|
|
695
|
+
|
|
696
|
+
- `'Analyzing results…'`
|
|
697
|
+
- `'Collecting results from one task…'`
|
|
698
|
+
- `'Collecting results from {count} tasks…'`
|
|
699
|
+
- `'Composing answer…'`
|
|
700
|
+
- `'Consulting {agent}…'`
|
|
701
|
+
- `'Delegating one task…'`
|
|
702
|
+
- `'Delegating {count} tasks…'`
|
|
703
|
+
- `'Incorporating your message…'`
|
|
704
|
+
- `'Thinking...'`
|
|
705
|
+
- `'Transferring to {agent}…'`
|
|
706
|
+
- `'Using tools…'`
|
|
707
|
+
- `'Waiting for one background task…'`
|
|
708
|
+
- `'Waiting for your approval…'`
|
|
709
|
+
- `'Waiting for {count} background tasks…'`
|
|
710
|
+
- `'the agent'`
|
|
711
|
+
- `'{tool} (+{count} more)…'`
|
|
712
|
+
|
|
713
|
+
**Waiting panel**
|
|
714
|
+
|
|
715
|
+
- `'Almost there'`
|
|
716
|
+
- `'Analyzing the details'`
|
|
717
|
+
- `'Connecting the dots'`
|
|
718
|
+
- `'Consulting the sources'`
|
|
719
|
+
- `'Crunching the data'`
|
|
720
|
+
- `'Play Space Invaders'`
|
|
721
|
+
- `'Play Space Invaders in XTM One'`
|
|
722
|
+
- `'Polishing the answer'`
|
|
723
|
+
- `'Putting it together'`
|
|
724
|
+
- `'Reticulating splines'`
|
|
725
|
+
- `'Thinking it through'`
|
|
726
|
+
- `'Wrapping things up'`
|
|
727
|
+
|
|
728
|
+
**Reasoning details**
|
|
729
|
+
|
|
730
|
+
- `'(no output)'`
|
|
731
|
+
- `'1 tool call'`
|
|
732
|
+
- `'1 transfer'`
|
|
733
|
+
- `'Input'`
|
|
600
734
|
- `'Model reasoning'`
|
|
601
|
-
- `'
|
|
602
|
-
- `'
|
|
735
|
+
- `'Output'`
|
|
736
|
+
- `"The agent's iteration budget was exhausted - execution stopped before completing all planned steps. The final response is a best-effort summary of work done so far."`
|
|
603
737
|
- `'Transfer chain'`
|
|
604
738
|
- `'Turn limit reached.'`
|
|
605
|
-
- `
|
|
606
|
-
- `'
|
|
607
|
-
- `'
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
- `'
|
|
612
|
-
- `'
|
|
613
|
-
- `'
|
|
614
|
-
- `'
|
|
615
|
-
- `'
|
|
739
|
+
- `'{count} iterations'`
|
|
740
|
+
- `'{count} tool calls'`
|
|
741
|
+
- `'{count} transfers'`
|
|
742
|
+
|
|
743
|
+
**Tool approval**
|
|
744
|
+
|
|
745
|
+
- `'Also applies to your scheduled runs, until you revoke it'`
|
|
746
|
+
- `'Always allowed'`
|
|
747
|
+
- `'Approved'`
|
|
748
|
+
- `'Back'`
|
|
749
|
+
- `'Confirm'`
|
|
616
750
|
- `'Decline this call'`
|
|
751
|
+
- `'Declined'`
|
|
752
|
+
- `'No'`
|
|
753
|
+
- `'Sending…'`
|
|
754
|
+
- `'The agent needs your approval to run a tool:'`
|
|
755
|
+
- `'The agent needs your approval to run these tools:'`
|
|
617
756
|
- `'Why not? The agent sees this and can adapt (optional)'`
|
|
757
|
+
- `'Yes'`
|
|
758
|
+
- `'Yes, always'`
|
|
618
759
|
- `'e.g. wrong environment — use staging instead'`
|
|
619
|
-
- `'
|
|
760
|
+
- `'unknown tool'`
|
|
761
|
+
- `'{decided}/{total} decided'`
|
|
620
762
|
- `'“Yes, always” saves a preference for you. That tool will then run without asking — including on scheduled runs nobody is watching — until you revoke it.'`
|
|
621
|
-
|
|
763
|
+
|
|
764
|
+
**Context gauge**
|
|
765
|
+
|
|
766
|
+
- `'Context full — older turns are being dropped'`
|
|
767
|
+
- `'Context nearly full — older turns are being summarized'`
|
|
768
|
+
- `'Context used'`
|
|
769
|
+
- `'Conversation'`
|
|
770
|
+
- `'MCP & dynamic tools'`
|
|
771
|
+
- `'Summarized conversation'`
|
|
772
|
+
- `'System prompt'`
|
|
773
|
+
- `'Tool definitions'`
|
|
774
|
+
- `'Tool results'`
|
|
775
|
+
- `'{counts} tokens'`
|
|
776
|
+
- `'{percent}% full'`
|
|
777
|
+
- `'{summary} — click for details'`
|
|
778
|
+
|
|
779
|
+
**Quota**
|
|
780
|
+
|
|
781
|
+
- `'Quota'`
|
|
782
|
+
- `'Quota reached'`
|
|
783
|
+
- `'Usage'`
|
|
784
|
+
- `'Usage · {period}'`
|
|
785
|
+
|
|
786
|
+
**Notices, errors and timestamps**
|
|
787
|
+
|
|
622
788
|
- `'Could not send your decision. Please try again.'`
|
|
789
|
+
- `'No response.'`
|
|
790
|
+
- `'Response ready'`
|
|
791
|
+
- `'Sorry, an error occurred. Please try again.'`
|
|
623
792
|
- `'This decision could not be sent. Reload the chat and try again.'`
|
|
624
|
-
- `'
|
|
625
|
-
- `'
|
|
626
|
-
- `'
|
|
793
|
+
- `'This turn is no longer waiting for a decision.'`
|
|
794
|
+
- `'Unable to connect. Please check the configuration.'`
|
|
795
|
+
- `'Your answer is ready'`
|
|
796
|
+
- `'just now'`
|
|
797
|
+
- `'{agent} has finished'`
|
|
798
|
+
- `'{count}d ago'`
|
|
799
|
+
- `'{count}h ago'`
|
|
800
|
+
- `'{count}m ago'`
|
|
627
801
|
|
|
628
802
|
## Styling
|
|
629
803
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { FunctionComponent } from 'react';
|
|
2
2
|
|
|
3
3
|
type ChatMode = 'sidebar' | 'floating' | 'fullscreen';
|
|
4
|
+
/**
|
|
5
|
+
* The host's translation lookup, passed down to every component that renders
|
|
6
|
+
* text. Key in, translated string out — the package never owns a dictionary of
|
|
7
|
+
* its own, and never asks the host's `t` for more than a lookup: values are
|
|
8
|
+
* spliced into the *translated* sentence by `translate()` in `utils`, so a key
|
|
9
|
+
* is always a whole sentence and a locale stays free to reorder it.
|
|
10
|
+
*/
|
|
11
|
+
type Translate = (key: string) => string;
|
|
4
12
|
type BackendType = 'legacy' | 'rest' | 'ag-ui';
|
|
5
13
|
/** A user's rating of one assistant answer. */
|
|
6
14
|
type MessageFeedback = 'up' | 'down';
|
|
@@ -156,6 +164,7 @@ interface ToolApprovalProposal {
|
|
|
156
164
|
* different arguments.
|
|
157
165
|
*/
|
|
158
166
|
toolCallId: string;
|
|
167
|
+
/** Empty when the backend named no tool; the UI labels that case itself. */
|
|
159
168
|
toolName: string;
|
|
160
169
|
toolDescription?: string;
|
|
161
170
|
arguments: Record<string, unknown>;
|
|
@@ -236,11 +245,16 @@ interface ChatPanelProps {
|
|
|
236
245
|
apiBaseUrl: string;
|
|
237
246
|
/** Custom API endpoint configuration. */
|
|
238
247
|
apiEndpoints?: ApiEndpoints;
|
|
248
|
+
/**
|
|
249
|
+
* The XTM One URL: the header's "Browse agents" / "Create agent" links, and
|
|
250
|
+
* the waiting panel's invitation to play the arcade there
|
|
251
|
+
* (`{agentDashboardUrl}/chat?arcade=play`). Only an http(s) URL is linked.
|
|
252
|
+
*/
|
|
239
253
|
agentDashboardUrl?: string;
|
|
240
254
|
user: {
|
|
241
255
|
firstName: string;
|
|
242
256
|
};
|
|
243
|
-
t?:
|
|
257
|
+
t?: Translate;
|
|
244
258
|
accentColor?: string;
|
|
245
259
|
logoIcon?: React.ReactNode;
|
|
246
260
|
promptSuggestions?: string[];
|
|
@@ -305,12 +319,17 @@ interface ChatPanelProps {
|
|
|
305
319
|
*/
|
|
306
320
|
backendType?: BackendType;
|
|
307
321
|
/**
|
|
308
|
-
* Show the waiting
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
322
|
+
* Show the waiting panel during longer waits: rotating status messages and
|
|
323
|
+
* an invitation to play XTM One's Space Invaders arcade, in a new tab
|
|
324
|
+
* through `agentDashboardUrl` or in place through `onPlayWaitingGame`. The
|
|
325
|
+
* package ships no game of its own. Host-level master switch. Default: true.
|
|
312
326
|
*/
|
|
313
327
|
miniGameEnabled?: boolean;
|
|
328
|
+
/**
|
|
329
|
+
* Opens the arcade in place instead of linking to XTM One, for a host that
|
|
330
|
+
* runs it itself (the XTM One floating assistant). Wins over the link.
|
|
331
|
+
*/
|
|
332
|
+
onPlayWaitingGame?: () => void;
|
|
314
333
|
/**
|
|
315
334
|
* Notify the user when a long-running turn finishes while they are not
|
|
316
335
|
* watching the chat — away (tab hidden / another window) via a document-title
|
|
@@ -365,7 +384,9 @@ interface ChatPanelProps {
|
|
|
365
384
|
interface ChatToggleButtonProps {
|
|
366
385
|
isOpen: boolean;
|
|
367
386
|
onToggle: () => void;
|
|
387
|
+
/** Overrides the built-in label; already translated by the host. */
|
|
368
388
|
label?: string;
|
|
389
|
+
t?: Translate;
|
|
369
390
|
accentColor?: string;
|
|
370
391
|
icon?: React.ReactNode;
|
|
371
392
|
}
|
|
@@ -495,4 +516,4 @@ interface TransferredAgent {
|
|
|
495
516
|
}
|
|
496
517
|
|
|
497
518
|
export { ChatPanel, ChatToggleButton };
|
|
498
|
-
export type { ApiEndpoints, BackendType, ChatAttachment, ChatContextBreakdown, ChatContextUsage, ChatConversationSummary, ChatFile, ChatMessage, ChatMode, ChatPanelProps, ChatPromptTemplate, ChatQuotaStatus, ChatToggleButtonProps, MessageFeedback, ToolApprovalDecision, ToolApprovalProposal, ToolApprovalVerdict, TransferredAgent, XtmAgent };
|
|
519
|
+
export type { ApiEndpoints, BackendType, ChatAttachment, ChatContextBreakdown, ChatContextUsage, ChatConversationSummary, ChatFile, ChatMessage, ChatMode, ChatPanelProps, ChatPromptTemplate, ChatQuotaStatus, ChatToggleButtonProps, MessageFeedback, ToolApprovalDecision, ToolApprovalProposal, ToolApprovalVerdict, TransferredAgent, Translate, XtmAgent };
|