@icanbwell/baileyai-chat-ui 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -121,6 +121,83 @@ that case. If a host needs `privacyNote` to survive this (e.g. it's a persistent
121
121
  disclosure rather than a first-impression nicety), pass `privacyNote={{ ..., alwaysVisible: true }}`
122
122
  to render it in every state, not just the empty one.
123
123
 
124
+ ## Resuming a conversation
125
+
126
+ `useBaileyChat` also returns `loadMessages(messages)`, for restoring a transcript a host fetched
127
+ from its own backend — resuming a previous conversation, or switching to a different one a user
128
+ picked from a history list:
129
+
130
+ ```tsx
131
+ const chat = useBaileyChat({ transport, model: 'bailey-default', instructions: 'You are Bailey...' });
132
+
133
+ useEffect(() => {
134
+ if (restoredTranscript) {
135
+ chat.loadMessages(restoredTranscript);
136
+ }
137
+ }, [restoredTranscript]);
138
+ ```
139
+
140
+ Call it once per conversation load — from an effect keyed on the loaded data, not on every
141
+ render. `hidden` messages (e.g. a restored page-context turn originally sent via `sendHidden`)
142
+ are excluded from the visible transcript but stay part of the model-context history sent on the
143
+ next turn. Any in-flight turn is aborted first, and every restored message is normalized to
144
+ `streaming: false` regardless of what it claims, since a restored message can never legitimately
145
+ be mid-stream.
146
+
147
+ `loadMessages` only replaces `useBaileyChat`'s own state — a host still owns fetching the
148
+ transcript and its own loading/error UI, and owns conversation identity (which id is active,
149
+ where it's persisted) entirely outside this package.
150
+
151
+ ### Known limitations
152
+
153
+ - **Truncated messages from a failed turn look identical to a finished one.** If a backend
154
+ persists partial content from a turn that errored mid-stream, `loadMessages` has no way to tell
155
+ that apart from a normal completed message — it renders with `streaming: false` either way.
156
+ There is currently no signal, client- or server-side, that distinguishes "finished normally"
157
+ from "cut off by an error." This is a limitation of what gets persisted upstream, not something
158
+ `loadMessages` itself can detect or fix.
159
+ - **`loadMessages` never sorts or validates the order it's given.** It renders the array exactly
160
+ as provided. This is deliberate, not an oversight — a host owns fetching and correctness of the
161
+ transcript it hands over, and having this package silently reorder or repair a malformed array
162
+ would mask a real upstream bug instead of surfacing it.
163
+ - **Two consecutive `user`-role turns are not an error.** A restored transcript that ends on a
164
+ hidden message with no reply after it (e.g. a session interrupted right after a page-context
165
+ injection), followed by a new `send()`, produces two consecutive user-role entries in the
166
+ history handed to the transport. This is harmless: LangChain's `merge_message_runs` (used by
167
+ `ChatBedrockConverse`) and Anthropic's Messages API both merge consecutive same-role turns into
168
+ one before the model ever sees them — no error, no rejection. At most this is a cosmetic
169
+ oddity (the model sees one combined turn instead of two), never a failure.
170
+ - **Rapid conversation-switching is the host's responsibility.** Calling `loadMessages` again
171
+ before a prior `loadMessages`-triggered fetch resolves (e.g. a user clicking quickly through a
172
+ history list) is not guarded against by this hook — `loadMessages` itself is synchronous and
173
+ stateless between calls, with no notion of which fetch is "newest." A host must abort or ignore
174
+ stale fetches on its own side before calling `loadMessages` with fresher data.
175
+
176
+ ### Reacting to "New chat"
177
+
178
+ `BaileyChatPanel`'s built-in "New chat" button calls whatever `newChat` is on the `chat` object
179
+ it was given — read off `props.chat`, not `useBaileyChat` directly. A host that needs to react to
180
+ a reset (e.g. to also clear its own persisted conversation id) wraps `newChat` before handing
181
+ `chat` to the panel:
182
+
183
+ ```tsx
184
+ const chatForPanel = useMemo(
185
+ () => ({
186
+ ...chat,
187
+ newChat: () => {
188
+ chat.newChat(); // package clears its own state
189
+ onHostReset(); // host clears whatever it owns (e.g. a persisted conversation id)
190
+ },
191
+ }),
192
+ [chat]
193
+ );
194
+
195
+ <BaileyChatPanel chat={chatForPanel} />;
196
+ ```
197
+
198
+ `newChat()` is fully synchronous, so the wrapper returning is the only "did it finish" signal a
199
+ host needs — no callback or promise required.
200
+
124
201
  ## Privacy note
125
202
 
126
203
  Pass `privacyNote` to render a short compliance/privacy disclosure as a footer beneath the input row — there's no default copy or link, so nothing renders unless a host supplies one:
@@ -6,7 +6,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.
6
6
 
7
7
  `),n=t.pop()??``,r=[],i=!1;for(let e of t){let t=e.split(`
8
8
  `).filter(e=>e.length>0),n=`message`,a=[];for(let e of t)e.startsWith(`event:`)?n=e.slice(6).trim():e.startsWith(`data:`)&&a.push(e.slice(5).trim());if(a.length===0)continue;let o=a.join(`
