@hsafa/ui-sdk 0.1.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.
@@ -0,0 +1,174 @@
1
+ # @hsafa/ui-sdk Documentation
2
+
3
+ React SDK for integrating AI agents built with HSAFA AI Agent Studio into your applications.
4
+
5
+ ## 📚 Documentation Structure
6
+
7
+ ### 1. **Getting Started**
8
+ - [Installation & Setup](README.md#installation)
9
+ - [Basic AI Agent Chat](README.md#basic-ai-agent-chat)
10
+ - [Getting Started Example](examples/getting-started.tsx)
11
+
12
+ ### 2. **Core Components**
13
+ - [HsafaChat](README.md#hsafachat) - AI agent chat interface
14
+ - [HsafaProvider](README.md#hsafaprovider) - SDK context provider
15
+
16
+ ### 3. **Agent Integration**
17
+ - [useHsafaAction](README.md#usehsafaaction) - Register functions for agents
18
+ - [useHsafaComponent](README.md#usehsafacomponent) - Register UI components
19
+ - [useHsafa](README.md#usehsafa) - Advanced context access
20
+
21
+ ### 4. **Examples**
22
+ - [Getting Started](examples/getting-started.tsx) - Simple setup with basic actions
23
+ - [E-commerce Agent](examples/ecommerce-agent.tsx) - Product search & ordering
24
+
25
+ ### 5. **API Reference**
26
+ - [Complete API Documentation](docs/api/) - Generated from TypeScript definitions
27
+ - [Interactive Storybook](http://localhost:6006) - Component playground
28
+
29
+ ## 🚀 Quick Navigation
30
+
31
+ ### For Beginners
32
+ 1. Start with the [Installation](README.md#installation)
33
+ 2. Try the [Basic Usage Example](examples/basic-usage.tsx)
34
+ 3. Explore the [Interactive Storybook](#interactive-documentation)
35
+
36
+ ### For Advanced Users
37
+ 1. Check out [Chat Integration](examples/chat-integration.tsx)
38
+ 2. Review [Custom Actions](README.md#custom-actions--components)
39
+ 3. Browse the [API Reference](docs/api/)
40
+
41
+ ## 📖 Interactive Documentation
42
+
43
+ ### Storybook
44
+ Run the interactive component documentation:
45
+
46
+ ```bash
47
+ cd sdk
48
+ pnpm storybook
49
+ ```
50
+
51
+ Then visit [http://localhost:6006](http://localhost:6006) to:
52
+ - 🎮 **Play with components** interactively
53
+ - 📝 **View live documentation** with examples
54
+ - 🎨 **Test different props** and configurations
55
+ - 📱 **See responsive behavior**
56
+
57
+ ### API Documentation
58
+ Generate comprehensive API documentation:
59
+
60
+ ```bash
61
+ cd sdk
62
+ pnpm docs:api
63
+ ```
64
+
65
+ This creates detailed API docs in `docs/api/` with:
66
+ - 📋 **Complete type definitions**
67
+ - 🔍 **Function signatures**
68
+ - 💡 **Usage examples**
69
+ - 🏷️ **Parameter descriptions**
70
+
71
+ ## 🎨 Theming & Styling
72
+
73
+ ### CSS Modules
74
+ The SDK uses CSS Modules for styling. Each component has its own stylesheet:
75
+
76
+ ```
77
+ src/components/
78
+ ├── Button.tsx
79
+ ├── Button.module.css
80
+ ├── HsafaChat.tsx
81
+ └── HsafaChat.module.css
82
+ ```
83
+
84
+ ### Customization
85
+ You can customize the appearance by:
86
+
87
+ 1. **Using component props** (recommended):
88
+ ```tsx
89
+ <HsafaChat
90
+ primaryColor="#3b82f6"
91
+ backgroundColor="#ffffff"
92
+ borderColor="#e5e7eb"
93
+ />
94
+ ```
95
+
96
+ 2. **CSS custom properties**:
97
+ ```css
98
+ .my-chat {
99
+ --hsafa-primary-color: #3b82f6;
100
+ --hsafa-background-color: #ffffff;
101
+ }
102
+ ```
103
+
104
+ 3. **CSS Module overrides**:
105
+ ```tsx
106
+ import styles from './MyCustomStyles.module.css';
107
+
108
+ <Button className={styles.customButton} />
109
+ ```
110
+
111
+ ## 🔧 Development Workflow
112
+
113
+ ### Building Documentation
114
+ ```bash
115
+ # Build all documentation
116
+ pnpm docs:build
117
+
118
+ # Development mode with hot reload
119
+ pnpm docs:dev
120
+
121
+ # Build API docs only
122
+ pnpm docs:api
123
+ ```
124
+
125
+ ### Testing
126
+ ```bash
127
+ # Run all tests
128
+ pnpm test
129
+
130
+ # Run tests with UI
131
+ pnpm test:ui
132
+
133
+ # Type checking
134
+ pnpm type-check
135
+ ```
136
+
137
+ ## 📁 Project Structure
138
+
139
+ ```
140
+ sdk/
141
+ ├── src/
142
+ │ ├── components/ # React components
143
+ │ ├── hooks/ # Custom hooks
144
+ │ ├── providers/ # Context providers
145
+ │ └── index.ts # Main exports
146
+ ├── examples/ # Usage examples
147
+ ├── docs/ # Generated documentation
148
+ ├── .storybook/ # Storybook configuration
149
+ └── README.md # Main documentation
150
+ ```
151
+
152
+ ## 🤝 Contributing
153
+
154
+ We welcome contributions! Please see our [Contributing Guide](README.md#contributing) for details.
155
+
156
+ ### Documentation Contributions
157
+ - 📝 Improve existing documentation
158
+ - 🌟 Add new examples
159
+ - 🐛 Fix documentation bugs
160
+ - 💡 Suggest better explanations
161
+
162
+ ## 📞 Support
163
+
164
+ - 📖 **Documentation**: You're reading it!
165
+ - 🐛 **Issues**: [GitHub Issues](https://github.com/husamabusafa/hsafa/issues)
166
+ - 💬 **Discussions**: [GitHub Discussions](https://github.com/husamabusafa/hsafa/discussions)
167
+
168
+ ## 📄 License
169
+
170
+ MIT © [Husam Abu Safa](https://github.com/husamabusafa)
171
+
172
+ ---
173
+
174
+ **Happy coding!** 🎉
package/README.md ADDED
@@ -0,0 +1,347 @@
1
+ # @hsafa/ui-sdk
2
+
3
+ React SDK for building AI agent interfaces with custom actions and interactive components.
4
+
5
+ ## Features
6
+
7
+ - 🤖 **AI Agent Chat**: Ready-to-use chat interface for AI agents
8
+ - ⚡ **Custom Actions**: Register functions that AI agents can call
9
+ - 🎨 **Dynamic Components**: Create UI components that agents can render
10
+ - 🔧 **TypeScript**: Full TypeScript support with comprehensive type definitions
11
+ - 📦 **Lightweight**: Tree-shakable with minimal dependencies
12
+ - 🎯 **Agent-Focused**: Built specifically for AI agent interactions
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @hsafa/ui-sdk
18
+ # or
19
+ yarn add @hsafa/ui-sdk
20
+ # or
21
+ pnpm add @hsafa/ui-sdk
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ### Basic AI Agent Chat
27
+
28
+ ```tsx
29
+ import { HsafaProvider, HsafaChat } from '@hsafa/ui-sdk';
30
+
31
+ function App() {
32
+ return (
33
+ <HsafaProvider baseUrl="https://your-hsafa-api.com">
34
+ <HsafaChat
35
+ agentId="your-agent-id"
36
+ width={400}
37
+ height={600}
38
+ placeholder="Ask your AI agent anything..."
39
+ />
40
+ </HsafaProvider>
41
+ );
42
+ }
43
+ ```
44
+
45
+ ### Adding Custom Actions
46
+
47
+ ```tsx
48
+ import { HsafaProvider, HsafaChat, useHsafaAction } from '@hsafa/ui-sdk';
49
+
50
+ function MyApp() {
51
+ return (
52
+ <HsafaProvider baseUrl="https://your-hsafa-api.com">
53
+ <ActionProviders />
54
+ <HsafaChat agentId="your-agent-id" />
55
+ </HsafaProvider>
56
+ );
57
+ }
58
+
59
+ function ActionProviders() {
60
+ // Register an action that your AI agent can call
61
+ useHsafaAction('getUserData', async (params) => {
62
+ const { userId } = params;
63
+ // Fetch user data from your database
64
+ return {
65
+ name: 'John Doe',
66
+ email: 'john@example.com',
67
+ status: 'active'
68
+ };
69
+ });
70
+
71
+ useHsafaAction('createTask', async (params) => {
72
+ const { title, description } = params;
73
+ // Create task in your system
74
+ return { taskId: '123', status: 'created' };
75
+ });
76
+
77
+ return null;
78
+ }
79
+ ```
80
+
81
+ ### Custom UI Components
82
+
83
+ ```tsx
84
+ import { useHsafaComponent } from '@hsafa/ui-sdk';
85
+
86
+ function ComponentProviders() {
87
+ // Register UI components that agents can render
88
+ useHsafaComponent('ProductCard', ({ product }) => (
89
+ <div className="border rounded-lg p-4">
90
+ <img src={product.image} alt={product.name} />
91
+ <h3>{product.name}</h3>
92
+ <p>${product.price}</p>
93
+ <button>Add to Cart</button>
94
+ </div>
95
+ ));
96
+
97
+ useHsafaComponent('StatusChart', ({ data }) => (
98
+ <div className="chart-container">
99
+ {/* Your chart implementation */}
100
+ <h4>Status Overview</h4>
101
+ {data.map(item => (
102
+ <div key={item.id}>{item.label}: {item.value}</div>
103
+ ))}
104
+ </div>
105
+ ));
106
+
107
+ return null;
108
+ }
109
+ ```
110
+
111
+ ## Components
112
+
113
+ ### Button
114
+
115
+ A versatile button component with multiple variants and states.
116
+
117
+ ```tsx
118
+ import { Button } from '@hsafa/ui-sdk';
119
+
120
+ // Basic usage
121
+ <Button>Click me</Button>
122
+
123
+ // With variants
124
+ <Button variant="primary">Primary</Button>
125
+ <Button variant="secondary">Secondary</Button>
126
+ <Button variant="outline">Outline</Button>
127
+ <Button variant="ghost">Ghost</Button>
128
+
129
+ // With sizes
130
+ <Button size="sm">Small</Button>
131
+ <Button size="md">Medium</Button>
132
+ <Button size="lg">Large</Button>
133
+
134
+ // With loading state
135
+ <Button loading>Loading...</Button>
136
+
137
+ // Disabled
138
+ <Button disabled>Disabled</Button>
139
+ ```
140
+
141
+ #### Props
142
+
143
+ | Prop | Type | Default | Description |
144
+ |------|------|---------|-------------|
145
+ | `variant` | `'primary' \| 'secondary' \| 'outline' \| 'ghost'` | `'primary'` | Button style variant |
146
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
147
+ | `loading` | `boolean` | `false` | Show loading spinner |
148
+ | `disabled` | `boolean` | `false` | Disable the button |
149
+ | `children` | `ReactNode` | - | Button content |
150
+
151
+ ## Core Concepts
152
+
153
+ ### AI Agent Integration
154
+
155
+ The SDK connects to your HSAFA AI Agent Studio, allowing your agents to:
156
+ - **Execute Actions**: Call functions in your application
157
+ - **Render Components**: Display custom UI elements in chat
158
+ - **Access Data**: Interact with your backend systems
159
+
160
+ ### How It Works
161
+
162
+ 1. **Agent Calls Action**: Your AI agent (built in HSAFA Studio) decides to call a registered action
163
+ 2. **SDK Executes**: The action runs in your React app with the provided parameters
164
+ 3. **Return Data**: Results are sent back to the agent to continue the conversation
165
+ 4. **Render UI**: Agent can display custom components based on the data
166
+
167
+ ## API Reference
168
+
169
+ ### Components
170
+
171
+ #### HsafaChat
172
+
173
+ Chat interface for your AI agents built in HSAFA Studio.
174
+
175
+ ```tsx
176
+ <HsafaChat
177
+ agentId="your-agent-id"
178
+ width={400}
179
+ height={600}
180
+ />
181
+ ```
182
+
183
+ | Prop | Type | Description |
184
+ |------|------|-------------|
185
+ | `agentId` | `string` | **Required** - ID of your agent from HSAFA Studio |
186
+ | `width` | `number` | Chat panel width (default: 400) |
187
+ | `height` | `number` | Chat panel height (default: 600) |
188
+ | `placeholder` | `string` | Input placeholder text |
189
+ | `primaryColor` | `string` | Primary theme color |
190
+
191
+ #### HsafaProvider
192
+
193
+ Provides context for agent communication.
194
+
195
+ ```tsx
196
+ <HsafaProvider baseUrl="https://your-hsafa-api.com">
197
+ {/* Your app */}
198
+ </HsafaProvider>
199
+ ```
200
+
201
+ | Prop | Type | Description |
202
+ |------|------|-------------|
203
+ | `baseUrl` | `string` | **Required** - Your HSAFA API endpoint |
204
+ | `children` | `ReactNode` | **Required** - App components |
205
+
206
+ ### Hooks
207
+
208
+ #### useHsafaAction
209
+
210
+ Register functions that your AI agent can call. Perfect for connecting agents to your business logic.
211
+
212
+ ```tsx
213
+ import { useHsafaAction } from '@hsafa/ui-sdk';
214
+
215
+ function MyApp() {
216
+ // Register actions your agent can use
217
+ useHsafaAction('getUserProfile', async ({ userId }) => {
218
+ const user = await fetchUserFromDatabase(userId);
219
+ return { name: user.name, email: user.email };
220
+ });
221
+
222
+ useHsafaAction('placeOrder', async ({ productId, quantity }) => {
223
+ const order = await createOrder(productId, quantity);
224
+ return { orderId: order.id, total: order.total };
225
+ });
226
+
227
+ return <YourApp />;
228
+ }
229
+ ```
230
+
231
+ #### useHsafaComponent
232
+
233
+ Register UI components that agents can render in chat. Great for displaying data visually.
234
+
235
+ ```tsx
236
+ import { useHsafaComponent } from '@hsafa/ui-sdk';
237
+
238
+ function MyApp() {
239
+ // Register components your agent can display
240
+ useHsafaComponent('OrderSummary', ({ order }) => (
241
+ <div className="order-card">
242
+ <h3>Order #{order.id}</h3>
243
+ <p>Total: ${order.total}</p>
244
+ <p>Status: {order.status}</p>
245
+ </div>
246
+ ));
247
+
248
+ useHsafaComponent('ProductList', ({ products }) => (
249
+ <div className="grid">
250
+ {products.map(product => (
251
+ <div key={product.id} className="product-card">
252
+ <img src={product.image} alt={product.name} />
253
+ <h4>{product.name}</h4>
254
+ <p>${product.price}</p>
255
+ </div>
256
+ ))}
257
+ </div>
258
+ ));
259
+
260
+ return <YourApp />;
261
+ }
262
+ ```
263
+
264
+ #### useHsafa
265
+
266
+ Advanced hook for manual registration and context access.
267
+
268
+ ```tsx
269
+ import { useHsafa } from '@hsafa/ui-sdk';
270
+
271
+ function MyComponent() {
272
+ const { registerAction, registerComponent } = useHsafa();
273
+
274
+ // Manual registration with cleanup
275
+ useEffect(() => {
276
+ const cleanup1 = registerAction('customAction', handler);
277
+ const cleanup2 = registerComponent('CustomComponent', Component);
278
+
279
+ return () => {
280
+ cleanup1();
281
+ cleanup2();
282
+ };
283
+ }, []);
284
+ }
285
+ ```
286
+
287
+ ## Development
288
+
289
+ ### Prerequisites
290
+
291
+ - Node.js 18+
292
+ - pnpm (recommended)
293
+
294
+ ### Setup
295
+
296
+ ```bash
297
+ # Clone the repository
298
+ git clone https://github.com/husamabusafa/hsafa.git
299
+ cd hsafa/sdk
300
+
301
+ # Install dependencies
302
+ pnpm install
303
+
304
+ # Start development
305
+ pnpm dev
306
+
307
+ # Run tests
308
+ pnpm test
309
+
310
+ # Start Storybook
311
+ pnpm storybook
312
+ ```
313
+
314
+ ### Scripts
315
+
316
+ - `pnpm build` - Build the library for production
317
+ - `pnpm dev` - Build in watch mode
318
+ - `pnpm test` - Run tests
319
+ - `pnpm test:ui` - Run tests with UI
320
+ - `pnpm storybook` - Start Storybook development server
321
+ - `pnpm build:storybook` - Build Storybook for production
322
+ - `pnpm lint` - Run ESLint
323
+ - `pnpm type-check` - Run TypeScript type checking
324
+
325
+ ## Publishing
326
+
327
+ ```bash
328
+ # Build the library
329
+ pnpm build
330
+
331
+ # Publish to npm
332
+ npm publish --access public
333
+ ```
334
+
335
+ ## License
336
+
337
+ MIT © [Husam Abu Safa](https://github.com/husamabusafa)
338
+
339
+ ## Contributing
340
+
341
+ Contributions are welcome! Please feel free to submit a Pull Request.
342
+
343
+ 1. Fork the repository
344
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
345
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
346
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
347
+ 5. Open a Pull Request
package/dist/index.cjs ADDED
@@ -0,0 +1,30 @@
1
+ 'use strict';var jsxRuntime=require('react/jsx-runtime'),react=require('react'),reactDom=require('react-dom'),iconsReact=require('@tabler/icons-react');var Z={};var er=({variant:a="primary",size:u="md",loading:p=false,disabled:m,children:A,className:T,...z})=>{let j=[Z.button,Z[a],Z[u],p&&Z.loading,T].filter(Boolean).join(" ");return jsxRuntime.jsxs("button",{className:j,disabled:m||p,...z,children:[p&&jsxRuntime.jsx("span",{className:Z.spinner}),jsxRuntime.jsx("span",{className:p?Z.hiddenText:void 0,children:A})]})};function nr(a=false){let[u,p]=react.useState(a),m=react.useCallback(()=>p(z=>!z),[]),A=react.useCallback(()=>p(true),[]),T=react.useCallback(()=>p(false),[]);return {on:u,toggle:m,setOn:p,setTrue:A,setFalse:T}}function lr(){let a=react.useRef(null);return react.useEffect(()=>{let u=a.current;if(!u)return;let p=new MutationObserver(()=>{u.scrollTop=u.scrollHeight;});return p.observe(u,{childList:true,subtree:true}),u.scrollTop=u.scrollHeight,()=>p.disconnect()},[]),a}var We=react.createContext(void 0);function Et({baseUrl:a,children:u}){let[p,m]=react.useState(new Map),[A,T]=react.useState(new Map),z=react.useCallback((M,v)=>(m($=>{let g=new Map($);return g.set(String(M),v),g}),()=>{m($=>{let g=new Map($),y=g.get(String(M));return (!v||y===v)&&g.delete(String(M)),g});}),[]),j=react.useCallback((M,v)=>{m($=>{let g=new Map($),y=g.get(String(M));return (!v||y===v)&&g.delete(String(M)),g});},[]),Y=react.useCallback((M,v)=>(T($=>{let g=new Map($);return g.set(String(M),v),g}),()=>{T($=>{let g=new Map($),y=g.get(String(M));return (!v||y===v)&&g.delete(String(M)),g});}),[]),te=react.useCallback((M,v)=>{T($=>{let g=new Map($),y=g.get(String(M));return (!v||y===v)&&g.delete(String(M)),g});},[]),ce=react.useMemo(()=>({baseUrl:a,actions:p,components:A,registerAction:z,unregisterAction:j,registerComponent:Y,unregisterComponent:te}),[a,p,A,z,j,Y,te]);return jsxRuntime.jsx(We.Provider,{value:ce,children:u})}function ee(){let a=react.useContext(We);return a||{baseUrl:void 0,actions:new Map,components:new Map,registerAction:()=>()=>{},unregisterAction:()=>{},registerComponent:()=>()=>{},unregisterComponent:()=>{}}}function mr(a,u){let{registerAction:p}=ee(),m=react.useRef(u);react.useEffect(()=>{m.current=u;},[u]),react.useEffect(()=>!a||typeof m.current!="function"?void 0:p(a,(T,z)=>m.current(T,z)),[a,p]);}function Cr(a,u){let{registerComponent:p}=ee(),m=react.useRef(u);react.useEffect(()=>{m.current=u;},[u]),react.useEffect(()=>!a||typeof m.current!="function"?void 0:p(a,m.current),[a,p]);}function _t(a){let u=Date.now()-a,p=Math.max(1,Math.floor(u/1e3));if(p<60)return `${p}s`;let m=Math.floor(p/60);if(m<60)return `${m}m`;let A=Math.floor(m/60);if(A<24)return `${A}h`;let T=Math.floor(A/24);if(T<7)return `${T}d`;let z=Math.floor(T/7);if(z<4)return `${z}w`;let j=Math.floor(T/30);return j<12?`${j}mo`:`${Math.floor(j/12)}y`}function Qe(a,u){if(!a)return u;let p=a.endsWith("/")?a.slice(0,-1):a,m=u.startsWith("/")?u:`/${u}`;return `${p}${m}`}var Wt={dark:{primaryColor:"#4D78FF",backgroundColor:"#0B0B0F",borderColor:"#2A2C33",textColor:"#EDEEF0",accentColor:"#17181C",mutedTextColor:"#9AA0A6",inputBackground:"#17181C",cardBackground:"#121318",hoverBackground:"#1c1e25"},light:{primaryColor:"#2563EB",backgroundColor:"#FFFFFF",borderColor:"#E5E7EB",textColor:"#111827",accentColor:"#F9FAFB",mutedTextColor:"#6B7280",inputBackground:"#F9FAFB",cardBackground:"#F3F4F6",hoverBackground:"#F3F4F6"}};function Xt({agentId:a,children:u,theme:p="dark",primaryColor:m,backgroundColor:A,borderColor:T,textColor:z,accentColor:j,width:Y=420,maxWidth:te=420,height:ce="100vh",expandable:M=true,alwaysOpen:v=false,defaultOpen:$=true,dir:g="ltr",floatingButtonPosition:y=g==="rtl"?{bottom:16,left:16}:{bottom:16,right:16},enableBorderAnimation:Ae=true,enableContentPadding:Ze=true,borderRadius:Ce=16,enableContentBorder:$e=true,placeholder:et="Ask your question...",title:He="Agent",className:tt="",chatContainerClassName:rt=""}){let{baseUrl:Ie,actions:Ee,components:ot}=ee(),ue="hsafaChat",Re=`${ue}.chats`,he=e=>`${ue}.chat.${e}`,V=`${ue}.currentChatId`,Be=`${ue}.showChat`,[de,Fe]=react.useState(""),[_,pe]=react.useState(()=>{if(v)return true;try{let e=localStorage.getItem(Be);return e!==null?e==="true":$}catch{return $}});async function ze(e,n){if(!a)return;let r=n.trim();if(!r)return;U(null),re(true);let s=N.findIndex(d=>d.id===e);if(s===-1||N[s].role!=="user"){re(false);return}let c=N.slice(0,s),H={id:e,role:"user",text:r},O=ie(),C=[...c,H,{id:O,role:"assistant",items:[],reasoning:"",reasoningOpen:false}];w(C),ge(null);try{let d=[...c.map(E=>E.role==="user"?{role:"user",content:E.text}:{role:"assistant",items:Array.isArray(E.items)?E.items:[]}),{role:"user",content:r}],I={prompt:r,chatId:k??void 0,messages:d};w(E=>E.map(q=>q.id===O||q.id===e?{...q,requestParams:I}:q));let S=await fetch(Qe(Ie,`/api/run/${a}`),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(I)});if(!S.ok||!S.body){let E=await S.text().catch(()=>"");throw new Error(E||`Request failed with ${S.status}`)}let P=S.body.getReader(),Q=new TextDecoder,D="";for(;;){let{done:E,value:q}=await P.read();if(E)break;D+=Q.decode(q,{stream:!0});let f;for(;(f=D.indexOf(`
2
+ `))!==-1;){let R=D.slice(0,f).trim();if(D=D.slice(f+1),!!R)try{let i=JSON.parse(R);if(i?.type==="meta"){if(i.actionExecuteMap&&typeof i.actionExecuteMap=="object"&&(Te.current=i.actionExecuteMap),i.assistantMessageId&&(oe.current=String(i.assistantMessageId),me.current.clear(),ye.current.clear(),G.current.clear(),ne(new Map)),i.chatId&&!k){W(i.chatId),L.current=!0;let l=r,K=(X.current||l||"New chat").slice(0,80),b=Date.now();le({id:i.chatId,title:K,createdAt:b,updatedAt:b}),se({id:i.chatId,messages:C,agentId:a});try{localStorage.setItem(V,i.chatId);}catch{}}continue}if(i?.type==="reasoning"){let l=String(i.text??"");w(K=>K.map(b=>b.id===O&&b.role==="assistant"?{...b,reasoning:(b.reasoning??"")+l}:b));continue}if(i?.type==="partial"||i?.type==="final"){let l=i.value;l&&Array.isArray(l.items)&&(w(K=>K.map(b=>b.id===O&&b.role==="assistant"?{...b,items:l.items}:b)),Ue(l.items,i.type==="partial"?"partial":"final")),i?.type==="final"&&w(K=>K.map(b=>b.id===O&&b.role==="assistant"?{...b,reasoningOpen:!1}:b));continue}if(i?.type==="usage"){let l=i?.value?.reasoningTokens;typeof l=="number"&&w(K=>K.map(b=>b.id===O&&b.role==="assistant"?{...b,reasoningTokens:l}:b));continue}if(i?.type==="error"){U(String(i.error??"Unknown error"));continue}}catch{}}}}catch(d){U(String(d?.message??d));}finally{if(re(false),!k&&!L.current){let d=`local-${ie()}`;W(d),L.current=true;let I=(X.current||"New chat").slice(0,80),S=Date.now();le({id:d,title:I,createdAt:S,updatedAt:S}),se({id:d,messages:N,agentId:a});try{localStorage.setItem(V,d);}catch{}}}}let[N,w]=react.useState([]),[h,re]=react.useState(false),[Oe,U]=react.useState(null),ae=react.useRef(null),[k,W]=react.useState(null),[nt,ve]=react.useState(false),[De,at]=react.useState(""),[Gt,st]=react.useState(0),[lt,it]=react.useState(false),[ct,ge]=react.useState(null),[fe,Le]=react.useState(""),ut=react.useRef(null),Pe=react.useRef(null),dt=react.useRef(null),[ke,pt]=react.useState(true),we=react.useRef(false),L=react.useRef(false),X=react.useRef(null),gt=react.useRef(null),ft=react.useRef(null),Te=react.useRef({}),oe=react.useRef(void 0),me=react.useRef(new Set),ye=react.useRef(new Map),G=react.useRef(new Map),[mt,ne]=react.useState(new Map),je=react.useCallback((e,n)=>{let r=ye.current.get(e)||[],s=JSON.stringify(n);if(r.push(s),r.length>3&&r.shift(),ye.current.set(e,r),r.length>=2){let c=r.slice(-2);return c[0]===c[1]}return false},[]),Ue=react.useCallback((e,n)=>{!Array.isArray(e)||e.length===0||e.forEach((r,s)=>{if(!(!r||typeof r!="object")&&r.type==="action"){let c=String(r.name??"").trim();if(!c)return;let H=Ee.get(c);if(!H)return;let O=!!Te.current[c],C=`${oe.current||"assist"}:${c}:${s}`,d=`${c}:${s}`;try{if(n==="partial"&&O)ne(I=>new Map(I).set(d,"executing")),Promise.resolve(H(r.params,{name:c,trigger:n,index:s,assistantMessageId:oe.current,chatId:k||void 0})).catch(()=>{});else if(n==="partial"&&!O){let I=je(d,r.params),S=G.current.get(d);I&&S!=="executed"?(G.current.set(d,"executed"),ne(P=>new Map(P).set(d,"executed")),Promise.resolve(H(r.params,{name:c,trigger:"params_complete",index:s,assistantMessageId:oe.current,chatId:k||void 0})).catch(()=>{})):S||(G.current.set(d,"executing"),ne(P=>new Map(P).set(d,"executing")));}else n==="final"&&G.current.get(d)!=="executed"&&!me.current.has(C)&&(me.current.add(C),G.current.set(d,"executed"),ne(S=>new Map(S).set(d,"executed")),Promise.resolve(H(r.params,{name:c,trigger:O?"final":"params_complete",index:s,assistantMessageId:oe.current,chatId:k||void 0})).catch(()=>{}));}catch{}}});},[Ee,k,je]),Me=()=>{try{let e=localStorage.getItem(Re);return e?JSON.parse(e):[]}catch{return []}},Je=e=>{try{localStorage.setItem(Re,JSON.stringify(e));}catch{}},qe=e=>{try{let n=localStorage.getItem(he(e));return n?JSON.parse(n):null}catch{return null}},se=e=>{try{localStorage.setItem(he(e.id),JSON.stringify(e));}catch{}},le=e=>{let n=Me(),r=n.findIndex(s=>s.id===e.id);r>=0?n[r]=e:n.unshift(e),Je(n);},yt=e=>{let r=Me().filter(s=>s.id!==e);Je(r);},bt=e=>{try{localStorage.removeItem(he(e));}catch{}},xt=e=>{if(bt(e),yt(e),k===e){w([]),U(null),W(null),L.current=false,X.current=null;try{localStorage.removeItem(V);}catch{}}};react.useEffect(()=>{if(we.current){we.current=false;return}ke&&Pe.current?.scrollIntoView({behavior:"smooth",block:"end"});},[N,h,ke]),react.useEffect(()=>{try{let e=localStorage.getItem(V);if(e){let n=qe(e);n&&(W(n.id),L.current=!0,w(n.messages||[]));}}catch{}},[]),react.useEffect(()=>{try{localStorage.setItem(Be,String(_));}catch{}},[_]),react.useEffect(()=>{if(!k||!L.current)return;se({id:k,messages:N,agentId:a});let n=N.find(c=>c.role==="user"),r=(X.current||(n?.text??"New chat")).slice(0,80),s={id:k,title:r,createdAt:Date.now(),updatedAt:Date.now()};le(s);try{localStorage.setItem(V,k);}catch{}},[N,k,a]);let ie=()=>`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;function Ct(){ae.current&&(ae.current.abort(),ae.current=null),re(false),U("Request stopped by user");}async function Ke(){if(!a)return;let e=de.trim();if(!e)return;U(null),re(true),!k&&N.length===0&&(X.current=e);let n=ie(),r=ie(),s={id:n,role:"user",text:e},c={id:r,role:"assistant",items:[],reasoning:"",reasoningOpen:false},H=[...N,s,c],O=[...N.map(C=>C.role==="user"?{role:"user",content:C.text}:{role:"assistant",items:Array.isArray(C.items)?C.items:[]}),{role:"user",content:e}];w(H),Fe("");try{ae.current=new AbortController;let C={prompt:e,chatId:k??void 0,messages:O};w(Q=>Q.map(D=>D.id===r||D.id===n?{...D,requestParams:C}:D));let d=await fetch(Qe(Ie,`/api/run/${a}`),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(C),signal:ae.current.signal});if(!d.ok||!d.body){let Q=await d.text().catch(()=>"");throw new Error(Q||`Request failed with ${d.status}`)}let I=d.body.getReader(),S=new TextDecoder,P="";for(;;){let{done:Q,value:D}=await I.read();if(Q)break;P+=S.decode(D,{stream:!0});let E;for(;(E=P.indexOf(`
3
+ `))!==-1;){let q=P.slice(0,E).trim();if(P=P.slice(E+1),!!q)try{let f=JSON.parse(q);if(f?.type==="meta"){if(f.actionExecuteMap&&typeof f.actionExecuteMap=="object"&&(Te.current=f.actionExecuteMap),f.assistantMessageId&&(oe.current=String(f.assistantMessageId),me.current.clear(),ye.current.clear(),G.current.clear(),ne(new Map)),f.chatId&&!k){W(f.chatId),L.current=!0;let R=e,i=(X.current||R||"New chat").slice(0,80),l=Date.now();le({id:f.chatId,title:i,createdAt:l,updatedAt:l}),se({id:f.chatId,messages:H,agentId:a});try{localStorage.setItem(V,f.chatId);}catch{}}continue}if(f?.type==="reasoning"){let R=String(f.text??"");w(i=>i.map(l=>l.id===r&&l.role==="assistant"?{...l,reasoning:(l.reasoning??"")+R}:l));continue}if(f?.type==="partial"||f?.type==="final"){let R=f.value;R&&Array.isArray(R.items)&&(w(i=>i.map(l=>l.id===r&&l.role==="assistant"?{...l,items:R.items}:l)),Ue(R.items,f.type==="partial"?"partial":"final")),f?.type==="final"&&w(i=>i.map(l=>l.id===r&&l.role==="assistant"?{...l,reasoningOpen:!1}:l));continue}if(f?.type==="usage"){let R=f?.value?.reasoningTokens;typeof R=="number"&&w(i=>i.map(l=>l.id===r&&l.role==="assistant"?{...l,reasoningTokens:R}:l));continue}if(f?.type==="error"){U(String(f.error??"Unknown error"));continue}}catch{}}}}catch(C){U(String(C?.message??C));}finally{if(re(false),!k&&!L.current){let C=`local-${ie()}`;W(C),L.current=true;let d=(X.current||"New chat").slice(0,80),I=Date.now();le({id:C,title:d,createdAt:I,updatedAt:I}),se({id:C,messages:N,agentId:a});try{localStorage.setItem(V,C);}catch{}}}}function ht(e){return !Array.isArray(e)||e.length===0?null:jsxRuntime.jsx("div",{className:"space-y-3",children:e.map((n,r)=>{let s=`it-${r}`;if(typeof n=="string")return jsxRuntime.jsx("div",{className:"rounded-xl p-4 text-[14px] whitespace-pre-wrap",children:n},s);if(n&&typeof n=="object"){if(n.type==="action"){let c=`${String(n.name??"action")}:${r}`,H=mt.get(c);return jsxRuntime.jsx("div",{className:"space-y-2",children:jsxRuntime.jsx("div",{className:"px-2 py-1 text-xs",style:{color:t.mutedTextColor},children:H==="executing"?jsxRuntime.jsxs("span",{className:"flex items-center gap-2",children:[jsxRuntime.jsxs("svg",{className:"animate-spin h-3 w-3",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[jsxRuntime.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),jsxRuntime.jsx("path",{className:"opacity-75",fill:"currentColor",d:"m4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),String(n.name??"action")," is executing"]}):jsxRuntime.jsxs("span",{className:"flex items-center gap-1",children:[jsxRuntime.jsx("span",{className:"inline-block h-1.5 w-1.5 rounded-full",style:{backgroundColor:"#10b981"}}),String(n.name??"action")," has executed"]})})},s)}if(n.type==="ui-component"||n.type==="ui"){let c=String(n.name??n.component??"").trim(),H=c?ot.get(c):void 0;return H?jsxRuntime.jsx(H,{...n.props||{}}):jsxRuntime.jsxs("div",{className:"rounded-xl p-4",style:{backgroundColor:t.inputBackground,border:`1px solid ${t.borderColor}`},children:[jsxRuntime.jsxs("div",{className:"inline-flex items-center gap-2 text-xs mb-2",style:{color:t.mutedTextColor},children:[jsxRuntime.jsx("span",{className:"px-2 py-0.5 rounded",style:{backgroundColor:t.accentColor,border:`1px solid ${t.borderColor}`},children:"UI"}),jsxRuntime.jsx("span",{children:c||"component"}),jsxRuntime.jsx("span",{className:"ml-2 opacity-70",children:"(unregistered)"})]}),jsxRuntime.jsx("pre",{className:"text-xs overflow-auto",style:{color:t.mutedTextColor},children:JSON.stringify(n.props??{},null,2)})]},s)}return jsxRuntime.jsx("div",{className:"rounded-xl p-4 text-[14px]",style:{backgroundColor:t.cardBackground,border:`1px solid ${t.borderColor}`},children:jsxRuntime.jsx("pre",{className:"text-xs overflow-auto",style:{color:t.mutedTextColor},children:JSON.stringify(n,null,2)})},s)}return null})})}let J=Wt[p],t={primaryColor:m||J.primaryColor,backgroundColor:A||J.backgroundColor,borderColor:T||J.borderColor,textColor:z||J.textColor,accentColor:j||J.accentColor,mutedTextColor:J.mutedTextColor,inputBackground:J.inputBackground,cardBackground:J.cardBackground,hoverBackground:J.hoverBackground},vt={backgroundColor:t.backgroundColor,color:t.textColor,height:ce},kt={width:typeof Y=="number"?`${Y}px`:Y,maxWidth:typeof te=="number"?`${te}px`:te},wt={position:"fixed",bottom:typeof y.bottom=="number"?`${y.bottom}px`:y.bottom,right:y.right?typeof y.right=="number"?`${y.right}px`:y.right:void 0,top:y.top?typeof y.top=="number"?`${y.top}px`:y.top:void 0,left:y.left?typeof y.left=="number"?`${y.left}px`:y.left:void 0},Ne=typeof Ce=="number"?`${Ce}px`:Ce;return jsxRuntime.jsxs("div",{className:`flex h-full w-full ${tt}`,style:vt,dir:g,children:[jsxRuntime.jsx("div",{className:`flex items-stretch transition-all duration-1000 justify-stretch w-full h-full ${_&&Ze?"p-4":"p-0"}`,children:jsxRuntime.jsx("div",{className:"relative flex w-full h-full transition-all duration-1000 ease-out",style:{borderRadius:_&&$e?Ne:"0"},children:_&&$e?jsxRuntime.jsx("div",{className:`w-full h-full transition-all duration-600 ease-out ${h&&Ae?"tc-animated-border p-[1.5px]":"border p-0"}`,style:{borderRadius:Ne,borderColor:!h||!Ae?t.borderColor:"transparent"},children:jsxRuntime.jsx("div",{className:"w-full h-full",style:{borderRadius:Ne,backgroundColor:t.backgroundColor},children:u})}):jsxRuntime.jsx("div",{className:"w-full h-full",children:u})})}),jsxRuntime.jsxs("div",{className:`${rt} flex flex-col transition-all duration-300 ease-out overflow-hidden ${_||v?lt&&M?"fixed inset-0 z-50 w-full max-w-full px-6 py-6":"px-4 py-6 opacity-100 translate-x-0":`w-0 max-w-0 px-0 py-6 opacity-0 ${g==="rtl"?"translate-x-2":"-translate-x-2"} pointer-events-none`}`,style:{...kt,height:ce,backgroundColor:_||v?t.backgroundColor:"transparent"},children:[jsxRuntime.jsxs("div",{className:"mb-6 flex items-center justify-between",children:[jsxRuntime.jsx("div",{className:"min-w-0",children:jsxRuntime.jsx("h1",{title:He,className:"truncate text-[18px] font-semibold",style:{color:t.textColor},children:He})}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2 relative",style:{color:t.mutedTextColor},children:[M&&jsxRuntime.jsx("button",{"aria-label":"Pop out",className:"rounded-lg p-2 transition-all duration-200 ease-out",style:{backgroundColor:"transparent",color:t.mutedTextColor},onMouseEnter:e=>{e.currentTarget.style.backgroundColor=t.hoverBackground,e.currentTarget.style.color=t.textColor;},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent",e.currentTarget.style.color=t.mutedTextColor;},onClick:()=>{pe(true),it(e=>!e);},children:jsxRuntime.jsx(iconsReact.IconArrowsMaximize,{size:20,stroke:2})}),jsxRuntime.jsx("button",{"aria-label":"New",className:"rounded-lg p-2 transition-all duration-200 ease-out",style:{backgroundColor:"transparent",color:t.mutedTextColor},onMouseEnter:e=>{e.currentTarget.style.backgroundColor=t.hoverBackground,e.currentTarget.style.color=t.textColor;},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent",e.currentTarget.style.color=t.mutedTextColor;},onClick:()=>{h||(w([]),U(null),W(null),L.current=false,X.current=null);},children:jsxRuntime.jsx(iconsReact.IconPlus,{size:20,stroke:2})}),jsxRuntime.jsx("button",{"aria-label":"History",className:"rounded-lg p-2 transition-all duration-200 ease-out",style:{backgroundColor:"transparent",color:t.mutedTextColor},onMouseEnter:e=>{e.currentTarget.style.backgroundColor=t.hoverBackground,e.currentTarget.style.color=t.textColor;},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent",e.currentTarget.style.color=t.mutedTextColor;},onClick:()=>ve(e=>!e),ref:gt,children:jsxRuntime.jsx(iconsReact.IconHistory,{size:20,stroke:2})}),nt&&reactDom.createPortal(jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"fixed inset-0 z-[900] bg-black/40 backdrop-blur-sm",onClick:()=>ve(false)}),jsxRuntime.jsxs("div",{ref:ft,className:"fixed left-1/2 top-16 -translate-x-1/2 z-[1000] w-[680px] max-w-[94vw] overflow-hidden rounded-2xl border border-[#2A2C33] bg-[#0F1116]/95 shadow-2xl ring-1 ring-black/10",children:[jsxRuntime.jsx("div",{className:"flex items-center gap-3 border-b border-[#2A2C33] px-4 py-3",children:jsxRuntime.jsx("div",{className:"flex-1",children:jsxRuntime.jsx("input",{autoFocus:true,value:De,onChange:e=>at(e.target.value),placeholder:"Search",className:"w-full rounded-lg bg-[#0B0B0F] px-3 py-2 text-sm text-[#EDEEF0] placeholder:text-[#9AA0A6] outline-none border border-[#2A2C33] focus:border-[#3a3d46]"})})}),jsxRuntime.jsx("div",{className:"max-h-[60vh] overflow-y-auto",children:(()=>{let e=De.toLowerCase().trim(),n=Me();return e&&(n=n.filter(r=>(r.title||"").toLowerCase().includes(e))),!n||n.length===0?jsxRuntime.jsx("div",{className:"p-6 text-[#9AA0A6]",children:"No chats found."}):jsxRuntime.jsx("ul",{className:"divide-y divide-[#2A2C33]",children:n.map(r=>jsxRuntime.jsx("li",{children:jsxRuntime.jsxs("div",{className:`flex w-full items-center justify-between gap-3 p-3 ${r.id===k?"bg-[#121318]":""}`,children:[jsxRuntime.jsx("button",{className:"flex-1 text-left transition-colors hover:bg-[#17181C] rounded-lg px-2 py-2",onClick:()=>{let s=qe(r.id);if(s){W(r.id),L.current=true,w(s.messages||[]);try{localStorage.setItem(V,r.id);}catch{}ve(false),pe(true);}},children:jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-3",children:[jsxRuntime.jsx("div",{className:"min-w-0",children:jsxRuntime.jsx("div",{className:"truncate text-[14px] text-[#EDEEF0]",children:r.title||"Untitled chat"})}),jsxRuntime.jsx("div",{className:"shrink-0 text-[12px] text-[#9AA0A6]",children:_t(r.updatedAt)})]})}),jsxRuntime.jsx("button",{className:"shrink-0 rounded-md p-2 text-[#9AA0A6] hover:text-red-300 hover:bg-red-500/10 border border-transparent hover:border-red-500/30",title:"Delete chat",onClick:s=>{s.stopPropagation(),xt(r.id),st(c=>c+1);},children:jsxRuntime.jsx(iconsReact.IconTrash,{size:16,stroke:2})})]})},r.id))})})()})]})]}),document.body),!v&&jsxRuntime.jsx("button",{"aria-label":"Close chat",className:"rounded-lg p-2 transition-all duration-200 ease-out",style:{backgroundColor:"transparent",color:t.mutedTextColor},onMouseEnter:e=>{e.currentTarget.style.backgroundColor=t.hoverBackground,e.currentTarget.style.color=t.textColor;},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent",e.currentTarget.style.color=t.mutedTextColor;},onClick:()=>pe(false),children:jsxRuntime.jsx(iconsReact.IconChevronRight,{size:20,stroke:2,style:{transform:g==="rtl"?"rotate(180deg)":"none"}})})]})]}),jsxRuntime.jsxs("div",{className:"flex-1 overflow-y-auto space-y-4 px-1 pb-4 pt-4",ref:dt,onScroll:e=>{let n=e.currentTarget,c=n.scrollHeight-(n.scrollTop+n.clientHeight)<=64;c!==ke&&pt(c);},children:[Oe&&jsxRuntime.jsx("div",{className:"mx-2 rounded-xl bg-red-500/10 text-red-300 border border-red-500/30 p-3 text-sm",children:Oe}),N.length===0&&!h&&jsxRuntime.jsx("div",{className:"mx-2 rounded-xl p-4",style:{border:`1px solid ${t.borderColor}`,backgroundColor:t.accentColor,color:t.mutedTextColor},children:"Start by sending a message to the agent."}),jsxRuntime.jsx("ul",{className:"space-y-4",children:N.map((e,n)=>jsxRuntime.jsx("li",{className:"px-1",children:e.role==="user"?ct===e.id?jsxRuntime.jsxs("div",{className:"max-w-[720px] rounded-2xl p-2 text-[15px] ring-2",style:{backgroundColor:t.accentColor,color:t.textColor,borderColor:t.primaryColor},children:[jsxRuntime.jsx("textarea",{autoFocus:true,className:"w-full resize-none bg-transparent p-2 leading-relaxed outline-none",rows:Math.max(2,Math.min(10,Math.ceil((fe||e.text).length/60))),value:fe,onChange:r=>Le(r.target.value),onKeyDown:r=>{r.key==="Escape"?ge(null):r.key==="Enter"&&!r.shiftKey&&(r.preventDefault(),h||ze(e.id,fe||e.text));}}),jsxRuntime.jsxs("div",{className:"flex items-center justify-end gap-2 px-2 pb-2",children:[jsxRuntime.jsx("button",{className:"rounded-lg px-3 py-1 text-sm transition-colors",style:{border:`1px solid ${t.borderColor}`,color:t.mutedTextColor,backgroundColor:"transparent"},onMouseEnter:r=>r.currentTarget.style.backgroundColor=t.inputBackground,onMouseLeave:r=>r.currentTarget.style.backgroundColor="transparent",onClick:()=>ge(null),children:"Cancel"}),jsxRuntime.jsx("button",{className:"rounded-lg px-3 py-1 text-sm transition-colors",style:{border:`1px solid ${t.borderColor}`,backgroundColor:t.cardBackground,color:t.textColor},onMouseEnter:r=>r.currentTarget.style.borderColor=t.primaryColor,onMouseLeave:r=>r.currentTarget.style.borderColor=t.borderColor,onClick:()=>{h||ze(e.id,fe||e.text);},children:"Save"})]})]}):jsxRuntime.jsx("div",{title:"Click to edit",onClick:()=>{h||(ge(e.id),Le(e.text));},className:"max-w-[720px] rounded-2xl p-4 text-[15px] leading-relaxed whitespace-pre-wrap cursor-pointer transition",style:{backgroundColor:t.accentColor,color:t.textColor},onMouseEnter:r=>r.currentTarget.style.backgroundColor=t.hoverBackground,onMouseLeave:r=>r.currentTarget.style.backgroundColor=t.accentColor,children:e.text}):jsxRuntime.jsxs("div",{className:"space-y-3",children:[e.reasoning&&jsxRuntime.jsxs("div",{className:"rounded-xl p-3 cursor-pointer",style:{backgroundColor:t.inputBackground,border:`1px solid ${t.borderColor}`},onClick:()=>{we.current=true,w(r=>r.map(s=>s.id===e.id&&s.role==="assistant"?{...s,reasoningOpen:!s.reasoningOpen}:s));},children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-1",children:[jsxRuntime.jsx("div",{className:"text-xs",style:{color:t.mutedTextColor},children:"Reasoning"}),jsxRuntime.jsx("button",{type:"button",className:"text-xs transition-colors",style:{color:t.mutedTextColor},onMouseEnter:r=>r.currentTarget.style.color=t.textColor,onMouseLeave:r=>r.currentTarget.style.color=t.mutedTextColor,children:e.reasoningOpen?"Hide":"Show full"})]}),e.reasoningOpen?jsxRuntime.jsx("pre",{className:"text-xs whitespace-pre-wrap break-words",style:{color:t.mutedTextColor},children:e.reasoning}):(()=>{let r=(e.reasoning||"").trim().split(`
4
+ `).filter(c=>c.trim()),s=r.length>0?r[r.length-1]:"";return jsxRuntime.jsx("pre",{className:"text-xs whitespace-pre-wrap break-words",style:{color:t.mutedTextColor},children:s||"\u2026"})})()]}),ht(e.items),h&&n===N.length-1&&jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-xs",style:{color:t.mutedTextColor},children:[jsxRuntime.jsx("span",{className:"inline-block h-2 w-2 rounded-full animate-pulse",style:{backgroundColor:t.mutedTextColor}}),jsxRuntime.jsx("span",{children:"Working\u2026"})]})]})},e.id))}),jsxRuntime.jsx("div",{ref:Pe})]}),jsxRuntime.jsx("div",{className:"sticky bottom-0 mt-auto space-y-2 pb-2 pt-1",style:{backgroundColor:t.backgroundColor},children:jsxRuntime.jsx("div",{className:"relative flex-1",children:jsxRuntime.jsxs("div",{className:"relative w-full rounded-2xl pb-12 pt-4",style:{border:`1px solid ${t.borderColor}`,backgroundColor:t.accentColor},children:[jsxRuntime.jsx("div",{className:"px-4",children:jsxRuntime.jsx("textarea",{"aria-label":"Prompt",rows:2,className:"h-auto w-full resize-none bg-transparent text-[15px] leading-relaxed focus:outline-none hsafa-chat-textarea",style:{color:t.textColor},placeholder:et,value:de,onChange:e=>Fe(e.target.value),onKeyDown:e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),h||Ke());},ref:ut})}),jsxRuntime.jsxs("div",{className:"absolute bottom-2 left-2 flex items-center gap-1",style:{color:t.mutedTextColor},children:[jsxRuntime.jsx("button",{className:"rounded-lg p-2 transition-colors",style:{backgroundColor:"transparent"},onMouseEnter:e=>{e.currentTarget.style.backgroundColor=`${t.backgroundColor}99`,e.currentTarget.style.color=t.textColor;},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent",e.currentTarget.style.color=t.mutedTextColor;},"aria-label":"Attach files",children:jsxRuntime.jsx(iconsReact.IconPaperclip,{size:18,stroke:2})}),jsxRuntime.jsx("button",{className:"rounded-lg p-2 transition-colors",style:{backgroundColor:"transparent"},onMouseEnter:e=>{e.currentTarget.style.backgroundColor=`${t.backgroundColor}99`,e.currentTarget.style.color=t.textColor;},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent",e.currentTarget.style.color=t.mutedTextColor;},"aria-label":"Insert link",children:jsxRuntime.jsx(iconsReact.IconLink,{size:18,stroke:2})})]}),jsxRuntime.jsx("div",{className:"absolute bottom-2 right-2",children:jsxRuntime.jsx("button",{"aria-label":h?"Stop":"Send",disabled:!h&&!de.trim(),className:"rounded-xl p-3 transition-all duration-200 ease-out",style:{border:`1px solid ${h?"#ef4444":t.borderColor}`,backgroundColor:h?"#ef444420":t.cardBackground,color:h?"#ef4444":t.mutedTextColor,opacity:!h&&!de.trim()?.4:1},onMouseEnter:e=>{e.currentTarget.disabled||(h?(e.currentTarget.style.borderColor="#dc2626",e.currentTarget.style.backgroundColor="#dc262630",e.currentTarget.style.color="#dc2626"):(e.currentTarget.style.borderColor=t.primaryColor,e.currentTarget.style.backgroundColor=t.hoverBackground,e.currentTarget.style.color=t.textColor));},onMouseLeave:e=>{e.currentTarget.disabled||(h?(e.currentTarget.style.borderColor="#ef4444",e.currentTarget.style.backgroundColor="#ef444420",e.currentTarget.style.color="#ef4444"):(e.currentTarget.style.borderColor=t.borderColor,e.currentTarget.style.backgroundColor=t.cardBackground,e.currentTarget.style.color=t.mutedTextColor));},onClick:()=>{h?Ct():Ke();},children:h?jsxRuntime.jsx(iconsReact.IconPlayerStop,{size:18,stroke:2}):jsxRuntime.jsx(iconsReact.IconArrowUp,{size:18,stroke:2})})})]})})})]}),!_&&!v&&jsxRuntime.jsx("button",{"aria-label":"Open chat",onClick:()=>pe(true),className:"rounded-full border p-3 shadow-md transition-colors",style:{...wt,borderColor:t.borderColor,backgroundColor:t.accentColor,color:t.textColor,borderRadius:"50%"},onMouseEnter:e=>{e.currentTarget.style.borderColor=t.primaryColor,e.currentTarget.style.backgroundColor=`${t.accentColor}dd`;},onMouseLeave:e=>{e.currentTarget.style.borderColor=t.borderColor,e.currentTarget.style.backgroundColor=t.accentColor;},children:jsxRuntime.jsx(iconsReact.IconMessage,{size:20,stroke:2})}),jsxRuntime.jsx("style",{children:`
5
+ @keyframes tc-border-flow {
6
+ 0% { background-position: 0% 50%; }
7
+ 50% { background-position: 100% 50%; }
8
+ 100% { background-position: 0% 50%; }
9
+ }
10
+
11
+ .tc-animated-border {
12
+ position: relative;
13
+ /* Animated shimmer border using primary color */
14
+ background: linear-gradient(120deg,
15
+ ${t.primaryColor}dd 0%,
16
+ ${t.primaryColor}88 25%,
17
+ ${t.primaryColor}00 50%,
18
+ ${t.primaryColor}88 75%,
19
+ ${t.primaryColor}dd 100%
20
+ );
21
+ background-size: 300% 300%;
22
+ animation: tc-border-flow 3s ease-in-out infinite;
23
+ filter: drop-shadow(0 0 10px ${t.primaryColor}40);
24
+ }
25
+
26
+ .hsafa-chat-textarea::placeholder {
27
+ color: ${t.mutedTextColor};
28
+ }
29
+ `})]})}exports.Button=er;exports.HsafaChat=Xt;exports.HsafaProvider=Et;exports.useAutoScroll=lr;exports.useHsafa=ee;exports.useHsafaAction=mr;exports.useHsafaComponent=Cr;exports.useToggle=nr;//# sourceMappingURL=index.cjs.map
30
+ //# sourceMappingURL=index.cjs.map