@antipopp/agno-client
v0.13.0
Published
Core client library for Agno agents with streaming support and HITL frontend tool execution
Downloads
1,082
Maintainers
Readme
@antipopp/agno-client
Core stateful client library for Agno agents with streaming support.
Installation
npm install @antipopp/agno-clientFeatures
- ✅ Stateful Management - Manages messages, sessions, and configuration
- ✅ Event-Driven - Subscribe to real-time updates via EventEmitter
- ✅ Streaming Support - Real-time streaming of agent responses
- ✅ Session Management - Load and manage conversation sessions
- ✅ Type-Safe - Full TypeScript support with comprehensive types
- ✅ Framework Agnostic - Works with any JavaScript/TypeScript project
Quick Start
import { AgnoClient } from '@antipopp/agno-client';
// Create a client instance
const client = new AgnoClient({
endpoint: 'http://localhost:7777',
mode: 'agent',
agentId: 'your-agent-id',
authToken: 'optional-auth-token',
userId: 'user-123', // Optional: Link sessions to a user
});
// Listen to message updates
client.on('message:update', (messages) => {
console.log('New messages:', messages);
});
// Listen to errors
client.on('message:error', (error) => {
console.error('Error:', error);
});
// Send a message
await client.sendMessage('Hello, agent!');
// Get current messages
const messages = client.getMessages();
// Clear chat
client.clearMessages();API Reference
Constructor
new AgnoClient(config: AgnoClientConfig)Config Options:
endpoint(string, required) - Base endpoint URLauthToken(string, optional) - Authentication tokenmode('agent' | 'team', optional) - Operation mode (default: 'agent')agentId(string, optional) - Agent ID (required if mode is 'agent')teamId(string, optional) - Team ID (required if mode is 'team')dbId(string, optional) - Database IDsessionId(string, optional) - Current session IDuserId(string, optional) - User ID to link sessions to a specific userheaders(Record<string, string>, optional) - Global custom headers for all API requestsparams(Record<string, string>, optional) - Global query parameters for all API requestsdependencies(Record<string, unknown>, optional) - Global run dependencies merged into allsendMessagerequests
Methods
sendMessage(message, options?)
Send a message to the agent/team.
await client.sendMessage('Hello!');
// With FormData (for file uploads)
const formData = new FormData();
formData.append('message', 'Hello!');
formData.append('files', fileBlob);
await client.sendMessage(formData);
// With per-request files option
await client.sendMessage('Hello!', {
files: [fileBlob]
});
// With global dependencies from config
const dependencyClient = new AgnoClient({
endpoint: 'http://localhost:7777',
agentId: 'agent-123',
dependencies: {
tenantId: 'tenant-1',
locale: 'en-US'
}
});
await dependencyClient.sendMessage('Hello!');
// Override/extend dependencies per request
await dependencyClient.sendMessage('Hello!', {
dependencies: {
locale: 'fr-FR', // overrides global
feature: 'rag' // merged new key
}
});
// With custom headers
await client.sendMessage('Hello!', {
headers: { 'X-Custom-Header': 'value' }
});
// With query parameters
await client.sendMessage('Hello!', {
params: { temperature: '0.7', max_tokens: '500' }
});
// With both headers and params
await client.sendMessage('Hello!', {
headers: { 'X-Request-ID': '12345' },
params: { debug: 'true' }
});getMessages()
Get current messages.
const messages: ChatMessage[] = client.getMessages();clearMessages()
Clear all messages and reset session.
client.clearMessages();loadSession(sessionId)
Load a specific session.
const messages = await client.loadSession('session-id');fetchSessions()
Fetch all sessions for current agent/team.
const { data, meta } = await client.fetchSessions();initialize()
Initialize client (check status and fetch agents/teams).
const { agents, teams } = await client.initialize();updateConfig(updates)
Update client configuration.
client.updateConfig({
agentId: 'new-agent-id',
authToken: 'new-token',
userId: 'user-456', // Update user ID
});Events
Subscribe to events using client.on(event, handler):
message:update- Emitted when messages are updated during streamingmessage:complete- Emitted when a message stream completesmessage:error- Emitted when an error occurssession:loaded- Emitted when a session is loadedsession:created- Emitted when a new session is createdstream:start- Emitted when streaming startsstream:end- Emitted when streaming endsstate:change- Emitted when client state changesconfig:change- Emitted when configuration changes
// Subscribe to events
client.on('message:update', (messages) => {
console.log('Messages:', messages);
});
// Unsubscribe from events
const handler = (messages) => console.log(messages);
client.on('message:update', handler);
client.off('message:update', handler);Utilities
Logger
The package includes a secure Logger utility for production-safe debugging:
import { Logger } from '@antipopp/agno-client';
// Debug and info messages only log in development mode
Logger.debug('Debug message', { someData: 'value' });
Logger.info('Client initialized', { endpoint: 'http://localhost:7777' });
// Warnings and errors always log
Logger.warn('Connection issue detected');
Logger.error('Failed to send message', error);
// Sensitive data is automatically sanitized
Logger.debug('Config loaded', {
endpoint: 'http://localhost:7777',
authToken: 'secret-token' // Will be logged as [REDACTED]
});Features:
- Automatic sanitization - Sensitive fields (authToken, Authorization, token, password, apiKey) are automatically redacted
- Environment-aware - Debug/info logs only appear in development mode (NODE_ENV === 'development')
- Always-on errors - Warnings and errors always log, even in production
- Production-safe - Prevents accidental exposure of secrets in production logs
Sanitized Fields:
authToken,Authorization,token,password,apiKeyand any field containing these words (case-insensitive)
Advanced Usage
Session Management
// Fetch all sessions
const { data: sessions, meta } = await client.fetchSessions();
console.log(`Loaded ${meta.total_count} sessions across ${meta.total_pages} pages`);
// Load a specific session
const messages = await client.loadSession(sessions[0].session_id);
// Current session ID
const sessionId = client.getConfig().sessionId;State Management
// Get current state
const state = client.getState();
console.log(state.isStreaming);
console.log(state.isEndpointActive);
console.log(state.agents);
console.log(state.teams);Error Handling
client.on('message:error', (error) => {
console.error('Streaming error:', error);
});
try {
await client.sendMessage('Hello!');
} catch (error) {
console.error('Failed to send:', error);
}Custom Headers and Query Parameters
The client supports both global and per-request headers and query parameters.
Global Configuration
Set headers and params in the client config to apply them to all API requests:
const client = new AgnoClient({
endpoint: 'http://localhost:7777',
agentId: 'agent-123',
headers: {
'X-API-Version': 'v2',
'X-Client-ID': 'my-app'
},
params: {
locale: 'en-US',
environment: 'production'
}
});Per-Request Options
Override or add headers/params for specific requests:
// Per-request overrides global settings
await client.sendMessage('Hello!', {
headers: { 'X-Request-ID': '12345' },
params: { temperature: '0.7' }
});
// All methods support headers and params
await client.loadSession('session-123', {
params: { include_metadata: 'true' }
});
await client.fetchSessions({
params: { limit: '50', status: 'active' }
});
await client.continueRun(tools, {
headers: { 'X-Trace-ID': 'abc123' },
params: { debug: 'true' }
});Merge Behavior
Headers:
- Global headers from
config.headers(lowest precedence) - Per-request headers (overrides global)
- Authorization header from
authToken(highest precedence - always overrides)
Query Parameters:
- Global params from
config.params(lowest precedence) - Per-request params (highest precedence - overrides global)
Dependencies (sendMessage only):
- Global dependencies from
config.dependencies(lowest precedence) - Per-request dependencies from
sendMessage(..., { dependencies })(highest precedence - overrides global)
const client = new AgnoClient({
endpoint: 'http://localhost:7777',
agentId: 'agent-123',
params: { version: 'v1', locale: 'en-US' }
});
// This request will have: version=v2 (overridden), locale=en-US (from global), debug=true (added)
await client.sendMessage('Hello!', {
params: { version: 'v2', debug: 'true' }
});Common Use Cases
Headers:
- Request tracking:
{ 'X-Request-ID': uuid() } - API versioning:
{ 'X-API-Version': 'v2' } - Client identification:
{ 'X-Client-ID': 'mobile-app' } - Custom auth:
{ 'X-Custom-Auth': 'token' }
Query Parameters:
- Model configuration:
{ temperature: '0.7', max_tokens: '500' } - Feature flags:
{ enable_streaming: 'true' } - Locale/language:
{ locale: 'en-US', timezone: 'America/New_York' } - Debugging:
{ debug: 'true', trace_id: 'xyz' } - Pagination:
{ page: '1', limit: '50' }
Request Cancellation
Use AbortController to cancel ongoing requests. This is essential for preventing memory leaks when components unmount or users navigate away during streaming:
const controller = new AbortController();
// Pass signal to sendMessage options
await client.sendMessage('Hello!', {
signal: controller.signal
});
// Cancel the request (e.g., on component unmount)
controller.abort();React Example:
import { useEffect } from 'react';
import { AgnoClient } from '@antipopp/agno-client';
function ChatComponent() {
const client = new AgnoClient(config);
useEffect(() => {
const controller = new AbortController();
// Send message with abort signal
client.sendMessage('Hello!', {
signal: controller.signal
});
// Cleanup: cancel request on unmount
return () => {
controller.abort();
};
}, []);
return <div>Chat</div>;
}Use Cases:
- Component unmounting - Cancel requests when user navigates away
- Request timeouts - Implement custom timeout logic
- User cancellation - Allow users to cancel long-running requests
- Preventing memory leaks - Ensure streaming stops when components are destroyed
Note: Aborted requests will not trigger the onError callback - they complete silently.
License
MIT
