@talk2view/sdk 0.21.2 → 0.21.4

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 (48) hide show
  1. package/README.md +124 -46
  2. package/dist/assistant-ui/index.d.ts.map +1 -1
  3. package/dist/assistant-ui/index.js +12 -7
  4. package/dist/assistant-ui/index.js.map +1 -1
  5. package/dist/auth.d.ts +23 -4
  6. package/dist/auth.d.ts.map +1 -1
  7. package/dist/auth.js +48 -22
  8. package/dist/auth.js.map +1 -1
  9. package/dist/chat/lib/use-conversations.d.ts.map +1 -1
  10. package/dist/chat/lib/use-conversations.js +23 -6
  11. package/dist/chat/lib/use-conversations.js.map +1 -1
  12. package/dist/chat/provider.d.ts +20 -2
  13. package/dist/chat/provider.d.ts.map +1 -1
  14. package/dist/chat/provider.js +3 -1
  15. package/dist/chat/provider.js.map +1 -1
  16. package/dist/chat/views/account.d.ts.map +1 -1
  17. package/dist/chat/views/account.js +22 -9
  18. package/dist/chat/views/account.js.map +1 -1
  19. package/dist/chat/voice-button.js +3 -3
  20. package/dist/chat/voice-button.js.map +1 -1
  21. package/dist/client.d.ts.map +1 -1
  22. package/dist/client.js +5 -4
  23. package/dist/client.js.map +1 -1
  24. package/dist/errors.d.ts +7 -0
  25. package/dist/errors.d.ts.map +1 -1
  26. package/dist/errors.js +7 -0
  27. package/dist/errors.js.map +1 -1
  28. package/dist/index.d.ts +31 -9
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +64 -10
  31. package/dist/index.js.map +1 -1
  32. package/dist/storage.d.ts +6 -0
  33. package/dist/storage.d.ts.map +1 -1
  34. package/dist/storage.js +6 -0
  35. package/dist/storage.js.map +1 -1
  36. package/dist/tools.d.ts +2 -1
  37. package/dist/tools.d.ts.map +1 -1
  38. package/dist/tools.js +23 -10
  39. package/dist/tools.js.map +1 -1
  40. package/dist/types.d.ts +6 -1
  41. package/dist/types.d.ts.map +1 -1
  42. package/dist/ui/components/ChatPanel.d.ts +5 -1
  43. package/dist/ui/components/ChatPanel.d.ts.map +1 -1
  44. package/dist/ui/components/ChatPanel.js +5 -1
  45. package/dist/ui/components/ChatPanel.js.map +1 -1
  46. package/docs/chat.md +86 -15
  47. package/docs/voice.md +18 -8
  48. package/package.json +5 -5
package/README.md CHANGED
@@ -8,10 +8,26 @@ Add AI-powered natural language control to any application. Talk2View's SDK hand
8
8
  npm install @talk2view/sdk
9
9
  ```
10
10
 
11
- You need a partner key. Create one at
12
- **[dashboard.talk2view.com](https://dashboard.talk2view.com)** — a `pk_test_…`
13
- for development and a `pk_live_…` for production. Keys are public identifiers,
14
- safe to ship in a browser bundle; see [Partner Keys](#partner-keys).
11
+ You need a partner key. Talk2View is in private beta:
12
+ **[request a partner key](https://talk2view.com/resources/contact?subject=partner-key)**.
13
+ You get one key, `pk_live_…`, a public identifier that is safe to ship in a
14
+ browser bundle; see [Partner Keys](#partner-keys) and the docs at
15
+ [docs.talk2view.com](https://docs.talk2view.com).
16
+
17
+ ## Intended use and data handling
18
+
19
+ Talk2View is for education, research and general information. It is not a
20
+ medical device: it is not regulated or approved as one, and it must not be used
21
+ to diagnose or treat any condition or to make clinical decisions. Its answers
22
+ come from AI models and can be wrong.
23
+
24
+ Do not send protected health information (PHI), or any other data that can
25
+ identify a patient, through the SDK. What end-users type, attach or say, and
26
+ what your tools return, is passed to third-party AI providers, and Talk2View
27
+ has no safeguard that detects, redacts or blocks such data.
28
+
29
+ The [Terms of Use](https://talk2view.com/legal/terms-of-use) and the
30
+ [Privacy Policy](https://talk2view.com/legal/privacy-policy) say this in full.
15
31
 
16
32
  ## Chat UI
17
33
 
@@ -27,8 +43,8 @@ import '@talk2view/sdk/chat.css';
27
43
  ```
28
44
 
29
45
  That is the full pane: sign-in, streaming replies, attachments, dictation,
30
- Settings, earlier conversations and tool approvals. Give it a parent with a
31
- height — it fills its box.
46
+ Settings, earlier conversations (kept in the end-user's browser) and tool
47
+ approvals. Give it a parent with a height — it fills its box.
32
48
 
33
49
  For a floating chat instead — a mark in the corner of the page, a popover on a
34
50
  desktop, a full-screen sheet on a phone:
@@ -41,16 +57,20 @@ import '@talk2view/sdk/chat.css';
41
57
  ```
42
58
 
43
59
  Theming is the custom properties on `.t2v-chat` (`--radius`, `--primary`, the
44
- rest); dark mode is `className="dark"`. The chat fetches nothing at runtime — no
45
- fonts, no CDN — and uses your page's font unless you pass `fontFamily`.
60
+ rest); dark mode is `className="dark"`. The chat fetches nothing at runtime but
61
+ your Talk2View engine — no fonts, no CDN — and uses your page's font unless you
62
+ pass `fontFamily`. Voice is the exception; see
63
+ [What loads at runtime](#what-loads-at-runtime).
46
64
 
47
- **It is large: 372.4 KB gzip, excluding React.** A consumer who never imports
65
+ **It is large: 373.3 KB gzip, excluding React.** A consumer who never imports
48
66
  `/chat` pays none of it.
49
67
 
50
68
  **Voice.** For partners with the realtime voice agent enabled, the launcher
51
69
  shows a microphone beside the mark: press to talk, press again to hang up. The
52
70
  agent uses the same tools, permissions and approval card as the chat. Standalone
53
- it is `<VoiceButton client={t2v} />`; without a UI it is `t2v.voice`. See
71
+ it is `<VoiceButton client={t2v} />`; without a UI it is `t2v.voice`. A call
72
+ downloads Daily's call engine from `https://c.daily.co`, so a Content Security
73
+ Policy has to allow it. See
54
74
  **[`docs/voice.md`](https://github.com/Talk2View/talk2view-typescript/blob/main/docs/voice.md)**.
55
75
 
56
76
  Everything else — the full prop table, theming tokens, the launcher in a hostile
@@ -105,11 +125,11 @@ function App() {
105
125
 
106
126
  That's it. `<Talk2View>` registers your tools and holds the chat state; `<ChatPanel>` is the UI — sign-in, streaming replies, tool calls and approvals. Both come from `@talk2view/sdk/ui`, and `<ChatPanel>` must be inside `<Talk2View>`.
107
127
 
108
- > `/ui` is smaller than the packaged chat (53.4 KB gzip against 362.7, plus
128
+ > `/ui` is smaller than the packaged chat (40.9 KB gzip against 373.3, plus
109
129
  > syntax highlighting loaded on demand) and has no assistant-ui in it, which is
110
130
  > why it is still here.
111
131
 
112
- A logged-out visitor gets an anonymous demo session automatically, so there is nothing to wire up before the first reply. Pass `allowAnonymous={false}` to `<ChatPanel>` to ask people to sign in first.
132
+ A logged-out visitor can chat as a guest, with no account, only where guest access is on for your partner key. It is off by default: switch it on under **Settings → Anonymous access** in the dashboard. Guest sign-in also needs a CAPTCHA check by default, which the SDK does not send, so ask Talk2View to set your key up for guests as well; Talk2View also sets your daily limit on new guests. Otherwise `<ChatPanel>` asks people to sign in. Pass `allowAnonymous={false}` to `<ChatPanel>` to always ask them to sign in first.
113
133
 
114
134
  ### Vanilla JavaScript
115
135
 
@@ -123,11 +143,7 @@ const t2v = new Talk2View({ partnerKey: 'pk_live_...' });
123
143
  // 1. Authenticate
124
144
  await t2v.auth.login('user@example.com', 'password');
125
145
 
126
- // 2. Register tools with handlers
127
- t2v.tools.handle('get_time', async () => {
128
- return new Date().toISOString();
129
- });
130
-
146
+ // 2. Register tools, then attach their handlers
131
147
  await t2v.tools.register([
132
148
  {
133
149
  name: 'get_time',
@@ -136,6 +152,10 @@ await t2v.tools.register([
136
152
  },
137
153
  ]);
138
154
 
155
+ t2v.tools.handle('get_time', async () => {
156
+ return new Date().toISOString();
157
+ });
158
+
139
159
  // 3. Chat — tool calls are handled automatically
140
160
  let reply = '';
141
161
  for await (const event of t2v.chat('What time is it?')) {
@@ -150,7 +170,8 @@ for await (const event of t2v.chat('What time is it?')) {
150
170
 
151
171
  This package follows semantic versioning, with one qualification that matters
152
172
  while it is below 1.0: a **minor** version may change behaviour, and a
153
- **patch** never changes the public surface. Breaking changes to exports or to
173
+ **patch** never removes or changes anything in the public surface, though it
174
+ may add to it — a new optional prop, say. Breaking changes to exports or to
154
175
  prop shapes are called out in [CHANGELOG.md](CHANGELOG.md) under the release
155
176
  that makes them.
156
177
 
@@ -165,23 +186,63 @@ anything.
165
186
  typed surface needs them, not because they are meant to be constructed
166
187
  directly. Use `Talk2View`.
167
188
 
189
+ ## Supported environments
190
+
191
+ - **Node** `^22.14.0 || ^24.0.0 || >=26.0.0`, for builds, tests and server
192
+ rendering. That is the range the package's runtime dependencies declare;
193
+ outside it npm warns `EBADENGINE` on install.
194
+ - **ES modules only.** There is no CommonJS build. Node's `require()` of ES
195
+ modules, on by default in the versions above, loads it too.
196
+ - **React** 18 or 19, for `/react`, `/ui`, `/assistant-ui` and `/chat`. The
197
+ core client does not use React. The test suite runs on React 19.
198
+ - **Browsers.** The packaged chat uses `dvh` units and the `inert` attribute,
199
+ so it needs at least Chrome or Edge 108, Safari 15.5 or Firefox 112. Part of
200
+ its styling also needs CSS nesting, `:has()` and media-query range syntax:
201
+ Chrome and Edge 112, Safari 16.5, Firefox 121. The package's own JavaScript
202
+ is ES2022, not transpiled further. Those versions come from the package's own
203
+ code and stylesheet; its dependencies were not measured, and the browser test
204
+ suites run in current Chromium only.
205
+ - **Popup sign-in** (Google and Apple) works in a browser only: it opens a
206
+ window, so it throws in Node and during server rendering. It also needs an
207
+ `https://` website and never runs on `localhost`.
208
+
209
+ ## What loads at runtime
210
+
211
+ What each entry point fetches once it is running, for your Content Security
212
+ Policy. "The engine" is your `baseUrl`, `https://engine.talk2view.com` unless
213
+ you set another.
214
+
215
+ | Entry point | Fetches |
216
+ |---|---|
217
+ | `@talk2view/sdk` | The engine only. Popup sign-in opens a window on the engine, which hands over to Google or Apple. |
218
+ | `/react`, `/assistant-ui` | The engine only. |
219
+ | `/chat` | The engine only: no fonts, no CDN, no images (an image in a reply becomes a link). Previews of the files an end-user attaches are `blob:` URLs, so a strict `img-src` needs `blob:`. |
220
+ | `/ui` (deprecated) | The engine, the IBM Plex fonts from Google Fonts (`fonts.googleapis.com`, `fonts.gstatic.com`) and the Talk2View logo from `db.talk2view.com`. Code highlighting compiles WebAssembly, which a strict CSP allows with `'wasm-unsafe-eval'`. |
221
+ | Voice: `t2v.voice`, `<VoiceButton>`, the launcher's microphone | The engine, and Daily's call engine from `https://c.daily.co`, which runs through `Function()`. |
222
+
223
+ So voice needs `https://c.daily.co` in `connect-src` and `'unsafe-eval'` in
224
+ `script-src`. Without either, no call starts. If that download fails, Daily's
225
+ library tries to send an error report to Daily's own error tracking (Sentry);
226
+ you can leave that blocked. The Pipecat libraries voice runs on come from your
227
+ own bundle, loaded on the first press, so a chat that never starts a call never
228
+ loads them. The call's audio travels over WebRTC, through the ICE servers the
229
+ engine hands out for each call.
230
+ [`docs/voice.md`](https://github.com/Talk2View/talk2view-typescript/blob/main/docs/voice.md)
231
+ has the rest.
232
+
168
233
  ## Concepts
169
234
 
170
235
  ### Partner Keys
171
236
 
172
- Every request requires a partner API key (`X-T2V-Partner-Key` header). Keys are scoped to your application:
173
-
174
- - `pk_test_...` — test keys for development
175
- - `pk_live_...` — production keys
237
+ Every request requires a partner API key (`X-T2V-Partner-Key` header). The SDK attaches this header automatically.
176
238
 
177
- The SDK attaches this header automatically.
239
+ Each partner gets one key, `pk_live_…`, scoped to your application. Talk2View is in private beta: [request a partner key](https://talk2view.com/resources/contact?subject=partner-key).
178
240
 
179
- **Partner keys are public identifiers**, not secrets. They identify your application but do not grant access to user data — every data-accessing request also requires a user JWT. It is safe to include partner keys in client-side bundles.
241
+ **Partner keys are public identifiers**, not secrets. They identify your application but do not grant access to user data — every data-accessing request also requires a user JWT. It is safe to include partner keys in client-side bundles, and there is no secret key to keep on a server.
180
242
 
181
243
  Best practices:
182
- - Inject keys via environment variables at build time (e.g. `VITE_T2V_PARTNER_KEY`)
183
- - Use separate `pk_test_` and `pk_live_` keys for development and production
184
- - To rotate a key, generate a new one at [dashboard.talk2view.com](https://dashboard.talk2view.com), update your app, then deactivate the old key
244
+ - Inject the key via an environment variable at build time (e.g. `VITE_T2V_PARTNER_KEY`)
245
+ - There is no self-serve key creation or rotation. To rotate your key, [contact Talk2View](https://talk2view.com/resources/contact). Rotation issues a new key and retires the old one within about a minute, with no planned overlap, so plan the switch with us
185
246
 
186
247
  ### Two-Tier Authentication
187
248
 
@@ -215,7 +276,7 @@ Tools with `return_direct: true` skip the AI's post-processing step. The tool re
215
276
  There are four React entry points, and they do different jobs:
216
277
 
217
278
  - **`@talk2view/sdk/chat`** — the branded Talk2View chat, packaged: `<Talk2ViewChat>` and `<Talk2ViewChatLauncher>`, one stylesheet, nothing to configure. Start here. See [Chat UI](#chat-ui) above and [`docs/chat.md`](https://github.com/Talk2View/talk2view-typescript/blob/main/docs/chat.md).
218
- - **`@talk2view/sdk/ui`** — the previous chat panel, still supported: `<Talk2View>`, `<ChatPanel>`, `<ChatWidget>` and the components they are built from. 40.3 KB gzip against the packaged chat's 372.4, and no assistant-ui.
279
+ - **`@talk2view/sdk/ui`** — the previous chat panel, still supported: `<Talk2View>`, `<ChatPanel>`, `<ChatWidget>` and the components they are built from. 40.9 KB gzip against the packaged chat's 373.3, and no assistant-ui.
219
280
  - **`@talk2view/sdk/react`** — headless: `<T2VProvider>` and hooks, for building your own UI.
220
281
  - **`@talk2view/sdk/assistant-ui`** — a runtime for [assistant-ui](https://www.assistant-ui.com): render the stock `<Thread />` on Talk2View. See [assistant-ui](#assistant-ui) below.
221
282
 
@@ -254,7 +315,11 @@ The full chat surface: header, message list, composer, sign-in, tool approvals.
254
315
  />
255
316
  ```
256
317
 
257
- By default a logged-out visitor is signed into an anonymous demo session rather than being shown a login form. The sign-in form appears when `allowAnonymous` is `false`, when your partner account has anonymous access switched off or its daily cap is spent, or when the demo budget for that visitor runs out.
318
+ With `allowAnonymous` on (the default), a logged-out visitor sees the chat, and the SDK tries to start a guest session the first time it needs one. The sign-in form appears instead:
319
+
320
+ - when `allowAnonymous` is `false`;
321
+ - when the engine refuses the guest session: guest access is off for your key (the default), its daily guest limit is spent, or it requires a CAPTCHA, which the SDK does not send;
322
+ - when that visitor's guest allowance runs out.
258
323
 
259
324
  ### `<LoginForm>` (from `/ui`)
260
325
 
@@ -263,9 +328,9 @@ The sign-in form on its own, if you want to place it yourself. It renders uncond
263
328
  ```tsx
264
329
  <LoginForm
265
330
  heading="Sign in"
266
- subheading="to keep your chat history"
331
+ subheading="to keep chatting"
267
332
  defaultMode="login" // or 'signup'
268
- signupUrl="https://talk2view.com/auth?signup"
333
+ signupUrl="https://talk2view.com/sign-up"
269
334
  resetPasswordUrl="https://..."
270
335
  termsUrl="https://..."
271
336
  privacyUrl="https://..."
@@ -443,7 +508,7 @@ function Chat() {
443
508
  Four things do not map, on purpose:
444
509
 
445
510
  - **Editing tool arguments before approval.** The SDK supports it (`HumanDecision.updatedInput`, used by `<ApprovalCard>` in `/ui`), but the stock assistant-ui approval card has no edit-and-resubmit affordance to drive it from — it can only approve, deny, or attach a free-form reason.
446
- - **Sign-in UI.** `useTalk2ViewRuntime` only creates a client and a runtime; there is no `<LoginForm>` equivalent. A logged-out visitor gets an anonymous demo session automatically (same default as `<ChatPanel>`), and building your own sign-in UI, or gating the app before it mounts, is on the partner.
511
+ - **Sign-in UI.** `useTalk2ViewRuntime` only creates a client and a runtime; there is no `<LoginForm>` equivalent. Where your key allows guests, a logged-out visitor gets a guest session (same default as `<ChatPanel>`); where it does not, the message is not sent and the client emits `anonymousUnavailable`. Building your own sign-in UI, or gating the app before it mounts, is on the partner.
447
512
  - **The agent's plan.** The planning checklist `<ChatPanel>` shows arrives as a `data` part named `plan` (`{ markdown }`). The stock Thread has no renderer for it, so it is silently not shown; register one to see it: `<MessagePrimitive.Parts components={{ data: { by_name: { plan: PlanView } } }} />`.
448
513
  - **Editing and deleting sent messages.** The runtime supplies no `onEdit`/`onDelete`, so the stock Thread's pencil on user messages stays disabled. Remove it from your copy of the Thread if you'd rather not show it.
449
514
 
@@ -501,12 +566,7 @@ await t2v.tools.register([
501
566
  },
502
567
  ]);
503
568
 
504
- // Option B: separate handler registration
505
- t2v.tools.handle('zoom_in', async () => {
506
- myApp.zoomIn();
507
- return JSON.stringify({ success: true });
508
- });
509
-
569
+ // Option B: register the schemas, then attach the handlers
510
570
  await t2v.tools.register([
511
571
  {
512
572
  name: 'zoom_in',
@@ -515,6 +575,11 @@ await t2v.tools.register([
515
575
  },
516
576
  ]);
517
577
 
578
+ t2v.tools.handle('zoom_in', async () => {
579
+ myApp.zoomIn();
580
+ return JSON.stringify({ success: true });
581
+ });
582
+
518
583
  // Check state
519
584
  t2v.tools.getRegistered() // ClientToolSchema[]
520
585
  t2v.tools.hasHandler('zoom_in') // boolean
@@ -525,6 +590,8 @@ t2v.tools.hasHandler('zoom_in') // boolean
525
590
  Register user-defined skills — knowledge documents the AI agent can discover and load for specialised expertise. Skills are stored client-side and sent to the server per-session.
526
591
 
527
592
  ```typescript
593
+ // Fictional data. Never use real patient data.
594
+
528
595
  // Add skills locally
529
596
  t2v.skills.add({
530
597
  name: 'radiology-workflow',
@@ -588,8 +655,9 @@ input.addEventListener('input', () => t2v.warmUp(), { once: true });
588
655
 
589
656
  It is safe to call repeatedly (one request per signed-in end-user), never
590
657
  throws, and is a no-op against an engine that predates it. Don't call it when
591
- the chat merely opens: for a logged-out visitor it starts an anonymous session,
592
- which counts toward your daily anonymous cap.
658
+ the chat merely opens: for a logged-out visitor it starts a guest session
659
+ wherever your key allows guests, and each one counts toward your daily guest
660
+ limit.
593
661
 
594
662
  `<ChatWidget>`, `<ChatPanel>` and the assistant-ui runtime already do this.
595
663
 
@@ -664,6 +732,7 @@ A tool needs a **schema** (so the AI knows when and how to call it) and an **exe
664
732
  ```typescript
665
733
  import type { ClientTool } from '@talk2view/sdk';
666
734
 
735
+ // Fictional data. Never use real patient data.
667
736
  const myTool: ClientTool = {
668
737
  name: 'set_window_level',
669
738
  description: 'Set the brightness and contrast of the medical image viewer',
@@ -747,8 +816,16 @@ Stored keys:
747
816
  - `talk2view_refresh_token`
748
817
  - `talk2view_user`
749
818
  - `talk2view_user_api_key`
819
+ - `talk2view_is_anonymous`
820
+
821
+ On logout, all of these are cleared and a `talk2view_auth_cleared` event is dispatched on `window` for cross-component synchronization.
822
+
823
+ Logging out leaves the rest of what the SDK keeps in `localStorage`:
750
824
 
751
- On logout, all keys are cleared and a `talk2view_auth_cleared` event is dispatched on `window` for cross-component synchronization.
825
+ - `talk2view_preferences` — Settings choices: model, dictation (speech-to-text) model and language, font size.
826
+ - `t2v_chat_conversations_v1:<partner key>` — the packaged chat's earlier conversations, one bucket per end-user. See [where conversations are kept](https://github.com/Talk2View/talk2view-typescript/blob/main/docs/chat.md#conversations-are-kept-in-this-browser).
827
+ - `t2v_user_skills` and `t2v_disabled_skills` — skills saved in the chat's Skills view or with `t2v.skills.save()`. They are not divided by end-user: in the packaged chat, whoever signs in next on that browser sees them and sends them with their chats.
828
+ - `t2v-launcher-size`, `t2v-launcher-opened` and `t2v-launcher-colourway` — the launcher's size, whether it has been opened, and the colourway a visitor picked.
752
829
 
753
830
  ### Security Considerations
754
831
 
@@ -761,13 +838,13 @@ To mitigate this:
761
838
  - **Always serve your application over HTTPS**
762
839
  - **Sanitize user-generated content** to prevent XSS injection
763
840
 
764
- **CSRF protection:** The SDK sends a custom `X-T2V-Partner-Key` header on every request. Browsers block cross-origin requests with custom headers unless the server explicitly allows the origin via CORS. This makes CSRF attacks infeasible — a forged request from a malicious site would be blocked by the browser's preflight check.
841
+ **CORS and CSRF:** The engine accepts cross-origin requests from any website (`Access-Control-Allow-Origin: *`), so CORS protects neither your key nor your users. Your key needs no protecting: it is a public identifier. What protects user data is the end-user's sign-in token, which the SDK sends in the `Authorization` header, never in a cookie, so a page on another site cannot make the browser send it.
765
842
 
766
843
  ---
767
844
 
768
845
  ## Rendering model replies
769
846
 
770
- Treat every model reply as untrusted. Prompt injection through web search, documents, email or tool results can make the model write anything. `<ChatPanel>` renders replies as markdown only, and never loads remote content on its own:
847
+ Treat every model reply as untrusted. Prompt injection through web search, documents, email or tool results can make the model write anything. `<ChatPanel>` renders replies as markdown only, and nothing in a reply loads remote content on its own:
771
848
 
772
849
  - **Raw HTML** in a reply is shown as text, apart from a bare `<br>`, which is kept so a GFM table cell can break a line (a cell can't hold a literal newline).
773
850
  - **Images** become links (`Image: <alt> (<host>)`) that the end-user can choose to open.
@@ -860,7 +937,7 @@ const { error: chatError } = useT2VChat({ systemPrompt: '...' });
860
937
  | `baseUrl` | `string` | No | `'https://engine.talk2view.com'` | Talk2View engine URL |
861
938
  | `model` | `string` | No | Server default | LLM model to use |
862
939
  | `requestTimeout` | `number` | No | `30000` | HTTP request timeout in ms. Does not apply to SSE streams after connection. |
863
- | `anonymousAutoStart` | `boolean` | No | `true` | Start an anonymous demo session on the first `chat()` when nobody is signed in. Set `false` to require sign-in. |
940
+ | `anonymousAutoStart` | `boolean` | No | `true` | When nobody is signed in, try to start a guest session the first time a call needs one (sending, uploading, transcribing, listing models, `warmUp()`, voice). It succeeds only where your key allows guests; a refusal emits `anonymousUnavailable`. Set `false` to require sign-in. |
864
941
  | `debug` | `boolean` | No | `false` | Log streaming events, tool calls, history and state changes to the console. |
865
942
 
866
943
  ---
@@ -870,6 +947,7 @@ const { error: chatError } = useT2VChat({ systemPrompt: '...' });
870
947
  System prompts set the AI's behavior and context for your application. Pass one to `<Talk2View>` (the UI components) or to `useT2VChat` (the hooks):
871
948
 
872
949
  ```tsx
950
+ // Fictional data. Never use real patient data.
873
951
  <Talk2View
874
952
  partnerKey="pk_live_..."
875
953
  systemPrompt="You are a medical imaging assistant. Use the provided tools to control the DICOM viewer."
@@ -1019,8 +1097,8 @@ The source is at
1019
1097
  [github.com/Talk2View/talk2view-typescript](https://github.com/Talk2View/talk2view-typescript).
1020
1098
  Bugs and feature requests go in
1021
1099
  [Issues](https://github.com/Talk2View/talk2view-typescript/issues); pull
1022
- requests are welcome, and [CONTRIBUTING.md](CONTRIBUTING.md) says how the repo
1023
- is laid out and what a reviewer looks for.
1100
+ requests are welcome, and [CONTRIBUTING.md](CONTRIBUTING.md) says how to get
1101
+ set up and what a reviewer looks for.
1024
1102
 
1025
1103
  Security problems do **not** go in an issue — see
1026
1104
  [SECURITY.md](SECURITY.md).
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assistant-ui/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAEV,gBAAgB,EAIhB,8BAA8B,EAE/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAEV,UAAU,EACV,gBAAgB,EAGhB,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,OAAO,EAAmC,KAAK,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACjG,YAAY,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACrF,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,YAAY,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,gBAAgB,GAAG,UAAU,CAAC,EAAE,CAAC;IAC1C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,yBAAyB,CAAC;IAChD;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,8BAA8B,CAAC;CAC7C;AAED,MAAM,WAAW,0BAA2B,SAAQ,SAAS,EAAE,uBAAuB;CAAG;AAKzF,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,gBAAgB,CA6BzF;AAED,kGAAkG;AAClG,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,SAAS,EACd,EACE,YAAY,EACZ,KAAK,EACL,KAAK,EACL,SAAS,EACT,WAAW,EAAE,kBAAyB,EACtC,UAAU,GACX,GAAE,uBAA4B,GAC9B,gBAAgB,CAyNlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assistant-ui/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAEV,gBAAgB,EAIhB,8BAA8B,EAE/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAEV,UAAU,EACV,gBAAgB,EAGhB,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,OAAO,EAAmC,KAAK,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACjG,YAAY,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACrF,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,YAAY,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,gBAAgB,GAAG,UAAU,CAAC,EAAE,CAAC;IAC1C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,yBAAyB,CAAC;IAChD;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,8BAA8B,CAAC;CAC7C;AAED,MAAM,WAAW,0BAA2B,SAAQ,SAAS,EAAE,uBAAuB;CAAG;AAKzF,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,gBAAgB,CA6BzF;AAED,kGAAkG;AAClG,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,SAAS,EACd,EACE,YAAY,EACZ,KAAK,EACL,KAAK,EACL,SAAS,EACT,WAAW,EAAE,kBAAyB,EACtC,UAAU,GACX,GAAE,uBAA4B,GAC9B,gBAAgB,CA8NlB"}
@@ -103,10 +103,12 @@ export function useTalk2ViewRuntimeForClient(t2v, { systemPrompt, tools, model,
103
103
  registered.current = { t2v, key: schemaKey };
104
104
  t2v.tools.register(schemas).catch(() => { });
105
105
  }
106
- // Handlers AFTER register(): it rebuilds the handler map from what it is
107
- // given, and these schemas carry no `execute`, so handlers added first were
108
- // wiped. StrictMode's second effect run hid that in development; a
109
- // production build runs once, and every tool answered "Unknown tool".
106
+ // Handlers AFTER register(). These schemas carry no `execute`, and
107
+ // register() used to rebuild the handler map from what it was given, so
108
+ // handlers added first were wiped. StrictMode's second effect run hid that
109
+ // in development; a production build runs once, and every tool answered
110
+ // "Unknown tool". register() keeps a listed tool's handler now, and this
111
+ // order is right either way.
110
112
  // Re-added on every run, so a new `execute` closure always takes effect.
111
113
  for (const tool of tools ?? []) {
112
114
  if ('execute' in tool && tool.execute)
@@ -152,11 +154,14 @@ export function useTalk2ViewRuntimeForClient(t2v, { systemPrompt, tools, model,
152
154
  const dictationAdapter = useMemo(() => (dictationEnabled ? createTalk2ViewDictationAdapter(t2v, () => dictationOptions.current) : null), [t2v, dictationEnabled]);
153
155
  // A turn that fails before its first text chunk leaves no assistant message
154
156
  // behind (the SDK drops the empty one), and assistant-ui can only show an
155
- // error on an assistant message — so give it one to show it on.
157
+ // error on an assistant message — so give it one to show it on. An error
158
+ // with nothing on screen at all gets one too: an account whose session died
159
+ // takes its conversation with it, and the error is all that says why.
156
160
  const threadMessages = useMemo(() => {
157
161
  const last = messages[messages.length - 1];
158
- if (error && last && last.role !== 'assistant') {
159
- return [...messages, { id: `${last.id}:error`, role: 'assistant', content: '', timestamp: new Date() }];
162
+ if (error && last?.role !== 'assistant') {
163
+ const id = last ? `${last.id}:error` : 't2v-error';
164
+ return [...messages, { id, role: 'assistant', content: '', timestamp: new Date() }];
160
165
  }
161
166
  return messages;
162
167
  }, [messages, error]);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assistant-ui/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assistant-ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAU9D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AASpD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,+BAA+B,EAAkC,MAAM,gBAAgB,CAAC;AAGjG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AA4C1F,oEAAoE;AACpE,MAAM,2BAA2B,GAAG,uBAAuB,CAAC;AAE5D,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACrE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;IAC/F,2EAA2E;IAC3E,wEAAwE;IACxE,yDAAyD;IACzD,4EAA4E;IAC5E,+EAA+E;IAC/E,+EAA+E;IAC/E,gBAAgB;IAChB,MAAM,GAAG,GAAG,OAAO,CACjB,GAAG,EAAE;QACH,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,uDAAuD;IACvD,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAC7E,CAAC;IACF,MAAM,OAAO,GAAG,4BAA4B,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;IACvH,0EAA0E;IAC1E,yEAAyE;IACzE,+EAA+E;IAC/E,6EAA6E;IAC7E,2DAA2D;IAC3D,SAAS,CAAC,GAAG,EAAE;QACb,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACV,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,4BAA4B,CAC1C,GAAc,EACd,EACE,YAAY,EACZ,KAAK,EACL,KAAK,EACL,SAAS,EACT,WAAW,EAAE,kBAAkB,GAAG,IAAI,EACtC,UAAU,MACiB,EAAE;IAE/B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7D,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAyB,GAAG,CAAC,eAAe,CAAC,CAAC;IAEpG,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5B,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpB,kBAAkB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG;YACb,GAAG,CAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,CAAC;YACrC,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,YAAY,CAAC;YACrC,GAAG,CAAC,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC;YAC/B,GAAG,CAAC,EAAE,CAAC,gBAAgB,EAAE,kBAAkB,CAAC;SAC7C,CAAC;QACF,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,2EAA2E;IAC3E,uEAAuE;IACvE,4EAA4E;IAC5E,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CACH,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,IAAkB,CAAC;QAC5D,OAAO,MAA0B,CAAC;IACpC,CAAC,CAAC,EACJ,CAAC,KAAK,CAAC,CACR,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,MAAM,CAAyC,IAAI,CAAC,CAAC;IACxE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACjC,IAAI,UAAU,CAAC,OAAO,EAAE,GAAG,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC5E,UAAU,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YAC7C,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,mEAAmE;QACnE,wEAAwE;QACxE,2EAA2E;QAC3E,wEAAwE;QACxE,yEAAyE;QACzE,6BAA6B;QAC7B,yEAAyE;QACzE,KAAK,MAAM,IAAI,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;YAC/B,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO;gBAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACnF,CAAC;IACH,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAErC,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,GAAG,EAAsB,CAAC,CAAC;IAEvD,MAAM,WAAW,GAAG,OAAO,CACzB,GAAG,EAAE,CAAC,CAAC;QACL,MAAM,EAAE,iBAAiB;QACzB,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;YAChB,OAAO;gBACL,EAAE,EAAE,SAAS,EAAE;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU;gBAC3D,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,IAAI;gBACtB,IAAI;gBACJ,MAAM,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,eAAe,EAAE;aAC7D,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAAO;YAChB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3E,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACxC,OAAO;gBACL,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,MAAM,CAAC,QAAQ;gBACrB,WAAW,EAAE,MAAM,CAAC,SAAS;gBAC7B,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;gBAC5B,2DAA2D;gBAC3D,OAAO,EAAE,EAAE;aACZ,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,MAAM;YACV,yEAAyE;QAC3E,CAAC;KACF,CAAC,EACF,CAAC,GAAG,CAAC,CACN,CAAC;IAEF,yEAAyE;IACzE,uEAAuE;IACvE,MAAM,gBAAgB,GAAG,MAAM,CAA4B,EAAE,CAAC,CAAC;IAC/D,gBAAgB,CAAC,OAAO,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,MAAM,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,OAAO,CAC9B,GAAG,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,+BAA+B,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EACtG,CAAC,GAAG,EAAE,gBAAgB,CAAC,CACxB,CAAC;IAEF,4EAA4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,4EAA4E;IAC5E,sEAAsE;IACtE,MAAM,cAAc,GAAG,OAAO,CAAmB,GAAG,EAAE;QACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3C,IAAI,KAAK,IAAI,IAAI,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;YACxC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;YACnD,OAAO,CAAC,GAAG,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtB,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,GAAmB,EAAE,GAAW,EAAE,EAAE,CACnC,eAAe,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,KAAK,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,EAC7F,CAAC,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,CAChD,CAAC;IAEF,MAAM,KAAK,GAAG,WAAW,CACvB,KAAK,EAAE,OAAsB,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO;aACzB,MAAM,CAAC,CAAC,CAAC,EAAuC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;aACrE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAc,EAAE;YAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1C,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9B,qEAAqE;YACrE,4DAA4D;YAC5D,OAAO,MAAM,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QACjH,CAAC,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE;YAC1B,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;IACL,CAAC,EACD,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,CAAC,CAC3B,CAAC;IAEF,wEAAwE;IACxE,yEAAyE;IACzE,wEAAwE;IACxE,0EAA0E;IAC1E,cAAc;IACd,MAAM,QAAQ,GAAG,WAAW,CAC1B,KAAK,EAAE,QAAuB,EAAE,EAAE;QAChC,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QACxE,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAAC,EAAE;YAAE,OAAO;QAClD,MAAM,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC/B,CAAC,EACD,CAAC,GAAG,EAAE,QAAQ,CAAC,CAChB,CAAC;IAEF,0EAA0E;IAC1E,sEAAsE;IACtE,sCAAsC;IACtC,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACtC,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,2BAA2B,EAAE,CAAC,CAAC;YACrF,OAAO;QACT,CAAC;QACD,GAAG,CAAC,IAAI,EAAE,CAAC;IACb,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE,cAAc;QACxB,uEAAuE;QACvE,+DAA+D;QAC/D,SAAS,EAAE,SAAS,IAAI,eAAe,KAAK,IAAI;QAChD,cAAc;QACd,KAAK;QACL,QAAQ;QACR,QAAQ;QACR,uBAAuB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YAC1C,kEAAkE;YAClE,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,eAAe,EAAE,UAAU;gBAAE,OAAO;YACpE,MAAM,GAAG,CAAC,eAAe,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,QAAQ,EAAE;YACR,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5D,sEAAsE;YACtE,sEAAsE;YACtE,oEAAoE;YACpE,EAAE;YACF,qEAAqE;YACrE,wEAAwE;YACxE,sEAAsE;YACtE,yEAAyE;YACzE,uEAAuE;YACvE,mEAAmE;YACnE,UAAU,EAAE,UAAU,IAAI;gBACxB,mBAAmB,EAAE,GAAG,EAAE;oBACxB,GAAG,CAAC,aAAa,EAAE,CAAC;gBACtB,CAAC;aACF;SACF;KACF,CAAC,EACF,CAAC,cAAc,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAC5J,CAAC;IAEF,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAEjD,4EAA4E;IAC5E,+EAA+E;IAC/E,yEAAyE;IACzE,uEAAuE;IACvE,6EAA6E;IAC7E,MAAM,SAAS,GAAG,MAAM,CAAU,IAAI,CAAC,CAAC;IACxC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;QACzC,MAAM,KAAK,GAAG,GAAG,EAAE;YACjB,IAAI,SAAS,CAAC,OAAO,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI;gBAAE,OAAO;YACnE,SAAS,CAAC,OAAO,GAAG,GAAG,CAAC;YACxB,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;QACpB,CAAC,CAAC;QACF,KAAK,EAAE,CAAC;QACR,OAAO,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAEnB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,IAAI,cAAc,GAAG,CAAC,CAAC;AACvB,SAAS,SAAS;IAChB,cAAc,IAAI,CAAC,CAAC;IACpB,OAAO,WAAW,IAAI,CAAC,GAAG,EAAE,IAAI,cAAc,EAAE,CAAC;AACnD,CAAC"}
package/dist/auth.d.ts CHANGED
@@ -10,10 +10,22 @@ export declare class T2VAuth {
10
10
  private listeners;
11
11
  private readonly onAuthCleared;
12
12
  /**
13
- * Cross-tab logout sync. The native `storage` event fires in *other* tabs
14
- * when localStorage changes in one tab. When a sibling tab logs out (or a
15
- * dead-refresh-token 401 clears auth), the access-token key is removed/nulled;
16
- * we observe that here and flip this tab to logged-out too.
13
+ * Cross-tab auth sync. The native `storage` event fires in *other* tabs
14
+ * when localStorage changes in one tab.
15
+ *
16
+ * - When a sibling tab logs out (or a dead-refresh-token 401 clears auth),
17
+ * the access-token key is removed/nulled; this tab flips to logged-out too.
18
+ * - When a sibling tab signs a different end-user in, the user key changes to
19
+ * someone else. Every request this tab makes reads its token from storage,
20
+ * so it is already acting as them; announcing it is what makes the rest of
21
+ * this tab agree — above all, it takes the last account's conversation off
22
+ * the screen instead of replaying it under the new account.
23
+ * - When it signs the same end-user in again, that is most often a guest
24
+ * signing in to the account they converted to, which keeps the user id.
25
+ * Announcing it tells this tab it holds an account now, not a guest, so
26
+ * the conversation is treated as an account's from then on.
27
+ *
28
+ * A token refresh never writes the user key.
17
29
  */
18
30
  private readonly onStorage;
19
31
  /** Whether the window listeners below are currently registered. */
@@ -127,6 +139,13 @@ export declare class T2VAuth {
127
139
  * Subscribe to auth state changes.
128
140
  */
129
141
  onAuthStateChange(callback: AuthStateCallback): () => void;
142
+ /**
143
+ * Write a new session. The user goes last: another tab hears a sign-in as
144
+ * the user key changing (see {@link onStorage}) and reads the rest of the
145
+ * session there and then — whether this is a guest above all, which decides
146
+ * whether the conversation on its screen may follow — so everything it reads
147
+ * is written before it.
148
+ */
130
149
  private storeTokens;
131
150
  private notifyListeners;
132
151
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAe7C,OAAO,KAAK,EAAgB,aAAa,EAAgC,IAAI,EAAE,MAAM,YAAY,CAAC;AAElG,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC;AAqC/C,qBAAa,OAAO;IA2BN,OAAO,CAAC,QAAQ,CAAC,MAAM;IA1BnC,OAAO,CAAC,SAAS,CAAqC;IAGtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAKxB;IAEF,mEAAmE;IACnE,OAAO,CAAC,SAAS,CAAS;IAE1B,sEAAsE;IACtE,OAAO,CAAC,WAAW,CAAS;gBAEC,MAAM,EAAE,SAAS;IAO9C;;;;;;;;;;;;;;OAcG;IACH,MAAM,IAAI,IAAI;IASd;;;OAGG;IACH,OAAO,IAAI,IAAI;IAOf,oDAAoD;IAC9C,cAAc,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAerE,gEAAgE;IAChE,WAAW,IAAI,OAAO;IAItB;;;;;;;OAOG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAiCrE;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB3D,OAAO,CAAC,UAAU,CAAC,CAAkB;IAIrC,OAAO,CAAC,cAAc,CAAyC;IAE/D;;;;;;OAMG;IACH,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IA4C7C,+DAA+D;IACzD,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvC;;;;;OAKG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAoCxC,iBAAiB;IA4D/B,mDAAmD;IACnD,OAAO,CAAC,KAAK;IAkBb;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB7B;;;;OAIG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,GAAG,IAAI;IAUtB;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;;;;;;;;;;;;;;;;OAiBG;IACG,mBAAmB,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiBpF;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAO1D,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,eAAe;CAKxB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAgB7C,OAAO,KAAK,EAAgB,aAAa,EAAgC,IAAI,EAAE,MAAM,YAAY,CAAC;AAElG,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC;AA+C/C,qBAAa,OAAO;IA2CN,OAAO,CAAC,QAAQ,CAAC,MAAM;IA1CnC,OAAO,CAAC,SAAS,CAAqC;IAGtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CASxB;IAEF,mEAAmE;IACnE,OAAO,CAAC,SAAS,CAAS;IAE1B,sEAAsE;IACtE,OAAO,CAAC,WAAW,CAAS;gBAEC,MAAM,EAAE,SAAS;IAO9C;;;;;;;;;;;;;;OAcG;IACH,MAAM,IAAI,IAAI;IASd;;;OAGG;IACH,OAAO,IAAI,IAAI;IAOf,oDAAoD;IAC9C,cAAc,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrE,gEAAgE;IAChE,WAAW,IAAI,OAAO;IAItB;;;;;;;OAOG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAiCrE;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB3D,OAAO,CAAC,UAAU,CAAC,CAAkB;IAIrC,OAAO,CAAC,cAAc,CAAyC;IAE/D;;;;;;OAMG;IACH,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IA4C7C,+DAA+D;IACzD,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvC;;;;;OAKG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAoCxC,iBAAiB;IA4D/B,mDAAmD;IACnD,OAAO,CAAC,KAAK;IAkBb;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB7B;;;;OAIG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,GAAG,IAAI;IAItB;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;;;;;;;;;;;;;;;;OAiBG;IACG,mBAAmB,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiBpF;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAO1D;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,eAAe;CAKxB"}
package/dist/auth.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Auth module — login, signup, refresh, logout, auth state management.
3
3
  */
4
4
  import { AuthenticationError, T2VError } from './errors.js';
5
- import { ACCESS_TOKEN_STORAGE_KEY, clearAuth, getAccessToken, getIsAnonymous, getUser, hasValidTokens, setAccessToken, setIsAnonymous, setUserApiKey, setRefreshToken, setUser, } from './storage.js';
5
+ import { ACCESS_TOKEN_STORAGE_KEY, USER_STORAGE_KEY, clearAuth, getAccessToken, getIsAnonymous, getUser, hasValidTokens, setAccessToken, setIsAnonymous, setUserApiKey, setRefreshToken, setUser, } from './storage.js';
6
6
  // Refresh a token this many seconds before it actually expires, so a request
7
7
  // fired right at the boundary doesn't race the expiry against clock skew.
8
8
  const TOKEN_EXPIRY_SKEW_SECONDS = 30;
@@ -18,6 +18,17 @@ function isExpiringSoon(token, skewSeconds = TOKEN_EXPIRY_SKEW_SECONDS) {
18
18
  return false;
19
19
  return exp - Date.now() / 1000 <= skewSeconds;
20
20
  }
21
+ /** The stored end-user, or null when there is none or it cannot be read. */
22
+ function parseUser(raw) {
23
+ if (!raw)
24
+ return null;
25
+ try {
26
+ return JSON.parse(raw);
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
21
32
  function decodeJwtExp(token) {
22
33
  const payloadPart = token.split('.')[1];
23
34
  if (!payloadPart || typeof atob !== 'function')
@@ -40,15 +51,32 @@ export class T2VAuth {
40
51
  this.notifyListeners(null);
41
52
  };
42
53
  /**
43
- * Cross-tab logout sync. The native `storage` event fires in *other* tabs
44
- * when localStorage changes in one tab. When a sibling tab logs out (or a
45
- * dead-refresh-token 401 clears auth), the access-token key is removed/nulled;
46
- * we observe that here and flip this tab to logged-out too.
54
+ * Cross-tab auth sync. The native `storage` event fires in *other* tabs
55
+ * when localStorage changes in one tab.
56
+ *
57
+ * - When a sibling tab logs out (or a dead-refresh-token 401 clears auth),
58
+ * the access-token key is removed/nulled; this tab flips to logged-out too.
59
+ * - When a sibling tab signs a different end-user in, the user key changes to
60
+ * someone else. Every request this tab makes reads its token from storage,
61
+ * so it is already acting as them; announcing it is what makes the rest of
62
+ * this tab agree — above all, it takes the last account's conversation off
63
+ * the screen instead of replaying it under the new account.
64
+ * - When it signs the same end-user in again, that is most often a guest
65
+ * signing in to the account they converted to, which keeps the user id.
66
+ * Announcing it tells this tab it holds an account now, not a guest, so
67
+ * the conversation is treated as an account's from then on.
68
+ *
69
+ * A token refresh never writes the user key.
47
70
  */
48
71
  onStorage = (event) => {
49
- // Only react to our access-token key being cleared (removed → newValue null).
50
72
  if (event.key === ACCESS_TOKEN_STORAGE_KEY && event.newValue === null) {
51
73
  this.notifyListeners(null);
74
+ return;
75
+ }
76
+ if (event.key === USER_STORAGE_KEY && event.newValue !== null) {
77
+ const next = parseUser(event.newValue);
78
+ if (next)
79
+ this.notifyListeners(next);
52
80
  }
53
81
  };
54
82
  /** Whether the window listeners below are currently registered. */
@@ -101,8 +129,7 @@ export class T2VAuth {
101
129
  async startAnonymous(opts) {
102
130
  const body = opts?.captchaToken ? { captcha_token: opts.captchaToken } : {};
103
131
  const response = await this.client.request('/v1/auth/anonymous', { method: 'POST', body: JSON.stringify(body) }, false);
104
- this.storeTokens(response);
105
- setIsAnonymous(true);
132
+ this.storeTokens(response, true);
106
133
  const user = response.user;
107
134
  if (!user)
108
135
  throw new AuthenticationError('Anonymous sign-in returned no user');
@@ -371,15 +398,7 @@ export class T2VAuth {
371
398
  * Get the current user (from storage).
372
399
  */
373
400
  getUser() {
374
- const raw = getUser();
375
- if (!raw)
376
- return null;
377
- try {
378
- return JSON.parse(raw);
379
- }
380
- catch {
381
- return null;
382
- }
401
+ return parseUser(getUser());
383
402
  }
384
403
  /**
385
404
  * Check if a user is currently authenticated.
@@ -431,16 +450,23 @@ export class T2VAuth {
431
450
  this.listeners.delete(callback);
432
451
  };
433
452
  }
434
- storeTokens(response) {
453
+ /**
454
+ * Write a new session. The user goes last: another tab hears a sign-in as
455
+ * the user key changing (see {@link onStorage}) and reads the rest of the
456
+ * session there and then — whether this is a guest above all, which decides
457
+ * whether the conversation on its screen may follow — so everything it reads
458
+ * is written before it.
459
+ */
460
+ storeTokens(response, anonymous = response.is_anonymous === true) {
461
+ setIsAnonymous(anonymous);
435
462
  setAccessToken(response.access_token);
436
463
  setRefreshToken(response.refresh_token);
437
- if (response.user) {
438
- setUser(response.user);
439
- }
440
464
  if (response.user_api_key) {
441
465
  setUserApiKey(response.user_api_key);
442
466
  }
443
- setIsAnonymous(response.is_anonymous === true);
467
+ if (response.user) {
468
+ setUser(response.user);
469
+ }
444
470
  }
445
471
  notifyListeners(user) {
446
472
  for (const listener of this.listeners) {