lyzr-adk
v0.1.10
Published
Official Lyzr ADK for TypeScript/JavaScript - AI Agent Framework
Maintainers
Readme
Lyzr SDK for TypeScript/JavaScript
Official TypeScript/JavaScript SDK for the Lyzr AI Agent Platform.
Installation
npm install @lyzr/sdkQuick Start
import { Studio } from '@lyzr/sdk';
// Initialize SDK
const studio = new Studio({
apiKey: 'sk-your-api-key'
// or use LYZR_API_KEY environment variable
});
// Create an agent
const agent = await studio.createAgent({
name: 'Assistant',
provider: 'gpt-4o',
role: 'Helpful assistant',
goal: 'Answer user questions',
instructions: 'Be concise and friendly'
});
// Run the agent
const response = await agent.run('Hello! What is machine learning?');
console.log(response.response);
// Delete when done
await agent.delete();Features
- Smart Agents: Create and manage AI agents with custom instructions
- Knowledge Bases: Build RAG systems with multiple data sources
- Tools: Register local functions for agent execution — automatically called during
agent.run()(streaming or not) - Structured Outputs: Type-safe responses with Zod schemas
- Memory: Conversation context with external providers
- Streaming: Real-time agent responses
- RAI Guardrails: Safety and compliance checks
- Contexts: Global background information
- Image Models: Generate images with DALL-E, Stability AI
Supported Providers
LLM Models
- OpenAI: GPT-4o, GPT-4o-mini, O3
- Anthropic: Claude Sonnet 4.5, Claude Opus 4.5
- Google: Gemini 2.0, Gemini 2.5, Gemini 3.0
- Groq: Llama 3.1/3.3/4
- Perplexity: Sonar, Sonar Pro
- AWS Bedrock: Nova, Claude, Llama, Mistral
Vector Stores
- Qdrant
- Weaviate
- PostgreSQL (PG-Vector)
- Milvus
- Amazon Neptune
API Reference
Studio
const studio = new Studio({
apiKey: 'sk-xxx',
env: 'prod', // 'prod', 'dev', 'local'
logLevel: 'warning', // 'debug', 'info', 'warning', 'error'
timeout: 30000,
retries: 3
});
// Agent methods
await studio.createAgent(config);
await studio.getAgent(agentId);
await studio.listAgents();
await studio.updateAgent(agentId, config);
await studio.deleteAgent(agentId);
// Knowledge base methods
await studio.createKnowledgeBase(config);
await studio.getKnowledgeBase(kbId);
await studio.listKnowledgeBases();
await studio.deleteKnowledgeBase(kbId);
// Context methods
await studio.createContext(name, value);
await studio.getContext(contextId);
await studio.listContexts();
await studio.deleteContext(contextId);
// RAI methods
await studio.createRAIPolicy(config);
await studio.getRAIPolicy(policyId);
await studio.listRAIPolicies();
await studio.deleteRAIPolicy(policyId);
// Memory methods
await studio.createMemoryCredential(provider, name, credentials);
await studio.listMemoryProviders();Agent
// Core
await agent.run('message', { sessionId: 'user_1', stream: false });
await agent.update({ temperature: 0.5 });
await agent.delete();
await agent.clone('New Name');
// Tools — registered functions are called automatically during agent.run()
await agent.addTool(myFunction);
agent.removeTool('toolName');
agent.getTools();
// Memory
agent.addMemory(30);
agent.removeMemory();
agent.hasMemory();
// Context
await agent.addContext(context);
await agent.removeContext(contextId);
await agent.listContexts();
// RAI
agent.addRaiPolicy(policy);
agent.removeRaiPolicy();
agent.hasRaiPolicy();
// File & Image Output
agent.enableFileOutput();
agent.disableFileOutput();
agent.setImageModel(config);
// Features
agent.enableReflection();
agent.enableBiasCheck();
agent.enableLLMJudge();
agent.addGroundednessFacts(['fact1', 'fact2']);KnowledgeBase
// Training
await kb.addPdf('path/to/file.pdf');
await kb.addDocx('path/to/file.docx');
await kb.addTxt('path/to/file.txt');
await kb.addWebsite(['https://docs.example.com']);
await kb.addText('text content', 'source');
// Query
const results = await kb.query('question', { topK: 5 });
// Management
await kb.listDocuments();
await kb.deleteDocuments(['doc_id']);
await kb.reset();
await kb.delete();Memory
const memory = await studio.createMemoryCredential(
'mem0',
'My Memory',
{
mem0_api_key: 'key',
// ... other provider-specific fields
}
);
await memory.validate();
await memory.getStatus();
await memory.delete();Tools
Registered functions are executed automatically — agent.run() sends the tool's schema to the model, and whenever the model asks to call it, the SDK runs your function locally, sends the result back, and repeats until the model has a final answer. You never manually inspect tool calls yourself.
// Define a local tool (just a function!)
function calculateSum(a: number, b: number): number {
return a + b;
}
// Register with agent
agent.addTool(calculateSum);
// Or create a Tool explicitly
import { Tool } from '@lyzr/sdk';
const myTool = new Tool(
calculateSum,
'calculate_sum',
'Calculate the sum of two numbers'
);
agent.addTool(myTool);
// The model can call it zero, one, or several times per run — this
// actually invokes calculateSum(a, b) locally and feeds the result back:
const response = await agent.run('What is 12 plus 30?');
console.log(response.response);Notes:
- Tool parameters are inferred from the function's signature, but every parameter is typed
"string"in the schema sent to the model (JS/TS has no runtime type-hint equivalent to Python'sget_type_hints) — arguments always arrive as strings, even for logically-numeric params, so coerce defensively inside your tool (Number(a), etc.). - Tools work with streaming too (see below) —
agent.run(msg, { stream: true })drives the full tool-calling loop over SSE, reopening the stream after each tool call.
Structured Outputs with Zod
import { z } from 'zod';
const AnalysisSchema = z.object({
sentiment: z.enum(['positive', 'negative', 'neutral']),
confidence: z.number().min(0).max(1),
summary: z.string()
});
const agent = await studio.createAgent({
name: 'Analyzer',
provider: 'gpt-4o',
role: 'Sentiment analyzer',
goal: 'Analyze sentiment',
instructions: 'Provide detailed analysis',
responseModel: AnalysisSchema
});
const result = await agent.run('I love this product!');
// result is fully typed: { sentiment: 'positive', confidence: 0.95, summary: '...' }
console.log(result.sentiment); // Full IDE autocomplete!Error Handling
import {
LyzrError,
AuthenticationError,
NotFoundError,
ValidationError,
APIError
} from '@lyzr/sdk';
try {
const agent = await studio.createAgent(config);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof ValidationError) {
console.error('Invalid configuration:', error.message);
} else if (error instanceof NotFoundError) {
console.error('Resource not found');
} else if (error instanceof APIError) {
console.error('API error:', error.message);
} else {
throw error;
}
}Examples
Check the examples/ directory for comprehensive examples:
00-power-example.ts- Complete real-world example01-quickstart.ts- Basic agent operations02-structured-outputs.ts- Zod schemas03-knowledge-bases.ts- RAG functionality04-memory.ts- Conversation context05-local-tools.ts- Function tools06-complete-workflow.ts- All features07-contexts.ts- Background information08-file-output.ts- File generation09-rai-guardrails.ts- Safety features10-advanced-features.ts- Advanced patterns11-streaming.ts- Streaming responses
Development
# Install dependencies
npm install
# Build
npm run build
# Test
npm test
# Lint
npm run lint
# Format
npm run format
# Type check
npm run typecheckRequirements
- Node.js 16+
- TypeScript 5.0+ (if using TypeScript)
Best Practices
Session Management
import { v4 as uuidv4 } from 'uuid';
// Generate unique session ID per user
const sessionId = uuidv4();
// Maintain conversation context
const response1 = await agent.run('My name is Alice', { sessionId });
const response2 = await agent.run("What's my name?", { sessionId });
// Remembers "Alice"Streaming Responses
// Stream responses for real-time output
for await (const chunk of await agent.run('Tell a story', { stream: true })) {
process.stdout.write(chunk.content);
}Streaming works with local tools registered too — each tool call reopens the stream for the next round, and a zero-content marker chunk (chunk.metadata.toolCall) arrives just before each tool runs, so you can show progress instead of a silent gap:
for await (const chunk of await agent.run('What is 12 * 7? Use the multiply tool.', { stream: true })) {
if (chunk.metadata?.toolCall) {
console.log(`\n[calling tool: ${chunk.metadata.toolCall.name}]`);
} else {
process.stdout.write(chunk.content);
}
}Migration from Python
The TypeScript SDK maintains API compatibility with the Python SDK:
# Python
agent = studio.create_agent(name='Bot', provider='gpt-4o', ...)
response = agent.run('message')
agent.add_tool(my_function)// TypeScript
const agent = await studio.createAgent({ name: 'Bot', provider: 'gpt-4o', ... });
const response = await agent.run('message');
agent.addTool(myFunction);Key differences:
- Most agent/studio methods are async in TypeScript, but tool management (
addTool/removeTool/getTools) is synchronous in both SDKs — it only mutates a local, client-side registry, no network call. - Use camelCase for property names (vs snake_case in Python)
- Zod schemas instead of Pydantic models
- AsyncIterable for streaming vs Python generators
- Streaming + local tools together is supported in both SDKs (each tool call reopens the stream for the next round in both).
Support
- Documentation: docs.lyzr.ai
- GitHub: github.com/lyzr-ai/sdk
- Discord: discord.gg/lyzr
- Email: [email protected]
License
MIT License - see LICENSE
