@alexkroman1/aai-ui 16.0.1 → 17.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 (43) 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/audio-result.d.ts +2 -2
  7. package/dist/components/chat-view.js +1 -1
  8. package/dist/components/controls.js +1 -1
  9. package/dist/components/facts.d.ts +1 -1
  10. package/dist/components/message-list.js +1 -1
  11. package/dist/components/tool-call-block.js +1 -1
  12. package/dist/components/workflow-run-panel.d.ts +1 -1
  13. package/dist/context.d.ts +1 -1
  14. package/dist/context.js +1 -1
  15. package/dist/default-client/assets/index-18HWH46b.css +2 -0
  16. package/dist/default-client/assets/index-gJbwWrWS.js +121 -0
  17. package/dist/default-client/index.html +2 -2
  18. package/dist/default-client.d.ts +21 -0
  19. package/dist/define-client.js +4 -4
  20. package/dist/hooks.d.ts +20 -10
  21. package/dist/hooks.js +1 -1
  22. package/dist/index.d.ts +15 -12
  23. package/dist/index.js +578 -437
  24. package/dist/internal.js +3 -3
  25. package/dist/{message-list-BLyPRS1Q.js → message-list-CJX560b5.js} +1 -1
  26. package/dist/page.d.ts +47 -21
  27. package/dist/{session-core-gwePM95B.js → session-core-DHE1bQ1J.js} +388 -172
  28. package/dist/session-core-audio-effects.d.ts +26 -0
  29. package/dist/session-core-audio-setup.d.ts +38 -31
  30. package/dist/session-core-audio-state.d.ts +152 -0
  31. package/dist/session-core-messages.d.ts +9 -10
  32. package/dist/session-core-types.d.ts +13 -21
  33. package/dist/session-core.js +1 -1
  34. package/dist/use-run-key.d.ts +1 -1
  35. package/dist/use-workflow-form.d.ts +1 -1
  36. package/dist/{use-workflow-run-CNahvlgL.js → use-workflow-run-ZqJWJn2-.js} +24 -11
  37. package/dist/workflow-client.d.ts +26 -12
  38. package/package.json +2 -2
  39. package/styles.css +2 -2
  40. package/dist/default-client/assets/index-CMh4E-Ci.css +0 -2
  41. package/dist/default-client/assets/index-eOmPq2sS.js +0 -284
  42. package/dist/{tool-call-block-C2t_5fpp.js → tool-call-block-4gXoL_eP.js} +1 -1
  43. 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>;
@@ -58,9 +58,9 @@ export type AudioResultProps = {
58
58
  * and that is the whole reason both pages hand this a hook result rather than a
59
59
  * path.
60
60
  *
61
- * **A caption track is a judgement, not a default.** `spoken-summary` passes
61
+ * **A caption track is a judgement, not a default.** `spoken-summary-workflow` passes
62
62
  * `captions`: the summary was written before it was spoken, so one cue
63
- * spanning the clip is an honest transcript of it. `call-audit` deliberately
63
+ * spanning the clip is an honest transcript of it. `call-audit-workflow` deliberately
64
64
  * does not: the spoken text is rendered in full immediately below the player,
65
65
  * which is the same information a track would carry. Both are right, which is
66
66
  * why the prop is optional in both directions.
@@ -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";
@@ -42,7 +42,7 @@ export type FactsProps = {
42
42
  * 1,840 words".
43
43
  *
44
44
  * Nine pages had written this by hand under four different typographies for
45
- * one role, two of them (`call-audit` and `spoken-summary`) byte-identical down
45
+ * one role, two of them (`call-audit-workflow` and `spoken-summary-workflow`) byte-identical down
46
46
  * to the payload. Three things it takes off the caller:
47
47
  *
48
48
  * - **The separator cannot be forgotten, and neither can the space around it.**
@@ -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 };
@@ -40,7 +40,7 @@ export type WorkflowRunPanelProps<O> = {
40
40
  * button, the run's own narration, the live slot while it works, the completed
41
41
  * body once it has, and the announced error if it failed.
42
42
  *
43
- * Two pages had written this shell — `redline` and `transcription-workflow` —
43
+ * Two pages had written this shell — `document-redline-workflow` and `transcription-workflow` —
44
44
  * with the same header, the same `text-xs underline` Clear, the same
45
45
  * {@link WorkflowProgress} under it, the same `run.status === "completed"`
46
46
  * discrimination above the same {@link WorkflowRunError}, and each spread
package/dist/context.d.ts CHANGED
@@ -62,7 +62,7 @@ export declare function useSessionCore(): BrowserSession;
62
62
  * rebuilds the snapshot object on every change. Measured consequence: four
63
63
  * components across three templates re-rendered on every STT partial and every
64
64
  * streaming delta, in files whose every other component is narrowly subscribed
65
- * on purpose. One of them (`infocom-adventure`'s `TitleScreen`) reads nothing
65
+ * on purpose. One of them (`text-adventure-agent`'s `TitleScreen`) reads nothing
66
66
  * from the snapshot at all and subscribes to all of it for `session.start`.
67
67
  *
68
68
  * **Why publishing this does not reopen what `/internal` closed.**
package/dist/context.js CHANGED
@@ -47,7 +47,7 @@ function useSessionCore() {
47
47
  * rebuilds the snapshot object on every change. Measured consequence: four
48
48
  * components across three templates re-rendered on every STT partial and every
49
49
  * streaming delta, in files whose every other component is narrowly subscribed
50
- * on purpose. One of them (`infocom-adventure`'s `TitleScreen`) reads nothing
50
+ * on purpose. One of them (`text-adventure-agent`'s `TitleScreen`) reads nothing
51
51
  * from the snapshot at all and subscribes to all of it for `session.start`.
52
52
  *
53
53
  * **Why publishing this does not reopen what `/internal` closed.**
@@ -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}.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}}