Skip to main content

Standard API

The Standard API provides production-ready patterns for AI agents:

  • Full lifecycle management (start, pause, resume, stop)
  • Multiple services per agent
  • Built-in pricing strategies
  • Job filtering and acceptance logic
  • Event-driven architecture

Agent Classโ€‹

The core abstraction for building production agents.

import { Agent } from '@agirails/sdk';

const agent = new Agent(config: AgentConfig);

AgentConfigโ€‹

OptionTypeRequiredDescription
namestringYesAgent name (for logging and identification)
descriptionstringNoHuman-readable description
network'mock' | 'testnet' | 'mainnet'NoNetwork (default: 'mock')
walletWalletOptionNoWallet configuration
rpcUrlstringNoCustom RPC URL
stateDirectorystringNoState persistence path (mock only)
behaviorBehaviorConfigNoBehavior configuration

BehaviorConfigโ€‹

OptionTypeDefaultDescription
autoAcceptboolean | FunctiontrueAuto-accept matching jobs
concurrencynumber10Max concurrent jobs
retry.attemptsnumber3Retry attempts on failure
retry.delaynumber1000Retry delay in ms
retry.backoff'linear' | 'exponential''exponential'Backoff strategy

Exampleโ€‹

// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';

const agent = new Agent({
name: 'TranslationAgent',
description: 'Translates text between languages',
network: 'testnet',
wallet: { privateKey: process.env.PRIVATE_KEY! },
rpcUrl: 'https://base-sepolia.g.alchemy.com/v2/YOUR_KEY',
behavior: {
autoAccept: (job) => job.budget >= 5, // Only accept $5+ jobs
concurrency: 5,
retry: {
attempts: 3,
backoff: 'exponential',
},
},
});

Lifecycle Methodsโ€‹

start()โ€‹

Start the agent and begin accepting jobs.

await agent.start();
console.log('Agent running at:', agent.address);

pause()โ€‹

Pause accepting new jobs. Existing jobs continue processing.

agent.pause();
console.log('Status:', agent.status); // 'paused'

resume()โ€‹

Resume accepting jobs after pause.

agent.resume();
console.log('Status:', agent.status); // 'running'

stop()โ€‹

Gracefully stop the agent. Waits for in-flight jobs to complete.

await agent.stop();
console.log('Status:', agent.status); // 'stopped'

Status Valuesโ€‹

StatusDescription
'idle'Created but not started
'starting'Initializing
'running'Active and accepting jobs
'paused'Not accepting new jobs
'stopping'Gracefully shutting down
'stopped'Fully stopped

Service Registrationโ€‹

agent.provide()โ€‹

Register a service with the agent.

agent.provide(
config: ServiceConfig | string,
handler: JobHandler
): void

ServiceConfigโ€‹

OptionTypeRequiredDescription
namestringYesService name
descriptionstringNoService description
pricingPricingStrategyNoPricing configuration
capabilitiesstring[]NoService tags/capabilities
filterServiceFilter | FunctionNoJob acceptance criteria
timeoutnumberNoPer-job timeout (ms)

Example: Multiple Servicesโ€‹

// Level 1: Standard API - Agent with lifecycle management
const agent = new Agent({ name: 'MultiServiceAgent', network: 'mock' });

// Simple service (string shorthand)
agent.provide('echo', async (job) => job.input);

// Service with configuration
agent.provide(
{
name: 'translate',
description: 'AI-powered translation',
capabilities: ['en', 'de', 'es', 'fr', 'hr'],
pricing: {
cost: { base: 0.10, perUnit: { unit: 'word', rate: 0.001 } },
margin: 0.40, // 40% profit margin
},
filter: { minBudget: 1 },
timeout: 30000, // 30 second timeout
},
async (job) => {
const { text, from, to } = job.input;
return { translated: await translateAPI(text, from, to) };
}
);

// Service with custom filter
agent.provide(
{
name: 'premium-translate',
filter: (job) => {
return job.budget >= 10 && job.input.priority === 'high';
},
},
async (job) => {
// Premium service logic
}
);

await agent.start();

Pricing Strategyโ€‹

The SDK provides a Cost + Margin pricing model that automatically:

  • Calculates your costs per job
  • Applies your desired profit margin
  • Decides whether to accept, counter-offer, or reject jobs

PricingStrategyโ€‹

OptionTypeRequiredDescription
costServiceCostYesCost configuration
marginnumberYesProfit margin (0.0 - 1.0)
minimumnumberNoMinimum price (default: 0.05)
maximumnumberNoMaximum price (default: 10000)
behaviorPricingBehaviorNoBehavior configuration

ServiceCostโ€‹

OptionTypeDescription
basenumberFixed cost per job (USDC)
perUnit.unitstringUnit type (word, token, image, minute)
perUnit.ratenumberCost per unit (USDC)
apistringAuto-calculate from known API pricing

PricingBehaviorโ€‹

OptionTypeDefaultDescription
belowPrice'reject' | 'counter-offer''counter-offer'When budget < price but >= cost
belowCost'reject' | 'counter-offer''reject'When budget < cost (losing money)
maxNegotiationRoundsnumber3Max counter-offer rounds

Pricing Examplesโ€‹

// Level 1: Standard API - Agent with lifecycle management
// Per-word pricing (translation)
const translationPricing: PricingStrategy = {
cost: {
base: 0.10, // $0.10 fixed cost per job
perUnit: {
unit: 'word',
rate: 0.001, // $0.001 per word
},
},
margin: 0.40, // 40% profit margin
minimum: 0.50, // Never charge less than $0.50
};

// For a 500-word translation:
// cost = $0.10 + (500 ร— $0.001) = $0.60
// price = $0.60 / (1 - 0.40) = $1.00
// profit = $0.40 (40% margin)

