@stdiobus/workers-registry 1.4.10 → 1.4.12
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/launch/index.js +1 -1
- package/launch/index.js.map +2 -2
- package/out/dist/workers-registry/acp-registry/index.js +2 -2
- package/out/dist/workers-registry/acp-registry/index.js.map +3 -3
- package/out/dist/workers-registry/acp-worker/index.js +1 -1
- package/out/dist/workers-registry/acp-worker/index.js.map +2 -2
- package/out/dist/workers-registry/index.d.ts +1 -0
- package/out/dist/workers-registry/index.js +6 -0
- package/out/dist/workers-registry/mcp-to-acp-proxy/proxy.js +1 -1
- package/out/dist/workers-registry/mcp-to-acp-proxy/proxy.js.map +2 -2
- package/out/dist/workers-registry/openai-agent/index.js +4 -0
- package/out/dist/workers-registry/openai-agent/index.js.map +7 -0
- package/out/tsc/workers-registry/acp-worker/src/registry-launcher/config/types.d.ts +2 -0
- package/out/tsc/workers-registry/acp-worker/src/registry-launcher/registry/index.d.ts +45 -0
- package/out/tsc/workers-registry/openai-agent/src/agent.d.ts +26 -0
- package/out/tsc/workers-registry/openai-agent/src/client.d.ts +7 -0
- package/out/tsc/workers-registry/openai-agent/src/config.d.ts +2 -0
- package/out/tsc/workers-registry/openai-agent/src/index.d.ts +11 -0
- package/out/tsc/workers-registry/openai-agent/src/session-id-router.d.ts +21 -0
- package/out/tsc/workers-registry/openai-agent/src/session-manager.d.ts +7 -0
- package/out/tsc/workers-registry/openai-agent/src/session.d.ts +18 -0
- package/out/tsc/workers-registry/openai-agent/src/sse-parser.d.ts +2 -0
- package/out/tsc/workers-registry/openai-agent/src/types.d.ts +43 -0
- package/out/tsc/workers-registry/openai-agent/tests/agent.property.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/agent.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/client.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/config.property.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/config.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/conversion.property.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/error-handling.property.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/session.property.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/session.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/sse-parser.property.test.d.ts +1 -0
- package/out/tsc/workers-registry/openai-agent/tests/sse-parser.test.d.ts +1 -0
- package/package.json +5 -1
package/launch/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{fileURLToPath}from"url";import{dirname,join}from"path";import{readFile}from"fs/promises";var __filename=fileURLToPath(import.meta.url);var __dirname=dirname(__filename);var STDIO_BUS_WORKERS={"acp-worker":{path:"../out/dist/workers-registry/acp-worker/index.js",description:"Full ACP protocol implementation with MCP integration"},"acp-registry":{path:"../out/dist/workers-registry/acp-registry/index.js",description:"Registry Launcher worker for ACP Registry agents"},"echo-worker":{path:"../out/dist/workers-registry/echo-worker/echo-worker.js",description:"Simple echo worker for testing NDJSON protocol"},"mcp-echo-server":{path:"../out/dist/workers-registry/mcp-echo-server/index.js",description:"MCP server example for testing"},"mcp-to-acp-proxy":{path:"../out/dist/workers-registry/mcp-to-acp-proxy/proxy.js",description:"MCP-to-ACP protocol bridge"}};function showUsage(){console.error("Usage: stdiobus <worker-name>");console.error(" node ./node_modules/@stdiobus/workers-registry/launch <worker-name>");console.error("");console.error("Available workers:");for(const[name,config]of Object.entries(STDIO_BUS_WORKERS)){console.error(` - ${name.padEnd(20)} ${config.description}`)}console.error("");console.error("Examples:");console.error(" stdiobus acp-worker");console.error(" stdiobus echo-worker");console.error(" stdiobus mcp-echo-server")}function isValidWorkerName(name){return name in STDIO_BUS_WORKERS}async function main(){const workerName=process.argv[2];if(!workerName){console.error("Error: Worker name is required\n");showUsage();process.exit(1)}if(!isValidWorkerName(workerName)){console.error(`Error: Unknown worker "${workerName}"
|
|
2
|
+
import{fileURLToPath}from"url";import{dirname,join}from"path";import{readFile}from"fs/promises";var __filename=fileURLToPath(import.meta.url);var __dirname=dirname(__filename);var STDIO_BUS_WORKERS={"acp-worker":{path:"../out/dist/workers-registry/acp-worker/index.js",description:"Full ACP protocol implementation with MCP integration"},"acp-registry":{path:"../out/dist/workers-registry/acp-registry/index.js",description:"Registry Launcher worker for ACP Registry agents"},"echo-worker":{path:"../out/dist/workers-registry/echo-worker/echo-worker.js",description:"Simple echo worker for testing NDJSON protocol"},"mcp-echo-server":{path:"../out/dist/workers-registry/mcp-echo-server/index.js",description:"MCP server example for testing"},"mcp-to-acp-proxy":{path:"../out/dist/workers-registry/mcp-to-acp-proxy/proxy.js",description:"MCP-to-ACP protocol bridge"},"openai-agent":{path:"../out/dist/workers-registry/openai-agent/index.js",description:"OpenAI Chat Completions API agent via ACP protocol"}};function showUsage(){console.error("Usage: stdiobus <worker-name>");console.error(" node ./node_modules/@stdiobus/workers-registry/launch <worker-name>");console.error("");console.error("Available workers:");for(const[name,config]of Object.entries(STDIO_BUS_WORKERS)){console.error(` - ${name.padEnd(20)} ${config.description}`)}console.error("");console.error("Examples:");console.error(" stdiobus acp-worker");console.error(" stdiobus echo-worker");console.error(" stdiobus mcp-echo-server")}function isValidWorkerName(name){return name in STDIO_BUS_WORKERS}async function main(){const workerName=process.argv[2];if(!workerName){console.error("Error: Worker name is required\n");showUsage();process.exit(1)}if(!isValidWorkerName(workerName)){console.error(`Error: Unknown worker "${workerName}"
|
|
3
3
|
`);showUsage();process.exit(1)}const workerConfig=STDIO_BUS_WORKERS[workerName];const workerPath=workerConfig.path;const absolutePath=join(__dirname,workerPath);try{await readFile(absolutePath);console.error(`[launcher] Starting worker: ${workerName}`);console.error(`[launcher] Description: ${workerConfig.description}`);console.error(`[launcher] Path: ${absolutePath}`);await import(absolutePath)}catch(error){if(error&&typeof error==="object"&&"code"in error&&error.code==="ENOENT"){console.error(`Error: Worker file not found: ${absolutePath}`);console.error("");console.error('Please run "npm run build" first to compile the workers.');process.exit(1)}const errorMessage=error instanceof Error?error.message:String(error);const errorStack=error instanceof Error?error.stack:void 0;console.error(`Error loading worker "${workerName}":`,errorMessage);if(errorStack){console.error(errorStack)}process.exit(1)}}main().catch(error=>{console.error("Fatal error:",error);process.exit(1)});export{STDIO_BUS_WORKERS,isValidWorkerName,main as launch,showUsage};
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/launch/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../workers-registry/launch/index.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\n/*\n * Apache License 2.0\n * Copyright (c) 2025\u2013present Raman Marozau, Target Insight Function.\n * Contact: raman@worktif.com\n *\n * This file is part of the stdio bus protocol reference implementation:\n * stdio_bus_kernel_workers (target: <target_stdio_bus_kernel_workers>).\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Universal worker launcher for stdio Bus Workers Registry\n *\n * Usage:\n * stdiobus <worker-name>\n * stdiobus acp-worker\n * stdiobus echo-worker\n * stdiobus mcp-echo-server\n *\n * This script dynamically imports and runs the specified worker from the compiled output.\n */\n\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { readFile } from 'fs/promises';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Worker configuration mapping worker names to their entry points\n */\ninterface WorkerConfig {\n readonly path: string;\n readonly description: string;\n}\n\n/**\n * Available workers mapping\n */\nconst STDIO_BUS_WORKERS: Readonly<Record<string, WorkerConfig>> = {\n 'acp-worker': {\n path: '../out/dist/workers-registry/acp-worker/index.js',\n description: 'Full ACP protocol implementation with MCP integration'\n },\n 'acp-registry': {\n path: '../out/dist/workers-registry/acp-registry/index.js',\n description: 'Registry Launcher worker for ACP Registry agents'\n },\n 'echo-worker': {\n path: '../out/dist/workers-registry/echo-worker/echo-worker.js',\n description: 'Simple echo worker for testing NDJSON protocol'\n },\n 'mcp-echo-server': {\n path: '../out/dist/workers-registry/mcp-echo-server/index.js',\n description: 'MCP server example for testing'\n },\n 'mcp-to-acp-proxy': {\n path: '../out/dist/workers-registry/mcp-to-acp-proxy/proxy.js',\n description: 'MCP-to-ACP protocol bridge'\n }\n} as const;\n\n/**\n * Worker name type\n */\ntype WorkerName = keyof typeof STDIO_BUS_WORKERS;\n\n/**\n * Display usage information\n */\nfunction showUsage(): void {\n console.error('Usage: stdiobus <worker-name>');\n console.error(' node ./node_modules/@stdiobus/workers-registry/launch <worker-name>');\n console.error('');\n console.error('Available workers:');\n\n for (const [name, config] of Object.entries(STDIO_BUS_WORKERS)) {\n console.error(` - ${name.padEnd(20)} ${config.description}`);\n }\n\n console.error('');\n console.error('Examples:');\n console.error(' stdiobus acp-worker');\n console.error(' stdiobus echo-worker');\n console.error(' stdiobus mcp-echo-server');\n}\n\n/**\n * Validate worker name\n */\nfunction isValidWorkerName(name: string): name is WorkerName {\n return name in STDIO_BUS_WORKERS;\n}\n\n/**\n * Main entry point\n */\nasync function main(): Promise<void> {\n const workerName = process.argv[2];\n\n // Check if worker name is provided\n if (!workerName) {\n console.error('Error: Worker name is required\\n');\n showUsage();\n process.exit(1);\n }\n\n // Check if worker exists\n if (!isValidWorkerName(workerName)) {\n console.error(`Error: Unknown worker \"${workerName}\"\\n`);\n showUsage();\n process.exit(1);\n }\n\n const workerConfig = STDIO_BUS_WORKERS[workerName];\n const workerPath = workerConfig.path;\n\n // Resolve absolute path\n const absolutePath = join(__dirname, workerPath);\n\n try {\n // Verify the worker file exists\n await readFile(absolutePath);\n\n // Import and run the worker\n console.error(`[launcher] Starting worker: ${workerName}`);\n console.error(`[launcher] Description: ${workerConfig.description}`);\n console.error(`[launcher] Path: ${absolutePath}`);\n\n await import(absolutePath);\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {\n console.error(`Error: Worker file not found: ${absolutePath}`);\n console.error('');\n console.error('Please run \"npm run build\" first to compile the workers.');\n process.exit(1);\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n\n console.error(`Error loading worker \"${workerName}\":`, errorMessage);\n if (errorStack) {\n console.error(errorStack);\n }\n process.exit(1);\n }\n}\n\n// Run main function\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n\n// Export for programmatic usage\nexport { STDIO_BUS_WORKERS, showUsage, isValidWorkerName, main as launch };\nexport type { WorkerConfig, WorkerName };\n"],
|
|
5
|
-
"mappings": ";AAqCA,OAAS,kBAAqB,MAC9B,OAAS,QAAS,SAAY,OAC9B,OAAS,aAAgB,cAEzB,IAAM,WAAa,cAAc,YAAY,GAAG,EAChD,IAAM,UAAY,QAAQ,UAAU,EAapC,IAAM,kBAA4D,CAChE,aAAc,CACZ,KAAM,mDACN,YAAa,uDACf,EACA,eAAgB,CACd,KAAM,qDACN,YAAa,kDACf,EACA,cAAe,CACb,KAAM,0DACN,YAAa,gDACf,EACA,kBAAmB,CACjB,KAAM,wDACN,YAAa,gCACf,EACA,mBAAoB,CAClB,KAAM,yDACN,YAAa,4BACf,CACF,EAUA,SAAS,WAAkB,CACzB,QAAQ,MAAM,+BAA+B,EAC7C,QAAQ,MAAM,4EAA4E,EAC1F,QAAQ,MAAM,EAAE,EAChB,QAAQ,MAAM,oBAAoB,EAElC,SAAW,CAAC,KAAM,MAAM,IAAK,OAAO,QAAQ,iBAAiB,EAAG,CAC9D,QAAQ,MAAM,OAAO,KAAK,OAAO,EAAE,CAAC,IAAI,OAAO,WAAW,EAAE,CAC9D,CAEA,QAAQ,MAAM,EAAE,EAChB,QAAQ,MAAM,WAAW,EACzB,QAAQ,MAAM,uBAAuB,EACrC,QAAQ,MAAM,wBAAwB,EACtC,QAAQ,MAAM,4BAA4B,CAC5C,CAKA,SAAS,kBAAkB,KAAkC,CAC3D,OAAO,QAAQ,iBACjB,CAKA,eAAe,MAAsB,CACnC,MAAM,WAAa,QAAQ,KAAK,CAAC,EAGjC,GAAI,CAAC,WAAY,CACf,QAAQ,MAAM,kCAAkC,EAChD,UAAU,EACV,QAAQ,KAAK,CAAC,CAChB,CAGA,GAAI,CAAC,kBAAkB,UAAU,EAAG,CAClC,QAAQ,MAAM,0BAA0B,UAAU;AAAA,CAAK,EACvD,UAAU,EACV,QAAQ,KAAK,CAAC,CAChB,CAEA,MAAM,aAAe,kBAAkB,UAAU,EACjD,MAAM,WAAa,aAAa,KAGhC,MAAM,aAAe,KAAK,UAAW,UAAU,EAE/C,GAAI,CAEF,MAAM,SAAS,YAAY,EAG3B,QAAQ,MAAM,+BAA+B,UAAU,EAAE,EACzD,QAAQ,MAAM,2BAA2B,aAAa,WAAW,EAAE,EACnE,QAAQ,MAAM,oBAAoB,YAAY,EAAE,EAEhD,MAAM,OAAO,aACf,OAAS,MAAO,CACd,GAAI,OAAS,OAAO,QAAU,UAAY,SAAU,OAAS,MAAM,OAAS,SAAU,CACpF,QAAQ,MAAM,iCAAiC,YAAY,EAAE,EAC7D,QAAQ,MAAM,EAAE,EAChB,QAAQ,MAAM,0DAA0D,EACxE,QAAQ,KAAK,CAAC,CAChB,CAEA,MAAM,aAAe,iBAAiB,MAAQ,MAAM,QAAU,OAAO,KAAK,EAC1E,MAAM,WAAa,iBAAiB,MAAQ,MAAM,MAAQ,OAE1D,QAAQ,MAAM,yBAAyB,UAAU,KAAM,YAAY,EACnE,GAAI,WAAY,CACd,QAAQ,MAAM,UAAU,CAC1B,CACA,QAAQ,KAAK,CAAC,CAChB,CACF,CAGA,KAAK,EAAE,MAAO,OAAU,CACtB,QAAQ,MAAM,eAAgB,KAAK,EACnC,QAAQ,KAAK,CAAC,CAChB,CAAC",
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\n/*\n * Apache License 2.0\n * Copyright (c) 2025\u2013present Raman Marozau, Target Insight Function.\n * Contact: raman@worktif.com\n *\n * This file is part of the stdio bus protocol reference implementation:\n * stdio_bus_kernel_workers (target: <target_stdio_bus_kernel_workers>).\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Universal worker launcher for stdio Bus Workers Registry\n *\n * Usage:\n * stdiobus <worker-name>\n * stdiobus acp-worker\n * stdiobus echo-worker\n * stdiobus mcp-echo-server\n *\n * This script dynamically imports and runs the specified worker from the compiled output.\n */\n\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { readFile } from 'fs/promises';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Worker configuration mapping worker names to their entry points\n */\ninterface WorkerConfig {\n readonly path: string;\n readonly description: string;\n}\n\n/**\n * Available workers mapping\n */\nconst STDIO_BUS_WORKERS: Readonly<Record<string, WorkerConfig>> = {\n 'acp-worker': {\n path: '../out/dist/workers-registry/acp-worker/index.js',\n description: 'Full ACP protocol implementation with MCP integration'\n },\n 'acp-registry': {\n path: '../out/dist/workers-registry/acp-registry/index.js',\n description: 'Registry Launcher worker for ACP Registry agents'\n },\n 'echo-worker': {\n path: '../out/dist/workers-registry/echo-worker/echo-worker.js',\n description: 'Simple echo worker for testing NDJSON protocol'\n },\n 'mcp-echo-server': {\n path: '../out/dist/workers-registry/mcp-echo-server/index.js',\n description: 'MCP server example for testing'\n },\n 'mcp-to-acp-proxy': {\n path: '../out/dist/workers-registry/mcp-to-acp-proxy/proxy.js',\n description: 'MCP-to-ACP protocol bridge'\n },\n 'openai-agent': {\n path: '../out/dist/workers-registry/openai-agent/index.js',\n description: 'OpenAI Chat Completions API agent via ACP protocol'\n }\n} as const;\n\n/**\n * Worker name type\n */\ntype WorkerName = keyof typeof STDIO_BUS_WORKERS;\n\n/**\n * Display usage information\n */\nfunction showUsage(): void {\n console.error('Usage: stdiobus <worker-name>');\n console.error(' node ./node_modules/@stdiobus/workers-registry/launch <worker-name>');\n console.error('');\n console.error('Available workers:');\n\n for (const [name, config] of Object.entries(STDIO_BUS_WORKERS)) {\n console.error(` - ${name.padEnd(20)} ${config.description}`);\n }\n\n console.error('');\n console.error('Examples:');\n console.error(' stdiobus acp-worker');\n console.error(' stdiobus echo-worker');\n console.error(' stdiobus mcp-echo-server');\n}\n\n/**\n * Validate worker name\n */\nfunction isValidWorkerName(name: string): name is WorkerName {\n return name in STDIO_BUS_WORKERS;\n}\n\n/**\n * Main entry point\n */\nasync function main(): Promise<void> {\n const workerName = process.argv[2];\n\n // Check if worker name is provided\n if (!workerName) {\n console.error('Error: Worker name is required\\n');\n showUsage();\n process.exit(1);\n }\n\n // Check if worker exists\n if (!isValidWorkerName(workerName)) {\n console.error(`Error: Unknown worker \"${workerName}\"\\n`);\n showUsage();\n process.exit(1);\n }\n\n const workerConfig = STDIO_BUS_WORKERS[workerName];\n const workerPath = workerConfig.path;\n\n // Resolve absolute path\n const absolutePath = join(__dirname, workerPath);\n\n try {\n // Verify the worker file exists\n await readFile(absolutePath);\n\n // Import and run the worker\n console.error(`[launcher] Starting worker: ${workerName}`);\n console.error(`[launcher] Description: ${workerConfig.description}`);\n console.error(`[launcher] Path: ${absolutePath}`);\n\n await import(absolutePath);\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {\n console.error(`Error: Worker file not found: ${absolutePath}`);\n console.error('');\n console.error('Please run \"npm run build\" first to compile the workers.');\n process.exit(1);\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n\n console.error(`Error loading worker \"${workerName}\":`, errorMessage);\n if (errorStack) {\n console.error(errorStack);\n }\n process.exit(1);\n }\n}\n\n// Run main function\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n\n// Export for programmatic usage\nexport { STDIO_BUS_WORKERS, showUsage, isValidWorkerName, main as launch };\nexport type { WorkerConfig, WorkerName };\n"],
|
|
5
|
+
"mappings": ";AAqCA,OAAS,kBAAqB,MAC9B,OAAS,QAAS,SAAY,OAC9B,OAAS,aAAgB,cAEzB,IAAM,WAAa,cAAc,YAAY,GAAG,EAChD,IAAM,UAAY,QAAQ,UAAU,EAapC,IAAM,kBAA4D,CAChE,aAAc,CACZ,KAAM,mDACN,YAAa,uDACf,EACA,eAAgB,CACd,KAAM,qDACN,YAAa,kDACf,EACA,cAAe,CACb,KAAM,0DACN,YAAa,gDACf,EACA,kBAAmB,CACjB,KAAM,wDACN,YAAa,gCACf,EACA,mBAAoB,CAClB,KAAM,yDACN,YAAa,4BACf,EACA,eAAgB,CACd,KAAM,qDACN,YAAa,oDACf,CACF,EAUA,SAAS,WAAkB,CACzB,QAAQ,MAAM,+BAA+B,EAC7C,QAAQ,MAAM,4EAA4E,EAC1F,QAAQ,MAAM,EAAE,EAChB,QAAQ,MAAM,oBAAoB,EAElC,SAAW,CAAC,KAAM,MAAM,IAAK,OAAO,QAAQ,iBAAiB,EAAG,CAC9D,QAAQ,MAAM,OAAO,KAAK,OAAO,EAAE,CAAC,IAAI,OAAO,WAAW,EAAE,CAC9D,CAEA,QAAQ,MAAM,EAAE,EAChB,QAAQ,MAAM,WAAW,EACzB,QAAQ,MAAM,uBAAuB,EACrC,QAAQ,MAAM,wBAAwB,EACtC,QAAQ,MAAM,4BAA4B,CAC5C,CAKA,SAAS,kBAAkB,KAAkC,CAC3D,OAAO,QAAQ,iBACjB,CAKA,eAAe,MAAsB,CACnC,MAAM,WAAa,QAAQ,KAAK,CAAC,EAGjC,GAAI,CAAC,WAAY,CACf,QAAQ,MAAM,kCAAkC,EAChD,UAAU,EACV,QAAQ,KAAK,CAAC,CAChB,CAGA,GAAI,CAAC,kBAAkB,UAAU,EAAG,CAClC,QAAQ,MAAM,0BAA0B,UAAU;AAAA,CAAK,EACvD,UAAU,EACV,QAAQ,KAAK,CAAC,CAChB,CAEA,MAAM,aAAe,kBAAkB,UAAU,EACjD,MAAM,WAAa,aAAa,KAGhC,MAAM,aAAe,KAAK,UAAW,UAAU,EAE/C,GAAI,CAEF,MAAM,SAAS,YAAY,EAG3B,QAAQ,MAAM,+BAA+B,UAAU,EAAE,EACzD,QAAQ,MAAM,2BAA2B,aAAa,WAAW,EAAE,EACnE,QAAQ,MAAM,oBAAoB,YAAY,EAAE,EAEhD,MAAM,OAAO,aACf,OAAS,MAAO,CACd,GAAI,OAAS,OAAO,QAAU,UAAY,SAAU,OAAS,MAAM,OAAS,SAAU,CACpF,QAAQ,MAAM,iCAAiC,YAAY,EAAE,EAC7D,QAAQ,MAAM,EAAE,EAChB,QAAQ,MAAM,0DAA0D,EACxE,QAAQ,KAAK,CAAC,CAChB,CAEA,MAAM,aAAe,iBAAiB,MAAQ,MAAM,QAAU,OAAO,KAAK,EAC1E,MAAM,WAAa,iBAAiB,MAAQ,MAAM,MAAQ,OAE1D,QAAQ,MAAM,yBAAyB,UAAU,KAAM,YAAY,EACnE,GAAI,WAAY,CACd,QAAQ,MAAM,UAAU,CAC1B,CACA,QAAQ,KAAK,CAAC,CAChB,CACF,CAGA,KAAK,EAAE,MAAO,OAAU,CACtB,QAAQ,MAAM,eAAgB,KAAK,EACnC,QAAQ,KAAK,CAAC,CAChB,CAAC",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var __getOwnPropNames=Object.getOwnPropertyNames;var __esm=(fn,res)=>function __init(){return fn&&(res=(0,fn[__getOwnPropNames(fn)[0]])(fn=0)),res};var DEFAULT_CONFIG;var init_types=__esm({"workers-registry/acp-worker/src/registry-launcher/config/types.ts"(){"use strict";DEFAULT_CONFIG={registryUrl:"https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",apiKeysPath:"./api-keys.json",shutdownTimeoutSec:5}}});import{readFileSync}from"node:fs";function logWarning(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [WARN] [config] ${message}`)}function isNonEmptyString(value){return typeof value==="string"&&value.length>0}function isPositiveNumber(value){return typeof value==="number"&&value>0&&Number.isFinite(value)}function parseConfigObject(obj){const config={...DEFAULT_CONFIG};if(obj===null||typeof obj!=="object"){logWarning("Config file does not contain a valid object, using defaults");return config}const rawConfig=obj;if("registryUrl"in rawConfig){if(isNonEmptyString(rawConfig.registryUrl)){config.registryUrl=rawConfig.registryUrl}else{logWarning('Config field "registryUrl" is not a valid string, using default')}}if("apiKeysPath"in rawConfig){if(isNonEmptyString(rawConfig.apiKeysPath)){config.apiKeysPath=rawConfig.apiKeysPath}else{logWarning('Config field "apiKeysPath" is not a valid string, using default')}}if("shutdownTimeoutSec"in rawConfig){if(isPositiveNumber(rawConfig.shutdownTimeoutSec)){config.shutdownTimeoutSec=rawConfig.shutdownTimeoutSec}else{logWarning('Config field "shutdownTimeoutSec" is not a valid positive number, using default')}}return config}function applyEnvironmentOverrides(config){const envRegistryUrl=process.env[ENV_REGISTRY_URL];const envApiKeysPath=process.env[ENV_API_KEYS_PATH];const overrides={};if(isNonEmptyString(envRegistryUrl)){overrides.registryUrl=envRegistryUrl}if(isNonEmptyString(envApiKeysPath)){overrides.apiKeysPath=envApiKeysPath}return{...config,...overrides}}function loadConfig(configPath){let config={...DEFAULT_CONFIG};if(configPath){try{const fileContent=readFileSync(configPath,"utf-8");const parsed=JSON.parse(fileContent);config=parseConfigObject(parsed)}catch(error){if(error instanceof SyntaxError){logWarning(`Config file "${configPath}" contains malformed JSON, using defaults`)}else if(error.code==="ENOENT"){logWarning(`Config file "${configPath}" not found, using defaults`)}else if(error.code==="EACCES"){logWarning(`Config file "${configPath}" is not readable, using defaults`)}else{logWarning(`Failed to read config file "${configPath}": ${error.message}, using defaults`)}}}config=applyEnvironmentOverrides(config);return config}var ENV_REGISTRY_URL,ENV_API_KEYS_PATH;var init_config=__esm({"workers-registry/acp-worker/src/registry-launcher/config/config.ts"(){"use strict";init_types();ENV_REGISTRY_URL="ACP_REGISTRY_URL";ENV_API_KEYS_PATH="ACP_API_KEYS_PATH"}});import{readFileSync as readFileSync2}from"node:fs";function logWarning2(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [WARN] [api-keys] ${message}`)}function logInfo(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [INFO] [api-keys] ${message}`)}function loadApiKeys(apiKeysPath){try{const fileContent=readFileSync2(apiKeysPath,"utf-8");const parsed=JSON.parse(fileContent);if(!parsed.agents||typeof parsed.agents!=="object"){logWarning2(`API keys file "${apiKeysPath}" does not contain valid "agents" object`);return{}}const agentsWithKeys=Object.entries(parsed.agents).filter(([_,keys])=>keys.apiKey&&keys.apiKey.length>0);logInfo(`Loaded API keys for ${agentsWithKeys.length} agents from "${apiKeysPath}"`);return parsed.agents}catch(error){if(error.code==="ENOENT"){logWarning2(`API keys file "${apiKeysPath}" not found, agents will not be authenticated`)}else if(error instanceof SyntaxError){logWarning2(`API keys file "${apiKeysPath}" contains malformed JSON`)}else{logWarning2(`Failed to read API keys file "${apiKeysPath}": ${error.message}`)}return{}}}function getAgentApiKey(apiKeys,agentId){const keys=apiKeys[agentId];if(!keys||!keys.apiKey||keys.apiKey.length===0){return void 0}return keys.apiKey}var init_api_keys=__esm({"workers-registry/acp-worker/src/registry-launcher/config/api-keys.ts"(){"use strict"}});function getCurrentPlatform(){const platform=process.platform;const arch=process.arch;if(platform==="darwin"&&arch==="arm64")return"darwin-aarch64";if(platform==="darwin"&&arch==="x64")return"darwin-x86_64";if(platform==="linux"&&arch==="arm64")return"linux-aarch64";if(platform==="linux"&&arch==="x64")return"linux-x86_64";if(platform==="win32"&&arch==="arm64")return"windows-aarch64";if(platform==="win32"&&arch==="x64")return"windows-x86_64";return"linux-x86_64"}function resolveBinary(distribution,agentId){const currentPlatform=getCurrentPlatform();const target=distribution[currentPlatform];if(!target){throw new PlatformNotSupportedError(agentId,currentPlatform)}return{command:target.cmd,args:target.args??[],env:target.env}}function resolveNpx(distribution){return{command:"npx",args:[distribution.package,...distribution.args??[]],env:distribution.env}}function resolveUvx(distribution){return{command:"uvx",args:[distribution.package,...distribution.args??[]],env:distribution.env}}function resolve(distribution,agentId){if(distribution.npx){return resolveNpx(distribution.npx)}if(distribution.uvx){return resolveUvx(distribution.uvx)}if(distribution.binary){return resolveBinary(distribution.binary,agentId)}throw new NoDistributionError(agentId)}var PlatformNotSupportedError,NoDistributionError;var init_resolver=__esm({"workers-registry/acp-worker/src/registry-launcher/registry/resolver.ts"(){"use strict";PlatformNotSupportedError=class extends Error{constructor(agentId,platform){super(`Platform not supported: ${platform} for agent ${agentId}`);this.agentId=agentId;this.platform=platform;this.name="PlatformNotSupportedError"}};NoDistributionError=class extends Error{constructor(agentId){super(`No supported distribution type for agent ${agentId}`);this.agentId=agentId;this.name="NoDistributionError"}}}});function logError(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [ERROR] [registry] ${message}`)}function logInfo2(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [INFO] [registry] ${message}`)}function isNonEmptyString2(value){return typeof value==="string"&&value.length>0}function isValidDistribution(value){if(value===null||typeof value!=="object"){return false}const dist=value;const hasBinary=dist.binary!==void 0&&typeof dist.binary==="object";const hasNpx=dist.npx!==void 0&&typeof dist.npx==="object";const hasUvx=dist.uvx!==void 0&&typeof dist.uvx==="object";if(!hasBinary&&!hasNpx&&!hasUvx){return false}if(hasNpx){const npx=dist.npx;if(!isNonEmptyString2(npx.package)){return false}}if(hasUvx){const uvx=dist.uvx;if(!isNonEmptyString2(uvx.package)){return false}}return true}function parseAgent(value,index){if(value===null||typeof value!=="object"){throw new RegistryParseError(`Agent at index ${index} is not an object`)}const raw=value;if(!isNonEmptyString2(raw.id)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "id" field`)}if(!isNonEmptyString2(raw.name)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "name" field`)}if(!isNonEmptyString2(raw.version)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "version" field`)}if(!isValidDistribution(raw.distribution)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "distribution" field`)}const agent={id:raw.id,name:raw.name,version:raw.version,distribution:raw.distribution};if(typeof raw.description==="string"){agent.description=raw.description}if(typeof raw.repository==="string"){agent.repository=raw.repository}if(Array.isArray(raw.authors)){agent.authors=raw.authors.filter(a=>typeof a==="string")}if(typeof raw.license==="string"){agent.license=raw.license}if(typeof raw.icon==="string"){agent.icon=raw.icon}return agent}function parseRegistry(data){if(data===null||typeof data!=="object"){throw new RegistryParseError("Registry data is not an object")}const raw=data;if(!isNonEmptyString2(raw.version)){throw new RegistryParseError('Registry has invalid or missing "version" field')}if(!Array.isArray(raw.agents)){throw new RegistryParseError('Registry has invalid or missing "agents" field')}const agents=[];for(let i=0;i<raw.agents.length;i++){agents.push(parseAgent(raw.agents[i],i))}return{version:raw.version,agents}}var ENV_REGISTRY_URL2,RegistryFetchError,RegistryParseError,AgentNotFoundError,RegistryIndex;var init_registry=__esm({"workers-registry/acp-worker/src/registry-launcher/registry/index.ts"(){"use strict";init_resolver();init_resolver();ENV_REGISTRY_URL2="ACP_REGISTRY_URL";RegistryFetchError=class extends Error{constructor(message,cause){super(message);this.cause=cause;this.name="RegistryFetchError"}};RegistryParseError=class extends Error{constructor(message,cause){super(message);this.cause=cause;this.name="RegistryParseError"}};AgentNotFoundError=class extends Error{constructor(agentId){super(`Agent not found: ${agentId}`);this.agentId=agentId;this.name="AgentNotFoundError"}};RegistryIndex=class{registryUrl;registry=null;agentMap=new Map;constructor(registryUrl){const envUrl=process.env[ENV_REGISTRY_URL2];this.registryUrl=isNonEmptyString2(envUrl)?envUrl:registryUrl}async fetch(){logInfo2(`Fetching registry from ${this.registryUrl}`);let response;try{response=await fetch(this.registryUrl)}catch(error){const message=`Failed to fetch registry from ${this.registryUrl}: ${error.message}`;logError(message);throw new RegistryFetchError(message,error)}if(!response.ok){const message=`Failed to fetch registry from ${this.registryUrl}: HTTP ${response.status} ${response.statusText}`;logError(message);throw new RegistryFetchError(message)}let text;try{text=await response.text()}catch(error){const message=`Failed to read registry response body: ${error.message}`;logError(message);throw new RegistryFetchError(message,error)}let data;try{data=JSON.parse(text)}catch(error){const message=`Failed to parse registry JSON: ${error.message}`;logError(message);throw new RegistryParseError(message,error)}try{this.registry=parseRegistry(data)}catch(error){if(error instanceof RegistryParseError){logError(error.message);throw error}const message=`Failed to validate registry data: ${error.message}`;logError(message);throw new RegistryParseError(message,error)}this.agentMap.clear();for(const agent of this.registry.agents){this.agentMap.set(agent.id,agent)}logInfo2(`Registry loaded: version ${this.registry.version}, ${this.registry.agents.length} agents`)}lookup(agentId){return this.agentMap.get(agentId)}resolve(agentId){const agent=this.lookup(agentId);if(!agent){throw new AgentNotFoundError(agentId)}return resolve(agent.distribution,agentId)}getRegistry(){return this.registry}}}});function logError2(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [ERROR] [ndjson] ${message}`)}var NDJSONHandler;var init_ndjson_handler=__esm({"workers-registry/acp-worker/src/registry-launcher/stream/ndjson-handler.ts"(){"use strict";NDJSONHandler=class{buffer="";output;messageCallback=null;errorCallback=null;constructor(output){this.output=output}onMessage(callback){this.messageCallback=callback}onError(callback){this.errorCallback=callback}write(message){if(!this.output.writable){return false}try{const json=JSON.stringify(message);this.output.write(json+"\n");return true}catch{return false}}processChunk(chunk){this.buffer+=chunk.toString("utf-8");this.processBuffer()}processBuffer(){let newlineIndex;while((newlineIndex=this.buffer.indexOf("\n"))!==-1){const line=this.buffer.slice(0,newlineIndex);this.buffer=this.buffer.slice(newlineIndex+1);if(line.trim().length===0){continue}this.parseLine(line)}}parseLine(line){try{const message=JSON.parse(line);if(message===null||typeof message!=="object"){const error=new Error("Parsed JSON is not an object");logError2(`Malformed NDJSON line (not an object): ${this.truncateLine(line)}`);this.errorCallback?.(error,line);return}this.messageCallback?.(message)}catch(error){logError2(`Failed to parse NDJSON line: ${this.truncateLine(line)}`);this.errorCallback?.(error,line)}}truncateLine(line,maxLength=100){if(line.length<=maxLength){return line}return line.slice(0,maxLength)+"..."}}}});import{spawn}from"child_process";var DEFAULT_TERMINATE_TIMEOUT_MS,AgentRuntimeImpl;var init_agent_runtime=__esm({"workers-registry/acp-worker/src/registry-launcher/runtime/agent-runtime.ts"(){"use strict";DEFAULT_TERMINATE_TIMEOUT_MS=5e3;AgentRuntimeImpl=class _AgentRuntimeImpl{agentId;state;process;onExitCallback;constructor(agentId,process2,onExit){this.agentId=agentId;this.process=process2;this.state="starting";this.onExitCallback=onExit;this.setupProcessHandlers()}static spawn(agentId,spawnCommand,onExit){const childProcess=spawn(spawnCommand.command,spawnCommand.args,{stdio:["pipe","pipe","pipe"],env:{...process.env,...spawnCommand.env},detached:false});if(childProcess.stdout){childProcess.stdout.setEncoding("utf8")}if(childProcess.stderr){childProcess.stderr.setEncoding("utf8")}return new _AgentRuntimeImpl(agentId,childProcess,onExit)}setupProcessHandlers(){this.process.on("spawn",()=>{if(this.state==="starting"){this.state="running"}});this.process.on("error",error=>{this.state="stopped";process.stderr.write(`[${new Date().toISOString()}] ERROR: Agent ${this.agentId} process error: ${error.message}
|
|
2
|
+
var __getOwnPropNames=Object.getOwnPropertyNames;var __esm=(fn,res)=>function __init(){return fn&&(res=(0,fn[__getOwnPropNames(fn)[0]])(fn=0)),res};var DEFAULT_CONFIG;var init_types=__esm({"workers-registry/acp-worker/src/registry-launcher/config/types.ts"(){"use strict";DEFAULT_CONFIG={registryUrl:"https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",apiKeysPath:"./api-keys.json",shutdownTimeoutSec:5}}});import{readFileSync}from"node:fs";function logWarning(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [WARN] [config] ${message}`)}function isNonEmptyString(value){return typeof value==="string"&&value.length>0}function isPositiveNumber(value){return typeof value==="number"&&value>0&&Number.isFinite(value)}function parseConfigObject(obj){const config={...DEFAULT_CONFIG};if(obj===null||typeof obj!=="object"){logWarning("Config file does not contain a valid object, using defaults");return config}const rawConfig=obj;if("registryUrl"in rawConfig){if(isNonEmptyString(rawConfig.registryUrl)){config.registryUrl=rawConfig.registryUrl}else{logWarning('Config field "registryUrl" is not a valid string, using default')}}if("apiKeysPath"in rawConfig){if(isNonEmptyString(rawConfig.apiKeysPath)){config.apiKeysPath=rawConfig.apiKeysPath}else{logWarning('Config field "apiKeysPath" is not a valid string, using default')}}if("shutdownTimeoutSec"in rawConfig){if(isPositiveNumber(rawConfig.shutdownTimeoutSec)){config.shutdownTimeoutSec=rawConfig.shutdownTimeoutSec}else{logWarning('Config field "shutdownTimeoutSec" is not a valid positive number, using default')}}if("customAgentsPath"in rawConfig){if(isNonEmptyString(rawConfig.customAgentsPath)){config.customAgentsPath=rawConfig.customAgentsPath}else{logWarning('Config field "customAgentsPath" is not a valid string, ignoring')}}return config}function applyEnvironmentOverrides(config){const envRegistryUrl=process.env[ENV_REGISTRY_URL];const envApiKeysPath=process.env[ENV_API_KEYS_PATH];const envCustomAgentsPath=process.env[ENV_CUSTOM_AGENTS_PATH];const overrides={};if(isNonEmptyString(envRegistryUrl)){overrides.registryUrl=envRegistryUrl}if(isNonEmptyString(envApiKeysPath)){overrides.apiKeysPath=envApiKeysPath}if(isNonEmptyString(envCustomAgentsPath)){overrides.customAgentsPath=envCustomAgentsPath}return{...config,...overrides}}function loadConfig(configPath){let config={...DEFAULT_CONFIG};if(configPath){try{const fileContent=readFileSync(configPath,"utf-8");const parsed=JSON.parse(fileContent);config=parseConfigObject(parsed)}catch(error){if(error instanceof SyntaxError){logWarning(`Config file "${configPath}" contains malformed JSON, using defaults`)}else if(error.code==="ENOENT"){logWarning(`Config file "${configPath}" not found, using defaults`)}else if(error.code==="EACCES"){logWarning(`Config file "${configPath}" is not readable, using defaults`)}else{logWarning(`Failed to read config file "${configPath}": ${error.message}, using defaults`)}}}config=applyEnvironmentOverrides(config);return config}var ENV_REGISTRY_URL,ENV_API_KEYS_PATH,ENV_CUSTOM_AGENTS_PATH;var init_config=__esm({"workers-registry/acp-worker/src/registry-launcher/config/config.ts"(){"use strict";init_types();ENV_REGISTRY_URL="ACP_REGISTRY_URL";ENV_API_KEYS_PATH="ACP_API_KEYS_PATH";ENV_CUSTOM_AGENTS_PATH="ACP_CUSTOM_AGENTS_PATH"}});import{readFileSync as readFileSync2}from"node:fs";function logWarning2(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [WARN] [api-keys] ${message}`)}function logInfo(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [INFO] [api-keys] ${message}`)}function loadApiKeys(apiKeysPath){try{const fileContent=readFileSync2(apiKeysPath,"utf-8");const parsed=JSON.parse(fileContent);if(!parsed.agents||typeof parsed.agents!=="object"){logWarning2(`API keys file "${apiKeysPath}" does not contain valid "agents" object`);return{}}const agentsWithKeys=Object.entries(parsed.agents).filter(([_,keys])=>keys.apiKey&&keys.apiKey.length>0);logInfo(`Loaded API keys for ${agentsWithKeys.length} agents from "${apiKeysPath}"`);return parsed.agents}catch(error){if(error.code==="ENOENT"){logWarning2(`API keys file "${apiKeysPath}" not found, agents will not be authenticated`)}else if(error instanceof SyntaxError){logWarning2(`API keys file "${apiKeysPath}" contains malformed JSON`)}else{logWarning2(`Failed to read API keys file "${apiKeysPath}": ${error.message}`)}return{}}}function getAgentApiKey(apiKeys,agentId){const keys=apiKeys[agentId];if(!keys||!keys.apiKey||keys.apiKey.length===0){return void 0}return keys.apiKey}var init_api_keys=__esm({"workers-registry/acp-worker/src/registry-launcher/config/api-keys.ts"(){"use strict"}});function getCurrentPlatform(){const platform=process.platform;const arch=process.arch;if(platform==="darwin"&&arch==="arm64")return"darwin-aarch64";if(platform==="darwin"&&arch==="x64")return"darwin-x86_64";if(platform==="linux"&&arch==="arm64")return"linux-aarch64";if(platform==="linux"&&arch==="x64")return"linux-x86_64";if(platform==="win32"&&arch==="arm64")return"windows-aarch64";if(platform==="win32"&&arch==="x64")return"windows-x86_64";return"linux-x86_64"}function resolveBinary(distribution,agentId){const currentPlatform=getCurrentPlatform();const target=distribution[currentPlatform];if(!target){throw new PlatformNotSupportedError(agentId,currentPlatform)}return{command:target.cmd,args:target.args??[],env:target.env}}function resolveNpx(distribution){return{command:"npx",args:[distribution.package,...distribution.args??[]],env:distribution.env}}function resolveUvx(distribution){return{command:"uvx",args:[distribution.package,...distribution.args??[]],env:distribution.env}}function resolve(distribution,agentId){if(distribution.npx){return resolveNpx(distribution.npx)}if(distribution.uvx){return resolveUvx(distribution.uvx)}if(distribution.binary){return resolveBinary(distribution.binary,agentId)}throw new NoDistributionError(agentId)}var PlatformNotSupportedError,NoDistributionError;var init_resolver=__esm({"workers-registry/acp-worker/src/registry-launcher/registry/resolver.ts"(){"use strict";PlatformNotSupportedError=class extends Error{constructor(agentId,platform){super(`Platform not supported: ${platform} for agent ${agentId}`);this.agentId=agentId;this.platform=platform;this.name="PlatformNotSupportedError"}};NoDistributionError=class extends Error{constructor(agentId){super(`No supported distribution type for agent ${agentId}`);this.agentId=agentId;this.name="NoDistributionError"}}}});import{readFileSync as readFileSync3}from"node:fs";function logError(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [ERROR] [registry] ${message}`)}function logInfo2(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [INFO] [registry] ${message}`)}function isNonEmptyString2(value){return typeof value==="string"&&value.length>0}function isValidDistribution(value){if(value===null||typeof value!=="object"){return false}const dist=value;const hasBinary=dist.binary!==void 0&&typeof dist.binary==="object";const hasNpx=dist.npx!==void 0&&typeof dist.npx==="object";const hasUvx=dist.uvx!==void 0&&typeof dist.uvx==="object";if(!hasBinary&&!hasNpx&&!hasUvx){return false}if(hasNpx){const npx=dist.npx;if(!isNonEmptyString2(npx.package)){return false}}if(hasUvx){const uvx=dist.uvx;if(!isNonEmptyString2(uvx.package)){return false}}return true}function parseAgent(value,index){if(value===null||typeof value!=="object"){throw new RegistryParseError(`Agent at index ${index} is not an object`)}const raw=value;if(!isNonEmptyString2(raw.id)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "id" field`)}if(!isNonEmptyString2(raw.name)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "name" field`)}if(!isNonEmptyString2(raw.version)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "version" field`)}if(!isValidDistribution(raw.distribution)){throw new RegistryParseError(`Agent at index ${index} has invalid or missing "distribution" field`)}const agent={id:raw.id,name:raw.name,version:raw.version,distribution:raw.distribution};if(typeof raw.description==="string"){agent.description=raw.description}if(typeof raw.repository==="string"){agent.repository=raw.repository}if(Array.isArray(raw.authors)){agent.authors=raw.authors.filter(a=>typeof a==="string")}if(typeof raw.license==="string"){agent.license=raw.license}if(typeof raw.icon==="string"){agent.icon=raw.icon}return agent}function parseRegistry(data){if(data===null||typeof data!=="object"){throw new RegistryParseError("Registry data is not an object")}const raw=data;if(!isNonEmptyString2(raw.version)){throw new RegistryParseError('Registry has invalid or missing "version" field')}if(!Array.isArray(raw.agents)){throw new RegistryParseError('Registry has invalid or missing "agents" field')}const agents=[];for(let i=0;i<raw.agents.length;i++){agents.push(parseAgent(raw.agents[i],i))}return{version:raw.version,agents}}function loadCustomAgents(filePath){let fileContent;try{fileContent=readFileSync3(filePath,"utf-8")}catch(error){if(error.code==="ENOENT"){throw new CustomAgentsLoadError(`Custom agents file not found: ${filePath}`)}if(error.code==="EACCES"){throw new CustomAgentsLoadError(`Custom agents file not readable: ${filePath}`)}throw new CustomAgentsLoadError(`Failed to read custom agents file "${filePath}": ${error.message}`,error)}let data;try{data=JSON.parse(fileContent)}catch(error){throw new CustomAgentsLoadError(`Custom agents file "${filePath}" contains malformed JSON: ${error.message}`,error)}if(data===null||typeof data!=="object"){throw new CustomAgentsLoadError(`Custom agents file "${filePath}" does not contain a valid object`)}const raw=data;if(!Array.isArray(raw.agents)){throw new CustomAgentsLoadError(`Custom agents file "${filePath}" does not contain a valid "agents" array`)}const registryData={version:"custom",agents:raw.agents};const parsed=parseRegistry(registryData);return parsed.agents}var ENV_REGISTRY_URL2,RegistryFetchError,RegistryParseError,AgentNotFoundError,RegistryIndex,CustomAgentsLoadError;var init_registry=__esm({"workers-registry/acp-worker/src/registry-launcher/registry/index.ts"(){"use strict";init_resolver();init_resolver();ENV_REGISTRY_URL2="ACP_REGISTRY_URL";RegistryFetchError=class extends Error{constructor(message,cause){super(message);this.cause=cause;this.name="RegistryFetchError"}};RegistryParseError=class extends Error{constructor(message,cause){super(message);this.cause=cause;this.name="RegistryParseError"}};AgentNotFoundError=class extends Error{constructor(agentId){super(`Agent not found: ${agentId}`);this.agentId=agentId;this.name="AgentNotFoundError"}};RegistryIndex=class{registryUrl;registry=null;agentMap=new Map;constructor(registryUrl){const envUrl=process.env[ENV_REGISTRY_URL2];this.registryUrl=isNonEmptyString2(envUrl)?envUrl:registryUrl}async fetch(){logInfo2(`Fetching registry from ${this.registryUrl}`);let response;try{response=await fetch(this.registryUrl)}catch(error){const message=`Failed to fetch registry from ${this.registryUrl}: ${error.message}`;logError(message);throw new RegistryFetchError(message,error)}if(!response.ok){const message=`Failed to fetch registry from ${this.registryUrl}: HTTP ${response.status} ${response.statusText}`;logError(message);throw new RegistryFetchError(message)}let text;try{text=await response.text()}catch(error){const message=`Failed to read registry response body: ${error.message}`;logError(message);throw new RegistryFetchError(message,error)}let data;try{data=JSON.parse(text)}catch(error){const message=`Failed to parse registry JSON: ${error.message}`;logError(message);throw new RegistryParseError(message,error)}try{this.registry=parseRegistry(data)}catch(error){if(error instanceof RegistryParseError){logError(error.message);throw error}const message=`Failed to validate registry data: ${error.message}`;logError(message);throw new RegistryParseError(message,error)}this.agentMap.clear();for(const agent of this.registry.agents){this.agentMap.set(agent.id,agent)}logInfo2(`Registry loaded: version ${this.registry.version}, ${this.registry.agents.length} agents`)}lookup(agentId){return this.agentMap.get(agentId)}resolve(agentId){const agent=this.lookup(agentId);if(!agent){throw new AgentNotFoundError(agentId)}return resolve(agent.distribution,agentId)}getRegistry(){return this.registry}mergeCustomAgents(agents){if(agents.length===0){return}if(!this.registry){this.registry={version:"custom",agents:[]}}for(const agent of agents){const existingIndex=this.registry.agents.findIndex(a=>a.id===agent.id);if(existingIndex!==-1){this.registry.agents[existingIndex]=agent;logInfo2(`Custom agent "${agent.id}" overrides remote registry entry`)}else{this.registry.agents.push(agent);logInfo2(`Custom agent "${agent.id}" added to registry`)}this.agentMap.set(agent.id,agent)}logInfo2(`Registry now contains ${this.registry.agents.length} agents (${agents.length} custom)`)}};CustomAgentsLoadError=class extends Error{constructor(message,cause){super(message);this.cause=cause;this.name="CustomAgentsLoadError"}}}});function logError2(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [ERROR] [ndjson] ${message}`)}var NDJSONHandler;var init_ndjson_handler=__esm({"workers-registry/acp-worker/src/registry-launcher/stream/ndjson-handler.ts"(){"use strict";NDJSONHandler=class{buffer="";output;messageCallback=null;errorCallback=null;constructor(output){this.output=output}onMessage(callback){this.messageCallback=callback}onError(callback){this.errorCallback=callback}write(message){if(!this.output.writable){return false}try{const json=JSON.stringify(message);this.output.write(json+"\n");return true}catch{return false}}processChunk(chunk){this.buffer+=chunk.toString("utf-8");this.processBuffer()}processBuffer(){let newlineIndex;while((newlineIndex=this.buffer.indexOf("\n"))!==-1){const line=this.buffer.slice(0,newlineIndex);this.buffer=this.buffer.slice(newlineIndex+1);if(line.trim().length===0){continue}this.parseLine(line)}}parseLine(line){try{const message=JSON.parse(line);if(message===null||typeof message!=="object"){const error=new Error("Parsed JSON is not an object");logError2(`Malformed NDJSON line (not an object): ${this.truncateLine(line)}`);this.errorCallback?.(error,line);return}this.messageCallback?.(message)}catch(error){logError2(`Failed to parse NDJSON line: ${this.truncateLine(line)}`);this.errorCallback?.(error,line)}}truncateLine(line,maxLength=100){if(line.length<=maxLength){return line}return line.slice(0,maxLength)+"..."}}}});import{spawn}from"child_process";var DEFAULT_TERMINATE_TIMEOUT_MS,AgentRuntimeImpl;var init_agent_runtime=__esm({"workers-registry/acp-worker/src/registry-launcher/runtime/agent-runtime.ts"(){"use strict";DEFAULT_TERMINATE_TIMEOUT_MS=5e3;AgentRuntimeImpl=class _AgentRuntimeImpl{agentId;state;process;onExitCallback;constructor(agentId,process2,onExit){this.agentId=agentId;this.process=process2;this.state="starting";this.onExitCallback=onExit;this.setupProcessHandlers()}static spawn(agentId,spawnCommand,onExit){const childProcess=spawn(spawnCommand.command,spawnCommand.args,{stdio:["pipe","pipe","pipe"],env:{...process.env,...spawnCommand.env},detached:false});if(childProcess.stdout){childProcess.stdout.setEncoding("utf8")}if(childProcess.stderr){childProcess.stderr.setEncoding("utf8")}return new _AgentRuntimeImpl(agentId,childProcess,onExit)}setupProcessHandlers(){this.process.on("spawn",()=>{if(this.state==="starting"){this.state="running"}});this.process.on("error",error=>{this.state="stopped";process.stderr.write(`[${new Date().toISOString()}] ERROR: Agent ${this.agentId} process error: ${error.message}
|
|
3
3
|
`)});this.process.on("exit",(code,signal)=>{this.state="stopped";if(this.onExitCallback){this.onExitCallback(code,signal)}});if(this.process.stdin){this.process.stdin.on("error",error=>{process.stderr.write(`[${new Date().toISOString()}] WARN: Agent ${this.agentId} stdin error: ${error.message}
|
|
4
|
-
`)})}}write(message){if(this.state!=="running"&&this.state!=="starting"){return false}if(!this.process.stdin||this.process.stdin.destroyed){return false}try{const ndjsonLine=JSON.stringify(message)+"\n";return this.process.stdin.write(ndjsonLine)}catch{return false}}async terminate(timeout=DEFAULT_TERMINATE_TIMEOUT_MS){if(this.state==="stopped"){return}if(this.state==="stopping"){return this.waitForExit()}this.state="stopping";if(this.process.stdin&&!this.process.stdin.destroyed){this.process.stdin.end()}this.process.kill("SIGTERM");const exitPromise=this.waitForExit();const timeoutPromise=new Promise(resolve2=>{setTimeout(()=>resolve2("timeout"),timeout)});const result=await Promise.race([exitPromise,timeoutPromise]);if(result==="timeout"&&!this.process.killed&&this.process.exitCode===null){this.process.kill("SIGKILL");await this.waitForExit()}}waitForExit(){if(this.state==="stopped"){return Promise.resolve()}return new Promise(resolve2=>{this.process.once("exit",()=>{resolve2()})})}}}});var DEFAULT_SHUTDOWN_TIMEOUT_MS,AgentRuntimeManager;var init_manager=__esm({"workers-registry/acp-worker/src/registry-launcher/runtime/manager.ts"(){"use strict";init_agent_runtime();DEFAULT_SHUTDOWN_TIMEOUT_MS=5e3;AgentRuntimeManager=class{runtimes=new Map;exitCallbacks=[];async getOrSpawn(agentId,spawnCommand){const existing=this.runtimes.get(agentId);if(existing&&existing.state!=="stopped"){return existing}const runtime=AgentRuntimeImpl.spawn(agentId,spawnCommand,(code,_signal)=>{this.handleAgentExit(agentId,code)});this.runtimes.set(agentId,runtime);return runtime}get(agentId){return this.runtimes.get(agentId)}async terminate(agentId,timeout=DEFAULT_SHUTDOWN_TIMEOUT_MS){const runtime=this.runtimes.get(agentId);if(!runtime){return}await runtime.terminate(timeout);this.runtimes.delete(agentId)}async terminateAll(timeout=DEFAULT_SHUTDOWN_TIMEOUT_MS){const terminatePromises=[];for(const[agentId,runtime]of this.runtimes){if(runtime.state!=="stopped"){terminatePromises.push(runtime.terminate(timeout).then(()=>{this.runtimes.delete(agentId)}))}}await Promise.all(terminatePromises)}onAgentExit(callback){this.exitCallbacks.push(callback)}handleAgentExit(agentId,code){this.runtimes.delete(agentId);for(const callback of this.exitCallbacks){try{callback(agentId,code)}catch{}}}get size(){return this.runtimes.size}has(agentId){return this.runtimes.has(agentId)}}}});function logError3(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [ERROR] [router] ${message}`)}function logInfo3(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [INFO] [router] ${message}`)}function createErrorResponse(id,code,message,data){const response={jsonrpc:"2.0",id,error:{code,message}};if(data!==void 0){response.error.data=data}return response}function extractAgentId(message){const msg=message;const agentId=msg.agentId;if(typeof agentId==="string"&&agentId.length>0){return agentId}return void 0}function extractId(message){const msg=message;const id=msg.id;if(typeof id==="string"||typeof id==="number"){return id}return null}function transformMessage(message){const{agentId:_,...rest}=message;return rest}var RoutingErrorCodes,MessageRouter;var init_message_router=__esm({"workers-registry/acp-worker/src/registry-launcher/router/message-router.ts"(){"use strict";init_registry();init_api_keys();RoutingErrorCodes={MISSING_AGENT_ID:-32600,AGENT_NOT_FOUND:-32001,PLATFORM_NOT_SUPPORTED:-32002,SPAWN_FAILED:-32003};MessageRouter=class{registry;runtimeManager;writeCallback;apiKeys;pendingRequests=new Map;authState=new Map;sessionIdMap=new Map;constructor(registry,runtimeManager,writeCallback,apiKeys={}){this.registry=registry;this.runtimeManager=runtimeManager;this.writeCallback=writeCallback;this.apiKeys=apiKeys}async route(message){const id=extractId(message);const agentId=extractAgentId(message);if(agentId===void 0){logError3("Missing agentId in request");return createErrorResponse(id,RoutingErrorCodes.MISSING_AGENT_ID,"Missing agentId")}let spawnCommand;try{spawnCommand=this.registry.resolve(agentId)}catch(error){if(error instanceof AgentNotFoundError){logError3(`Agent not found: ${agentId}`);return createErrorResponse(id,RoutingErrorCodes.AGENT_NOT_FOUND,"Agent not found",{agentId})}if(error instanceof PlatformNotSupportedError){logError3(`Platform not supported for agent: ${agentId}`);return createErrorResponse(id,RoutingErrorCodes.PLATFORM_NOT_SUPPORTED,"Platform not supported",{agentId,platform:error.platform})}throw error}let runtime;try{runtime=await this.runtimeManager.getOrSpawn(agentId,spawnCommand)}catch(error){logError3(`Failed to spawn agent ${agentId}: ${error.message}`);return createErrorResponse(id,RoutingErrorCodes.SPAWN_FAILED,"Agent spawn failed",{agentId,error:error.message})}if(id!==null){const msg=message;const clientSessionId=typeof msg.sessionId==="string"?msg.sessionId:void 0;this.pendingRequests.set(id,{id,agentId,timestamp:Date.now(),clientSessionId})}const transformedMessage=transformMessage(message);const success=runtime.write(transformedMessage);if(!success){logError3(`Failed to write to agent ${agentId}`);if(id!==null){this.pendingRequests.delete(id)}}else{logInfo3(`Routed message to agent ${agentId}`)}return void 0}handleAgentResponse(agentId,response){const id=extractId(response);const msg=response;const method=typeof msg.method==="string"?msg.method:void 0;if(id!==null&&method){this.handleAgentRequest(agentId,id,method,msg);return}if(id!==null){const pending=this.pendingRequests.get(id);if(pending&&pending.agentId===agentId){const result=msg.result;if(result&&Array.isArray(result.authMethods)&&result.authMethods.length>0){logInfo3(`Agent ${agentId} requires authentication, attempting auto-auth`);this.authState.set(agentId,"pending");void this.attemptAuthentication(agentId,result.authMethods)}if(result&&typeof result.sessionId==="string"){const agentSessionId=result.sessionId;const clientSessionId=pending.clientSessionId;if(clientSessionId){this.sessionIdMap.set(agentSessionId,clientSessionId);logInfo3(`Mapped agent sessionId ${agentSessionId} to client sessionId ${clientSessionId}`)}}this.pendingRequests.delete(id)}}if(id===null&&method){logInfo3(`Received notification: ${method}`);const params=msg.params;if(params&&typeof params.sessionId==="string"){const agentSessionId=params.sessionId;const clientSessionId=this.sessionIdMap.get(agentSessionId);if(clientSessionId){const enriched={...msg,sessionId:clientSessionId,params:{...params,sessionId:agentSessionId}};logInfo3(`Forwarding notification with mapped sessionId: ${clientSessionId}`);this.writeCallback(enriched);return}else{logError3(`Notification with unmapped agentSessionId: ${agentSessionId}, using default sessionId`);const enriched={...msg,sessionId:"global-notifications",params:{...params,sessionId:agentSessionId}};this.writeCallback(enriched);return}}else{const topLevelSessionId=msg.sessionId;if(topLevelSessionId){this.writeCallback(response);return}else{logError3(`Notification without sessionId: ${method}, adding default sessionId for routing`);const enriched={...msg,sessionId:"global-notifications"};this.writeCallback(enriched);return}}}this.writeCallback(response)}handleAgentRequest(agentId,id,method,msg){logInfo3(`Agent ${agentId} sent request: ${method} (id=${id}), auto-responding`);let result;if(method==="session/request_permission"){result=this.buildPermissionResponse(msg)}else{logInfo3(`Unknown agent request method: ${method}, sending generic success`);result={}}const response={jsonrpc:"2.0",id,result};this.sendToAgent(agentId,response)}buildPermissionResponse(msg){const params=msg.params;const options=params?.options;if(!options||options.length===0){return{optionId:"approved"}}const allowAlways=options.find(o=>o.kind==="allow_always");if(allowAlways&&typeof allowAlways.optionId==="string"){logInfo3(`Auto-approving permission with option: ${allowAlways.optionId} (allow_always)`);return{optionId:allowAlways.optionId}}const allowOnce=options.find(o=>o.kind==="allow_once");if(allowOnce&&typeof allowOnce.optionId==="string"){logInfo3(`Auto-approving permission with option: ${allowOnce.optionId} (allow_once)`);return{optionId:allowOnce.optionId}}const firstOption=options[0];const optionId=typeof firstOption.optionId==="string"?firstOption.optionId:"approved";logInfo3(`Auto-approving permission with fallback option: ${optionId}`);return{optionId}}sendToAgent(agentId,message){let runtime;try{runtime=this.runtimeManager.get(agentId)}catch{logError3(`Failed to get runtime for agent ${agentId} to send response`);return}if(!runtime){logError3(`No runtime found for agent ${agentId}, cannot send response`);return}const success=runtime.write(message);if(!success){logError3(`Failed to write response to agent ${agentId}`)}else{logInfo3(`Sent auto-response to agent ${agentId}`)}}async attemptAuthentication(agentId,authMethods){const apiKey=getAgentApiKey(this.apiKeys,agentId);if(!apiKey){logError3(`No API key found for agent ${agentId}, authentication will fail`);this.authState.set(agentId,"none");return}let selectedMethod=authMethods.find(m=>m.id==="openai-api-key");if(!selectedMethod){selectedMethod=authMethods.find(m=>m.id.includes("api-key")||m.id.includes("apikey"))}if(!selectedMethod){selectedMethod=authMethods[0]}logInfo3(`Authenticating agent ${agentId} with method: ${selectedMethod.id}`);let runtime;try{const spawnCommand=this.registry.resolve(agentId);runtime=await this.runtimeManager.getOrSpawn(agentId,spawnCommand)}catch(error){logError3(`Failed to get runtime for authentication: ${error.message}`);this.authState.set(agentId,"none");return}const authRequest={jsonrpc:"2.0",id:`auth-${agentId}-${Date.now()}`,method:"authenticate",params:{methodId:selectedMethod.id,credentials:{apiKey}}};const transformed=transformMessage(authRequest);const serialized=JSON.stringify(transformed)+"\n";if(runtime.process.stdin){runtime.process.stdin.write(serialized,error=>{if(error){logError3(`Failed to send authenticate request to ${agentId}: ${error.message}`);this.authState.set(agentId,"none")}else{logInfo3(`Sent authenticate request to agent ${agentId}`);this.authState.set(agentId,"authenticated")}})}}get pendingCount(){return this.pendingRequests.size}isPending(id){return this.pendingRequests.has(id)}clearPending(){this.pendingRequests.clear()}}}});function formatLogMessage(level,message,context=LOG_CONTEXT){const timestamp=new Date().toISOString();return`[${timestamp}] [${level}] [${context}] ${message}`}function log(level,message,context){const formatted=formatLogMessage(level,message,context);console.error(formatted)}function logExit(agentId,exitCode,signal){if(signal){log("INFO",`Agent "${agentId}" exited with signal ${signal}`)}else if(exitCode!==null){log("INFO",`Agent "${agentId}" exited with code ${exitCode}`)}else{log("INFO",`Agent "${agentId}" exited`)}}function logInfo4(message,context){log("INFO",message,context)}function logError4(message,context){log("ERROR",message,context)}var LOG_CONTEXT;var init_log=__esm({"workers-registry/acp-worker/src/registry-launcher/log.ts"(){"use strict";LOG_CONTEXT="registry-launcher"}});var registry_launcher_exports={};function parseArgs(){const args=process.argv.slice(2);if(args.length>0&&args[0]&&!args[0].startsWith("-")){return args[0]}return void 0}function setupSignalHandlers(runtimeManager,shutdownTimeoutMs){const shutdown=async()=>{if(isShuttingDown){return}isShuttingDown=true;logInfo4("Received shutdown signal, initiating graceful shutdown");try{await runtimeManager.terminateAll(shutdownTimeoutMs);logInfo4("All agent processes terminated");process.exit(ExitCodes.SUCCESS)}catch(error){logError4(`Error during shutdown: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}};process.on("SIGTERM",()=>{void shutdown()});process.on("SIGINT",()=>{void shutdown()});return shutdown}function setupStdinHandler(router,ndjsonHandler){ndjsonHandler.onMessage(async message=>{try{const errorResponse=await router.route(message);if(errorResponse){ndjsonHandler.write(errorResponse)}}catch(error){logError4(`Unexpected error routing message: ${error.message}`)}});ndjsonHandler.onError((error,line)=>{logError4(`Failed to parse NDJSON: ${error.message} - Line: ${line.slice(0,100)}`)});process.stdin.setEncoding("utf8");process.stdin.on("data",chunk=>{const buffer=typeof chunk==="string"?Buffer.from(chunk):chunk;ndjsonHandler.processChunk(buffer)});process.stdin.on("end",()=>{logInfo4("stdin closed")});process.stdin.on("error",error=>{logError4(`stdin error: ${error.message}`)})}function setupAgentResponseHandling(runtimeManager,router){runtimeManager.onAgentExit((agentId,code)=>{logExit(agentId,code)});const originalGetOrSpawn=runtimeManager.getOrSpawn.bind(runtimeManager);runtimeManager.getOrSpawn=async function(agentId,spawnCommand){const runtime=await originalGetOrSpawn(agentId,spawnCommand);const proc=runtime.process;if(proc.stdout&&!proc.stdout.listenerCount("data")){let buffer="";proc.stdout.on("data",chunk=>{buffer+=chunk;let newlineIndex;while((newlineIndex=buffer.indexOf("\n"))!==-1){const line=buffer.slice(0,newlineIndex);buffer=buffer.slice(newlineIndex+1);if(line.trim()){try{const response=JSON.parse(line);router.handleAgentResponse(agentId,response)}catch(err){logError4(`Failed to parse agent ${agentId} response: ${err.message}`)}}}})}if(proc.stderr&&!proc.stderr.listenerCount("data")){proc.stderr.on("data",chunk=>{process.stderr.write(`[agent:${agentId}] ${chunk}`)})}return runtime}}async function main(){logInfo4("Registry Launcher starting");const configPath=parseArgs();if(configPath){logInfo4(`Loading configuration from: ${configPath}`)}const config=loadConfig(configPath);logInfo4(`Configuration loaded: registryUrl=${config.registryUrl}, apiKeysPath=${config.apiKeysPath}, shutdownTimeoutSec=${config.shutdownTimeoutSec}`);const apiKeys=loadApiKeys(config.apiKeysPath);const registry=new RegistryIndex(config.registryUrl);try{await registry.fetch()}catch(error){if(error instanceof RegistryFetchError){logError4(`Failed to fetch registry: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}if(error instanceof RegistryParseError){logError4(`Failed to parse registry: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}logError4(`Unexpected error fetching registry: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}const runtimeManager=new AgentRuntimeManager;const ndjsonHandler=new NDJSONHandler(process.stdout);const router=new MessageRouter(registry,runtimeManager,message=>ndjsonHandler.write(message),apiKeys);const shutdownTimeoutMs=config.shutdownTimeoutSec*1e3;setupSignalHandlers(runtimeManager,shutdownTimeoutMs);setupAgentResponseHandling(runtimeManager,router);setupStdinHandler(router,ndjsonHandler);process.stdout.on("error",error=>{logError4(`stdout error: ${error.message}`)});process.on("unhandledRejection",reason=>{logError4(`Unhandled rejection: ${reason instanceof Error?reason.message:String(reason)}`)});logInfo4("Registry Launcher ready, waiting for messages")}var ExitCodes,isShuttingDown;var init_registry_launcher=__esm({"workers-registry/acp-worker/src/registry-launcher/index.ts"(){"use strict";init_config();init_api_keys();init_registry();init_ndjson_handler();init_manager();init_message_router();init_log();ExitCodes={SUCCESS:0,FATAL_ERROR:1};isShuttingDown=false;main().catch(error=>{logError4(`Fatal error: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)})}});import{fileURLToPath}from"url";import{dirname,join}from"path";var __filename=fileURLToPath(import.meta.url);var __dirname=dirname(__filename);var DEFAULT_CONFIG_FILE="acp-registry-config.json";function ensureDefaultConfigArg(){const hasExplicitConfig=process.argv.length>2&&process.argv[2]&&!process.argv[2].startsWith("-");if(hasExplicitConfig){return}const defaultConfigPath=join(__dirname,DEFAULT_CONFIG_FILE);process.argv.splice(2,0,defaultConfigPath)}ensureDefaultConfigArg();await Promise.resolve().then(()=>(init_registry_launcher(),registry_launcher_exports));
|
|
4
|
+
`)})}}write(message){if(this.state!=="running"&&this.state!=="starting"){return false}if(!this.process.stdin||this.process.stdin.destroyed){return false}try{const ndjsonLine=JSON.stringify(message)+"\n";return this.process.stdin.write(ndjsonLine)}catch{return false}}async terminate(timeout=DEFAULT_TERMINATE_TIMEOUT_MS){if(this.state==="stopped"){return}if(this.state==="stopping"){return this.waitForExit()}this.state="stopping";if(this.process.stdin&&!this.process.stdin.destroyed){this.process.stdin.end()}this.process.kill("SIGTERM");const exitPromise=this.waitForExit();const timeoutPromise=new Promise(resolve2=>{setTimeout(()=>resolve2("timeout"),timeout)});const result=await Promise.race([exitPromise,timeoutPromise]);if(result==="timeout"&&!this.process.killed&&this.process.exitCode===null){this.process.kill("SIGKILL");await this.waitForExit()}}waitForExit(){if(this.state==="stopped"){return Promise.resolve()}return new Promise(resolve2=>{this.process.once("exit",()=>{resolve2()})})}}}});var DEFAULT_SHUTDOWN_TIMEOUT_MS,AgentRuntimeManager;var init_manager=__esm({"workers-registry/acp-worker/src/registry-launcher/runtime/manager.ts"(){"use strict";init_agent_runtime();DEFAULT_SHUTDOWN_TIMEOUT_MS=5e3;AgentRuntimeManager=class{runtimes=new Map;exitCallbacks=[];async getOrSpawn(agentId,spawnCommand){const existing=this.runtimes.get(agentId);if(existing&&existing.state!=="stopped"){return existing}const runtime=AgentRuntimeImpl.spawn(agentId,spawnCommand,(code,_signal)=>{this.handleAgentExit(agentId,code)});this.runtimes.set(agentId,runtime);return runtime}get(agentId){return this.runtimes.get(agentId)}async terminate(agentId,timeout=DEFAULT_SHUTDOWN_TIMEOUT_MS){const runtime=this.runtimes.get(agentId);if(!runtime){return}await runtime.terminate(timeout);this.runtimes.delete(agentId)}async terminateAll(timeout=DEFAULT_SHUTDOWN_TIMEOUT_MS){const terminatePromises=[];for(const[agentId,runtime]of this.runtimes){if(runtime.state!=="stopped"){terminatePromises.push(runtime.terminate(timeout).then(()=>{this.runtimes.delete(agentId)}))}}await Promise.all(terminatePromises)}onAgentExit(callback){this.exitCallbacks.push(callback)}handleAgentExit(agentId,code){this.runtimes.delete(agentId);for(const callback of this.exitCallbacks){try{callback(agentId,code)}catch{}}}get size(){return this.runtimes.size}has(agentId){return this.runtimes.has(agentId)}}}});function logError3(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [ERROR] [router] ${message}`)}function logInfo3(message){const timestamp=new Date().toISOString();console.error(`[${timestamp}] [INFO] [router] ${message}`)}function createErrorResponse(id,code,message,data){const response={jsonrpc:"2.0",id,error:{code,message}};if(data!==void 0){response.error.data=data}return response}function extractAgentId(message){const msg=message;const agentId=msg.agentId;if(typeof agentId==="string"&&agentId.length>0){return agentId}return void 0}function extractId(message){const msg=message;const id=msg.id;if(typeof id==="string"||typeof id==="number"){return id}return null}function transformMessage(message){const{agentId:_,...rest}=message;return rest}var RoutingErrorCodes,MessageRouter;var init_message_router=__esm({"workers-registry/acp-worker/src/registry-launcher/router/message-router.ts"(){"use strict";init_registry();init_api_keys();RoutingErrorCodes={MISSING_AGENT_ID:-32600,AGENT_NOT_FOUND:-32001,PLATFORM_NOT_SUPPORTED:-32002,SPAWN_FAILED:-32003};MessageRouter=class{registry;runtimeManager;writeCallback;apiKeys;pendingRequests=new Map;authState=new Map;sessionIdMap=new Map;constructor(registry,runtimeManager,writeCallback,apiKeys={}){this.registry=registry;this.runtimeManager=runtimeManager;this.writeCallback=writeCallback;this.apiKeys=apiKeys}async route(message){const id=extractId(message);const agentId=extractAgentId(message);if(agentId===void 0){logError3("Missing agentId in request");return createErrorResponse(id,RoutingErrorCodes.MISSING_AGENT_ID,"Missing agentId")}let spawnCommand;try{spawnCommand=this.registry.resolve(agentId)}catch(error){if(error instanceof AgentNotFoundError){logError3(`Agent not found: ${agentId}`);return createErrorResponse(id,RoutingErrorCodes.AGENT_NOT_FOUND,"Agent not found",{agentId})}if(error instanceof PlatformNotSupportedError){logError3(`Platform not supported for agent: ${agentId}`);return createErrorResponse(id,RoutingErrorCodes.PLATFORM_NOT_SUPPORTED,"Platform not supported",{agentId,platform:error.platform})}throw error}let runtime;try{runtime=await this.runtimeManager.getOrSpawn(agentId,spawnCommand)}catch(error){logError3(`Failed to spawn agent ${agentId}: ${error.message}`);return createErrorResponse(id,RoutingErrorCodes.SPAWN_FAILED,"Agent spawn failed",{agentId,error:error.message})}if(id!==null){const msg=message;const clientSessionId=typeof msg.sessionId==="string"?msg.sessionId:void 0;this.pendingRequests.set(id,{id,agentId,timestamp:Date.now(),clientSessionId})}const transformedMessage=transformMessage(message);const success=runtime.write(transformedMessage);if(!success){logError3(`Failed to write to agent ${agentId}`);if(id!==null){this.pendingRequests.delete(id)}}else{logInfo3(`Routed message to agent ${agentId}`)}return void 0}handleAgentResponse(agentId,response){const id=extractId(response);const msg=response;const method=typeof msg.method==="string"?msg.method:void 0;if(id!==null&&method){this.handleAgentRequest(agentId,id,method,msg);return}if(id!==null){const pending=this.pendingRequests.get(id);if(pending&&pending.agentId===agentId){const result=msg.result;if(result&&Array.isArray(result.authMethods)&&result.authMethods.length>0){logInfo3(`Agent ${agentId} requires authentication, attempting auto-auth`);this.authState.set(agentId,"pending");void this.attemptAuthentication(agentId,result.authMethods)}if(result&&typeof result.sessionId==="string"){const agentSessionId=result.sessionId;const clientSessionId=pending.clientSessionId;if(clientSessionId){this.sessionIdMap.set(agentSessionId,clientSessionId);logInfo3(`Mapped agent sessionId ${agentSessionId} to client sessionId ${clientSessionId}`)}}this.pendingRequests.delete(id)}}if(id===null&&method){logInfo3(`Received notification: ${method}`);const params=msg.params;if(params&&typeof params.sessionId==="string"){const agentSessionId=params.sessionId;const clientSessionId=this.sessionIdMap.get(agentSessionId);if(clientSessionId){const enriched={...msg,sessionId:clientSessionId,params:{...params,sessionId:agentSessionId}};logInfo3(`Forwarding notification with mapped sessionId: ${clientSessionId}`);this.writeCallback(enriched);return}else{logError3(`Notification with unmapped agentSessionId: ${agentSessionId}, using default sessionId`);const enriched={...msg,sessionId:"global-notifications",params:{...params,sessionId:agentSessionId}};this.writeCallback(enriched);return}}else{const topLevelSessionId=msg.sessionId;if(topLevelSessionId){this.writeCallback(response);return}else{logError3(`Notification without sessionId: ${method}, adding default sessionId for routing`);const enriched={...msg,sessionId:"global-notifications"};this.writeCallback(enriched);return}}}this.writeCallback(response)}handleAgentRequest(agentId,id,method,msg){logInfo3(`Agent ${agentId} sent request: ${method} (id=${id}), auto-responding`);let result;if(method==="session/request_permission"){result=this.buildPermissionResponse(msg)}else{logInfo3(`Unknown agent request method: ${method}, sending generic success`);result={}}const response={jsonrpc:"2.0",id,result};this.sendToAgent(agentId,response)}buildPermissionResponse(msg){const params=msg.params;const options=params?.options;if(!options||options.length===0){return{optionId:"approved"}}const allowAlways=options.find(o=>o.kind==="allow_always");if(allowAlways&&typeof allowAlways.optionId==="string"){logInfo3(`Auto-approving permission with option: ${allowAlways.optionId} (allow_always)`);return{optionId:allowAlways.optionId}}const allowOnce=options.find(o=>o.kind==="allow_once");if(allowOnce&&typeof allowOnce.optionId==="string"){logInfo3(`Auto-approving permission with option: ${allowOnce.optionId} (allow_once)`);return{optionId:allowOnce.optionId}}const firstOption=options[0];const optionId=typeof firstOption.optionId==="string"?firstOption.optionId:"approved";logInfo3(`Auto-approving permission with fallback option: ${optionId}`);return{optionId}}sendToAgent(agentId,message){let runtime;try{runtime=this.runtimeManager.get(agentId)}catch{logError3(`Failed to get runtime for agent ${agentId} to send response`);return}if(!runtime){logError3(`No runtime found for agent ${agentId}, cannot send response`);return}const success=runtime.write(message);if(!success){logError3(`Failed to write response to agent ${agentId}`)}else{logInfo3(`Sent auto-response to agent ${agentId}`)}}async attemptAuthentication(agentId,authMethods){const apiKey=getAgentApiKey(this.apiKeys,agentId);if(!apiKey){logError3(`No API key found for agent ${agentId}, authentication will fail`);this.authState.set(agentId,"none");return}let selectedMethod=authMethods.find(m=>m.id==="openai-api-key");if(!selectedMethod){selectedMethod=authMethods.find(m=>m.id.includes("api-key")||m.id.includes("apikey"))}if(!selectedMethod){selectedMethod=authMethods[0]}logInfo3(`Authenticating agent ${agentId} with method: ${selectedMethod.id}`);let runtime;try{const spawnCommand=this.registry.resolve(agentId);runtime=await this.runtimeManager.getOrSpawn(agentId,spawnCommand)}catch(error){logError3(`Failed to get runtime for authentication: ${error.message}`);this.authState.set(agentId,"none");return}const authRequest={jsonrpc:"2.0",id:`auth-${agentId}-${Date.now()}`,method:"authenticate",params:{methodId:selectedMethod.id,credentials:{apiKey}}};const transformed=transformMessage(authRequest);const serialized=JSON.stringify(transformed)+"\n";if(runtime.process.stdin){runtime.process.stdin.write(serialized,error=>{if(error){logError3(`Failed to send authenticate request to ${agentId}: ${error.message}`);this.authState.set(agentId,"none")}else{logInfo3(`Sent authenticate request to agent ${agentId}`);this.authState.set(agentId,"authenticated")}})}}get pendingCount(){return this.pendingRequests.size}isPending(id){return this.pendingRequests.has(id)}clearPending(){this.pendingRequests.clear()}}}});function formatLogMessage(level,message,context=LOG_CONTEXT){const timestamp=new Date().toISOString();return`[${timestamp}] [${level}] [${context}] ${message}`}function log(level,message,context){const formatted=formatLogMessage(level,message,context);console.error(formatted)}function logExit(agentId,exitCode,signal){if(signal){log("INFO",`Agent "${agentId}" exited with signal ${signal}`)}else if(exitCode!==null){log("INFO",`Agent "${agentId}" exited with code ${exitCode}`)}else{log("INFO",`Agent "${agentId}" exited`)}}function logInfo4(message,context){log("INFO",message,context)}function logWarn(message,context){log("WARN",message,context)}function logError4(message,context){log("ERROR",message,context)}var LOG_CONTEXT;var init_log=__esm({"workers-registry/acp-worker/src/registry-launcher/log.ts"(){"use strict";LOG_CONTEXT="registry-launcher"}});var registry_launcher_exports={};function parseArgs(){const args=process.argv.slice(2);const result={};let i=0;while(i<args.length){const arg=args[i];if(arg==="--custom-agents"){const nextArg=args[i+1];if(nextArg&&!nextArg.startsWith("-")){result.customAgentsPath=nextArg;i+=2;continue}logWarn("--custom-agents requires a file path argument, ignoring");i+=1;continue}if(!arg.startsWith("-")&&!result.configPath){result.configPath=arg}i+=1}return result}function setupSignalHandlers(runtimeManager,shutdownTimeoutMs){const shutdown=async()=>{if(isShuttingDown){return}isShuttingDown=true;logInfo4("Received shutdown signal, initiating graceful shutdown");try{await runtimeManager.terminateAll(shutdownTimeoutMs);logInfo4("All agent processes terminated");process.exit(ExitCodes.SUCCESS)}catch(error){logError4(`Error during shutdown: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}};process.on("SIGTERM",()=>{void shutdown()});process.on("SIGINT",()=>{void shutdown()});return shutdown}function setupStdinHandler(router,ndjsonHandler){ndjsonHandler.onMessage(async message=>{try{const errorResponse=await router.route(message);if(errorResponse){ndjsonHandler.write(errorResponse)}}catch(error){logError4(`Unexpected error routing message: ${error.message}`)}});ndjsonHandler.onError((error,line)=>{logError4(`Failed to parse NDJSON: ${error.message} - Line: ${line.slice(0,100)}`)});process.stdin.setEncoding("utf8");process.stdin.on("data",chunk=>{const buffer=typeof chunk==="string"?Buffer.from(chunk):chunk;ndjsonHandler.processChunk(buffer)});process.stdin.on("end",()=>{logInfo4("stdin closed")});process.stdin.on("error",error=>{logError4(`stdin error: ${error.message}`)})}function setupAgentResponseHandling(runtimeManager,router){runtimeManager.onAgentExit((agentId,code)=>{logExit(agentId,code)});const originalGetOrSpawn=runtimeManager.getOrSpawn.bind(runtimeManager);runtimeManager.getOrSpawn=async function(agentId,spawnCommand){const runtime=await originalGetOrSpawn(agentId,spawnCommand);const proc=runtime.process;if(proc.stdout&&!proc.stdout.listenerCount("data")){let buffer="";proc.stdout.on("data",chunk=>{buffer+=chunk;let newlineIndex;while((newlineIndex=buffer.indexOf("\n"))!==-1){const line=buffer.slice(0,newlineIndex);buffer=buffer.slice(newlineIndex+1);if(line.trim()){try{const response=JSON.parse(line);router.handleAgentResponse(agentId,response)}catch(err){logError4(`Failed to parse agent ${agentId} response: ${err.message}`)}}}})}if(proc.stderr&&!proc.stderr.listenerCount("data")){proc.stderr.on("data",chunk=>{process.stderr.write(`[agent:${agentId}] ${chunk}`)})}return runtime}}async function main(){logInfo4("Registry Launcher starting");const parsedArgs=parseArgs();if(parsedArgs.configPath){logInfo4(`Loading configuration from: ${parsedArgs.configPath}`)}const config=loadConfig(parsedArgs.configPath);if(parsedArgs.customAgentsPath){config.customAgentsPath=parsedArgs.customAgentsPath}logInfo4(`Configuration loaded: registryUrl=${config.registryUrl}, apiKeysPath=${config.apiKeysPath}, shutdownTimeoutSec=${config.shutdownTimeoutSec}`);const apiKeys=loadApiKeys(config.apiKeysPath);const registry=new RegistryIndex(config.registryUrl);try{await registry.fetch()}catch(error){if(error instanceof RegistryFetchError){logError4(`Failed to fetch registry: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}if(error instanceof RegistryParseError){logError4(`Failed to parse registry: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}logError4(`Unexpected error fetching registry: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}if(config.customAgentsPath){try{logInfo4(`Loading custom agents from: ${config.customAgentsPath}`);const customAgents=loadCustomAgents(config.customAgentsPath);registry.mergeCustomAgents(customAgents)}catch(error){if(error instanceof CustomAgentsLoadError){logError4(`Failed to load custom agents: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}if(error instanceof RegistryParseError){logError4(`Invalid custom agents file: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}logError4(`Unexpected error loading custom agents: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)}}const runtimeManager=new AgentRuntimeManager;const ndjsonHandler=new NDJSONHandler(process.stdout);const router=new MessageRouter(registry,runtimeManager,message=>ndjsonHandler.write(message),apiKeys);const shutdownTimeoutMs=config.shutdownTimeoutSec*1e3;setupSignalHandlers(runtimeManager,shutdownTimeoutMs);setupAgentResponseHandling(runtimeManager,router);setupStdinHandler(router,ndjsonHandler);logInfo4("Registry Launcher ready, waiting for messages")}var ExitCodes,isShuttingDown;var init_registry_launcher=__esm({"workers-registry/acp-worker/src/registry-launcher/index.ts"(){"use strict";init_config();init_api_keys();init_registry();init_ndjson_handler();init_manager();init_message_router();init_log();ExitCodes={SUCCESS:0,FATAL_ERROR:1};isShuttingDown=false;main().catch(error=>{logError4(`Fatal error: ${error.message}`);process.exit(ExitCodes.FATAL_ERROR)})}});import{fileURLToPath}from"url";import{dirname,join}from"path";var __filename=fileURLToPath(import.meta.url);var __dirname=dirname(__filename);var DEFAULT_CONFIG_FILE="acp-registry-config.json";function ensureDefaultConfigArg(){const userArgs=process.argv.slice(2);const hasExplicitConfig=userArgs.length>0&&userArgs[0]&&!userArgs[0].startsWith("-");if(!hasExplicitConfig){const defaultConfigPath=join(__dirname,DEFAULT_CONFIG_FILE);process.argv.splice(2,0,defaultConfigPath)}}ensureDefaultConfigArg();await Promise.resolve().then(()=>(init_registry_launcher(),registry_launcher_exports));
|
|
5
5
|
//# sourceMappingURL=index.js.map
|