9
- `);if(o===`[DONE]`){i=!0;continue}let s;try{s=JSON.parse(o)}catch{s=void 0}let c=s;if(n===`error`){let e=typeof c?.message==`string`?c.message:o;r.push({type:`error`,message:e})}else if(c?.type===`response.output_text.delta`&&typeof c.delta==`string`){let e=S(c.delta);e&&r.push({type:`response.output_text.delta`,delta:e})}else c&&typeof c.type==`string`?r.push(c):n!==`message`&&r.push({type:`info`,message:`${n}: ${o}`})}return{events:r,remainder:n,done:i}}var w=200,T=15e4,E=()=>typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`bailey-${Date.now()}-${Math.random().toString(36).slice(2)}`,ee=(e,t,n)=>{if(e===401||e===403)return`Bailey isn't reachable with your current login.`;let r=`Bailey request failed (status ${e??`network error`}).`,i=(n||t||``).trim();return i?`${r} ${i.length>w?`${i.slice(0,w)}…`:i}`:r},D=({transport:e,model:t,instructions:n,tools:r=[],toolChoice:i,firstUserMessagePrefix:a,onAssistantMessageComplete:o,idleTimeoutMs:s=T})=>{let[c,u]=(0,l.useState)([]),[d,f]=(0,l.useState)([]),[p,m]=(0,l.useState)(null),[h,g]=(0,l.useState)(`idle`),[_,v]=(0,l.useState)(null),y=(0,l.useRef)(null),b=(0,l.useRef)(``),S=(0,l.useRef)(0),w=(0,l.useRef)([]);(0,l.useEffect)(()=>{w.current=c},[c]);let D=(0,l.useRef)([]),O=(0,l.useRef)(new Map),k=(0,l.useRef)(new Map),A=(0,l.useRef)(null),j=(0,l.useCallback)(()=>{A.current!==null&&(clearTimeout(A.current),A.current=null)},[]),M=(0,l.useCallback)(e=>{j(),A.current=setTimeout(()=>{e.abort(new DOMException(`The assistant took too long to respond. Please try again.`,`TimeoutError`))},s)},[j,s]);(0,l.useEffect)(()=>()=>{y.current?.abort(),j()},[j]);let N=(0,l.useCallback)((e,t,n)=>{let r=e=>{n.push(e),f(t=>[...t,e])};if(t.type===`response.output_text.delta`){if(!t.delta)return!1;let n=O.current.get(e)??{raw:``,emittedCount:0};n.raw+=t.delta;let{cleanedText:i,matches:a}=x(n.raw),o=i.trim(),s=a.slice(n.emittedCount);if(n.emittedCount=a.length,O.current.set(e,n),k.current.set(e,o),u(t=>t.map(t=>t.id===e?{...t,content:o}:t)),s.length>0){let e=Date.now(),t=S.current;s.forEach(n=>r({kind:`pseudo_tool_call`,name:n.name,args:n.args,at:e,turnSentAt:t}))}return!0}if(t.type===`response.output_item.added`||t.type===`response.output_item.done`){let e=t.item;if(e.type===`function_call`||e.type===`mcp_call`){let n=Date.now(),i=S.current,a=e.name||`unknown_tool`;return r(t.type===`response.output_item.added`?{kind:`tool_start`,name:a,args:e.arguments,at:n,turnSentAt:i}:{kind:`tool_end`,name:a,args:e.arguments,at:n,turnSentAt:i,output:e.output,isError:e.is_error,runtimeSeconds:e.runtime_seconds}),!0}return!1}return t.type===`task.progress`?(r({kind:`progress`,status:t.status,message:t.message,at:Date.now(),turnSentAt:S.current}),!0):t.type===`response.output_text.done`||t.type===`response.created`||t.type===`response.completed`?!1:t.type===`info`?(r({kind:`info`,message:t.message,at:Date.now(),turnSentAt:S.current}),!0):(r({kind:`raw`,eventType:t.type,raw:JSON.stringify(t),at:Date.now(),turnSentAt:S.current}),!0)},[]),P=(0,l.useCallback)(async s=>{g(`streaming`),v(null);let c=Date.now();S.current=c;let l=E(),d={id:l,role:`assistant`,content:``,streaming:!0,createdAt:c};u(e=>[...e,d]),D.current=[...s,d];let p=s.findIndex(e=>e.role===`user`&&!e.hidden),h=s.map((e,t)=>t===p&&a?{role:e.role,content:`${a}${e.content}`}:{role:e.role,content:e.content});m({model:t,systemPrompt:n,messages:h,tools:r,toolChoice:i,stream:!0,sentAt:c,streamStats:{chunkCount:0,firstChunkAt:null,lastChunkAt:null}});let _=new AbortController;y.current=_,M(_);let b=``,x=null,w=!1,T=!1,A=[],P=(e,t)=>{g(`error`),v(e);let n={kind:`error`,message:e,at:Date.now(),turnSentAt:c,...t};A.push(n),f(e=>[...e,n])},F=(e,t)=>{e.forEach(e=>{if(e.type===`error`){x=e.message;let t={kind:`error`,message:e.message,at:Date.now(),turnSentAt:c};A.push(t),f(e=>[...e,t]);return}e.type===`response.output_text.delta`&&e.delta&&(T=!0),N(l,e,A)&&(w=!0)}),t&&u(e=>e.map(e=>e.id===l?{...e,streaming:!1}:e))};try{let{status:a,text:s,errorMessage:u}=await e.streamChat({model:t,instructions:n,input:h,tools:r,toolChoice:i,signal:_.signal,onChunk:e=>{M(_),b+=e;let{events:t,remainder:n,done:r}=C(b);b=n,F(t,r);let i=Date.now();m(e=>e&&e.sentAt===c?{...e,streamStats:{chunkCount:e.streamStats.chunkCount+1,firstChunkAt:e.streamStats.firstChunkAt??i,lastChunkAt:i}}:e)},onRequestId:e=>{m(t=>t&&t.sentAt===c?{...t,requestId:e}:t)}});if(b.trim()){let{events:e,done:t}=C(`${b}\n\n`);b=``,F(e,t)}if(x){g(`error`),v(x);return}if(a===void 0||a>=400){P(ee(a,s,u),{httpStatus:a,rawBody:s||void 0});return}if(!w){P(`Bailey returned an empty response.`);return}if(!T){P(`Bailey ran some tools but didn't return an answer. Try asking again.`);return}g(`idle`);let d=k.current.get(l)??``;m(e=>e&&e.sentAt===c?{...e,response:{content:d}}:e),o&&await o({id:l,role:`assistant`,content:d,streaming:!1},A)}catch(e){let t=e;if(t?.name===`TimeoutError`){P(t.message,{source:`client-timeout`});return}if(t?.name===`AbortError`){g(`idle`);return}P(t?.message||`Bailey request failed.`)}finally{j();let e=k.current.get(l)??``;O.current.delete(l),k.current.delete(l),u(e=>e.flatMap(e=>e.id===l?e.content?[{...e,streaming:!1}]:[]:[e])),D.current=D.current.flatMap(t=>t.id===l?e?[{...t,content:e,streaming:!1}]:[]:[t])}},[e,t,n,r,i,a,o,N,M,j]),F=(0,l.useCallback)(e=>{w.current=e,u(e)},[]);return{messages:c,traceEvents:d,lastRequest:p,status:h,error:_,send:(0,l.useCallback)(e=>{let t=e.trim();if(!t)return;b.current=t;let n={id:E(),role:`user`,content:t,createdAt:Date.now()},r=[...D.current,n];D.current=r,F([...w.current,n]),P(r)},[P,F]),sendHidden:(0,l.useCallback)(e=>{if(h===`streaming`)return;let t=e.trim();if(!t)return;b.current=t;let n={id:E(),role:`user`,content:t,createdAt:Date.now(),hidden:!0},r=[...D.current,n];D.current=r,P(r)},[P,h]),stop:(0,l.useCallback)(()=>{y.current?.abort()},[]),retryLast:(0,l.useCallback)(()=>{if(h===`streaming`||!b.current)return;let e=w.current,t=e[e.length-1],n=t&&t.role===`assistant`?e.slice(0,-1):e;F(n);let r=D.current,i=r[r.length-1],a=i&&i.role===`assistant`?r.slice(0,-1):r;D.current=a,P(a)},[P,F,h]),clearTrace:(0,l.useCallback)(()=>f([]),[]),clearError:(0,l.useCallback)(()=>{v(null),g(e=>e===`error`?`idle`:e)},[]),newChat:(0,l.useCallback)(()=>{y.current?.abort(),F([]),D.current=[],f([]),m(null),g(`idle`),v(null),b.current=``},[F])}};function O(...e){return e.filter(e=>!!(e&&e.trim())).join(`
9
+ `);if(o===`[DONE]`){i=!0;continue}let s;try{s=JSON.parse(o)}catch{s=void 0}let c=s;if(n===`error`){let e=typeof c?.message==`string`?c.message:o;r.push({type:`error`,message:e})}else if(c?.type===`response.output_text.delta`&&typeof c.delta==`string`){let e=S(c.delta);e&&r.push({type:`response.output_text.delta`,delta:e})}else c&&typeof c.type==`string`?r.push(c):n!==`message`&&r.push({type:`info`,message:`${n}: ${o}`})}return{events:r,remainder:n,done:i}}var w=200,T=15e4,E=()=>typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`bailey-${Date.now()}-${Math.random().toString(36).slice(2)}`,ee=(e,t,n)=>{if(e===401||e===403)return`Bailey isn't reachable with your current login.`;let r=`Bailey request failed (status ${e??`network error`}).`,i=(n||t||``).trim();return i?`${r} ${i.length>w?`${i.slice(0,w)}…`:i}`:r},D=({transport:e,model:t,instructions:n,tools:r=[],toolChoice:i,firstUserMessagePrefix:a,onAssistantMessageComplete:o,idleTimeoutMs:s=T})=>{let[c,u]=(0,l.useState)([]),[d,f]=(0,l.useState)([]),[p,m]=(0,l.useState)(null),[h,g]=(0,l.useState)(`idle`),[_,v]=(0,l.useState)(null),y=(0,l.useRef)(null),b=(0,l.useRef)(``),S=(0,l.useRef)(0),w=(0,l.useRef)([]);(0,l.useEffect)(()=>{w.current=c},[c]);let D=(0,l.useRef)([]),O=(0,l.useRef)(new Map),k=(0,l.useRef)(new Map),A=(0,l.useRef)(null),j=(0,l.useCallback)(()=>{A.current!==null&&(clearTimeout(A.current),A.current=null)},[]),M=(0,l.useCallback)(e=>{j(),A.current=setTimeout(()=>{e.abort(new DOMException(`The assistant took too long to respond. Please try again.`,`TimeoutError`))},s)},[j,s]);(0,l.useEffect)(()=>()=>{y.current?.abort(),j()},[j]);let N=(0,l.useCallback)((e,t,n)=>{let r=e=>{n.push(e),f(t=>[...t,e])};if(t.type===`response.output_text.delta`){if(!t.delta)return!1;let n=O.current.get(e)??{raw:``,emittedCount:0};n.raw+=t.delta;let{cleanedText:i,matches:a}=x(n.raw),o=i.trim(),s=a.slice(n.emittedCount);if(n.emittedCount=a.length,O.current.set(e,n),k.current.set(e,o),u(t=>t.map(t=>t.id===e?{...t,content:o}:t)),s.length>0){let e=Date.now(),t=S.current;s.forEach(n=>r({kind:`pseudo_tool_call`,name:n.name,args:n.args,at:e,turnSentAt:t}))}return!0}if(t.type===`response.output_item.added`||t.type===`response.output_item.done`){let e=t.item;if(e.type===`function_call`||e.type===`mcp_call`){let n=Date.now(),i=S.current,a=e.name||`unknown_tool`;return r(t.type===`response.output_item.added`?{kind:`tool_start`,name:a,args:e.arguments,at:n,turnSentAt:i}:{kind:`tool_end`,name:a,args:e.arguments,at:n,turnSentAt:i,output:e.output,isError:e.is_error,runtimeSeconds:e.runtime_seconds}),!0}return!1}return t.type===`task.progress`?(r({kind:`progress`,status:t.status,message:t.message,at:Date.now(),turnSentAt:S.current}),!0):t.type===`response.output_text.done`||t.type===`response.created`||t.type===`response.completed`?!1:t.type===`info`?(r({kind:`info`,message:t.message,at:Date.now(),turnSentAt:S.current}),!0):(r({kind:`raw`,eventType:t.type,raw:JSON.stringify(t),at:Date.now(),turnSentAt:S.current}),!0)},[]),P=(0,l.useCallback)(async s=>{g(`streaming`),v(null);let c=Date.now();S.current=c;let l=E(),d={id:l,role:`assistant`,content:``,streaming:!0,createdAt:c};u(e=>[...e,d]),D.current=[...s,d];let p=s.findIndex(e=>e.role===`user`&&!e.hidden),h=s.map((e,t)=>t===p&&a?{role:e.role,content:`${a}${e.content}`}:{role:e.role,content:e.content});m({model:t,systemPrompt:n,messages:h,tools:r,toolChoice:i,stream:!0,sentAt:c,streamStats:{chunkCount:0,firstChunkAt:null,lastChunkAt:null}});let _=new AbortController;y.current=_,M(_);let b=``,x=null,w=!1,T=!1,A=[],P=(e,t)=>{g(`error`),v(e);let n={kind:`error`,message:e,at:Date.now(),turnSentAt:c,...t};A.push(n),f(e=>[...e,n])},F=(e,t)=>{e.forEach(e=>{if(e.type===`error`){x=e.message;let t={kind:`error`,message:e.message,at:Date.now(),turnSentAt:c};A.push(t),f(e=>[...e,t]);return}e.type===`response.output_text.delta`&&e.delta&&(T=!0),N(l,e,A)&&(w=!0)}),t&&u(e=>e.map(e=>e.id===l?{...e,streaming:!1}:e))};try{let{status:a,text:s,errorMessage:u}=await e.streamChat({model:t,instructions:n,input:h,tools:r,toolChoice:i,signal:_.signal,onChunk:e=>{M(_),b+=e;let{events:t,remainder:n,done:r}=C(b);b=n,F(t,r);let i=Date.now();m(e=>e&&e.sentAt===c?{...e,streamStats:{chunkCount:e.streamStats.chunkCount+1,firstChunkAt:e.streamStats.firstChunkAt??i,lastChunkAt:i}}:e)},onRequestId:e=>{m(t=>t&&t.sentAt===c?{...t,requestId:e}:t)}});if(b.trim()){let{events:e,done:t}=C(`${b}\n\n`);b=``,F(e,t)}if(x){g(`error`),v(x);return}if(a===void 0||a>=400){P(ee(a,s,u),{httpStatus:a,rawBody:s||void 0});return}if(!w){P(`Bailey returned an empty response.`);return}if(!T){P(`Bailey ran some tools but didn't return an answer. Try asking again.`);return}g(`idle`);let d=k.current.get(l)??``;m(e=>e&&e.sentAt===c?{...e,response:{content:d}}:e),o&&await o({id:l,role:`assistant`,content:d,streaming:!1},A)}catch(e){let t=e;if(t?.name===`TimeoutError`){P(t.message,{source:`client-timeout`});return}if(t?.name===`AbortError`){g(`idle`);return}P(t?.message||`Bailey request failed.`)}finally{j();let e=k.current.get(l)??``;O.current.delete(l),k.current.delete(l),u(e=>e.flatMap(e=>e.id===l?e.content?[{...e,streaming:!1}]:[]:[e])),D.current=D.current.flatMap(t=>t.id===l?e?[{...t,content:e,streaming:!1}]:[]:[t])}},[e,t,n,r,i,a,o,N,M,j]),F=(0,l.useCallback)(e=>{w.current=e,u(e)},[]);return{messages:c,traceEvents:d,lastRequest:p,status:h,error:_,send:(0,l.useCallback)(e=>{let t=e.trim();if(!t)return;b.current=t;let n={id:E(),role:`user`,content:t,createdAt:Date.now()},r=[...D.current,n];D.current=r,F([...w.current,n]),P(r)},[P,F]),sendHidden:(0,l.useCallback)(e=>{if(h===`streaming`)return;let t=e.trim();if(!t)return;b.current=t;let n={id:E(),role:`user`,content:t,createdAt:Date.now(),hidden:!0},r=[...D.current,n];D.current=r,P(r)},[P,h]),stop:(0,l.useCallback)(()=>{y.current?.abort()},[]),retryLast:(0,l.useCallback)(()=>{if(h===`streaming`||!b.current)return;let e=w.current,t=e[e.length-1],n=t&&t.role===`assistant`?e.slice(0,-1):e;F(n);let r=D.current,i=r[r.length-1],a=i&&i.role===`assistant`?r.slice(0,-1):r;D.current=a,P(a)},[P,F,h]),clearTrace:(0,l.useCallback)(()=>f([]),[]),clearError:(0,l.useCallback)(()=>{v(null),g(e=>e===`error`?`idle`:e)},[]),newChat:(0,l.useCallback)(()=>{y.current?.abort(),F([]),D.current=[],f([]),m(null),g(`idle`),v(null),b.current=``},[F]),loadMessages:(0,l.useCallback)(e=>{y.current?.abort();let t=e.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({...e,streaming:!1}));F(t.filter(e=>!e.hidden)),D.current=t,f([]),m(null),g(`idle`),v(null),b.current=``},[F])}};function O(...e){return e.filter(e=>!!(e&&e.trim())).join(`
10
10
 
