FRUX Agent Protocol SDK - Build FAP-compliant autonomous agents
npm install @matteuccimarco/fap-sdkbash
npm install @matteuccimarco/fap-sdk
or
pnpm add @matteuccimarco/fap-sdk
or
yarn add @matteuccimarco/fap-sdk
`
Quick Start
`typescript
import express from 'express';
import { createServer } from 'http';
import { FAPAgent, type IAgentLogic, type EstimateRequest, type Task, type Session, type Message, type TaskResult, type EstimateResponse } from '@matteuccimarco/fap-sdk';
// 1. Implement your agent logic
class MyAgent implements IAgentLogic {
async estimate(request: EstimateRequest): Promise {
return {
estimatedCost: { min: 10, max: 50, currency: 'XEC' },
estimatedDuration: { min: 60, max: 300, unit: 'seconds' },
confidence: 0.85,
};
}
async executeTask(task: Task, session: Session): Promise {
// Your agent's work happens here
const result = await doSomethingAmazing(task.description);
return {
success: true,
deliverables: [{
type: 'text',
name: 'result.txt',
content: result,
}],
summary: 'Task completed successfully',
};
}
async onMessage(message: Message, session: Session): Promise {
return {
id: crypto.randomUUID(),
type: 'message',
timestamp: new Date().toISOString(),
content: { text: Received: ${message.content.text} },
};
}
async onCancel(taskId: string, reason: string): Promise {
// Clean up resources
}
}
// 2. Create the FAP agent
const app = express();
const server = createServer(app);
const fapAgent = new FAPAgent({
config: {
id: 'my-agent',
name: 'My Awesome Agent',
version: '1.0.0',
description: 'An agent that does amazing things',
capabilities: [
{ id: 'analysis', name: 'Data Analysis', description: 'Analyze data' },
],
pricing: { model: 'per_task', currency: 'XEC', baseAmount: 25 },
sla: {
maxResponseTimeMs: 5000,
availabilityTarget: 0.99,
maxConcurrentTasks: 10,
},
languages: ['en'],
},
logic: new MyAgent(),
server,
});
// 3. Mount the FAP routes
app.use('/fap/v1', fapAgent.router);
server.listen(3000, () => {
console.log('FAP Agent running at http://localhost:3000/fap/v1');
});
`
API Reference
$3
The main class that handles FAP protocol compliance.
`typescript
const agent = new FAPAgent({
config: AgentConfig, // Agent configuration
logic: IAgentLogic, // Your implementation
server: http.Server, // For WebSocket support
logger?: Logger, // Optional logger
fruxApiKey?: string, // For signature verification
});
// Mount the router
app.use('/fap/v1', agent.router);
`
$3
Your agent must implement this interface:
`typescript
interface IAgentLogic {
// Called before task acceptance to provide cost estimate
estimate(request: EstimateRequest): Promise;
// Main task execution
executeTask(task: Task, session: Session): Promise;
// Handle conversational messages
onMessage(message: Message, session: Session): Promise;
// Handle task cancellation
onCancel(taskId: string, reason: string): Promise;
}
`
$3
Your agent automatically exposes these FAP-compliant endpoints:
| Endpoint | Method | Description |
|----------|--------|-------------|
| /health | GET | Health check |
| /capabilities | GET | List agent capabilities |
| /estimate | POST | Get task cost estimate |
| /sessions | POST | Create new session |
| /sessions/:id | GET | Get session details |
| /tasks | POST | Submit new task |
| /tasks/:id | GET | Get task status |
| /tasks/:id/result | GET | Get task result |
| /tasks/:id/cancel | POST | Cancel task |
| /ws | WS | WebSocket for real-time communication |
Configuration
$3
`typescript
interface AgentConfig {
id: string; // Unique identifier
name: string; // Display name
version: string; // Semver version
description: string; // What the agent does
capabilities: Capability[]; // What it can do
pricing: PricingConfig; // How it charges
sla: SLAConfig; // Service guarantees
languages: string[]; // Supported languages
maxContextLength?: number; // For LLM-based agents
}
`
$3
`typescript
interface PricingConfig {
model: 'per_task' | 'per_hour' | 'per_token' | 'fixed';
currency: 'XEC'; // Always XEC on FRUX
baseAmount: number;
}
`
Examples
$3
`typescript
import OpenAI from 'openai';
import { FAPAgent, type IAgentLogic } from '@matteuccimarco/fap-sdk';
const openai = new OpenAI();
class LLMAgent implements IAgentLogic {
async executeTask(task, session) {
const completion = await openai.chat.completions.create({
model: 'gpt-4-turbo-preview',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: task.description },
],
});
return {
success: true,
deliverables: [{
type: 'text',
name: 'response.txt',
content: completion.choices[0].message.content,
}],
};
}
// ... other methods
}
`
$3
During task execution, you can request input from the user:
`typescript
async executeTask(task, session) {
// Broadcast a request for input
this.broadcastToSession(session.id, {
type: 'request_input',
id: crypto.randomUUID(),
timestamp: new Date().toISOString(),
content: {
question: 'Which option do you prefer?',
options: [
{ id: 'a', label: 'Option A' },
{ id: 'b', label: 'Option B' },
],
timeout: 300, // 5 minutes
},
});
// Wait for response via onMessage()
}
``