@moltium/world-core 0.1.21 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CardFetcher-3QKJ2I5P.js → CardFetcher-4ENWKI6E.js} +2 -2
- package/dist/CardFetcher-UCJGPZ7X.cjs +9 -0
- package/dist/{CardFetcher-AR7IANM7.cjs.map → CardFetcher-UCJGPZ7X.cjs.map} +1 -1
- package/dist/{chunk-NEXCYEQT.cjs → chunk-DHQFXIEW.cjs} +2 -2
- package/dist/chunk-DHQFXIEW.cjs.map +1 -0
- package/dist/{chunk-JW3PZRCW.js → chunk-DWXNX5V3.js} +2 -2
- package/dist/chunk-DWXNX5V3.js.map +1 -0
- package/dist/index.cjs +31 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/CardFetcher-AR7IANM7.cjs +0 -9
- package/dist/chunk-JW3PZRCW.js.map +0 -1
- package/dist/chunk-NEXCYEQT.cjs.map +0 -1
- /package/dist/{CardFetcher-3QKJ2I5P.js.map → CardFetcher-4ENWKI6E.js.map} +0 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/brooklyn/Desktop/SchrodingerLabs/Byzantium/packages/world-core/dist/index.cjs","../src/config/types.ts","../src/config/validator.ts","../src/persistence/adapters/InMemoryAdapter.ts","../src/persistence/PersistenceFactory.ts","../src/engine/World.ts","../src/discovery/AgentEvaluator.ts","../src/blockchain/BlockchainClient.ts","../src/a2a/WorldA2AClient.ts","../src/engine/WorldActions.ts","../src/engine/ActionProcessor.ts","../src/engine/TickOrchestrator.ts","../src/a2a/MessageRouter.ts","../src/server/app.ts"],"names":[],"mappings":"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","file":"/Users/brooklyn/Desktop/SchrodingerLabs/Byzantium/packages/world-core/dist/index.cjs","sourcesContent":[null,"import type { AgentCard } from '@a2a-js/sdk';\n\n/**\n * ============================================================================\n * WORLD CONFIGURATION TYPES\n * ============================================================================\n */\n\nexport interface WorldConfig {\n /** World name (unique identifier) */\n name: string;\n \n /** World description */\n description?: string;\n \n /** World type (for plugin system) */\n type?: string;\n \n /** Server configuration */\n server: {\n port: number;\n host: string;\n };\n \n /** A2A configuration for the world itself */\n a2a?: {\n baseUrl: string;\n pushNotifications?: boolean;\n streaming?: boolean;\n };\n \n /** Admission rules for agent entry */\n admission: AdmissionRules;\n \n /** Simulation configuration */\n simulation?: {\n /** Tick interval in milliseconds */\n tickIntervalMs?: number;\n \n /** Maximum ticks before auto-stop */\n maxTicks?: number;\n \n /** Auto-start simulation on world init */\n autoStart?: boolean;\n };\n \n /** Persistence configuration */\n persistence?: PersistenceConfig;\n \n /** Blockchain configuration */\n blockchain?: BlockchainConfig;\n \n /** Optional world token configuration */\n token?: TokenConfig;\n \n /** World-specific rules */\n rules?: WorldRule[];\n\n /** Pre-configured agent URLs to discover on startup */\n agentUrls?: string[];\n\n /** World-defined actions that agents can execute */\n actions?: WorldAction[];\n\n /** Tick orchestration configuration */\n orchestration?: {\n /** Whether to broadcast tick context to agents (default: true) */\n broadcastOnTick?: boolean;\n /** Timeout for agent responses in ms (default: 10000) */\n tickTimeout?: number;\n /** Custom prompt template for tick broadcasts */\n promptTemplate?: string;\n };\n}\n\n/**\n * ============================================================================\n * WORLD ACTIONS\n * ============================================================================\n */\n\nexport interface WorldAction {\n /** Action name (unique identifier) */\n name: string;\n /** Human-readable description */\n description: string;\n /** Parameter definitions */\n parameters?: Record<string, { type: 'string' | 'number' | 'boolean' | 'object'; required?: boolean; description?: string }>;\n}\n\n/**\n * ============================================================================\n * ADMISSION RULES\n * ============================================================================\n */\n\nexport interface AdmissionRules {\n /** Maximum number of agents allowed */\n maxAgents?: number;\n \n /** Required skills (agent must have ALL of these) */\n requiredSkills?: string[];\n \n /** Required tags (agent must have AT LEAST ONE) */\n requiredTags?: string[];\n \n /** Minimum protocol version */\n minProtocolVersion?: string;\n \n /** Custom evaluator function */\n customEvaluator?: (profile: AgentProfile) => Promise<AdmissionDecision>;\n}\n\nexport interface AdmissionDecision {\n admitted: boolean;\n reason?: string;\n role?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * ============================================================================\n * AGENT PROFILE\n * ============================================================================\n */\n\nexport interface AgentProfile {\n /** Agent URL (canonical identifier from Agent Card) */\n url: string;\n \n /** Agent name */\n name: string;\n \n /** Protocol version */\n protocolVersion: string;\n \n /** Skills from Agent Card */\n skills: Array<{\n id: string;\n name: string;\n description?: string;\n tags?: string[];\n }>;\n \n /** Capabilities */\n capabilities: {\n streaming: boolean;\n pushNotifications: boolean;\n stateTransitionHistory?: boolean;\n };\n \n /** When agent joined the world */\n joinedAt: number;\n \n /** Assigned role (optional) */\n role?: string;\n \n /** Additional metadata */\n metadata?: Record<string, any>;\n \n /** Wallet address (for blockchain membership) */\n walletAddress?: string;\n}\n\n/**\n * ============================================================================\n * WORLD STATE\n * ============================================================================\n */\n\nexport type WorldPhase = \n | 'idle' \n | 'initializing' \n | 'ready' \n | 'running' \n | 'paused' \n | 'completed' \n | 'stopped' \n | 'failed';\n\nexport interface WorldStateSnapshot {\n phase: WorldPhase;\n tick: number;\n round: number;\n timestamp: number;\n metadata: Record<string, any>;\n}\n\n/**\n * ============================================================================\n * WORLD EVENTS\n * ============================================================================\n */\n\nexport interface WorldEvent {\n id: string;\n type: string;\n timestamp: number;\n agentUrl?: string;\n data?: Record<string, any>;\n}\n\n/**\n * ============================================================================\n * WORLD RULES\n * ============================================================================\n */\n\nexport interface WorldRule {\n id: string;\n name: string;\n description?: string;\n evaluate: (context: RuleContext) => Promise<RuleViolation | null>;\n}\n\nexport interface RuleContext {\n world: {\n phase: WorldPhase;\n tick: number;\n agents: Map<string, AgentProfile>;\n };\n event?: WorldEvent;\n agent?: AgentProfile;\n}\n\nexport interface RuleViolation {\n ruleId: string;\n severity: 'warning' | 'error' | 'critical';\n message: string;\n agentUrl?: string;\n action?: 'warn' | 'kick' | 'pause_world';\n}\n\n/**\n * ============================================================================\n * PERSISTENCE CONFIGURATION\n * ============================================================================\n */\n\nexport interface PersistenceConfig {\n type: 'memory' | 'postgres' | 'redis' | 'mongodb' | 'sqlite' | 'leveldb';\n \n // Adapter-specific configs (only one should be present based on type)\n postgres?: {\n connectionString?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n ssl?: boolean;\n max?: number; // connection pool size\n };\n \n redis?: {\n host: string;\n port?: number;\n password?: string;\n db?: number;\n };\n \n mongodb?: {\n url: string;\n database: string;\n };\n \n sqlite?: {\n filename: string;\n };\n \n leveldb?: {\n location: string;\n };\n \n /** Auto-save interval in milliseconds (default: 10000) */\n autoSaveIntervalMs?: number;\n}\n\n/**\n * ============================================================================\n * BLOCKCHAIN CONFIGURATION\n * ============================================================================\n */\n\nexport interface BlockchainConfig {\n /** Monad RPC URL */\n rpcUrl: string;\n \n /** World owner's private key */\n privateKey: string;\n \n /** Entry fee in MON tokens */\n entryFee: number;\n \n /** Require NFT membership for participation (default: true) */\n requireMembership?: boolean;\n \n /** Enforce on-chain agent validation (default: false) */\n enforceOnChainValidation?: boolean;\n \n /** Contract addresses (filled after deployment) */\n agentRegistryAddress?: string;\n membershipContractAddress?: string;\n worldTokenAddress?: string;\n \n /** Chain ID */\n chainId?: number;\n}\n\n/**\n * ============================================================================\n * TOKEN CONFIGURATION\n * ============================================================================\n */\n\nexport interface TokenConfig {\n /** Deploy custom world token */\n deploy: boolean;\n \n /** Token name */\n name?: string;\n \n /** Token symbol */\n symbol?: string;\n \n /** Initial supply */\n initialSupply?: number;\n \n /** Decimals */\n decimals?: number;\n}\n\n/**\n * ============================================================================\n * WORLD TYPE MODULE (for plugin system)\n * ============================================================================\n */\n\nexport interface WorldTypeModule {\n name: string;\n description: string;\n defaultRules: WorldRule[];\n defaultAdmissionRules: Partial<AdmissionRules>;\n onInit?: (world: any) => Promise<void>;\n onTick?: (world: any, tick: number) => Promise<void>;\n onAgentJoin?: (world: any, agent: AgentProfile) => Promise<void>;\n onAgentLeave?: (world: any, agent: AgentProfile) => Promise<void>;\n}\n\n/**\n * ============================================================================\n * UTILITY TYPES\n * ============================================================================\n */\n\nexport interface EventFilter {\n type?: string;\n agentUrl?: string;\n fromTimestamp?: number;\n toTimestamp?: number;\n limit?: number;\n}\n\n/** Helper to build AgentProfile from AgentCard */\nexport function profileFromCard(card: AgentCard, walletAddress?: string): AgentProfile {\n return {\n url: card.url,\n name: card.name,\n protocolVersion: card.protocolVersion,\n skills: card.skills,\n capabilities: {\n streaming: card.capabilities.streaming ?? false,\n pushNotifications: card.capabilities.pushNotifications ?? false,\n stateTransitionHistory: card.capabilities.stateTransitionHistory,\n },\n joinedAt: Date.now(),\n walletAddress,\n };\n}\n","import { z } from 'zod';\n\n/**\n * ============================================================================\n * ZOD SCHEMAS FOR RUNTIME VALIDATION\n * ============================================================================\n */\n\nexport const AdmissionRulesSchema = z.object({\n maxAgents: z.number().int().positive().optional(),\n requiredSkills: z.array(z.string()).optional(),\n requiredTags: z.array(z.string()).optional(),\n minProtocolVersion: z.string().optional(),\n customEvaluator: z.function().optional(),\n});\n\n// Persistence configuration schemas\nconst SQLiteConfigSchema = z.object({\n filename: z.string(),\n memory: z.boolean().optional(),\n});\n\nconst PostgresConfigSchema = z.object({\n connectionString: z.string().optional(),\n host: z.string().optional(),\n port: z.number().optional(),\n database: z.string().optional(),\n user: z.string().optional(),\n password: z.string().optional(),\n ssl: z.boolean().optional(),\n max: z.number().optional(),\n}).refine(\n (data) => data.connectionString || (data.host && data.database && data.user),\n { message: 'Either connectionString or host+database+user is required' }\n);\n\nconst RedisConfigSchema = z.object({\n host: z.string(),\n port: z.number().optional(),\n password: z.string().optional(),\n db: z.number().optional(),\n keyPrefix: z.string().optional(),\n});\n\nconst MongoDBConfigSchema = z.object({\n url: z.string(),\n database: z.string(),\n useUnifiedTopology: z.boolean().optional(),\n});\n\nconst LevelDBConfigSchema = z.object({\n location: z.string(),\n});\n\nexport const PersistenceConfigSchema = z.object({\n type: z.enum(['memory', 'postgres', 'redis', 'mongodb', 'sqlite', 'leveldb']),\n sqlite: SQLiteConfigSchema.optional(),\n postgres: PostgresConfigSchema.optional(),\n redis: RedisConfigSchema.optional(),\n mongodb: MongoDBConfigSchema.optional(),\n leveldb: LevelDBConfigSchema.optional(),\n autoSaveIntervalMs: z.number().int().positive().optional(),\n});\n\nexport const BlockchainConfigSchema = z.object({\n rpcUrl: z.string().url(),\n privateKey: z.string().regex(/^0x[a-fA-F0-9]{64}$/, 'Invalid private key format').optional(),\n entryFee: z.number().nonnegative().optional(),\n requireMembership: z.boolean().optional(),\n enforceOnChainValidation: z.boolean().optional(),\n agentRegistryAddress: z.string().optional(),\n membershipContractAddress: z.string().optional(),\n worldTokenAddress: z.string().optional(),\n chainId: z.number().int().optional(),\n});\n\nexport const TokenConfigSchema = z.object({\n deploy: z.boolean(),\n name: z.string().optional(),\n symbol: z.string().optional(),\n initialSupply: z.number().positive().optional(),\n decimals: z.number().int().min(0).max(18).optional(),\n});\n\nexport const WorldConfigSchema = z.object({\n name: z.string().min(1, 'World name is required'),\n description: z.string().optional(),\n type: z.string().optional(),\n \n server: z.object({\n port: z.number().int().min(1).max(65535),\n host: z.string(),\n }),\n \n a2a: z.object({\n baseUrl: z.string().url(),\n pushNotifications: z.boolean().optional(),\n streaming: z.boolean().optional(),\n }).optional(),\n \n admission: AdmissionRulesSchema,\n \n simulation: z.object({\n tickIntervalMs: z.number().int().positive().optional(),\n maxTicks: z.number().int().positive().optional(),\n autoStart: z.boolean().optional(),\n }).optional(),\n \n persistence: PersistenceConfigSchema.optional(),\n blockchain: BlockchainConfigSchema.optional(),\n token: TokenConfigSchema.optional(),\n \n rules: z.array(z.any()).optional(),\n agentUrls: z.array(z.string().url()).optional(),\n\n actions: z.array(z.object({\n name: z.string().min(1),\n description: z.string(),\n parameters: z.record(z.object({\n type: z.enum(['string', 'number', 'boolean', 'object']),\n required: z.boolean().optional(),\n description: z.string().optional(),\n })).optional(),\n })).optional(),\n\n orchestration: z.object({\n broadcastOnTick: z.boolean().optional(),\n tickTimeout: z.number().int().positive().optional(),\n promptTemplate: z.string().optional(),\n }).optional(),\n});\n\n/**\n * Validate world configuration\n */\nexport function validateWorldConfig(config: unknown): void {\n try {\n WorldConfigSchema.parse(config);\n } catch (error) {\n if (error instanceof z.ZodError) {\n const messages = error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Invalid world configuration: ${messages}`);\n }\n throw error;\n }\n}\n\n/**\n * Validate world configuration and return result\n */\nexport function isValidWorldConfig(config: unknown): boolean {\n try {\n WorldConfigSchema.parse(config);\n return true;\n } catch {\n return false;\n }\n}\n","import type { PersistenceAdapter } from '../PersistenceAdapter.js';\nimport type {\n WorldStateSnapshot,\n WorldEvent,\n AgentProfile,\n EventFilter,\n} from '../../config/types.js';\n\n/**\n * ============================================================================\n * IN-MEMORY PERSISTENCE ADAPTER\n * ============================================================================\n * \n * Simple in-memory persistence for testing and development.\n * No external dependencies - works on any Node version.\n * \n * WARNING: All data is lost when process exits.\n * \n * Use Case: Testing, development, temporary worlds\n */\n\nexport class InMemoryAdapter implements PersistenceAdapter {\n private state: WorldStateSnapshot | null = null;\n private events: WorldEvent[] = [];\n private agents: Map<string, AgentProfile> = new Map();\n \n async connect(): Promise<void> {\n // No-op for in-memory\n }\n \n async saveState(state: WorldStateSnapshot): Promise<void> {\n this.state = { ...state };\n }\n \n async loadState(): Promise<WorldStateSnapshot | null> {\n return this.state ? { ...this.state } : null;\n }\n \n async saveEvent(event: WorldEvent): Promise<void> {\n this.events.push({ ...event });\n }\n \n async getEvents(filter?: EventFilter): Promise<WorldEvent[]> {\n let filtered = [...this.events];\n \n if (filter?.type) {\n filtered = filtered.filter(e => e.type === filter.type);\n }\n \n if (filter?.agentUrl) {\n filtered = filtered.filter(e => e.agentUrl === filter.agentUrl);\n }\n \n if (filter?.fromTimestamp) {\n filtered = filtered.filter(e => e.timestamp >= filter.fromTimestamp!);\n }\n \n if (filter?.toTimestamp) {\n filtered = filtered.filter(e => e.timestamp <= filter.toTimestamp!);\n }\n \n // Sort by timestamp descending\n filtered.sort((a, b) => b.timestamp - a.timestamp);\n \n if (filter?.limit) {\n filtered = filtered.slice(0, filter.limit);\n }\n \n return filtered;\n }\n \n async saveAgent(profile: AgentProfile): Promise<void> {\n this.agents.set(profile.url, { ...profile });\n }\n \n async removeAgent(agentUrl: string): Promise<void> {\n this.agents.delete(agentUrl);\n }\n \n async getAgents(): Promise<AgentProfile[]> {\n return Array.from(this.agents.values()).map(a => ({ ...a }));\n }\n \n async getAgent(agentUrl: string): Promise<AgentProfile | null> {\n const agent = this.agents.get(agentUrl);\n return agent ? { ...agent } : null;\n }\n \n async disconnect(): Promise<void> {\n // No-op for in-memory\n }\n \n async healthCheck(): Promise<boolean> {\n return true;\n }\n \n async clear(): Promise<void> {\n this.state = null;\n this.events = [];\n this.agents.clear();\n }\n}\n","import type { PersistenceAdapter } from './PersistenceAdapter.js';\nimport type { PersistenceConfig } from '../config/types.js';\nimport { InMemoryAdapter } from './adapters/InMemoryAdapter.js';\n\n/**\n * ============================================================================\n * PERSISTENCE FACTORY\n * ============================================================================\n * \n * Creates the appropriate persistence adapter based on configuration.\n * Uses dynamic import() for optional dependencies to avoid requiring all databases\n * to be installed. Only the adapter for the configured persistence type is loaded.\n */\n\nexport async function createPersistence(config: PersistenceConfig): Promise<PersistenceAdapter> {\n switch (config.type) {\n case 'memory':\n return new InMemoryAdapter();\n \n case 'sqlite':\n return createSQLiteAdapter(config.sqlite || { filename: './world.db' });\n \n case 'postgres':\n if (!config.postgres) {\n throw new Error('PostgreSQL configuration is required');\n }\n return createPostgresAdapter(config.postgres);\n \n case 'redis':\n if (!config.redis) {\n throw new Error('Redis configuration is required');\n }\n return createRedisAdapter(config.redis);\n \n case 'mongodb':\n if (!config.mongodb) {\n throw new Error('MongoDB configuration is required');\n }\n return createMongoAdapter(config.mongodb);\n \n case 'leveldb':\n if (!config.leveldb) {\n throw new Error('LevelDB configuration is required');\n }\n return createLevelDBAdapter(config.leveldb);\n \n default:\n throw new Error(`Unknown persistence type: ${(config as any).type}`);\n }\n}\n\n/**\n * Lazy-load SQLite adapter via dynamic import\n */\nasync function createSQLiteAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n const Database = (await import('better-sqlite3')).default;\n \n // Inline adapter that uses the dynamically-imported Database\n return new (class implements PersistenceAdapter {\n private db!: any;\n \n async connect(): Promise<void> {\n // Ensure the parent directory exists\n const path = await import('path');\n const fs = await import('fs');\n const dir = path.dirname(config.filename);\n if (dir && dir !== '.') {\n fs.mkdirSync(dir, { recursive: true });\n }\n this.db = new Database(config.filename);\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS world_state (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n phase TEXT NOT NULL,\n tick INTEGER NOT NULL,\n round INTEGER NOT NULL,\n timestamp INTEGER NOT NULL,\n metadata TEXT\n );\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n agent_url TEXT,\n timestamp INTEGER NOT NULL,\n data TEXT\n );\n CREATE TABLE IF NOT EXISTS agents (\n url TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n protocol_version TEXT NOT NULL,\n skills TEXT NOT NULL,\n capabilities TEXT NOT NULL,\n joined_at INTEGER NOT NULL,\n role TEXT,\n metadata TEXT,\n wallet_address TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_events_type ON events(type);\n CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\n CREATE INDEX IF NOT EXISTS idx_events_agent ON events(agent_url);\n `);\n }\n\n async saveState(state: any): Promise<void> {\n const stmt = this.db.prepare(`INSERT OR REPLACE INTO world_state (id, phase, tick, round, timestamp, metadata) VALUES (1, ?, ?, ?, ?, ?)`);\n stmt.run(state.phase, state.tick, state.round, state.timestamp, JSON.stringify(state.metadata));\n }\n\n async loadState(): Promise<any> {\n const stmt = this.db.prepare('SELECT * FROM world_state WHERE id = 1');\n const row = stmt.get() as any;\n if (!row) return null;\n return { phase: row.phase, tick: row.tick, round: row.round, timestamp: row.timestamp, metadata: JSON.parse(row.metadata || '{}') };\n }\n\n async saveEvent(event: any): Promise<void> {\n const stmt = this.db.prepare(`INSERT INTO events (id, type, agent_url, timestamp, data) VALUES (?, ?, ?, ?, ?)`);\n stmt.run(event.id, event.type, event.agentUrl || null, event.timestamp, JSON.stringify(event.data || {}));\n }\n\n async getEvents(filter?: any): Promise<any[]> {\n let query = 'SELECT * FROM events WHERE 1=1';\n const params: any[] = [];\n if (filter?.type) { query += ' AND type = ?'; params.push(filter.type); }\n if (filter?.agentUrl) { query += ' AND agent_url = ?'; params.push(filter.agentUrl); }\n if (filter?.fromTimestamp) { query += ' AND timestamp >= ?'; params.push(filter.fromTimestamp); }\n if (filter?.toTimestamp) { query += ' AND timestamp <= ?'; params.push(filter.toTimestamp); }\n query += ' ORDER BY timestamp DESC';\n if (filter?.limit) { query += ' LIMIT ?'; params.push(filter.limit); }\n const stmt = this.db.prepare(query);\n const rows = stmt.all(...params) as any[];\n return rows.map(row => ({ id: row.id, type: row.type, timestamp: row.timestamp, agentUrl: row.agent_url || undefined, data: JSON.parse(row.data || '{}') }));\n }\n\n async saveAgent(profile: any): Promise<void> {\n const stmt = this.db.prepare(`INSERT OR REPLACE INTO agents (url, name, protocol_version, skills, capabilities, joined_at, role, metadata, wallet_address) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`);\n stmt.run(profile.url, profile.name, profile.protocolVersion, JSON.stringify(profile.skills), JSON.stringify(profile.capabilities), profile.joinedAt, profile.role || null, JSON.stringify(profile.metadata || {}), profile.walletAddress || null);\n }\n\n async removeAgent(agentUrl: string): Promise<void> {\n this.db.prepare('DELETE FROM agents WHERE url = ?').run(agentUrl);\n }\n\n async getAgents(): Promise<any[]> {\n const rows = this.db.prepare('SELECT * FROM agents ORDER BY joined_at ASC').all() as any[];\n return rows.map(row => ({ url: row.url, name: row.name, protocolVersion: row.protocol_version, skills: JSON.parse(row.skills), capabilities: JSON.parse(row.capabilities), joinedAt: row.joined_at, role: row.role || undefined, metadata: JSON.parse(row.metadata || '{}'), walletAddress: row.wallet_address || undefined }));\n }\n\n async getAgent(agentUrl: string): Promise<any> {\n const row = this.db.prepare('SELECT * FROM agents WHERE url = ?').get(agentUrl) as any;\n if (!row) return null;\n return { url: row.url, name: row.name, protocolVersion: row.protocol_version, skills: JSON.parse(row.skills), capabilities: JSON.parse(row.capabilities), joinedAt: row.joined_at, role: row.role || undefined, metadata: JSON.parse(row.metadata || '{}'), walletAddress: row.wallet_address || undefined };\n }\n\n async disconnect(): Promise<void> { this.db.close(); }\n async healthCheck(): Promise<boolean> { try { this.db.prepare('SELECT 1').get(); return true; } catch { return false; } }\n async clear(): Promise<void> { this.db.exec('DELETE FROM world_state; DELETE FROM events; DELETE FROM agents;'); }\n })();\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'SQLite adapter requires better-sqlite3. Install it with: npm install better-sqlite3'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load PostgreSQL adapter via dynamic import\n */\nasync function createPostgresAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n const pg = await import('pg');\n const Pool = pg.default?.Pool || pg.Pool;\n const { PostgresAdapter } = await import('./adapters/PostgresAdapter.js');\n return new PostgresAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'PostgreSQL adapter requires pg. Install it with: npm install pg'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load Redis adapter via dynamic import\n */\nasync function createRedisAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n await import('ioredis');\n const { RedisAdapter } = await import('./adapters/RedisAdapter.js');\n return new RedisAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'Redis adapter requires ioredis. Install it with: npm install ioredis'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load MongoDB adapter via dynamic import\n */\nasync function createMongoAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n // @ts-ignore - mongodb is an optional peer dependency\n await import('mongodb');\n const { MongoAdapter } = await import('./adapters/MongoAdapter.js');\n return new MongoAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'MongoDB adapter requires mongodb. Install it with: npm install mongodb'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load LevelDB adapter via dynamic import\n */\nasync function createLevelDBAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n // @ts-ignore - level is an optional peer dependency\n await import('level');\n const { LevelDBAdapter } = await import('./adapters/LevelDBAdapter.js');\n return new LevelDBAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'LevelDB adapter requires level. Install it with: npm install level'\n );\n }\n throw error;\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport type {\n WorldConfig,\n WorldPhase,\n WorldStateSnapshot,\n WorldEvent,\n AgentProfile,\n} from '../config/types.js';\nimport { validateWorldConfig } from '../config/validator.js';\nimport type { PersistenceAdapter } from '../persistence/PersistenceAdapter.js';\nimport { createPersistence } from '../persistence/PersistenceFactory.js';\nimport { CardFetcher } from '../discovery/CardFetcher.js';\nimport { AgentEvaluator } from '../discovery/AgentEvaluator.js';\nimport { BlockchainClient } from '../blockchain/BlockchainClient.js';\nimport { WorldA2AClient } from '../a2a/WorldA2AClient.js';\nimport { WorldActionsRegistry } from './WorldActions.js';\nimport { TickOrchestrator } from './TickOrchestrator.js';\nimport { MessageRouter } from '../a2a/MessageRouter.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('World');\n\n/**\n * ============================================================================\n * WORLD ENGINE\n * ============================================================================\n * \n * Core world runtime managing:\n * - Agent discovery and admission\n * - World state and lifecycle\n * - Persistence and event logging\n * - Simulation ticks (if enabled)\n * - Rule enforcement\n */\n\nexport class World {\n private state: WorldStateSnapshot;\n private agents: Map<string, AgentProfile>;\n private persistence: PersistenceAdapter | null = null;\n private blockchainClient: BlockchainClient | null = null;\n private cardFetcher: CardFetcher;\n private evaluator: AgentEvaluator;\n private tickInterval: NodeJS.Timeout | null = null;\n private autoSaveInterval: NodeJS.Timeout | null = null;\n\n // Agent-World bridge components\n private a2aClient: WorldA2AClient;\n private actionsRegistry: WorldActionsRegistry;\n private orchestrator: TickOrchestrator;\n private messageRouter: MessageRouter;\n\n constructor(public readonly config: WorldConfig) {\n // Validate configuration\n validateWorldConfig(config);\n\n // Initialize state\n this.state = {\n phase: 'idle',\n tick: 0,\n round: 0,\n timestamp: Date.now(),\n metadata: {},\n };\n\n this.agents = new Map();\n this.cardFetcher = new CardFetcher();\n this.evaluator = new AgentEvaluator(config.admission);\n\n // Initialize bridge components\n this.a2aClient = new WorldA2AClient();\n this.actionsRegistry = new WorldActionsRegistry();\n this.orchestrator = new TickOrchestrator(\n this.a2aClient,\n this.actionsRegistry,\n config.rules || [],\n config.orchestration\n );\n this.messageRouter = new MessageRouter(\n this.a2aClient,\n () => this.getAgents()\n );\n\n // Register world-defined actions\n if (config.actions && config.actions.length > 0) {\n this.actionsRegistry.registerAll(config.actions);\n logger.info(`Registered ${config.actions.length} world actions`);\n }\n\n logger.info(`World \"${config.name}\" created`, {\n type: config.type || 'generic',\n maxAgents: config.admission.maxAgents,\n orchestration: !!config.orchestration?.broadcastOnTick,\n });\n }\n \n /**\n * Initialize the world (connect persistence, restore state, discover agents)\n */\n async init(): Promise<void> {\n logger.info('Initializing world...');\n this.setState('initializing');\n \n try {\n // 1. Connect to persistence backend\n if (this.config.persistence) {\n logger.info(`Connecting to persistence backend: ${this.config.persistence.type}`);\n this.persistence = await createPersistence(this.config.persistence);\n await this.persistence.connect();\n \n // Try to restore state from persistence\n const savedState = await this.persistence.loadState();\n if (savedState) {\n this.state = savedState;\n logger.info('Restored world state from persistence', {\n phase: savedState.phase,\n tick: savedState.tick,\n });\n \n // Restore agents\n const savedAgents = await this.persistence.getAgents();\n for (const agent of savedAgents) {\n this.agents.set(agent.url, agent);\n }\n \n logger.info(`Restored ${savedAgents.length} agents from persistence`);\n }\n }\n \n // 2. Initialize blockchain client if configured\n if (this.config.blockchain) {\n logger.info('Initializing blockchain client...');\n this.blockchainClient = new BlockchainClient(this.config.blockchain);\n await this.blockchainClient.init();\n }\n \n // 3. Discover pre-configured agents\n if (this.config.agentUrls && this.config.agentUrls.length > 0) {\n logger.info(`Discovering ${this.config.agentUrls.length} pre-configured agents...`);\n \n const results = await this.cardFetcher.fetchCards(this.config.agentUrls);\n \n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (result.success && result.card) {\n // Auto-admit pre-configured agents\n try {\n await this.admitAgent(result.card);\n } catch (error: any) {\n logger.warn(`Failed to admit pre-configured agent:`, error.message);\n }\n }\n }\n }\n \n // 3. Start auto-save if persistence enabled\n if (this.persistence) {\n this.startAutoSave();\n }\n \n this.setState('ready');\n logger.info('World initialized successfully', {\n agents: this.agents.size,\n persistence: this.config.persistence?.type || 'none',\n });\n } catch (error: any) {\n logger.error('Failed to initialize world:', error);\n this.setState('failed');\n throw error;\n }\n }\n \n /**\n * Start the world simulation\n */\n async start(): Promise<void> {\n if (this.state.phase === 'running') {\n logger.warn('World is already running');\n return;\n }\n \n logger.info('Starting world simulation...');\n this.setState('running');\n \n await this.logEvent({\n id: uuidv4(),\n type: 'world_started',\n timestamp: Date.now(),\n });\n \n // Start tick interval if simulation is enabled\n if (this.config.simulation?.tickIntervalMs) {\n this.startTicking();\n }\n }\n \n /**\n * Stop the world simulation\n */\n async stop(): Promise<void> {\n logger.info('Stopping world...');\n this.setState('stopped');\n \n // Stop ticking\n if (this.tickInterval) {\n clearInterval(this.tickInterval);\n this.tickInterval = null;\n }\n \n // Stop auto-save\n if (this.autoSaveInterval) {\n clearInterval(this.autoSaveInterval);\n this.autoSaveInterval = null;\n }\n \n // Final save\n if (this.persistence) {\n await this.persistence.saveState(this.state);\n }\n \n await this.logEvent({\n id: uuidv4(),\n type: 'world_stopped',\n timestamp: Date.now(),\n });\n \n logger.info('World stopped');\n }\n \n /**\n * Admit an agent to the world\n */\n async admitAgent(card: any, walletAddress?: string): Promise<void> {\n const decision = await this.evaluator.evaluate(card, this.agents.size, walletAddress);\n \n if (!decision.admitted) {\n throw new Error(`Agent admission denied: ${decision.reason}`);\n }\n \n // Optional: Validate agent on-chain\n if (this.blockchainClient && this.config.blockchain?.enforceOnChainValidation && walletAddress) {\n const isValid = await this.blockchainClient.validateAgent(walletAddress);\n if (!isValid) {\n throw new Error('Agent not registered in on-chain AgentRegistry');\n }\n logger.info(`Agent validated on-chain: ${card.name}`);\n }\n \n // Optional: Mint membership NFT\n if (this.blockchainClient && this.config.blockchain?.requireMembership && walletAddress) {\n // Check if agent already has membership\n const hasMembership = await this.blockchainClient.hasMembership(walletAddress);\n \n if (!hasMembership) {\n logger.info(`Minting membership NFT for agent: ${card.name}`);\n await this.blockchainClient.mintMembership(walletAddress);\n } else {\n logger.info(`Agent already has membership: ${card.name}`);\n }\n }\n \n const profile: AgentProfile = {\n url: card.url,\n name: card.name,\n protocolVersion: card.protocolVersion,\n skills: card.skills,\n capabilities: {\n streaming: card.capabilities.streaming ?? false,\n pushNotifications: card.capabilities.pushNotifications ?? false,\n stateTransitionHistory: card.capabilities.stateTransitionHistory,\n },\n joinedAt: Date.now(),\n role: decision.role,\n metadata: decision.metadata,\n walletAddress,\n };\n \n this.agents.set(profile.url, profile);\n\n // Add agent to A2A client pool for tick broadcasting\n this.a2aClient.addAgent(profile.url);\n\n if (this.persistence) {\n await this.persistence.saveAgent(profile);\n }\n\n await this.logEvent({\n id: uuidv4(),\n type: 'agent_joined',\n timestamp: Date.now(),\n agentUrl: profile.url,\n data: { name: profile.name, role: profile.role },\n });\n\n logger.info(`Agent admitted: ${profile.name}`, {\n role: profile.role,\n totalAgents: this.agents.size,\n });\n }\n \n /**\n * Remove an agent from the world\n */\n async removeAgent(agentUrl: string): Promise<void> {\n const agent = this.agents.get(agentUrl);\n if (!agent) {\n throw new Error(`Agent not found: ${agentUrl}`);\n }\n \n this.agents.delete(agentUrl);\n\n // Remove from A2A client pool\n this.a2aClient.removeAgent(agentUrl);\n\n if (this.persistence) {\n await this.persistence.removeAgent(agentUrl);\n }\n \n await this.logEvent({\n id: uuidv4(),\n type: 'agent_left',\n timestamp: Date.now(),\n agentUrl,\n data: { name: agent.name },\n });\n \n logger.info(`Agent removed: ${agent.name}`, {\n totalAgents: this.agents.size,\n });\n }\n \n /**\n * Get all agents in the world\n */\n getAgents(): AgentProfile[] {\n return Array.from(this.agents.values());\n }\n \n /**\n * Get current world state\n */\n getState(): WorldStateSnapshot {\n return { ...this.state };\n }\n\n /**\n * Get the message router (for agent-to-agent communication via server)\n */\n getMessageRouter(): MessageRouter {\n return this.messageRouter;\n }\n\n /**\n * Get the actions registry\n */\n getActionsRegistry(): WorldActionsRegistry {\n return this.actionsRegistry;\n }\n \n /**\n * Log an event\n */\n private async logEvent(event: WorldEvent): Promise<void> {\n if (this.persistence) {\n await this.persistence.saveEvent(event);\n }\n }\n \n /**\n * Set world phase\n */\n private setState(phase: WorldPhase): void {\n this.state.phase = phase;\n this.state.timestamp = Date.now();\n }\n \n /**\n * Start auto-save interval\n */\n private startAutoSave(): void {\n const interval = this.config.persistence?.autoSaveIntervalMs || 10000;\n \n this.autoSaveInterval = setInterval(async () => {\n if (this.persistence) {\n await this.persistence.saveState(this.state);\n logger.debug('Auto-saved world state');\n }\n }, interval);\n \n logger.info(`Auto-save enabled (interval: ${interval}ms)`);\n }\n \n /**\n * Start simulation ticking\n */\n private startTicking(): void {\n const interval = this.config.simulation!.tickIntervalMs!;\n\n this.tickInterval = setInterval(async () => {\n this.state.tick++;\n this.state.timestamp = Date.now();\n\n // Execute orchestrated tick (broadcast to agents, collect responses, validate)\n try {\n const tickResult = await this.orchestrator.executeTick(\n this.state.tick,\n this.getAgents(),\n this.state,\n this.config.name\n );\n\n // Apply state updates from agent actions\n if (tickResult.stateUpdates && Object.keys(tickResult.stateUpdates).length > 0) {\n Object.assign(this.state.metadata, tickResult.stateUpdates);\n }\n\n // Log all events from the tick\n for (const event of tickResult.events) {\n await this.logEvent(event);\n }\n } catch (error: any) {\n logger.error(`Tick ${this.state.tick} orchestration error:`, error);\n await this.logEvent({\n id: uuidv4(),\n type: 'tick_error',\n timestamp: Date.now(),\n data: { tick: this.state.tick, error: error?.message || String(error) },\n });\n }\n\n logger.debug(`Tick ${this.state.tick}`);\n\n // Check max ticks\n if (this.config.simulation?.maxTicks && this.state.tick >= this.config.simulation.maxTicks) {\n logger.info('Max ticks reached, stopping world');\n await this.stop();\n }\n }, interval);\n\n logger.info(`Simulation ticking enabled (interval: ${interval}ms)`);\n }\n}\n","import type { AgentCard } from '@a2a-js/sdk';\nimport type { AgentProfile, AdmissionRules, AdmissionDecision } from '../config/types.js';\nimport { profileFromCard } from '../config/types.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('AgentEvaluator');\n\n/**\n * ============================================================================\n * AGENT EVALUATOR\n * ============================================================================\n * \n * Evaluates whether an agent should be admitted to the world based on rules.\n * \n * Evaluation criteria:\n * - Max agents limit\n * - Required skills (agent must have ALL)\n * - Required tags (agent must have AT LEAST ONE)\n * - Minimum protocol version\n * - Custom evaluator function\n */\n\nexport class AgentEvaluator {\n constructor(private rules: AdmissionRules) {}\n \n /**\n * Evaluate whether an agent should be admitted.\n * \n * @param card Agent's A2A card\n * @param currentAgentCount Current number of agents in world\n * @param walletAddress Optional wallet address for blockchain membership\n * @returns Admission decision\n */\n async evaluate(\n card: AgentCard,\n currentAgentCount: number,\n walletAddress?: string\n ): Promise<AdmissionDecision> {\n logger.debug(`Evaluating agent: ${card.name}`, {\n currentAgents: currentAgentCount,\n maxAgents: this.rules.maxAgents,\n });\n \n // Check max agents limit\n if (this.rules.maxAgents && currentAgentCount >= this.rules.maxAgents) {\n logger.info(`Agent ${card.name} rejected: world is full`, {\n current: currentAgentCount,\n max: this.rules.maxAgents,\n });\n \n return {\n admitted: false,\n reason: `World is full (${this.rules.maxAgents} agents maximum)`,\n };\n }\n \n // Check protocol version\n if (this.rules.minProtocolVersion) {\n if (!this.meetsProtocolVersion(card.protocolVersion, this.rules.minProtocolVersion)) {\n logger.info(`Agent ${card.name} rejected: protocol version too old`, {\n agent: card.protocolVersion,\n required: this.rules.minProtocolVersion,\n });\n \n return {\n admitted: false,\n reason: `Protocol version ${card.protocolVersion} is below minimum ${this.rules.minProtocolVersion}`,\n };\n }\n }\n \n // Check required skills (agent must have ALL)\n if (this.rules.requiredSkills && this.rules.requiredSkills.length > 0) {\n const agentSkillIds = card.skills.map(s => s.id.toLowerCase());\n const missingSkills = this.rules.requiredSkills.filter(\n required => !agentSkillIds.includes(required.toLowerCase())\n );\n \n if (missingSkills.length > 0) {\n logger.info(`Agent ${card.name} rejected: missing required skills`, {\n missing: missingSkills,\n });\n \n return {\n admitted: false,\n reason: `Missing required skills: ${missingSkills.join(', ')}`,\n };\n }\n }\n \n // Check required tags (agent must have AT LEAST ONE)\n if (this.rules.requiredTags && this.rules.requiredTags.length > 0) {\n const agentTags = card.skills.flatMap(s => s.tags || []).map(t => t.toLowerCase());\n const hasRequiredTag = this.rules.requiredTags.some(\n required => agentTags.includes(required.toLowerCase())\n );\n \n if (!hasRequiredTag) {\n logger.info(`Agent ${card.name} rejected: no matching tags`, {\n required: this.rules.requiredTags,\n });\n \n return {\n admitted: false,\n reason: `Must have at least one of these tags: ${this.rules.requiredTags.join(', ')}`,\n };\n }\n }\n \n // Run custom evaluator if provided\n if (this.rules.customEvaluator) {\n const profile = profileFromCard(card, walletAddress);\n const customDecision = await this.rules.customEvaluator(profile);\n \n if (!customDecision.admitted) {\n logger.info(`Agent ${card.name} rejected by custom evaluator`, {\n reason: customDecision.reason,\n });\n \n return customDecision;\n }\n \n // Custom evaluator can assign roles and metadata\n if (customDecision.role || customDecision.metadata) {\n logger.debug(`Custom evaluator assigned role/metadata to ${card.name}`, {\n role: customDecision.role,\n });\n }\n \n return customDecision;\n }\n \n // All checks passed\n logger.info(`Agent ${card.name} admitted to world`);\n \n return {\n admitted: true,\n reason: 'All admission criteria met',\n };\n }\n \n /**\n * Check if agent's protocol version meets minimum requirement.\n * Simple semver comparison (major.minor).\n */\n private meetsProtocolVersion(agentVersion: string, minVersion: string): boolean {\n const parse = (v: string) => {\n const parts = v.split('.');\n return {\n major: parseInt(parts[0] || '0', 10),\n minor: parseInt(parts[1] || '0', 10),\n };\n };\n \n const agent = parse(agentVersion);\n const min = parse(minVersion);\n \n if (agent.major > min.major) return true;\n if (agent.major < min.major) return false;\n return agent.minor >= min.minor;\n }\n}\n","import { ethers } from 'ethers';\nimport type { BlockchainConfig } from '../config/types.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('BlockchainClient');\n\n// Contract ABIs (minimal interfaces)\nconst AGENT_REGISTRY_ABI = [\n 'function registerAgent(string agentUrl, string name) external',\n 'function isAgentValid(address wallet) external view returns (bool)',\n 'function getAgent(address wallet) external view returns (tuple(address walletAddress, string agentUrl, string name, uint256 registeredAt, bool isActive))',\n 'function getWalletByUrl(string agentUrl) external view returns (address)',\n 'event AgentRegistered(address indexed wallet, string agentUrl, string name)',\n];\n\nconst WORLD_MEMBERSHIP_ABI = [\n 'function mintMembership(address agent) external payable',\n 'function revokeMembership(address agent) external',\n 'function hasMembership(address agent) external view returns (bool)',\n 'function entryFee() external view returns (uint256)',\n 'function totalMembers() external view returns (uint256)',\n 'function withdrawFees() external',\n 'event MembershipMinted(address indexed agent, uint256 indexed tokenId, uint256 feePaid)',\n];\n\nconst WORLD_TOKEN_ABI = [\n 'function mint(address to, uint256 amount) external',\n 'function burn(address from, uint256 amount) external',\n 'function balanceOf(address account) external view returns (uint256)',\n 'function transfer(address to, uint256 amount) external returns (bool)',\n];\n\n/**\n * ============================================================================\n * BLOCKCHAIN CLIENT\n * ============================================================================\n * \n * Handles all blockchain interactions for the World SDK:\n * - Agent registry validation\n * - Membership NFT minting\n * - Entry fee collection\n * - World token operations\n */\n\nexport class BlockchainClient {\n private provider: ethers.JsonRpcProvider;\n private wallet: ethers.Wallet;\n private agentRegistry?: ethers.Contract;\n private membershipContract?: ethers.Contract;\n private worldToken?: ethers.Contract;\n \n constructor(private config: BlockchainConfig) {\n // Initialize provider and wallet\n this.provider = new ethers.JsonRpcProvider(config.rpcUrl);\n this.wallet = new ethers.Wallet(config.privateKey, this.provider);\n \n logger.info('Blockchain client initialized', {\n network: config.rpcUrl,\n wallet: this.wallet.address,\n });\n }\n \n /**\n * Initialize contract connections\n */\n async init(): Promise<void> {\n // Connect to AgentRegistry if address provided\n if (this.config.agentRegistryAddress) {\n this.agentRegistry = new ethers.Contract(\n this.config.agentRegistryAddress,\n AGENT_REGISTRY_ABI,\n this.wallet\n );\n logger.info('Connected to AgentRegistry', {\n address: this.config.agentRegistryAddress,\n });\n }\n \n // Connect to WorldMembership if address provided\n if (this.config.membershipContractAddress) {\n this.membershipContract = new ethers.Contract(\n this.config.membershipContractAddress,\n WORLD_MEMBERSHIP_ABI,\n this.wallet\n );\n logger.info('Connected to WorldMembership', {\n address: this.config.membershipContractAddress,\n });\n }\n \n // Connect to WorldToken if address provided\n if (this.config.worldTokenAddress) {\n this.worldToken = new ethers.Contract(\n this.config.worldTokenAddress,\n WORLD_TOKEN_ABI,\n this.wallet\n );\n logger.info('Connected to WorldToken', {\n address: this.config.worldTokenAddress,\n });\n }\n \n logger.info('Blockchain client ready');\n }\n \n /**\n * Validate agent on-chain\n * @param walletAddress Agent's wallet address\n * @returns True if agent is registered and valid\n */\n async validateAgent(walletAddress: string): Promise<boolean> {\n if (!this.agentRegistry) {\n logger.warn('AgentRegistry not configured, skipping on-chain validation');\n return true; // Skip validation if not configured\n }\n \n try {\n const isValid = await this.agentRegistry.isAgentValid(walletAddress);\n logger.debug('Agent validation result', {\n wallet: walletAddress,\n isValid,\n });\n return isValid;\n } catch (error: any) {\n logger.error('Failed to validate agent on-chain', {\n wallet: walletAddress,\n error: error.message,\n });\n return false;\n }\n }\n \n /**\n * Mint membership NFT for an agent\n * @param agentWallet Agent's wallet address\n * @returns Transaction hash\n */\n async mintMembership(agentWallet: string): Promise<string> {\n if (!this.membershipContract) {\n throw new Error('WorldMembership contract not configured');\n }\n \n try {\n // Get entry fee\n const entryFee = await this.membershipContract.entryFee();\n \n logger.info('Minting membership NFT', {\n agent: agentWallet,\n entryFee: ethers.formatEther(entryFee),\n });\n \n // Mint membership\n const tx = await this.membershipContract.mintMembership(agentWallet, {\n value: entryFee,\n });\n \n const receipt = await tx.wait();\n \n logger.info('Membership NFT minted', {\n agent: agentWallet,\n txHash: receipt.hash,\n blockNumber: receipt.blockNumber,\n });\n \n return receipt.hash;\n } catch (error: any) {\n logger.error('Failed to mint membership NFT', {\n agent: agentWallet,\n error: error.message,\n });\n throw error;\n }\n }\n \n /**\n * Check if agent has membership\n * @param agentWallet Agent's wallet address\n * @returns True if agent has membership\n */\n async hasMembership(agentWallet: string): Promise<boolean> {\n if (!this.membershipContract) {\n logger.warn('WorldMembership not configured, skipping membership check');\n return true; // Skip check if not configured\n }\n \n try {\n const hasMembership = await this.membershipContract.hasMembership(agentWallet);\n return hasMembership;\n } catch (error: any) {\n logger.error('Failed to check membership', {\n agent: agentWallet,\n error: error.message,\n });\n return false;\n }\n }\n \n /**\n * Revoke membership NFT\n * @param agentWallet Agent's wallet address\n * @returns Transaction hash\n */\n async revokeMembership(agentWallet: string): Promise<string> {\n if (!this.membershipContract) {\n throw new Error('WorldMembership contract not configured');\n }\n \n try {\n logger.info('Revoking membership', { agent: agentWallet });\n \n const tx = await this.membershipContract.revokeMembership(agentWallet);\n const receipt = await tx.wait();\n \n logger.info('Membership revoked', {\n agent: agentWallet,\n txHash: receipt.hash,\n });\n \n return receipt.hash;\n } catch (error: any) {\n logger.error('Failed to revoke membership', {\n agent: agentWallet,\n error: error.message,\n });\n throw error;\n }\n }\n \n /**\n * Get total number of members\n */\n async getTotalMembers(): Promise<number> {\n if (!this.membershipContract) {\n return 0;\n }\n \n try {\n const total = await this.membershipContract.totalMembers();\n return Number(total);\n } catch (error: any) {\n logger.error('Failed to get total members', { error: error.message });\n return 0;\n }\n }\n \n /**\n * Withdraw collected entry fees (world owner only)\n */\n async withdrawFees(): Promise<string> {\n if (!this.membershipContract) {\n throw new Error('WorldMembership contract not configured');\n }\n \n try {\n logger.info('Withdrawing entry fees');\n \n const tx = await this.membershipContract.withdrawFees();\n const receipt = await tx.wait();\n \n logger.info('Fees withdrawn', {\n txHash: receipt.hash,\n blockNumber: receipt.blockNumber,\n });\n \n return receipt.hash;\n } catch (error: any) {\n logger.error('Failed to withdraw fees', { error: error.message });\n throw error;\n }\n }\n \n /**\n * Get world owner's wallet address\n */\n getWalletAddress(): string {\n return this.wallet.address;\n }\n \n /**\n * Get entry fee in MON\n */\n async getEntryFee(): Promise<string> {\n if (!this.membershipContract) {\n return '0';\n }\n \n try {\n const fee = await this.membershipContract.entryFee();\n return ethers.formatEther(fee);\n } catch (error: any) {\n logger.error('Failed to get entry fee', { error: error.message });\n return '0';\n }\n }\n}\n","import { A2AClient, type A2AMessageResponse } from '@moltium/core';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('WorldA2AClient');\n\n/**\n * ============================================================================\n * WORLD A2A CLIENT\n * ============================================================================\n *\n * Manages a pool of A2A clients for all admitted agents.\n * Used by the TickOrchestrator to broadcast tick context and collect responses,\n * and by the MessageRouter for agent-to-agent communication.\n */\n\nexport class WorldA2AClient {\n private clients: Map<string, A2AClient> = new Map();\n\n /**\n * Add an agent to the client pool\n */\n addAgent(agentUrl: string): void {\n if (this.clients.has(agentUrl)) {\n logger.debug(`Agent already in client pool: ${agentUrl}`);\n return;\n }\n\n const client = new A2AClient({ agentUrl });\n this.clients.set(agentUrl, client);\n logger.info(`Added agent to A2A client pool: ${agentUrl}`);\n }\n\n /**\n * Remove an agent from the client pool\n */\n removeAgent(agentUrl: string): void {\n this.clients.delete(agentUrl);\n logger.info(`Removed agent from A2A client pool: ${agentUrl}`);\n }\n\n /**\n * Send an A2A message to a specific agent\n */\n async sendToAgent(\n agentUrl: string,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<A2AMessageResponse> {\n const client = this.clients.get(agentUrl);\n if (!client) {\n return {\n success: false,\n error: `Agent not in client pool: ${agentUrl}`,\n agentUrl,\n };\n }\n\n try {\n const response = await client.sendMessage({ text: message, metadata });\n logger.debug(`A2A message sent to ${agentUrl}`, { success: response.success });\n return response;\n } catch (error: any) {\n logger.error(`Failed to send A2A message to ${agentUrl}:`, error);\n return {\n success: false,\n error: error?.message || String(error),\n agentUrl,\n };\n }\n }\n\n /**\n * Broadcast an A2A message to all agents in the pool\n */\n async broadcastToAll(\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<Map<string, A2AMessageResponse>> {\n const results = new Map<string, A2AMessageResponse>();\n\n const promises = Array.from(this.clients.entries()).map(\n async ([agentUrl]) => {\n const response = await this.sendToAgent(agentUrl, message, metadata);\n results.set(agentUrl, response);\n }\n );\n\n await Promise.allSettled(promises);\n\n logger.info(`Broadcast complete: ${results.size} agents`, {\n succeeded: Array.from(results.values()).filter(r => r.success).length,\n failed: Array.from(results.values()).filter(r => !r.success).length,\n });\n\n return results;\n }\n\n /**\n * Get the number of agents in the pool\n */\n get size(): number {\n return this.clients.size;\n }\n\n /**\n * Check if an agent is in the pool\n */\n has(agentUrl: string): boolean {\n return this.clients.has(agentUrl);\n }\n\n /**\n * Get all agent URLs in the pool\n */\n getAgentUrls(): string[] {\n return Array.from(this.clients.keys());\n }\n}\n","import { createLogger } from '../logger.js';\n\nconst logger = createLogger('WorldActions');\n\n/**\n * ============================================================================\n * WORLD ACTION DEFINITIONS\n * ============================================================================\n *\n * Worlds define what actions agents can take. These are sent as context\n * during tick broadcasts so agents know their available options.\n */\n\nexport interface WorldAction {\n /** Action name (unique identifier) */\n name: string;\n\n /** Human-readable description */\n description: string;\n\n /** Parameter definitions */\n parameters?: Record<string, WorldActionParam>;\n}\n\nexport interface WorldActionParam {\n type: 'string' | 'number' | 'boolean' | 'object';\n required?: boolean;\n description?: string;\n}\n\n/**\n * Registry for world-defined actions.\n * Agents receive the registered actions as available options during tick broadcasts.\n */\nexport class WorldActionsRegistry {\n private actions: Map<string, WorldAction> = new Map();\n\n /**\n * Register a world action\n */\n register(action: WorldAction): void {\n if (this.actions.has(action.name)) {\n logger.warn(`Overwriting existing action: ${action.name}`);\n }\n this.actions.set(action.name, action);\n logger.debug(`Registered world action: ${action.name}`);\n }\n\n /**\n * Register multiple actions at once\n */\n registerAll(actions: WorldAction[]): void {\n for (const action of actions) {\n this.register(action);\n }\n }\n\n /**\n * Get all registered actions\n */\n getAll(): WorldAction[] {\n return Array.from(this.actions.values());\n }\n\n /**\n * Get a specific action by name\n */\n get(name: string): WorldAction | undefined {\n return this.actions.get(name);\n }\n\n /**\n * Check if an action exists\n */\n has(name: string): boolean {\n return this.actions.has(name);\n }\n\n /**\n * Validate an action name and its parameters\n */\n validate(\n actionName: string,\n params: Record<string, any>\n ): { valid: boolean; error?: string } {\n const action = this.actions.get(actionName);\n if (!action) {\n return { valid: false, error: `Unknown action: ${actionName}` };\n }\n\n if (!action.parameters) {\n return { valid: true };\n }\n\n // Check required parameters\n for (const [paramName, paramDef] of Object.entries(action.parameters)) {\n if (paramDef.required && !(paramName in params)) {\n return {\n valid: false,\n error: `Missing required parameter: ${paramName} for action ${actionName}`,\n };\n }\n\n // Type check if parameter is provided\n if (paramName in params && params[paramName] !== undefined) {\n const actualType = typeof params[paramName];\n if (paramDef.type === 'object') {\n if (actualType !== 'object' || params[paramName] === null) {\n return {\n valid: false,\n error: `Parameter ${paramName} must be an object`,\n };\n }\n } else if (actualType !== paramDef.type) {\n return {\n valid: false,\n error: `Parameter ${paramName} must be of type ${paramDef.type}, got ${actualType}`,\n };\n }\n }\n }\n\n return { valid: true };\n }\n\n /**\n * Get action names as a simple list (for tick context)\n */\n getActionNames(): string[] {\n return Array.from(this.actions.keys());\n }\n\n /**\n * Get actions as a serializable summary (for tick context)\n */\n toSummary(): Array<{ name: string; description: string; parameters?: Record<string, WorldActionParam> }> {\n return this.getAll().map(a => ({\n name: a.name,\n description: a.description,\n ...(a.parameters && { parameters: a.parameters }),\n }));\n }\n}\n","import type {\n WorldRule,\n RuleContext,\n RuleViolation,\n WorldEvent,\n AgentProfile,\n WorldPhase,\n} from '../config/types.js';\nimport type { WorldActionsRegistry } from './WorldActions.js';\nimport { createLogger } from '../logger.js';\nimport { v4 as uuidv4 } from 'uuid';\n\nconst logger = createLogger('ActionProcessor');\n\n/**\n * ============================================================================\n * ACTION PROCESSOR\n * ============================================================================\n *\n * Validates agent tick responses against world rules before applying.\n * Ensures agents only execute valid, permitted actions.\n */\n\nexport interface AgentTickResponse {\n agentUrl: string;\n action?: string;\n parameters?: Record<string, any>;\n message?: string;\n error?: string;\n}\n\nexport interface ProcessResult {\n accepted: boolean;\n violations: RuleViolation[];\n stateUpdates?: Record<string, any>;\n events?: WorldEvent[];\n}\n\nexport class ActionProcessor {\n constructor(\n private rules: WorldRule[],\n private actionsRegistry: WorldActionsRegistry\n ) {}\n\n /**\n * Process an agent's tick response: validate action and check rules\n */\n async process(\n response: AgentTickResponse,\n agent: AgentProfile,\n worldContext: {\n phase: WorldPhase;\n tick: number;\n agents: Map<string, AgentProfile>;\n }\n ): Promise<ProcessResult> {\n const violations: RuleViolation[] = [];\n const events: WorldEvent[] = [];\n\n // If agent returned an error or no action, skip validation\n if (response.error || !response.action) {\n return { accepted: false, violations: [], events: [] };\n }\n\n // 1. Validate that the action exists in the registry\n const actionValidation = this.actionsRegistry.validate(\n response.action,\n response.parameters || {}\n );\n\n if (!actionValidation.valid) {\n logger.warn(`Invalid action from ${response.agentUrl}: ${actionValidation.error}`);\n violations.push({\n ruleId: '_action_validation',\n severity: 'warning',\n message: actionValidation.error!,\n agentUrl: response.agentUrl,\n action: 'warn',\n });\n return { accepted: false, violations, events: [] };\n }\n\n // 2. Run through world rules\n const ruleContext: RuleContext = {\n world: {\n phase: worldContext.phase,\n tick: worldContext.tick,\n agents: worldContext.agents,\n },\n event: {\n id: uuidv4(),\n type: 'agent_action',\n timestamp: Date.now(),\n agentUrl: response.agentUrl,\n data: {\n action: response.action,\n parameters: response.parameters,\n },\n },\n agent,\n };\n\n for (const rule of this.rules) {\n try {\n const violation = await rule.evaluate(ruleContext);\n if (violation) {\n violations.push(violation);\n logger.warn(`Rule violation: ${rule.name}`, {\n agentUrl: response.agentUrl,\n action: response.action,\n severity: violation.severity,\n });\n }\n } catch (error: any) {\n logger.error(`Rule evaluation error (${rule.name}):`, error);\n }\n }\n\n // Check for blocking violations (error or critical severity)\n const blocking = violations.filter(\n v => v.severity === 'error' || v.severity === 'critical'\n );\n\n if (blocking.length > 0) {\n return { accepted: false, violations, events: [] };\n }\n\n // 3. Action accepted — create event\n events.push({\n id: uuidv4(),\n type: 'action_executed',\n timestamp: Date.now(),\n agentUrl: response.agentUrl,\n data: {\n action: response.action,\n parameters: response.parameters,\n },\n });\n\n return {\n accepted: true,\n violations,\n stateUpdates: {\n [`lastAction_${response.agentUrl}`]: {\n action: response.action,\n parameters: response.parameters,\n tick: worldContext.tick,\n },\n },\n events,\n };\n }\n\n /**\n * Update the rules list\n */\n setRules(rules: WorldRule[]): void {\n this.rules = rules;\n }\n}\n","import type {\n AgentProfile,\n WorldStateSnapshot,\n WorldEvent,\n WorldRule,\n} from '../config/types.js';\nimport type { WorldA2AClient } from '../a2a/WorldA2AClient.js';\nimport type { WorldActionsRegistry } from './WorldActions.js';\nimport { ActionProcessor, type AgentTickResponse } from './ActionProcessor.js';\nimport { createLogger } from '../logger.js';\nimport { v4 as uuidv4 } from 'uuid';\n\nconst logger = createLogger('TickOrchestrator');\n\n/**\n * ============================================================================\n * TICK ORCHESTRATOR\n * ============================================================================\n *\n * Orchestrates the world tick loop:\n * 1. Build tick context (state, actions, agents)\n * 2. Broadcast to all agents via A2A\n * 3. Collect and parse responses\n * 4. Validate responses against rules\n * 5. Apply state updates and log events\n */\n\nexport interface TickResult {\n tick: number;\n responses: Map<string, AgentTickResponse>;\n events: WorldEvent[];\n stateUpdates: Record<string, any>;\n errors: Array<{ agentUrl: string; error: string }>;\n}\n\nexport interface OrchestrationConfig {\n /** Whether to broadcast tick context to agents (default: true) */\n broadcastOnTick?: boolean;\n\n /** Timeout for agent responses in ms (default: 10000) */\n tickTimeout?: number;\n\n /** Custom prompt template for tick broadcasts */\n promptTemplate?: string;\n}\n\nexport class TickOrchestrator {\n private actionProcessor: ActionProcessor;\n private orchestrationConfig: OrchestrationConfig;\n\n constructor(\n private a2aClient: WorldA2AClient,\n private actionsRegistry: WorldActionsRegistry,\n rules: WorldRule[],\n config?: OrchestrationConfig\n ) {\n this.actionProcessor = new ActionProcessor(rules, actionsRegistry);\n this.orchestrationConfig = {\n broadcastOnTick: config?.broadcastOnTick ?? true,\n tickTimeout: config?.tickTimeout ?? 10000,\n promptTemplate: config?.promptTemplate,\n };\n }\n\n /**\n * Execute a single world tick\n */\n async executeTick(\n tick: number,\n agents: AgentProfile[],\n state: WorldStateSnapshot,\n worldName: string\n ): Promise<TickResult> {\n const result: TickResult = {\n tick,\n responses: new Map(),\n events: [],\n stateUpdates: {},\n errors: [],\n };\n\n // If no agents or broadcasting disabled, just log the tick\n if (agents.length === 0 || !this.orchestrationConfig.broadcastOnTick) {\n logger.debug(`Tick ${tick}: no agents to broadcast to`);\n return result;\n }\n\n // 1. Build tick context message\n const tickContext = this.buildTickContext(tick, agents, state, worldName);\n const message = JSON.stringify(tickContext);\n\n logger.debug(`Tick ${tick}: broadcasting to ${agents.length} agents`);\n\n // 2. Broadcast to all agents via A2A\n const responses = await this.a2aClient.broadcastToAll(message, {\n type: 'world_tick',\n tick,\n worldName,\n });\n\n // 3. Parse and process responses\n const agentsMap = new Map<string, AgentProfile>();\n for (const agent of agents) {\n agentsMap.set(agent.url, agent);\n }\n\n for (const [agentUrl, a2aResponse] of responses) {\n // Parse the agent's response\n const tickResponse = this.parseAgentResponse(agentUrl, a2aResponse);\n result.responses.set(agentUrl, tickResponse);\n\n if (tickResponse.error) {\n result.errors.push({ agentUrl, error: tickResponse.error });\n continue;\n }\n\n // 4. Validate against rules\n const agent = agentsMap.get(agentUrl);\n if (!agent || !tickResponse.action) continue;\n\n const processResult = await this.actionProcessor.process(\n tickResponse,\n agent,\n { phase: state.phase, tick, agents: agentsMap }\n );\n\n if (processResult.accepted) {\n // Merge state updates\n if (processResult.stateUpdates) {\n Object.assign(result.stateUpdates, processResult.stateUpdates);\n }\n if (processResult.events) {\n result.events.push(...processResult.events);\n }\n }\n\n // Log violations (even for accepted actions with warnings)\n for (const violation of processResult.violations) {\n result.events.push({\n id: uuidv4(),\n type: 'rule_violation',\n timestamp: Date.now(),\n agentUrl,\n data: {\n ruleId: violation.ruleId,\n severity: violation.severity,\n message: violation.message,\n },\n });\n }\n }\n\n // 5. Log tick completion\n result.events.push({\n id: uuidv4(),\n type: 'tick',\n timestamp: Date.now(),\n data: {\n tick,\n agentsBroadcasted: agents.length,\n responsesReceived: result.responses.size,\n errorsCount: result.errors.length,\n },\n });\n\n logger.info(`Tick ${tick} complete`, {\n responses: result.responses.size,\n errors: result.errors.length,\n stateUpdates: Object.keys(result.stateUpdates).length,\n });\n\n return result;\n }\n\n /**\n * Build the tick context that gets sent to each agent\n */\n private buildTickContext(\n tick: number,\n agents: AgentProfile[],\n state: WorldStateSnapshot,\n worldName: string\n ): Record<string, any> {\n const availableActions = this.actionsRegistry.toSummary();\n\n const agentsSummary = agents.map(a => ({\n name: a.name,\n role: a.role || 'participant',\n skills: a.skills.map(s => s.id),\n }));\n\n const prompt =\n this.orchestrationConfig.promptTemplate ||\n `You are participating in world \"${worldName}\". Current tick: ${tick}. ` +\n `Choose an action from the available actions and respond with a JSON object: ` +\n `{ \"action\": \"<action_name>\", \"parameters\": { ... } }. ` +\n `You may also include a \"message\" field for free-form communication.`;\n\n return {\n type: 'world_tick',\n tick,\n worldName,\n state: {\n phase: state.phase,\n tick: state.tick,\n round: state.round,\n metadata: state.metadata,\n },\n availableActions,\n agents: agentsSummary,\n prompt,\n };\n }\n\n /**\n * Parse an A2A response into an AgentTickResponse\n */\n private parseAgentResponse(\n agentUrl: string,\n a2aResponse: { success: boolean; reply?: string; error?: string }\n ): AgentTickResponse {\n if (!a2aResponse.success) {\n return {\n agentUrl,\n error: a2aResponse.error || 'A2A communication failed',\n };\n }\n\n const reply = a2aResponse.reply;\n if (!reply) {\n return { agentUrl, message: '' };\n }\n\n // Try to parse as JSON (structured action response)\n try {\n const parsed = JSON.parse(reply);\n return {\n agentUrl,\n action: parsed.action,\n parameters: parsed.parameters || {},\n message: parsed.message,\n };\n } catch {\n // Not JSON — treat as free-form message\n return {\n agentUrl,\n message: reply,\n };\n }\n }\n\n /**\n * Update orchestration config\n */\n setConfig(config: Partial<OrchestrationConfig>): void {\n Object.assign(this.orchestrationConfig, config);\n }\n\n /**\n * Update rules on the action processor\n */\n setRules(rules: WorldRule[]): void {\n this.actionProcessor.setRules(rules);\n }\n}\n","import type { A2AMessageResponse } from '@moltium/core';\nimport type { WorldA2AClient } from './WorldA2AClient.js';\nimport type { AgentProfile } from '../config/types.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('MessageRouter');\n\n/**\n * ============================================================================\n * MESSAGE ROUTER\n * ============================================================================\n *\n * Routes agent-to-agent messages through the world hub.\n * Agents send messages to the world's /world/message endpoint,\n * and the router forwards them to the target agent(s) via A2A.\n */\n\nexport class MessageRouter {\n constructor(\n private a2aClient: WorldA2AClient,\n private getAgents: () => AgentProfile[]\n ) {}\n\n /**\n * Route a message from one agent to another\n */\n async route(\n fromAgentUrl: string,\n toAgentUrl: string,\n message: string\n ): Promise<A2AMessageResponse> {\n // Verify sender is in the world\n const agents = this.getAgents();\n const sender = agents.find(a => a.url === fromAgentUrl);\n if (!sender) {\n return {\n success: false,\n error: `Sender not in world: ${fromAgentUrl}`,\n };\n }\n\n // Verify recipient is in the world\n const recipient = agents.find(a => a.url === toAgentUrl);\n if (!recipient) {\n return {\n success: false,\n error: `Recipient not in world: ${toAgentUrl}`,\n };\n }\n\n // Wrap message with sender context\n const wrappedMessage = JSON.stringify({\n type: 'world_message',\n from: {\n url: sender.url,\n name: sender.name,\n role: sender.role,\n },\n message,\n });\n\n logger.info(`Routing message: ${sender.name} → ${recipient.name}`);\n\n return this.a2aClient.sendToAgent(toAgentUrl, wrappedMessage, {\n type: 'world_message',\n fromAgentUrl,\n });\n }\n\n /**\n * Broadcast a message from one agent to all other agents in the world\n */\n async routeToAll(\n fromAgentUrl: string,\n message: string\n ): Promise<Map<string, A2AMessageResponse>> {\n const agents = this.getAgents();\n const sender = agents.find(a => a.url === fromAgentUrl);\n if (!sender) {\n const result = new Map<string, A2AMessageResponse>();\n result.set(fromAgentUrl, {\n success: false,\n error: `Sender not in world: ${fromAgentUrl}`,\n });\n return result;\n }\n\n const wrappedMessage = JSON.stringify({\n type: 'world_broadcast',\n from: {\n url: sender.url,\n name: sender.name,\n role: sender.role,\n },\n message,\n });\n\n // Send to all agents except the sender\n const results = new Map<string, A2AMessageResponse>();\n const recipients = agents.filter(a => a.url !== fromAgentUrl);\n\n const promises = recipients.map(async (recipient) => {\n const response = await this.a2aClient.sendToAgent(\n recipient.url,\n wrappedMessage,\n { type: 'world_broadcast', fromAgentUrl }\n );\n results.set(recipient.url, response);\n });\n\n await Promise.allSettled(promises);\n\n logger.info(`Broadcast from ${sender.name} to ${recipients.length} agents`);\n return results;\n }\n}\n","import express, { type Express, type Request, type Response } from 'express';\nimport type { World } from '../engine/World.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('WorldServer');\n\n/**\n * ============================================================================\n * WORLD HTTP SERVER\n * ============================================================================\n * \n * Express server providing HTTP endpoints for:\n * - World information\n * - Agent join requests \n * - Agent list\n * - World state and events\n * \n * Mirrors the agent SDK server pattern.\n */\n\nexport function createWorldApp(world: World): Express {\n const app = express();\n \n // Middleware\n app.use(express.json());\n app.use(express.urlencoded({ extended: true }));\n \n // Request logging\n app.use((req, res, next) => {\n logger.debug(`${req.method} ${req.path}`, {\n query: req.query,\n ip: req.ip,\n });\n next();\n });\n \n /**\n * GET / - World information\n */\n app.get('/', (req: Request, res: Response) => {\n res.json({\n name: world.config.name,\n description: world.config.description,\n type: world.config.type || 'generic',\n state: world.getState(),\n agentCount: world.getAgents().length,\n maxAgents: world.config.admission.maxAgents || null,\n admission: {\n requiredSkills: world.config.admission.requiredSkills || [],\n requiredTags: world.config.admission.requiredTags || [],\n minProtocolVersion: world.config.admission.minProtocolVersion || null,\n },\n });\n });\n \n /**\n * POST /world/join - Agent join request\n * \n * Body:\n * {\n * \"agentUrl\": \"http://localhost:3000\",\n * \"walletAddress\": \"0x...\" // optional, for blockchain membership\n * }\n */\n app.post('/world/join', async (req: Request, res: Response) => {\n try {\n const { agentUrl, walletAddress } = req.body;\n \n if (!agentUrl) {\n return res.status(400).json({\n success: false,\n error: 'agentUrl is required',\n });\n }\n \n logger.info(`Agent join request from: ${agentUrl}`, {\n wallet: walletAddress || 'none',\n });\n \n // Fetch agent card\n const cardFetcher = new (await import('../discovery/CardFetcher.js')).CardFetcher();\n const result = await cardFetcher.fetchCard(agentUrl);\n \n if (!result.success || !result.card) {\n return res.status(400).json({\n success: false,\n error: `Failed to fetch agent card: ${result.error}`,\n });\n }\n \n // Admit agent\n await world.admitAgent(result.card, walletAddress);\n \n res.json({\n success: true,\n message: 'Agent admitted to world',\n world: {\n name: world.config.name,\n agentCount: world.getAgents().length,\n },\n });\n } catch (error: any) {\n logger.error('Failed to process join request:', error);\n \n res.status(400).json({\n success: false,\n error: error.message || 'Failed to join world',\n });\n }\n });\n \n /**\n * GET /world/agents - List all agents\n */\n app.get('/world/agents', (req: Request, res: Response) => {\n const agents = world.getAgents().map(agent => ({\n url: agent.url,\n name: agent.name,\n protocolVersion: agent.protocolVersion,\n skills: agent.skills.map(s => s.id),\n joinedAt: agent.joinedAt,\n role: agent.role,\n }));\n \n res.json({\n agents,\n count: agents.length,\n });\n });\n \n /**\n * GET /world/state - World state\n */\n app.get('/world/state', (req: Request, res: Response) => {\n res.json(world.getState());\n });\n \n /**\n * POST /world/start - Start world simulation\n */\n app.post('/world/start', async (req: Request, res: Response) => {\n try {\n await world.start();\n res.json({\n success: true,\n message: 'World simulation started',\n state: world.getState(),\n });\n } catch (error: any) {\n res.status(400).json({\n success: false,\n error: error.message,\n });\n }\n });\n \n /**\n * POST /world/stop - Stop world simulation\n */\n app.post('/world/stop', async (req: Request, res: Response) => {\n try {\n await world.stop();\n res.json({\n success: true,\n message: 'World simulation stopped',\n state: world.getState(),\n });\n } catch (error: any) {\n res.status(400).json({\n success: false,\n error: error.message,\n });\n }\n });\n \n /**\n * POST /world/message - Route a message between agents through the world hub\n *\n * Body:\n * {\n * \"fromAgentUrl\": \"http://localhost:3000\",\n * \"toAgentUrl\": \"http://localhost:3001\", // optional — omit to broadcast\n * \"message\": \"Hello from agent A\"\n * }\n */\n app.post('/world/message', async (req: Request, res: Response) => {\n try {\n const { fromAgentUrl, toAgentUrl, message } = req.body;\n\n if (!fromAgentUrl) {\n return res.status(400).json({\n success: false,\n error: 'fromAgentUrl is required',\n });\n }\n\n if (!message) {\n return res.status(400).json({\n success: false,\n error: 'message is required',\n });\n }\n\n const router = world.getMessageRouter();\n\n if (toAgentUrl) {\n // Route to specific agent\n const result = await router.route(fromAgentUrl, toAgentUrl, message);\n res.json({\n success: result.success,\n reply: result.reply,\n error: result.error,\n });\n } else {\n // Broadcast to all agents\n const results = await router.routeToAll(fromAgentUrl, message);\n const responses: Record<string, any> = {};\n for (const [url, result] of results) {\n responses[url] = {\n success: result.success,\n reply: result.reply,\n error: result.error,\n };\n }\n res.json({\n success: true,\n responses,\n count: results.size,\n });\n }\n } catch (error: any) {\n logger.error('Failed to route message:', error);\n res.status(500).json({\n success: false,\n error: error.message || 'Failed to route message',\n });\n }\n });\n\n /**\n * GET /world/actions - List available world actions\n */\n app.get('/world/actions', (req: Request, res: Response) => {\n const registry = world.getActionsRegistry();\n res.json({\n actions: registry.toSummary(),\n count: registry.getAll().length,\n });\n });\n\n /**\n * DELETE /world/agents/:agentUrl - Remove an agent\n */\n app.delete('/world/agents/:agentUrl', async (req: Request, res: Response) => {\n try {\n const agentUrlParam = req.params.agentUrl;\n const agentUrl = typeof agentUrlParam === 'string' \n ? decodeURIComponent(agentUrlParam)\n : decodeURIComponent(agentUrlParam[0]);\n \n await world.removeAgent(agentUrl);\n \n res.json({\n success: true,\n message: 'Agent removed from world',\n });\n } catch (error: any) {\n res.status(400).json({\n success: false,\n error: error.message,\n });\n }\n });\n \n // 404 handler\n app.use((req: Request, res: Response) => {\n res.status(404).json({\n error: 'Not found',\n path: req.path,\n });\n });\n \n // Error handler\n app.use((err: any, req: Request, res: Response, next: any) => {\n logger.error('Server error:', err);\n \n res.status(500).json({\n error: 'Internal server error',\n message: err.message,\n });\n });\n \n return app;\n}\n\n/**\n * Start world server on configured port\n */\nexport async function startWorldServer(world: World): Promise<void> {\n const app = createWorldApp(world);\n \n const server = app.listen(world.config.server.port, world.config.server.host, () => {\n const { host, port } = world.config.server;\n \n logger.info(`World \"${world.config.name}\" server started`);\n logger.info(` http://${host}:${port}`);\n logger.info('');\n logger.info('Endpoints:');\n logger.info(` GET / - World info`);\n logger.info(` POST /world/join - Agent join request`);\n logger.info(` GET /world/agents - List agents`);\n logger.info(` GET /world/state - World state`);\n logger.info(` GET /world/actions - List world actions`);\n logger.info(` POST /world/message - Route agent messages`);\n logger.info(` POST /world/start - Start simulation`);\n logger.info(` POST /world/stop - Stop simulation`);\n logger.info(` DELETE /world/agents/:url - Remove agent`);\n });\n \n // Graceful shutdown\n process.on('SIGTERM', async () => {\n logger.info('SIGTERM received, shutting down gracefully...');\n \n server.close(async () => {\n await world.stop();\n process.exit(0);\n });\n });\n \n process.on('SIGINT', async () => {\n logger.info('SIGINT received, shutting down gracefully...');\n \n server.close(async () => {\n await world.stop();\n process.exit(0);\n });\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/brooklyn/Desktop/SchrodingerLabs/Byzantium/packages/world-core/dist/index.cjs","../src/config/types.ts","../src/config/validator.ts","../src/persistence/adapters/InMemoryAdapter.ts","../src/persistence/PersistenceFactory.ts","../src/engine/World.ts","../src/discovery/AgentEvaluator.ts","../src/blockchain/BlockchainClient.ts","../src/a2a/WorldA2AClient.ts","../src/engine/WorldActions.ts","../src/engine/ActionProcessor.ts","../src/engine/TickOrchestrator.ts","../src/a2a/MessageRouter.ts","../src/server/app.ts"],"names":[],"mappings":"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","file":"/Users/brooklyn/Desktop/SchrodingerLabs/Byzantium/packages/world-core/dist/index.cjs","sourcesContent":[null,"import type { AgentCard } from '@a2a-js/sdk';\n\n/**\n * ============================================================================\n * WORLD CONFIGURATION TYPES\n * ============================================================================\n */\n\nexport interface WorldConfig {\n /** World name (unique identifier) */\n name: string;\n \n /** World description */\n description?: string;\n \n /** World type (for plugin system) */\n type?: string;\n \n /** Server configuration */\n server: {\n port: number;\n host: string;\n };\n \n /** A2A configuration for the world itself */\n a2a?: {\n baseUrl: string;\n pushNotifications?: boolean;\n streaming?: boolean;\n };\n \n /** Admission rules for agent entry */\n admission: AdmissionRules;\n \n /** Simulation configuration */\n simulation?: {\n /** Tick interval in milliseconds */\n tickIntervalMs?: number;\n \n /** Maximum ticks before auto-stop */\n maxTicks?: number;\n \n /** Auto-start simulation on world init */\n autoStart?: boolean;\n };\n \n /** Persistence configuration */\n persistence?: PersistenceConfig;\n \n /** Blockchain configuration */\n blockchain?: BlockchainConfig;\n \n /** Optional world token configuration */\n token?: TokenConfig;\n \n /** World-specific rules */\n rules?: WorldRule[];\n\n /** Pre-configured agent URLs to discover on startup */\n agentUrls?: string[];\n\n /** World-defined actions that agents can execute */\n actions?: WorldAction[];\n\n /** Tick orchestration configuration */\n orchestration?: {\n /** Whether to broadcast tick context to agents (default: true) */\n broadcastOnTick?: boolean;\n /** Timeout for agent responses in ms (default: 10000) */\n tickTimeout?: number;\n /** Custom prompt template for tick broadcasts */\n promptTemplate?: string;\n };\n}\n\n/**\n * ============================================================================\n * WORLD ACTIONS\n * ============================================================================\n */\n\nexport interface WorldAction {\n /** Action name (unique identifier) */\n name: string;\n /** Human-readable description */\n description: string;\n /** Parameter definitions */\n parameters?: Record<string, { type: 'string' | 'number' | 'boolean' | 'object'; required?: boolean; description?: string }>;\n}\n\n/**\n * ============================================================================\n * ADMISSION RULES\n * ============================================================================\n */\n\nexport interface AdmissionRules {\n /** Maximum number of agents allowed */\n maxAgents?: number;\n \n /** Required skills (agent must have ALL of these) */\n requiredSkills?: string[];\n \n /** Required tags (agent must have AT LEAST ONE) */\n requiredTags?: string[];\n \n /** Minimum protocol version */\n minProtocolVersion?: string;\n \n /** Custom evaluator function */\n customEvaluator?: (profile: AgentProfile) => Promise<AdmissionDecision>;\n}\n\nexport interface AdmissionDecision {\n admitted: boolean;\n reason?: string;\n role?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * ============================================================================\n * AGENT PROFILE\n * ============================================================================\n */\n\nexport interface AgentProfile {\n /** Agent URL (canonical identifier from Agent Card) */\n url: string;\n \n /** Agent name */\n name: string;\n \n /** Protocol version */\n protocolVersion: string;\n \n /** Skills from Agent Card */\n skills: Array<{\n id: string;\n name: string;\n description?: string;\n tags?: string[];\n }>;\n \n /** Capabilities */\n capabilities: {\n streaming: boolean;\n pushNotifications: boolean;\n stateTransitionHistory?: boolean;\n };\n \n /** When agent joined the world */\n joinedAt: number;\n \n /** Assigned role (optional) */\n role?: string;\n \n /** Additional metadata */\n metadata?: Record<string, any>;\n \n /** Wallet address (for blockchain membership) */\n walletAddress?: string;\n}\n\n/**\n * ============================================================================\n * WORLD STATE\n * ============================================================================\n */\n\nexport type WorldPhase = \n | 'idle' \n | 'initializing' \n | 'ready' \n | 'running' \n | 'paused' \n | 'completed' \n | 'stopped' \n | 'failed';\n\nexport interface WorldStateSnapshot {\n phase: WorldPhase;\n tick: number;\n round: number;\n timestamp: number;\n metadata: Record<string, any>;\n}\n\n/**\n * ============================================================================\n * WORLD EVENTS\n * ============================================================================\n */\n\nexport interface WorldEvent {\n id: string;\n type: string;\n timestamp: number;\n agentUrl?: string;\n data?: Record<string, any>;\n}\n\n/**\n * ============================================================================\n * WORLD RULES\n * ============================================================================\n */\n\nexport interface WorldRule {\n id: string;\n name: string;\n description?: string;\n evaluate: (context: RuleContext) => Promise<RuleViolation | null>;\n}\n\nexport interface RuleContext {\n world: {\n phase: WorldPhase;\n tick: number;\n agents: Map<string, AgentProfile>;\n };\n event?: WorldEvent;\n agent?: AgentProfile;\n}\n\nexport interface RuleViolation {\n ruleId: string;\n severity: 'warning' | 'error' | 'critical';\n message: string;\n agentUrl?: string;\n action?: 'warn' | 'kick' | 'pause_world';\n}\n\n/**\n * ============================================================================\n * PERSISTENCE CONFIGURATION\n * ============================================================================\n */\n\nexport interface PersistenceConfig {\n type: 'memory' | 'postgres' | 'redis' | 'mongodb' | 'sqlite' | 'leveldb';\n \n // Adapter-specific configs (only one should be present based on type)\n postgres?: {\n connectionString?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n ssl?: boolean;\n max?: number; // connection pool size\n };\n \n redis?: {\n host: string;\n port?: number;\n password?: string;\n db?: number;\n };\n \n mongodb?: {\n url: string;\n database: string;\n };\n \n sqlite?: {\n filename: string;\n };\n \n leveldb?: {\n location: string;\n };\n \n /** Auto-save interval in milliseconds (default: 10000) */\n autoSaveIntervalMs?: number;\n}\n\n/**\n * ============================================================================\n * BLOCKCHAIN CONFIGURATION\n * ============================================================================\n */\n\nexport interface BlockchainConfig {\n /** Monad RPC URL */\n rpcUrl: string;\n \n /** World owner's private key */\n privateKey: string;\n \n /** Entry fee in MON tokens */\n entryFee: number;\n \n /** Require NFT membership for participation (default: true) */\n requireMembership?: boolean;\n \n /** Enforce on-chain agent validation (default: false) */\n enforceOnChainValidation?: boolean;\n \n /** Contract addresses (filled after deployment) */\n agentRegistryAddress?: string;\n membershipContractAddress?: string;\n worldTokenAddress?: string;\n \n /** Chain ID */\n chainId?: number;\n}\n\n/**\n * ============================================================================\n * TOKEN CONFIGURATION\n * ============================================================================\n */\n\nexport interface TokenConfig {\n /** Deploy custom world token */\n deploy: boolean;\n \n /** Token name */\n name?: string;\n \n /** Token symbol */\n symbol?: string;\n \n /** Initial supply */\n initialSupply?: number;\n \n /** Decimals */\n decimals?: number;\n}\n\n/**\n * ============================================================================\n * WORLD TYPE MODULE (for plugin system)\n * ============================================================================\n */\n\nexport interface WorldTypeModule {\n name: string;\n description: string;\n defaultRules: WorldRule[];\n defaultAdmissionRules: Partial<AdmissionRules>;\n onInit?: (world: any) => Promise<void>;\n onTick?: (world: any, tick: number) => Promise<void>;\n onAgentJoin?: (world: any, agent: AgentProfile) => Promise<void>;\n onAgentLeave?: (world: any, agent: AgentProfile) => Promise<void>;\n}\n\n/**\n * ============================================================================\n * UTILITY TYPES\n * ============================================================================\n */\n\nexport interface EventFilter {\n type?: string;\n agentUrl?: string;\n fromTimestamp?: number;\n toTimestamp?: number;\n limit?: number;\n}\n\n/** Helper to build AgentProfile from AgentCard */\nexport function profileFromCard(card: AgentCard, walletAddress?: string): AgentProfile {\n return {\n url: card.url,\n name: card.name,\n protocolVersion: card.protocolVersion,\n skills: card.skills,\n capabilities: {\n streaming: card.capabilities.streaming ?? false,\n pushNotifications: card.capabilities.pushNotifications ?? false,\n stateTransitionHistory: card.capabilities.stateTransitionHistory,\n },\n joinedAt: Date.now(),\n walletAddress,\n };\n}\n","import { z } from 'zod';\n\n/**\n * ============================================================================\n * ZOD SCHEMAS FOR RUNTIME VALIDATION\n * ============================================================================\n */\n\nexport const AdmissionRulesSchema = z.object({\n maxAgents: z.number().int().positive().optional(),\n requiredSkills: z.array(z.string()).optional(),\n requiredTags: z.array(z.string()).optional(),\n minProtocolVersion: z.string().optional(),\n customEvaluator: z.function().optional(),\n});\n\n// Persistence configuration schemas\nconst SQLiteConfigSchema = z.object({\n filename: z.string(),\n memory: z.boolean().optional(),\n});\n\nconst PostgresConfigSchema = z.object({\n connectionString: z.string().optional(),\n host: z.string().optional(),\n port: z.number().optional(),\n database: z.string().optional(),\n user: z.string().optional(),\n password: z.string().optional(),\n ssl: z.boolean().optional(),\n max: z.number().optional(),\n}).refine(\n (data) => data.connectionString || (data.host && data.database && data.user),\n { message: 'Either connectionString or host+database+user is required' }\n);\n\nconst RedisConfigSchema = z.object({\n host: z.string(),\n port: z.number().optional(),\n password: z.string().optional(),\n db: z.number().optional(),\n keyPrefix: z.string().optional(),\n});\n\nconst MongoDBConfigSchema = z.object({\n url: z.string(),\n database: z.string(),\n useUnifiedTopology: z.boolean().optional(),\n});\n\nconst LevelDBConfigSchema = z.object({\n location: z.string(),\n});\n\nexport const PersistenceConfigSchema = z.object({\n type: z.enum(['memory', 'postgres', 'redis', 'mongodb', 'sqlite', 'leveldb']),\n sqlite: SQLiteConfigSchema.optional(),\n postgres: PostgresConfigSchema.optional(),\n redis: RedisConfigSchema.optional(),\n mongodb: MongoDBConfigSchema.optional(),\n leveldb: LevelDBConfigSchema.optional(),\n autoSaveIntervalMs: z.number().int().positive().optional(),\n});\n\nexport const BlockchainConfigSchema = z.object({\n rpcUrl: z.string().url(),\n privateKey: z.string().regex(/^0x[a-fA-F0-9]{64}$/, 'Invalid private key format').optional(),\n entryFee: z.number().nonnegative().optional(),\n requireMembership: z.boolean().optional(),\n enforceOnChainValidation: z.boolean().optional(),\n agentRegistryAddress: z.string().optional(),\n membershipContractAddress: z.string().optional(),\n worldTokenAddress: z.string().optional(),\n chainId: z.number().int().optional(),\n});\n\nexport const TokenConfigSchema = z.object({\n deploy: z.boolean(),\n name: z.string().optional(),\n symbol: z.string().optional(),\n initialSupply: z.number().positive().optional(),\n decimals: z.number().int().min(0).max(18).optional(),\n});\n\nexport const WorldConfigSchema = z.object({\n name: z.string().min(1, 'World name is required'),\n description: z.string().optional(),\n type: z.string().optional(),\n \n server: z.object({\n port: z.number().int().min(1).max(65535),\n host: z.string(),\n }),\n \n a2a: z.object({\n baseUrl: z.string().url(),\n pushNotifications: z.boolean().optional(),\n streaming: z.boolean().optional(),\n }).optional(),\n \n admission: AdmissionRulesSchema,\n \n simulation: z.object({\n tickIntervalMs: z.number().int().positive().optional(),\n maxTicks: z.number().int().positive().optional(),\n autoStart: z.boolean().optional(),\n }).optional(),\n \n persistence: PersistenceConfigSchema.optional(),\n blockchain: BlockchainConfigSchema.optional(),\n token: TokenConfigSchema.optional(),\n \n rules: z.array(z.any()).optional(),\n agentUrls: z.array(z.string().url()).optional(),\n\n actions: z.array(z.object({\n name: z.string().min(1),\n description: z.string(),\n parameters: z.record(z.object({\n type: z.enum(['string', 'number', 'boolean', 'object']),\n required: z.boolean().optional(),\n description: z.string().optional(),\n })).optional(),\n })).optional(),\n\n orchestration: z.object({\n broadcastOnTick: z.boolean().optional(),\n tickTimeout: z.number().int().positive().optional(),\n promptTemplate: z.string().optional(),\n }).optional(),\n});\n\n/**\n * Validate world configuration\n */\nexport function validateWorldConfig(config: unknown): void {\n try {\n WorldConfigSchema.parse(config);\n } catch (error) {\n if (error instanceof z.ZodError) {\n const messages = error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Invalid world configuration: ${messages}`);\n }\n throw error;\n }\n}\n\n/**\n * Validate world configuration and return result\n */\nexport function isValidWorldConfig(config: unknown): boolean {\n try {\n WorldConfigSchema.parse(config);\n return true;\n } catch {\n return false;\n }\n}\n","import type { PersistenceAdapter } from '../PersistenceAdapter.js';\nimport type {\n WorldStateSnapshot,\n WorldEvent,\n AgentProfile,\n EventFilter,\n} from '../../config/types.js';\n\n/**\n * ============================================================================\n * IN-MEMORY PERSISTENCE ADAPTER\n * ============================================================================\n * \n * Simple in-memory persistence for testing and development.\n * No external dependencies - works on any Node version.\n * \n * WARNING: All data is lost when process exits.\n * \n * Use Case: Testing, development, temporary worlds\n */\n\nexport class InMemoryAdapter implements PersistenceAdapter {\n private state: WorldStateSnapshot | null = null;\n private events: WorldEvent[] = [];\n private agents: Map<string, AgentProfile> = new Map();\n \n async connect(): Promise<void> {\n // No-op for in-memory\n }\n \n async saveState(state: WorldStateSnapshot): Promise<void> {\n this.state = { ...state };\n }\n \n async loadState(): Promise<WorldStateSnapshot | null> {\n return this.state ? { ...this.state } : null;\n }\n \n async saveEvent(event: WorldEvent): Promise<void> {\n this.events.push({ ...event });\n }\n \n async getEvents(filter?: EventFilter): Promise<WorldEvent[]> {\n let filtered = [...this.events];\n \n if (filter?.type) {\n filtered = filtered.filter(e => e.type === filter.type);\n }\n \n if (filter?.agentUrl) {\n filtered = filtered.filter(e => e.agentUrl === filter.agentUrl);\n }\n \n if (filter?.fromTimestamp) {\n filtered = filtered.filter(e => e.timestamp >= filter.fromTimestamp!);\n }\n \n if (filter?.toTimestamp) {\n filtered = filtered.filter(e => e.timestamp <= filter.toTimestamp!);\n }\n \n // Sort by timestamp descending\n filtered.sort((a, b) => b.timestamp - a.timestamp);\n \n if (filter?.limit) {\n filtered = filtered.slice(0, filter.limit);\n }\n \n return filtered;\n }\n \n async saveAgent(profile: AgentProfile): Promise<void> {\n this.agents.set(profile.url, { ...profile });\n }\n \n async removeAgent(agentUrl: string): Promise<void> {\n this.agents.delete(agentUrl);\n }\n \n async getAgents(): Promise<AgentProfile[]> {\n return Array.from(this.agents.values()).map(a => ({ ...a }));\n }\n \n async getAgent(agentUrl: string): Promise<AgentProfile | null> {\n const agent = this.agents.get(agentUrl);\n return agent ? { ...agent } : null;\n }\n \n async disconnect(): Promise<void> {\n // No-op for in-memory\n }\n \n async healthCheck(): Promise<boolean> {\n return true;\n }\n \n async clear(): Promise<void> {\n this.state = null;\n this.events = [];\n this.agents.clear();\n }\n}\n","import type { PersistenceAdapter } from './PersistenceAdapter.js';\nimport type { PersistenceConfig } from '../config/types.js';\nimport { InMemoryAdapter } from './adapters/InMemoryAdapter.js';\n\n/**\n * ============================================================================\n * PERSISTENCE FACTORY\n * ============================================================================\n * \n * Creates the appropriate persistence adapter based on configuration.\n * Uses dynamic import() for optional dependencies to avoid requiring all databases\n * to be installed. Only the adapter for the configured persistence type is loaded.\n */\n\nexport async function createPersistence(config: PersistenceConfig): Promise<PersistenceAdapter> {\n switch (config.type) {\n case 'memory':\n return new InMemoryAdapter();\n \n case 'sqlite':\n return createSQLiteAdapter(config.sqlite || { filename: './world.db' });\n \n case 'postgres':\n if (!config.postgres) {\n throw new Error('PostgreSQL configuration is required');\n }\n return createPostgresAdapter(config.postgres);\n \n case 'redis':\n if (!config.redis) {\n throw new Error('Redis configuration is required');\n }\n return createRedisAdapter(config.redis);\n \n case 'mongodb':\n if (!config.mongodb) {\n throw new Error('MongoDB configuration is required');\n }\n return createMongoAdapter(config.mongodb);\n \n case 'leveldb':\n if (!config.leveldb) {\n throw new Error('LevelDB configuration is required');\n }\n return createLevelDBAdapter(config.leveldb);\n \n default:\n throw new Error(`Unknown persistence type: ${(config as any).type}`);\n }\n}\n\n/**\n * Lazy-load SQLite adapter via dynamic import\n */\nasync function createSQLiteAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n const Database = (await import('better-sqlite3')).default;\n \n // Inline adapter that uses the dynamically-imported Database\n return new (class implements PersistenceAdapter {\n private db!: any;\n \n async connect(): Promise<void> {\n // Ensure the parent directory exists\n const path = await import('path');\n const fs = await import('fs');\n const dir = path.dirname(config.filename);\n if (dir && dir !== '.') {\n fs.mkdirSync(dir, { recursive: true });\n }\n this.db = new Database(config.filename);\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS world_state (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n phase TEXT NOT NULL,\n tick INTEGER NOT NULL,\n round INTEGER NOT NULL,\n timestamp INTEGER NOT NULL,\n metadata TEXT\n );\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n agent_url TEXT,\n timestamp INTEGER NOT NULL,\n data TEXT\n );\n CREATE TABLE IF NOT EXISTS agents (\n url TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n protocol_version TEXT NOT NULL,\n skills TEXT NOT NULL,\n capabilities TEXT NOT NULL,\n joined_at INTEGER NOT NULL,\n role TEXT,\n metadata TEXT,\n wallet_address TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_events_type ON events(type);\n CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\n CREATE INDEX IF NOT EXISTS idx_events_agent ON events(agent_url);\n `);\n }\n\n async saveState(state: any): Promise<void> {\n const stmt = this.db.prepare(`INSERT OR REPLACE INTO world_state (id, phase, tick, round, timestamp, metadata) VALUES (1, ?, ?, ?, ?, ?)`);\n stmt.run(state.phase, state.tick, state.round, state.timestamp, JSON.stringify(state.metadata));\n }\n\n async loadState(): Promise<any> {\n const stmt = this.db.prepare('SELECT * FROM world_state WHERE id = 1');\n const row = stmt.get() as any;\n if (!row) return null;\n return { phase: row.phase, tick: row.tick, round: row.round, timestamp: row.timestamp, metadata: JSON.parse(row.metadata || '{}') };\n }\n\n async saveEvent(event: any): Promise<void> {\n const stmt = this.db.prepare(`INSERT INTO events (id, type, agent_url, timestamp, data) VALUES (?, ?, ?, ?, ?)`);\n stmt.run(event.id, event.type, event.agentUrl || null, event.timestamp, JSON.stringify(event.data || {}));\n }\n\n async getEvents(filter?: any): Promise<any[]> {\n let query = 'SELECT * FROM events WHERE 1=1';\n const params: any[] = [];\n if (filter?.type) { query += ' AND type = ?'; params.push(filter.type); }\n if (filter?.agentUrl) { query += ' AND agent_url = ?'; params.push(filter.agentUrl); }\n if (filter?.fromTimestamp) { query += ' AND timestamp >= ?'; params.push(filter.fromTimestamp); }\n if (filter?.toTimestamp) { query += ' AND timestamp <= ?'; params.push(filter.toTimestamp); }\n query += ' ORDER BY timestamp DESC';\n if (filter?.limit) { query += ' LIMIT ?'; params.push(filter.limit); }\n const stmt = this.db.prepare(query);\n const rows = stmt.all(...params) as any[];\n return rows.map(row => ({ id: row.id, type: row.type, timestamp: row.timestamp, agentUrl: row.agent_url || undefined, data: JSON.parse(row.data || '{}') }));\n }\n\n async saveAgent(profile: any): Promise<void> {\n const stmt = this.db.prepare(`INSERT OR REPLACE INTO agents (url, name, protocol_version, skills, capabilities, joined_at, role, metadata, wallet_address) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`);\n stmt.run(profile.url, profile.name, profile.protocolVersion, JSON.stringify(profile.skills), JSON.stringify(profile.capabilities), profile.joinedAt, profile.role || null, JSON.stringify(profile.metadata || {}), profile.walletAddress || null);\n }\n\n async removeAgent(agentUrl: string): Promise<void> {\n this.db.prepare('DELETE FROM agents WHERE url = ?').run(agentUrl);\n }\n\n async getAgents(): Promise<any[]> {\n const rows = this.db.prepare('SELECT * FROM agents ORDER BY joined_at ASC').all() as any[];\n return rows.map(row => ({ url: row.url, name: row.name, protocolVersion: row.protocol_version, skills: JSON.parse(row.skills), capabilities: JSON.parse(row.capabilities), joinedAt: row.joined_at, role: row.role || undefined, metadata: JSON.parse(row.metadata || '{}'), walletAddress: row.wallet_address || undefined }));\n }\n\n async getAgent(agentUrl: string): Promise<any> {\n const row = this.db.prepare('SELECT * FROM agents WHERE url = ?').get(agentUrl) as any;\n if (!row) return null;\n return { url: row.url, name: row.name, protocolVersion: row.protocol_version, skills: JSON.parse(row.skills), capabilities: JSON.parse(row.capabilities), joinedAt: row.joined_at, role: row.role || undefined, metadata: JSON.parse(row.metadata || '{}'), walletAddress: row.wallet_address || undefined };\n }\n\n async disconnect(): Promise<void> { this.db.close(); }\n async healthCheck(): Promise<boolean> { try { this.db.prepare('SELECT 1').get(); return true; } catch { return false; } }\n async clear(): Promise<void> { this.db.exec('DELETE FROM world_state; DELETE FROM events; DELETE FROM agents;'); }\n })();\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'SQLite adapter requires better-sqlite3. Install it with: npm install better-sqlite3'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load PostgreSQL adapter via dynamic import\n */\nasync function createPostgresAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n const pg = await import('pg');\n const Pool = pg.default?.Pool || pg.Pool;\n const { PostgresAdapter } = await import('./adapters/PostgresAdapter.js');\n return new PostgresAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'PostgreSQL adapter requires pg. Install it with: npm install pg'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load Redis adapter via dynamic import\n */\nasync function createRedisAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n await import('ioredis');\n const { RedisAdapter } = await import('./adapters/RedisAdapter.js');\n return new RedisAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'Redis adapter requires ioredis. Install it with: npm install ioredis'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load MongoDB adapter via dynamic import\n */\nasync function createMongoAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n // @ts-ignore - mongodb is an optional peer dependency\n await import('mongodb');\n const { MongoAdapter } = await import('./adapters/MongoAdapter.js');\n return new MongoAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'MongoDB adapter requires mongodb. Install it with: npm install mongodb'\n );\n }\n throw error;\n }\n}\n\n/**\n * Lazy-load LevelDB adapter via dynamic import\n */\nasync function createLevelDBAdapter(config: any): Promise<PersistenceAdapter> {\n try {\n // @ts-ignore - level is an optional peer dependency\n await import('level');\n const { LevelDBAdapter } = await import('./adapters/LevelDBAdapter.js');\n return new LevelDBAdapter(config);\n } catch (error: any) {\n if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {\n throw new Error(\n 'LevelDB adapter requires level. Install it with: npm install level'\n );\n }\n throw error;\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport type {\n WorldConfig,\n WorldPhase,\n WorldStateSnapshot,\n WorldEvent,\n AgentProfile,\n} from '../config/types.js';\nimport { validateWorldConfig } from '../config/validator.js';\nimport type { PersistenceAdapter } from '../persistence/PersistenceAdapter.js';\nimport { createPersistence } from '../persistence/PersistenceFactory.js';\nimport { CardFetcher } from '../discovery/CardFetcher.js';\nimport { AgentEvaluator } from '../discovery/AgentEvaluator.js';\nimport { BlockchainClient } from '../blockchain/BlockchainClient.js';\nimport { WorldA2AClient } from '../a2a/WorldA2AClient.js';\nimport { WorldActionsRegistry } from './WorldActions.js';\nimport { TickOrchestrator } from './TickOrchestrator.js';\nimport { MessageRouter } from '../a2a/MessageRouter.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('World');\n\n/**\n * ============================================================================\n * WORLD ENGINE\n * ============================================================================\n * \n * Core world runtime managing:\n * - Agent discovery and admission\n * - World state and lifecycle\n * - Persistence and event logging\n * - Simulation ticks (if enabled)\n * - Rule enforcement\n */\n\nexport class World {\n private state: WorldStateSnapshot;\n private agents: Map<string, AgentProfile>;\n private persistence: PersistenceAdapter | null = null;\n private blockchainClient: BlockchainClient | null = null;\n private cardFetcher: CardFetcher;\n private evaluator: AgentEvaluator;\n private tickInterval: NodeJS.Timeout | null = null;\n private autoSaveInterval: NodeJS.Timeout | null = null;\n\n // Agent-World bridge components\n private a2aClient: WorldA2AClient;\n private actionsRegistry: WorldActionsRegistry;\n private orchestrator: TickOrchestrator;\n private messageRouter: MessageRouter;\n\n constructor(public readonly config: WorldConfig) {\n // Validate configuration\n validateWorldConfig(config);\n\n // Initialize state\n this.state = {\n phase: 'idle',\n tick: 0,\n round: 0,\n timestamp: Date.now(),\n metadata: {},\n };\n\n this.agents = new Map();\n this.cardFetcher = new CardFetcher();\n this.evaluator = new AgentEvaluator(config.admission);\n\n // Initialize bridge components\n this.a2aClient = new WorldA2AClient();\n this.actionsRegistry = new WorldActionsRegistry();\n this.orchestrator = new TickOrchestrator(\n this.a2aClient,\n this.actionsRegistry,\n config.rules || [],\n config.orchestration\n );\n this.messageRouter = new MessageRouter(\n this.a2aClient,\n () => this.getAgents()\n );\n\n // Register world-defined actions\n if (config.actions && config.actions.length > 0) {\n this.actionsRegistry.registerAll(config.actions);\n logger.info(`Registered ${config.actions.length} world actions`);\n }\n\n logger.info(`World \"${config.name}\" created`, {\n type: config.type || 'generic',\n maxAgents: config.admission.maxAgents,\n orchestration: !!config.orchestration?.broadcastOnTick,\n });\n }\n \n /**\n * Initialize the world (connect persistence, restore state, discover agents)\n */\n async init(): Promise<void> {\n logger.info('Initializing world...');\n this.setState('initializing');\n \n try {\n // 1. Connect to persistence backend\n if (this.config.persistence) {\n logger.info(`Connecting to persistence backend: ${this.config.persistence.type}`);\n this.persistence = await createPersistence(this.config.persistence);\n await this.persistence.connect();\n \n // Try to restore state from persistence\n const savedState = await this.persistence.loadState();\n if (savedState) {\n this.state = savedState;\n logger.info('Restored world state from persistence', {\n phase: savedState.phase,\n tick: savedState.tick,\n });\n \n // Restore agents\n const savedAgents = await this.persistence.getAgents();\n for (const agent of savedAgents) {\n this.agents.set(agent.url, agent);\n }\n \n logger.info(`Restored ${savedAgents.length} agents from persistence`);\n }\n }\n \n // 2. Initialize blockchain client if configured\n if (this.config.blockchain) {\n logger.info('Initializing blockchain client...');\n this.blockchainClient = new BlockchainClient(this.config.blockchain);\n await this.blockchainClient.init();\n }\n \n // 3. Discover pre-configured agents\n if (this.config.agentUrls && this.config.agentUrls.length > 0) {\n logger.info(`Discovering ${this.config.agentUrls.length} pre-configured agents...`);\n \n const results = await this.cardFetcher.fetchCards(this.config.agentUrls);\n \n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (result.success && result.card) {\n // Auto-admit pre-configured agents\n try {\n await this.admitAgent(result.card);\n } catch (error: any) {\n logger.warn(`Failed to admit pre-configured agent:`, error.message);\n }\n }\n }\n }\n \n // 3. Start auto-save if persistence enabled\n if (this.persistence) {\n this.startAutoSave();\n }\n \n this.setState('ready');\n logger.info('World initialized successfully', {\n agents: this.agents.size,\n persistence: this.config.persistence?.type || 'none',\n });\n } catch (error: any) {\n logger.error('Failed to initialize world:', error);\n this.setState('failed');\n throw error;\n }\n }\n \n /**\n * Start the world simulation\n */\n async start(): Promise<void> {\n if (this.state.phase === 'running') {\n logger.warn('World is already running');\n return;\n }\n \n logger.info('Starting world simulation...');\n this.setState('running');\n \n await this.logEvent({\n id: uuidv4(),\n type: 'world_started',\n timestamp: Date.now(),\n });\n \n // Start tick interval if simulation is enabled\n if (this.config.simulation?.tickIntervalMs) {\n this.startTicking();\n }\n }\n \n /**\n * Stop the world simulation\n */\n async stop(): Promise<void> {\n logger.info('Stopping world...');\n this.setState('stopped');\n \n // Stop ticking\n if (this.tickInterval) {\n clearInterval(this.tickInterval);\n this.tickInterval = null;\n }\n \n // Stop auto-save\n if (this.autoSaveInterval) {\n clearInterval(this.autoSaveInterval);\n this.autoSaveInterval = null;\n }\n \n // Final save\n if (this.persistence) {\n await this.persistence.saveState(this.state);\n }\n \n await this.logEvent({\n id: uuidv4(),\n type: 'world_stopped',\n timestamp: Date.now(),\n });\n \n logger.info('World stopped');\n }\n \n /**\n * Admit an agent to the world\n */\n async admitAgent(card: any, walletAddress?: string): Promise<void> {\n const decision = await this.evaluator.evaluate(card, this.agents.size, walletAddress);\n \n if (!decision.admitted) {\n throw new Error(`Agent admission denied: ${decision.reason}`);\n }\n \n // Optional: Validate agent on-chain\n if (this.blockchainClient && this.config.blockchain?.enforceOnChainValidation && walletAddress) {\n const isValid = await this.blockchainClient.validateAgent(walletAddress);\n if (!isValid) {\n throw new Error('Agent not registered in on-chain AgentRegistry');\n }\n logger.info(`Agent validated on-chain: ${card.name}`);\n }\n \n // Optional: Mint membership NFT\n if (this.blockchainClient && this.config.blockchain?.requireMembership && walletAddress) {\n // Check if agent already has membership\n const hasMembership = await this.blockchainClient.hasMembership(walletAddress);\n \n if (!hasMembership) {\n logger.info(`Minting membership NFT for agent: ${card.name}`);\n await this.blockchainClient.mintMembership(walletAddress);\n } else {\n logger.info(`Agent already has membership: ${card.name}`);\n }\n }\n \n const profile: AgentProfile = {\n url: card.url,\n name: card.name,\n protocolVersion: card.protocolVersion,\n skills: card.skills,\n capabilities: {\n streaming: card.capabilities.streaming ?? false,\n pushNotifications: card.capabilities.pushNotifications ?? false,\n stateTransitionHistory: card.capabilities.stateTransitionHistory,\n },\n joinedAt: Date.now(),\n role: decision.role,\n metadata: decision.metadata,\n walletAddress,\n };\n \n this.agents.set(profile.url, profile);\n\n // Add agent to A2A client pool for tick broadcasting\n this.a2aClient.addAgent(profile.url);\n\n if (this.persistence) {\n await this.persistence.saveAgent(profile);\n }\n\n await this.logEvent({\n id: uuidv4(),\n type: 'agent_joined',\n timestamp: Date.now(),\n agentUrl: profile.url,\n data: { name: profile.name, role: profile.role },\n });\n\n logger.info(`Agent admitted: ${profile.name}`, {\n role: profile.role,\n totalAgents: this.agents.size,\n });\n }\n \n /**\n * Remove an agent from the world\n */\n async removeAgent(agentUrl: string): Promise<void> {\n const agent = this.agents.get(agentUrl);\n if (!agent) {\n throw new Error(`Agent not found: ${agentUrl}`);\n }\n \n this.agents.delete(agentUrl);\n\n // Remove from A2A client pool\n this.a2aClient.removeAgent(agentUrl);\n\n if (this.persistence) {\n await this.persistence.removeAgent(agentUrl);\n }\n \n await this.logEvent({\n id: uuidv4(),\n type: 'agent_left',\n timestamp: Date.now(),\n agentUrl,\n data: { name: agent.name },\n });\n \n logger.info(`Agent removed: ${agent.name}`, {\n totalAgents: this.agents.size,\n });\n }\n \n /**\n * Get all agents in the world\n */\n getAgents(): AgentProfile[] {\n return Array.from(this.agents.values());\n }\n \n /**\n * Get current world state\n */\n getState(): WorldStateSnapshot {\n return { ...this.state };\n }\n\n /**\n * Get the message router (for agent-to-agent communication via server)\n */\n getMessageRouter(): MessageRouter {\n return this.messageRouter;\n }\n\n /**\n * Get the actions registry\n */\n getActionsRegistry(): WorldActionsRegistry {\n return this.actionsRegistry;\n }\n \n /**\n * Log an event\n */\n private async logEvent(event: WorldEvent): Promise<void> {\n if (this.persistence) {\n await this.persistence.saveEvent(event);\n }\n }\n \n /**\n * Set world phase\n */\n private setState(phase: WorldPhase): void {\n this.state.phase = phase;\n this.state.timestamp = Date.now();\n }\n \n /**\n * Start auto-save interval\n */\n private startAutoSave(): void {\n const interval = this.config.persistence?.autoSaveIntervalMs || 10000;\n \n this.autoSaveInterval = setInterval(async () => {\n if (this.persistence) {\n await this.persistence.saveState(this.state);\n logger.debug('Auto-saved world state');\n }\n }, interval);\n \n logger.info(`Auto-save enabled (interval: ${interval}ms)`);\n }\n \n /**\n * Start simulation ticking\n */\n private startTicking(): void {\n const interval = this.config.simulation!.tickIntervalMs!;\n\n this.tickInterval = setInterval(async () => {\n this.state.tick++;\n this.state.timestamp = Date.now();\n\n // Execute orchestrated tick (broadcast to agents, collect responses, validate)\n try {\n const tickResult = await this.orchestrator.executeTick(\n this.state.tick,\n this.getAgents(),\n this.state,\n this.config.name\n );\n\n // Apply state updates from agent actions\n if (tickResult.stateUpdates && Object.keys(tickResult.stateUpdates).length > 0) {\n Object.assign(this.state.metadata, tickResult.stateUpdates);\n }\n\n // Log all events from the tick\n for (const event of tickResult.events) {\n await this.logEvent(event);\n }\n } catch (error: any) {\n logger.error(`Tick ${this.state.tick} orchestration error:`, error);\n await this.logEvent({\n id: uuidv4(),\n type: 'tick_error',\n timestamp: Date.now(),\n data: { tick: this.state.tick, error: error?.message || String(error) },\n });\n }\n\n logger.debug(`Tick ${this.state.tick}`);\n\n // Check max ticks\n if (this.config.simulation?.maxTicks && this.state.tick >= this.config.simulation.maxTicks) {\n logger.info('Max ticks reached, stopping world');\n await this.stop();\n }\n }, interval);\n\n logger.info(`Simulation ticking enabled (interval: ${interval}ms)`);\n }\n}\n","import type { AgentCard } from '@a2a-js/sdk';\nimport type { AgentProfile, AdmissionRules, AdmissionDecision } from '../config/types.js';\nimport { profileFromCard } from '../config/types.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('AgentEvaluator');\n\n/**\n * ============================================================================\n * AGENT EVALUATOR\n * ============================================================================\n * \n * Evaluates whether an agent should be admitted to the world based on rules.\n * \n * Evaluation criteria:\n * - Max agents limit\n * - Required skills (agent must have ALL)\n * - Required tags (agent must have AT LEAST ONE)\n * - Minimum protocol version\n * - Custom evaluator function\n */\n\nexport class AgentEvaluator {\n constructor(private rules: AdmissionRules) {}\n \n /**\n * Evaluate whether an agent should be admitted.\n * \n * @param card Agent's A2A card\n * @param currentAgentCount Current number of agents in world\n * @param walletAddress Optional wallet address for blockchain membership\n * @returns Admission decision\n */\n async evaluate(\n card: AgentCard,\n currentAgentCount: number,\n walletAddress?: string\n ): Promise<AdmissionDecision> {\n logger.debug(`Evaluating agent: ${card.name}`, {\n currentAgents: currentAgentCount,\n maxAgents: this.rules.maxAgents,\n });\n \n // Check max agents limit\n if (this.rules.maxAgents && currentAgentCount >= this.rules.maxAgents) {\n logger.info(`Agent ${card.name} rejected: world is full`, {\n current: currentAgentCount,\n max: this.rules.maxAgents,\n });\n \n return {\n admitted: false,\n reason: `World is full (${this.rules.maxAgents} agents maximum)`,\n };\n }\n \n // Check protocol version\n if (this.rules.minProtocolVersion) {\n if (!this.meetsProtocolVersion(card.protocolVersion, this.rules.minProtocolVersion)) {\n logger.info(`Agent ${card.name} rejected: protocol version too old`, {\n agent: card.protocolVersion,\n required: this.rules.minProtocolVersion,\n });\n \n return {\n admitted: false,\n reason: `Protocol version ${card.protocolVersion} is below minimum ${this.rules.minProtocolVersion}`,\n };\n }\n }\n \n // Check required skills (agent must have ALL)\n if (this.rules.requiredSkills && this.rules.requiredSkills.length > 0) {\n const agentSkillIds = card.skills.map(s => s.id.toLowerCase());\n const missingSkills = this.rules.requiredSkills.filter(\n required => !agentSkillIds.includes(required.toLowerCase())\n );\n \n if (missingSkills.length > 0) {\n logger.info(`Agent ${card.name} rejected: missing required skills`, {\n missing: missingSkills,\n });\n \n return {\n admitted: false,\n reason: `Missing required skills: ${missingSkills.join(', ')}`,\n };\n }\n }\n \n // Check required tags (agent must have AT LEAST ONE)\n if (this.rules.requiredTags && this.rules.requiredTags.length > 0) {\n const agentTags = card.skills.flatMap(s => s.tags || []).map(t => t.toLowerCase());\n const hasRequiredTag = this.rules.requiredTags.some(\n required => agentTags.includes(required.toLowerCase())\n );\n \n if (!hasRequiredTag) {\n logger.info(`Agent ${card.name} rejected: no matching tags`, {\n required: this.rules.requiredTags,\n });\n \n return {\n admitted: false,\n reason: `Must have at least one of these tags: ${this.rules.requiredTags.join(', ')}`,\n };\n }\n }\n \n // Run custom evaluator if provided\n if (this.rules.customEvaluator) {\n const profile = profileFromCard(card, walletAddress);\n const customDecision = await this.rules.customEvaluator(profile);\n \n if (!customDecision.admitted) {\n logger.info(`Agent ${card.name} rejected by custom evaluator`, {\n reason: customDecision.reason,\n });\n \n return customDecision;\n }\n \n // Custom evaluator can assign roles and metadata\n if (customDecision.role || customDecision.metadata) {\n logger.debug(`Custom evaluator assigned role/metadata to ${card.name}`, {\n role: customDecision.role,\n });\n }\n \n return customDecision;\n }\n \n // All checks passed\n logger.info(`Agent ${card.name} admitted to world`);\n \n return {\n admitted: true,\n reason: 'All admission criteria met',\n };\n }\n \n /**\n * Check if agent's protocol version meets minimum requirement.\n * Simple semver comparison (major.minor).\n */\n private meetsProtocolVersion(agentVersion: string, minVersion: string): boolean {\n const parse = (v: string) => {\n const parts = v.split('.');\n return {\n major: parseInt(parts[0] || '0', 10),\n minor: parseInt(parts[1] || '0', 10),\n };\n };\n \n const agent = parse(agentVersion);\n const min = parse(minVersion);\n \n if (agent.major > min.major) return true;\n if (agent.major < min.major) return false;\n return agent.minor >= min.minor;\n }\n}\n","import { ethers } from 'ethers';\nimport type { BlockchainConfig } from '../config/types.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('BlockchainClient');\n\n// Contract ABIs (minimal interfaces)\nconst AGENT_REGISTRY_ABI = [\n 'function registerAgent(string agentUrl, string name) external',\n 'function isAgentValid(address wallet) external view returns (bool)',\n 'function getAgent(address wallet) external view returns (tuple(address walletAddress, string agentUrl, string name, uint256 registeredAt, bool isActive))',\n 'function getWalletByUrl(string agentUrl) external view returns (address)',\n 'event AgentRegistered(address indexed wallet, string agentUrl, string name)',\n];\n\nconst WORLD_MEMBERSHIP_ABI = [\n 'function mintMembership(address agent) external payable',\n 'function revokeMembership(address agent) external',\n 'function hasMembership(address agent) external view returns (bool)',\n 'function entryFee() external view returns (uint256)',\n 'function totalMembers() external view returns (uint256)',\n 'function withdrawFees() external',\n 'event MembershipMinted(address indexed agent, uint256 indexed tokenId, uint256 feePaid)',\n];\n\nconst WORLD_TOKEN_ABI = [\n 'function mint(address to, uint256 amount) external',\n 'function burn(address from, uint256 amount) external',\n 'function balanceOf(address account) external view returns (uint256)',\n 'function transfer(address to, uint256 amount) external returns (bool)',\n];\n\n/**\n * ============================================================================\n * BLOCKCHAIN CLIENT\n * ============================================================================\n * \n * Handles all blockchain interactions for the World SDK:\n * - Agent registry validation\n * - Membership NFT minting\n * - Entry fee collection\n * - World token operations\n */\n\nexport class BlockchainClient {\n private provider: ethers.JsonRpcProvider;\n private wallet: ethers.Wallet;\n private agentRegistry?: ethers.Contract;\n private membershipContract?: ethers.Contract;\n private worldToken?: ethers.Contract;\n \n constructor(private config: BlockchainConfig) {\n // Initialize provider and wallet\n this.provider = new ethers.JsonRpcProvider(config.rpcUrl);\n this.wallet = new ethers.Wallet(config.privateKey, this.provider);\n \n logger.info('Blockchain client initialized', {\n network: config.rpcUrl,\n wallet: this.wallet.address,\n });\n }\n \n /**\n * Initialize contract connections\n */\n async init(): Promise<void> {\n // Connect to AgentRegistry if address provided\n if (this.config.agentRegistryAddress) {\n this.agentRegistry = new ethers.Contract(\n this.config.agentRegistryAddress,\n AGENT_REGISTRY_ABI,\n this.wallet\n );\n logger.info('Connected to AgentRegistry', {\n address: this.config.agentRegistryAddress,\n });\n }\n \n // Connect to WorldMembership if address provided\n if (this.config.membershipContractAddress) {\n this.membershipContract = new ethers.Contract(\n this.config.membershipContractAddress,\n WORLD_MEMBERSHIP_ABI,\n this.wallet\n );\n logger.info('Connected to WorldMembership', {\n address: this.config.membershipContractAddress,\n });\n }\n \n // Connect to WorldToken if address provided\n if (this.config.worldTokenAddress) {\n this.worldToken = new ethers.Contract(\n this.config.worldTokenAddress,\n WORLD_TOKEN_ABI,\n this.wallet\n );\n logger.info('Connected to WorldToken', {\n address: this.config.worldTokenAddress,\n });\n }\n \n logger.info('Blockchain client ready');\n }\n \n /**\n * Validate agent on-chain\n * @param walletAddress Agent's wallet address\n * @returns True if agent is registered and valid\n */\n async validateAgent(walletAddress: string): Promise<boolean> {\n if (!this.agentRegistry) {\n logger.warn('AgentRegistry not configured, skipping on-chain validation');\n return true; // Skip validation if not configured\n }\n \n try {\n const isValid = await this.agentRegistry.isAgentValid(walletAddress);\n logger.debug('Agent validation result', {\n wallet: walletAddress,\n isValid,\n });\n return isValid;\n } catch (error: any) {\n logger.error('Failed to validate agent on-chain', {\n wallet: walletAddress,\n error: error.message,\n });\n return false;\n }\n }\n \n /**\n * Mint membership NFT for an agent\n * @param agentWallet Agent's wallet address\n * @returns Transaction hash\n */\n async mintMembership(agentWallet: string): Promise<string> {\n if (!this.membershipContract) {\n throw new Error('WorldMembership contract not configured');\n }\n \n try {\n // Get entry fee\n const entryFee = await this.membershipContract.entryFee();\n \n logger.info('Minting membership NFT', {\n agent: agentWallet,\n entryFee: ethers.formatEther(entryFee),\n });\n \n // Mint membership\n const tx = await this.membershipContract.mintMembership(agentWallet, {\n value: entryFee,\n });\n \n const receipt = await tx.wait();\n \n logger.info('Membership NFT minted', {\n agent: agentWallet,\n txHash: receipt.hash,\n blockNumber: receipt.blockNumber,\n });\n \n return receipt.hash;\n } catch (error: any) {\n logger.error('Failed to mint membership NFT', {\n agent: agentWallet,\n error: error.message,\n });\n throw error;\n }\n }\n \n /**\n * Check if agent has membership\n * @param agentWallet Agent's wallet address\n * @returns True if agent has membership\n */\n async hasMembership(agentWallet: string): Promise<boolean> {\n if (!this.membershipContract) {\n logger.warn('WorldMembership not configured, skipping membership check');\n return true; // Skip check if not configured\n }\n \n try {\n const hasMembership = await this.membershipContract.hasMembership(agentWallet);\n return hasMembership;\n } catch (error: any) {\n logger.error('Failed to check membership', {\n agent: agentWallet,\n error: error.message,\n });\n return false;\n }\n }\n \n /**\n * Revoke membership NFT\n * @param agentWallet Agent's wallet address\n * @returns Transaction hash\n */\n async revokeMembership(agentWallet: string): Promise<string> {\n if (!this.membershipContract) {\n throw new Error('WorldMembership contract not configured');\n }\n \n try {\n logger.info('Revoking membership', { agent: agentWallet });\n \n const tx = await this.membershipContract.revokeMembership(agentWallet);\n const receipt = await tx.wait();\n \n logger.info('Membership revoked', {\n agent: agentWallet,\n txHash: receipt.hash,\n });\n \n return receipt.hash;\n } catch (error: any) {\n logger.error('Failed to revoke membership', {\n agent: agentWallet,\n error: error.message,\n });\n throw error;\n }\n }\n \n /**\n * Get total number of members\n */\n async getTotalMembers(): Promise<number> {\n if (!this.membershipContract) {\n return 0;\n }\n \n try {\n const total = await this.membershipContract.totalMembers();\n return Number(total);\n } catch (error: any) {\n logger.error('Failed to get total members', { error: error.message });\n return 0;\n }\n }\n \n /**\n * Withdraw collected entry fees (world owner only)\n */\n async withdrawFees(): Promise<string> {\n if (!this.membershipContract) {\n throw new Error('WorldMembership contract not configured');\n }\n \n try {\n logger.info('Withdrawing entry fees');\n \n const tx = await this.membershipContract.withdrawFees();\n const receipt = await tx.wait();\n \n logger.info('Fees withdrawn', {\n txHash: receipt.hash,\n blockNumber: receipt.blockNumber,\n });\n \n return receipt.hash;\n } catch (error: any) {\n logger.error('Failed to withdraw fees', { error: error.message });\n throw error;\n }\n }\n \n /**\n * Get world owner's wallet address\n */\n getWalletAddress(): string {\n return this.wallet.address;\n }\n \n /**\n * Get entry fee in MON\n */\n async getEntryFee(): Promise<string> {\n if (!this.membershipContract) {\n return '0';\n }\n \n try {\n const fee = await this.membershipContract.entryFee();\n return ethers.formatEther(fee);\n } catch (error: any) {\n logger.error('Failed to get entry fee', { error: error.message });\n return '0';\n }\n }\n}\n","import { A2AClient, type A2AMessageResponse } from '@moltium/core';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('WorldA2AClient');\n\n/**\n * ============================================================================\n * WORLD A2A CLIENT\n * ============================================================================\n *\n * Manages a pool of A2A clients for all admitted agents.\n * Used by the TickOrchestrator to broadcast tick context and collect responses,\n * and by the MessageRouter for agent-to-agent communication.\n */\n\nexport class WorldA2AClient {\n private clients: Map<string, A2AClient> = new Map();\n\n /**\n * Add an agent to the client pool\n */\n addAgent(agentUrl: string): void {\n // Extract base URL (protocol + host + port) — the A2A SDK client\n // appends /.well-known/agent.json to discover the agent card\n const baseUrl = this.extractBaseUrl(agentUrl);\n\n if (this.clients.has(baseUrl)) {\n logger.debug(`Agent already in client pool: ${baseUrl}`);\n return;\n }\n\n const client = new A2AClient({ agentUrl: baseUrl });\n this.clients.set(baseUrl, client);\n logger.info(`Added agent to A2A client pool: ${baseUrl}`);\n }\n\n /**\n * Remove an agent from the client pool\n */\n removeAgent(agentUrl: string): void {\n this.clients.delete(agentUrl);\n logger.info(`Removed agent from A2A client pool: ${agentUrl}`);\n }\n\n /**\n * Send an A2A message to a specific agent\n */\n async sendToAgent(\n agentUrl: string,\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<A2AMessageResponse> {\n const client = this.clients.get(agentUrl);\n if (!client) {\n return {\n success: false,\n error: `Agent not in client pool: ${agentUrl}`,\n agentUrl,\n };\n }\n\n try {\n const response = await client.sendMessage({ text: message, metadata });\n logger.debug(`A2A message sent to ${agentUrl}`, { success: response.success });\n return response;\n } catch (error: any) {\n logger.error(`Failed to send A2A message to ${agentUrl}:`, error);\n return {\n success: false,\n error: error?.message || String(error),\n agentUrl,\n };\n }\n }\n\n /**\n * Broadcast an A2A message to all agents in the pool\n */\n async broadcastToAll(\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<Map<string, A2AMessageResponse>> {\n const results = new Map<string, A2AMessageResponse>();\n\n const promises = Array.from(this.clients.entries()).map(\n async ([agentUrl]) => {\n const response = await this.sendToAgent(agentUrl, message, metadata);\n results.set(agentUrl, response);\n }\n );\n\n await Promise.allSettled(promises);\n\n logger.info(`Broadcast complete: ${results.size} agents`, {\n succeeded: Array.from(results.values()).filter(r => r.success).length,\n failed: Array.from(results.values()).filter(r => !r.success).length,\n });\n\n return results;\n }\n\n /**\n * Get the number of agents in the pool\n */\n get size(): number {\n return this.clients.size;\n }\n\n /**\n * Check if an agent is in the pool\n */\n has(agentUrl: string): boolean {\n return this.clients.has(agentUrl);\n }\n\n /**\n * Get all agent URLs in the pool\n */\n getAgentUrls(): string[] {\n return Array.from(this.clients.keys());\n }\n\n /**\n * Extract base URL (protocol://host:port) from a full URL\n */\n private extractBaseUrl(url: string): string {\n try {\n const parsed = new URL(url);\n return `${parsed.protocol}//${parsed.host}`;\n } catch {\n return url;\n }\n }\n}\n","import { createLogger } from '../logger.js';\n\nconst logger = createLogger('WorldActions');\n\n/**\n * ============================================================================\n * WORLD ACTION DEFINITIONS\n * ============================================================================\n *\n * Worlds define what actions agents can take. These are sent as context\n * during tick broadcasts so agents know their available options.\n */\n\nexport interface WorldAction {\n /** Action name (unique identifier) */\n name: string;\n\n /** Human-readable description */\n description: string;\n\n /** Parameter definitions */\n parameters?: Record<string, WorldActionParam>;\n}\n\nexport interface WorldActionParam {\n type: 'string' | 'number' | 'boolean' | 'object';\n required?: boolean;\n description?: string;\n}\n\n/**\n * Registry for world-defined actions.\n * Agents receive the registered actions as available options during tick broadcasts.\n */\nexport class WorldActionsRegistry {\n private actions: Map<string, WorldAction> = new Map();\n\n /**\n * Register a world action\n */\n register(action: WorldAction): void {\n if (this.actions.has(action.name)) {\n logger.warn(`Overwriting existing action: ${action.name}`);\n }\n this.actions.set(action.name, action);\n logger.debug(`Registered world action: ${action.name}`);\n }\n\n /**\n * Register multiple actions at once\n */\n registerAll(actions: WorldAction[]): void {\n for (const action of actions) {\n this.register(action);\n }\n }\n\n /**\n * Get all registered actions\n */\n getAll(): WorldAction[] {\n return Array.from(this.actions.values());\n }\n\n /**\n * Get a specific action by name\n */\n get(name: string): WorldAction | undefined {\n return this.actions.get(name);\n }\n\n /**\n * Check if an action exists\n */\n has(name: string): boolean {\n return this.actions.has(name);\n }\n\n /**\n * Validate an action name and its parameters\n */\n validate(\n actionName: string,\n params: Record<string, any>\n ): { valid: boolean; error?: string } {\n const action = this.actions.get(actionName);\n if (!action) {\n return { valid: false, error: `Unknown action: ${actionName}` };\n }\n\n if (!action.parameters) {\n return { valid: true };\n }\n\n // Check required parameters\n for (const [paramName, paramDef] of Object.entries(action.parameters)) {\n if (paramDef.required && !(paramName in params)) {\n return {\n valid: false,\n error: `Missing required parameter: ${paramName} for action ${actionName}`,\n };\n }\n\n // Type check if parameter is provided\n if (paramName in params && params[paramName] !== undefined) {\n const actualType = typeof params[paramName];\n if (paramDef.type === 'object') {\n if (actualType !== 'object' || params[paramName] === null) {\n return {\n valid: false,\n error: `Parameter ${paramName} must be an object`,\n };\n }\n } else if (actualType !== paramDef.type) {\n return {\n valid: false,\n error: `Parameter ${paramName} must be of type ${paramDef.type}, got ${actualType}`,\n };\n }\n }\n }\n\n return { valid: true };\n }\n\n /**\n * Get action names as a simple list (for tick context)\n */\n getActionNames(): string[] {\n return Array.from(this.actions.keys());\n }\n\n /**\n * Get actions as a serializable summary (for tick context)\n */\n toSummary(): Array<{ name: string; description: string; parameters?: Record<string, WorldActionParam> }> {\n return this.getAll().map(a => ({\n name: a.name,\n description: a.description,\n ...(a.parameters && { parameters: a.parameters }),\n }));\n }\n}\n","import type {\n WorldRule,\n RuleContext,\n RuleViolation,\n WorldEvent,\n AgentProfile,\n WorldPhase,\n} from '../config/types.js';\nimport type { WorldActionsRegistry } from './WorldActions.js';\nimport { createLogger } from '../logger.js';\nimport { v4 as uuidv4 } from 'uuid';\n\nconst logger = createLogger('ActionProcessor');\n\n/**\n * ============================================================================\n * ACTION PROCESSOR\n * ============================================================================\n *\n * Validates agent tick responses against world rules before applying.\n * Ensures agents only execute valid, permitted actions.\n */\n\nexport interface AgentTickResponse {\n agentUrl: string;\n action?: string;\n parameters?: Record<string, any>;\n message?: string;\n error?: string;\n}\n\nexport interface ProcessResult {\n accepted: boolean;\n violations: RuleViolation[];\n stateUpdates?: Record<string, any>;\n events?: WorldEvent[];\n}\n\nexport class ActionProcessor {\n constructor(\n private rules: WorldRule[],\n private actionsRegistry: WorldActionsRegistry\n ) {}\n\n /**\n * Process an agent's tick response: validate action and check rules\n */\n async process(\n response: AgentTickResponse,\n agent: AgentProfile,\n worldContext: {\n phase: WorldPhase;\n tick: number;\n agents: Map<string, AgentProfile>;\n }\n ): Promise<ProcessResult> {\n const violations: RuleViolation[] = [];\n const events: WorldEvent[] = [];\n\n // If agent returned an error or no action, skip validation\n if (response.error || !response.action) {\n return { accepted: false, violations: [], events: [] };\n }\n\n // 1. Validate that the action exists in the registry\n const actionValidation = this.actionsRegistry.validate(\n response.action,\n response.parameters || {}\n );\n\n if (!actionValidation.valid) {\n logger.warn(`Invalid action from ${response.agentUrl}: ${actionValidation.error}`);\n violations.push({\n ruleId: '_action_validation',\n severity: 'warning',\n message: actionValidation.error!,\n agentUrl: response.agentUrl,\n action: 'warn',\n });\n return { accepted: false, violations, events: [] };\n }\n\n // 2. Run through world rules\n const ruleContext: RuleContext = {\n world: {\n phase: worldContext.phase,\n tick: worldContext.tick,\n agents: worldContext.agents,\n },\n event: {\n id: uuidv4(),\n type: 'agent_action',\n timestamp: Date.now(),\n agentUrl: response.agentUrl,\n data: {\n action: response.action,\n parameters: response.parameters,\n },\n },\n agent,\n };\n\n for (const rule of this.rules) {\n try {\n const violation = await rule.evaluate(ruleContext);\n if (violation) {\n violations.push(violation);\n logger.warn(`Rule violation: ${rule.name}`, {\n agentUrl: response.agentUrl,\n action: response.action,\n severity: violation.severity,\n });\n }\n } catch (error: any) {\n logger.error(`Rule evaluation error (${rule.name}):`, error);\n }\n }\n\n // Check for blocking violations (error or critical severity)\n const blocking = violations.filter(\n v => v.severity === 'error' || v.severity === 'critical'\n );\n\n if (blocking.length > 0) {\n return { accepted: false, violations, events: [] };\n }\n\n // 3. Action accepted — create event\n events.push({\n id: uuidv4(),\n type: 'action_executed',\n timestamp: Date.now(),\n agentUrl: response.agentUrl,\n data: {\n action: response.action,\n parameters: response.parameters,\n },\n });\n\n return {\n accepted: true,\n violations,\n stateUpdates: {\n [`lastAction_${response.agentUrl}`]: {\n action: response.action,\n parameters: response.parameters,\n tick: worldContext.tick,\n },\n },\n events,\n };\n }\n\n /**\n * Update the rules list\n */\n setRules(rules: WorldRule[]): void {\n this.rules = rules;\n }\n}\n","import type {\n AgentProfile,\n WorldStateSnapshot,\n WorldEvent,\n WorldRule,\n} from '../config/types.js';\nimport type { WorldA2AClient } from '../a2a/WorldA2AClient.js';\nimport type { WorldActionsRegistry } from './WorldActions.js';\nimport { ActionProcessor, type AgentTickResponse } from './ActionProcessor.js';\nimport { createLogger } from '../logger.js';\nimport { v4 as uuidv4 } from 'uuid';\n\nconst logger = createLogger('TickOrchestrator');\n\n/**\n * ============================================================================\n * TICK ORCHESTRATOR\n * ============================================================================\n *\n * Orchestrates the world tick loop:\n * 1. Build tick context (state, actions, agents)\n * 2. Broadcast to all agents via A2A\n * 3. Collect and parse responses\n * 4. Validate responses against rules\n * 5. Apply state updates and log events\n */\n\nexport interface TickResult {\n tick: number;\n responses: Map<string, AgentTickResponse>;\n events: WorldEvent[];\n stateUpdates: Record<string, any>;\n errors: Array<{ agentUrl: string; error: string }>;\n}\n\nexport interface OrchestrationConfig {\n /** Whether to broadcast tick context to agents (default: true) */\n broadcastOnTick?: boolean;\n\n /** Timeout for agent responses in ms (default: 10000) */\n tickTimeout?: number;\n\n /** Custom prompt template for tick broadcasts */\n promptTemplate?: string;\n}\n\nexport class TickOrchestrator {\n private actionProcessor: ActionProcessor;\n private orchestrationConfig: OrchestrationConfig;\n\n constructor(\n private a2aClient: WorldA2AClient,\n private actionsRegistry: WorldActionsRegistry,\n rules: WorldRule[],\n config?: OrchestrationConfig\n ) {\n this.actionProcessor = new ActionProcessor(rules, actionsRegistry);\n this.orchestrationConfig = {\n broadcastOnTick: config?.broadcastOnTick ?? true,\n tickTimeout: config?.tickTimeout ?? 10000,\n promptTemplate: config?.promptTemplate,\n };\n }\n\n /**\n * Execute a single world tick\n */\n async executeTick(\n tick: number,\n agents: AgentProfile[],\n state: WorldStateSnapshot,\n worldName: string\n ): Promise<TickResult> {\n const result: TickResult = {\n tick,\n responses: new Map(),\n events: [],\n stateUpdates: {},\n errors: [],\n };\n\n // If no agents or broadcasting disabled, just log the tick\n if (agents.length === 0 || !this.orchestrationConfig.broadcastOnTick) {\n logger.debug(`Tick ${tick}: no agents to broadcast to`);\n return result;\n }\n\n // 1. Build tick context message\n const tickContext = this.buildTickContext(tick, agents, state, worldName);\n const message = JSON.stringify(tickContext);\n\n logger.debug(`Tick ${tick}: broadcasting to ${agents.length} agents`);\n\n // 2. Broadcast to all agents via A2A\n const responses = await this.a2aClient.broadcastToAll(message, {\n type: 'world_tick',\n tick,\n worldName,\n });\n\n // 3. Parse and process responses\n const agentsMap = new Map<string, AgentProfile>();\n for (const agent of agents) {\n agentsMap.set(agent.url, agent);\n }\n\n for (const [agentUrl, a2aResponse] of responses) {\n // Parse the agent's response\n const tickResponse = this.parseAgentResponse(agentUrl, a2aResponse);\n result.responses.set(agentUrl, tickResponse);\n\n if (tickResponse.error) {\n result.errors.push({ agentUrl, error: tickResponse.error });\n continue;\n }\n\n // 4. Validate against rules\n const agent = agentsMap.get(agentUrl);\n if (!agent || !tickResponse.action) continue;\n\n const processResult = await this.actionProcessor.process(\n tickResponse,\n agent,\n { phase: state.phase, tick, agents: agentsMap }\n );\n\n if (processResult.accepted) {\n // Merge state updates\n if (processResult.stateUpdates) {\n Object.assign(result.stateUpdates, processResult.stateUpdates);\n }\n if (processResult.events) {\n result.events.push(...processResult.events);\n }\n }\n\n // Log violations (even for accepted actions with warnings)\n for (const violation of processResult.violations) {\n result.events.push({\n id: uuidv4(),\n type: 'rule_violation',\n timestamp: Date.now(),\n agentUrl,\n data: {\n ruleId: violation.ruleId,\n severity: violation.severity,\n message: violation.message,\n },\n });\n }\n }\n\n // 5. Log tick completion\n result.events.push({\n id: uuidv4(),\n type: 'tick',\n timestamp: Date.now(),\n data: {\n tick,\n agentsBroadcasted: agents.length,\n responsesReceived: result.responses.size,\n errorsCount: result.errors.length,\n },\n });\n\n logger.info(`Tick ${tick} complete`, {\n responses: result.responses.size,\n errors: result.errors.length,\n stateUpdates: Object.keys(result.stateUpdates).length,\n });\n\n return result;\n }\n\n /**\n * Build the tick context that gets sent to each agent\n */\n private buildTickContext(\n tick: number,\n agents: AgentProfile[],\n state: WorldStateSnapshot,\n worldName: string\n ): Record<string, any> {\n const availableActions = this.actionsRegistry.toSummary();\n\n const agentsSummary = agents.map(a => ({\n name: a.name,\n role: a.role || 'participant',\n skills: a.skills.map(s => s.id),\n }));\n\n const prompt =\n this.orchestrationConfig.promptTemplate ||\n `You are participating in world \"${worldName}\". Current tick: ${tick}. ` +\n `Choose an action from the available actions and respond with a JSON object: ` +\n `{ \"action\": \"<action_name>\", \"parameters\": { ... } }. ` +\n `You may also include a \"message\" field for free-form communication.`;\n\n return {\n type: 'world_tick',\n tick,\n worldName,\n state: {\n phase: state.phase,\n tick: state.tick,\n round: state.round,\n metadata: state.metadata,\n },\n availableActions,\n agents: agentsSummary,\n prompt,\n };\n }\n\n /**\n * Parse an A2A response into an AgentTickResponse\n */\n private parseAgentResponse(\n agentUrl: string,\n a2aResponse: { success: boolean; reply?: string; error?: string }\n ): AgentTickResponse {\n if (!a2aResponse.success) {\n return {\n agentUrl,\n error: a2aResponse.error || 'A2A communication failed',\n };\n }\n\n const reply = a2aResponse.reply;\n if (!reply) {\n return { agentUrl, message: '' };\n }\n\n // Try to parse as JSON (structured action response)\n try {\n const parsed = JSON.parse(reply);\n return {\n agentUrl,\n action: parsed.action,\n parameters: parsed.parameters || {},\n message: parsed.message,\n };\n } catch {\n // Not JSON — treat as free-form message\n return {\n agentUrl,\n message: reply,\n };\n }\n }\n\n /**\n * Update orchestration config\n */\n setConfig(config: Partial<OrchestrationConfig>): void {\n Object.assign(this.orchestrationConfig, config);\n }\n\n /**\n * Update rules on the action processor\n */\n setRules(rules: WorldRule[]): void {\n this.actionProcessor.setRules(rules);\n }\n}\n","import type { A2AMessageResponse } from '@moltium/core';\nimport type { WorldA2AClient } from './WorldA2AClient.js';\nimport type { AgentProfile } from '../config/types.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('MessageRouter');\n\n/**\n * ============================================================================\n * MESSAGE ROUTER\n * ============================================================================\n *\n * Routes agent-to-agent messages through the world hub.\n * Agents send messages to the world's /world/message endpoint,\n * and the router forwards them to the target agent(s) via A2A.\n */\n\nexport class MessageRouter {\n constructor(\n private a2aClient: WorldA2AClient,\n private getAgents: () => AgentProfile[]\n ) {}\n\n /**\n * Route a message from one agent to another\n */\n async route(\n fromAgentUrl: string,\n toAgentUrl: string,\n message: string\n ): Promise<A2AMessageResponse> {\n // Verify sender is in the world\n const agents = this.getAgents();\n const sender = agents.find(a => a.url === fromAgentUrl);\n if (!sender) {\n return {\n success: false,\n error: `Sender not in world: ${fromAgentUrl}`,\n };\n }\n\n // Verify recipient is in the world\n const recipient = agents.find(a => a.url === toAgentUrl);\n if (!recipient) {\n return {\n success: false,\n error: `Recipient not in world: ${toAgentUrl}`,\n };\n }\n\n // Wrap message with sender context\n const wrappedMessage = JSON.stringify({\n type: 'world_message',\n from: {\n url: sender.url,\n name: sender.name,\n role: sender.role,\n },\n message,\n });\n\n logger.info(`Routing message: ${sender.name} → ${recipient.name}`);\n\n return this.a2aClient.sendToAgent(toAgentUrl, wrappedMessage, {\n type: 'world_message',\n fromAgentUrl,\n });\n }\n\n /**\n * Broadcast a message from one agent to all other agents in the world\n */\n async routeToAll(\n fromAgentUrl: string,\n message: string\n ): Promise<Map<string, A2AMessageResponse>> {\n const agents = this.getAgents();\n const sender = agents.find(a => a.url === fromAgentUrl);\n if (!sender) {\n const result = new Map<string, A2AMessageResponse>();\n result.set(fromAgentUrl, {\n success: false,\n error: `Sender not in world: ${fromAgentUrl}`,\n });\n return result;\n }\n\n const wrappedMessage = JSON.stringify({\n type: 'world_broadcast',\n from: {\n url: sender.url,\n name: sender.name,\n role: sender.role,\n },\n message,\n });\n\n // Send to all agents except the sender\n const results = new Map<string, A2AMessageResponse>();\n const recipients = agents.filter(a => a.url !== fromAgentUrl);\n\n const promises = recipients.map(async (recipient) => {\n const response = await this.a2aClient.sendToAgent(\n recipient.url,\n wrappedMessage,\n { type: 'world_broadcast', fromAgentUrl }\n );\n results.set(recipient.url, response);\n });\n\n await Promise.allSettled(promises);\n\n logger.info(`Broadcast from ${sender.name} to ${recipients.length} agents`);\n return results;\n }\n}\n","import express, { type Express, type Request, type Response } from 'express';\nimport type { World } from '../engine/World.js';\nimport { createLogger } from '../logger.js';\n\nconst logger = createLogger('WorldServer');\n\n/**\n * ============================================================================\n * WORLD HTTP SERVER\n * ============================================================================\n * \n * Express server providing HTTP endpoints for:\n * - World information\n * - Agent join requests \n * - Agent list\n * - World state and events\n * \n * Mirrors the agent SDK server pattern.\n */\n\nexport function createWorldApp(world: World): Express {\n const app = express();\n \n // Middleware\n app.use(express.json());\n app.use(express.urlencoded({ extended: true }));\n \n // Request logging\n app.use((req, res, next) => {\n logger.debug(`${req.method} ${req.path}`, {\n query: req.query,\n ip: req.ip,\n });\n next();\n });\n \n /**\n * GET / - World information\n */\n app.get('/', (req: Request, res: Response) => {\n res.json({\n name: world.config.name,\n description: world.config.description,\n type: world.config.type || 'generic',\n state: world.getState(),\n agentCount: world.getAgents().length,\n maxAgents: world.config.admission.maxAgents || null,\n admission: {\n requiredSkills: world.config.admission.requiredSkills || [],\n requiredTags: world.config.admission.requiredTags || [],\n minProtocolVersion: world.config.admission.minProtocolVersion || null,\n },\n });\n });\n \n /**\n * POST /world/join - Agent join request\n * \n * Body:\n * {\n * \"agentUrl\": \"http://localhost:3000\",\n * \"walletAddress\": \"0x...\" // optional, for blockchain membership\n * }\n */\n app.post('/world/join', async (req: Request, res: Response) => {\n try {\n const { agentUrl, walletAddress } = req.body;\n \n if (!agentUrl) {\n return res.status(400).json({\n success: false,\n error: 'agentUrl is required',\n });\n }\n \n logger.info(`Agent join request from: ${agentUrl}`, {\n wallet: walletAddress || 'none',\n });\n \n // Fetch agent card\n const cardFetcher = new (await import('../discovery/CardFetcher.js')).CardFetcher();\n const result = await cardFetcher.fetchCard(agentUrl);\n \n if (!result.success || !result.card) {\n return res.status(400).json({\n success: false,\n error: `Failed to fetch agent card: ${result.error}`,\n });\n }\n \n // Admit agent\n await world.admitAgent(result.card, walletAddress);\n \n res.json({\n success: true,\n message: 'Agent admitted to world',\n world: {\n name: world.config.name,\n agentCount: world.getAgents().length,\n },\n });\n } catch (error: any) {\n logger.error('Failed to process join request:', error);\n \n res.status(400).json({\n success: false,\n error: error.message || 'Failed to join world',\n });\n }\n });\n \n /**\n * GET /world/agents - List all agents\n */\n app.get('/world/agents', (req: Request, res: Response) => {\n const agents = world.getAgents().map(agent => ({\n url: agent.url,\n name: agent.name,\n protocolVersion: agent.protocolVersion,\n skills: agent.skills.map(s => s.id),\n joinedAt: agent.joinedAt,\n role: agent.role,\n }));\n \n res.json({\n agents,\n count: agents.length,\n });\n });\n \n /**\n * GET /world/state - World state\n */\n app.get('/world/state', (req: Request, res: Response) => {\n res.json(world.getState());\n });\n \n /**\n * POST /world/start - Start world simulation\n */\n app.post('/world/start', async (req: Request, res: Response) => {\n try {\n await world.start();\n res.json({\n success: true,\n message: 'World simulation started',\n state: world.getState(),\n });\n } catch (error: any) {\n res.status(400).json({\n success: false,\n error: error.message,\n });\n }\n });\n \n /**\n * POST /world/stop - Stop world simulation\n */\n app.post('/world/stop', async (req: Request, res: Response) => {\n try {\n await world.stop();\n res.json({\n success: true,\n message: 'World simulation stopped',\n state: world.getState(),\n });\n } catch (error: any) {\n res.status(400).json({\n success: false,\n error: error.message,\n });\n }\n });\n \n /**\n * POST /world/message - Route a message between agents through the world hub\n *\n * Body:\n * {\n * \"fromAgentUrl\": \"http://localhost:3000\",\n * \"toAgentUrl\": \"http://localhost:3001\", // optional — omit to broadcast\n * \"message\": \"Hello from agent A\"\n * }\n */\n app.post('/world/message', async (req: Request, res: Response) => {\n try {\n const { fromAgentUrl, toAgentUrl, message } = req.body;\n\n if (!fromAgentUrl) {\n return res.status(400).json({\n success: false,\n error: 'fromAgentUrl is required',\n });\n }\n\n if (!message) {\n return res.status(400).json({\n success: false,\n error: 'message is required',\n });\n }\n\n const router = world.getMessageRouter();\n\n if (toAgentUrl) {\n // Route to specific agent\n const result = await router.route(fromAgentUrl, toAgentUrl, message);\n res.json({\n success: result.success,\n reply: result.reply,\n error: result.error,\n });\n } else {\n // Broadcast to all agents\n const results = await router.routeToAll(fromAgentUrl, message);\n const responses: Record<string, any> = {};\n for (const [url, result] of results) {\n responses[url] = {\n success: result.success,\n reply: result.reply,\n error: result.error,\n };\n }\n res.json({\n success: true,\n responses,\n count: results.size,\n });\n }\n } catch (error: any) {\n logger.error('Failed to route message:', error);\n res.status(500).json({\n success: false,\n error: error.message || 'Failed to route message',\n });\n }\n });\n\n /**\n * GET /world/actions - List available world actions\n */\n app.get('/world/actions', (req: Request, res: Response) => {\n const registry = world.getActionsRegistry();\n res.json({\n actions: registry.toSummary(),\n count: registry.getAll().length,\n });\n });\n\n /**\n * DELETE /world/agents/:agentUrl - Remove an agent\n */\n app.delete('/world/agents/:agentUrl', async (req: Request, res: Response) => {\n try {\n const agentUrlParam = req.params.agentUrl;\n const agentUrl = typeof agentUrlParam === 'string' \n ? decodeURIComponent(agentUrlParam)\n : decodeURIComponent(agentUrlParam[0]);\n \n await world.removeAgent(agentUrl);\n \n res.json({\n success: true,\n message: 'Agent removed from world',\n });\n } catch (error: any) {\n res.status(400).json({\n success: false,\n error: error.message,\n });\n }\n });\n \n // 404 handler\n app.use((req: Request, res: Response) => {\n res.status(404).json({\n error: 'Not found',\n path: req.path,\n });\n });\n \n // Error handler\n app.use((err: any, req: Request, res: Response, next: any) => {\n logger.error('Server error:', err);\n \n res.status(500).json({\n error: 'Internal server error',\n message: err.message,\n });\n });\n \n return app;\n}\n\n/**\n * Start world server on configured port\n */\nexport async function startWorldServer(world: World): Promise<void> {\n const app = createWorldApp(world);\n \n const server = app.listen(world.config.server.port, world.config.server.host, () => {\n const { host, port } = world.config.server;\n \n logger.info(`World \"${world.config.name}\" server started`);\n logger.info(` http://${host}:${port}`);\n logger.info('');\n logger.info('Endpoints:');\n logger.info(` GET / - World info`);\n logger.info(` POST /world/join - Agent join request`);\n logger.info(` GET /world/agents - List agents`);\n logger.info(` GET /world/state - World state`);\n logger.info(` GET /world/actions - List world actions`);\n logger.info(` POST /world/message - Route agent messages`);\n logger.info(` POST /world/start - Start simulation`);\n logger.info(` POST /world/stop - Stop simulation`);\n logger.info(` DELETE /world/agents/:url - Remove agent`);\n });\n \n // Graceful shutdown\n process.on('SIGTERM', async () => {\n logger.info('SIGTERM received, shutting down gracefully...');\n \n server.close(async () => {\n await world.stop();\n process.exit(0);\n });\n });\n \n process.on('SIGINT', async () => {\n logger.info('SIGINT received, shutting down gracefully...');\n \n server.close(async () => {\n await world.stop();\n process.exit(0);\n });\n });\n}\n"]}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED