@alexkroman1/aai-ui 16.1.0 → 18.0.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.
Files changed (39) hide show
  1. package/README.md +3 -2
  2. package/dist/_page-shell.d.ts +11 -0
  3. package/dist/{chat-view-DsylXJsw.js → chat-view-P12pHKQU.js} +1 -1
  4. package/dist/{client-config-DJQHnYjm.js → client-config-CFhkMkmv.js} +15 -13
  5. package/dist/client-config.d.ts +14 -13
  6. package/dist/components/chat-view.js +1 -1
  7. package/dist/components/controls.js +1 -1
  8. package/dist/components/message-list.js +1 -1
  9. package/dist/components/tool-call-block.js +1 -1
  10. package/dist/context.d.ts +27 -5
  11. package/dist/context.js +3 -3
  12. package/dist/default-client/assets/index-5XG8PqGw.css +2 -0
  13. package/dist/default-client/assets/index-tc-nAWq3.js +121 -0
  14. package/dist/default-client/index.html +2 -2
  15. package/dist/default-client.d.ts +21 -0
  16. package/dist/define-client.js +4 -4
  17. package/dist/hooks.d.ts +19 -9
  18. package/dist/hooks.js +1 -1
  19. package/dist/index.d.ts +17 -13
  20. package/dist/index.js +734 -433
  21. package/dist/internal.js +3 -3
  22. package/dist/{message-list-BLyPRS1Q.js → message-list-CJX560b5.js} +1 -1
  23. package/dist/page.d.ts +47 -21
  24. package/dist/{session-core-gwePM95B.js → session-core-TOdm_Con.js} +424 -174
  25. package/dist/session-core-audio-effects.d.ts +26 -0
  26. package/dist/session-core-audio-setup.d.ts +38 -31
  27. package/dist/session-core-audio-state.d.ts +152 -0
  28. package/dist/session-core-messages.d.ts +9 -10
  29. package/dist/session-core-types.d.ts +60 -21
  30. package/dist/session-core-user-turn.d.ts +30 -0
  31. package/dist/session-core.js +1 -1
  32. package/dist/use-push-to-talk.d.ts +105 -0
  33. package/dist/{use-workflow-run-CNahvlgL.js → use-workflow-run-ZqJWJn2-.js} +24 -11
  34. package/dist/workflow-client.d.ts +26 -12
  35. package/package.json +2 -2
  36. package/dist/default-client/assets/index-CMh4E-Ci.css +0 -2
  37. package/dist/default-client/assets/index-eOmPq2sS.js +0 -284
  38. package/dist/{tool-call-block-C2t_5fpp.js → tool-call-block-4gXoL_eP.js} +1 -1
  39. package/dist/{url-chips-D62RTz7v.js → url-chips-0n35fPJY.js} +1 -1
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # @alexkroman1/aai-ui
2
2
 
3
- The browser client for aai agents: React 19 hooks and components over a
4
- framework-agnostic session core (WebSocket + microphone + playback).
3
+ The browser client for AssemblyAI Agent SDK agents: React 19 hooks and
4
+ components over a framework-agnostic session core (WebSocket + microphone +
5
+ playback).
5
6
 
6
7
  ```sh
7
8
  npm i @alexkroman1/aai-ui react react-dom
@@ -0,0 +1,11 @@
1
+ import { type ReactNode } from "react";
2
+ /**
3
+ * The default page: the agent, its workflows, and one form.
4
+ *
5
+ * A picker appears only when there is more than one workflow — an agent with a
6
+ * single workflow is the common case and a select with one option is chrome
7
+ * about nothing.
8
+ */
9
+ export declare function DefaultPageShell({ name }: {
10
+ name?: string | undefined;
11
+ }): ReactNode;
@@ -1,4 +1,4 @@
1
- import { t as MessageList } from "./message-list-BLyPRS1Q.js";
1
+ import { t as MessageList } from "./message-list-CJX560b5.js";
2
2
  import { useSessionError, useSessionStatus, useTheme } from "./context.js";
3
3
  import { a as inkTint, r as THINKING_COLOR, t as ERROR_COLOR } from "./_colors-CpZO-88A.js";
4
4
  import { t as AaiLogo } from "./aai-logo-CFlomZlS.js";
@@ -1,3 +1,4 @@
1
+ import { t as pageBaseUrl } from "./_utils-DnQDM9Uy.js";
1
2
  import { CLIENT_CONFIG_PATH, ClientConfigResponseSchema } from "@alexkroman1/aai/protocol";
2
3
  //#region src/client-config.ts
3
4
  /**
@@ -83,12 +84,12 @@ async function loadClientConfig(platformUrl, fetchFn) {
83
84
  * Fetch the agent's declared `name`, `greeting` and front door; any failure
84
85
  * yields the agent default (`{}`).
85
86
  *
86
- * **This is what a workflow app calls instead of receiving the config.**
87
- * `mountClient()` fetches `GET client-config` for itself before it renders the
88
- * default chat shell, so a voice client never has to. `mountPage()` mounts no
89
- * session and makes no such request — deliberately, since a page has no shell
90
- * to put a name in — so a page that wants the agent's own `name` or `greeting`
91
- * asks for them here.
87
+ * **This is what a workflow app's own component calls instead of receiving the
88
+ * config.** Both mounts fetch `GET client-config` for the shell they render
89
+ * themselves — `mountClient()` for the chat shell, `mountPage()` for the
90
+ * generated workflow shell — so neither DEFAULT has to be told the agent's
91
+ * name. A `component:` replaces that shell, and with it the lookup, so a page
92
+ * that wants the agent's own `name` or `greeting` asks for them here.
92
93
  *
93
94
  * Every failure path degrades to the empty default rather than throwing: a
94
95
  * network error, a 404 from a server older than the endpoint, a malformed
@@ -98,9 +99,12 @@ async function loadClientConfig(platformUrl, fetchFn) {
98
99
  * treat every field as optional, because an agent that declared none is a
99
100
  * normal agent.
100
101
  *
101
- * @param platformUrl - The agent's base URL. On a deployed page that is the
102
- * page's own origin and path (`location.origin + location.pathname`); the
103
- * endpoint is resolved relative to it.
102
+ * @param platformUrl - The agent's base URL. **Defaults to the page's own
103
+ * origin and path** (`pageBaseUrl()`), which is the agent that served the page
104
+ * and the only case a browser has — the argument was required while the default
105
+ * sat one module away in this same package, so every caller wrote
106
+ * `location.origin + location.pathname` for itself. Pass one for a page reading
107
+ * a DIFFERENT agent. The endpoint is resolved relative to it.
104
108
  * @param fetchFn - Fetch implementation, for tests and for a caller that
105
109
  * supplies its own credentials. Defaults to the global `fetch`.
106
110
  * @returns The agent's config, or `{}` when the lookup produced no answer.
@@ -109,9 +113,7 @@ async function loadClientConfig(platformUrl, fetchFn) {
109
113
  * ```tsx
110
114
  * import { fetchClientConfig, mountPage } from "@alexkroman1/aai-ui";
111
115
  *
112
- * const { name, greeting } = await fetchClientConfig(
113
- * location.origin + location.pathname,
114
- * );
116
+ * const { name, greeting } = await fetchClientConfig();
115
117
  *
116
118
  * function App() {
117
119
  * return (
@@ -127,7 +129,7 @@ async function loadClientConfig(platformUrl, fetchFn) {
127
129
  *
128
130
  * @public
129
131
  */
130
- async function fetchClientConfig(platformUrl, fetchFn) {
132
+ async function fetchClientConfig(platformUrl = pageBaseUrl(), fetchFn) {
131
133
  return await loadClientConfig(platformUrl, fetchFn) ?? AGENT_DEFAULT;
132
134
  }
133
135
  //#endregion
@@ -71,12 +71,12 @@ export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof g
71
71
  * Fetch the agent's declared `name`, `greeting` and front door; any failure
72
72
  * yields the agent default (`{}`).
73
73
  *
74
- * **This is what a workflow app calls instead of receiving the config.**
75
- * `mountClient()` fetches `GET client-config` for itself before it renders the
76
- * default chat shell, so a voice client never has to. `mountPage()` mounts no
77
- * session and makes no such request — deliberately, since a page has no shell
78
- * to put a name in — so a page that wants the agent's own `name` or `greeting`
79
- * asks for them here.
74
+ * **This is what a workflow app's own component calls instead of receiving the
75
+ * config.** Both mounts fetch `GET client-config` for the shell they render
76
+ * themselves — `mountClient()` for the chat shell, `mountPage()` for the
77
+ * generated workflow shell — so neither DEFAULT has to be told the agent's
78
+ * name. A `component:` replaces that shell, and with it the lookup, so a page
79
+ * that wants the agent's own `name` or `greeting` asks for them here.
80
80
  *
81
81
  * Every failure path degrades to the empty default rather than throwing: a
82
82
  * network error, a 404 from a server older than the endpoint, a malformed
@@ -86,9 +86,12 @@ export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof g
86
86
  * treat every field as optional, because an agent that declared none is a
87
87
  * normal agent.
88
88
  *
89
- * @param platformUrl - The agent's base URL. On a deployed page that is the
90
- * page's own origin and path (`location.origin + location.pathname`); the
91
- * endpoint is resolved relative to it.
89
+ * @param platformUrl - The agent's base URL. **Defaults to the page's own
90
+ * origin and path** (`pageBaseUrl()`), which is the agent that served the page
91
+ * and the only case a browser has — the argument was required while the default
92
+ * sat one module away in this same package, so every caller wrote
93
+ * `location.origin + location.pathname` for itself. Pass one for a page reading
94
+ * a DIFFERENT agent. The endpoint is resolved relative to it.
92
95
  * @param fetchFn - Fetch implementation, for tests and for a caller that
93
96
  * supplies its own credentials. Defaults to the global `fetch`.
94
97
  * @returns The agent's config, or `{}` when the lookup produced no answer.
@@ -97,9 +100,7 @@ export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof g
97
100
  * ```tsx
98
101
  * import { fetchClientConfig, mountPage } from "@alexkroman1/aai-ui";
99
102
  *
100
- * const { name, greeting } = await fetchClientConfig(
101
- * location.origin + location.pathname,
102
- * );
103
+ * const { name, greeting } = await fetchClientConfig();
103
104
  *
104
105
  * function App() {
105
106
  * return (
@@ -115,4 +116,4 @@ export declare function loadClientConfig(platformUrl: string, fetchFn?: typeof g
115
116
  *
116
117
  * @public
117
118
  */
118
- export declare function fetchClientConfig(platformUrl: string, fetchFn?: typeof globalThis.fetch): Promise<ClientConfigResponse>;
119
+ export declare function fetchClientConfig(platformUrl?: string, fetchFn?: typeof globalThis.fetch): Promise<ClientConfigResponse>;
@@ -1,3 +1,3 @@
1
- import { t as ChatView } from "../chat-view-DsylXJsw.js";
1
+ import { t as ChatView } from "../chat-view-P12pHKQU.js";
2
2
  import "../context.js";
3
3
  export { ChatView };
@@ -1,6 +1,6 @@
1
1
  import { useSessionCore, useSessionSelector } from "../context.js";
2
2
  import { Button } from "./button.js";
3
- import { n as SessionUrlChips } from "../url-chips-D62RTz7v.js";
3
+ import { n as SessionUrlChips } from "../url-chips-0n35fPJY.js";
4
4
  import clsx from "clsx";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import { memo } from "react";
@@ -1,3 +1,3 @@
1
- import { t as MessageList } from "../message-list-BLyPRS1Q.js";
1
+ import { t as MessageList } from "../message-list-CJX560b5.js";
2
2
  import "../context.js";
3
3
  export { MessageList };
@@ -1,3 +1,3 @@
1
1
  import "../context.js";
2
- import { t as ToolCallBlock } from "../tool-call-block-C2t_5fpp.js";
2
+ import { t as ToolCallBlock } from "../tool-call-block-4gXoL_eP.js";
3
3
  export { ToolCallBlock };
package/dist/context.d.ts CHANGED
@@ -20,11 +20,33 @@ export declare function SessionProvider({ value, children, }: {
20
20
  * places: the two lists have to be the same list, and a member added to one and
21
21
  * not the other is a hook that cannot do what `useSession()` can.
22
22
  *
23
- * Method signatures come from {@link BrowserSession} — one source of truth.
23
+ * DECLARED here rather than picked out of {@link BrowserSession}: that handle is
24
+ * sealed and grows, and a `Pick` made every member it gained a candidate for
25
+ * this list without anyone deciding. Push-to-talk is the case in point — its
26
+ * three edges are `session.userTurn`, reached through `usePushToTalk`, and not
27
+ * actions every chrome is handed. `createBrowserSession` is what keeps each of
28
+ * these assignable from the session's own methods.
24
29
  *
25
30
  * @public
26
31
  */
27
- export type SessionActions = Pick<BrowserSession, "start" | "cancel" | "resetState" | "reset" | "restart" | "disconnect" | "toggle" | "end">;
32
+ export type SessionActions = {
33
+ /** Start the call for the first time — see {@link BrowserSession.start}. */
34
+ start(): void;
35
+ /** Cancel the current agent turn and discard in-flight TTS audio. */
36
+ cancel(): void;
37
+ /** Clear messages, transcripts and error state, keeping the connection. */
38
+ resetState(): void;
39
+ /** Clear state and reopen the connection — the same session id. */
40
+ reset(): void;
41
+ /** End the call and begin a fresh one — see {@link BrowserSession.restart}. */
42
+ restart(): void;
43
+ /** Close the WebSocket and release all audio resources. */
44
+ disconnect(): void;
45
+ /** Toggle between connected and disconnected (after `start()`). */
46
+ toggle(): void;
47
+ /** End the call and return to the not-started state — see {@link BrowserSession.end}. */
48
+ end(): void;
49
+ };
28
50
  /**
29
51
  * What {@link useSession} returns: the live {@link SessionSnapshot} fields
30
52
  * (`state`, `messages`, `toolCalls`, `agentState`, live transcripts, `error`,
@@ -50,8 +72,8 @@ export type Session = SessionSnapshot & SessionActions;
50
72
  export declare function useSessionCore(): BrowserSession;
51
73
  /**
52
74
  * The session's control methods — `start`, `cancel`, `resetState`, `reset`,
53
- * `restart`, `disconnect`, `toggle`, `end` — with **no snapshot
54
- * subscription**.
75
+ * `restart`, `disconnect`, `toggle`, `end` — with **no snapshot subscription**.
76
+ * Push-to-talk is not among them: that is `usePushToTalk`.
55
77
  *
56
78
  * This is the narrow half of {@link useSession}, and it is the half a custom
57
79
  * chrome could not reach. `<Controls>` and `<StartScreen>` in this package pair
@@ -101,7 +123,7 @@ export declare function useSessionCore(): BrowserSession;
101
123
  * }
102
124
  * ```
103
125
  *
104
- * @returns The eight control methods — see {@link SessionActions}.
126
+ * @returns The control methods — see {@link SessionActions}.
105
127
  *
106
128
  * @public
107
129
  */
package/dist/context.js CHANGED
@@ -35,8 +35,8 @@ function useSessionCore() {
35
35
  }
36
36
  /**
37
37
  * The session's control methods — `start`, `cancel`, `resetState`, `reset`,
38
- * `restart`, `disconnect`, `toggle`, `end` — with **no snapshot
39
- * subscription**.
38
+ * `restart`, `disconnect`, `toggle`, `end` — with **no snapshot subscription**.
39
+ * Push-to-talk is not among them: that is `usePushToTalk`.
40
40
  *
41
41
  * This is the narrow half of {@link useSession}, and it is the half a custom
42
42
  * chrome could not reach. `<Controls>` and `<StartScreen>` in this package pair
@@ -86,7 +86,7 @@ function useSessionCore() {
86
86
  * }
87
87
  * ```
88
88
  *
89
- * @returns The eight control methods — see {@link SessionActions}.
89
+ * @returns The control methods — see {@link SessionActions}.
90
90
  *
91
91
  * @public
92
92
  */
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-600:oklch(57.7% .245 27.325);--spacing:.25rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-aai-surface:var(--aai-surface,#fff);--color-aai-text:var(--aai-text,#1b1a18);--color-aai-border:var(--aai-border,#dcd7cc);--font-aai:"Monument Grotesk", "ABC Monument Grotesk", ui-sans-serif, system-ui, -apple-system, sans-serif;--font-aai-serif:"Source Serif 4", "Source Serif Pro", Charter, "Iowan Old Style", Georgia, serif;--font-aai-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--radius-aai:4px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}html,body{margin:0;padding:0}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.order-last{order:9999}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-auto{margin-inline:auto}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2\.5{margin-block:calc(var(--spacing) * 2.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.ml-auto{margin-left:auto}.box-border{box-sizing:border-box}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-\[7px\]{height:7px}.h-full{height:100%}.h-screen{height:100vh}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\[40vh\]{max-height:40vh}.min-h-0{min-height:0}.min-h-5{min-height:calc(var(--spacing) * 5)}.min-h-screen{min-height:100vh}.w-1{width:var(--spacing)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-4{width:calc(var(--spacing) * 4)}.w-\[7px\]{width:7px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-75{max-width:calc(var(--spacing) * 75)}.max-w-105{max-width:calc(var(--spacing) * 105)}.max-w-190{max-width:calc(var(--spacing) * 190)}.max-w-\[82\%\]{max-width:82%}.max-w-\[min\(78\%\,64ch\)\]{max-width:min(78%,64ch)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.basis-full{flex-basis:100%}.border-collapse{border-collapse:collapse}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.resize{resize:both}.\[scrollbar-width\:none\]{scrollbar-width:none}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-\[1fr_320px\]{grid-template-columns:1fr 320px}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.self-end{align-self:flex-end}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-aai{border-radius:var(--radius-aai)}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-none{--tw-border-style:none;border-style:none}.border-\(--aai-btn-bd\){border-color:var(--aai-btn-bd)}.border-aai-border{border-color:var(--color-aai-border)}.bg-\(--aai-btn-bg\){background-color:var(--aai-btn-bg)}.bg-aai-surface{background-color:var(--color-aai-surface)}.bg-transparent{background-color:#0000}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-7{padding:calc(var(--spacing) * 7)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.font-aai{font-family:var(--font-aai)}.font-aai-mono{font-family:var(--font-aai-mono)}.font-aai-serif{font-family:var(--font-aai-serif)}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.625rem\]{font-size:.625rem}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[22px\]{font-size:22px}.text-\[32px\]{font-size:32px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.15\]{--tw-leading:1.15;line-height:1.15}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.leading-\[23px\]{--tw-leading:23px;line-height:23px}.leading-\[130\%\]{--tw-leading:130%;line-height:130%}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.2px\]{--tw-tracking:-.2px;letter-spacing:-.2px}.tracking-\[1\.2px\]{--tw-tracking:1.2px;letter-spacing:1.2px}.tracking-\[1\.4px\]{--tw-tracking:1.4px;letter-spacing:1.4px}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-balance{text-wrap:balance}.wrap-break-word{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\(--aai-btn-fg\){color:var(--aai-btn-fg)}.text-aai-text{color:var(--color-aai-text)}.text-red-600{color:var(--color-red-600)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_6px_currentColor\]{--tw-shadow:0 0 6px var(--tw-shadow-color,currentColor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.file\:mr-3::file-selector-button{margin-right:calc(var(--spacing) * 3)}.file\:cursor-pointer::file-selector-button{cursor:pointer}.file\:rounded-aai::file-selector-button{border-radius:var(--radius-aai)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:px-3::file-selector-button{padding-inline:calc(var(--spacing) * 3)}.file\:py-1\.5::file-selector-button{padding-block:calc(var(--spacing) * 1.5)}.file\:font-aai::file-selector-button{font-family:var(--font-aai)}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:\[color\:var\(--aai-file-button-fg\)\]::file-selector-button{color:var(--aai-file-button-fg)}.file\:\[background\:var\(--aai-file-button-bg\)\]::file-selector-button{background:var(--aai-file-button-bg)}.first\:mt-0:first-child{margin-top:0}.last\:mb-0:last-child{margin-bottom:0}.focus-visible\:\[outline\:2px_solid\]:focus-visible{outline:2px solid}.focus-visible\:\[outline-offset\:2px\]:focus-visible{outline-offset:2px}@media (hover:hover){.enabled\:hover\:border-\(--aai-btn-bd-hover\):enabled:hover{border-color:var(--aai-btn-bd-hover)}.enabled\:hover\:bg-\(--aai-btn-bg-hover\):enabled:hover{background-color:var(--aai-btn-bg-hover)}.enabled\:hover\:text-\(--aai-btn-fg-hover\):enabled:hover{color:var(--aai-btn-fg-hover)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:ml-auto{margin-left:auto}.sm\:max-w-\[60\%\]{max-width:60%}.sm\:basis-auto{flex-basis:auto}.sm\:px-16{padding-inline:calc(var(--spacing) * 16)}.sm\:py-14{padding-block:calc(var(--spacing) * 14)}}@media (width>=48rem){.md\:order-none{order:0}.md\:h-screen{height:100vh}.md\:max-h-none{max-height:none}.md\:w-\(--aai-sidebar-w\){width:var(--aai-sidebar-w)}.md\:flex-row{flex-direction:row}.md\:border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}.md\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.md\:border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.md\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}}}@keyframes aai-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.82)}}@keyframes aai-bounce{0%,80%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1)}}@keyframes aai-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.tool-shimmer{-webkit-text-fill-color:transparent;background:linear-gradient(90deg,currentColor 25%,#0000 50%,currentColor 75%) 0 0/200% 100%;-webkit-background-clip:text;background-clip:text;animation:2s infinite aai-shimmer}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}.aai-scroll{scrollbar-width:thin;scrollbar-color:var(--aai-scrollbar-thumb,var(--aai-border,#dcd7cc)) var(--aai-scrollbar-track,transparent)}.aai-scroll::-webkit-scrollbar{width:6px}.aai-scroll::-webkit-scrollbar-track{background:var(--aai-scrollbar-track,transparent)}.aai-scroll::-webkit-scrollbar-thumb{background:var(--aai-scrollbar-thumb,var(--aai-border,#dcd7cc));border-radius:3px}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}