Skip to content

@ludus/agent-sdk

The agent creation SDK. Build AI game agents with configurable personality, LLM providers with automatic fallback, lifecycle management, and match orchestration.

Terminal window
npm install @ludus/agent-sdk

Fluent API for creating agents:

import { AgentBuilder, AnthropicProvider } from '@ludus/agent-sdk';
const agent = new AgentBuilder('Caesar')
.withId('caesar-001')
.withOwner('user-123')
.withDescription('Aggressive Roman strategist')
.withPersonality({ aggression: 0.8, risk: 0.6, cooperation: 0.3, creativity: 0.4, patience: 0.3 })
.withProvider(new AnthropicProvider({ apiKey: '...', model: 'claude-sonnet-4-6' }))
.withFallback(new RandomAgent(42))
.build();
MethodDescription
withId(id)Set agent ID
withOwner(owner)Set owner ID
withDescription(desc)Set description
withPersonality(traits)Set custom traits (auto-clamped to 0–1)
withPreset(name)Use a preset: balanced, warlord, diplomat, gambler, turtle, chaotic
withProvider(provider)Set primary LLM provider
withFallback(provider)Set fallback LLM provider
withProviders(providers[])Create a FallbackProvider cascade
build()Returns a BaseAgent

Five traits, each 0.0–1.0. Values outside range are clamped automatically.

import { normalizePersonality, validatePersonality, PERSONALITY_PRESETS } from '@ludus/agent-sdk';
const custom = normalizePersonality({ aggression: 1.5, risk: -0.1 });
// { aggression: 1.0, risk: 0.0, cooperation: 0.5, creativity: 0.5, patience: 0.5 }
const error = validatePersonality(custom); // null if valid
import { PERSONALITY_WARLORD, PERSONALITY_DIPLOMAT, PERSONALITY_GAMBLER,
PERSONALITY_TURTLE, PERSONALITY_CHAOTIC, PERSONALITY_BALANCED } from '@ludus/agent-sdk';
import { AnthropicProvider } from '@ludus/agent-sdk';
const claude = new AnthropicProvider({
apiKey: process.env.ANTHROPIC_API_KEY,
model: 'claude-sonnet-4-6',
maxTokens: 1024,
temperature: 0.7,
timeoutMs: 30000,
});

Same interface as AnthropicProvider with provider-specific config.

Cascades through providers on failure:

import { FallbackProvider } from '@ludus/agent-sdk';
const provider = new FallbackProvider(
[claude, openai, gemini],
{ onFallback: (from, to, error) => console.log(`${from} failed, trying ${to}`) },
);
// After a call:
provider.lastResult; // { resolvedBy: 'anthropic', attempts: 1, errors: [] }

Personality-weighted random action selection. No LLM needed — useful as a final fallback or for testing.

import { RandomAgent } from '@ludus/agent-sdk';
const random = new RandomAgent(42); // Deterministic with seed

Orchestrates a complete game between agents:

import { MatchRunner } from '@ludus/agent-sdk';
import { GameEventEmitter } from '@ludus/game-engine';
const runner = new MatchRunner(myGame);
const result = await runner.runMatch([agent1, agent2], {
seed: 42,
maxTurns: 100,
turnTimeoutMs: 10000,
emitter: new GameEventEmitter(), // Optional: attach event sinks
});
result.gameResult.winner; // Player | null
result.gameResult.replay; // GameReplay
result.agents; // AgentMatchInfo[] (per-agent stats)
result.lifecycleEvents; // LifecycleEvent[] (status transitions)

Case-insensitive game lookup:

import { GameRegistry } from '@ludus/agent-sdk';
const registry = new GameRegistry();
registry.register(konquistaGame);
registry.register(destreectGame);
registry.get('Konquista'); // Found (case-insensitive)
registry.list(); // GameMetadata[]
registry.has('konquista'); // true

Track agent status transitions with persistence:

import { AgentLifecycleService, InMemoryAgentStore } from '@ludus/agent-sdk';
const lifecycle = new AgentLifecycleService(new InMemoryAgentStore());
const record = await lifecycle.create({ name: 'Caesar', owner: 'user-1' }, personality, 'anthropic');
await lifecycle.transition(record.id, 'registered');
await lifecycle.transition(record.id, 'deployed');
lifecycle.onTransition((event) => {
console.log(`${event.agentId}: ${event.from}${event.to}`);
});
import { buildSystemPrompt, buildActionPrompt } from '@ludus/agent-sdk';
const systemPrompt = buildSystemPrompt('Caesar', personality);
const actionPrompt = buildActionPrompt(gameState, validActions, turnNumber);
ErrorWhen
AgentBuildErrorInvalid agent configuration
ProviderErrorLLM provider failure (includes provider name and cause)