@alexkroman1/aai-ui 5.11.0 → 5.13.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/_colors-CcAi2FOU.js +44 -0
- package/dist/{chat-view-DFBmX5eX.js → chat-view-DadZOvJO.js} +11 -7
- package/dist/client-config.d.ts +29 -0
- package/dist/components/_colors.d.ts +35 -9
- package/dist/components/button.js +31 -15
- 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/sidebar-layout.js +9 -8
- package/dist/components/start-screen.d.ts +1 -1
- package/dist/components/start-screen.js +2 -2
- package/dist/components/tool-call-block.js +1 -1
- package/dist/{controls-CoBO6sId.js → controls-DzQEKq9c.js} +8 -7
- package/dist/default-client/assets/{audio-DJF-gC7e.js → audio-BAAzYW28.js} +1 -1
- package/dist/default-client/assets/{capture-processor-D_A9RUeB.js → capture-processor-vx5IW_Rd.js} +1 -1
- package/dist/default-client/assets/index-Cn-zI5ic.js +293 -0
- package/dist/default-client/assets/index-Ctjrde3-.css +2 -0
- package/dist/default-client/assets/{playback-processor-GPTQTyza.js → playback-processor-2p9HLz_W.js} +1 -1
- package/dist/default-client/index.html +2 -2
- package/dist/define-client.js +3 -3
- package/dist/hooks.test-d.d.ts +14 -0
- package/dist/index.js +5 -5
- package/dist/{message-list-DkAHoB3A.js → message-list-YdLocGoT.js} +11 -9
- package/dist/{session-core-CS37WE1G.js → session-core-BoB7kTzL.js} +184 -43
- package/dist/session-core-handshake.d.ts +25 -0
- package/dist/session-core-reconnect.d.ts +8 -0
- package/dist/session-core.js +1 -1
- package/dist/{tool-call-block-BjemDFB9.js → tool-call-block-CAscLGFy.js} +6 -6
- package/package.json +2 -2
- package/dist/_colors-Bfh3-BVE.js +0 -29
- package/dist/default-client/assets/index-1JIz81CD.css +0 -2
- package/dist/default-client/assets/index-D_RNiTIh.js +0 -278
|
@@ -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-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking: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;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--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-in-out:cubic-bezier(.4, 0, .2, 1);--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);--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}.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)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.box-border{box-sizing:border-box}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-\[7px\]{height:7px}.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\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-\[7px\]{width:7px}.w-fit{width:fit-content}.w-full{width:100%}.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}.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}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.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)}.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:3.40282e38px}.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-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)}.bg-\(--aai-btn-bg\){background-color:var(--aai-btn-bg)}.bg-transparent{background-color:#0000}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-7{padding:calc(var(--spacing) * 7)}.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-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-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-3{padding-left:calc(var(--spacing) * 3)}.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)}.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-\[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)}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.ring{--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)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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-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}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.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}@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-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}
|
package/dist/default-client/assets/{playback-processor-GPTQTyza.js → playback-processor-2p9HLz_W.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as e}from"./index-
|
|
1
|
+
import{i as e}from"./index-Cn-zI5ic.js";import{t}from"./_module-url-BX0RuRU2.js";var n=t(`
|
|
2
2
|
class PlaybackProcessor extends AudioWorkletProcessor {
|
|
3
3
|
constructor(options) {
|
|
4
4
|
super();
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<title>aai</title>
|
|
7
7
|
<link rel="icon" href="./favicon.ico" />
|
|
8
8
|
<style>html, body { background: #FBF8F2; margin: 0; }</style>
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-Cn-zI5ic.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="./assets/index-Ctjrde3-.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<main id="app"></main>
|
package/dist/define-client.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { r as fetchClientConfig, t as createSessionCore } from "./session-core-
|
|
1
|
+
import { r as fetchClientConfig, t as createSessionCore } from "./session-core-BoB7kTzL.js";
|
|
2
2
|
import { SessionProvider, ThemeProvider } from "./context.js";
|
|
3
|
-
import { t as ChatView } from "./chat-view-
|
|
3
|
+
import { t as ChatView } from "./chat-view-DadZOvJO.js";
|
|
4
4
|
import { t as pageBaseUrl } from "./_utils-CsqbIVGI.js";
|
|
5
|
-
import { n as ToolConfigContext } from "./tool-call-block-
|
|
5
|
+
import { n as ToolConfigContext } from "./tool-call-block-CAscLGFy.js";
|
|
6
6
|
import { SidebarLayout } from "./components/sidebar-layout.js";
|
|
7
7
|
import { StartScreen } from "./components/start-screen.js";
|
|
8
8
|
import { createElement, useEffect, useState } from "react";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-level contract for the four `aai-ui` hooks a custom client is written
|
|
3
|
+
* against. All four are generic, all four are typed BY THE CALLER, and every
|
|
4
|
+
* one of them was unpinned — the root guide claimed `aai-ui` (`.`) had
|
|
5
|
+
* type-level coverage and no `.test-d.ts` existed in this package at all.
|
|
6
|
+
*
|
|
7
|
+
* The reason these need a type test rather than a runtime one: nothing here
|
|
8
|
+
* has runtime behaviour to observe. `useAgentState` is one `useSessionSelector`
|
|
9
|
+
* call plus a cast, and `useToolResult`'s two overloads erase to the same
|
|
10
|
+
* `(...args: unknown[])` implementation. What a consumer actually depends on
|
|
11
|
+
* is the SIGNATURE, and a signature is exactly what a runtime suite cannot
|
|
12
|
+
* assert.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { i as loadClientConfig, n as buildAgentUrl, r as fetchClientConfig, t as createSessionCore } from "./session-core-
|
|
1
|
+
import { i as loadClientConfig, n as buildAgentUrl, r as fetchClientConfig, t as createSessionCore } from "./session-core-BoB7kTzL.js";
|
|
2
2
|
import { SessionProvider, ThemeProvider, useSession, useSessionSelector, useTheme } from "./context.js";
|
|
3
3
|
import { Button } from "./components/button.js";
|
|
4
|
-
import { t as ChatView } from "./chat-view-
|
|
5
|
-
import { i as UiUrlChip, n as ApiUrlChip, r as SessionUrlChips, t as Controls } from "./controls-
|
|
6
|
-
import { n as Markdown, t as MessageList } from "./message-list-
|
|
7
|
-
import { n as ToolConfigContext, r as ToolCallRow } from "./tool-call-block-
|
|
4
|
+
import { t as ChatView } from "./chat-view-DadZOvJO.js";
|
|
5
|
+
import { i as UiUrlChip, n as ApiUrlChip, r as SessionUrlChips, t as Controls } from "./controls-DzQEKq9c.js";
|
|
6
|
+
import { n as Markdown, t as MessageList } from "./message-list-YdLocGoT.js";
|
|
7
|
+
import { n as ToolConfigContext, r as ToolCallRow } from "./tool-call-block-CAscLGFy.js";
|
|
8
8
|
import { SidebarLayout } from "./components/sidebar-layout.js";
|
|
9
9
|
import { StartScreen } from "./components/start-screen.js";
|
|
10
10
|
import { VOICE_CAPTURE_CONSTRAINTS } from "./types.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useSessionSelector, useTheme } from "./context.js";
|
|
2
|
-
import { i as
|
|
3
|
-
import { t as ToolCallBlock } from "./tool-call-block-
|
|
2
|
+
import { i as primaryTint, r as inkTint } from "./_colors-CcAi2FOU.js";
|
|
3
|
+
import { t as ToolCallBlock } from "./tool-call-block-CAscLGFy.js";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import { memo, useMemo } from "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -120,7 +120,7 @@ const Markdown = memo(function Markdown({ text, variant = "default" }) {
|
|
|
120
120
|
className: clsx("rounded-sm border px-1 py-0.5 font-aai-mono", scale.code),
|
|
121
121
|
style: {
|
|
122
122
|
borderColor: theme.border,
|
|
123
|
-
background:
|
|
123
|
+
background: inkTint(theme.text, theme.surface, 3),
|
|
124
124
|
...style
|
|
125
125
|
},
|
|
126
126
|
...rest,
|
|
@@ -131,7 +131,7 @@ const Markdown = memo(function Markdown({ text, variant = "default" }) {
|
|
|
131
131
|
className: "my-1.5 overflow-x-auto rounded-md border p-2.5 whitespace-pre-wrap wrap-break-word",
|
|
132
132
|
style: {
|
|
133
133
|
borderColor: theme.border,
|
|
134
|
-
background:
|
|
134
|
+
background: inkTint(theme.text, theme.surface, 3),
|
|
135
135
|
...style
|
|
136
136
|
},
|
|
137
137
|
...props
|
|
@@ -140,7 +140,7 @@ const Markdown = memo(function Markdown({ text, variant = "default" }) {
|
|
|
140
140
|
className: "my-1.5 border-l-2 pl-3",
|
|
141
141
|
style: {
|
|
142
142
|
borderColor: theme.border,
|
|
143
|
-
color:
|
|
143
|
+
color: inkTint(theme.text, theme.surface, 75),
|
|
144
144
|
...style
|
|
145
145
|
},
|
|
146
146
|
...props
|
|
@@ -193,14 +193,16 @@ const DOT_STYLES = [
|
|
|
193
193
|
}));
|
|
194
194
|
/** Animated three-dot "thinking" indicator. @internal */
|
|
195
195
|
function ThinkingDots() {
|
|
196
|
+
const theme = useTheme();
|
|
197
|
+
const muted = inkTint(theme.text, theme.surface, 75);
|
|
196
198
|
return /* @__PURE__ */ jsx("div", {
|
|
197
199
|
className: "flex items-center gap-2 text-sm font-medium min-h-5",
|
|
198
|
-
style: { color:
|
|
200
|
+
style: { color: muted },
|
|
199
201
|
children: DOT_STYLES.map((style, i) => /* @__PURE__ */ jsx("div", {
|
|
200
202
|
className: "w-1.5 h-1.5 rounded-full",
|
|
201
203
|
style: {
|
|
202
204
|
...style,
|
|
203
|
-
background:
|
|
205
|
+
background: muted
|
|
204
206
|
}
|
|
205
207
|
}, i))
|
|
206
208
|
});
|
|
@@ -243,7 +245,7 @@ const MessageBubble = memo(function MessageBubble({ message, theme }) {
|
|
|
243
245
|
className: "flex flex-col gap-1 max-w-[82%]",
|
|
244
246
|
children: [/* @__PURE__ */ jsx("span", {
|
|
245
247
|
className: "text-[10px] font-medium tracking-[1.2px] uppercase leading-none",
|
|
246
|
-
style: { color:
|
|
248
|
+
style: { color: inkTint(theme.text, theme.surface, 65) },
|
|
247
249
|
children: "Agent"
|
|
248
250
|
}), /* @__PURE__ */ jsx("div", {
|
|
249
251
|
className: "wrap-break-word text-[15px] font-normal leading-[23px]",
|
|
@@ -347,7 +349,7 @@ const MessageList = memo(function MessageList({ className }) {
|
|
|
347
349
|
}),
|
|
348
350
|
userTranscript !== null && /* @__PURE__ */ jsx(UserBubble, {
|
|
349
351
|
theme,
|
|
350
|
-
color:
|
|
352
|
+
color: inkTint(theme.text, theme.surface, 65),
|
|
351
353
|
children: userTranscript ? userTranscript : /* @__PURE__ */ jsx(ThinkingDots, {})
|
|
352
354
|
}),
|
|
353
355
|
showThinking && /* @__PURE__ */ jsx(ThinkingDots, {})
|
|
@@ -28,6 +28,35 @@ function buildAgentUrl(platformUrl, endpointPath) {
|
|
|
28
28
|
}
|
|
29
29
|
const AGENT_DEFAULT = {};
|
|
30
30
|
/**
|
|
31
|
+
* Per-attempt deadline for the `client-config` lookup.
|
|
32
|
+
*
|
|
33
|
+
* A request issued while the platform is restarting or saturated can HANG
|
|
34
|
+
* rather than fail — the proxy holds the socket open — and a browser fetch
|
|
35
|
+
* has no timeout of its own. Every other failure here is already handled
|
|
36
|
+
* (`null`, then the same-origin fallback), but a hang is not a failure: the
|
|
37
|
+
* promise simply never settles.
|
|
38
|
+
*
|
|
39
|
+
* That is unrecoverable rather than merely slow, because this lookup runs
|
|
40
|
+
* inside the session's WebSocket URL *provider*. partysocket awaits the
|
|
41
|
+
* provider under `_connectLock` and arms its own `connectionTimeout` only
|
|
42
|
+
* AFTER the URL resolves, so a hung lookup means no socket is ever
|
|
43
|
+
* constructed, no `error`/`close` ever fires, and none of the 10 reconnect
|
|
44
|
+
* attempts ever happen — the session sits on "connecting" forever, and stays
|
|
45
|
+
* there long after the server is back. Reproduced: zero sockets opened.
|
|
46
|
+
*
|
|
47
|
+
* A timed-out attempt therefore degrades exactly like any other failed one —
|
|
48
|
+
* `null`, so `serverIsBroker` stays unlatched and the attempt falls through
|
|
49
|
+
* to the same-origin `websocket` path, whose failure re-enters the normal
|
|
50
|
+
* backoff and re-fetches this on the next attempt.
|
|
51
|
+
*
|
|
52
|
+
* Sized well above the real work (one same-origin JSON GET that reads the
|
|
53
|
+
* agent's row) and well under a user's patience — the same 10s the studio's
|
|
54
|
+
* gating reads use for the identical hazard.
|
|
55
|
+
*
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
const CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS = 1e4;
|
|
59
|
+
/**
|
|
31
60
|
* Fetch the agent's client config, reporting `null` when the lookup did not
|
|
32
61
|
* produce an answer (network error, non-2xx, unparsable body).
|
|
33
62
|
*
|
|
@@ -46,7 +75,7 @@ const AGENT_DEFAULT = {};
|
|
|
46
75
|
async function loadClientConfig(platformUrl, fetchFn) {
|
|
47
76
|
const doFetch = fetchFn ?? ((input, init) => globalThis.fetch(input, init));
|
|
48
77
|
try {
|
|
49
|
-
const resp = await doFetch(buildAgentUrl(platformUrl, CLIENT_CONFIG_PATH).href);
|
|
78
|
+
const resp = await doFetch(buildAgentUrl(platformUrl, CLIENT_CONFIG_PATH).href, { signal: AbortSignal.timeout(CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS) });
|
|
50
79
|
if (!resp.ok) return null;
|
|
51
80
|
const parsed = ClientConfigResponseSchema.safeParse(await resp.json());
|
|
52
81
|
return parsed.success ? parsed.data : null;
|
|
@@ -174,6 +203,129 @@ async function initAudioCapture(conn, msg, deps) {
|
|
|
174
203
|
}
|
|
175
204
|
}
|
|
176
205
|
//#endregion
|
|
206
|
+
//#region session-core-reconnect.ts
|
|
207
|
+
/**
|
|
208
|
+
* Automatic reconnection for the browser session socket, built on
|
|
209
|
+
* partysocket's `ReconnectingWebSocket`. Kept out of `session-core.ts` so
|
|
210
|
+
* the state machine there reads as protocol logic, not socket plumbing.
|
|
211
|
+
*/
|
|
212
|
+
/**
|
|
213
|
+
* Backoff for automatic reconnects after an unexpected close (partysocket):
|
|
214
|
+
* exponential from 1s, capped at 15s, giving up after 10 attempts. Applies
|
|
215
|
+
* only to the default socket implementation — an injected
|
|
216
|
+
* `options.WebSocket` (tests) never reconnects on its own.
|
|
217
|
+
*/
|
|
218
|
+
const RECONNECT_OPTIONS = {
|
|
219
|
+
minReconnectionDelay: 1e3,
|
|
220
|
+
maxReconnectionDelay: 15e3,
|
|
221
|
+
reconnectionDelayGrowFactor: 2,
|
|
222
|
+
maxRetries: 10
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Open partysocket's reconnecting WebSocket. The URL is a *provider*,
|
|
226
|
+
* re-evaluated on every attempt (async supported), so each retry picks up
|
|
227
|
+
* the current broker-named endpoint and resume URL rather than the ones the
|
|
228
|
+
* session started with.
|
|
229
|
+
*/
|
|
230
|
+
function openReconnectingSocket(urlProvider) {
|
|
231
|
+
return new ReconnectingWebSocket(urlProvider, void 0, RECONNECT_OPTIONS);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* True while `socket` is a reconnecting socket that will retry after the
|
|
235
|
+
* close event currently being handled. partysocket schedules the retry
|
|
236
|
+
* *before* dispatching `close`, so `retryCount` already names the attempt
|
|
237
|
+
* just scheduled — at `maxRetries` it has given up.
|
|
238
|
+
*/
|
|
239
|
+
/**
|
|
240
|
+
* Force a fresh connection attempt on a reconnecting socket, reporting
|
|
241
|
+
* whether it was one. Used for a failure partysocket cannot see: a socket it
|
|
242
|
+
* considers open and healthy, whose peer never completed OUR handshake.
|
|
243
|
+
* Returns false for an injected `options.WebSocket` (tests), which has no
|
|
244
|
+
* reconnect machinery — the caller then treats the failure as terminal.
|
|
245
|
+
*/
|
|
246
|
+
function forceReconnect(socket) {
|
|
247
|
+
if (!(socket instanceof ReconnectingWebSocket)) return false;
|
|
248
|
+
socket.reconnect();
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
function reconnectPending(socket) {
|
|
252
|
+
return socket instanceof ReconnectingWebSocket && socket.shouldReconnect && socket.retryCount < RECONNECT_OPTIONS.maxRetries;
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region session-core-handshake.ts
|
|
256
|
+
/**
|
|
257
|
+
* The deadline on a socket that opened but never became a session.
|
|
258
|
+
*
|
|
259
|
+
* A completed WebSocket handshake is not a session. The server builds the
|
|
260
|
+
* session synchronously from its own upgrade callback and sends `config` at
|
|
261
|
+
* zero RTT (`aai/host/ws-handler.ts`), so a socket that has been open for
|
|
262
|
+
* seconds with nothing on it is not slow — its peer is not a healthy agent
|
|
263
|
+
* server. That happens: a tunnel or proxy answers the `101` while the guest
|
|
264
|
+
* behind it is wedged, or the host dies between accepting and building the
|
|
265
|
+
* session.
|
|
266
|
+
*
|
|
267
|
+
* Nothing else catches it. partysocket's `connectionTimeout` covers only the
|
|
268
|
+
* handshake and is cleared the moment `open` fires, so the session reached
|
|
269
|
+
* `state: "ready"` — painted with the same live indicator the UI gives
|
|
270
|
+
* "listening" — and stayed there permanently: no `config` means
|
|
271
|
+
* `initAudioCapture` never runs, so there is no mic, no error, no retry, and
|
|
272
|
+
* nothing on screen to say so. Measured against a server that accepts and
|
|
273
|
+
* then says nothing: `ready` at 34ms, still `ready` and errorless when the
|
|
274
|
+
* probe gave up.
|
|
275
|
+
*/
|
|
276
|
+
/** What the session reports once the budget below is spent. */
|
|
277
|
+
const HANDSHAKE_ERROR = {
|
|
278
|
+
code: "connection",
|
|
279
|
+
message: "Agent did not complete the session handshake"
|
|
280
|
+
};
|
|
281
|
+
/** How long an OPEN socket may go without a `config` frame. */
|
|
282
|
+
const HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
283
|
+
/**
|
|
284
|
+
* How many consecutive handshake timeouts to ride out before giving up.
|
|
285
|
+
*
|
|
286
|
+
* `forceReconnect` restarts partysocket's own retry budget, so this is the
|
|
287
|
+
* budget for this failure mode — without one, a permanently wedged peer would
|
|
288
|
+
* be re-dialed every ~10s forever, which is the unbounded retry loop
|
|
289
|
+
* `RECONNECT_OPTIONS.maxRetries` exists to prevent.
|
|
290
|
+
*/
|
|
291
|
+
const MAX_HANDSHAKE_TIMEOUTS = 3;
|
|
292
|
+
/**
|
|
293
|
+
* Watch one connection's handshake.
|
|
294
|
+
*
|
|
295
|
+
* `onRetry` fires when a timed-out attempt has been re-dialed (the sandbox
|
|
296
|
+
* behind the endpoint may have been replaced, and the URL provider re-brokers
|
|
297
|
+
* on the next attempt); `onExhausted` when the budget is spent, or when the
|
|
298
|
+
* socket has no reconnect machinery at all (an injected `options.WebSocket`).
|
|
299
|
+
*
|
|
300
|
+
* @internal
|
|
301
|
+
*/
|
|
302
|
+
function createHandshakeGuard(opts) {
|
|
303
|
+
let timer;
|
|
304
|
+
let timeouts = 0;
|
|
305
|
+
function disarm() {
|
|
306
|
+
if (timer === void 0) return;
|
|
307
|
+
clearTimeout(timer);
|
|
308
|
+
timer = void 0;
|
|
309
|
+
}
|
|
310
|
+
function fire() {
|
|
311
|
+
timer = void 0;
|
|
312
|
+
timeouts += 1;
|
|
313
|
+
if (timeouts < MAX_HANDSHAKE_TIMEOUTS && forceReconnect(opts.socket)) {
|
|
314
|
+
opts.onRetry();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
opts.onExhausted();
|
|
318
|
+
}
|
|
319
|
+
opts.signal.addEventListener("abort", disarm);
|
|
320
|
+
return {
|
|
321
|
+
arm() {
|
|
322
|
+
disarm();
|
|
323
|
+
timer = setTimeout(fire, HANDSHAKE_TIMEOUT_MS);
|
|
324
|
+
},
|
|
325
|
+
disarm
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
//#endregion
|
|
177
329
|
//#region session-core-messages.ts
|
|
178
330
|
/**
|
|
179
331
|
* Incoming-message handling for the voice session core.
|
|
@@ -465,43 +617,6 @@ function createMessageHandlers(deps) {
|
|
|
465
617
|
};
|
|
466
618
|
}
|
|
467
619
|
//#endregion
|
|
468
|
-
//#region session-core-reconnect.ts
|
|
469
|
-
/**
|
|
470
|
-
* Automatic reconnection for the browser session socket, built on
|
|
471
|
-
* partysocket's `ReconnectingWebSocket`. Kept out of `session-core.ts` so
|
|
472
|
-
* the state machine there reads as protocol logic, not socket plumbing.
|
|
473
|
-
*/
|
|
474
|
-
/**
|
|
475
|
-
* Backoff for automatic reconnects after an unexpected close (partysocket):
|
|
476
|
-
* exponential from 1s, capped at 15s, giving up after 10 attempts. Applies
|
|
477
|
-
* only to the default socket implementation — an injected
|
|
478
|
-
* `options.WebSocket` (tests) never reconnects on its own.
|
|
479
|
-
*/
|
|
480
|
-
const RECONNECT_OPTIONS = {
|
|
481
|
-
minReconnectionDelay: 1e3,
|
|
482
|
-
maxReconnectionDelay: 15e3,
|
|
483
|
-
reconnectionDelayGrowFactor: 2,
|
|
484
|
-
maxRetries: 10
|
|
485
|
-
};
|
|
486
|
-
/**
|
|
487
|
-
* Open partysocket's reconnecting WebSocket. The URL is a *provider*,
|
|
488
|
-
* re-evaluated on every attempt (async supported), so each retry picks up
|
|
489
|
-
* the current broker-named endpoint and resume URL rather than the ones the
|
|
490
|
-
* session started with.
|
|
491
|
-
*/
|
|
492
|
-
function openReconnectingSocket(urlProvider) {
|
|
493
|
-
return new ReconnectingWebSocket(urlProvider, void 0, RECONNECT_OPTIONS);
|
|
494
|
-
}
|
|
495
|
-
/**
|
|
496
|
-
* True while `socket` is a reconnecting socket that will retry after the
|
|
497
|
-
* close event currently being handled. partysocket schedules the retry
|
|
498
|
-
* *before* dispatching `close`, so `retryCount` already names the attempt
|
|
499
|
-
* just scheduled — at `maxRetries` it has given up.
|
|
500
|
-
*/
|
|
501
|
-
function reconnectPending(socket) {
|
|
502
|
-
return socket instanceof ReconnectingWebSocket && socket.shouldReconnect && socket.retryCount < RECONNECT_OPTIONS.maxRetries;
|
|
503
|
-
}
|
|
504
|
-
//#endregion
|
|
505
620
|
//#region session-core-url.ts
|
|
506
621
|
/** Build the session WebSocket URL from the platform URL and resume state. */
|
|
507
622
|
function buildWsUrl(platformUrl, resume, sessionId) {
|
|
@@ -743,18 +858,46 @@ function createSessionCore(options) {
|
|
|
743
858
|
socket.binaryType = "arraybuffer";
|
|
744
859
|
conn.ws = socket;
|
|
745
860
|
let socketErrored = false;
|
|
861
|
+
const handshake = createHandshakeGuard({
|
|
862
|
+
socket,
|
|
863
|
+
signal: sig,
|
|
864
|
+
onRetry: () => {
|
|
865
|
+
cleanupAudio();
|
|
866
|
+
conn.generation.bump();
|
|
867
|
+
updateState({
|
|
868
|
+
state: "connecting",
|
|
869
|
+
recording: false
|
|
870
|
+
});
|
|
871
|
+
},
|
|
872
|
+
onExhausted: () => {
|
|
873
|
+
cleanupAudio();
|
|
874
|
+
controller.abort();
|
|
875
|
+
socket.close();
|
|
876
|
+
conn.ws = null;
|
|
877
|
+
updateState({
|
|
878
|
+
state: "error",
|
|
879
|
+
error: HANDSHAKE_ERROR,
|
|
880
|
+
running: false,
|
|
881
|
+
recording: false
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
});
|
|
746
885
|
socket.addEventListener("open", () => {
|
|
747
886
|
updateState({ state: "ready" });
|
|
887
|
+
handshake.arm();
|
|
748
888
|
}, { signal: sig });
|
|
749
889
|
socket.addEventListener("message", (event) => {
|
|
750
890
|
const config = handleMessage(event.data);
|
|
751
|
-
if (config)
|
|
891
|
+
if (!config) return;
|
|
892
|
+
handshake.disarm();
|
|
893
|
+
onServerConfig(config);
|
|
752
894
|
}, { signal: sig });
|
|
753
895
|
socket.addEventListener("error", () => {
|
|
754
896
|
socketErrored = true;
|
|
755
897
|
}, { signal: sig });
|
|
756
898
|
socket.addEventListener("close", () => {
|
|
757
899
|
if (sig.aborted) return;
|
|
900
|
+
handshake.disarm();
|
|
758
901
|
cleanupAudio();
|
|
759
902
|
if (!conn.retiredByServer && reconnectPending(socket)) {
|
|
760
903
|
conn.generation.bump();
|
|
@@ -803,10 +946,8 @@ function createSessionCore(options) {
|
|
|
803
946
|
sendJson({ type: "reset" });
|
|
804
947
|
return;
|
|
805
948
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
updateState({ running: true });
|
|
809
|
-
connect();
|
|
949
|
+
end();
|
|
950
|
+
start();
|
|
810
951
|
}
|
|
811
952
|
function disconnect() {
|
|
812
953
|
teardownConnection();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SessionError } from "./types.ts";
|
|
2
|
+
/** What the session reports once the budget below is spent. */
|
|
3
|
+
export declare const HANDSHAKE_ERROR: SessionError;
|
|
4
|
+
export type HandshakeGuard = {
|
|
5
|
+
/** Start the deadline for the attempt that just opened. */
|
|
6
|
+
arm(): void;
|
|
7
|
+
/** Stop it — `config` arrived, or this socket is closing. */
|
|
8
|
+
disarm(): void;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Watch one connection's handshake.
|
|
12
|
+
*
|
|
13
|
+
* `onRetry` fires when a timed-out attempt has been re-dialed (the sandbox
|
|
14
|
+
* behind the endpoint may have been replaced, and the URL provider re-brokers
|
|
15
|
+
* on the next attempt); `onExhausted` when the budget is spent, or when the
|
|
16
|
+
* socket has no reconnect machinery at all (an injected `options.WebSocket`).
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare function createHandshakeGuard(opts: {
|
|
21
|
+
socket: unknown;
|
|
22
|
+
signal: AbortSignal;
|
|
23
|
+
onRetry: () => void;
|
|
24
|
+
onExhausted: () => void;
|
|
25
|
+
}): HandshakeGuard;
|
|
@@ -17,4 +17,12 @@ export declare function openReconnectingSocket(urlProvider: () => Promise<string
|
|
|
17
17
|
* *before* dispatching `close`, so `retryCount` already names the attempt
|
|
18
18
|
* just scheduled — at `maxRetries` it has given up.
|
|
19
19
|
*/
|
|
20
|
+
/**
|
|
21
|
+
* Force a fresh connection attempt on a reconnecting socket, reporting
|
|
22
|
+
* whether it was one. Used for a failure partysocket cannot see: a socket it
|
|
23
|
+
* considers open and healthy, whose peer never completed OUR handshake.
|
|
24
|
+
* Returns false for an injected `options.WebSocket` (tests), which has no
|
|
25
|
+
* reconnect machinery — the caller then treats the failure as terminal.
|
|
26
|
+
*/
|
|
27
|
+
export declare function forceReconnect(socket: unknown): boolean;
|
|
20
28
|
export declare function reconnectPending(socket: unknown): boolean;
|
package/dist/session-core.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createSessionCore } from "./session-core-
|
|
1
|
+
import { t as createSessionCore } from "./session-core-BoB7kTzL.js";
|
|
2
2
|
export { createSessionCore };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useTheme } from "./context.js";
|
|
2
|
-
import { r as
|
|
2
|
+
import { r as inkTint } from "./_colors-CcAi2FOU.js";
|
|
3
3
|
import { t as Eyebrow } from "./eyebrow-C6ZFuiz6.js";
|
|
4
4
|
import { n as truncate, r as tryParseJSON } from "./_utils-CsqbIVGI.js";
|
|
5
5
|
import clsx from "clsx";
|
|
@@ -60,22 +60,22 @@ function ToolCallRow({ title, detail, pending = false, icon, variant = "default"
|
|
|
60
60
|
children: icon
|
|
61
61
|
}) : /* @__PURE__ */ jsx(Eyebrow, {
|
|
62
62
|
className: "shrink-0",
|
|
63
|
-
style: { color:
|
|
63
|
+
style: { color: inkTint(theme.text, theme.bg, 65) },
|
|
64
64
|
children: "Tool"
|
|
65
65
|
}),
|
|
66
66
|
/* @__PURE__ */ jsx("span", {
|
|
67
|
-
className: clsx("
|
|
67
|
+
className: clsx("min-w-0 truncate font-aai-mono font-medium", sizes.title, pending && "tool-shimmer"),
|
|
68
68
|
style: { color: theme.text },
|
|
69
69
|
children: title
|
|
70
70
|
}),
|
|
71
71
|
/* @__PURE__ */ jsx("span", {
|
|
72
72
|
className: clsx("font-aai-mono truncate flex-1 min-w-0", sizes.title),
|
|
73
|
-
style: { color:
|
|
73
|
+
style: { color: inkTint(theme.text, theme.bg, 65) },
|
|
74
74
|
children: detail
|
|
75
75
|
}),
|
|
76
76
|
canExpand && /* @__PURE__ */ jsx("span", {
|
|
77
77
|
className: clsx("shrink-0 transition-transform duration-150", sizes.chevron, isOpen && "rotate-90"),
|
|
78
|
-
style: { color:
|
|
78
|
+
style: { color: inkTint(theme.text, theme.bg, 65) },
|
|
79
79
|
children: "▶"
|
|
80
80
|
})
|
|
81
81
|
]
|
|
@@ -167,7 +167,7 @@ const ToolCallBlock = memo(function ToolCallBlock({ toolCall, className }) {
|
|
|
167
167
|
children: String(toolCall.args.code)
|
|
168
168
|
}), formatted && /* @__PURE__ */ jsx("pre", {
|
|
169
169
|
className: "font-aai-mono text-xs px-3.5 py-3 m-0 whitespace-pre-wrap wrap-break-word",
|
|
170
|
-
style: { color:
|
|
170
|
+
style: { color: inkTint(theme.text, theme.surface, 75) },
|
|
171
171
|
children: formatted
|
|
172
172
|
})] }) : void 0
|
|
173
173
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexkroman1/aai-ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"remark-gfm": "^4.0.1",
|
|
29
29
|
"use-stick-to-bottom": "^1.1.6",
|
|
30
30
|
"use-sync-external-store": "^1.6.0",
|
|
31
|
-
"@alexkroman1/aai": "5.
|
|
31
|
+
"@alexkroman1/aai": "5.13.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"react": "^19.0.0",
|
package/dist/_colors-Bfh3-BVE.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//#region components/_colors.ts
|
|
2
|
-
/**
|
|
3
|
-
* Shared tints used by the default components (AssemblyAI design system,
|
|
4
|
-
* "website refresh": warm neutrals over the cream/white surfaces).
|
|
5
|
-
*
|
|
6
|
-
* These sit on top of the {@link ClientTheme} colors (which own the opaque
|
|
7
|
-
* palette) and are intentionally not themeable: they are the warm-gray text
|
|
8
|
-
* steps and ink alpha layers the refresh uses over any light surface.
|
|
9
|
-
*/
|
|
10
|
-
/** Muted text — subtitles, secondary labels, thinking dots (fg-muted). */
|
|
11
|
-
const TEXT_MUTED = "#57534B";
|
|
12
|
-
/** Faint text — live transcripts, state indicator, start-screen subtitle (warm-500). */
|
|
13
|
-
const TEXT_FAINT = "#6F6A60";
|
|
14
|
-
/** Subtle surface tint — message bubbles, tool-call blocks. */
|
|
15
|
-
const SURFACE_TINT = "rgba(20,18,12,0.03)";
|
|
16
|
-
/** Error red tuned for warm light surfaces. */
|
|
17
|
-
const ERROR_COLOR = "#B3261E";
|
|
18
|
-
/** Amber used by the "thinking" state indicator. */
|
|
19
|
-
const THINKING_COLOR = "#B98900";
|
|
20
|
-
/**
|
|
21
|
-
* Derive the user-bubble fill/edge from the theme primary (the mock's
|
|
22
|
-
* indigo-50 background with an indigo-100 border), so custom themes keep a
|
|
23
|
-
* coherent tinted bubble instead of a hardcoded indigo.
|
|
24
|
-
*/
|
|
25
|
-
function primaryTint(primary, surface, pct) {
|
|
26
|
-
return `color-mix(in srgb, ${primary} ${pct}%, ${surface})`;
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
export { THINKING_COLOR as a, TEXT_MUTED as i, SURFACE_TINT as n, primaryTint as o, TEXT_FAINT as r, ERROR_COLOR as t };
|
|
@@ -1,2 +0,0 @@
|
|
|
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-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking: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-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;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--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-in-out:cubic-bezier(.4, 0, .2, 1);--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);--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}.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)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.ml-auto{margin-left:auto}.box-border{box-sizing:border-box}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-\[7px\]{height:7px}.h-screen{height:100vh}.max-h-64{max-height:calc(var(--spacing) * 64)}.min-h-0{min-height:0}.min-h-5{min-height:calc(var(--spacing) * 5)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-\[7px\]{width:7px}.w-fit{width:fit-content}.w-full{width:100%}.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-\[60\%\]{max-width:60%}.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}.border-collapse{border-collapse:collapse}.rotate-90{rotate:90deg}.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}.flex-col{flex-direction:column}.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)}.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:3.40282e38px}.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-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-none{--tw-border-style:none;border-style:none}.bg-transparent{background-color:#0000}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-7{padding:calc(var(--spacing) * 7)}.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-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-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-3{padding-left:calc(var(--spacing) * 3)}.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)}.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-\[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}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.ring{--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)}.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-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}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.first\:mt-0:first-child{margin-top:0}.last\:mb-0:last-child{margin-bottom:0}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:px-16{padding-inline:calc(var(--spacing) * 16)}.sm\:py-14{padding-block:calc(var(--spacing) * 14)}}}@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}@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-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-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}
|