agent-world 0.4.0 → 0.4.5

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/README.md CHANGED
@@ -107,14 +107,23 @@ Each Agent World has a collection of agents that can communicate through a share
107
107
 
108
108
  ### Quick Start
109
109
 
110
- **Option 1: CLI Interface**
110
+ **Option 1: Web Interface**
111
111
  ```bash
112
- npx agent-world
112
+ npx agent-world-server
113
113
  ```
114
114
 
115
- **Option 2: Web Interface**
115
+ **Option 2: CLI Interface**
116
+ 1. Interactive Mode
117
+ ```bash
118
+ npx agent-world
119
+ ```
120
+ 2. Command Mode
121
+ ```bash
122
+ npx agent-world -w default-world "hi"
123
+ ```
124
+ 3. Pipeline Mode
116
125
  ```bash
117
- npx agent-world --server
126
+ echo "hi" | npx agent-world -w default-world
118
127
  ```
119
128
 
120
129
  ## Project Structure (npm workspaces)
package/dist/cli/index.js CHANGED
@@ -39,6 +39,7 @@ import { fileURLToPath } from 'url';
39
39
  import { program } from 'commander';
40
40
  import readline from 'readline';
41
41
  import { listWorlds, subscribeWorld, createCategoryLogger, LLMProvider, initializeLogger, enableStreaming, disableStreaming } from '../core/index.js';
42
+ import { getDefaultRootPath } from '../core/storage-factory.js';
42
43
  import { processCLIInput } from './commands.js';
43
44
  import { createStreamingState, handleWorldEventWithStreaming } from './stream.js';
44
45
  import { configureLLMProvider } from '../core/llm-config.js';
@@ -167,8 +168,8 @@ function configureLLMProvidersFromEnv() {
167
168
  logger.debug('Configured Ollama provider with default URL');
168
169
  }
169
170
  }
170
- const AGENT_WORLD_DATA_PATH = process.env.AGENT_WORLD_DATA_PATH || './data/worlds';
171
- const DEFAULT_ROOT_PATH = path.join(process.cwd(), AGENT_WORLD_DATA_PATH);
171
+ // Get default root path from storage-factory (no local defaults)
172
+ const DEFAULT_ROOT_PATH = getDefaultRootPath();
172
173
  // Pipeline mode execution with timer-based cleanup
