@alexkroman1/aai-ui 0.12.2 → 1.0.2

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 (68) hide show
  1. package/dist/_react-test-utils.d.ts +86 -0
  2. package/dist/audio.js +4 -5
  3. package/dist/build-default-client.d.ts +1 -0
  4. package/dist/{_components → components}/button.d.ts +4 -4
  5. package/dist/{_components → components}/button.js +28 -5
  6. package/dist/components/chat-view.d.ts +38 -0
  7. package/dist/components/chat-view.js +102 -0
  8. package/dist/{_components → components}/controls.d.ts +1 -1
  9. package/dist/{_components → components}/controls.js +8 -5
  10. package/dist/{_components → components}/message-list.d.ts +2 -2
  11. package/dist/components/message-list.js +149 -0
  12. package/dist/components/sidebar-layout.d.ts +21 -0
  13. package/dist/components/sidebar-layout.js +43 -0
  14. package/dist/{_components → components}/start-screen.d.ts +4 -4
  15. package/dist/{_components → components}/start-screen.js +17 -8
  16. package/dist/{_components → components}/tool-call-block.d.ts +5 -6
  17. package/dist/components/tool-call-block.js +3 -0
  18. package/dist/components/tool-config-context.d.ts +22 -0
  19. package/dist/context.d.ts +23 -0
  20. package/dist/context.js +39 -0
  21. package/dist/default-client/assets/audio-DH9LpexG.js +1 -0
  22. package/dist/default-client/assets/capture-processor-C26lSiVr.js +53 -0
  23. package/dist/default-client/assets/default-client-AeJhjHfj.js +49 -0
  24. package/dist/default-client/assets/default-client-BK1ItCvw.css +2 -0
  25. package/dist/default-client/assets/playback-processor-dSA8Im99.js +101 -0
  26. package/dist/default-client/default-client.html +15 -0
  27. package/dist/default-client.d.ts +2 -0
  28. package/dist/define-client.d.ts +72 -24
  29. package/dist/define-client.js +71 -45
  30. package/dist/hooks.d.ts +5 -0
  31. package/dist/hooks.js +55 -0
  32. package/dist/index.d.ts +15 -37
  33. package/dist/index.js +11 -18
  34. package/dist/session-core.d.ts +70 -0
  35. package/dist/session-core.js +437 -0
  36. package/dist/tool-call-block-CCuChsFm.js +131 -0
  37. package/dist/types.d.ts +19 -22
  38. package/package.json +24 -18
  39. package/styles.css +3 -33
  40. package/dist/_components/app.d.ts +0 -23
  41. package/dist/_components/app.js +0 -41
  42. package/dist/_components/chat-view.d.ts +0 -29
  43. package/dist/_components/chat-view.js +0 -61
  44. package/dist/_components/error-banner.d.ts +0 -21
  45. package/dist/_components/error-banner.js +0 -27
  46. package/dist/_components/message-bubble.d.ts +0 -23
  47. package/dist/_components/message-bubble.js +0 -35
  48. package/dist/_components/message-list.js +0 -76
  49. package/dist/_components/sidebar-layout.d.ts +0 -21
  50. package/dist/_components/sidebar-layout.js +0 -36
  51. package/dist/_components/state-indicator.d.ts +0 -29
  52. package/dist/_components/state-indicator.js +0 -37
  53. package/dist/_components/thinking-indicator.d.ts +0 -16
  54. package/dist/_components/thinking-indicator.js +0 -34
  55. package/dist/_components/tool-call-block.js +0 -118
  56. package/dist/_components/tool-icons.d.ts +0 -17
  57. package/dist/_components/tool-icons.js +0 -128
  58. package/dist/_components/transcript.d.ts +0 -25
  59. package/dist/_components/transcript.js +0 -35
  60. package/dist/client-context.d.ts +0 -33
  61. package/dist/client-context.js +0 -15
  62. package/dist/client-handler.d.ts +0 -43
  63. package/dist/session-CWB7vmqz.js +0 -429
  64. package/dist/session.d.ts +0 -69
  65. package/dist/session.js +0 -2
  66. package/dist/signals.d.ts +0 -120
  67. package/dist/signals.js +0 -161
  68. package/dist/types.test-d.d.ts +0 -7
@@ -1,12 +1,11 @@
1
- import type * as preact from "preact";
1
+ import { type ReactNode } from "react";
2
2
  import type { ToolCallInfo } from "../types.ts";
