/ actors-main.ts
actors-main.ts
1 #!/usr/bin/env deno run --allow-read --allow-write --allow-env --unstable-kv 2 3 import { Task } from "./lib.ts"; 4 import { ActorManager } from "./actors/manager.ts"; 5 import { getActorRegistry, getAvailableActorNames } from "./actors/registry.ts"; 6 import { createActorInstances } from "./actors/core/runtime.ts"; 7 import { initializeEnv } from "./actors/utils/env.ts"; 8 9 /** 10 * Parse command line arguments to configure actors 11 */ 12 function parseArgs(args: string[]) { 13 const config = { 14 subscriber: 1, 15 writer: 1, 16 hybrid: 0, 17 preset: "", 18 }; 19 20 for (let i = 0; i < args.length; i++) { 21 const arg = args[i]; 22 switch (arg) { 23 case "--subscriber": 24 case "--subscribers": 25 config.subscriber = parseInt(args[++i]) || 1; 26 break; 27 case "--writer": 28 case "--writers": 29 config.writer = parseInt(args[++i]) || 1; 30 break; 31 case "--hybrid": 32 case "--hybrids": 33 config.hybrid = parseInt(args[++i]) || 0; 34 break; 35 case "--preset": 36 config.preset = args[++i] || ""; 37 break; 38 } 39 } 40 41 return config; 42 } 43 44 /** 45 * Apply preset configurations 46 */ 47 function applyPreset(config: any, preset: string) { 48 switch (preset) { 49 case "demo": 50 return { ...config, subscriber: 2, writer: 1, hybrid: 1 }; 51 case "heavy": 52 return { ...config, subscriber: 3, writer: 3, hybrid: 2 }; 53 case "light": 54 return { ...config, subscriber: 1, writer: 0, hybrid: 1 }; 55 case "writers-only": 56 return { ...config, subscriber: 0, writer: 5, hybrid: 0 }; 57 case "discord-bot-only": 58 return { 59 ...config, 60 subscriber: 0, 61 writer: 0, 62 hybrid: 0, 63 "discord-indexer": 0, 64 "discord-slash-commands": 1, 65 }; 66 case "discord": 67 return { 68 ...config, 69 subscriber: 0, 70 writer: 0, 71 hybrid: 0, 72 "discord-indexer": 1, 73 "discord-slash-commands": 1, 74 }; 75 case "discord-only": 76 return { 77 ...config, 78 subscriber: 0, 79 writer: 0, 80 hybrid: 0, 81 "discord-indexer": 1, 82 "discord-slash-commands": 1, 83 }; 84 case "llm-agent": 85 return { 86 ...config, 87 subscriber: 0, 88 writer: 0, 89 hybrid: 0, 90 "llm-response-agent": 1, 91 }; 92 case "discord-full": 93 return { 94 ...config, 95 subscriber: 0, 96 writer: 0, 97 hybrid: 0, 98 "discord-indexer": 1, 99 "discord-slash-commands": 1, 100 "llm-response-agent": 1, 101 }; 102 case "lm-studio-insight": 103 return { 104 ...config, 105 subscriber: 0, 106 writer: 0, 107 hybrid: 0, 108 "lm-studio-insight-agent": 1, 109 }; 110 case "lm-studio-tarot": 111 return { 112 ...config, 113 subscriber: 0, 114 writer: 0, 115 hybrid: 0, 116 "lm-studio-tarot-agent": 1, 117 }; 118 case "discord-all": 119 return { 120 ...config, 121 subscriber: 0, 122 writer: 0, 123 hybrid: 0, 124 "discord-indexer": 1, 125 "discord-slash-commands": 1, 126 "llm-response-agent": 1, 127 "lm-studio-insight-agent": 1, 128 }; 129 case "content-fragment": 130 return { 131 ...config, 132 subscriber: 0, 133 writer: 0, 134 hybrid: 0, 135 "content-fragment-agent": 1, 136 }; 137 case "question": 138 return { 139 ...config, 140 subscriber: 0, 141 writer: 0, 142 hybrid: 0, 143 "question-agent": 1, 144 }; 145 case "qa-feedback": 146 return { 147 ...config, 148 subscriber: 0, 149 writer: 0, 150 hybrid: 0, 151 "qa-feedback-loop-agent": 1, 152 }; 153 case "qa-full": 154 return { 155 ...config, 156 subscriber: 0, 157 writer: 0, 158 hybrid: 0, 159 "question-agent": 1, 160 "content-fragment-agent": 1, 161 "qa-feedback-loop-agent": 1, 162 }; 163 case "latent-space-navigator": 164 return { 165 ...config, 166 subscriber: 0, 167 writer: 0, 168 hybrid: 0, 169 "latent-space-navigator": 1, 170 }; 171 default: 172 return config; 173 } 174 } 175 176 /** 177 * Main function with auto-discovery 178 */ 179 function main() { 180 return Task.spawn(function* () { 181 console.log("🎭 Actor System Starting..."); 182 183 // Parse command line arguments 184 const baseConfig = parseArgs(Deno.args); 185 const config = baseConfig.preset 186 ? applyPreset(baseConfig, baseConfig.preset) 187 : baseConfig; 188 189 console.log("⚙️ Configuration:", config); 190 191 // Initialize environment loading 192 console.log("📁 Loading environment configuration..."); 193 yield* Task.wait(initializeEnv()); 194 195 // Auto-discover all available actors 196 console.log("🔍 Auto-discovering actors..."); 197 const actorRegistry = yield* getActorRegistry(); 198 199 const availableNames = yield* getAvailableActorNames(); 200 console.log("📋 Available actor types:", availableNames); 201 202 // Create actor manager 203 const manager = new ActorManager(); 204 205 // Create instances based on configuration 206 for (const definition of actorRegistry) { 207 const count = config[definition.name as keyof typeof config] || 0; 208 209 if (count > 0) { 210 console.log( 211 `🏗️ Creating ${count} instance(s) of ${definition.name}...`, 212 ); 213 const instances = createActorInstances(definition, count); 214 manager.addActors(instances); 215 } 216 } 217 218 const totalActors = manager.getActorCount(); 219 console.log( 220 `🚀 Created ${totalActors} total actors: ${ 221 manager.getActorNames().join(", ") 222 }`, 223 ); 224 225 if (totalActors === 0) { 226 console.log( 227 "⚠️ No actors to start. Try --preset demo or specify --subscriber 1 --writer 1", 228 ); 229 return; 230 } 231 232 // Start all actors 233 yield* manager.startAll(); 234 }); 235 } 236 237 // Show help if requested 238 if (Deno.args.includes("--help") || Deno.args.includes("-h")) { 239 console.log(` 240 🎭 Actor System - Lightweight reactive agents for dialog database 241 242 Usage: 243 deno run actors-main.ts [options] 244 245 Options: 246 --subscriber N Number of subscriber actors (default: 1) 247 --writer N Number of writer actors (default: 1) 248 --hybrid N Number of hybrid actors (default: 0) 249 --preset NAME Use a preset configuration 250 251 Presets: 252 demo 2 subscribers, 1 writer, 1 hybrid 253 heavy 3 subscribers, 3 writers, 2 hybrids 254 light 1 subscriber, 1 hybrid 255 writers-only 5 writers 256 discord Discord indexer and slash commands 257 discord-full Discord + LLM response agent 258 lm-studio-insight LM Studio insight extraction agent 259 lm-studio-tarot LM Studio tarot reading agent 260 content-fragment Content fragment processing agent 261 question Question processing agent 262 qa-feedback QA feedback loop agent (discovers & generates Q&A) 263 qa-full Question + Fragment + QA Feedback agents 264 discord-all All Discord features + both AI agents 265 latent-space-navigator Embedding space navigator with physics-based movement 266 267 Examples: 268 deno run actors-main.ts --preset demo 269 deno run actors-main.ts --subscriber 3 --writer 2 270 deno run actors-main.ts --hybrid 5 271 272 Note: Actors are auto-discovered from the /actors/implementations/ directory. 273 Add new actor files there and they'll be automatically available! 274 `); 275 Deno.exit(0); 276 } 277 278 if (import.meta.main) { 279 main().catch(console.error); 280 }