173
174
  async function runPipelineMode(options, messageFromArgs) {
174
175
  const rootPath = options.root || DEFAULT_ROOT_PATH;
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Web Server - Express.js HTTP Server with REST API and SSE
4
+ *
5
+ * Features:
6
+ * - Express server with CORS, static files, and modular API routing
7
+ * - Environment-based LLM provider configuration
8
+ * - Category-based logging with configurable levels
9
+ * - Health check endpoint and proper error handling
10
+ * - Environment Variables: Automatically loads .env file for API keys and configuration
11
+ *
12
+ * Configuration: AGENT_WORLD_DATA_PATH, LOG_LEVEL, LLM provider keys
13
+ * Endpoints: /health + API routes from ./api.ts
14
+ */
15
+ // Load environment variables from .env file
16
+ import dotenv from 'dotenv';
17
+ dotenv.config();
18
+ import open from 'open';
19
+ import { initializeLogger, createCategoryLogger, LLMProvider } from '../core/index.js';
20
+ import { configureLLMProvider } from '../core/llm-config.js';
21
+ import express from 'express';
22
+ import cors from 'cors';
23
+ import path from 'path';
24
+ import { fileURLToPath, pathToFileURL } from 'url';
25
+ import apiRouter from './api.js';
26
+ // ES modules setup
27
+ const __filename = fileURLToPath(import.meta.url);
28
+ const __dirname = path.dirname(__filename);
29
+ // Configuration
30
+ const PORT = Number(process.env.PORT) || 0;
31
+ const HOST = process.env.HOST || '127.0.0.1';
32
+ const logLevel = (process.env.LOG_LEVEL || 'error');
33
+ // Initialize logger (now synchronous)
34
+ initializeLogger({ globalLevel: logLevel });
35
+ const serverLogger = createCategoryLogger('server');
36
+ serverLogger.debug('Server logger initialized', { logLevel });
37
+ // LLM provider configuration
38
+ function configureLLMProvidersFromEnv() {
39
+ const providers = [
40
+ { env: 'OPENAI_API_KEY', provider: LLMProvider.OPENAI, config: (key) => ({ apiKey: key }) },
41
+ { env: 'ANTHROPIC_API_KEY', provider: LLMProvider.ANTHROPIC, config: (key) => ({ apiKey: key }) },
42
+ { env: 'GOOGLE_API_KEY', provider: LLMProvider.GOOGLE, config: (key) => ({ apiKey: key }) },
43
+ { env: 'XAI_API_KEY', provider: LLMProvider.XAI, config: (key) => ({ apiKey: key }) }
44
+ ];
45
+ providers.forEach(({ env, provider, config }) => {
46
+ const key = process.env[env];
47
+ if (key) {
48
+ configureLLMProvider(provider, config(key));
49
+ serverLogger.debug(`Configured ${provider} provider from environment`);
50
+ }
51
+ });
52
+ // Azure (requires multiple env vars)
53
+ if (process.env.AZURE_OPENAI_API_KEY && process.env.AZURE_ENDPOINT && process.env.AZURE_DEPLOYMENT) {
54
+ configureLLMProvider(LLMProvider.AZURE, {
55
+ apiKey: process.env.AZURE_OPENAI_API_KEY,
56
+ endpoint: process.env.AZURE_ENDPOINT,
57
+ deployment: process.env.AZURE_DEPLOYMENT,
58
+ apiVersion: process.env.AZURE_API_VERSION || '2023-12-01-preview'
59
+ });
60
+ serverLogger.debug('Configured Azure provider from environment');
61
+ }
62
+ // OpenAI Compatible
63
+ if (process.env.OPENAI_COMPATIBLE_API_KEY && process.env.OPENAI_COMPATIBLE_BASE_URL) {
64
+ configureLLMProvider(LLMProvider.OPENAI_COMPATIBLE, {
65
+ apiKey: process.env.OPENAI_COMPATIBLE_API_KEY,
66
+ baseUrl: process.env.OPENAI_COMPATIBLE_BASE_URL
67
+ });
68
+ serverLogger.debug('Configured OpenAI-Compatible provider from environment');
69
+ }
70
+ // Ollama
71
+ const ollamaUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434/api';
72
+ configureLLMProvider(LLMProvider.OLLAMA, { baseUrl: ollamaUrl });
73
+ serverLogger.debug('Configured Ollama provider', { baseUrl: ollamaUrl });
74
+ }
75
+ // Express app setup
76
+ const app = express();
77
+ app.use(cors());
78
+ app.use(express.json());
79
+ // Request logging
80
+ app.use((req, res, next) => {
81
+ console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
82
+ next();
83
+ });
84
+ // Static files and API routes
85
+ app.use(express.static(path.join(__dirname, '../public')));
86
+ app.use('/api', apiRouter);
87
+ // Health check endpoint
88
+ app.get('/health', (req, res) => {
89
+ try {
90
+ res.json({
91
+ status: 'healthy',
92
+ timestamp: new Date().toISOString(),
93
+ services: { express: 'running' }
94
+ });
95
+ }
96
+ catch (error) {
97
+ console.error('Error getting server health:', error);
98
+ res.status(500).json({
99
+ status: 'error',
100
+ timestamp: new Date().toISOString(),
101
+ error: 'Failed to get server health'
102
+ });
103
+ }
104
+ });
105
+ // SPA fallback - serve index.html for all non-API routes
106
+ app.get('*', (req, res) => {
107
+ res.sendFile(path.join(__dirname, '../public/index.html'));
108
+ });
109
+ // Error handling middleware
110
+ app.use((error, req, res, next) => {
111
+ console.error('Unhandled error:', error);
112
+ res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
113
+ });
114
+ // 404 handler
115
+ app.use((req, res) => {
116
+ res.status(404).json({ error: 'Endpoint not found', code: 'NOT_FOUND' });
117
+ });
118
+ // Server startup function
119
+ export function startWebServer(port = PORT, host = HOST) {
120
+ return new Promise((resolve, reject) => {
121
+ configureLLMProvidersFromEnv();
122
+ const server = app.listen(port, host, () => {
123
+ const serverAddress = server.address();
124
+ if (serverAddress && typeof serverAddress === 'object') {
125
+ const actualPort = serverAddress.port;
126
+ const url = `http://${host}:${actualPort}`;
127
+ console.log(`🌐 Web server running at ${url}`);
128
+ // console.log(`📁 Serving static files from: ${path.join(__dirname, '../public')}`);
129
+ // console.log(`🚀 HTTP server running with REST API and SSE chat`);
130
+ resolve(server);
131
+ open(url);
132
+ }
133
+ });
134
+ server.on('error', reject);
135
+ });
136
+ }
137
+ // Direct execution handling - check both direct execution and npm bin execution
138
+ const currentFileUrl = import.meta.url;
139
+ const entryPointUrl = pathToFileURL(path.resolve(process.argv[1])).href;
140
+ const isDirectExecution = currentFileUrl === entryPointUrl;
141
+ const isServerBinCommand = process.argv[1].includes('agent-world-server') || currentFileUrl.includes('server/index.js');
142
+ if (isDirectExecution || isServerBinCommand) {
143
+ startWebServer()
144
+ .then(() => console.log('Server started successfully'))
145
+ .catch((error) => {
146
+ console.error('Failed to start server:', error);
147
+ process.exit(1);
148
+ });
149
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-world",
3
- "version": "0.4.0",
3
+ "version": "0.4.5",
4
4
  "main": "index.ts",
5
5
  "type": "module",
6
6
  "workspaces": [
@@ -8,7 +8,8 @@
8
8
  "next"
9
9
  ],
10
10
  "bin": {
11
- "agent-world": "dist/cli/index.js"
11
+ "agent-world": "dist/cli/index.js",
12
+ "agent-world-server": "dist/server/index.js"
12
13
  },
13
14
  "scripts": {
14
15
  "prestart": "npm run build",
@@ -49,6 +50,7 @@
49
50
  "chalk": "^4.1.2",
50
51
  "cors": "^2.8.5",
51
52
  "dotenv": "^16.5.0",
53
+ "enquirer": "^2.4.1",
52
54
  "events": "^3.3.0",
53
55
  "express": "^4.21.2",
54
56
  "ollama-ai-provider": "^1.2.0",