
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@hsafa/ui-sdk
Advanced tools
React SDK for building AI agent interfaces with custom actions and interactive components.
npm install @hsafa/ui-sdk
# or
yarn add @hsafa/ui-sdk
# or
pnpm add @hsafa/ui-sdk
Use the ready-made chat interface:
import { HsafaProvider, HsafaChat } from '@hsafa/ui-sdk';
function App() {
return (
<HsafaProvider baseUrl="https://your-hsafa-api.com">
<HsafaChat
agentId="your-agent-id"
width={400}
height={600}
placeholder="Ask your AI agent anything..."
/>
</HsafaProvider>
);
}
Use the headless hooks to build a completely custom chat interface:
import { useHsafaAgent } from '@hsafa/ui-sdk';
function MyCustomChat() {
const agent = useHsafaAgent({
agentId: 'my-agent',
baseUrl: 'https://your-hsafa-api.com',
});
return (
<div>
{/* Messages */}
<div>
{agent.messages.map(msg => (
<div key={msg.id}>
<strong>{msg.role}:</strong> {msg.content}
</div>
))}
</div>
{/* Input */}
<input
value={agent.input}
onChange={(e) => agent.setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && agent.sendMessage()}
/>
<button onClick={() => agent.sendMessage()}>Send</button>
</div>
);
}
📚 Full Headless Documentation - Complete guide with examples
import { HsafaProvider, HsafaChat, useHsafaAction } from '@hsafa/ui-sdk';
function MyApp() {
return (
<HsafaProvider baseUrl="https://your-hsafa-api.com">
<ActionProviders />
<HsafaChat agentId="your-agent-id" />
</HsafaProvider>
);
}
function ActionProviders() {
// Register an action that your AI agent can call
useHsafaAction('getUserData', async (params) => {
const { userId } = params;
// Fetch user data from your database
return {
name: 'John Doe',
email: 'john@example.com',
status: 'active'
};
});
useHsafaAction('createTask', async (params) => {
const { title, description } = params;
// Create task in your system
return { taskId: '123', status: 'created' };
});
return null;
}
import { useHsafaComponent } from '@hsafa/ui-sdk';
function ComponentProviders() {
// Register UI components that agents can render
useHsafaComponent('ProductCard', ({ product }) => (
<div className="border rounded-lg p-4">
<img src={product.image} alt={product.name} />
<h3>{product.name}</h3>
<p>${product.price}</p>
<button>Add to Cart</button>
</div>
));
useHsafaComponent('StatusChart', ({ data }) => (
<div className="chart-container">
{/* Your chart implementation */}
<h4>Status Overview</h4>
{data.map(item => (
<div key={item.id}>{item.label}: {item.value}</div>
))}
</div>
));
return null;
}
A versatile button component with multiple variants and states.
import { Button } from '@hsafa/ui-sdk';
// Basic usage
<Button>Click me</Button>
// With variants
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
// With sizes
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
// With loading state
<Button loading>Loading...</Button>
// Disabled
<Button disabled>Disabled</Button>
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'outline' | 'ghost' | 'primary' | Button style variant |
size | 'sm' | 'md' | 'lg' | 'md' | Button size |
loading | boolean | false | Show loading spinner |
disabled | boolean | false | Disable the button |
children | ReactNode | - | Button content |
The SDK connects to your HSAFA AI Agent Studio, allowing your agents to:
Chat interface for your AI agents built in HSAFA Studio.
<HsafaChat
agentId="your-agent-id"
width={400}
height={600}
/>
| Prop | Type | Description |
|---|---|---|
agentId | string | Required - ID of your agent from HSAFA Studio |
width | number | Chat panel width (default: 400) |
height | number | Chat panel height (default: 600) |
placeholder | string | Input placeholder text |
primaryColor | string | Primary theme color |
Provides context for agent communication.
<HsafaProvider baseUrl="https://your-hsafa-api.com">
{/* Your app */}
</HsafaProvider>
| Prop | Type | Description |
|---|---|---|
baseUrl | string | Required - Your HSAFA API endpoint |
children | ReactNode | Required - App components |
Build custom chat UIs with complete control over styling and layout.
The main hook for headless agent integration. Provides all chat functionality without UI.
import { useHsafaAgent } from '@hsafa/ui-sdk';
const agent = useHsafaAgent({
agentId: 'my-agent',
baseUrl: 'https://your-hsafa-api.com',
tools: { /* custom tools */ },
uiComponents: { /* custom UI components */ },
onFinish: (message) => console.log('Done:', message),
onError: (error) => console.error('Error:', error),
});
// Available properties:
agent.input // Current input text
agent.setInput() // Update input
agent.messages // All messages
agent.isLoading // Loading state
agent.sendMessage() // Send message
agent.stop() // Stop generation
agent.newChat() // Start new chat
Persist and manage chat history in localStorage.
import { useHsafaAgent, useChatStorage } from '@hsafa/ui-sdk';
const agent = useHsafaAgent({ /* ... */ });
const storage = useChatStorage({
agentId: 'my-agent',
chatId: agent.chatId,
messages: agent.messages,
isLoading: agent.isLoading,
autoSave: true,
autoRestore: true,
});
// Available properties:
storage.chatList // All saved chats
storage.loadChat(chatId) // Load specific chat
storage.deleteChat(chatId) // Delete chat
storage.switchToChat(chatId) // Switch to chat
Edit messages and regenerate responses.
import { useMessageEditor } from '@hsafa/ui-sdk';
const editor = useMessageEditor({
messages: agent.messages,
isLoading: agent.isLoading,
sendMessage: agent.sendMessage,
setMessages: agent.setMessages,
});
// Available properties:
editor.startEdit(msgId, text) // Start editing
editor.saveEdit(msgId) // Save and regenerate
editor.cancelEdit() // Cancel editing
editor.isEditing(msgId) // Check if editing
Handle file attachments for messages.
import { useFileUpload } from '@hsafa/ui-sdk';
const fileUpload = useFileUpload('https://your-api.com');
// Available properties:
fileUpload.attachments // Current attachments
fileUpload.handleFileSelection() // Handle file input
fileUpload.clearAttachments() // Clear all
Register functions that your AI agent can call. Perfect for connecting agents to your business logic.
import { useHsafaAction } from '@hsafa/ui-sdk';
function MyApp() {
// Register actions your agent can use
useHsafaAction('getUserProfile', async ({ userId }) => {
const user = await fetchUserFromDatabase(userId);
return { name: user.name, email: user.email };
});
useHsafaAction('placeOrder', async ({ productId, quantity }) => {
const order = await createOrder(productId, quantity);
return { orderId: order.id, total: order.total };
});
return <YourApp />;
}
Register UI components that agents can render in chat. Great for displaying data visually.
import { useHsafaComponent } from '@hsafa/ui-sdk';
function MyApp() {
// Register components your agent can display
useHsafaComponent('OrderSummary', ({ order }) => (
<div className="order-card">
<h3>Order #{order.id}</h3>
<p>Total: ${order.total}</p>
<p>Status: {order.status}</p>
</div>
));
useHsafaComponent('ProductList', ({ products }) => (
<div className="grid">
{products.map(product => (
<div key={product.id} className="product-card">
<img src={product.image} alt={product.name} />
<h4>{product.name}</h4>
<p>${product.price}</p>
</div>
))}
</div>
));
return <YourApp />;
}
Advanced hook for manual registration and context access.
import { useHsafa } from '@hsafa/ui-sdk';
function MyComponent() {
const { registerAction, registerComponent } = useHsafa();
// Manual registration with cleanup
useEffect(() => {
const cleanup1 = registerAction('customAction', handler);
const cleanup2 = registerComponent('CustomComponent', Component);
return () => {
cleanup1();
cleanup2();
};
}, []);
}
# Clone the repository
git clone https://github.com/husamabusafa/hsafa.git
cd hsafa/sdk
# Install dependencies
pnpm install
# Start development
pnpm dev
# Run tests
pnpm test
# Start Storybook
pnpm storybook
pnpm build - Build the library for productionpnpm dev - Build in watch modepnpm test - Run testspnpm test:ui - Run tests with UIpnpm storybook - Start Storybook development serverpnpm build:storybook - Build Storybook for productionpnpm lint - Run ESLintpnpm type-check - Run TypeScript type checking# Build the library
pnpm build
# Publish to npm
npm publish --access public
MIT © Husam Abu Safa
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)FAQs
React SDK for integrating AI agents built with HSAFA AI Agent Studio
We found that @hsafa/ui-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.