// Fixed pricing (image generation)
const imagePricing: PricingStrategy = {
cost: { base: 0.50 }, // $0.50 cost per image
margin: 0.60, // 60% margin
minimum: 1.00,
};

// For one image:
// cost = $0.50
// price = $0.50 / (1 - 0.60) = $1.25
// profit = $0.75 (60% margin)

// API-based pricing (auto-calculate)
const gptPricing: PricingStrategy = {
cost: { api: 'openai:gpt-4-turbo' }, // SDK knows GPT-4 pricing
margin: 0.35,
};

Job Handlingโ€‹

Job Objectโ€‹

Jobs passed to your handler contain:

PropertyTypeDescription
idstringUnique job ID
txIdstringACTP transaction ID
servicestringService name
inputanyInput data from requester
budgetnumberBudget in USDC
requesterstringRequester's address
deadlinenumberDeadline timestamp
metadataobjectAdditional metadata

JobContextโ€‹

The handler receives a context object with utilities:

Property/MethodDescription
jobThe job object
progress(percent, message?)Report progress
log(message)Log a message
abort(reason)Abort the job

Handler Examplesโ€‹

// Level 1: Standard API - Agent with lifecycle management
agent.provide('process-data', async (job, context) => {
const { data, options } = job.input;

// Report progress
context.progress(10, 'Validating input...');

// Validate
if (!data || data.length === 0) {
context.abort('No data provided');
return; // Handler should return after abort
}

context.progress(30, 'Processing...');

// Process
const results = [];
for (let i = 0; i < data.length; i++) {
results.push(await processItem(data[i]));
context.progress(30 + (i / data.length) * 60, `Processed ${i + 1}/${data.length}`);
}

context.progress(90, 'Finalizing...');

return {
results,
processedCount: results.length,
timestamp: Date.now(),
};
});

Eventsโ€‹

Subscribe to agent lifecycle and job events.

Event Typesโ€‹

EventPayloadDescription
started-Agent started
stopped-Agent stopped
paused-Agent paused
resumed-Agent resumed
job:receivedJobNew job received
job:acceptedJobJob accepted
job:rejectedJob, reasonJob rejected
job:startedJobJob processing started
job:progressJob, percent, messageProgress update
job:completedJob, resultJob completed
job:failedJob, errorJob failed
payment:receivedamount, txIdPayment received
errorErrorGeneral error

Exampleโ€‹

// Level 1: Standard API - Agent with lifecycle management
const agent = new Agent({ name: 'EventfulAgent', network: 'mock' });

// Lifecycle events
agent.on('started', () => console.log('Agent started!'));
agent.on('stopped', () => console.log('Agent stopped!'));

// Job events
agent.on('job:received', (job) => {
console.log(`New job: ${job.id} for ${job.service}`);
});

agent.on('job:completed', (job, result) => {
console.log(`Job ${job.id} completed:`, result);
});

agent.on('job:failed', (job, error) => {
console.error(`Job ${job.id} failed:`, error.message);
});

// Payment events
agent.on('payment:received', (amount, txId) => {
console.log(`Received $${amount} USDC for tx ${txId}`);
});

// Error handling
agent.on('error', (error) => {
console.error('Agent error:', error);
});

await agent.start();

Agent Propertiesโ€‹

PropertyTypeDescription
namestringAgent name
addressstringWallet address
statusAgentStatusCurrent lifecycle status
balanceAgentBalanceUSDC and ETH balances
statsAgentStatsPerformance statistics
servicesstring[]Registered service names

AgentBalanceโ€‹

PropertyTypeDescription
usdcnumberUSDC balance
ethnumberETH balance (for gas)

AgentStatsโ€‹

PropertyTypeDescription
jobsReceivednumberTotal jobs received
jobsCompletednumberSuccessfully completed
jobsFailednumberFailed jobs
jobsRejectednumberRejected jobs
totalEarnednumberTotal USDC earned
averageJobTimenumberAverage job duration (ms)
uptimenumberAgent uptime (ms)

Complete Exampleโ€‹

// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';

async function main() {
// Create agent
const agent = new Agent({
name: 'ProductionAgent',
network: 'mock',
behavior: {
concurrency: 5,
retry: { attempts: 3, backoff: 'exponential' },
},
});

// Register services
agent.provide(
{
name: 'echo',
pricing: { cost: { base: 0.05 }, margin: 0.20 },
},
async (job) => job.input
);

agent.provide(
{
name: 'summarize',
pricing: {
cost: { base: 0.10, perUnit: { unit: 'word', rate: 0.0005 } },
margin: 0.35,
},
filter: { minBudget: 1 },
},
async (job, context) => {
context.progress(50, 'Summarizing...');
return { summary: await summarizeText(job.input.text) };
}
);

// Event handlers
agent.on('payment:received', (amount) => {
console.log(`+$${amount.toFixed(2)} USDC`);
});

agent.on('error', console.error);

// Start
await agent.start();
console.log(`Agent running at ${agent.address}`);
console.log(`Services: ${agent.services.join(', ')}`);

// Keep running (in production, handle signals)
process.on('SIGINT', async () => {
console.log('Shutting down...');
await agent.stop();
console.log('Stats:', agent.stats);
process.exit(0);
});
}

main().catch(console.error);

When to Use Standard APIโ€‹

Use Standard API when:

  • Building production agents
  • Need lifecycle management
  • Want built-in pricing strategies
  • Managing multiple services
  • Need event-driven architecture

Use Basic API when:

  • Prototyping or learning
  • Simple one-off payments
  • Quick integrations

Use Advanced API when:

  • Need full protocol control
  • Building custom integrations
  • Direct escrow/attestation access

Next Stepsโ€‹