TypeScript SDK Overview
Build intelligent AI agents with the Agentfield TypeScript SDK
The Agentfield TypeScript SDK enables you to build intelligent AI agents with full type safety, automatic workflow tracking, and seamless integration with the Agentfield control plane. Built on Express, it provides a chainable API for defining reasoners (AI-powered functions) and skills (deterministic utilities).
Quick Start
Follow these steps to create your first agent from scratch.
1. Create Project Directory
mkdir my-agent && cd my-agent
npm init -y2. Install Dependencies
npm install @agentfield/sdk dotenv zod
npm install -D typescript tsx @types/node3. Project Structure
Your project should look like this:
4. Configure package.json
Update your package.json with the proper module type and scripts:
{
"name": "my-agent",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "tsx watch src/agent.ts",
"start": "tsx src/agent.ts",
"build": "tsc",
"serve": "node dist/agent.js"
},
"dependencies": {
"@agentfield/sdk": "^0.1.20",
"dotenv": "^16.4.5",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/node": "^20.10.0",
"tsx": "^4.19.2",
"typescript": "^5.3.0"
}
}5. Configure TypeScript
Create tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"]
}6. Set Up Environment Variables
Create a .env file:
# AI Provider (choose one)
OPENAI_API_KEY=sk-your-openai-key
# Or use OpenRouter for multi-provider access
# OPENROUTER_API_KEY=sk-or-v1-your-key
# Agentfield Control Plane
AGENTFIELD_URL=http://localhost:8080
# Agent Configuration
PORT=80017. Create Your Agent
Create src/agent.ts:
import 'dotenv/config';
import { Agent } from '@agentfield/sdk';
const agent = new Agent({
nodeId: 'my-agent',
agentFieldUrl: process.env.AGENTFIELD_URL || 'http://localhost:8080',
port: Number(process.env.PORT) || 8001,
version: '1.0.0',
devMode: true,
aiConfig: {
provider: 'openai',
model: 'gpt-4o',
apiKey: process.env.OPENAI_API_KEY,
}
});
// Define an AI-powered reasoner
agent.reasoner('analyze_ticket', async (ctx) => {
const analysis = await ctx.ai(
`Analyze this support ticket: ${JSON.stringify(ctx.input)}`,
{ system: 'You are a support ticket analyzer.' }
);
return { analysis };
});
// Define a deterministic skill
agent.skill('format_response', async (ctx) => {
const { category, priority } = ctx.input;
return `Category: ${category}\nPriority: ${priority}`;
});
// Start the agent server
await agent.serve();
console.log(`Agent running at http://localhost:${agent.config.port}`);8. Run Your Agent
Start the agent in development mode with hot-reload:
npm run devYou should see output like:
Agent running at http://localhost:80019. Test Your Agent
With the Agentfield control plane running, test your agent:
# Test the reasoner via control plane
curl -X POST http://localhost:8080/api/v1/execute/my-agent.analyze_ticket \
-H "Content-Type: application/json" \
-d '{"input": {"subject": "Cannot login", "body": "I forgot my password"}}'
# Or call the agent directly
curl -X POST http://localhost:8001/reasoners/analyze_ticket \
-H "Content-Type: application/json" \
-d '{"input": {"subject": "Cannot login", "body": "I forgot my password"}}'The devMode: true setting allows the agent to run without a control plane connection, useful for local testing.
Core Concepts
Agent
The Agent class is the foundation of your AI agent. It provides:
- Chainable API for registering reasoners and skills
- Automatic REST API generation via Express
- Agentfield server integration with heartbeat
- Workflow tracking and DAG building
- Memory management across scopes
- Cross-agent communication
import { Agent } from '@agentfield/sdk';
const agent = new Agent({
nodeId: 'my-agent',
agentFieldUrl: 'http://localhost:8080',
aiConfig: {
model: 'gpt-4o',
temperature: 0.7
}
});Reasoners
Reasoners are AI-powered functions registered with agent.reasoner(). They receive a ReasonerContext with access to AI, memory, and workflow services:
import { z } from 'zod';
const SentimentSchema = z.object({
sentiment: z.enum(['positive', 'negative', 'neutral']),
confidence: z.number(),
reasoning: z.string()
});
agent.reasoner('analyze_sentiment', async (ctx) => {
const result = await ctx.ai(
`Analyze sentiment: ${ctx.input.text}`,
{ schema: SentimentSchema }
);
return result;
}, { description: 'Analyze text sentiment' });Key Features:
- Automatic workflow tracking
- Structured output with Zod schemas
- REST API endpoints at
/reasoners/:name - Full execution context propagation
Skills
Skills are deterministic functions registered with agent.skill(). They receive a SkillContext for memory and workflow access:
agent.skill('get_user_profile', async (ctx) => {
const { userId } = ctx.input;
const user = await database.findUser(userId);
return {
id: user.id,
name: user.name,
email: user.email
};
}, { tags: ['database', 'user'] });Key Features:
- Type-safe function signatures
- Automatic API generation at
/skills/:name - Tagging for organization
- No AI overhead
Cross-Agent Communication
Use agent.call() or ctx.call() to invoke reasoners and skills on other agents:
agent.reasoner('comprehensive_analysis', async (ctx) => {
// Call sentiment analyzer on different agent
const sentiment = await ctx.call(
'sentiment-agent.analyze_sentiment',
{ text: ctx.input.ticketText }
);
// Call priority classifier
const priority = await ctx.call(
'priority-agent.classify_priority',
{ ticketText: ctx.input.ticketText }
);
return { sentiment, priority };
});All cross-agent calls automatically build workflow DAGs showing the complete execution flow.
Memory System
Access persistent storage with automatic scoping via ctx.memory:
agent.reasoner('personalized_response', async (ctx) => {
const { userId, message } = ctx.input;
// Get user preferences from session memory
const sessionMem = ctx.memory.session(userId);
const preferences = await sessionMem.get('preferences') || {};
// Generate personalized response
const response = await ctx.ai(
`User preferences: ${JSON.stringify(preferences)}\nMessage: ${message}`
);
// Update conversation history
const history = await sessionMem.get('history') || [];
history.push({ message, response });
await sessionMem.set('history', history);
return response;
});Development Workflow
const agent = new Agent({
nodeId: 'dev-agent',
agentFieldUrl: 'http://localhost:8080',
devMode: true
});
agent.reasoner('test', async (ctx) => {
return await ctx.ai(ctx.input.prompt);
});
await agent.serve();
// Server starts on port 8001 by defaultconst agent = new Agent({
nodeId: 'prod-agent',
agentFieldUrl: 'https://agentfield.company.com',
port: 8080,
aiConfig: {
model: 'gpt-4o',
maxTokens: 2000,
enableRateLimitRetry: true,
rateLimitMaxRetries: 20
}
});
await agent.serve();// AWS Lambda / Cloud Functions / Vercel
const agent = new Agent({
nodeId: 'serverless-agent',
deploymentType: 'serverless'
});
agent.reasoner('process', async (ctx) => {
return await ctx.ai(`Process: ${JSON.stringify(ctx.input)}`);
});
// Export handler with an adapter to normalize platform event shapes
export const handler = agent.handler((event) => {
const body = typeof event?.body === 'string' ? JSON.parse(event.body || '{}') : event?.body;
return {
path: event?.rawPath || event?.path || '/execute',
headers: event?.headers ?? {},
target: event?.target ?? event?.reasoner,
input: body?.input ?? body ?? {},
executionContext: event?.executionContext ?? event?.execution_context,
};
});Environment Variables
The SDK reads configuration from environment variables:
# AI Provider
OPENAI_API_KEY="sk-..."
AI_MODEL="gpt-4o"
# Or use OpenRouter for multi-provider access
OPENROUTER_API_KEY="sk-or-v1-..."
AI_MODEL="anthropic/claude-3-5-sonnet"
# Control Plane
AGENTFIELD_URL="http://localhost:8080"SDK Components
| Module | Purpose | Key Types |
|---|---|---|
Agent | Agent lifecycle, reasoner/skill registration | Agent, AgentConfig |
AIClient | LLM integration with rate limiting | AIClient, AIRequestOptions |
MemoryInterface | Distributed memory with scoping | MemoryInterface, MemoryScope |
AgentRouter | Organize reasoners/skills with prefixes | AgentRouter |
DidInterface | Cryptographic identity and audit trails | DidInterface, ExecutionCredential |
Comparison with Python/Go SDKs
| Feature | TypeScript SDK | Python SDK | Go SDK |
|---|---|---|---|
| AI Calls | ctx.ai(prompt) | await app.ai(user=prompt) | agent.AI(ctx, prompt) |
| Structured Output | { schema: ZodSchema } | schema=Model | ai.WithSchema(Model{}) |
| Registration | agent.reasoner(name, fn) | @app.reasoner decorator | agent.RegisterReasoner() |
| Cross-Agent Calls | ctx.call(target, input) | await app.call() | agent.Call(ctx, ...) |
| Streaming | ctx.aiStream(prompt) | stream=True | agent.AIStream() |
| Memory | ctx.memory.get/set() | await app.memory.get/set() | agent.Memory.Get/Set() |
Next Steps
Core Concepts
- Agent Class - Initialize and configure agents
- ReasonerContext - Context for AI functions
- SkillContext - Context for utility functions
AI Integration
- ctx.ai() - LLM interface with streaming
- ctx.call() - Cross-agent communication
- ctx.memory - Persistent storage
Advanced Features
- AgentRouter - Organize reasoners/skills
- DID/Credentials - Cryptographic audit trails
- Configuration - All config options
Deployment
- Serverless - Lambda/Cloud Functions
- Async Execution - Long-running tasks
- Webhooks - Event notifications