@reminix/http-adapter 0.2.0 → 0.3.0
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 +2 -10
- package/dist/cli.js +12 -10
- package/dist/cli.js.map +1 -1
- package/dist/converter.d.ts +1 -1
- package/dist/converter.d.ts.map +1 -1
- package/dist/converter.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +5 -6
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
- package/dist/loader.d.ts +0 -19
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js +0 -52
- package/dist/loader.js.map +0 -1
- package/dist/registry.d.ts +0 -24
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -208
- package/dist/registry.js.map +0 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ yarn add @reminix/http-adapter
|
|
|
19
19
|
Create a file `my-handler.ts`:
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
|
-
import type { AgentHandler, Context, Request, Response } from '@reminix/
|
|
22
|
+
import type { AgentHandler, Context, Request, Response } from '@reminix/runtime';
|
|
23
23
|
|
|
24
24
|
export const agents = {
|
|
25
25
|
chatbot: async (context: Context, request: Request): Promise<Response> => {
|
|
@@ -196,7 +196,7 @@ Content-Type: application/json
|
|
|
196
196
|
Handlers receive a `Context` and `Request`, and return a `Response`:
|
|
197
197
|
|
|
198
198
|
```typescript
|
|
199
|
-
import type { AgentHandler, Context, Request, Response } from '@reminix/
|
|
199
|
+
import type { AgentHandler, Context, Request, Response } from '@reminix/runtime';
|
|
200
200
|
|
|
201
201
|
const myAgent: AgentHandler = async (context: Context, request: Request): Promise<Response> => {
|
|
202
202
|
// Access context
|
|
@@ -224,13 +224,6 @@ const myAgent: AgentHandler = async (context: Context, request: Request): Promis
|
|
|
224
224
|
};
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
-
## Examples
|
|
228
|
-
|
|
229
|
-
See the [examples directory](./examples/) for complete working examples:
|
|
230
|
-
|
|
231
|
-
- **Basic Handler**: Single-file handler with agents and tools
|
|
232
|
-
- **Multi Handler**: Directory-based handler with auto-discovery
|
|
233
|
-
|
|
234
227
|
## API Reference
|
|
235
228
|
|
|
236
229
|
### `startServer(handlerPath, options?)`
|
|
@@ -300,4 +293,3 @@ MIT
|
|
|
300
293
|
|
|
301
294
|
- [GitHub Repository](https://github.com/reminix-ai/reminix-typescript)
|
|
302
295
|
- [Documentation](https://docs.reminix.com)
|
|
303
|
-
- [Examples](./examples/)
|
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
5
5
|
// src/server.ts
|
|
6
6
|
import { createServer } from "http";
|
|
7
7
|
|
|
8
|
-
//
|
|
8
|
+
// ../runtime/dist/loader.js
|
|
9
9
|
import { pathToFileURL } from "url";
|
|
10
10
|
import { statSync } from "fs";
|
|
11
11
|
async function loadHandler(handlerPath) {
|
|
@@ -23,9 +23,7 @@ async function loadHandler(handlerPath) {
|
|
|
23
23
|
loaded.prompts = module.prompts;
|
|
24
24
|
}
|
|
25
25
|
if (!loaded.agents && !loaded.tools && !loaded.prompts) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`Handler file "${handlerPath}" must export at least one of: agents, tools, or prompts`
|
|
28
|
-
);
|
|
26
|
+
throw new Error(`Handler file "${handlerPath}" must export at least one of: agents, tools, or prompts`);
|
|
29
27
|
}
|
|
30
28
|
return loaded;
|
|
31
29
|
} catch (error) {
|
|
@@ -46,7 +44,7 @@ function isFile(path) {
|
|
|
46
44
|
}
|
|
47
45
|
__name(isFile, "isFile");
|
|
48
46
|
|
|
49
|
-
//
|
|
47
|
+
// ../runtime/dist/registry.js
|
|
50
48
|
import { readdir, stat } from "fs/promises";
|
|
51
49
|
import { join, extname, basename } from "path";
|
|
52
50
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -175,9 +173,7 @@ async function loadDirectory(dirPath) {
|
|
|
175
173
|
if (exportedValue !== void 0) {
|
|
176
174
|
handlers[key] = exportedValue;
|
|
177
175
|
} else {
|
|
178
|
-
const moduleKeys = Object.keys(module).filter(
|
|
179
|
-
(k) => k !== "default" && !k.startsWith("__")
|
|
180
|
-
);
|
|
176
|
+
const moduleKeys = Object.keys(module).filter((k) => k !== "default" && !k.startsWith("__"));
|
|
181
177
|
if (moduleKeys.length > 0) {
|
|
182
178
|
handlers[key] = module[moduleKeys[0]] || module;
|
|
183
179
|
}
|
|
@@ -198,6 +194,12 @@ async function loadDirectory(dirPath) {
|
|
|
198
194
|
}
|
|
199
195
|
__name(loadDirectory, "loadDirectory");
|
|
200
196
|
|
|
197
|
+
// ../runtime/dist/executor.js
|
|
198
|
+
async function executeHandler(handler, context, request) {
|
|
199
|
+
return await handler(context, request);
|
|
200
|
+
}
|
|
201
|
+
__name(executeHandler, "executeHandler");
|
|
202
|
+
|
|
201
203
|
// src/converter.ts
|
|
202
204
|
async function convertHttpToRequest(httpReq) {
|
|
203
205
|
try {
|
|
@@ -344,7 +346,7 @@ async function startServer(handlerPath, options = {}) {
|
|
|
344
346
|
}
|
|
345
347
|
const context = options.context ? await options.context(req) : createDefaultContext(req);
|
|
346
348
|
const handlerReq = await convertHttpToRequest(req);
|
|
347
|
-
const handlerRes = await agent
|
|
349
|
+
const handlerRes = await executeHandler(agent, context, handlerReq);
|
|
348
350
|
convertResponseToHttp(handlerRes, res);
|
|
349
351
|
return;
|
|
350
352
|
}
|
|
@@ -358,7 +360,7 @@ async function startServer(handlerPath, options = {}) {
|
|
|
358
360
|
}
|
|
359
361
|
const context = options.context ? await options.context(req) : createDefaultContext(req);
|
|
360
362
|
const handlerReq = await convertHttpToRequest(req);
|
|
361
|
-
const handlerRes = await tool
|
|
363
|
+
const handlerRes = await executeHandler(tool, context, handlerReq);
|
|
362
364
|
convertResponseToHttp(handlerRes, res);
|
|
363
365
|
return;
|
|
364
366
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/loader.ts","../src/registry.ts","../src/converter.ts","../src/cli.ts"],"sourcesContent":["/**\n * HTTP server for Reminix handlers\n */\n\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport { loadHandler, isFile } from './loader';\nimport { discoverRegistry } from './registry';\nimport { convertHttpToRequest, convertResponseToHttp, convertErrorToHttp } from './converter';\nimport type { Context, AgentHandler, ToolHandler } from '@reminix/sdk';\n\nexport interface ServerOptions {\n port?: number;\n host?: string;\n context?: (req: IncomingMessage) => Promise<Context> | Context;\n}\n\n/**\n * Start HTTP server for handler\n */\nexport async function startServer(handlerPath: string, options: ServerOptions = {}): Promise<void> {\n const port = options.port || 3000;\n const host = options.host || 'localhost';\n\n // Load handler or discover registry\n let agents: Record<string, AgentHandler> = {};\n let tools: Record<string, ToolHandler> = {};\n let prompts: Record<string, unknown> = {};\n\n if (isFile(handlerPath)) {\n // Single file handler\n const loaded = await loadHandler(handlerPath);\n agents = loaded.agents || {};\n tools = loaded.tools || {};\n prompts = loaded.prompts || {};\n } else {\n // Directory - auto-discover\n const registry = await discoverRegistry(handlerPath);\n agents = registry.agents;\n tools = registry.tools;\n prompts = registry.prompts;\n }\n\n // Create HTTP server\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n // Set CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n // Handle OPTIONS request\n if (req.method === 'OPTIONS') {\n res.writeHead(200);\n res.end();\n return;\n }\n\n // Parse URL to determine route\n const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n const pathParts = url.pathname.split('/').filter(Boolean);\n\n // Route: /agents/:agentId/invoke\n if (pathParts[0] === 'agents' && pathParts[2] === 'invoke') {\n const agentId = pathParts[1];\n const agent = agents[agentId];\n\n if (!agent) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `Agent not found: ${agentId}` }));\n return;\n }\n\n // Get context (provided by orchestrator or default)\n const context = options.context ? await options.context(req) : createDefaultContext(req);\n\n // Convert HTTP request to handler request\n const handlerReq = await convertHttpToRequest(req);\n\n // Call agent handler\n const handlerRes = await agent(context, handlerReq);\n\n // Convert handler response to HTTP response\n convertResponseToHttp(handlerRes, res);\n return;\n }\n\n // Route: /tools/:toolId/invoke\n if (pathParts[0] === 'tools' && pathParts[2] === 'invoke') {\n const toolId = pathParts[1];\n const tool = tools[toolId];\n\n if (!tool) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `Tool not found: ${toolId}` }));\n return;\n }\n\n // Get context\n const context = options.context ? await options.context(req) : createDefaultContext(req);\n\n // Convert HTTP request to handler request\n const handlerReq = await convertHttpToRequest(req);\n\n // Call tool handler\n const handlerRes = await tool(context, handlerReq);\n\n // Convert handler response to HTTP response\n convertResponseToHttp(handlerRes, res);\n return;\n }\n\n // Route: /health (health check)\n if (pathParts[0] === 'health' || url.pathname === '/') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n status: 'ok',\n agents: Object.keys(agents),\n tools: Object.keys(tools),\n prompts: Object.keys(prompts),\n })\n );\n return;\n }\n\n // 404 for unknown routes\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n } catch (error) {\n convertErrorToHttp(error as Error, res);\n }\n });\n\n // Start server\n server.listen(port, host, () => {\n console.log(`Reminix HTTP adapter listening on http://${host}:${port}`);\n console.log(`Agents: ${Object.keys(agents).join(', ') || 'none'}`);\n console.log(`Tools: ${Object.keys(tools).join(', ') || 'none'}`);\n });\n\n // Handle server errors\n server.on('error', (error: Error) => {\n console.error('Server error:', error);\n });\n}\n\n/**\n * Create default context (for development)\n * In production, this would come from the orchestrator\n */\nfunction createDefaultContext(req: IncomingMessage): Context {\n // Extract chatId from headers or query params\n const chatId =\n req.headers['x-chat-id'] ||\n new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`).searchParams.get(\n 'chatId'\n ) ||\n 'default-chat';\n\n // Return a minimal context (orchestrator will provide full context in production)\n return {\n chatId: chatId as string,\n memory: createMockMemoryStore(),\n knowledgeBase: createMockKnowledgeBase(),\n } as Context;\n}\n\n/**\n * Mock memory store for development\n */\nfunction createMockMemoryStore() {\n const store = new Map<string, unknown>();\n return {\n get: async (key: string) => store.get(key),\n set: async (key: string, value: unknown) => {\n store.set(key, value);\n },\n delete: async (key: string) => {\n store.delete(key);\n },\n clear: async () => {\n store.clear();\n },\n };\n}\n\n/**\n * Mock knowledge base for development\n */\nfunction createMockKnowledgeBase() {\n return {\n search: async (_query: string) => [],\n add: async (_content: string) => {},\n delete: async (_id: string) => {},\n };\n}\n","/**\n * Load handler from file\n */\n\nimport { pathToFileURL } from 'url';\nimport { statSync } from 'fs';\nimport type { AgentHandler, ToolHandler } from '@reminix/sdk';\n\nexport interface LoadedHandler {\n agents?: Record<string, AgentHandler>;\n tools?: Record<string, ToolHandler>;\n prompts?: Record<string, unknown>;\n}\n\n/**\n * Load handler from a file path\n * Supports both TypeScript (.ts) and JavaScript (.js) files\n */\nexport async function loadHandler(handlerPath: string): Promise<LoadedHandler> {\n try {\n // Convert file path to file URL for ES modules\n const fileUrl = pathToFileURL(handlerPath).href;\n\n // Dynamic import of the handler module\n const module = await import(fileUrl);\n\n // Extract agents, tools, and prompts\n const loaded: LoadedHandler = {};\n\n if (module.agents) {\n loaded.agents = module.agents;\n }\n\n if (module.tools) {\n loaded.tools = module.tools;\n }\n\n if (module.prompts) {\n loaded.prompts = module.prompts;\n }\n\n // Validate that at least one export exists\n if (!loaded.agents && !loaded.tools && !loaded.prompts) {\n throw new Error(\n `Handler file \"${handlerPath}\" must export at least one of: agents, tools, or prompts`\n );\n }\n\n return loaded;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to load handler from \"${handlerPath}\": ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Check if a path is a file (not a directory)\n */\nexport function isFile(path: string): boolean {\n try {\n const stats = statSync(path);\n return stats.isFile();\n } catch {\n return false;\n }\n}\n","/**\n * Registry for auto-discovering agents, tools, and prompts from directories\n */\n\nimport { readdir, stat } from 'fs/promises';\nimport { join, extname, basename } from 'path';\nimport { pathToFileURL } from 'url';\nimport { loadHandler } from './loader';\nimport type { AgentHandler, ToolHandler } from '@reminix/sdk';\n\nexport interface Registry {\n agents: Record<string, AgentHandler>;\n tools: Record<string, ToolHandler>;\n prompts: Record<string, unknown>;\n}\n\n/**\n * Auto-discover and load handlers from a directory structure\n *\n * Expected structure:\n * handler/\n * agents/\n * chatbot.ts\n * assistant.ts\n * tools/\n * search.ts\n * prompts/\n * system.ts\n */\nexport async function discoverRegistry(handlerPath: string): Promise<Registry> {\n const registry: Registry = {\n agents: {},\n tools: {},\n prompts: {},\n };\n\n try {\n // Check if path exists and is a directory\n const stats = await stat(handlerPath);\n if (!stats.isDirectory()) {\n throw new Error(`Handler path must be a directory: ${handlerPath}`);\n }\n\n // Discover agents\n const agentsPath = join(handlerPath, 'agents');\n try {\n const agentsStats = await stat(agentsPath);\n if (agentsStats.isDirectory()) {\n const agents = await loadDirectory(agentsPath);\n // Filter to only AgentHandler types\n for (const [key, value] of Object.entries(agents)) {\n if (typeof value === 'function') {\n registry.agents[key] = value as AgentHandler;\n }\n }\n }\n } catch {\n // agents/ directory doesn't exist, skip\n }\n\n // Discover tools\n const toolsPath = join(handlerPath, 'tools');\n try {\n const toolsStats = await stat(toolsPath);\n if (toolsStats.isDirectory()) {\n const tools = await loadDirectory(toolsPath);\n // Filter to only ToolHandler types\n for (const [key, value] of Object.entries(tools)) {\n if (typeof value === 'function') {\n registry.tools[key] = value as ToolHandler;\n }\n }\n }\n } catch {\n // tools/ directory doesn't exist, skip\n }\n\n // Discover prompts\n const promptsPath = join(handlerPath, 'prompts');\n try {\n const promptsStats = await stat(promptsPath);\n if (promptsStats.isDirectory()) {\n const prompts = await loadDirectory(promptsPath);\n registry.prompts = prompts;\n }\n } catch {\n // prompts/ directory doesn't exist, skip\n }\n\n // Validate that at least something was discovered\n if (\n Object.keys(registry.agents).length === 0 &&\n Object.keys(registry.tools).length === 0 &&\n Object.keys(registry.prompts).length === 0\n ) {\n throw new Error(`No agents, tools, or prompts found in directory: ${handlerPath}`);\n }\n\n return registry;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to discover registry from \"${handlerPath}\": ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Load all handler files from a directory\n * Filename (without extension) becomes the key in the registry\n */\nasync function loadDirectory(\n dirPath: string\n): Promise<Record<string, AgentHandler | ToolHandler | unknown>> {\n const handlers: Record<string, AgentHandler | ToolHandler | unknown> = {};\n\n try {\n const entries = await readdir(dirPath);\n\n for (const entry of entries) {\n const fullPath = join(dirPath, entry);\n const stats = await stat(fullPath);\n\n // Skip if not a file\n if (!stats.isFile()) {\n continue;\n }\n\n // Only process TypeScript/JavaScript files\n const ext = extname(entry);\n if (ext !== '.ts' && ext !== '.js' && ext !== '.mjs') {\n continue;\n }\n\n // Extract the key from filename (without extension)\n const key = entry.replace(ext, '');\n\n try {\n // Try loading as a handler file (expects agents/tools/prompts exports)\n const loaded = await loadHandler(fullPath);\n\n // Merge agents, tools, and prompts into the registry\n if (loaded.agents) {\n const agentKeys = Object.keys(loaded.agents);\n if (agentKeys.length === 1) {\n handlers[key] = loaded.agents[agentKeys[0]];\n } else {\n for (const agentKey of agentKeys) {\n handlers[`${key}.${agentKey}`] = loaded.agents[agentKey];\n }\n }\n }\n\n if (loaded.tools) {\n const toolKeys = Object.keys(loaded.tools);\n if (toolKeys.length === 1) {\n handlers[key] = loaded.tools[toolKeys[0]];\n } else {\n for (const toolKey of toolKeys) {\n handlers[`${key}.${toolKey}`] = loaded.tools[toolKey];\n }\n }\n }\n\n if (loaded.prompts) {\n const promptKeys = Object.keys(loaded.prompts);\n if (promptKeys.length === 1) {\n handlers[key] = loaded.prompts[promptKeys[0]];\n } else {\n for (const promptKey of promptKeys) {\n handlers[`${key}.${promptKey}`] = loaded.prompts[promptKey];\n }\n }\n }\n } catch {\n // If loadHandler fails, try loading as direct export\n // This handles files that export functions directly (e.g., export const chatbot)\n try {\n const fileUrl = pathToFileURL(fullPath).href;\n const module = await import(fileUrl);\n\n // Determine type based on directory name\n const dirName = basename(dirPath);\n\n // Check for direct exports matching the directory type\n if (dirName === 'agents') {\n // Look for exported function with same name as file, or any exported function\n const exportedFunction = module[key] || module.default;\n if (typeof exportedFunction === 'function') {\n handlers[key] = exportedFunction;\n }\n } else if (dirName === 'tools') {\n const exportedFunction = module[key] || module.default;\n if (typeof exportedFunction === 'function') {\n handlers[key] = exportedFunction;\n }\n } else if (dirName === 'prompts') {\n // For prompts, accept any export (function, object, string, etc.)\n // Try to get export with same name as file, or default, or any named export\n const exportedValue = module[key] || module.default;\n if (exportedValue !== undefined) {\n handlers[key] = exportedValue;\n } else {\n // Check if module has any exports (excluding default module properties)\n const moduleKeys = Object.keys(module).filter(\n (k) => k !== 'default' && !k.startsWith('__')\n );\n if (moduleKeys.length > 0) {\n // Use the first export, or the module itself if it's a simple object\n handlers[key] = module[moduleKeys[0]] || module;\n }\n }\n }\n } catch {\n // Skip this file if both methods fail\n continue;\n }\n }\n }\n\n return handlers;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to load directory \"${dirPath}\": ${error.message}`);\n }\n throw error;\n }\n}\n","/**\n * Convert between HTTP and Handler formats\n */\n\nimport type { IncomingMessage, ServerResponse } from 'http';\nimport type { Request as HandlerRequest, Response as HandlerResponse, Message } from '@reminix/sdk';\n\n/**\n * Convert HTTP request to Handler Request\n * Extracts messages from HTTP request body\n */\nexport async function convertHttpToRequest(httpReq: IncomingMessage): Promise<HandlerRequest> {\n try {\n // Read request body\n const body = await readRequestBody(httpReq);\n\n // Parse JSON body\n let parsedBody: Record<string, unknown> = {};\n if (body) {\n try {\n parsedBody = JSON.parse(body) as Record<string, unknown>;\n } catch {\n // If not JSON, treat as text\n parsedBody = { content: body };\n }\n }\n\n // Extract messages from body\n // Expected format: { messages: Message[] } or { message: Message } or just Message[]\n let messages: Message[] = [];\n\n if (Array.isArray(parsedBody)) {\n // Body is array of messages\n messages = parsedBody as Message[];\n } else if (parsedBody.messages && Array.isArray(parsedBody.messages)) {\n // Body has messages array\n messages = parsedBody.messages as Message[];\n } else if (parsedBody.message) {\n // Body has single message\n messages = [parsedBody.message as Message];\n } else if (parsedBody.content || parsedBody.role) {\n // Body is a single message object\n messages = [parsedBody as unknown as Message];\n }\n\n // Extract metadata from query params and headers\n const metadata: Record<string, unknown> = {\n method: httpReq.method,\n url: httpReq.url,\n headers: httpReq.headers,\n };\n\n // Add query params to metadata\n if (httpReq.url) {\n const url = new URL(httpReq.url, `http://${httpReq.headers.host || 'localhost'}`);\n const queryParams: Record<string, string> = {};\n url.searchParams.forEach((value, key) => {\n queryParams[key] = value;\n });\n if (Object.keys(queryParams).length > 0) {\n metadata.query = queryParams;\n }\n }\n\n // Merge any additional metadata from body\n if (parsedBody.metadata) {\n Object.assign(metadata, parsedBody.metadata);\n }\n\n return {\n messages,\n metadata,\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to convert HTTP request: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Convert Handler Response to HTTP response\n */\nexport function convertResponseToHttp(handlerRes: HandlerResponse, httpRes: ServerResponse): void {\n try {\n // Set status code (default 200)\n const statusCode =\n typeof handlerRes.metadata?.statusCode === 'number' ? handlerRes.metadata.statusCode : 200;\n httpRes.statusCode = statusCode;\n\n // Set headers\n const headers =\n (handlerRes.metadata?.headers as Record<string, unknown> | undefined) ||\n ({} as Record<string, unknown>);\n headers['Content-Type'] =\n (typeof headers['Content-Type'] === 'string' ? headers['Content-Type'] : undefined) ||\n 'application/json';\n\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n httpRes.setHeader(key, value);\n }\n }\n\n // Prepare response body\n const responseBody = {\n messages: handlerRes.messages,\n ...(handlerRes.metadata && { metadata: handlerRes.metadata }),\n ...(handlerRes.toolCalls && { toolCalls: handlerRes.toolCalls }),\n ...(handlerRes.stateUpdates && { stateUpdates: handlerRes.stateUpdates }),\n };\n\n // Send response\n httpRes.end(JSON.stringify(responseBody));\n } catch (error) {\n if (error instanceof Error) {\n httpRes.statusCode = 500;\n httpRes.setHeader('Content-Type', 'application/json');\n httpRes.end(JSON.stringify({ error: error.message }));\n }\n }\n}\n\n/**\n * Read request body from IncomingMessage\n */\nasync function readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let body = '';\n\n req.on('data', (chunk) => {\n body += chunk.toString();\n });\n\n req.on('end', () => {\n resolve(body);\n });\n\n req.on('error', (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Convert error to HTTP error response\n */\nexport function convertErrorToHttp(error: Error, httpRes: ServerResponse): void {\n httpRes.statusCode = 500;\n httpRes.setHeader('Content-Type', 'application/json');\n httpRes.end(\n JSON.stringify({\n error: error.message,\n ...(process.env.NODE_ENV === 'development' && { stack: error.stack }),\n })\n );\n}\n","/**\n * CLI entry point for Reminix HTTP adapter\n *\n * Usage:\n * npx @reminix/http-adapter serve <handler-path> [options]\n * tsx src/cli.ts serve <handler-path> [options]\n */\n\nimport { startServer, type ServerOptions } from './server';\nimport { parseArgs } from 'util';\nimport { extname } from 'path';\n\n/**\n * Try to register tsx loader for TypeScript support\n * Uses dynamic import which respects Node's module resolution including global packages\n * Returns true if successful, false if tsx is not available\n */\nasync function tryRegisterTsx(): Promise<boolean> {\n try {\n // Use dynamic import to load tsx's ESM API which includes the register function\n // @ts-expect-error - tsx is a runtime dependency, not available at compile time\n const tsx = await import('tsx/esm/api');\n if (tsx && typeof tsx.register === 'function') {\n tsx.register();\n return true;\n }\n } catch {\n // tsx not available\n }\n return false;\n}\n\ninterface CliOptions {\n port?: number;\n host?: string;\n handlerPath: string;\n loader?: string;\n}\n\nfunction parseCliArgs(): CliOptions {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || args[0] !== 'serve') {\n console.error('Usage: reminix-http-adapter serve <handler-path> [options]');\n console.error('');\n console.error('Options:');\n console.error(' --port <number> Port to listen on (default: 3000)');\n console.error(' --host <string> Host to listen on (default: localhost)');\n console.error(' --loader <name> Loader to use for TypeScript support (e.g., tsx)');\n console.error('');\n console.error('Examples:');\n console.error(' npx @reminix/http-adapter serve ./my-handler.ts');\n console.error(' npx @reminix/http-adapter serve ./my-handler.ts --loader tsx');\n console.error(' npx @reminix/http-adapter serve ./my-handler --port 8080');\n process.exit(1);\n }\n\n const handlerPath = args[1];\n if (!handlerPath) {\n console.error('Error: handler-path is required');\n process.exit(1);\n }\n\n const { values } = parseArgs({\n args: args.slice(2),\n options: {\n port: { type: 'string' },\n host: { type: 'string' },\n loader: { type: 'string' },\n },\n });\n\n const options: CliOptions = {\n handlerPath,\n port: values.port ? parseInt(values.port, 10) : undefined,\n host: values.host,\n loader: values.loader,\n };\n\n return options;\n}\n\nasync function main() {\n try {\n const options = parseCliArgs();\n\n // Check if TypeScript support is needed\n const ext = extname(options.handlerPath).toLowerCase();\n const isTypeScript = ext === '.ts' || ext === '.tsx';\n // For directories, we'll check later if they contain .ts files, but register tsx preemptively\n const isDirectory = !ext || ext === '';\n const needsTsx = options.loader === 'tsx' || isTypeScript || (isDirectory && !options.loader);\n\n // Register tsx loader if needed\n if (needsTsx) {\n const registered = await tryRegisterTsx();\n if (!registered) {\n console.error('Error: TypeScript support requires \"tsx\" to be installed.');\n console.error('');\n console.error('To install tsx:');\n console.error(' npm install -g tsx');\n console.error(' # or locally:');\n console.error(' npm install tsx');\n console.error('');\n console.error('Then run:');\n console.error(` npx @reminix/http-adapter serve ${options.handlerPath} --loader tsx`);\n console.error('');\n console.error('Alternatively, use Node.js with --import flag (Node 20.6+):');\n console.error(\n ` node --import tsx node_modules/@reminix/http-adapter/dist/cli.js serve ${options.handlerPath}`\n );\n process.exit(1);\n }\n }\n\n const serverOptions: ServerOptions = {\n port: options.port,\n host: options.host,\n };\n\n await startServer(options.handlerPath, serverOptions);\n } catch (error) {\n console.error('Error starting server:', error);\n process.exit(1);\n }\n}\n\n// Run if called directly\nmain();\n"],"mappings":"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","names":["pathToFileURL","pathToFileURL","extname","extname"]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../../runtime/src/loader.ts","../../runtime/src/registry.ts","../../runtime/src/executor.ts","../src/converter.ts","../src/cli.ts"],"sourcesContent":["/**\n * HTTP server for Reminix handlers\n */\n\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport { loadHandler, isFile, discoverRegistry, executeHandler } from '@reminix/runtime';\nimport { convertHttpToRequest, convertResponseToHttp, convertErrorToHttp } from './converter';\nimport type { Context, AgentHandler, ToolHandler } from '@reminix/runtime';\n\nexport interface ServerOptions {\n port?: number;\n host?: string;\n context?: (req: IncomingMessage) => Promise<Context> | Context;\n}\n\n/**\n * Start HTTP server for handler\n */\nexport async function startServer(handlerPath: string, options: ServerOptions = {}): Promise<void> {\n const port = options.port || 3000;\n const host = options.host || 'localhost';\n\n // Load handler or discover registry\n let agents: Record<string, AgentHandler> = {};\n let tools: Record<string, ToolHandler> = {};\n let prompts: Record<string, unknown> = {};\n\n if (isFile(handlerPath)) {\n // Single file handler\n const loaded = await loadHandler(handlerPath);\n agents = loaded.agents || {};\n tools = loaded.tools || {};\n prompts = loaded.prompts || {};\n } else {\n // Directory - auto-discover\n const registry = await discoverRegistry(handlerPath);\n agents = registry.agents;\n tools = registry.tools;\n prompts = registry.prompts;\n }\n\n // Create HTTP server\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n // Set CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n // Handle OPTIONS request\n if (req.method === 'OPTIONS') {\n res.writeHead(200);\n res.end();\n return;\n }\n\n // Parse URL to determine route\n const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n const pathParts = url.pathname.split('/').filter(Boolean);\n\n // Route: /agents/:agentId/invoke\n if (pathParts[0] === 'agents' && pathParts[2] === 'invoke') {\n const agentId = pathParts[1];\n const agent = agents[agentId];\n\n if (!agent) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `Agent not found: ${agentId}` }));\n return;\n }\n\n // Get context (provided by orchestrator or default)\n const context = options.context ? await options.context(req) : createDefaultContext(req);\n\n // Convert HTTP request to handler request\n const handlerReq = await convertHttpToRequest(req);\n\n // Execute agent handler\n const handlerRes = await executeHandler(agent, context, handlerReq);\n\n // Convert handler response to HTTP response\n convertResponseToHttp(handlerRes, res);\n return;\n }\n\n // Route: /tools/:toolId/invoke\n if (pathParts[0] === 'tools' && pathParts[2] === 'invoke') {\n const toolId = pathParts[1];\n const tool = tools[toolId];\n\n if (!tool) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: `Tool not found: ${toolId}` }));\n return;\n }\n\n // Get context\n const context = options.context ? await options.context(req) : createDefaultContext(req);\n\n // Convert HTTP request to handler request\n const handlerReq = await convertHttpToRequest(req);\n\n // Execute tool handler\n const handlerRes = await executeHandler(tool, context, handlerReq);\n\n // Convert handler response to HTTP response\n convertResponseToHttp(handlerRes, res);\n return;\n }\n\n // Route: /health (health check)\n if (pathParts[0] === 'health' || url.pathname === '/') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n status: 'ok',\n agents: Object.keys(agents),\n tools: Object.keys(tools),\n prompts: Object.keys(prompts),\n })\n );\n return;\n }\n\n // 404 for unknown routes\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n } catch (error) {\n convertErrorToHttp(error as Error, res);\n }\n });\n\n // Start server\n server.listen(port, host, () => {\n console.log(`Reminix HTTP adapter listening on http://${host}:${port}`);\n console.log(`Agents: ${Object.keys(agents).join(', ') || 'none'}`);\n console.log(`Tools: ${Object.keys(tools).join(', ') || 'none'}`);\n });\n\n // Handle server errors\n server.on('error', (error: Error) => {\n console.error('Server error:', error);\n });\n}\n\n/**\n * Create default context (for development)\n * In production, this would come from the orchestrator\n */\nfunction createDefaultContext(req: IncomingMessage): Context {\n // Extract chatId from headers or query params\n const chatId =\n req.headers['x-chat-id'] ||\n new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`).searchParams.get(\n 'chatId'\n ) ||\n 'default-chat';\n\n // Return a minimal context (orchestrator will provide full context in production)\n return {\n chatId: chatId as string,\n memory: createMockMemoryStore(),\n knowledgeBase: createMockKnowledgeBase(),\n } as Context;\n}\n\n/**\n * Mock memory store for development\n */\nfunction createMockMemoryStore() {\n const store = new Map<string, unknown>();\n return {\n get: async (key: string) => store.get(key),\n set: async (key: string, value: unknown) => {\n store.set(key, value);\n },\n delete: async (key: string) => {\n store.delete(key);\n },\n clear: async () => {\n store.clear();\n },\n };\n}\n\n/**\n * Mock knowledge base for development\n */\nfunction createMockKnowledgeBase() {\n return {\n search: async (_query: string) => [],\n add: async (_content: string) => {},\n delete: async (_id: string) => {},\n };\n}\n","/**\n * Load handler from file\n */\n\nimport { pathToFileURL } from 'url';\nimport { statSync } from 'fs';\nimport type { AgentHandler, ToolHandler } from './types';\n\nexport interface LoadedHandler {\n agents?: Record<string, AgentHandler>;\n tools?: Record<string, ToolHandler>;\n prompts?: Record<string, unknown>;\n}\n\n/**\n * Load handler from a file path\n * Supports both TypeScript (.ts) and JavaScript (.js) files\n */\nexport async function loadHandler(handlerPath: string): Promise<LoadedHandler> {\n try {\n // Convert file path to file URL for ES modules\n const fileUrl = pathToFileURL(handlerPath).href;\n\n // Dynamic import of the handler module\n const module = await import(fileUrl);\n\n // Extract agents, tools, and prompts\n const loaded: LoadedHandler = {};\n\n if (module.agents) {\n loaded.agents = module.agents;\n }\n\n if (module.tools) {\n loaded.tools = module.tools;\n }\n\n if (module.prompts) {\n loaded.prompts = module.prompts;\n }\n\n // Validate that at least one export exists\n if (!loaded.agents && !loaded.tools && !loaded.prompts) {\n throw new Error(\n `Handler file \"${handlerPath}\" must export at least one of: agents, tools, or prompts`\n );\n }\n\n return loaded;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to load handler from \"${handlerPath}\": ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Check if a path is a file (not a directory)\n */\nexport function isFile(path: string): boolean {\n try {\n const stats = statSync(path);\n return stats.isFile();\n } catch {\n return false;\n }\n}\n","/**\n * Registry for auto-discovering agents, tools, and prompts from directories\n */\n\nimport { readdir, stat } from 'fs/promises';\nimport { join, extname, basename } from 'path';\nimport { pathToFileURL } from 'url';\nimport { loadHandler } from './loader';\nimport type { AgentHandler, ToolHandler } from './types';\n\nexport interface Registry {\n agents: Record<string, AgentHandler>;\n tools: Record<string, ToolHandler>;\n prompts: Record<string, unknown>;\n}\n\n/**\n * Auto-discover and load handlers from a directory structure\n *\n * Expected structure:\n * handler/\n * agents/\n * chatbot.ts\n * assistant.ts\n * tools/\n * search.ts\n * prompts/\n * system.ts\n */\nexport async function discoverRegistry(handlerPath: string): Promise<Registry> {\n const registry: Registry = {\n agents: {},\n tools: {},\n prompts: {},\n };\n\n try {\n // Check if path exists and is a directory\n const stats = await stat(handlerPath);\n if (!stats.isDirectory()) {\n throw new Error(`Handler path must be a directory: ${handlerPath}`);\n }\n\n // Discover agents\n const agentsPath = join(handlerPath, 'agents');\n try {\n const agentsStats = await stat(agentsPath);\n if (agentsStats.isDirectory()) {\n const agents = await loadDirectory(agentsPath);\n // Filter to only AgentHandler types\n for (const [key, value] of Object.entries(agents)) {\n if (typeof value === 'function') {\n registry.agents[key] = value as AgentHandler;\n }\n }\n }\n } catch {\n // agents/ directory doesn't exist, skip\n }\n\n // Discover tools\n const toolsPath = join(handlerPath, 'tools');\n try {\n const toolsStats = await stat(toolsPath);\n if (toolsStats.isDirectory()) {\n const tools = await loadDirectory(toolsPath);\n // Filter to only ToolHandler types\n for (const [key, value] of Object.entries(tools)) {\n if (typeof value === 'function') {\n registry.tools[key] = value as ToolHandler;\n }\n }\n }\n } catch {\n // tools/ directory doesn't exist, skip\n }\n\n // Discover prompts\n const promptsPath = join(handlerPath, 'prompts');\n try {\n const promptsStats = await stat(promptsPath);\n if (promptsStats.isDirectory()) {\n const prompts = await loadDirectory(promptsPath);\n registry.prompts = prompts;\n }\n } catch {\n // prompts/ directory doesn't exist, skip\n }\n\n // Validate that at least something was discovered\n if (\n Object.keys(registry.agents).length === 0 &&\n Object.keys(registry.tools).length === 0 &&\n Object.keys(registry.prompts).length === 0\n ) {\n throw new Error(`No agents, tools, or prompts found in directory: ${handlerPath}`);\n }\n\n return registry;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to discover registry from \"${handlerPath}\": ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Load all handler files from a directory\n * Filename (without extension) becomes the key in the registry\n */\nasync function loadDirectory(\n dirPath: string\n): Promise<Record<string, AgentHandler | ToolHandler | unknown>> {\n const handlers: Record<string, AgentHandler | ToolHandler | unknown> = {};\n\n try {\n const entries = await readdir(dirPath);\n\n for (const entry of entries) {\n const fullPath = join(dirPath, entry);\n const stats = await stat(fullPath);\n\n // Skip if not a file\n if (!stats.isFile()) {\n continue;\n }\n\n // Only process TypeScript/JavaScript files\n const ext = extname(entry);\n if (ext !== '.ts' && ext !== '.js' && ext !== '.mjs') {\n continue;\n }\n\n // Extract the key from filename (without extension)\n const key = entry.replace(ext, '');\n\n try {\n // Try loading as a handler file (expects agents/tools/prompts exports)\n const loaded = await loadHandler(fullPath);\n\n // Merge agents, tools, and prompts into the registry\n if (loaded.agents) {\n const agentKeys = Object.keys(loaded.agents);\n if (agentKeys.length === 1) {\n handlers[key] = loaded.agents[agentKeys[0]];\n } else {\n for (const agentKey of agentKeys) {\n handlers[`${key}.${agentKey}`] = loaded.agents[agentKey];\n }\n }\n }\n\n if (loaded.tools) {\n const toolKeys = Object.keys(loaded.tools);\n if (toolKeys.length === 1) {\n handlers[key] = loaded.tools[toolKeys[0]];\n } else {\n for (const toolKey of toolKeys) {\n handlers[`${key}.${toolKey}`] = loaded.tools[toolKey];\n }\n }\n }\n\n if (loaded.prompts) {\n const promptKeys = Object.keys(loaded.prompts);\n if (promptKeys.length === 1) {\n handlers[key] = loaded.prompts[promptKeys[0]];\n } else {\n for (const promptKey of promptKeys) {\n handlers[`${key}.${promptKey}`] = loaded.prompts[promptKey];\n }\n }\n }\n } catch {\n // If loadHandler fails, try loading as direct export\n // This handles files that export functions directly (e.g., export const chatbot)\n try {\n const fileUrl = pathToFileURL(fullPath).href;\n const module = await import(fileUrl);\n\n // Determine type based on directory name\n const dirName = basename(dirPath);\n\n // Check for direct exports matching the directory type\n if (dirName === 'agents') {\n // Look for exported function with same name as file, or any exported function\n const exportedFunction = module[key] || module.default;\n if (typeof exportedFunction === 'function') {\n handlers[key] = exportedFunction;\n }\n } else if (dirName === 'tools') {\n const exportedFunction = module[key] || module.default;\n if (typeof exportedFunction === 'function') {\n handlers[key] = exportedFunction;\n }\n } else if (dirName === 'prompts') {\n // For prompts, accept any export (function, object, string, etc.)\n // Try to get export with same name as file, or default, or any named export\n const exportedValue = module[key] || module.default;\n if (exportedValue !== undefined) {\n handlers[key] = exportedValue;\n } else {\n // Check if module has any exports (excluding default module properties)\n const moduleKeys = Object.keys(module).filter(\n (k) => k !== 'default' && !k.startsWith('__')\n );\n if (moduleKeys.length > 0) {\n // Use the first export, or the module itself if it's a simple object\n handlers[key] = module[moduleKeys[0]] || module;\n }\n }\n }\n } catch {\n // Skip this file if both methods fail\n continue;\n }\n }\n }\n\n return handlers;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to load directory \"${dirPath}\": ${error.message}`);\n }\n throw error;\n }\n}\n","/**\n * Core handler execution logic\n */\n\nimport type { AgentHandler, ToolHandler, Context, Request, Response } from './types';\n\n/**\n * Execute an agent handler\n */\nexport async function executeAgent(\n handler: AgentHandler,\n context: Context,\n request: Request\n): Promise<Response> {\n return await handler(context, request);\n}\n\n/**\n * Execute a tool handler\n */\nexport async function executeTool(\n handler: ToolHandler,\n context: Context,\n request: Request\n): Promise<Response> {\n return await handler(context, request);\n}\n\n/**\n * Execute a handler (agent or tool)\n */\nexport async function executeHandler(\n handler: AgentHandler | ToolHandler,\n context: Context,\n request: Request\n): Promise<Response> {\n return await handler(context, request);\n}\n","/**\n * Convert between HTTP and Handler formats\n */\n\nimport type { IncomingMessage, ServerResponse } from 'http';\nimport type {\n Request as HandlerRequest,\n Response as HandlerResponse,\n Message,\n} from '@reminix/runtime';\n\n/**\n * Convert HTTP request to Handler Request\n * Extracts messages from HTTP request body\n */\nexport async function convertHttpToRequest(httpReq: IncomingMessage): Promise<HandlerRequest> {\n try {\n // Read request body\n const body = await readRequestBody(httpReq);\n\n // Parse JSON body\n let parsedBody: Record<string, unknown> = {};\n if (body) {\n try {\n parsedBody = JSON.parse(body) as Record<string, unknown>;\n } catch {\n // If not JSON, treat as text\n parsedBody = { content: body };\n }\n }\n\n // Extract messages from body\n // Expected format: { messages: Message[] } or { message: Message } or just Message[]\n let messages: Message[] = [];\n\n if (Array.isArray(parsedBody)) {\n // Body is array of messages\n messages = parsedBody as Message[];\n } else if (parsedBody.messages && Array.isArray(parsedBody.messages)) {\n // Body has messages array\n messages = parsedBody.messages as Message[];\n } else if (parsedBody.message) {\n // Body has single message\n messages = [parsedBody.message as Message];\n } else if (parsedBody.content || parsedBody.role) {\n // Body is a single message object\n messages = [parsedBody as unknown as Message];\n }\n\n // Extract metadata from query params and headers\n const metadata: Record<string, unknown> = {\n method: httpReq.method,\n url: httpReq.url,\n headers: httpReq.headers,\n };\n\n // Add query params to metadata\n if (httpReq.url) {\n const url = new URL(httpReq.url, `http://${httpReq.headers.host || 'localhost'}`);\n const queryParams: Record<string, string> = {};\n url.searchParams.forEach((value, key) => {\n queryParams[key] = value;\n });\n if (Object.keys(queryParams).length > 0) {\n metadata.query = queryParams;\n }\n }\n\n // Merge any additional metadata from body\n if (parsedBody.metadata) {\n Object.assign(metadata, parsedBody.metadata);\n }\n\n return {\n messages,\n metadata,\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to convert HTTP request: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Convert Handler Response to HTTP response\n */\nexport function convertResponseToHttp(handlerRes: HandlerResponse, httpRes: ServerResponse): void {\n try {\n // Set status code (default 200)\n const statusCode =\n typeof handlerRes.metadata?.statusCode === 'number' ? handlerRes.metadata.statusCode : 200;\n httpRes.statusCode = statusCode;\n\n // Set headers\n const headers =\n (handlerRes.metadata?.headers as Record<string, unknown> | undefined) ||\n ({} as Record<string, unknown>);\n headers['Content-Type'] =\n (typeof headers['Content-Type'] === 'string' ? headers['Content-Type'] : undefined) ||\n 'application/json';\n\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n httpRes.setHeader(key, value);\n }\n }\n\n // Prepare response body\n const responseBody = {\n messages: handlerRes.messages,\n ...(handlerRes.metadata && { metadata: handlerRes.metadata }),\n ...(handlerRes.toolCalls && { toolCalls: handlerRes.toolCalls }),\n ...(handlerRes.stateUpdates && { stateUpdates: handlerRes.stateUpdates }),\n };\n\n // Send response\n httpRes.end(JSON.stringify(responseBody));\n } catch (error) {\n if (error instanceof Error) {\n httpRes.statusCode = 500;\n httpRes.setHeader('Content-Type', 'application/json');\n httpRes.end(JSON.stringify({ error: error.message }));\n }\n }\n}\n\n/**\n * Read request body from IncomingMessage\n */\nasync function readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let body = '';\n\n req.on('data', (chunk) => {\n body += chunk.toString();\n });\n\n req.on('end', () => {\n resolve(body);\n });\n\n req.on('error', (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Convert error to HTTP error response\n */\nexport function convertErrorToHttp(error: Error, httpRes: ServerResponse): void {\n httpRes.statusCode = 500;\n httpRes.setHeader('Content-Type', 'application/json');\n httpRes.end(\n JSON.stringify({\n error: error.message,\n ...(process.env.NODE_ENV === 'development' && { stack: error.stack }),\n })\n );\n}\n","/**\n * CLI entry point for Reminix HTTP adapter\n *\n * Usage:\n * npx @reminix/http-adapter serve <handler-path> [options]\n * tsx src/cli.ts serve <handler-path> [options]\n */\n\nimport { startServer, type ServerOptions } from './server';\nimport { parseArgs } from 'util';\nimport { extname } from 'path';\n\n/**\n * Try to register tsx loader for TypeScript support\n * Uses dynamic import which respects Node's module resolution including global packages\n * Returns true if successful, false if tsx is not available\n */\nasync function tryRegisterTsx(): Promise<boolean> {\n try {\n // Use dynamic import to load tsx's ESM API which includes the register function\n // @ts-expect-error - tsx is a runtime dependency, not available at compile time\n const tsx = await import('tsx/esm/api');\n if (tsx && typeof tsx.register === 'function') {\n tsx.register();\n return true;\n }\n } catch {\n // tsx not available\n }\n return false;\n}\n\ninterface CliOptions {\n port?: number;\n host?: string;\n handlerPath: string;\n loader?: string;\n}\n\nfunction parseCliArgs(): CliOptions {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || args[0] !== 'serve') {\n console.error('Usage: reminix-http-adapter serve <handler-path> [options]');\n console.error('');\n console.error('Options:');\n console.error(' --port <number> Port to listen on (default: 3000)');\n console.error(' --host <string> Host to listen on (default: localhost)');\n console.error(' --loader <name> Loader to use for TypeScript support (e.g., tsx)');\n console.error('');\n console.error('Examples:');\n console.error(' npx @reminix/http-adapter serve ./my-handler.ts');\n console.error(' npx @reminix/http-adapter serve ./my-handler.ts --loader tsx');\n console.error(' npx @reminix/http-adapter serve ./my-handler --port 8080');\n process.exit(1);\n }\n\n const handlerPath = args[1];\n if (!handlerPath) {\n console.error('Error: handler-path is required');\n process.exit(1);\n }\n\n const { values } = parseArgs({\n args: args.slice(2),\n options: {\n port: { type: 'string' },\n host: { type: 'string' },\n loader: { type: 'string' },\n },\n });\n\n const options: CliOptions = {\n handlerPath,\n port: values.port ? parseInt(values.port, 10) : undefined,\n host: values.host,\n loader: values.loader,\n };\n\n return options;\n}\n\nasync function main() {\n try {\n const options = parseCliArgs();\n\n // Check if TypeScript support is needed\n const ext = extname(options.handlerPath).toLowerCase();\n const isTypeScript = ext === '.ts' || ext === '.tsx';\n // For directories, we'll check later if they contain .ts files, but register tsx preemptively\n const isDirectory = !ext || ext === '';\n const needsTsx = options.loader === 'tsx' || isTypeScript || (isDirectory && !options.loader);\n\n // Register tsx loader if needed\n if (needsTsx) {\n const registered = await tryRegisterTsx();\n if (!registered) {\n console.error('Error: TypeScript support requires \"tsx\" to be installed.');\n console.error('');\n console.error('To install tsx:');\n console.error(' npm install -g tsx');\n console.error(' # or locally:');\n console.error(' npm install tsx');\n console.error('');\n console.error('Then run:');\n console.error(` npx @reminix/http-adapter serve ${options.handlerPath} --loader tsx`);\n console.error('');\n console.error('Alternatively, use Node.js with --import flag (Node 20.6+):');\n console.error(\n ` node --import tsx node_modules/@reminix/http-adapter/dist/cli.js serve ${options.handlerPath}`\n );\n process.exit(1);\n }\n }\n\n const serverOptions: ServerOptions = {\n port: options.port,\n host: options.host,\n };\n\n await startServer(options.handlerPath, serverOptions);\n } catch (error) {\n console.error('Error starting server:', error);\n process.exit(1);\n }\n}\n\n// Run if called directly\nmain();\n"],"mappings":"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","names":["pathToFileURL","pathToFileURL","extname","extname"]}
|
package/dist/converter.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Convert between HTTP and Handler formats
|
|
3
3
|
*/
|
|
4
4
|
import type { IncomingMessage, ServerResponse } from 'http';
|
|
5
|
-
import type { Request as HandlerRequest, Response as HandlerResponse } from '@reminix/
|
|
5
|
+
import type { Request as HandlerRequest, Response as HandlerResponse } from '@reminix/runtime';
|
|
6
6
|
/**
|
|
7
7
|
* Convert HTTP request to Handler Request
|
|
8
8
|
* Extracts messages from HTTP request body
|
package/dist/converter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../src/converter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../src/converter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,KAAK,EACV,OAAO,IAAI,cAAc,EACzB,QAAQ,IAAI,eAAe,EAE5B,MAAM,kBAAkB,CAAC;AAE1B;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAoE5F;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAsChG;AAuBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAS9E"}
|
package/dist/converter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"converter.js","sourceRoot":"","sources":["../src/converter.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"converter.js","sourceRoot":"","sources":["../src/converter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* @reminix/http-adapter
|
|
3
3
|
* HTTP adapter for Reminix handlers
|
|
4
4
|
*/
|
|
5
|
-
export { loadHandler, isFile, type LoadedHandler } from '
|
|
6
|
-
export { discoverRegistry, type Registry } from './registry';
|
|
5
|
+
export { loadHandler, isFile, discoverRegistry, type LoadedHandler, type Registry, } from '@reminix/runtime';
|
|
7
6
|
export { convertHttpToRequest, convertResponseToHttp, convertErrorToHttp } from './converter';
|
|
8
7
|
export { startServer, type ServerOptions } from './server';
|
|
9
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,WAAW,EACX,MAAM,EACN,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,QAAQ,GACd,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* @reminix/http-adapter
|
|
3
3
|
* HTTP adapter for Reminix handlers
|
|
4
4
|
*/
|
|
5
|
-
export
|
|
6
|
-
export { discoverRegistry } from '
|
|
5
|
+
// Re-export runtime utilities for convenience
|
|
6
|
+
export { loadHandler, isFile, discoverRegistry, } from '@reminix/runtime';
|
|
7
|
+
// HTTP-specific exports
|
|
7
8
|
export { convertHttpToRequest, convertResponseToHttp, convertErrorToHttp } from './converter';
|
|
8
9
|
export { startServer } from './server';
|
|
9
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,OAAO,EACL,WAAW,EACX,MAAM,EACN,gBAAgB,GAGjB,MAAM,kBAAkB,CAAC;AAE1B,wBAAwB;AACxB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAC"}
|
package/dist/server.d.ts
CHANGED
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAgB,eAAe,EAAkB,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAgB,eAAe,EAAkB,MAAM,MAAM,CAAC;AAGrE,OAAO,KAAK,EAAE,OAAO,EAA6B,MAAM,kBAAkB,CAAC;AAE3E,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAChE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6HjG"}
|
package/dist/server.js
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* HTTP server for Reminix handlers
|
|
3
3
|
*/
|
|
4
4
|
import { createServer } from 'http';
|
|
5
|
-
import { loadHandler, isFile } from '
|
|
6
|
-
import { discoverRegistry } from './registry';
|
|
5
|
+
import { loadHandler, isFile, discoverRegistry, executeHandler } from '@reminix/runtime';
|
|
7
6
|
import { convertHttpToRequest, convertResponseToHttp, convertErrorToHttp } from './converter';
|
|
8
7
|
/**
|
|
9
8
|
* Start HTTP server for handler
|
|
@@ -58,8 +57,8 @@ export async function startServer(handlerPath, options = {}) {
|
|
|
58
57
|
const context = options.context ? await options.context(req) : createDefaultContext(req);
|
|
59
58
|
// Convert HTTP request to handler request
|
|
60
59
|
const handlerReq = await convertHttpToRequest(req);
|
|
61
|
-
//
|
|
62
|
-
const handlerRes = await agent
|
|
60
|
+
// Execute agent handler
|
|
61
|
+
const handlerRes = await executeHandler(agent, context, handlerReq);
|
|
63
62
|
// Convert handler response to HTTP response
|
|
64
63
|
convertResponseToHttp(handlerRes, res);
|
|
65
64
|
return;
|
|
@@ -77,8 +76,8 @@ export async function startServer(handlerPath, options = {}) {
|
|
|
77
76
|
const context = options.context ? await options.context(req) : createDefaultContext(req);
|
|
78
77
|
// Convert HTTP request to handler request
|
|
79
78
|
const handlerReq = await convertHttpToRequest(req);
|
|
80
|
-
//
|
|
81
|
-
const handlerRes = await tool
|
|
79
|
+
// Execute tool handler
|
|
80
|
+
const handlerRes = await executeHandler(tool, context, handlerReq);
|
|
82
81
|
// Convert handler response to HTTP response
|
|
83
82
|
convertResponseToHttp(handlerRes, res);
|
|
84
83
|
return;
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAmC,MAAM,MAAM,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reminix/http-adapter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Reminix HTTP adapter for running handlers",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"homepage": "https://github.com/reminix-ai/reminix-typescript",
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"tsx": "^4.21.0",
|
|
37
|
-
"@reminix/
|
|
37
|
+
"@reminix/runtime": "0.3.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^25.0.3",
|
package/dist/loader.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Load handler from file
|
|
3
|
-
*/
|
|
4
|
-
import type { AgentHandler, ToolHandler } from '@reminix/sdk';
|
|
5
|
-
export interface LoadedHandler {
|
|
6
|
-
agents?: Record<string, AgentHandler>;
|
|
7
|
-
tools?: Record<string, ToolHandler>;
|
|
8
|
-
prompts?: Record<string, unknown>;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Load handler from a file path
|
|
12
|
-
* Supports both TypeScript (.ts) and JavaScript (.js) files
|
|
13
|
-
*/
|
|
14
|
-
export declare function loadHandler(handlerPath: string): Promise<LoadedHandler>;
|
|
15
|
-
/**
|
|
16
|
-
* Check if a path is a file (not a directory)
|
|
17
|
-
*/
|
|
18
|
-
export declare function isFile(path: string): boolean;
|
|
19
|
-
//# sourceMappingURL=loader.d.ts.map
|
package/dist/loader.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAqC7E;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO5C"}
|
package/dist/loader.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Load handler from file
|
|
3
|
-
*/
|
|
4
|
-
import { pathToFileURL } from 'url';
|
|
5
|
-
import { statSync } from 'fs';
|
|
6
|
-
/**
|
|
7
|
-
* Load handler from a file path
|
|
8
|
-
* Supports both TypeScript (.ts) and JavaScript (.js) files
|
|
9
|
-
*/
|
|
10
|
-
export async function loadHandler(handlerPath) {
|
|
11
|
-
try {
|
|
12
|
-
// Convert file path to file URL for ES modules
|
|
13
|
-
const fileUrl = pathToFileURL(handlerPath).href;
|
|
14
|
-
// Dynamic import of the handler module
|
|
15
|
-
const module = await import(fileUrl);
|
|
16
|
-
// Extract agents, tools, and prompts
|
|
17
|
-
const loaded = {};
|
|
18
|
-
if (module.agents) {
|
|
19
|
-
loaded.agents = module.agents;
|
|
20
|
-
}
|
|
21
|
-
if (module.tools) {
|
|
22
|
-
loaded.tools = module.tools;
|
|
23
|
-
}
|
|
24
|
-
if (module.prompts) {
|
|
25
|
-
loaded.prompts = module.prompts;
|
|
26
|
-
}
|
|
27
|
-
// Validate that at least one export exists
|
|
28
|
-
if (!loaded.agents && !loaded.tools && !loaded.prompts) {
|
|
29
|
-
throw new Error(`Handler file "${handlerPath}" must export at least one of: agents, tools, or prompts`);
|
|
30
|
-
}
|
|
31
|
-
return loaded;
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
if (error instanceof Error) {
|
|
35
|
-
throw new Error(`Failed to load handler from "${handlerPath}": ${error.message}`);
|
|
36
|
-
}
|
|
37
|
-
throw error;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Check if a path is a file (not a directory)
|
|
42
|
-
*/
|
|
43
|
-
export function isFile(path) {
|
|
44
|
-
try {
|
|
45
|
-
const stats = statSync(path);
|
|
46
|
-
return stats.isFile();
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
//# sourceMappingURL=loader.js.map
|
package/dist/loader.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAS9B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,WAAmB;IACnD,IAAI,CAAC;QACH,+CAA+C;QAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC;QAEhD,uCAAuC;QACvC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QAErC,qCAAqC;QACrC,MAAM,MAAM,GAAkB,EAAE,CAAC;QAEjC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,CAAC;QAED,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC9B,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAClC,CAAC;QAED,2CAA2C;QAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CACb,iBAAiB,WAAW,0DAA0D,CACvF,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,gCAAgC,WAAW,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/registry.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registry for auto-discovering agents, tools, and prompts from directories
|
|
3
|
-
*/
|
|
4
|
-
import type { AgentHandler, ToolHandler } from '@reminix/sdk';
|
|
5
|
-
export interface Registry {
|
|
6
|
-
agents: Record<string, AgentHandler>;
|
|
7
|
-
tools: Record<string, ToolHandler>;
|
|
8
|
-
prompts: Record<string, unknown>;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Auto-discover and load handlers from a directory structure
|
|
12
|
-
*
|
|
13
|
-
* Expected structure:
|
|
14
|
-
* handler/
|
|
15
|
-
* agents/
|
|
16
|
-
* chatbot.ts
|
|
17
|
-
* assistant.ts
|
|
18
|
-
* tools/
|
|
19
|
-
* search.ts
|
|
20
|
-
* prompts/
|
|
21
|
-
* system.ts
|
|
22
|
-
*/
|
|
23
|
-
export declare function discoverRegistry(handlerPath: string): Promise<Registry>;
|
|
24
|
-
//# sourceMappingURL=registry.d.ts.map
|
package/dist/registry.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4E7E"}
|
package/dist/registry.js
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registry for auto-discovering agents, tools, and prompts from directories
|
|
3
|
-
*/
|
|
4
|
-
import { readdir, stat } from 'fs/promises';
|
|
5
|
-
import { join, extname, basename } from 'path';
|
|
6
|
-
import { pathToFileURL } from 'url';
|
|
7
|
-
import { loadHandler } from './loader';
|
|
8
|
-
/**
|
|
9
|
-
* Auto-discover and load handlers from a directory structure
|
|
10
|
-
*
|
|
11
|
-
* Expected structure:
|
|
12
|
-
* handler/
|
|
13
|
-
* agents/
|
|
14
|
-
* chatbot.ts
|
|
15
|
-
* assistant.ts
|
|
16
|
-
* tools/
|
|
17
|
-
* search.ts
|
|
18
|
-
* prompts/
|
|
19
|
-
* system.ts
|
|
20
|
-
*/
|
|
21
|
-
export async function discoverRegistry(handlerPath) {
|
|
22
|
-
const registry = {
|
|
23
|
-
agents: {},
|
|
24
|
-
tools: {},
|
|
25
|
-
prompts: {},
|
|
26
|
-
};
|
|
27
|
-
try {
|
|
28
|
-
// Check if path exists and is a directory
|
|
29
|
-
const stats = await stat(handlerPath);
|
|
30
|
-
if (!stats.isDirectory()) {
|
|
31
|
-
throw new Error(`Handler path must be a directory: ${handlerPath}`);
|
|
32
|
-
}
|
|
33
|
-
// Discover agents
|
|
34
|
-
const agentsPath = join(handlerPath, 'agents');
|
|
35
|
-
try {
|
|
36
|
-
const agentsStats = await stat(agentsPath);
|
|
37
|
-
if (agentsStats.isDirectory()) {
|
|
38
|
-
const agents = await loadDirectory(agentsPath);
|
|
39
|
-
// Filter to only AgentHandler types
|
|
40
|
-
for (const [key, value] of Object.entries(agents)) {
|
|
41
|
-
if (typeof value === 'function') {
|
|
42
|
-
registry.agents[key] = value;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
// agents/ directory doesn't exist, skip
|
|
49
|
-
}
|
|
50
|
-
// Discover tools
|
|
51
|
-
const toolsPath = join(handlerPath, 'tools');
|
|
52
|
-
try {
|
|
53
|
-
const toolsStats = await stat(toolsPath);
|
|
54
|
-
if (toolsStats.isDirectory()) {
|
|
55
|
-
const tools = await loadDirectory(toolsPath);
|
|
56
|
-
// Filter to only ToolHandler types
|
|
57
|
-
for (const [key, value] of Object.entries(tools)) {
|
|
58
|
-
if (typeof value === 'function') {
|
|
59
|
-
registry.tools[key] = value;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// tools/ directory doesn't exist, skip
|
|
66
|
-
}
|
|
67
|
-
// Discover prompts
|
|
68
|
-
const promptsPath = join(handlerPath, 'prompts');
|
|
69
|
-
try {
|
|
70
|
-
const promptsStats = await stat(promptsPath);
|
|
71
|
-
if (promptsStats.isDirectory()) {
|
|
72
|
-
const prompts = await loadDirectory(promptsPath);
|
|
73
|
-
registry.prompts = prompts;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
// prompts/ directory doesn't exist, skip
|
|
78
|
-
}
|
|
79
|
-
// Validate that at least something was discovered
|
|
80
|
-
if (Object.keys(registry.agents).length === 0 &&
|
|
81
|
-
Object.keys(registry.tools).length === 0 &&
|
|
82
|
-
Object.keys(registry.prompts).length === 0) {
|
|
83
|
-
throw new Error(`No agents, tools, or prompts found in directory: ${handlerPath}`);
|
|
84
|
-
}
|
|
85
|
-
return registry;
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
if (error instanceof Error) {
|
|
89
|
-
throw new Error(`Failed to discover registry from "${handlerPath}": ${error.message}`);
|
|
90
|
-
}
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Load all handler files from a directory
|
|
96
|
-
* Filename (without extension) becomes the key in the registry
|
|
97
|
-
*/
|
|
98
|
-
async function loadDirectory(dirPath) {
|
|
99
|
-
const handlers = {};
|
|
100
|
-
try {
|
|
101
|
-
const entries = await readdir(dirPath);
|
|
102
|
-
for (const entry of entries) {
|
|
103
|
-
const fullPath = join(dirPath, entry);
|
|
104
|
-
const stats = await stat(fullPath);
|
|
105
|
-
// Skip if not a file
|
|
106
|
-
if (!stats.isFile()) {
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
// Only process TypeScript/JavaScript files
|
|
110
|
-
const ext = extname(entry);
|
|
111
|
-
if (ext !== '.ts' && ext !== '.js' && ext !== '.mjs') {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
// Extract the key from filename (without extension)
|
|
115
|
-
const key = entry.replace(ext, '');
|
|
116
|
-
try {
|
|
117
|
-
// Try loading as a handler file (expects agents/tools/prompts exports)
|
|
118
|
-
const loaded = await loadHandler(fullPath);
|
|
119
|
-
// Merge agents, tools, and prompts into the registry
|
|
120
|
-
if (loaded.agents) {
|
|
121
|
-
const agentKeys = Object.keys(loaded.agents);
|
|
122
|
-
if (agentKeys.length === 1) {
|
|
123
|
-
handlers[key] = loaded.agents[agentKeys[0]];
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
for (const agentKey of agentKeys) {
|
|
127
|
-
handlers[`${key}.${agentKey}`] = loaded.agents[agentKey];
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (loaded.tools) {
|
|
132
|
-
const toolKeys = Object.keys(loaded.tools);
|
|
133
|
-
if (toolKeys.length === 1) {
|
|
134
|
-
handlers[key] = loaded.tools[toolKeys[0]];
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
for (const toolKey of toolKeys) {
|
|
138
|
-
handlers[`${key}.${toolKey}`] = loaded.tools[toolKey];
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (loaded.prompts) {
|
|
143
|
-
const promptKeys = Object.keys(loaded.prompts);
|
|
144
|
-
if (promptKeys.length === 1) {
|
|
145
|
-
handlers[key] = loaded.prompts[promptKeys[0]];
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
for (const promptKey of promptKeys) {
|
|
149
|
-
handlers[`${key}.${promptKey}`] = loaded.prompts[promptKey];
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
catch {
|
|
155
|
-
// If loadHandler fails, try loading as direct export
|
|
156
|
-
// This handles files that export functions directly (e.g., export const chatbot)
|
|
157
|
-
try {
|
|
158
|
-
const fileUrl = pathToFileURL(fullPath).href;
|
|
159
|
-
const module = await import(fileUrl);
|
|
160
|
-
// Determine type based on directory name
|
|
161
|
-
const dirName = basename(dirPath);
|
|
162
|
-
// Check for direct exports matching the directory type
|
|
163
|
-
if (dirName === 'agents') {
|
|
164
|
-
// Look for exported function with same name as file, or any exported function
|
|
165
|
-
const exportedFunction = module[key] || module.default;
|
|
166
|
-
if (typeof exportedFunction === 'function') {
|
|
167
|
-
handlers[key] = exportedFunction;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
else if (dirName === 'tools') {
|
|
171
|
-
const exportedFunction = module[key] || module.default;
|
|
172
|
-
if (typeof exportedFunction === 'function') {
|
|
173
|
-
handlers[key] = exportedFunction;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
else if (dirName === 'prompts') {
|
|
177
|
-
// For prompts, accept any export (function, object, string, etc.)
|
|
178
|
-
// Try to get export with same name as file, or default, or any named export
|
|
179
|
-
const exportedValue = module[key] || module.default;
|
|
180
|
-
if (exportedValue !== undefined) {
|
|
181
|
-
handlers[key] = exportedValue;
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
// Check if module has any exports (excluding default module properties)
|
|
185
|
-
const moduleKeys = Object.keys(module).filter((k) => k !== 'default' && !k.startsWith('__'));
|
|
186
|
-
if (moduleKeys.length > 0) {
|
|
187
|
-
// Use the first export, or the module itself if it's a simple object
|
|
188
|
-
handlers[key] = module[moduleKeys[0]] || module;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
catch {
|
|
194
|
-
// Skip this file if both methods fail
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return handlers;
|
|
200
|
-
}
|
|
201
|
-
catch (error) {
|
|
202
|
-
if (error instanceof Error) {
|
|
203
|
-
throw new Error(`Failed to load directory "${dirPath}": ${error.message}`);
|
|
204
|
-
}
|
|
205
|
-
throw error;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
//# sourceMappingURL=registry.js.map
|
package/dist/registry.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|