11
11
  `)}var k=`call_tool`,A=`a tool`;function j(e,t){let n={name:e===k?A:e,args:null,viaCallTool:!1};if(!t)return n;let r;try{r=JSON.parse(t)}catch{return n}if(typeof r!=`object`||!r)return n;let i=r;if(e===k){let e=typeof i.name==`string`?i.name:void 0;if(!e)return n;let t=i.arguments;return{name:e,args:typeof t==`object`&&t?t:null,viaCallTool:!0}}return{name:e,args:i,viaCallTool:!1}}var M=5,N=e=>e.type===`text`?e.value??``:(e.children??[]).map(N).join(``),P=e=>{if(e.tagName===`a`&&e.properties?.href)return e.properties.href;for(let t of e.children??[]){let e=P(t);if(e)return e}},F=(e,t)=>(e.children??[]).find(e=>e.tagName===t),I=e=>{let t=N(e),n=P(e);return n?{text:t,href:n}:{text:t}},L=e=>(e.children??[]).filter(e=>e.type===`element`).map(I),R=e=>{if(e.tagName!==`table`)return null;let t=F(e,`thead`),n=t&&F(t,`tr`);return{headers:n?L(n).map(e=>e.text):[],rows:(F(e,`tbody`)?.children??[]).filter(e=>e.tagName===`tr`).map(L)}},z=e=>e.length>5,B='When a chart would help answer a question (e.g. plotting a trend over time), include a fenced code block tagged `chartjs` containing a JSON object with this exact shape: {"type": "bar" | "line" | "pie" | "doughnut" | "scatter", "title"?: string, "data": {"labels": string[], "datasets": [{"label": string, "data": number[]}]}}. For "scatter" charts, omit "labels" and give each dataset "data" as an array of {"x": number, "y": number} points instead of a number array. "pie" and "doughnut" charts must have exactly one dataset. Do not include any other fields (no "options", no colors) — the app handles styling. Example:\n```chartjs\n{"type": "line", "title": "BP readings", "data": {"labels": ["Jul 14", "Jul 21", "Jul 28"], "datasets": [{"label": "Systolic", "data": [120, 118, 122]}]}}\n```',V=[`bar`,`line`,`pie`,`doughnut`,`scatter`],H=8,U=50,te=8,ne=500,re=e=>typeof e==`object`&&!!e&&typeof e.x==`number`&&typeof e.y==`number`,ie=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;if(typeof n.type!=`string`||!V.includes(n.type))return null;let r=n.type;if(n.title!==void 0&&typeof n.title!=`string`)return null;let i=n.title;if(typeof n.data!=`object`||n.data===null)return null;let a=n.data;if(!Array.isArray(a.datasets)||a.datasets.length<1||a.datasets.length>H||(r===`pie`||r===`doughnut`)&&a.datasets.length!==1)return null;for(let e of a.datasets)if(typeof e!=`object`||!e||typeof e.label!=`string`||!Array.isArray(e.data))return null;let o=a.datasets;if(r===`scatter`){for(let e of o)if(e.data.length<1||e.data.length>ne||!e.data.every(re))return null;return{type:r,title:i,data:{datasets:o}}}if(!Array.isArray(a.labels)||!a.labels.every(e=>typeof e==`string`))return null;let s=a.labels,c=r===`pie`||r===`doughnut`?te:U;if(s.length<1||s.length>c)return null;for(let e of o)if(e.data.length!==s.length||!e.data.every(e=>typeof e==`number`))return null;return{type:r,title:i,data:{labels:s,datasets:o}}},ae={tool_start:`Tool start`,tool_end:`Tool end`,pseudo_tool_call:`Narrated tool call`,progress:`Progress`,info:`Info`,error:`Error`,raw:`Raw event`};function W(e){return e.kind!==`tool_start`&&e.kind!==`tool_end`?null:j(e.name,e.args)}function G(e,t=W(e)){return e.kind===`pseudo_tool_call`?e.name:t?.name??null}function oe(e,t=W(e)){switch(e.kind){case`tool_start`:return t.viaCallTool?`${t.name} (via call_tool)`:t.name;case`tool_end`:return`${t.viaCallTool?`${t.name} (via call_tool)`:t.name}${e.runtimeSeconds===void 0?``:` — ${e.runtimeSeconds.toFixed(2)}s`}${e.isError?` — failed`:``}`;case`pseudo_tool_call`:return`${e.name} — written as text, not actually called`;case`progress`:return e.message?`${e.status} — ${e.message}`:e.status;case`info`:return e.message;case`error`:return e.httpStatus?`${e.message} (HTTP ${e.httpStatus})`:e.message;case`raw`:return`Unrecognized event: ${e.eventType}`}}function se(e,t=W(e)){return e.kind===`tool_start`||e.kind===`tool_end`?t.args?JSON.stringify(t.args,null,2):e.args??null:e.kind===`pseudo_tool_call`?e.args??null:null}function ce(e){return e.kind===`tool_end`?e.output??null:null}function le(e){return e.kind===`raw`?e.raw:e.kind===`error`?e.rawBody??null:null}function K(e){switch(e.kind){case`tool_start`:return`Calling ${j(e.name,e.args).name}...`;case`tool_end`:{let t=j(e.name,e.args).name;return e.isError?`${t} failed`:`${t} returned`}case`pseudo_tool_call`:return`${e.name} (written as text, not called)`;case`progress`:return e.message??e.status;case`info`:return e.message;case`error`:return e.source===`client-timeout`?`Timed out: ${e.message}`:`Error: ${e.message}`;case`raw`:return`Unrecognized event: ${e.eventType}`}}function ue(e){let t=new Date(e);return`${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}:${String(t.getSeconds()).padStart(2,`0`)}.${String(t.getMilliseconds()).padStart(3,`0`)}`}function de(e){if(e<=0)return`+0ms`;if(e<1e3)return`+${Math.round(e)}ms`;let t=e/1e3;if(t<60)return`+${t.toFixed(1)}s`;let n=Math.floor(t/60),r=Math.round(t%60);return`+${n}m${String(r).padStart(2,`0`)}s`}function q(e){return e.map((t,n)=>{let r=W(t),i=n===0?t.turnSentAt:e[n-1].at;return{key:`${t.at}-${n}`,kind:t.kind,toolName:G(t,r),isToolStart:t.kind===`tool_start`,failed:t.kind===`tool_end`&&t.isError===!0,time:ue(t.at),gapMs:t.at-i,label:t.kind===`tool_end`&&t.isError===!0?`Tool failed`:ae[t.kind],summary:oe(t,r),argsDetail:se(t,r),outputDetail:ce(t),rawDetail:le(t)}})}function fe(e){let t=e.filter(e=>e.kind===`tool_end`),n=t.filter(e=>e.kind===`tool_end`&&e.isError),r=e.filter(e=>e.kind===`error`),i=[];return t.length>0&&i.push(`${t.length} tool call${t.length===1?``:`s`}`+(n.length>0?`, ${n.length} failed`:``)),r.length>0&&i.push(`${r.length} stream error${r.length===1?``:`s`}`),i.join(` · `)}function pe(e){let t=[];for(let n of e){let e=t[t.length-1];if(n.toolName&&e?.type===`group`&&e.toolName===n.toolName){e.rows.push(n);continue}t.push(n.toolName?{type:`group`,toolName:n.toolName,rows:[n]}:{type:`single`,row:n})}return t}function me(e){return e.some(e=>e.kind===`tool_end`&&e.isError||e.kind===`error`)}function he(e,t){return t===void 0?[]:e.filter(e=>e.turnSentAt===t&&(e.kind===`tool_end`||e.kind===`pseudo_tool_call`||e.kind===`progress`)).map((e,t)=>({key:`${e.at}-${t}`,text:K(e),toolName:G(e)}))}var ge=`/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
