@filigran/chatbot 3.19.0 → 3.19.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/CHANGELOG.md CHANGED
@@ -8,6 +8,32 @@ the versions follow [semantic versioning](https://semver.org/spec/v2.0.0.html).
8
8
  This file starts at 3.10.0; earlier releases are on the
9
9
  [releases page](https://github.com/FiligranHQ/filigran-ui/releases).
10
10
 
11
+ ## 3.19.1 — unreleased
12
+
13
+ ### Added
14
+
15
+ - The panel speaks German, Italian, Korean, Russian and Simplified Chinese on
16
+ its own: a catalog for each, picked from `locale` by its language whatever
17
+ the region (`de-de`, `it-it`, `ko-kr`, `ru-ru`, `zh-cn`). Those languages
18
+ showed in English unless the host translated every key through `t`.
19
+ Traditional Chinese tags (`zh-TW`, `zh-HK`, `zh-Hant`) keep falling back.
20
+
21
+ ### Fixed
22
+
23
+ - A refusal whose body has no `detail` shows its `error` when that is a
24
+ sentence, as the products' proxies answer (`{ "error": "..." }`, beside a
25
+ `status` or not), never a code (`invalid_token`, `Unauthorized`) nor a
26
+ status's reason phrase (`Not Found`, `Too Many Requests`). It shows above
27
+ the composer, in place of the answer, on a failed upload's chip, under the
28
+ conversation list and on a conversation that could not be loaded. The panel
29
+ showed its generic message instead.
30
+ - The status line has its own wording when it has no agent's name (`The agent
31
+ is answering…`, `Consulting an agent…`, `Transferring to another agent…`),
32
+ where it filled the name with a lowercase `the agent`: `the agent is
33
+ answering…` started without a capital. A host translating through `t` in a
34
+ language the panel has no catalog for translates these three keys; it
35
+ translated `the agent` before, and shows them in English until it does.
36
+
11
37
  ## 3.19.0 — unreleased
12
38
 
13
39
  ### Added
package/README.md CHANGED
@@ -520,8 +520,8 @@ conversation. If the endpoint responds with a non-2xx status, the component
520
520
  silently resets the stored id and starts fresh on the next message, except
521
521
  when it says nothing of the conversation: a `502`, `503` or `504` (or no
522
522
  answer at all) keeps the id and reads it back once the backend answers, and a
523
- `401` or `403` (expired credentials) keeps it, shows the response's `detail`
524
- (or "This conversation could not be loaded.") with a Retry button, and reads
523
+ `401` or `403` (expired credentials) keeps it, shows the response's
524
+ [reason](#a-refusals-reason) (or "This conversation could not be loaded.") with a Retry button, and reads
525
525
  it back as soon as `requestHeaders` change.
526
526
 
527
527
  Assistant history messages **should echo the same `attachments[]` array** that
@@ -583,7 +583,7 @@ the row reverts to its previous title.
583
583
 
584
584
  With [workspaces](#workspaces) on, the same route files a conversation:
585
585
  `{ "workspace_id": "uuid" }`, or `{ "workspace_id": null }` to take it out of
586
- its workspace. A refusal's `detail` is shown under the list.
586
+ its workspace. A refusal's [reason](#a-refusals-reason) is shown under the list.
587
587
 
588
588
  ### Workspaces
589
589
 
@@ -659,6 +659,17 @@ Deletes a conversation from the history menu. Any 2xx response counts as
659
659
  success; deleting the active conversation resets the panel to a fresh chat so
660
660
  the next message never targets a dead conversation id.
661
661
 
662
+ ### A refusal's reason
663
+
664
+ Where the panel shows why the backend refused a request, it reads the JSON body
665
+ of the non-2xx answer: its `detail` when a string, or the `message` (or
666
+ `detail`) of a `detail` object, as XTM One answers; else its `error` when that
667
+ is a sentence, as the products' proxies answer (`{ "error": "..." }`, beside a
668
+ `status` or not). A code (`invalid_token`, `Unauthorized`), a status's reason
669
+ phrase (`Not Found`, `Too Many Requests`), anything else in the body (a
670
+ top-level `message` included), a string over 500 characters or a body that is
671
+ not JSON shows the panel's own, translated message.
672
+
662
673
  ### `POST {apiBaseUrl}/chat/messages`
663
674
 
664
675
  Sends a message and streams the response via SSE.
@@ -686,7 +697,7 @@ It must be JSON-serializable — a non-serializable value (circular reference,
686
697
 
687
698
  A refusal before the stream (a non-2xx answer: a rate limit, a refused
688
699
  option, an unknown conversation) shows the response's `detail` in place of the
689
- answer - a string, or the `message` (or `detail`) of an object - and
700
+ answer ([its reason](#a-refusals-reason)), and
690
701
  "Unable to connect. Please check the configuration." when it has none; the
691
702
  handle's `send` resolves `'failed'`.
692
703
 
@@ -820,7 +831,7 @@ until the next send. On a non-2xx
820
831
  response or a network error nothing was stored: the optimistic user bubble is
821
832
  rolled back, the text is restored into the composer (prepended on its own line
822
833
  if the user already typed something new), the send resolves `'failed'` and the
823
- refusal's `detail`, when there is one, shows above the composer — so a backend
834
+ refusal's [reason](#a-refusals-reason), when there is one, shows above the composer — so a backend
824
835
  without steering support degrades gracefully and the message is never silently
825
836
  lost. A `409` means no turn is running any more, an ordinary race: no notice
826
837
  shows, and with `holdSendsDuringTurn` the message is held and sent as the next
@@ -836,7 +847,7 @@ mentions or body fields of its own (`send`'s `extras`, `onBeforeSend`'s
836
847
  for the turn to end (`holdSendsDuringTurn`), and `onBeforeSend` is asked again,
837
848
  with `turnRunning: false`, before it goes out. A file that failed to upload
838
849
  neither steers nor waits, nor goes without that file: its chip says why (the
839
- upload's `detail`), and the composer offers no send, and says why, until the
850
+ upload's [reason](#a-refusals-reason)), and the composer offers no send, and says why, until the
840
851
  user removes it. `send` and a voice
841
852
  call attach no files, so this never holds them. Esc stops generating.
842
853
 
@@ -1044,7 +1055,7 @@ chat) opts into six more routes, none with a default:
1044
1055
 
1045
1056
  | `apiEndpoints` key | Request | What it does |
1046
1057
  | --- | --- | --- |
1047
- | `cancel` | `POST {cancel}` with `{ conversation_id }` | Stop asks the backend to end the turn; the panel keeps reading until the stream's `cancelled` frame (or lets go after 10 s, or at once on a network error or an answer of `{ "turn": "none" }`, reading the conversation back for an end it had not read yet). A Stop pressed before the panel's own send started its turn (its stream delivered nothing yet) carries `"awaiting_send": true`, and its `none` says nothing of that turn: the Stop stays pending and is sent again, without the flag, as the turn starts (or as the answer comes, the turn started meanwhile); any other answer reached a turn, and nothing goes again. A backend may keep a Stop with that flag for the send's turn, and must then take a second cancel of one turn; a Stop without it says nothing of a later send. A refusal (non-2xx) keeps the turn running and shows its `detail` above the composer |
1058
+ | `cancel` | `POST {cancel}` with `{ conversation_id }` | Stop asks the backend to end the turn; the panel keeps reading until the stream's `cancelled` frame (or lets go after 10 s, or at once on a network error or an answer of `{ "turn": "none" }`, reading the conversation back for an end it had not read yet). A Stop pressed before the panel's own send started its turn (its stream delivered nothing yet) carries `"awaiting_send": true`, and its `none` says nothing of that turn: the Stop stays pending and is sent again, without the flag, as the turn starts (or as the answer comes, the turn started meanwhile); any other answer reached a turn, and nothing goes again. A backend may keep a Stop with that flag for the send's turn, and must then take a second cancel of one turn; a Stop without it says nothing of a later send. A refusal (non-2xx) keeps the turn running and shows its [reason](#a-refusals-reason) above the composer |
1048
1059
  | `skipWait` | `POST {skipWait}` with `{ conversation_id }` | `Continue now` on `status: wait_start` (`{ seconds, reason }`), for as long as the pause lasts (see the status values) |
1049
1060
  | `events` | `GET {events}/{conversation_id}/events?client_id=<id>` → SSE | Turns this panel did not start (another tab, a reload mid-turn), `user_message`, `conversation_title`, `approval_resolved`; every frame of a turn names it (`turn_id`, below) |
1050
1061
  | `messagesPage` | `GET {messagesPage}/{conversation_id}/messages?before=<message id>&limit=50&supports_artifacts=true` → `{ messages, has_more }` | "Load earlier messages" past the restored ones, offered when the restore answers `has_more: true` |
@@ -1290,9 +1301,12 @@ both. The same variables may be set in CSS on an ancestor instead.
1290
1301
 
1291
1302
  ### Internationalization
1292
1303
 
1293
- The panel speaks English, French, Spanish and Japanese on its own: it ships a
1294
- catalog for each and picks one from `locale` (`fr-FR` reads French; English, or
1295
- a language it lacks, is its own keys). A host in another language translates
1304
+ The panel speaks English, French, German, Italian, Spanish, Japanese, Korean,
1305
+ Russian and Simplified Chinese on its own: it ships a catalog for each and
1306
+ picks one from `locale` by its language, whatever the region (`fr-FR` reads
1307
+ French, `zh-cn` Chinese; English, or a language it lacks, is its own keys).
1308
+ Traditional Chinese (`zh-TW`, `zh-HK`, `zh-Hant`) has no catalog: it reads
1309
+ English unless the host translates it through `t`. A host in another language translates
1296
1310
  through `t`. A host with nothing to add only passes `locale`:
1297
1311
 
1298
1312
  ```tsx
package/dist/index.d.ts CHANGED
@@ -570,7 +570,7 @@ interface ChatPanelProps {
570
570
  onMessageFeedback?: (messageId: string, feedback: MessageFeedback | null, message: ChatMessage) => void;
571
571
  /**
572
572
  * The user's language as a BCP 47 tag (`'fr'`, `'en-US'`): the language the
573
- * panel speaks (its own catalog: en, es, fr, ja) where `t` does not
573
+ * panel speaks (its own catalog: en, de, es, fr, it, ja, ko, ru, zh-Hans) where `t` does not
574
574
  * translate a key, formats the time under each message and is the language
575
575
  * answers are read aloud in. Default: the browser's own, except that a host
576
576
  * passing `t` and no `locale` gets no catalog.
@@ -1264,7 +1264,7 @@ interface ChatFile {
1264
1264
  fileId?: string;
1265
1265
  /** Upload status: 'pending' while uploading, 'done' when uploaded, 'error' on failure. */
1266
1266
  uploadStatus?: 'pending' | 'done' | 'error';
1267
- /** Why the upload failed, as the backend said (`detail`), when it said. */
1267
+ /** Why the upload failed, as the backend said, when it said: its reason (README, "A refusal's reason"). */
1268
1268
  uploadError?: string;
1269
1269
  }
1270
1270
  /** The conversation list's search, as a host's sections read it (`sidebarSections`). */