@rodrigocoliveira/agno-client
v2.2.0
Published
Core client library for Agno agents with streaming support and HITL frontend tool execution
Maintainers
Readme
@rodrigocoliveira/agno-client
Core stateful client library for Agno agents with streaming support.
Installation
npm install @rodrigocoliveira/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 '@rodrigocoliveira/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 requests
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('file', fileBlob);
await client.sendMessage(formData);
// 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 sessions = 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 '@rodrigocoliveira/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 sessions = await client.fetchSessions();
// 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)
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 the cancelRun() method to cancel ongoing streaming requests. This provides a complete cancellation flow that:
- Aborts the local fetch stream - Immediate UI feedback
- Notifies the backend - Stops LLM processing and saves compute costs
// Start a streaming request
await client.sendMessage('Hello!');
// Cancel the request
await client.cancelRun();State Tracking:
// Check cancellation state
const state = client.getState();
console.log(state.isStreaming); // true while streaming
console.log(state.isCancelling); // true during cancellation
console.log(state.currentRunId); // current run ID (if streaming)React Example:
import { useAgnoChat } from '@rodrigocoliveira/agno-react';
function ChatComponent() {
const { sendMessage, cancelRun, isStreaming, isCancelling } = useAgnoChat();
const handleSend = async () => {
await sendMessage('Hello!');
};
const handleCancel = async () => {
await cancelRun();
};
return (
<div>
<button onClick={handleSend} disabled={isStreaming}>Send</button>
<button onClick={handleCancel} disabled={!isStreaming || isCancelling}>
{isCancelling ? 'Cancelling...' : 'Cancel'}
</button>
</div>
);
}Use Cases:
- User cancellation - Allow users to stop long-running requests via a "Stop" button
- Component unmounting - Cancel requests when user navigates away
- Timeout handling - Cancel requests that exceed a time limit
Events:
run:cancelled- Emitted when cancellation completes (includesrunIdandsessionId)- Cancelled messages have
cancelled: trueflag (distinct from errors)
Publishing
To publish this package to npm:
# Login to npm (first time only)
npm login
# Build the package
bun run build
# Publish (use --access public for scoped packages)
npm publish --access publicPublish order: This package depends on @rodrigocoliveira/agno-types, so publish types first:
@rodrigocoliveira/agno-types@rodrigocoliveira/agno-client(this package)@rodrigocoliveira/agno-react
License
MIT