12
12
  @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-font-weight: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-border-style:solid;--tw-leading:initial;--tw-space-y-reverse:0}}}@layer theme{:root,:host{--font-sans:"Inter", -apple-system, "Segoe UI", Roboto, Arial, sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-100:oklch(93.6% .032 17.717);--color-green-100:oklch(96.2% .044 156.743);--color-green-700:oklch(52.7% .154 150.069);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-700:oklch(48.8% .243 264.376);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-700:oklch(49.6% .265 301.924);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-700:oklch(37.3% .034 259.733);--color-black:#000;--spacing:.25rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-medium:500;--font-weight-semibold:600;--leading-relaxed:1.625;--radius-md:.375rem;--radius-2xl:1rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--color-bailey-accent:#4f46e5;--color-bailey-bubble-bg:#fff;--color-bailey-error:#d32f2f;--color-bailey-border:#e5e5e5;--color-bailey-surface:#fff;--color-bailey-surface-muted:#f9fafb;--color-bailey-text:#000;--color-bailey-text-secondary:#6b6b6b;--color-bailey-tooltip-bg:#000;--color-bailey-tooltip-text:#fff;--color-bailey-page-bg:#eceef4;--color-bailey-heart:#16a34a}}@layer utilities;.bailey-chat-panel{box-sizing:border-box;background-color:var(--color-bailey-page-bg);height:100%;padding:calc(var(--spacing) * 3);font-family:var(--font-sans);flex-direction:column;display:flex}.bailey-chat-panel-inner{width:100%;min-height:0;max-width:var(--container-3xl);gap:calc(var(--spacing) * 2);flex-direction:column;flex:1;margin-inline:auto;display:flex;overflow-y:auto}.bailey-toolbar-row{justify-content:flex-end;display:flex}.bailey-new-chat-button{cursor:pointer;appearance:none;--tw-border-style:none;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-bailey-accent);background-color:#0000;border-style:none}@media (hover:hover){.bailey-new-chat-button:hover{text-decoration-line:underline}}.bailey-new-chat-button:disabled{cursor:default;opacity:.5;text-decoration-line:none}.bailey-chat-transcript{min-height:0;padding:calc(var(--spacing) * 2);padding-bottom:calc(var(--spacing) * 4);flex:1;overflow-y:auto}.bailey-message-row{margin-bottom:calc(var(--spacing) * 3);justify-content:flex-start;display:flex}.bailey-message-row-user{justify-content:flex-end}.bailey-user-message{flex-direction:column;align-items:flex-end;max-width:75%;display:flex}.bailey-message-meta{margin-bottom:var(--spacing);align-items:center;gap:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-bailey-text-secondary);display:flex}.bailey-message-meta-name{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-bailey-text)}.bailey-user-bubble{border-radius:var(--radius-2xl);background-color:var(--color-bailey-bubble-bg);max-width:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);white-space:pre-wrap;color:var(--color-bailey-text);--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)}.bailey-assistant-message{width:100%;padding-inline:var(--spacing)}.bailey-thinking-hint{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-bailey-text-secondary);font-style:italic}.bailey-streaming-hint{margin-top:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-bailey-text-secondary);font-style:italic;display:block}.bailey-message-actions{margin-top:var(--spacing);align-items:center;gap:var(--spacing);display:flex}.bailey-empty-state{text-align:center;height:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-bailey-text-secondary);justify-content:center;align-items:center;display:flex}.bailey-suggestions{gap:calc(var(--spacing) * 3);padding:calc(var(--spacing) * 2);flex-direction:column;display:flex}.bailey-suggestions-title{padding-inline:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-bailey-text)}.bailey-suggestion-card{cursor:pointer;appearance:none;justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 2);border-radius:var(--radius-2xl);--tw-border-style:none;background-color:var(--color-bailey-surface);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);text-align:left;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-bailey-text);--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);transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-style:none;display:flex}@media (hover:hover){.bailey-suggestion-card:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px 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)}}.bailey-suggestion-icon{height:calc(var(--spacing) * 4);width:calc(var(--spacing) * 4);color:var(--color-bailey-text-secondary);flex-shrink:0}.bailey-privacy-note{border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--color-bailey-border);padding-inline:calc(var(--spacing) * 4);padding-top:calc(var(--spacing) * 3);padding-bottom:var(--spacing);text-align:center;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-bailey-text-secondary)}.bailey-privacy-note a{color:var(--color-bailey-text-secondary);text-decoration-line:underline}.bailey-activity-line{margin-bottom:calc(var(--spacing) * 2);align-items:center;gap:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-bailey-text-secondary);display:flex}.bailey-activity-icon{height:calc(var(--spacing) * 4);width:calc(var(--spacing) * 4);color:var(--color-bailey-accent);flex-shrink:0}.bailey-error-banner{margin-bottom:calc(var(--spacing) * 2);justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 2);border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-bailey-error);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);color:var(--color-bailey-error);display:flex}.bailey-retry-button{cursor:pointer;appearance:none;--tw-border-style:none;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);background-color:#0000;border-style:none;text-decoration-line:underline}.bailey-error-actions{align-items:center;gap:calc(var(--spacing) * 2);display:flex}.bailey-dismiss-button{cursor:pointer;appearance:none;--tw-border-style:none;color:var(--color-bailey-error);background-color:#0000;border-style:none}@media (hover:hover){.bailey-dismiss-button:hover{opacity:.7}}.bailey-input-row{align-items:center;gap:calc(var(--spacing) * 2);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-bailey-border);background-color:var(--color-bailey-surface);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);--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);border-radius:2147483647px;display:flex}.bailey-input-row:focus-within{border-color:var(--color-bailey-accent)}.bailey-input{--tw-border-style:none;min-width:0;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);--tw-outline-style:none;background-color:#0000;border-style:none;outline-style:none;flex:1}.bailey-input:disabled{opacity:.5}.bailey-send-button,.bailey-stop-button{cursor:pointer;appearance:none;background-color:#0000;border-radius:2147483647px;flex-shrink:0;justify-content:center;align-items:center;display:flex}:is(.bailey-send-button,.bailey-stop-button):disabled{cursor:default;opacity:.4}.bailey-send-button{height:calc(var(--spacing) * 9);width:calc(var(--spacing) * 9);--tw-border-style:none;color:var(--color-bailey-heart);border-style:none}@media (hover:hover){.bailey-send-button:hover{background-color:#16a34a1a}@supports (color:color-mix(in lab, red, red)){.bailey-send-button:hover{background-color:color-mix(in oklab, var(--color-bailey-heart) 10%, transparent)}}}.bailey-send-icon{height:calc(var(--spacing) * 5);width:calc(var(--spacing) * 5)}.bailey-stop-button{height:calc(var(--spacing) * 9);width:calc(var(--spacing) * 9);--tw-border-style:none;color:var(--color-bailey-error);border-style:none}@media (hover:hover){.bailey-stop-button:hover{background-color:#d32f2f1a}@supports (color:color-mix(in lab, red, red)){.bailey-stop-button:hover{background-color:color-mix(in oklab, var(--color-bailey-error) 10%, transparent)}}}.bailey-stop-icon{height:calc(var(--spacing) * 4);width:calc(var(--spacing) * 4)}.bailey-copy-button{height:calc(var(--spacing) * 7);width:calc(var(--spacing) * 7);cursor:pointer;appearance:none;--tw-border-style:none;color:var(--color-bailey-text-secondary);background-color:#0000;border-style:none;border-radius:2147483647px;justify-content:center;align-items:center;display:flex}@media (hover:hover){.bailey-copy-button:hover{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.bailey-copy-button:hover{background-color:color-mix(in oklab, var(--color-black) 5%, transparent)}}.bailey-copy-button:hover{color:var(--color-bailey-text)}}.bailey-copy-icon{height:calc(var(--spacing) * 4);width:calc(var(--spacing) * 4)}.bailey-tooltip-content{padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));background-color:var(--color-bailey-tooltip-bg,#000);color:var(--color-bailey-tooltip-text,#fff);border-radius:.25rem}.bailey-tooltip-arrow{fill:var(--color-bailey-tooltip-bg,#000)}.bailey-markdown-content table{border-collapse:collapse;width:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.bailey-markdown-content th{background-color:var(--color-bailey-surface-muted);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);text-align:left;--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.bailey-markdown-content td{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-bailey-border);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);vertical-align:top}.bailey-markdown-content tr:nth-child(2n){background-color:var(--color-bailey-surface-muted)}.bailey-markdown-content{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.bailey-markdown-content>:first-child{margin-top:0}.bailey-markdown-content>:last-child{margin-bottom:0}.bailey-markdown-content p{margin-block:calc(var(--spacing) * 2)}.bailey-markdown-content h1{margin-top:calc(var(--spacing) * 4);margin-bottom:calc(var(--spacing) * 2);font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.bailey-markdown-content h2{margin-top:calc(var(--spacing) * 4);margin-bottom:calc(var(--spacing) * 2);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.bailey-markdown-content h3{margin-top:calc(var(--spacing) * 3);margin-bottom:calc(var(--spacing) * 1.5);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.bailey-markdown-content h4,.bailey-markdown-content h5,.bailey-markdown-content h6{margin-top:calc(var(--spacing) * 3);margin-bottom:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.bailey-markdown-content ul{margin-block:calc(var(--spacing) * 2);list-style-type:disc}:where(.bailey-markdown-content ul>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}.bailey-markdown-content ul{padding-left:calc(var(--spacing) * 5)}.bailey-markdown-content ol{margin-block:calc(var(--spacing) * 2);list-style-type:decimal}:where(.bailey-markdown-content ol>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}.bailey-markdown-content ol{padding-left:calc(var(--spacing) * 5)}.bailey-markdown-content a{color:var(--color-bailey-accent);text-underline-offset:2px;text-decoration-line:underline}.bailey-markdown-content code{background-color:var(--color-bailey-surface-muted);padding-inline:var(--spacing);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);border-radius:.25rem;font-size:.85em}.bailey-markdown-content pre{margin-block:calc(var(--spacing) * 2);border-radius:var(--radius-md);background-color:var(--color-bailey-surface-muted);padding:calc(var(--spacing) * 2);overflow-x:auto}.bailey-markdown-content pre code{background-color:#0000;padding:0}.bailey-markdown-content blockquote{margin-block:calc(var(--spacing) * 2);border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--color-bailey-border);padding-left:calc(var(--spacing) * 3);color:var(--color-bailey-text-secondary);font-style:italic}.bailey-markdown-content hr{margin-block:calc(var(--spacing) * 3);border-color:var(--color-bailey-border)}.bailey-trace-panel{margin-bottom:calc(var(--spacing) * 2)}.bailey-trace-toggle-row{align-items:center;gap:calc(var(--spacing) * 2);display:flex}.bailey-trace-toggle{cursor:pointer;appearance:none;--tw-border-style:none;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-bailey-accent);background-color:#0000;border-style:none}@media (hover:hover){.bailey-trace-toggle:hover{text-decoration-line:underline}}.bailey-trace-toggle-error{color:var(--color-bailey-error)}.bailey-trace-summary{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-bailey-text-secondary)}.bailey-trace-summary-error{color:var(--color-bailey-error)}.bailey-trace-body{margin-top:var(--spacing);max-height:calc(var(--spacing) * 80);overflow-y:auto}.bailey-trace-actions-row{justify-content:flex-end;gap:calc(var(--spacing) * 3);display:flex}.bailey-trace-copy-button{cursor:pointer;appearance:none;--tw-border-style:none;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-bailey-accent);background-color:#0000;border-style:none;text-decoration-line:underline}@media (hover:hover){.bailey-trace-copy-button:hover{text-decoration-line:none}}.bailey-trace-request-details{margin-bottom:var(--spacing);border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-bailey-border);background-color:var(--color-bailey-surface);padding:calc(var(--spacing) * 2)}.bailey-trace-request-meta{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-bailey-text-secondary);display:block}.bailey-trace-rows{gap:var(--spacing);flex-direction:column;display:flex}.bailey-trace-row{border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-bailey-border);padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);font-family:var(--font-mono);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.bailey-trace-row-header{align-items:center;gap:calc(var(--spacing) * 2);flex-wrap:wrap;display:flex}.bailey-trace-row-time{color:var(--color-bailey-text-secondary)}.bailey-trace-row-gap{color:var(--color-gray-400)}.bailey-trace-row-summary{word-break:break-all}.bailey-trace-chip{padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);--tw-font-weight:var(--font-weight-semibold);font-size:.65rem;font-weight:var(--font-weight-semibold);border-radius:.25rem}.bailey-trace-chip-default{background-color:var(--color-gray-200);color:var(--color-gray-700)}.bailey-trace-chip-info{background-color:var(--color-blue-100);color:var(--color-blue-700)}.bailey-trace-chip-success{background-color:var(--color-green-100);color:var(--color-green-700)}.bailey-trace-chip-secondary{background-color:var(--color-purple-100);color:var(--color-purple-700)}.bailey-trace-chip-error{background-color:var(--color-red-100);color:var(--color-bailey-error)}.bailey-trace-disclosure{margin-top:var(--spacing)}.bailey-trace-disclosure-summary{cursor:pointer;color:var(--color-bailey-text-secondary);font-size:.7rem}.bailey-trace-disclosure-actions{margin-top:var(--spacing);justify-content:flex-end;display:flex}.bailey-trace-disclosure-content{margin-top:var(--spacing);max-height:calc(var(--spacing) * 48);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-bailey-border);background-color:var(--color-bailey-surface-muted);padding:calc(var(--spacing) * 1.5);word-break:break-all;white-space:pre-wrap;border-radius:.25rem;font-size:.7rem;overflow:auto}.bailey-trace-group{border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-bailey-border);padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing)}.bailey-trace-group-summary{cursor:pointer;font-family:var(--font-mono);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.bailey-trace-group-failed{margin-left:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-bailey-error)}@property --tw-font-weight{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-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}`,_e=(0,l.createContext)(void 0),ve=/:root\s*,\s*:host\s*\{/,ye=`.bailey-chat-panel{`;function be(e){let t=e.match(new RegExp(ve,`g`))?.length??0;if(t!==1)throw Error(`Expected exactly one ":root, :host {" rule in the compiled styles.css, found ${t}. Tailwind likely changed how @theme compiles — update this rewrite (and its sibling, scripts/scope-theme-vars.js) before shipping.`);return e.replace(ve,ye)}var xe=be(ge),J=`data-source`,Y=`baileyai-chat-ui`,X=new WeakMap;function Se(e){let t=e.getRootNode();return t instanceof ShadowRoot?t:document}function Ce(e){let t=e instanceof ShadowRoot?e:document.head,n=X.get(e)??0;if(n===0&&!t.querySelector(`style[${J}="${Y}"]`)){let e=document.createElement(`style`);e.setAttribute(J,Y),e.textContent=xe,t.appendChild(e)}return X.set(e,n+1),()=>{let n=(X.get(e)??1)-1;n<=0?(X.delete(e),t.querySelector(`style[${J}="${Y}"]`)?.remove()):X.set(e,n)}}function we(e,t=!1){let[n,r]=(0,l.useState)(null);return(0,l.useLayoutEffect)(()=>{if(t)return;let n=e.current;if(!n)return;let i=Se(n);return r(i),Ce(i)},[t,e]),n}function Te(e){let t=(0,l.useContext)(_e),n=t!==void 0,r=we(e,n);return n?t:r}function Z({renderTable:e,renderChart:t}={}){return{a:({href:e,children:t})=>!e||!c.t(e)?(0,p.jsx)(p.Fragment,{children:t}):(0,p.jsx)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,children:t}),table:({node:t,children:n})=>{let r=t&&R(t);if(r&&z(r.rows)&&e){let t=r.rows.map(e=>e.map(e=>e.href&&!c.t(e.href)?{text:e.text}:e));return(0,p.jsx)(p.Fragment,{children:e({headers:r.headers,rows:t})})}return(0,p.jsx)(`table`,{children:n})},pre:({children:e})=>{let n=(Array.isArray(e)?e[0]:e)?.props;if((n?.className?.split(` `)??[]).includes(`language-chartjs`)&&t){let e=n?.children,r=ie(Array.isArray(e)?e.join(``):String(e??``));if(r)return(0,p.jsx)(p.Fragment,{children:t(r)})}return(0,p.jsx)(`pre`,{children:e})}}}function Ee({className:e}){return(0,p.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`currentColor`,className:e,"aria-hidden":`true`,children:(0,p.jsx)(`path`,{d:`M12 20.3s-7.6-4.7-10-9.4C.4 7.7 1.7 4 5.2 3.1c2.2-.6 4.4.4 5.5 2.2 1.2-1.8 3.4-2.8 5.6-2.2 3.5.9 4.8 4.6 3.2 7.8-2.4 4.7-10 9.4-10 9.4z`})})}function De({className:e}){return(0,p.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`currentColor`,className:e,"aria-hidden":`true`,children:(0,p.jsx)(`rect`,{x:`6`,y:`6`,width:`12`,height:`12`,rx:`2`})})}function Oe({className:e}){return(0,p.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,className:e,"aria-hidden":`true`,children:[(0,p.jsx)(`path`,{d:`M7 17 17 7`}),(0,p.jsx)(`path`,{d:`M9 7h8v8`})]})}function ke({className:e}){return(0,p.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,className:e,"aria-hidden":`true`,children:[(0,p.jsx)(`rect`,{x:`8`,y:`8`,width:`12`,height:`12`,rx:`2`}),(0,p.jsx)(`path`,{d:`M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2`})]})}function Ae({className:e}){return(0,p.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,className:e,"aria-hidden":`true`,children:(0,p.jsx)(`path`,{d:`M5 12.5 9.5 17 19 7`})})}function je({className:e}){return(0,p.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,className:e,"aria-hidden":`true`,children:[(0,p.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,p.jsx)(`path`,{d:`M8.5 12.5 11 15l4.5-5.5`})]})}var Me=1500;function Ne({markdown:e,className:t,ariaLabel:n=`copy response as markdown`,tooltipDefaultText:r=`Copy as markdown`,tooltipCopiedText:i=`Copied!`}){let[a,o]=(0,l.useState)(!1),[s,c]=(0,l.useState)(!1),u=(0,l.useRef)(null),d=(0,l.useRef)(null),m=Te(d);return(0,l.useEffect)(()=>()=>{u.current!==null&&clearTimeout(u.current)},[]),(0,p.jsx)(f.Provider,{delayDuration:200,children:(0,p.jsxs)(f.Root,{open:a||s,onOpenChange:c,children:[(0,p.jsx)(f.Trigger,{asChild:!0,children:(0,p.jsx)(`button`,{ref:d,type:`button`,onClick:async()=>{try{await navigator.clipboard.writeText(e)}catch{return}o(!0),u.current!==null&&clearTimeout(u.current),u.current=setTimeout(()=>o(!1),Me)},"aria-label":n,className:`bailey-copy-button${t?` ${t}`:``}`,children:a?(0,p.jsx)(Ae,{className:`bailey-copy-icon`}):(0,p.jsx)(ke,{className:`bailey-copy-icon`})})}),(0,p.jsx)(f.Portal,{container:m instanceof ShadowRoot?m:void 0,children:(0,p.jsxs)(f.Content,{side:`top`,className:`bailey-tooltip-content`,children:[a?i:r,(0,p.jsx)(f.Arrow,{className:`bailey-tooltip-arrow`})]})})]})})}async function Pe(e){try{await navigator.clipboard.writeText(e)}catch{}}function Fe({text:e,label:t=`Copy`}){return(0,p.jsx)(`button`,{type:`button`,onClick:()=>Pe(e),className:`bailey-trace-copy-button`,children:t})}function Ie(e){if(e.failed||e.kind===`error`)return`bailey-trace-chip bailey-trace-chip-error`;switch(e.kind){case`tool_start`:return`bailey-trace-chip bailey-trace-chip-info`;case`tool_end`:return`bailey-trace-chip bailey-trace-chip-success`;case`progress`:return`bailey-trace-chip bailey-trace-chip-secondary`;default:return`bailey-trace-chip bailey-trace-chip-default`}}function Q({label:e,content:t,copyable:n}){return(0,p.jsxs)(`details`,{className:`bailey-trace-disclosure`,children:[(0,p.jsx)(`summary`,{className:`bailey-trace-disclosure-summary`,children:e}),n&&(0,p.jsx)(`div`,{className:`bailey-trace-disclosure-actions`,children:(0,p.jsx)(Fe,{text:t})}),(0,p.jsx)(`pre`,{className:`bailey-trace-disclosure-content`,children:t})]})}function $({row:e}){return(0,p.jsxs)(`div`,{className:`bailey-trace-row`,children:[(0,p.jsxs)(`div`,{className:`bailey-trace-row-header`,children:[(0,p.jsx)(`span`,{className:`bailey-trace-row-time`,children:e.time}),(0,p.jsx)(`span`,{className:`bailey-trace-row-gap`,title:`Time since the previous event`,children:de(e.gapMs)}),(0,p.jsx)(`span`,{className:Ie(e),children:e.label}),(0,p.jsx)(`span`,{className:`bailey-trace-row-summary`,children:e.summary})]}),e.argsDetail&&(0,p.jsx)(Q,{label:`args`,content:e.argsDetail}),e.outputDetail&&(0,p.jsx)(Q,{label:`output`,content:e.outputDetail}),e.rawDetail&&(0,p.jsx)(Q,{label:`raw`,content:e.rawDetail})]})}function Le(e,t){if(e.chunkCount===0)return`Streamed: no chunks received`;if(e.chunkCount===1||e.firstChunkAt===null)return`Streamed: 1 chunk (not incremental)`;let n=e.firstChunkAt-t,r=(e.lastChunkAt??e.firstChunkAt)-e.firstChunkAt;return`Streamed: ${e.chunkCount} chunks · first chunk after ${n}ms · spread over ${(r/1e3).toFixed(1)}s`}function Re({request:e}){let t=(0,l.useMemo)(()=>JSON.stringify({model:e.model,instructions:e.systemPrompt,input:e.messages,stream:e.stream,tools:e.tools,toolChoice:e.toolChoice},null,2),[e]);return(0,p.jsxs)(`div`,{className:`bailey-trace-request-details`,children:[(0,p.jsxs)(`span`,{className:`bailey-trace-request-meta`,children:[`Last request — `,e.model,` · `,new Date(e.sentAt).toLocaleTimeString(),e.requestId?` · ${e.requestId}`:``]}),(0,p.jsx)(`span`,{className:`bailey-trace-request-meta`,children:Le(e.streamStats,e.sentAt)}),(0,p.jsx)(Q,{label:`System prompt (${e.systemPrompt.length.toLocaleString()} chars)`,content:e.systemPrompt,copyable:!0}),(0,p.jsx)(Q,{label:`Messages (${e.messages.length})`,content:JSON.stringify(e.messages,null,2),copyable:!0}),e.response&&(0,p.jsx)(Q,{label:`Response (${e.response.content.length.toLocaleString()} chars)`,content:e.response.content,copyable:!0}),(0,p.jsx)(Q,{label:`Full payload (JSON)`,content:t,copyable:!0})]})}function ze({events:e,lastRequest:t,onClear:n}){let r=(0,l.useMemo)(()=>q(e),[e]),i=(0,l.useMemo)(()=>pe(r),[r]),a=(0,l.useMemo)(()=>JSON.stringify(e,null,2),[e]);return(0,p.jsxs)(`div`,{className:`bailey-trace-body`,children:[(0,p.jsxs)(`div`,{className:`bailey-trace-actions-row`,children:[e.length>0&&(0,p.jsx)(Fe,{text:a,label:`Copy trace as JSON`}),(0,p.jsx)(`button`,{type:`button`,onClick:n,className:`bailey-trace-copy-button`,children:`Clear`})]}),t&&(0,p.jsx)(Re,{request:t}),(0,p.jsx)(`div`,{className:`bailey-trace-rows`,children:i.map((e,t)=>{if(e.type===`single`)return(0,p.jsx)($,{row:e.row},e.row.key);let n=e.rows.filter(e=>e.isToolStart).length;if(n<=1)return(0,p.jsx)(`div`,{className:`bailey-trace-rows`,children:e.rows.map(e=>(0,p.jsx)($,{row:e},e.key))},`group-${t}`);let r=e.rows.filter(e=>e.failed).length;return(0,p.jsxs)(`details`,{className:`bailey-trace-group`,children:[(0,p.jsxs)(`summary`,{className:`bailey-trace-group-summary`,children:[(0,p.jsx)(`strong`,{children:e.toolName}),` × `,n,r>0&&(0,p.jsxs)(`span`,{className:`bailey-trace-group-failed`,children:[` `,r,` failed`]})]}),(0,p.jsx)(`div`,{className:`bailey-trace-rows`,children:e.rows.map(e=>(0,p.jsx)($,{row:e},e.key))})]},`group-${t}`)})})]})}function Be({events:e,lastRequest:t,onClear:n}){let[r,i]=(0,l.useState)(!1),a=(0,l.useMemo)(()=>me(e),[e]),o=(0,l.useMemo)(()=>fe(e),[e]);return e.length===0&&!t?null:(0,p.jsxs)(`div`,{className:`bailey-trace-panel`,children:[(0,p.jsxs)(`div`,{className:`bailey-trace-toggle-row`,children:[(0,p.jsxs)(`button`,{type:`button`,onClick:()=>i(e=>!e),"aria-expanded":r,className:a?`bailey-trace-toggle bailey-trace-toggle-error`:`bailey-trace-toggle`,children:[a&&!r?`⚠ `:``,r?`Hide details`:`Show details`,` (`,e.length,`)`]}),o&&(0,p.jsx)(`span`,{className:a?`bailey-trace-summary bailey-trace-summary-error`:`bailey-trace-summary`,children:o})]}),r&&(0,p.jsx)(ze,{events:e,lastRequest:t,onClear:n})]})}var Ve=`How can bailey AI help you today?`,He=`Reply to bailey AI`,Ue={newChatButtonText:`New chat`,newChatAriaLabel:`new chat`,suggestionsTitle:`Suggested for you`,emptyStateMessage:`Ask Bailey a question to get started.`,youLabel:`You`,thinkingHint:`Thinking…`,retryButtonText:`Retry`,dismissErrorAriaLabel:`dismiss error`,sendAriaLabel:`send`,stopButtonText:`Stop`,stopAriaLabel:`stop`,copyButtonAriaLabel:`copy response as markdown`,copyButtonTooltipDefault:`Copy as markdown`,copyButtonTooltipCopied:`Copied!`},We=[d.default],Ge={...Z(),p:({children:e})=>(0,p.jsx)(p.Fragment,{children:e})},Ke=(0,l.memo)(function({content:e,components:t}){return(0,p.jsx)(`div`,{className:`bailey-markdown-content`,children:(0,p.jsx)(u.default,{remarkPlugins:We,components:t,skipHtml:!0,children:e})})});function qe(e,t,n){if(e!==`streaming`)return;let r=t.filter(e=>e.turnSentAt===n?.sentAt);if(r.length!==0)return K(r[r.length-1])}function Je(e){let t=new Date(e),n=t.toDateString()===new Date().toDateString(),r=t.toLocaleTimeString([],{hour:`numeric`,minute:`2-digit`});return n?`Today ${r}`:`${t.toLocaleDateString()} ${r}`}function Ye({chat:e,placeholder:t,replyPlaceholder:n=He,emptyPlaceholder:r,suggestions:i,privacyNote:a,resolveActivityIcon:o,className:s,height:c,width:d,hideDeveloperDetails:m=!1,renderMessageActions:h,renderTable:g,renderChart:_,labels:v,formatMessageTime:y}){let{messages:b,traceEvents:x,lastRequest:S,status:C,error:w,send:T,stop:E,retryLast:ee,clearTrace:D,clearError:O,newChat:k}=e,[A,j]=(0,l.useState)(``),M={...Ue,...v},N=y??Je,P=(0,l.useRef)(null),F=we(P),I=(0,l.useRef)(null),L=(0,l.useRef)(null),R=(0,l.useRef)(!0),z=(0,l.useMemo)(()=>Z({renderTable:g,renderChart:_}),[g,_]),B=(0,l.useMemo)(()=>qe(C,x,S),[C,x,S]),V=b.length===0,H=t??(V?r??Ve:n);(0,l.useEffect)(()=>{let e=L.current;if(!e)return;let t=()=>{let t=e.scrollHeight-e.scrollTop-e.clientHeight;R.current=t<60};return e.addEventListener(`scroll`,t,{passive:!0}),()=>e.removeEventListener(`scroll`,t)},[]),(0,l.useEffect)(()=>{R.current&&I.current?.scrollIntoView({behavior:C===`streaming`?`auto`:`smooth`,block:`nearest`})},[b,C]);let U=e=>{R.current=!0,T(e)};return(0,p.jsx)(_e.Provider,{value:F,children:(0,p.jsx)(`div`,{ref:P,className:`bailey-chat-panel${s?` ${s}`:``}`,style:c!==void 0||d!==void 0?{height:c,width:d}:void 0,children:(0,p.jsxs)(`div`,{className:`bailey-chat-panel-inner`,children:[(0,p.jsx)(`div`,{className:`bailey-toolbar-row`,children:!V&&(0,p.jsx)(`button`,{type:`button`,onClick:k,"aria-label":M.newChatAriaLabel,className:`bailey-new-chat-button`,children:M.newChatButtonText})}),(0,p.jsxs)(`div`,{className:`bailey-chat-transcript`,ref:L,children:[V&&(i&&i.length>0?(0,p.jsxs)(`div`,{className:`bailey-suggestions`,children:[(0,p.jsx)(`div`,{className:`bailey-suggestions-title`,children:M.suggestionsTitle}),i.map((e,t)=>(0,p.jsxs)(`button`,{type:`button`,onClick:()=>U(e.value??e.label),className:`bailey-suggestion-card`,children:[(0,p.jsx)(`span`,{children:e.label}),(0,p.jsx)(Oe,{className:`bailey-suggestion-icon`})]},`${e.label}-${t}`))]}):(0,p.jsx)(`div`,{className:`bailey-empty-state`,children:M.emptyStateMessage})),b.map((e,t)=>{let n=e.role===`assistant`&&t===b.length-1,r=C===`streaming`&&n&&e.content===``,i=e.role===`assistant`&&!r?he(x,e.createdAt):[],a=i[i.length-1];return(0,p.jsx)(`div`,{className:e.role===`user`?`bailey-message-row bailey-message-row-user`:`bailey-message-row`,children:e.role===`user`?(0,p.jsxs)(`div`,{className:`bailey-user-message`,children:[(0,p.jsxs)(`div`,{className:`bailey-message-meta`,children:[(0,p.jsx)(`span`,{className:`bailey-message-meta-name`,children:M.youLabel}),e.createdAt!==void 0&&(0,p.jsx)(`span`,{children:N(e.createdAt)})]}),(0,p.jsx)(`div`,{className:`bailey-user-bubble`,children:e.content})]}):r?(0,p.jsx)(`div`,{className:`bailey-thinking-hint`,children:B??M.thinkingHint}):(0,p.jsxs)(`div`,{className:`bailey-assistant-message`,children:[a&&(0,p.jsxs)(`div`,{className:`bailey-activity-line`,children:[(0,p.jsx)(`span`,{className:`bailey-activity-icon`,children:o?.(a.toolName)??(0,p.jsx)(je,{})}),(0,p.jsx)(`span`,{children:a.text})]}),(0,p.jsx)(Ke,{content:e.content,components:z}),e.streaming&&B&&(0,p.jsx)(`div`,{className:`bailey-streaming-hint`,children:B}),!e.streaming&&(0,p.jsxs)(`div`,{className:`bailey-message-actions`,children:[(0,p.jsx)(Ne,{markdown:e.content,ariaLabel:M.copyButtonAriaLabel,tooltipDefaultText:M.copyButtonTooltipDefault,tooltipCopiedText:M.copyButtonTooltipCopied}),h?.(e)]})]})},e.id)}),(0,p.jsx)(`div`,{ref:I})]}),w&&(0,p.jsxs)(`div`,{className:`bailey-error-banner`,role:`alert`,children:[(0,p.jsx)(`span`,{children:w}),(0,p.jsxs)(`div`,{className:`bailey-error-actions`,children:[(0,p.jsx)(`button`,{type:`button`,onClick:ee,className:`bailey-retry-button`,children:M.retryButtonText}),(0,p.jsx)(`button`,{type:`button`,onClick:O,"aria-label":M.dismissErrorAriaLabel,className:`bailey-dismiss-button`,children:`✕`})]})]}),!m&&(0,p.jsx)(Be,{events:x,lastRequest:S,onClear:D}),(0,p.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),!(!A.trim()||C===`streaming`)&&(U(A),j(``))},className:`bailey-input-row`,children:[(0,p.jsx)(`input`,{type:`text`,placeholder:H,"aria-label":H,value:A,onChange:e=>j(e.target.value),disabled:C===`streaming`,className:`bailey-input`}),C===`streaming`?(0,p.jsx)(f.Provider,{delayDuration:200,children:(0,p.jsxs)(f.Root,{children:[(0,p.jsx)(f.Trigger,{asChild:!0,children:(0,p.jsx)(`button`,{type:`button`,onClick:E,"aria-label":M.stopAriaLabel,className:`bailey-stop-button`,children:(0,p.jsx)(De,{className:`bailey-stop-icon`})})}),(0,p.jsx)(f.Portal,{container:F instanceof ShadowRoot?F:void 0,children:(0,p.jsxs)(f.Content,{side:`top`,className:`bailey-tooltip-content`,children:[M.stopButtonText,(0,p.jsx)(f.Arrow,{className:`bailey-tooltip-arrow`})]})})]})}):(0,p.jsx)(`button`,{type:`submit`,"aria-label":M.sendAriaLabel,disabled:!A.trim(),className:`bailey-send-button`,children:(0,p.jsx)(Ee,{className:`bailey-send-icon`})})]}),(V||a?.alwaysVisible)&&a&&(0,p.jsx)(`div`,{className:`bailey-privacy-note`,children:(0,p.jsx)(u.default,{remarkPlugins:We,components:Ge,skipHtml:!0,children:a.markdown})})]})})})}var Xe=`0.3.1-pre.2`;exports.ActivityIcon=je,exports.ArrowUpRightIcon=Oe,exports.BAILEYAI_CHAT_UI_VERSION=Xe,exports.BAILEY_CHART_PROMPT_FRAGMENT=B,exports.BAILEY_TABLE_GRID_ROW_THRESHOLD=M,exports.BaileyChatPanel=Ye,exports.BaileyTracePanel=Be,exports.CopyMarkdownButton=Ne,exports.HeartIcon=Ee,exports.TRACE_KIND_LABEL=ae,exports.createBaileyMarkdownComponents=Z,exports.extractPseudoToolCalls=x,exports.extractTableData=R,exports.formatTraceGap=de,exports.formatTraceTime=ue,exports.hasTraceFailure=me,exports.isSafeMarkdownUrl=c.t,exports.joinInstructions=O,exports.parseBaileyChartSpec=ie,exports.parseSseFrames=C,exports.resolveToolCall=j,exports.shouldUseGrid=z,exports.toActivityLines=he,exports.toTraceRows=q,exports.toTraceSegments=pe,exports.traceEventArgsDetail=se,exports.traceEventHint=K,exports.traceEventOutputDetail=ce,exports.traceEventRawDetail=le,exports.traceEventSummary=oe,exports.traceEventToolName=G,exports.traceSummaryLine=fe,exports.useBaileyChat=D;
@@ -408,6 +408,14 @@ var E = 200, D = 15e4, O = () => typeof crypto < "u" && typeof crypto.randomUUID
408
408
  }, []),
