@moltium/core
v0.1.34
Published
Agent runtime, adapters, and types for the Moltium autonomous agent SDK
Maintainers
Readme
@moltium/core
Agent runtime, adapters, and types for the Moltium autonomous agent SDK.
Installation
npm install @moltium/coreOverview
@moltium/core is the runtime library that powers Moltium agents. It provides:
- Agent class with full lifecycle management (init, start, tick, stop)
- LLM providers for Anthropic (Claude) and OpenAI (GPT)
- Memory system with short-term (in-memory) and long-term (Redis + Postgres) storage
- Social adapters for Moltbook and Twitter
- Action system with built-in actions, custom actions, and markdown-interpreted skills
- HTTP server (Express) with REST endpoints for monitoring and control
- A2A Protocol support for agent-to-agent communication (JSON-RPC, HTTP+JSON/REST)
- Config loader supporting both TypeScript and Markdown configurations
Quick Start
import 'dotenv/config';
import { Agent, startServer } from '@moltium/core';
import type { AgentConfig } from '@moltium/core';
const config: AgentConfig = {
name: 'my-agent',
type: 'assistant',
personality: {
traits: ['helpful', 'curious'],
bio: 'A helpful autonomous agent.',
},
llm: {
provider: 'anthropic',
model: 'claude-sonnet-4-20250514',
apiKey: process.env.ANTHROPIC_API_KEY!,
temperature: 0.7,
},
social: {},
behaviors: {
autonomous: true,
decisionMaking: 'llm-driven',
actionsPerHour: 5,
},
memory: { type: 'memory' },
actions: ['post_social_update', 'respond_to_mention'],
};
const agent = new Agent(config);
startServer(agent, { port: 3000 });The agent automatically exposes A2A Protocol endpoints for agent-to-agent communication:
/.well-known/agent-card.json- Agent discovery/a2a/jsonrpc- JSON-RPC transport/a2a/rest- HTTP+JSON/REST transport (v0.3.0)
To enable A2A communication actions, add an a2a configuration section (see A2A Protocol Integration below).
Agent Lifecycle
Agents follow a strict lifecycle: idle -> initializing -> running -> stopping -> stopped.
const agent = new Agent(config, {
onInit: async (agent) => {
console.log(`${agent.name} initializing...`);
},
onStart: async (agent) => {
console.log(`${agent.name} started`);
},
onTick: async (agent) => {
// Called on every autonomous loop iteration
const memory = agent.getMemory();
const count = ((await memory.recall('tick_count')) as number) || 0;
await memory.remember('tick_count', count + 1);
},
onShutdown: async (agent) => {
console.log(`${agent.name} shutting down`);
},
onError: async (error, agent) => {
console.error(`${agent.name} error:`, error.message);
},
});Custom Actions
Actions are the building blocks of agent behavior. Each action has a name, description, and an execute() method.
import type { Action, ActionContext, ActionResult } from '@moltium/core';
export const myAction: Action = {
name: 'analyze_data',
description: 'Analyze incoming data and produce insights',
async execute(context: ActionContext): Promise<ActionResult> {
const { memory, llm, parameters } = context;
// Read from memory
const previousAnalysis = await memory.recall('last_analysis');
// Use LLM to generate a response
const insight = await llm.generateText(
`Analyze this data: ${JSON.stringify(parameters)}`,
{ temperature: 0.5 },
);
// Store in memory
await memory.remember('last_analysis', insight, 3600);
return { success: true, data: { insight } };
},
};Register custom actions in your config:
const config: AgentConfig = {
// ...
customActions: [myAction],
};Memory
Short-Term (In-Memory)
Default memory type. Fast, session-scoped, lost on restart.
const memory = agent.getMemory();
await memory.remember('key', 'value', 3600); // optional TTL in seconds
const value = await memory.recall('key');
await memory.forget('key');Long-Term (Redis + Postgres)
Persistent storage across sessions. Redis for cache, Postgres for durable storage.
import { LongTermMemory } from '@moltium/core';
const memory = new LongTermMemory({
redis: { url: 'redis://localhost:6379', keyPrefix: 'myagent:' },
postgres: { url: 'postgresql://localhost/myagent' },
});
agent.setMemory(memory);
// Redis (short-term cache with TTL)
await memory.remember('session_data', { count: 1 }, 3600);
const data = await memory.recall('session_data');
// Postgres (persistent)
await memory.store('user_preferences', { theme: 'dark' });
const prefs = await memory.retrieve('user_preferences');
// Experience tracking
await memory.addExperience({
type: 'action',
action: 'post_update',
result: { success: true },
timestamp: new Date(),
});
const experiences = await memory.queryExperiences('post_update', 10);LLM Providers
Anthropic (Claude)
import { AnthropicProvider } from '@moltium/core';
const llm = new AnthropicProvider(apiKey, 'claude-sonnet-4-20250514');
const response = await llm.generateText('Hello!', { temperature: 0.7 });OpenAI (GPT)
import { OpenAIProvider } from '@moltium/core';
const llm = new OpenAIProvider(apiKey, 'gpt-4o');
const response = await llm.generateText('Hello!', { temperature: 0.7 });Structured Output
const decision = await llm.generateStructured<{ action: string; reasoning: string }>(
'What should I do next?',
{
type: 'object',
properties: {
action: { type: 'string' },
reasoning: { type: 'string' },
},
required: ['action', 'reasoning'],
},
);Social Adapters
Moltbook
const config: AgentConfig = {
// ...
social: {
moltbook: {
enabled: true,
apiKey: process.env.MOLTBOOK_API_KEY!,
postFrequency: 'hourly',
autoReply: true,
},
},
};const config: AgentConfig = {
// ...
social: {
twitter: {
enabled: true,
credentials: {
apiKey: process.env.TWITTER_API_KEY!,
apiSecret: process.env.TWITTER_API_SECRET!,
accessToken: process.env.TWITTER_ACCESS_TOKEN!,
accessSecret: process.env.TWITTER_ACCESS_SECRET!,
},
replyToMentions: true,
maxTweetsPerDay: 5,
},
},
};HTTP Server & API Endpoints
When you call startServer(agent, { port }), an Express server starts with these endpoints:
| Endpoint | Method | Description |
|----------|--------|-------------|
| /health | GET | Health check |
| /status | GET | Agent state, uptime, config summary |
| /message | POST | Send a message to the agent |
| /memory | GET | View agent memory |
| /action | POST | Trigger a specific action |
| /logs | GET | View agent logs |
| /config | GET | View current configuration |
| /shutdown | POST | Graceful shutdown |
Markdown Config (MarkdownParser)
For non-developers who prefer natural language configuration:
import { MarkdownParser } from '@moltium/core';
const parser = new MarkdownParser();
const config = parser.parse(markdownString);
// Returns a validated AgentConfig objectConfiguration Loading
ConfigLoader auto-detects whether a directory uses code-based or markdown-based configuration:
import { ConfigLoader } from '@moltium/core';
const loader = new ConfigLoader();
const { config, type } = await loader.load('./my-agent');
// type is 'code' or 'markdown'A2A Protocol Integration
Moltium includes full support for the A2A Protocol v0.3.0, enabling seamless agent-to-agent communication with automatic action registration and zero boilerplate.
Quick Start
Add the a2a config section to automatically register communication actions:
export default {
name: 'My Agent',
// ... other config
a2a: {
enabled: true,
defaultPeerUrl: 'http://localhost:3001', // Optional default peer
verbose: true, // Enable detailed logging
},
actions: [
'talk_to_agent', // Automatically registered when a2a is enabled
],
} satisfies AgentConfig;Configure your server with A2A support:
const port = parseInt(process.env.PORT || '3000', 10);
startServer(agent, {
port,
enableA2A: true,
a2aConfig: {
enabled: true,
baseUrl: `http://0.0.0.0:${port}`,
},
});Your agent now exposes:
- Agent Card at
/.well-known/agent-card.json - JSON-RPC endpoint at
/a2a/jsonrpc - Auto-registered
talk_to_agentaction
Multiple Peer Agents
Define specific peer agents for targeted communication:
a2a: {
enabled: true,
peers: {
talk_to_analyst: 'http://localhost:3001',
talk_to_researcher: 'http://localhost:3002',
talk_to_trader: 'http://localhost:3003',
},
verbose: false,
},
actions: [
'talk_to_analyst', // Auto-registered with pre-configured URL
'talk_to_researcher', // Auto-registered
'talk_to_trader', // Auto-registered
],Programmatic A2A Client
For custom actions or advanced use cases:
import { createA2AClient, A2AClient } from '@moltium/core';
// Simple usage
const client = createA2AClient('http://localhost:3001');
const response = await client.sendMessage({
text: 'What are your thoughts on this strategy?',
});
if (response.success) {
console.log('Reply:', response.reply);
}
// Advanced usage
const client = new A2AClient({
agentUrl: 'http://localhost:3001',
agentCardPath: '.well-known/agent-card.json',
timeout: 30000,
});
const response = await client.sendMessage({
text: 'Analyze this data',
contextId: 'analysis-session-123',
metadata: { priority: 'high' },
});Custom A2A Actions
Use action builders for maximum flexibility:
import { createA2ACommunicationAction, createMultipleA2AActions } from '@moltium/core';
// Single action
const talkToAnalyst = createA2ACommunicationAction({
actionName: 'consult_analyst',
defaultAgentUrl: 'http://localhost:3001',
description: 'Consult with the business analyst for strategic advice',
verbose: true,
});
// Multiple actions at once
const a2aActions = createMultipleA2AActions({
ask_technical: {
defaultAgentUrl: 'http://localhost:3001',
description: 'Ask technical engineering questions',
},
ask_business: {
defaultAgentUrl: 'http://localhost:3002',
description: 'Ask business strategy questions',
},
});
export default {
customActions: [...a2aActions, talkToAnalyst],
actions: ['ask_technical', 'ask_business', 'consult_analyst'],
};A2A API Reference
A2AClient
class A2AClient {
constructor(config: A2AClientConfig)
sendMessage(options: A2AMessageOptions): Promise<A2AMessageResponse>
getAgentCard(): Promise<AgentCard>
getAgentUrl(): string
}
interface A2AClientConfig {
agentUrl: string;
agentCardPath?: string; // Default: .well-known/agent-card.json
timeout?: number; // Default: 30000ms
}
interface A2AMessageOptions {
text: string;
contextId?: string;
metadata?: Record<string, unknown>;
}
interface A2AMessageResponse {
success: boolean;
reply?: string;
agentUrl?: string;
error?: string;
raw?: any;
}Action Builders
// Single action builder
function createA2ACommunicationAction(config: {
defaultAgentUrl?: string;
actionName?: string; // Default: 'talk_to_agent'
description?: string;
verbose?: boolean;
}): Action
// Multiple actions builder
function createMultipleA2AActions(
configs: Record<string, A2ACommunicationActionConfig>
): Action[]Best Practices
Use environment variables for URLs:
a2a: {
peers: {
talk_to_analyst: process.env.ANALYST_URL || 'http://localhost:3001',
},
},Enable verbose logging during development:
a2a: {
verbose: true, // Detailed A2A logs
},Use 0.0.0.0 for local development:
a2aConfig: {
baseUrl: `http://0.0.0.0:${port}`, // Accessible from other agents
},Handle errors gracefully:
const response = await client.sendMessage({ text: 'Hello' });
if (!response.success) {
console.error('Communication failed:', response.error);
}AgentConfig Reference
interface AgentConfig {
name: string;
type?: string; // Free-form: 'assistant', 'trader', 'moderator', etc.
personality: {
traits: string[];
bio: string;
};
llm: {
provider: 'anthropic' | 'openai';
model: string;
apiKey: string;
temperature?: number; // 0-2, default 0.7
maxTokens?: number;
systemPrompt?: string;
};
social: {
moltbook?: MoltbookConfig;
twitter?: TwitterConfig;
};
behaviors: {
autonomous: boolean;
decisionMaking: 'llm-driven' | 'rule-based' | 'hybrid';
actionsPerHour?: number;
sleepSchedule?: { start: number; end: number; timezone?: string };
};
memory: {
type: 'memory' | 'redis' | 'postgres' | 'hybrid';
retention?: string;
redis?: RedisConfig;
postgres?: PostgresConfig;
};
actions: string[]; // Built-in action names
customActions?: Action[]; // User-defined actions
plugins?: Plugin[];
// A2A Protocol configuration (optional)
a2a?: {
enabled?: boolean; // Enable A2A support
peers?: Record<string, string>; // Peer agents: { actionName: 'url' }
defaultPeerUrl?: string; // Default peer URL
verbose?: boolean; // Enable detailed logging
genericActionName?: string; // Custom name for generic action
};
}License
MIT
