@talk2view/sdk 0.15.0 → 0.16.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.
Files changed (185) hide show
  1. package/README.md +47 -2
  2. package/dist/assistant-ui/index.d.ts +7 -1
  3. package/dist/assistant-ui/index.d.ts.map +1 -1
  4. package/dist/assistant-ui/index.js +23 -6
  5. package/dist/assistant-ui/index.js.map +1 -1
  6. package/dist/auth.d.ts +19 -1
  7. package/dist/auth.d.ts.map +1 -1
  8. package/dist/auth.js +36 -13
  9. package/dist/auth.js.map +1 -1
  10. package/dist/chat/auth-gate.d.ts +42 -0
  11. package/dist/chat/auth-gate.d.ts.map +1 -0
  12. package/dist/chat/auth-gate.js +93 -0
  13. package/dist/chat/auth-gate.js.map +1 -0
  14. package/dist/chat/chat.d.ts +36 -0
  15. package/dist/chat/chat.d.ts.map +1 -0
  16. package/dist/chat/chat.js +124 -0
  17. package/dist/chat/chat.js.map +1 -0
  18. package/dist/chat/composer-extras.d.ts +23 -0
  19. package/dist/chat/composer-extras.d.ts.map +1 -0
  20. package/dist/chat/composer-extras.js +48 -0
  21. package/dist/chat/composer-extras.js.map +1 -0
  22. package/dist/chat/hooks/use-attachment-src.d.ts +2 -0
  23. package/dist/chat/hooks/use-attachment-src.d.ts.map +1 -0
  24. package/dist/chat/hooks/use-attachment-src.js +38 -0
  25. package/dist/chat/hooks/use-attachment-src.js.map +1 -0
  26. package/dist/chat/hooks/use-copy-to-clipboard.d.ts +8 -0
  27. package/dist/chat/hooks/use-copy-to-clipboard.d.ts.map +1 -0
  28. package/dist/chat/hooks/use-copy-to-clipboard.js +16 -0
  29. package/dist/chat/hooks/use-copy-to-clipboard.js.map +1 -0
  30. package/dist/chat/index.d.ts +32 -0
  31. package/dist/chat/index.d.ts.map +1 -0
  32. package/dist/chat/index.js +35 -0
  33. package/dist/chat/index.js.map +1 -0
  34. package/dist/chat/inject-styles.d.ts +2 -0
  35. package/dist/chat/inject-styles.d.ts.map +1 -0
  36. package/dist/chat/inject-styles.js +23 -0
  37. package/dist/chat/inject-styles.js.map +1 -0
  38. package/dist/chat/launcher.d.ts +37 -0
  39. package/dist/chat/launcher.d.ts.map +1 -0
  40. package/dist/chat/launcher.js +343 -0
  41. package/dist/chat/launcher.js.map +1 -0
  42. package/dist/chat/lib/cn.d.ts +19 -0
  43. package/dist/chat/lib/cn.d.ts.map +1 -0
  44. package/dist/chat/lib/cn.js +20 -0
  45. package/dist/chat/lib/cn.js.map +1 -0
  46. package/dist/chat/lib/dictation-phase.d.ts +9 -0
  47. package/dist/chat/lib/dictation-phase.d.ts.map +1 -0
  48. package/dist/chat/lib/dictation-phase.js +33 -0
  49. package/dist/chat/lib/dictation-phase.js.map +1 -0
  50. package/dist/chat/lib/guard.d.ts +4 -0
  51. package/dist/chat/lib/guard.d.ts.map +1 -0
  52. package/dist/chat/lib/guard.js +41 -0
  53. package/dist/chat/lib/guard.js.map +1 -0
  54. package/dist/chat/lib/launcher-variant.d.ts +33 -0
  55. package/dist/chat/lib/launcher-variant.d.ts.map +1 -0
  56. package/dist/chat/lib/launcher-variant.js +109 -0
  57. package/dist/chat/lib/launcher-variant.js.map +1 -0
  58. package/dist/chat/lib/portal-host.d.ts +13 -0
  59. package/dist/chat/lib/portal-host.d.ts.map +1 -0
  60. package/dist/chat/lib/portal-host.js +58 -0
  61. package/dist/chat/lib/portal-host.js.map +1 -0
  62. package/dist/chat/markdown.d.ts +32 -0
  63. package/dist/chat/markdown.d.ts.map +1 -0
  64. package/dist/chat/markdown.js +18 -0
  65. package/dist/chat/markdown.js.map +1 -0
  66. package/dist/chat/provider.d.ts +113 -0
  67. package/dist/chat/provider.d.ts.map +1 -0
  68. package/dist/chat/provider.js +176 -0
  69. package/dist/chat/provider.js.map +1 -0
  70. package/dist/chat/tool-fallback.d.ts +39 -0
  71. package/dist/chat/tool-fallback.d.ts.map +1 -0
  72. package/dist/chat/tool-fallback.js +167 -0
  73. package/dist/chat/tool-fallback.js.map +1 -0
  74. package/dist/chat/ui/avatar.d.ts +12 -0
  75. package/dist/chat/ui/avatar.d.ts.map +1 -0
  76. package/dist/chat/ui/avatar.js +24 -0
  77. package/dist/chat/ui/avatar.js.map +1 -0
  78. package/dist/chat/ui/button.d.ts +9 -0
  79. package/dist/chat/ui/button.d.ts.map +1 -0
  80. package/dist/chat/ui/button.js +35 -0
  81. package/dist/chat/ui/button.js.map +1 -0
  82. package/dist/chat/ui/collapsible.d.ts +6 -0
  83. package/dist/chat/ui/collapsible.d.ts.map +1 -0
  84. package/dist/chat/ui/collapsible.js +13 -0
  85. package/dist/chat/ui/collapsible.js.map +1 -0
  86. package/dist/chat/ui/dialog.d.ts +18 -0
  87. package/dist/chat/ui/dialog.d.ts.map +1 -0
  88. package/dist/chat/ui/dialog.js +42 -0
  89. package/dist/chat/ui/dialog.js.map +1 -0
  90. package/dist/chat/ui/input.d.ts +4 -0
  91. package/dist/chat/ui/input.d.ts.map +1 -0
  92. package/dist/chat/ui/input.js +8 -0
  93. package/dist/chat/ui/input.js.map +1 -0
  94. package/dist/chat/ui/skeleton.d.ts +3 -0
  95. package/dist/chat/ui/skeleton.d.ts.map +1 -0
  96. package/dist/chat/ui/skeleton.js +7 -0
  97. package/dist/chat/ui/skeleton.js.map +1 -0
  98. package/dist/chat/ui/textarea.d.ts +4 -0
  99. package/dist/chat/ui/textarea.d.ts.map +1 -0
  100. package/dist/chat/ui/textarea.js +7 -0
  101. package/dist/chat/ui/textarea.js.map +1 -0
  102. package/dist/chat/ui/tooltip.d.ts +7 -0
  103. package/dist/chat/ui/tooltip.d.ts.map +1 -0
  104. package/dist/chat/ui/tooltip.js +22 -0
  105. package/dist/chat/ui/tooltip.js.map +1 -0
  106. package/dist/chat/vendor/attachment.aui.d.ts +5 -0
  107. package/dist/chat/vendor/attachment.aui.d.ts.map +1 -0
  108. package/dist/chat/vendor/attachment.aui.js +79 -0
  109. package/dist/chat/vendor/attachment.aui.js.map +1 -0
  110. package/dist/chat/vendor/file.d.ts +41 -0
  111. package/dist/chat/vendor/file.d.ts.map +1 -0
  112. package/dist/chat/vendor/file.js +137 -0
  113. package/dist/chat/vendor/file.js.map +1 -0
  114. package/dist/chat/vendor/follow-up-suggestions.aui.d.ts +3 -0
  115. package/dist/chat/vendor/follow-up-suggestions.aui.d.ts.map +1 -0
  116. package/dist/chat/vendor/follow-up-suggestions.aui.js +45 -0
  117. package/dist/chat/vendor/follow-up-suggestions.aui.js.map +1 -0
  118. package/dist/chat/vendor/image.d.ts +47 -0
  119. package/dist/chat/vendor/image.d.ts.map +1 -0
  120. package/dist/chat/vendor/image.js +258 -0
  121. package/dist/chat/vendor/image.js.map +1 -0
  122. package/dist/chat/vendor/markdown-text.d.ts +8 -0
  123. package/dist/chat/vendor/markdown-text.d.ts.map +1 -0
  124. package/dist/chat/vendor/markdown-text.js +73 -0
  125. package/dist/chat/vendor/markdown-text.js.map +1 -0
  126. package/dist/chat/vendor/reasoning.aui.d.ts +22 -0
  127. package/dist/chat/vendor/reasoning.aui.d.ts.map +1 -0
  128. package/dist/chat/vendor/reasoning.aui.js +56 -0
  129. package/dist/chat/vendor/reasoning.aui.js.map +1 -0
  130. package/dist/chat/vendor/reasoning.d.ts +35 -0
  131. package/dist/chat/vendor/reasoning.d.ts.map +1 -0
  132. package/dist/chat/vendor/reasoning.js +112 -0
  133. package/dist/chat/vendor/reasoning.js.map +1 -0
  134. package/dist/chat/vendor/thread-list.aui.d.ts +37 -0
  135. package/dist/chat/vendor/thread-list.aui.d.ts.map +1 -0
  136. package/dist/chat/vendor/thread-list.aui.js +158 -0
  137. package/dist/chat/vendor/thread-list.aui.js.map +1 -0
  138. package/dist/chat/vendor/thread.aui.d.ts +47 -0
  139. package/dist/chat/vendor/thread.aui.d.ts.map +1 -0
  140. package/dist/chat/vendor/thread.aui.js +176 -0
  141. package/dist/chat/vendor/thread.aui.js.map +1 -0
  142. package/dist/chat/vendor/tool-fallback.aui.d.ts +39 -0
  143. package/dist/chat/vendor/tool-fallback.aui.d.ts.map +1 -0
  144. package/dist/chat/vendor/tool-fallback.aui.js +251 -0
  145. package/dist/chat/vendor/tool-fallback.aui.js.map +1 -0
  146. package/dist/chat/vendor/tool-group.aui.d.ts +34 -0
  147. package/dist/chat/vendor/tool-group.aui.d.ts.map +1 -0
  148. package/dist/chat/vendor/tool-group.aui.js +60 -0
  149. package/dist/chat/vendor/tool-group.aui.js.map +1 -0
  150. package/dist/chat/vendor/tooltip-icon-button.d.ts +8 -0
  151. package/dist/chat/vendor/tooltip-icon-button.d.ts.map +1 -0
  152. package/dist/chat/vendor/tooltip-icon-button.js +11 -0
  153. package/dist/chat/vendor/tooltip-icon-button.js.map +1 -0
  154. package/dist/chat/views/account.d.ts +6 -0
  155. package/dist/chat/views/account.d.ts.map +1 -0
  156. package/dist/chat/views/account.js +128 -0
  157. package/dist/chat/views/account.js.map +1 -0
  158. package/dist/chat/views/settings.d.ts +2 -0
  159. package/dist/chat/views/settings.d.ts.map +1 -0
  160. package/dist/chat/views/settings.js +104 -0
  161. package/dist/chat/views/settings.js.map +1 -0
  162. package/dist/chat/views/thread-list.d.ts +10 -0
  163. package/dist/chat/views/thread-list.d.ts.map +1 -0
  164. package/dist/chat/views/thread-list.js +21 -0
  165. package/dist/chat/views/thread-list.js.map +1 -0
  166. package/dist/chat/welcome.d.ts +10 -0
  167. package/dist/chat/welcome.d.ts.map +1 -0
  168. package/dist/chat/welcome.js +9 -0
  169. package/dist/chat/welcome.js.map +1 -0
  170. package/dist/chat-css.d.ts +1 -0
  171. package/dist/chat-css.js +1 -0
  172. package/dist/chat.css +2 -0
  173. package/dist/chat.isolated.css +3823 -0
  174. package/dist/chat.raw.css +3833 -0
  175. package/dist/index.d.ts +9 -0
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +9 -0
  178. package/dist/index.js.map +1 -1
  179. package/dist/react/T2VProvider.d.ts.map +1 -1
  180. package/dist/react/T2VProvider.js +17 -1
  181. package/dist/react/T2VProvider.js.map +1 -1
  182. package/dist/sessions.d.ts.map +1 -1
  183. package/dist/sessions.js +6 -2
  184. package/dist/sessions.js.map +1 -1
  185. package/package.json +46 -11
@@ -0,0 +1,109 @@
1
+ 'use client';
2
+ /**
3
+ * The launcher's colourway, and whether the visitor has met it before.
4
+ *
5
+ * The three colourways are the brand's own logomark pairings (brand book,
6
+ * "Logo" — each is named for its background):
7
+ *
8
+ * | value | tile | mark |
9
+ * |--------------|--------|--------|
10
+ * | `smoke-teal` | Teal | Smoke |
11
+ * | `teal-smoke` | Smoke | Teal |
12
+ * | `teal-white` | white | Teal |
13
+ *
14
+ * The integrator picks one with `colourway`. With `visitorColourway` they also
15
+ * let the end-user pick, from Settings; that choice is remembered in
16
+ * localStorage and broadcast on a DOM event, so the launcher repaints the moment
17
+ * it changes. The paint itself is in `styles/chat.src.css`, keyed on the
18
+ * `data-launcher-variant` attribute this module's value is written to.
19
+ */
20
+ import { createContext, useContext, useSyncExternalStore } from 'react';
21
+ export const LAUNCHER_COLOURWAYS = ['smoke-teal', 'teal-smoke', 'teal-white'];
22
+ export const DEFAULT_LAUNCHER_COLOURWAY = 'smoke-teal';
23
+ export const LAUNCHER_COLOURWAY_LABELS = {
24
+ 'smoke-teal': 'Smoke on Teal',
25
+ 'teal-smoke': 'Teal on Smoke',
26
+ 'teal-white': 'Teal on white',
27
+ };
28
+ const COLOURWAY_KEY = 't2v-launcher-colourway';
29
+ const COLOURWAY_EVENT = 't2v-launcher-colourway-changed';
30
+ const isColourway = (value) => typeof value === 'string' && LAUNCHER_COLOURWAYS.includes(value);
31
+ /** The visitor's own choice, or null: they have not made one, or cannot. */
32
+ function readColourway() {
33
+ try {
34
+ const stored = localStorage.getItem(COLOURWAY_KEY);
35
+ return isColourway(stored) ? stored : null;
36
+ }
37
+ catch {
38
+ // A private window, or storage the host page has blocked.
39
+ return null;
40
+ }
41
+ }
42
+ function subscribeColourway(onChange) {
43
+ window.addEventListener(COLOURWAY_EVENT, onChange);
44
+ window.addEventListener('storage', onChange); // another tab
45
+ return () => {
46
+ window.removeEventListener(COLOURWAY_EVENT, onChange);
47
+ window.removeEventListener('storage', onChange);
48
+ };
49
+ }
50
+ /** Remember the visitor's choice and repaint every launcher on the page. */
51
+ export function setLauncherColourway(colourway) {
52
+ try {
53
+ localStorage.setItem(COLOURWAY_KEY, colourway);
54
+ }
55
+ catch {
56
+ // Without storage the choice lasts until the page reloads.
57
+ }
58
+ window.dispatchEvent(new Event(COLOURWAY_EVENT));
59
+ }
60
+ /**
61
+ * The colourway to paint: the visitor's, when the integrator allows one, else
62
+ * the integrator's. A remembered choice is ignored — not deleted — when the
63
+ * integrator takes the option away, so turning it back on restores it.
64
+ */
65
+ export function useLauncherColourway(fallback, visitorChoice) {
66
+ const stored = useSyncExternalStore(subscribeColourway, readColourway, () => null);
67
+ return (visitorChoice && stored) || fallback;
68
+ }
69
+ /* The label beside the mark is an introduction, not furniture: once the visitor
70
+ has opened the chat they know what the mark is, and the launcher shrinks back
71
+ to the tile. */
72
+ const OPENED_KEY = 't2v-launcher-opened';
73
+ const OPENED_EVENT = 't2v-launcher-opened-changed';
74
+ function readOpened() {
75
+ try {
76
+ return localStorage.getItem(OPENED_KEY) === '1';
77
+ }
78
+ catch {
79
+ return false;
80
+ }
81
+ }
82
+ function subscribeOpened(onChange) {
83
+ window.addEventListener(OPENED_EVENT, onChange);
84
+ return () => window.removeEventListener(OPENED_EVENT, onChange);
85
+ }
86
+ export function markLauncherOpened() {
87
+ try {
88
+ localStorage.setItem(OPENED_KEY, '1');
89
+ }
90
+ catch {
91
+ // Without storage the label comes back on the next page.
92
+ }
93
+ window.dispatchEvent(new Event(OPENED_EVENT));
94
+ }
95
+ /**
96
+ * True once this visitor has opened the chat. Renders as true on a server, so a
97
+ * returning visitor never sees the label flash in and back out on hydration.
98
+ */
99
+ export function useLauncherOpened() {
100
+ return useSyncExternalStore(subscribeOpened, readOpened, () => true);
101
+ }
102
+ const NO_LAUNCHER = {
103
+ colourway: DEFAULT_LAUNCHER_COLOURWAY,
104
+ visitorColourway: false,
105
+ };
106
+ export const LauncherOptionsContext = createContext(NO_LAUNCHER);
107
+ /** The launcher around this chat. The defaults mean "there isn't one". */
108
+ export const useLauncherOptions = () => useContext(LauncherOptionsContext);
109
+ //# sourceMappingURL=launcher-variant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher-variant.js","sourceRoot":"","sources":["../../../src/chat/lib/launcher-variant.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** The element portals inside the chat render into; null outside a chat. */
2
+ export declare const PortalHostContext: import("react").Context<HTMLElement | null>;
3
+ /**
4
+ * The chat's portal host. Null outside `<Talk2ViewChat>`, which is a valid
5
+ * answer: Base UI reads `container={null}` as "use the default", `<body>`.
6
+ */
7
+ export declare const usePortalHost: () => HTMLElement | null;
8
+ /**
9
+ * Create (or join) this document's portal host. Returns null while rendering on
10
+ * a server, where there is no document and nothing portals anyway.
11
+ */
12
+ export declare function useCreatePortalHost(): HTMLElement | null;
13
+ //# sourceMappingURL=portal-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portal-host.d.ts","sourceRoot":"","sources":["../../../src/chat/lib/portal-host.ts"],"names":[],"mappings":"AAaA,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,6CAA0C,CAAC;AAEzE;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAO,WAAW,GAAG,IAAqC,CAAC;AAmBrF;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,GAAG,IAAI,CAmBxD"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Every popover, tooltip and dialog in the chat is portaled, and a portal
3
+ * defaults to `<body>` — outside the `.t2v-chat` element the whole stylesheet is
4
+ * scoped to, so a portaled popup would render unstyled. The provider keeps one
5
+ * host element in `<body>` that carries the same class, and every portal points
6
+ * at it.
7
+ *
8
+ * One host per document, shared by every chat on the page and removed when the
9
+ * last one unmounts, so a page that mounts and unmounts chats does not
10
+ * accumulate empty divs.
11
+ */
12
+ import { createContext, useContext, useEffect, useState } from 'react';
13
+ /** The element portals inside the chat render into; null outside a chat. */
14
+ export const PortalHostContext = createContext(null);
15
+ /**
16
+ * The chat's portal host. Null outside `<Talk2ViewChat>`, which is a valid
17
+ * answer: Base UI reads `container={null}` as "use the default", `<body>`.
18
+ */
19
+ export const usePortalHost = () => useContext(PortalHostContext);
20
+ const hosts = new WeakMap();
21
+ function ensure(doc) {
22
+ let host = hosts.get(doc);
23
+ if (!host) {
24
+ const el = doc.createElement('div');
25
+ el.className = 't2v-chat t2v-portal-host';
26
+ host = { el, refs: 0 };
27
+ hosts.set(doc, host);
28
+ }
29
+ // Re-attached rather than recreated, so React's StrictMode double-mount (and
30
+ // any host page that empties <body>) gets the same element back.
31
+ if (!host.el.isConnected)
32
+ doc.body.appendChild(host.el);
33
+ return host;
34
+ }
35
+ /**
36
+ * Create (or join) this document's portal host. Returns null while rendering on
37
+ * a server, where there is no document and nothing portals anyway.
38
+ */
39
+ export function useCreatePortalHost() {
40
+ // In the state initialiser, not an effect: a popup can be open on the very
41
+ // first render, and a detached container renders nothing.
42
+ const [el] = useState(() => typeof document === 'undefined' ? null : ensure(document).el);
43
+ useEffect(() => {
44
+ if (!el)
45
+ return;
46
+ const host = ensure(el.ownerDocument);
47
+ host.refs += 1;
48
+ return () => {
49
+ host.refs -= 1;
50
+ if (host.refs <= 0) {
51
+ host.refs = 0;
52
+ host.el.remove();
53
+ }
54
+ };
55
+ }, [el]);
56
+ return el;
57
+ }
58
+ //# sourceMappingURL=portal-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portal-host.js","sourceRoot":"","sources":["../../../src/chat/lib/portal-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEvE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAqB,IAAI,CAAC,CAAC;AAEzE;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAuB,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AAGrF,MAAM,KAAK,GAAG,IAAI,OAAO,EAAkB,CAAC;AAE5C,SAAS,MAAM,CAAC,GAAa;IAC3B,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACpC,EAAE,CAAC,SAAS,GAAG,0BAA0B,CAAC;QAC1C,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,6EAA6E;IAC7E,iEAAiE;IACjE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW;QAAE,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,2EAA2E;IAC3E,0DAA0D;IAC1D,MAAM,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAqB,GAAG,EAAE,CAC7C,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAC7D,CAAC;IACF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QACf,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;YACf,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;gBACd,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;YACnB,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACT,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The chat's markdown renderer: the vendored one, with the links the model
3
+ * writes opened beside the host app instead of navigating it away.
4
+ *
5
+ * The packaged chat's whole premise is that it lives inside somebody else's
6
+ * application — a Word task pane, an ERP dashboard, a partner's SPA. Upstream's
7
+ * `a` renderer emits a bare `<a href>`, so one click on a source the agent cited
8
+ * replaces the host app, taking whatever unsaved state it held with it. The
9
+ * chat already made this call for its own link: the password-reset link in
10
+ * `views/account.tsx` opens in a new tab for exactly this reason, and it applies
11
+ * far more strongly to a link nobody on either side authored.
12
+ *
13
+ * Always, with no prop to turn it off. A same-tab link out of an agent's answer
14
+ * is not something a partner should be able to opt into by accident.
15
+ *
16
+ * This is not an injection guard — there is none to add here. react-markdown's
17
+ * `defaultUrlTransform` is in force (`@assistant-ui/react-markdown` sets no
18
+ * override) and no `rehype-raw` is configured, so `javascript:` hrefs and raw
19
+ * HTML are already neutralised. `rel="noopener noreferrer"` is about the opened
20
+ * page, which must not reach back through `window.opener` or be handed the
21
+ * partner's URL as a referrer.
22
+ *
23
+ * Why the wrapper, and not the vendored file: `src/chat/vendor/*` is
24
+ * hash-pinned and refetched from an unversioned registry, so an edit there is a
25
+ * hunk to reconcile on every bump. Upstream renders `<MarkdownText />` with no
26
+ * components map and offers no other seam, so `sync-registry.mjs` points its two
27
+ * call sites at this file instead — a path rewrite, which needs no reconciling.
28
+ */
29
+ import type { FC } from 'react';
30
+ /** Drop-in for the vendored `MarkdownText`; takes no props, as upstream's use does. */
31
+ export declare const MarkdownText: FC;
32
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/chat/markdown.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAkB,EAAE,EAAE,MAAM,OAAO,CAAC;AAoBhD,uFAAuF;AACvF,eAAO,MAAM,YAAY,EAAE,EAA2D,CAAC"}
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { MarkdownText as VendoredMarkdownText } from './vendor/markdown-text.js';
4
+ import { cn } from './lib/cn.js';
5
+ /**
6
+ * Upstream's own `a` classes, repeated: a component passed in `components`
7
+ * REPLACES the default rather than wrapping it, and the default is not
8
+ * exported. If a bump restyles links in `vendor/markdown-text.tsx`, copy the
9
+ * class list across.
10
+ */
11
+ const LINK_CLASS = 'aui-md-a text-primary hover:text-primary/80 underline underline-offset-2';
12
+ // The spread comes FIRST: `target` and `rel` are the point of this component
13
+ // and nothing coming out of the markdown may displace them.
14
+ const ExternalLink = ({ className, ...props }) => (_jsx("a", { ...props, className: cn(LINK_CLASS, className), target: "_blank", rel: "noopener noreferrer" }));
15
+ const COMPONENTS = { a: ExternalLink };
16
+ /** Drop-in for the vendored `MarkdownText`; takes no props, as upstream's use does. */
17
+ export const MarkdownText = () => _jsx(VendoredMarkdownText, { components: COMPONENTS });
18
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/chat/markdown.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AA+Bb,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,UAAU,GAAG,0EAA0E,CAAC;AAE9F,6EAA6E;AAC7E,4DAA4D;AAC5D,MAAM,YAAY,GAA4B,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC,CACzE,eAAO,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,GAAG,CACjG,CAAC;AAEF,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;AAEvC,uFAAuF;AACvF,MAAM,CAAC,MAAM,YAAY,GAAO,GAAG,EAAE,CAAC,KAAC,oBAAoB,IAAC,UAAU,EAAE,UAAU,GAAI,CAAC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Everything the packaged chat needs, in one place: the Talk2View client, the
3
+ * assistant-ui runtime built on it, the suggestion store, the portal host, and
4
+ * the end-user's own choices from Settings.
5
+ *
6
+ * `<Talk2ViewChat>` and (from Task 6) `<Talk2ViewChatLauncher>` are both this
7
+ * provider plus a different frame around the same shell.
8
+ */
9
+ import { type ReactNode } from 'react';
10
+ import { Talk2View } from '../index.js';
11
+ import type { ClientTool, ClientToolSchema, PartnerConfig, T2VConfig } from '../types.js';
12
+ import { type GuestLimits } from './auth-gate.js';
13
+ import { type DictationPhaseStore } from './lib/dictation-phase.js';
14
+ /** The opening screen: a heading and the openers offered under the composer. */
15
+ export interface Talk2ViewChatWelcome {
16
+ heading?: string;
17
+ suggestions?: string[];
18
+ }
19
+ /**
20
+ * Built-in views, all on by default. `dictation` also needs a browser
21
+ * microphone: without one the voice button never appears.
22
+ */
23
+ export interface Talk2ViewChatFeatures {
24
+ dictation?: boolean;
25
+ attachments?: boolean;
26
+ settings?: boolean;
27
+ account?: boolean;
28
+ threadList?: boolean;
29
+ }
30
+ export interface Talk2ViewChatProps extends Omit<T2VConfig, 'partnerKey'> {
31
+ /** Either give the config (a client is created for you) … */
32
+ partnerKey?: string;
33
+ /** … or an existing client (e.g. shared with the rest of the app). */
34
+ client?: Talk2View;
35
+ tools?: (ClientToolSchema | ClientTool)[];
36
+ /**
37
+ * Your own instructions, sent with every message — the same prop `/ui` and
38
+ * `/assistant-ui` take. It is a runtime option, not part of `T2VConfig`, so
39
+ * changing it does not rebuild the client or drop the conversation.
40
+ */
41
+ systemPrompt?: string;
42
+ welcome?: Talk2ViewChatWelcome;
43
+ /**
44
+ * Logged-out visitors chat as guests (default true). false → sign-in first:
45
+ * the Account view replaces the thread, and no guest session is started.
46
+ */
47
+ allowAnonymous?: boolean;
48
+ features?: Talk2ViewChatFeatures;
49
+ /** The host's own font stack, e.g. '"Space Grotesk", sans-serif'. Default: inherit. */
50
+ fontFamily?: string;
51
+ /** Where "Forgot it?" sends people. Default: none (the link is left out). */
52
+ resetPasswordUrl?: string;
53
+ /** A short line under the composer, e.g. terms. */
54
+ footer?: ReactNode;
55
+ /**
56
+ * Tool approvals. `describeToolActivity` names what a running tool is doing
57
+ * ("Inserting 240 characters"); `isToolDestructive` marks a call that changes
58
+ * the end-user's work, and `destructiveWarning` replaces the warning shown
59
+ * above the approval buttons when it does.
60
+ */
61
+ describeToolActivity?: (name: string, args?: Record<string, unknown>) => string | null;
62
+ isToolDestructive?: (name: string, args?: Record<string, unknown>) => boolean;
63
+ destructiveWarning?: (name: string, activity: string | null) => ReactNode;
64
+ className?: string;
65
+ }
66
+ /**
67
+ * The props a slot component cannot be handed directly (assistant-ui's
68
+ * `components={{ ToolFallback }}` takes a component, not a closure), read
69
+ * through a ref so adding one does not re-render the whole chat.
70
+ */
71
+ export interface Talk2ViewChatBehaviour {
72
+ allowAnonymous: boolean;
73
+ resetPasswordUrl?: string | undefined;
74
+ describeToolActivity?: Talk2ViewChatProps['describeToolActivity'];
75
+ isToolDestructive?: Talk2ViewChatProps['isToolDestructive'];
76
+ destructiveWarning?: Talk2ViewChatProps['destructiveWarning'];
77
+ }
78
+ export interface Talk2ViewChatContextValue {
79
+ client: Talk2View;
80
+ /** The partner's defaults, shown as "Default — …" in Settings. Null until loaded. */
81
+ config: PartnerConfig | null;
82
+ features: Required<Talk2ViewChatFeatures>;
83
+ welcome: Talk2ViewChatWelcome;
84
+ /** Where portaled popups render. Null only while rendering on a server. */
85
+ portalHost: HTMLElement | null;
86
+ /**
87
+ * Whether a guest has been turned away. Tracked here rather than in the view
88
+ * that shows the sign-in, because the launcher's panel is unmounted when the
89
+ * refusal arrives.
90
+ */
91
+ limits: GuestLimits;
92
+ dictation: DictationPhaseStore;
93
+ /**
94
+ * Whether the integrator asked for dark mode, i.e. `className` carries
95
+ * `dark`. Read by anything that renders OUTSIDE the chat's own element — see
96
+ * the portal-host effect below.
97
+ */
98
+ dark: boolean;
99
+ /** Always the latest render's values; stable identity. */
100
+ behaviour: {
101
+ readonly current: Talk2ViewChatBehaviour;
102
+ };
103
+ }
104
+ /** `dark` as a whole word, so `darkroom-theme` is not dark mode. */
105
+ export declare function hasDarkClass(className: string | undefined): boolean;
106
+ export declare function useChatContext(): Talk2ViewChatContextValue;
107
+ /** The client behind the chat, for the host's own UI (sign-out buttons and the like). */
108
+ export declare function useTalk2ViewChatClient(): Talk2View;
109
+ export interface ChatProviderProps extends Talk2ViewChatProps {
110
+ children: ReactNode;
111
+ }
112
+ export declare function ChatProvider({ children, ...props }: ChatProviderProps): ReactNode;
113
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/chat/provider.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI1F,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/F,gFAAgF;AAChF,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;IACvE,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,gBAAgB,GAAG,UAAU,CAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mDAAmD;IACnD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,IAAI,CAAC;IACvF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IAC9E,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,oBAAoB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;IAClE,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;IAC5D,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,SAAS,CAAC;IAClB,qFAAqF;IACrF,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAC1C,OAAO,EAAE,oBAAoB,CAAC;IAC9B,2EAA2E;IAC3E,UAAU,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/B;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,mBAAmB,CAAC;IAC/B;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,0DAA0D;IAC1D,SAAS,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAA;KAAE,CAAC;CACzD;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEnE;AAID,wBAAgB,cAAc,IAAI,yBAAyB,CAM1D;AAED,yFAAyF;AACzF,wBAAgB,sBAAsB,IAAI,SAAS,CAElD;AAYD,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,GAAG,SAAS,CA4JjF"}
@@ -0,0 +1,176 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Everything the packaged chat needs, in one place: the Talk2View client, the
5
+ * assistant-ui runtime built on it, the suggestion store, the portal host, and
6
+ * the end-user's own choices from Settings.
7
+ *
8
+ * `<Talk2ViewChat>` and (from Task 6) `<Talk2ViewChatLauncher>` are both this
9
+ * provider plus a different frame around the same shell.
10
+ */
11
+ import { createContext, useContext, useEffect, useMemo, useRef, useState, } from 'react';
12
+ import { AssistantRuntimeProvider, AuiProvider, Suggestions, useAui } from '@assistant-ui/react';
13
+ import { Talk2View } from '../index.js';
14
+ import { useTalk2ViewRuntimeForClient } from '../assistant-ui/index.js';
15
+ import { useUserPreferences } from '../react/useUserPreferences.js';
16
+ import { assertOneAssistantUi } from './lib/guard.js';
17
+ import { useGuestLimits } from './auth-gate.js';
18
+ import { PortalHostContext, useCreatePortalHost } from './lib/portal-host.js';
19
+ import { createDictationPhaseStore } from './lib/dictation-phase.js';
20
+ /** `dark` as a whole word, so `darkroom-theme` is not dark mode. */
21
+ export function hasDarkClass(className) {
22
+ return !!className && /(^|\s)dark(\s|$)/.test(className);
23
+ }
24
+ const ChatContext = createContext(null);
25
+ export function useChatContext() {
26
+ const value = useContext(ChatContext);
27
+ if (!value) {
28
+ throw new Error('This component must be rendered inside <Talk2ViewChat>.');
29
+ }
30
+ return value;
31
+ }
32
+ /** The client behind the chat, for the host's own UI (sign-out buttons and the like). */
33
+ export function useTalk2ViewChatClient() {
34
+ return useChatContext().client;
35
+ }
36
+ const FEATURE_DEFAULTS = {
37
+ dictation: true,
38
+ attachments: true,
39
+ settings: true,
40
+ account: true,
41
+ threadList: true,
42
+ };
43
+ const NO_WELCOME = {};
44
+ export function ChatProvider({ children, ...props }) {
45
+ assertOneAssistantUi();
46
+ const { client: givenClient, partnerKey, tools, systemPrompt, welcome = NO_WELCOME, features: givenFeatures, allowAnonymous = true, resetPasswordUrl, describeToolActivity, isToolDestructive, destructiveWarning,
47
+ // Not connection options: `fontFamily`, `footer` and `className` belong to
48
+ // the frame, and the rest of `props` is T2VConfig.
49
+ fontFamily: _fontFamily, footer: _footer, className, ...config } = props;
50
+ if (!givenClient && !partnerKey) {
51
+ throw new Error('<Talk2ViewChat> needs either a partnerKey or a client.');
52
+ }
53
+ // `allowAnonymous: false` has to reach the client, not just the view: the gate
54
+ // is computed from whether anyone is signed in, and a guest session started
55
+ // behind it — by listing the models for Settings, say — would open it. An
56
+ // explicit `anonymousAutoStart` still wins; this only fills in the default.
57
+ const anonymousAutoStart = config.anonymousAutoStart ?? allowAnonymous;
58
+ // A new client only when the connection details change. `model` is not one of
59
+ // them: it travels with each message, so an end-user can switch models in
60
+ // Settings without losing the conversation.
61
+ //
62
+ // React invokes this factory TWICE per mount under StrictMode and keeps only
63
+ // one of the two clients, so it must leave nothing behind: `new Talk2View()`
64
+ // registers two `window` listeners for auth, and the instance React discards
65
+ // is unreachable from the effect below and could never take them off again.
66
+ // So every client built here starts asleep and the effect wakes the survivor.
67
+ // Nothing outside the instance can tell the difference — auth events only
68
+ // matter to a mounted chat, and the gap is one commit long.
69
+ const client = useMemo(() => {
70
+ if (givenClient)
71
+ return givenClient;
72
+ const made = new Talk2View({ ...config, anonymousAutoStart, partnerKey: partnerKey });
73
+ made.auth.destroy();
74
+ return made;
75
+ // eslint-disable-next-line react-hooks/exhaustive-deps
76
+ }, [givenClient, partnerKey, config.baseUrl, config.debug, anonymousAutoStart]);
77
+ const ours = client !== givenClient;
78
+ const features = useMemo(() => ({ ...FEATURE_DEFAULTS, ...givenFeatures }), [givenFeatures]);
79
+ const [partnerConfig, setPartnerConfig] = useState(null);
80
+ useEffect(() => {
81
+ let live = true;
82
+ // Single-flighted and cached by the client, so Settings asking again is free.
83
+ // A brand-new visitor has no session yet and this 401s; Settings retries
84
+ // once the model list has started a guest session.
85
+ client
86
+ .getConfig()
87
+ .then((value) => live && value && setPartnerConfig(value))
88
+ .catch(() => { });
89
+ return () => {
90
+ live = false;
91
+ };
92
+ }, [client]);
93
+ const dictation = useMemo(() => createDictationPhaseStore(), []);
94
+ const { preferences } = useUserPreferences();
95
+ const runtime = useTalk2ViewRuntimeForClient(client, {
96
+ systemPrompt,
97
+ tools,
98
+ // The end-user's choice from Settings; empty means the partner's default.
99
+ model: preferences.model || undefined,
100
+ attachments: features.attachments,
101
+ dictation: features.dictation && {
102
+ model: preferences.sttModel || undefined,
103
+ language: preferences.sttLanguage || undefined,
104
+ // assistant-ui has no surface for a dictation failure; at least leave a trace.
105
+ onError: (error) => console.warn('[Talk2View] Dictation failed:', error),
106
+ onPhaseChange: dictation.set,
107
+ },
108
+ });
109
+ // After the runtime hook, so its subscriptions are torn down before the
110
+ // client we own is destroyed. A client the integrator passed in is theirs.
111
+ //
112
+ // Setup wakes it and cleanup puts it back to sleep, both ways round and any
113
+ // number of times: StrictMode runs this as setup → cleanup → setup, and a
114
+ // cleanup that only tore listeners off would leave the surviving client deaf
115
+ // to cross-tab sign-out and to `clearAuth()` for the rest of the session.
116
+ useEffect(() => {
117
+ if (!ours)
118
+ return;
119
+ client.auth.listen();
120
+ return () => client.destroy();
121
+ }, [client, ours]);
122
+ const portalHost = useCreatePortalHost();
123
+ const limits = useGuestLimits(client);
124
+ // Dark mode is `dark` on the chat's container, and every token it redefines
125
+ // is declared on `.t2v-chat.dark`. But tooltips, dialogs and the launcher's
126
+ // own panel do not render inside that element — they render in the portal
127
+ // host, a sibling of the chat in <body> — so a dark chat was opening a white
128
+ // panel and showing light-themed tooltips. The class has to travel with them.
129
+ //
130
+ // One portal host serves every chat on the page: two chats with different
131
+ // themes would share whichever was set last. Nobody does that today, and the
132
+ // alternative is a host per chat.
133
+ const dark = hasDarkClass(className);
134
+ useEffect(() => {
135
+ if (!portalHost)
136
+ return;
137
+ portalHost.classList.toggle('dark', dark);
138
+ return () => portalHost.classList.remove('dark');
139
+ }, [portalHost, dark]);
140
+ const behaviour = useRef({ allowAnonymous });
141
+ behaviour.current = {
142
+ allowAnonymous,
143
+ resetPasswordUrl,
144
+ describeToolActivity,
145
+ isToolDestructive,
146
+ destructiveWarning,
147
+ };
148
+ const value = useMemo(() => ({
149
+ client,
150
+ config: partnerConfig,
151
+ features,
152
+ welcome,
153
+ portalHost,
154
+ limits,
155
+ dictation,
156
+ dark,
157
+ behaviour,
158
+ }), [client, partnerConfig, features, welcome, portalHost, limits, dictation, dark]);
159
+ return (_jsx(ChatContext.Provider, { value: value, children: _jsx(PortalHostContext.Provider, { value: portalHost, children: _jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(SuggestionStore, { suggestions: welcome.suggestions, children: children }) }) }) }));
160
+ }
161
+ /**
162
+ * The openers the thread shows under the composer on an empty chat. Inside the
163
+ * runtime provider, so they attach to this chat's store and not another's.
164
+ */
165
+ function SuggestionStore({ suggestions, children, }) {
166
+ // Joined on a character that cannot occur in an opener, so two different
167
+ // lists can never produce the same key. Written as the escape, not as a
168
+ // literal NUL byte: one of those makes the whole file binary to grep, git and
169
+ // half the editors that open it.
170
+ const key = suggestions?.join('\0') ?? '';
171
+ const aui = useAui(
172
+ // eslint-disable-next-line react-hooks/exhaustive-deps
173
+ useMemo(() => (suggestions?.length ? { suggestions: Suggestions(suggestions) } : {}), [key]));
174
+ return _jsx(AuiProvider, { value: aui, children: children });
175
+ }
176
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/chat/provider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * How every tool call looks in the packaged chat — one component, no tool names
3
+ * hard-coded, passed to the thread as `components={{ ToolFallback }}`.
4
+ *
5
+ * Three states:
6
+ * - running — an activity row: what the host says the agent is doing
7
+ * (`describeToolActivity`) and how long it has been at it;
8
+ * - waiting on the end-user — the approval card: allow once, always allow, or
9
+ * deny with a reason, with the arguments editable first, and a warning above
10
+ * the buttons for a tool the host marks as changing the end-user's work;
11
+ * - finished — the collapsed "Used tool" line, opening to the arguments and the
12
+ * result.
13
+ *
14
+ * Two things worth knowing before restyling the card:
15
+ * - Edited arguments apply to THIS call only. "Always allow" skips the card for
16
+ * later calls, which then run with whatever the agent proposes — so the card
17
+ * does not offer it while the arguments are edited.
18
+ * - Decisions go straight to the Talk2View client (`approveToolCall`), not
19
+ * through assistant-ui's approval seam, because that seam carries a decision
20
+ * and a reason but not changed input.
21
+ */
22
+ import { type ReactNode } from 'react';
23
+ import { type ToolCallMessagePartComponent } from '@assistant-ui/react';
24
+ import type { ThreadGroupPart } from './vendor/thread.aui.js';
25
+ export declare const ToolFallback: ToolCallMessagePartComponent;
26
+ /**
27
+ * The run of tool calls in one assistant turn, as a single "2 tool calls" line.
28
+ *
29
+ * Upstream's group starts closed and stays closed, which is right for a finished
30
+ * turn and wrong for a live one: an approval card inside a closed group leaves
31
+ * the end-user looking at "1 tool call" while the agent waits on them, with
32
+ * nothing to say a decision is needed. This opens the group while the run is
33
+ * under way and leaves whatever the end-user last chose standing once it settles.
34
+ */
35
+ export declare function ToolGroup({ group, children, }: {
36
+ group: ThreadGroupPart;
37
+ children?: ReactNode;
38
+ }): ReactNode;
39
+ //# sourceMappingURL=tool-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-fallback.d.ts","sourceRoot":"","sources":["../../src/chat/tool-fallback.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAyD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9F,OAAO,EAEL,KAAK,4BAA4B,EAElC,MAAM,qBAAqB,CAAC;AAW7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAuB9D,eAAO,MAAM,YAAY,EAAE,4BAU1B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GAAG,SAAS,CAgBZ"}