409
409
  newChat: r(() => {
410
410
  S.current?.abort(), R([]), A.current = [], h([]), _(null), y("idle"), x(null), w.current = "";
411
+ }, [R]),
412
+ loadMessages: r((e) => {
413
+ S.current?.abort();
414
+ let t = e.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
415
+ ...e,
416
+ streaming: !1
417
+ }));
418
+ R(t.filter((e) => !e.hidden)), A.current = t, h([]), _(null), y("idle"), x(null), w.current = "";
411
419
  }, [R])
412
420
  };
413
421
  };
package/dist/index.d.ts CHANGED
@@ -496,8 +496,38 @@ export declare interface UseBaileyChatResult {
496
496
  /** Dismisses the current error without resending — distinct from retryLast, which resends. */
497
497
  clearError: () => void;
498
498
  /** Aborts any in-flight turn and resets the conversation to empty, so a host can offer a
499
- * "start over" control without remounting the component. */
499
+ * "start over" control without remounting the component.
500
+ *
501
+ * `BaileyChatPanel`'s own "New chat" button calls whatever `newChat` sits on the `chat`
502
+ * object it was given (read off `props.chat`, not this hook directly) — so a host that
503
+ * needs to react to a reset (e.g. to also clear its own persisted conversation identity)
504
+ * wraps this function before handing `chat` to the panel:
505
+ *
506
+ * ```ts
507
+ * const chat = useBaileyChat({ transport, model, instructions });
508
+ * const chatForPanel = useMemo(
509
+ * () => ({ ...chat, newChat: () => { chat.newChat(); onHostReset(); } }),
510
+ * [chat]
511
+ * );
512
+ * ```
513
+ *
514
+ * `newChat()` is fully synchronous, so the wrapper returning is the only "did it finish"
515
+ * signal a host needs — no callback or promise required. */
500
516
  newChat: () => void;
517
+ /** Replaces the current transcript with a caller-supplied one, for resuming a previously
518
+ * started conversation or switching to a different one a host's user selected from a
519
+ * history list. Call once per conversation load (e.g. from an effect keyed on the loaded
520
+ * data), not on every render — repeated calls silently re-apply the same reset each time,
521
+ * the same class of bug as a wrong `useEffect` dependency.
522
+ *
523
+ * Aborts any in-flight turn first (switching conversations is decisive, unlike
524
+ * `sendHidden`/`retryLast`, which no-op instead). Every provided message is normalized to
525
+ * `streaming: false` — a restored message can never legitimately be mid-stream. `hidden`
526
+ * messages are excluded from the visible transcript but retained in the model-context
527
+ * history sent on the next turn, mirroring `sendHidden`'s live behaviour exactly. Any entry
528
+ * whose `role` isn't `'user'` or `'assistant'` is dropped rather than trusted, since a
529
+ * restored transcript crosses a service boundary this hook doesn't control. */
530
+ loadMessages: (messages: BaileyMessage[]) => void;
501
531
  }
502
532
 
503
533
  export { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icanbwell/baileyai-chat-ui",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Shared React chat UI and streaming logic for Bailey, the icanbwell AI assistant",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {