@alexkroman1/aai-ui 5.13.1 → 5.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chat-view-DadZOvJO.js → chat-view-CgFytvGy.js} +3 -3
- package/dist/components/auto-scroll.d.ts +63 -0
- package/dist/components/chat-view.js +1 -1
- package/dist/components/controls.js +1 -1
- package/dist/components/message-list.js +1 -1
- package/dist/components/start-screen.js +1 -1
- package/dist/components/tool-call-block.js +1 -1
- package/dist/default-client/assets/{audio-BAAzYW28.js → audio-CsQVQn3f.js} +1 -1
- package/dist/default-client/assets/{capture-processor-vx5IW_Rd.js → capture-processor-B_5Ive8e.js} +1 -1
- package/dist/default-client/assets/{index-Cn-zI5ic.js → index-D35_z2WM.js} +26 -26
- package/dist/default-client/assets/index-DCjB3qtb.css +2 -0
- package/dist/default-client/assets/{playback-processor-2p9HLz_W.js → playback-processor-6L8SIQ_l.js} +1 -1
- package/dist/default-client/index.html +2 -2
- package/dist/define-client.js +4 -4
- package/dist/hooks.d.ts +30 -0
- package/dist/hooks.js +4 -26
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -6
- package/dist/{message-list-YdLocGoT.js → message-list-CcjgWRVZ.js} +90 -26
- package/dist/{session-core-BoB7kTzL.js → session-core-BA8H3qtF.js} +38 -15
- package/dist/session-core-types.d.ts +22 -0
- package/dist/session-core.js +1 -1
- package/package.json +2 -2
- package/dist/default-client/assets/index-Ctjrde3-.css +0 -2
- package/dist/{aai-logo-B8lDmsut.js → aai-logo-9xRBGVFl.js} +1 -1
- package/dist/{controls-DzQEKq9c.js → controls-Cy_YVfsa.js} +1 -1
- package/dist/{tool-call-block-CAscLGFy.js → tool-call-block-CrLN7xlI.js} +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { t as MessageList } from "./message-list-CcjgWRVZ.js";
|
|
1
2
|
import { useSessionSelector, useTheme } from "./context.js";
|
|
2
3
|
import { n as THINKING_COLOR, r as inkTint, t as ERROR_COLOR } from "./_colors-CcAi2FOU.js";
|
|
3
|
-
import { t as AaiLogo } from "./aai-logo-
|
|
4
|
+
import { t as AaiLogo } from "./aai-logo-9xRBGVFl.js";
|
|
4
5
|
import { t as Eyebrow } from "./eyebrow-C6ZFuiz6.js";
|
|
5
|
-
import { t as Controls } from "./controls-
|
|
6
|
-
import { t as MessageList } from "./message-list-YdLocGoT.js";
|
|
6
|
+
import { t as Controls } from "./controls-Cy_YVfsa.js";
|
|
7
7
|
import clsx from "clsx";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
//#region components/console-shell.tsx
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* A scroll container that stays pinned to the bottom as its content grows,
|
|
4
|
+
* releases when the reader scrolls up, and re-engages once they return to the
|
|
5
|
+
* bottom.
|
|
6
|
+
*
|
|
7
|
+
* For clients that render their own chat chrome instead of using
|
|
8
|
+
* {@link MessageList} — a terminal, a dispatch board, a themed transcript.
|
|
9
|
+
* `MessageList` already behaves this way; this is the same mechanism with no
|
|
10
|
+
* opinion about what goes inside it.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* The pattern this replaces is a `useEffect` that calls
|
|
14
|
+
* `ref.current?.scrollIntoView()` on every message change. That version has
|
|
15
|
+
* three faults, and they compound: it fights the reader, since scrolling up to
|
|
16
|
+
* re-read is undone by the next transcript delta; it misses growth that is not
|
|
17
|
+
* a new message, because a streamed reply, an expanding tool block or a
|
|
18
|
+
* markdown reflow changes height without changing the dependency array; and it
|
|
19
|
+
* needs a synthetic dependency (`messages.length + transcript.length`) to fire
|
|
20
|
+
* at all, which is where the dead `if (version < 0) return;` line comes from.
|
|
21
|
+
* A `ResizeObserver` on the content — what this uses — has none of those.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* import { AutoScroll, useSession } from "@alexkroman1/aai-ui";
|
|
26
|
+
*
|
|
27
|
+
* function Transcript() {
|
|
28
|
+
* const session = useSession();
|
|
29
|
+
* return (
|
|
30
|
+
* <AutoScroll className="flex-1 min-h-0" contentClassName="flex flex-col gap-2 p-4">
|
|
31
|
+
* {session.messages.map((m) => (
|
|
32
|
+
* <div key={m.id}>{m.content}</div>
|
|
33
|
+
* ))}
|
|
34
|
+
* </AutoScroll>
|
|
35
|
+
* );
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @param children - The scrollable content.
|
|
40
|
+
* @param className - Classes for the outer container. It must be given a
|
|
41
|
+
* bounded height (`flex-1 min-h-0`, `h-full`, a fixed height) — an unbounded
|
|
42
|
+
* one grows with its content and never scrolls, so nothing pins.
|
|
43
|
+
* @param contentClassName - Classes for the inner content element, where
|
|
44
|
+
* padding and the children's own layout belong.
|
|
45
|
+
* @param scrollClassName - Classes for the scrolling element itself. Defaults
|
|
46
|
+
* to hiding the scrollbar; pass `"overflow-y-auto"` to show a native one.
|
|
47
|
+
* @param style - Inline styles for the outer container.
|
|
48
|
+
* @param initial - Scroll behavior on mount. Defaults to `"instant"` (start at
|
|
49
|
+
* the latest content without animating a scroll the reader did not ask for).
|
|
50
|
+
* @param resize - Scroll behavior when pinned content grows. Defaults to
|
|
51
|
+
* `"smooth"`.
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
export declare function AutoScroll({ children, className, contentClassName, scrollClassName, style, initial, resize, }: {
|
|
56
|
+
children: ReactNode;
|
|
57
|
+
className?: string | undefined;
|
|
58
|
+
contentClassName?: string | undefined;
|
|
59
|
+
scrollClassName?: string | undefined;
|
|
60
|
+
style?: CSSProperties | undefined;
|
|
61
|
+
initial?: "instant" | "smooth" | undefined;
|
|
62
|
+
resize?: "instant" | "smooth" | undefined;
|
|
63
|
+
}): ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useSessionCore, useSessionSelector, useTheme } from "../context.js";
|
|
2
2
|
import { r as inkTint } from "../_colors-CcAi2FOU.js";
|
|
3
3
|
import { Button } from "./button.js";
|
|
4
|
-
import { t as AaiLogo } from "../aai-logo-
|
|
4
|
+
import { t as AaiLogo } from "../aai-logo-9xRBGVFl.js";
|
|
5
5
|
import { t as Eyebrow } from "../eyebrow-C6ZFuiz6.js";
|
|
6
6
|
import clsx from "clsx";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,o as t,t as n}from"./index-
|
|
1
|
+
import{a as e,o as t,t as n}from"./index-D35_z2WM.js";function r(e,t,n){if(e!==t)throw Error(`Browser refused the ${n} sample rate: asked for ${t} Hz, got ${e} Hz`)}function i(e){e.then(e=>{for(let t of e.getTracks())t.stop()}).catch(()=>{})}function a(e,t,n){let r=new AudioWorkletNode(e,`capture-processor`,{channelCount:1,channelCountMode:`explicit`}),i=null;return r.port.onmessage=e=>{let r=e.data;r.event===`chunk`&&r.buffer?t(r.buffer):r.event===`silent`?n?.():r.event===`stopped`&&(i?.(),i=null)},{node:r,start(){r.port.postMessage({event:`start`})},stop(){return new Promise(e=>{let t=setTimeout(e,250);i=()=>{clearTimeout(t),e()},r.port.postMessage({event:`stop`})})}}}async function o(o){let{sttSampleRate:s,ttsSampleRate:c,captureWorkletSrc:l,playbackWorkletSrc:u,onMicData:d,onError:f,onPlaybackStats:p,onPlaybackProgress:m,onMicSilent:h}=o,g=new AudioContext({sampleRate:c,latencyHint:`playback`}),_=s===c,v=_?g:new AudioContext({sampleRate:s,latencyHint:`interactive`});async function y(){let e=_?[g]:[g,v];await Promise.all(e.map(e=>e.close().catch(e=>{console.warn(`AudioContext close failed:`,e)})))}let b=navigator.mediaDevices.getUserMedia({audio:{deviceId:{ideal:`default`},...n}}),x;try{[x]=await Promise.all([b,g.resume(),v.resume(),v.audioWorklet.addModule(l),g.audioWorklet.addModule(u)]),r(v.sampleRate,s,`capture`),r(g.sampleRate,c,`playback`)}catch(e){throw i(b),await y(),e}let S=v.createMediaStreamSource(x),C=a(v,d,h);S.connect(C.node),C.node.onprocessorerror=()=>{let e=Error(`Audio capture worklet crashed`);console.error(`[aai-ui]`,e.message),f?.(e)},C.start();let w=null,T=null,E=0,D=null,O=new AbortController;function k(){T?.(),T=null,D=null}function A(e){e.stats&&e.stats.concealedSamples>0&&p?.(e.stats),e.reason!==`interrupt`&&(D!==null&&e.turn!==D||k())}function j(){if(w)return w;let e=new AudioWorkletNode(g,`playback-processor`);return e.connect(g.destination),e.port.onmessage=e=>{e.data.event===`stop`?A(e.data):e.data.event===`progress`&&m?.(e.data.bufferedMs)},e.onprocessorerror=()=>{let e=Error(`Audio playback worklet crashed`);console.error(`[aai-ui]`,e.message),k(),f?.(e)},w=e,e}let M={enqueue(e){O.signal.aborted||e.byteLength!==0&&j().port.postMessage({event:`write`,buffer:new Uint8Array(e)},[e])},done(){if(!w)return Promise.resolve();let n=++E;return w.port.postMessage({event:`done`,turn:n}),g.state===`running`?new Promise(r=>{T?.();let i=()=>{clearInterval(a),clearTimeout(o),T===i&&(T=null,D=null),r()},a=setInterval(()=>{g.state!==`running`&&i()},t),o=setTimeout(i,e);T=i,D=n}):(D=null,Promise.resolve())},flush(){w&&(k(),w.port.postMessage({event:`interrupt`}))},async close(){if(!O.signal.aborted){O.abort(),await C.stop(),S.disconnect(),C.node.disconnect(),w&&w.disconnect();for(let e of x.getTracks())e.stop();await y()}},async[Symbol.asyncDispose](){await M.close()}};return M}export{o as createVoiceIO};
|
package/dist/default-client/assets/{capture-processor-vx5IW_Rd.js → capture-processor-B_5Ive8e.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e,r as t}from"./index-
|
|
1
|
+
import{n as e,r as t}from"./index-D35_z2WM.js";import{t as n}from"./_module-url-BX0RuRU2.js";var r=n(`
|
|
2
2
|
class CaptureProcessor extends AudioWorkletProcessor {
|
|
3
3
|
constructor(options) {
|
|
4
4
|
super();
|