3
3
  /**
4
- * Renders a tool invocation with an icon, title, subtitle, and a
4
+ * Renders a tool invocation with an optional icon/emoji, title, subtitle, and a
5
5
  * collapsible result viewer.
6
6
  *
7
- * Built-in tool types (`web_search`, `visit_webpage`, `run_code`,
8
- * `fetch_json`, `user_input`) get custom icons and labels. Unknown tools
9
- * fall back to a generic bolt icon.
7
+ * Tool display is configured via `ToolConfigContext`. If no config is found
8
+ * for a tool name, the raw tool name is shown as the title.
10
9
  *
11
10
  * While the tool call is pending a shimmer animation is shown. Once
12
11
  * complete, clicking the block expands the formatted JSON result.
@@ -24,4 +23,4 @@ import type { ToolCallInfo } from "../types.ts";
24
23
  export declare function ToolCallBlock({ toolCall, className, }: {
25
24
  toolCall: ToolCallInfo;
26
25
  className?: string;
27
- }): preact.JSX.Element;
26
+ }): ReactNode;
@@ -0,0 +1,3 @@
1
+ import "../context.js";
2
+ import { t as ToolCallBlock } from "../tool-call-block-CCuChsFm.js";
3
+ export { ToolCallBlock };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Display configuration for a tool call in the UI.
3
+ *
4
+ * @public
5
+ */
6
+ export type ToolDisplayConfig = Record<string, {
7
+ icon?: string;
8
+ label?: string;
9
+ }>;
10
+ /**
11
+ * Context for tool display configuration.
12
+ * Provided by `client` or manually via `ToolConfigContext.Provider`.
13
+ *
14
+ * @public
15
+ */
16
+ export declare const ToolConfigContext: import("react").Context<ToolDisplayConfig>;
17
+ /**
18
+ * Read tool display configuration from the nearest `ToolConfigContext.Provider`.
19
+ *
20
+ * @internal
21
+ */
22
+ export declare function useToolConfig(): ToolDisplayConfig;
@@ -0,0 +1,23 @@
1
+ import { type ReactNode } from "react";
2
+ import type { SessionCore, SessionSnapshot } from "./session-core.ts";
3
+ import type { ClientTheme } from "./types.ts";
4
+ declare const DEFAULT_THEME: Required<ClientTheme>;
5
+ export declare function SessionProvider({ value, children }: {
6
+ value: SessionCore;
7
+ children?: ReactNode;
8
+ }): import("react").FunctionComponentElement<import("react").ProviderProps<SessionCore | null>>;
9
+ export type Session = SessionSnapshot & {
10
+ start(): void;
11
+ cancel(): void;
12
+ resetState(): void;
13
+ reset(): void;
14
+ disconnect(): void;
15
+ toggle(): void;
16
+ };
17
+ export declare function useSession(): Session;
18
+ export declare function ThemeProvider({ value, children }: {
19
+ value?: ClientTheme;
20
+ children?: ReactNode;
21
+ }): import("react").FunctionComponentElement<import("react").ProviderProps<Required<ClientTheme>>>;
22
+ export declare function useTheme(): Required<ClientTheme>;
23
+ export { DEFAULT_THEME };
@@ -0,0 +1,39 @@
1
+ import { createContext, createElement, useContext, useSyncExternalStore } from "react";
2
+ //#region context.ts
3
+ const DEFAULT_THEME = {
4
+ bg: "#101010",
5
+ primary: "#fab283",
6
+ text: "rgba(255, 255, 255, 0.94)",
7
+ surface: "#151515",
8
+ border: "#282828"
9
+ };
10
+ const SessionCtx = createContext(null);
11
+ function SessionProvider({ value, children }) {
12
+ return createElement(SessionCtx.Provider, { value }, children);
13
+ }
14
+ function useSession() {
15
+ const core = useContext(SessionCtx);
16
+ if (!core) throw new Error("useSession must be used within <SessionProvider>");
17
+ return {
18
+ ...useSyncExternalStore(core.subscribe, core.getSnapshot),
19
+ start: core.start,
20
+ cancel: core.cancel,
21
+ resetState: core.resetState,
22
+ reset: core.reset,
23
+ disconnect: core.disconnect,
24
+ toggle: core.toggle
25
+ };
26
+ }
27
+ const ThemeCtx = createContext(DEFAULT_THEME);
28
+ function ThemeProvider({ value, children }) {
29
+ const merged = value ? {
30
+ ...DEFAULT_THEME,
31
+ ...value
32
+ } : DEFAULT_THEME;
33
+ return createElement(ThemeCtx.Provider, { value: merged }, children);
34
+ }
35
+ function useTheme() {
36
+ return useContext(ThemeCtx);
37
+ }
38
+ //#endregion
39
+ export { DEFAULT_THEME, SessionProvider, ThemeProvider, useSession, useTheme };
@@ -0,0 +1 @@
1
+ var e=.1;async function t(t){let{sttSampleRate:n,ttsSampleRate:r,captureWorkletSrc:i,playbackWorkletSrc:a,onMicData:o}=t,s=r,c=new AudioContext({sampleRate:s,latencyHint:`playback`});await c.resume();let l=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:s,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}});try{await Promise.all([c.audioWorklet.addModule(i),c.audioWorklet.addModule(a)])}catch(e){for(let e of l.getTracks())e.stop();throw await c.close().catch(e=>{console.warn(`AudioContext close failed:`,e)}),e}let u=c.createMediaStreamSource(l),d=new AudioWorkletNode(c,`capture-processor`,{channelCount:1,channelCountMode:`explicit`,processorOptions:{contextRate:s,sttSampleRate:n}});u.connect(d);let f=Math.floor(n*e)*2,p=f*2,m=new Uint8Array(p),h=new Uint8Array(p),g=m,_=0;d.port.postMessage({event:`start`}),d.port.onmessage=e=>{if(e.data.event!==`chunk`)return;let t=new Uint8Array(e.data.buffer);g.set(t,_),_+=t.byteLength,_>=f&&(o(g.buffer.slice(0,_)),g=g===m?h:m,_=0)};let v=null,y=null,b=new AbortController,{onPlaybackProgress:x}=t;function S(){if(v)return v;let e=new AudioWorkletNode(c,`playback-processor`,{processorOptions:{sampleRate:s}});return e.connect(c.destination),e.port.onmessage=t=>{t.data.event===`stop`?(e.disconnect(),v===e&&(v=null),y?.(),y=null):t.data.event===`progress`&&x?.(t.data.readPos)},v=e,e}let C={enqueue(e){b.signal.aborted||e.byteLength!==0&&S().port.postMessage({event:`write`,buffer:new Uint8Array(e)},[e])},done(){return v?new Promise(e=>{y=e,v?.port.postMessage({event:`done`})}):Promise.resolve()},flush(){v&&v.port.postMessage({event:`interrupt`})},async close(){if(!b.signal.aborted){b.abort(),d.port.postMessage({event:`stop`}),u.disconnect(),d.disconnect(),v&&v.disconnect();for(let e of l.getTracks())e.stop();await c.close().catch(()=>{})}},async[Symbol.asyncDispose](){await C.close()}};return C}export{t as createVoiceIO};
@@ -0,0 +1,53 @@
1
+ var e=new Blob([`
2
+ class CaptureProcessor extends AudioWorkletProcessor {
3
+ constructor(options) {
4
+ super();
5
+ this.recording = false;
6
+ const opts = options.processorOptions || {};
7
+ this.fromRate = opts.contextRate || sampleRate;
8
+ this.toRate = opts.sttSampleRate || sampleRate;
9
+ this.ratio = this.fromRate / this.toRate;
10
+ this.needsResample = this.fromRate !== this.toRate;
11
+ this.port.onmessage = (e) => {
12
+ if (e.data.event === 'start') this.recording = true;
13
+ else if (e.data.event === 'stop') this.recording = false;
14
+ };
15
+ }
16
+
17
+ resample(input) {
18
+ const ratio = this.ratio;
19
+ const outLen = Math.ceil(input.length / ratio);
20
+ const out = new Float32Array(outLen);
21
+ for (let i = 0; i < outLen; i++) {
22
+ const srcIdx = i * ratio;
23
+ const idx = srcIdx | 0;
24
+ const frac = srcIdx - idx;
25
+ const a = input[idx];
26
+ const b = idx + 1 < input.length ? input[idx + 1] : a;
27
+ out[i] = a + frac * (b - a);
28
+ }
29
+ return out;
30
+ }
31
+
32
+ process(inputs) {
33
+ const input = inputs[0];
34
+ if (!input || !input[0] || !this.recording) return true;
35
+
36
+ const raw = input[0];
37
+ const samples = this.needsResample ? this.resample(raw) : raw;
38
+
39
+ // Convert Float32 -> Int16
40
+ const buffer = new ArrayBuffer(samples.length * 2);
41
+ const view = new DataView(buffer);
42
+ for (let i = 0; i < samples.length; i++) {
43
+ const s = Math.max(-1, Math.min(1, samples[i]));
44
+ view.setInt16(i * 2, s < 0 ? s * 0x8000 : s * 0x7fff, true);
45
+ }
46
+
47
+ this.port.postMessage({ event: 'chunk', buffer }, [buffer]);
48
+ return true;
49
+ }
50
+ }
51
+
52
+ registerProcessor('capture-processor', CaptureProcessor);
53
+ `],{type:`application/javascript`}),t=URL.createObjectURL(e);export{t as default};