@lmnr-ai/lmnr 0.8.6 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/worker/index.cjs +2 -3
- package/dist/cli/worker/index.cjs.map +1 -1
- package/dist/cli/worker/index.mjs +2 -3
- package/dist/cli/worker/index.mjs.map +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/{decorators-BNkfMc8I.mjs → decorators-DQcJtTyJ.mjs} +205 -164
- package/dist/decorators-DQcJtTyJ.mjs.map +1 -0
- package/dist/{decorators-BMu8FLY8.cjs → decorators-DcauYr1x.cjs} +205 -164
- package/dist/decorators-DcauYr1x.cjs.map +1 -0
- package/dist/{dist-TqD6UrQB.cjs → dist-DozF0Nrf.cjs} +3 -3
- package/dist/{dist-TqD6UrQB.cjs.map → dist-DozF0Nrf.cjs.map} +1 -1
- package/dist/{dist-yFPIkWoB.mjs → dist-oYGT08tL.mjs} +3 -3
- package/dist/{dist-yFPIkWoB.mjs.map → dist-oYGT08tL.mjs.map} +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +5 -5
- package/dist/decorators-BMu8FLY8.cjs.map +0 -1
- package/dist/decorators-BNkfMc8I.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const require_chunk = require('../../chunk-BrXtsOCC.cjs');
|
|
2
|
-
require('../../dist-
|
|
2
|
+
require('../../dist-DozF0Nrf.cjs');
|
|
3
3
|
require('../../utils-dnHn-Dz-.cjs');
|
|
4
|
-
const require_decorators = require('../../decorators-
|
|
4
|
+
const require_decorators = require('../../decorators-DcauYr1x.cjs');
|
|
5
5
|
const require_cli_worker_build = require('./build.cjs');
|
|
6
6
|
let readline = require("readline");
|
|
7
7
|
readline = require_chunk.__toESM(readline);
|
|
@@ -87,7 +87,6 @@ async function runWorker(config) {
|
|
|
87
87
|
workerLogger.debug("Consuming result (if stream)...");
|
|
88
88
|
const result = await require_decorators.consumeStreamResult(rawResult);
|
|
89
89
|
workerLogger.info("Rollout function completed successfully");
|
|
90
|
-
workerLogger.debug(`Result: ${JSON.stringify(result, null, 2)}`);
|
|
91
90
|
return result;
|
|
92
91
|
}
|
|
93
92
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["buildFile","selectRolloutFunction","Laminar","reconstructed: Record<string, any>","consumeStreamResult","config: WorkerConfig","error: any"],"sources":["../../../src/cli/worker/index.ts"],"sourcesContent":["import * as readline from 'readline';\n\nimport { Laminar } from '../../laminar';\nimport { consumeStreamResult } from '../../opentelemetry-lib/tracing/stream-utils';\nimport { buildFile, loadModule, selectRolloutFunction } from './build';\n\n/**\n * Message types sent from child to parent via stdout\n */\ninterface LogMessage {\n type: 'log';\n level: 'info' | 'debug' | 'error' | 'warn';\n message: string;\n}\n\ninterface ResultMessage {\n type: 'result';\n data: any;\n}\n\ninterface ErrorMessage {\n type: 'error';\n error: string;\n stack?: string;\n}\n\ntype WorkerMessage = LogMessage | ResultMessage | ErrorMessage;\n\n/**\n * Configuration received from parent via stdin\n */\nexport interface WorkerConfig {\n filePath: string;\n functionName?: string;\n args: Record<string, any> | any[];\n env: Record<string, string>;\n cacheServerPort: number;\n baseUrl: string;\n projectApiKey?: string;\n httpPort: number;\n grpcPort: number;\n externalPackages?: string[];\n dynamicImportsToSkip?: string[];\n}\n\n/**\n * Prefix for worker protocol messages to distinguish from user console.log output\n */\nconst WORKER_MESSAGE_PREFIX = '__LMNR_WORKER__:';\n\n/**\n * Sends a message to parent process via stdout\n * Uses a special prefix to distinguish from user's console.log output\n */\nfunction sendMessage(message: WorkerMessage): void {\n console.log(WORKER_MESSAGE_PREFIX + JSON.stringify(message));\n}\n\n/**\n * Logger that sends log messages to parent\n */\nconst workerLogger = {\n info: (message: string) => sendMessage({ type: 'log', level: 'info', message }),\n debug: (message: string) => sendMessage({ type: 'log', level: 'debug', message }),\n error: (message: string) => sendMessage({ type: 'log', level: 'error', message }),\n warn: (message: string) => sendMessage({ type: 'log', level: 'warn', message }),\n};\n\n/**\n * Main worker execution function\n * Returns the result of the rollout function or throws an error\n */\nasync function runWorker(config: WorkerConfig): Promise<any> {\n // Set environment variables\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = value;\n }\n\n workerLogger.debug('Building user file...');\n const moduleText = await buildFile(config.filePath, {\n externalPackages: config.externalPackages,\n dynamicImportsToSkip: config.dynamicImportsToSkip,\n });\n\n workerLogger.debug('Loading user file...');\n loadModule({\n filename: config.filePath,\n moduleText,\n });\n\n // Select the appropriate rollout function\n const selectedFunction = selectRolloutFunction(config.functionName);\n workerLogger.debug(`Selected function: ${selectedFunction.name}`);\n\n // Initialize Laminar\n const urlWithoutSlash = config.baseUrl.replace(/\\/$/, '').replace(/:\\d{1,5}$/g, '');\n const baseHttpUrl = `${urlWithoutSlash}:${config.httpPort}`;\n\n if (!Laminar.initialized()) {\n workerLogger.debug('Initializing Laminar...');\n Laminar.initialize({\n projectApiKey: config.projectApiKey,\n baseUrl: config.baseUrl,\n baseHttpUrl,\n httpPort: config.httpPort,\n grpcPort: config.grpcPort,\n disableBatch: true,\n });\n }\n\n // Execute the rollout function with args\n workerLogger.debug('Executing rollout function...');\n\n const orderedArgs = Array.isArray(config.args)\n ? config.args\n : selectedFunction.params.map(param => {\n // Handle destructured parameters by reconstructing the object from nested properties\n if (param.nested && param.nested.length > 0) {\n const reconstructed: Record<string, any> = {};\n for (const nestedParam of param.nested) {\n reconstructed[nestedParam.name] = (config.args as Record<string, any>)[nestedParam.name];\n }\n return reconstructed;\n }\n // Regular parameter\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (config.args as Record<string, any>)[param.name];\n });\n workerLogger.info(\n `Calling function ${selectedFunction.name} with args: ${JSON.stringify(orderedArgs)}`,\n );\n\n const rawResult = await selectedFunction.fn(...orderedArgs);\n\n // Consume the result if it's a stream to ensure background processing completes\n workerLogger.debug('Consuming result (if stream)...');\n const result = await consumeStreamResult(rawResult);\n\n workerLogger.info('Rollout function completed successfully');\n workerLogger.debug(`Result: ${JSON.stringify(result, null, 2)}`);\n\n return result;\n}\n\n/**\n * Read configuration from stdin and start worker\n * Centralized exit point for the worker process\n */\nconst main = () => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n let configReceived = false;\n\n // This function is called anyway, so it can be async.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n rl.on('line', async (line: string) => {\n if (configReceived) {\n return;\n }\n\n try {\n const config: WorkerConfig = JSON.parse(line);\n configReceived = true;\n rl.close();\n\n // Execute the worker and handle result/errors\n try {\n const result = await runWorker(config);\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Send result back to parent\n sendMessage({ type: 'result', data: result });\n\n // Exit successfully\n process.exit(0);\n } catch (error: any) {\n\n\n workerLogger.error(`Error in worker: ${error instanceof Error ? error.message : error}`);\n\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Exit with error code\n process.exit(1);\n }\n } catch (error: any) {\n sendMessage({\n type: 'error',\n error: `Failed to parse config: ${error instanceof Error ? error.message : error}`,\n });\n process.exit(1);\n }\n });\n\n rl.on('close', () => {\n if (!configReceived) {\n sendMessage({\n type: 'error',\n error: 'No configuration received on stdin',\n });\n process.exit(1);\n }\n });\n};\n\n/**\n * Handle graceful shutdown on SIGTERM/SIGINT\n */\nconst handleShutdown = () => {\n if (Laminar.initialized()) {\n Laminar.shutdown().catch((error: any) => {\n workerLogger.error(\n `Error during Laminar shutdown: ${error instanceof Error ? error.message : error}`,\n );\n }).finally(() => {\n process.exit(0);\n });\n } else {\n process.exit(0);\n }\n};\n\n// Register signal handlers\nprocess.on('SIGTERM', handleShutdown);\nprocess.on('SIGINT', handleShutdown);\n\n// Start the worker\ntry {\n main();\n} catch (error: any) {\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n process.exit(1);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["buildFile","selectRolloutFunction","Laminar","reconstructed: Record<string, any>","consumeStreamResult","config: WorkerConfig","error: any"],"sources":["../../../src/cli/worker/index.ts"],"sourcesContent":["import * as readline from 'readline';\n\nimport { Laminar } from '../../laminar';\nimport { consumeStreamResult } from '../../opentelemetry-lib/tracing/stream-utils';\nimport { buildFile, loadModule, selectRolloutFunction } from './build';\n\n/**\n * Message types sent from child to parent via stdout\n */\ninterface LogMessage {\n type: 'log';\n level: 'info' | 'debug' | 'error' | 'warn';\n message: string;\n}\n\ninterface ResultMessage {\n type: 'result';\n data: any;\n}\n\ninterface ErrorMessage {\n type: 'error';\n error: string;\n stack?: string;\n}\n\ntype WorkerMessage = LogMessage | ResultMessage | ErrorMessage;\n\n/**\n * Configuration received from parent via stdin\n */\nexport interface WorkerConfig {\n filePath: string;\n functionName?: string;\n args: Record<string, any> | any[];\n env: Record<string, string>;\n cacheServerPort: number;\n baseUrl: string;\n projectApiKey?: string;\n httpPort: number;\n grpcPort: number;\n externalPackages?: string[];\n dynamicImportsToSkip?: string[];\n}\n\n/**\n * Prefix for worker protocol messages to distinguish from user console.log output\n */\nconst WORKER_MESSAGE_PREFIX = '__LMNR_WORKER__:';\n\n/**\n * Sends a message to parent process via stdout\n * Uses a special prefix to distinguish from user's console.log output\n */\nfunction sendMessage(message: WorkerMessage): void {\n console.log(WORKER_MESSAGE_PREFIX + JSON.stringify(message));\n}\n\n/**\n * Logger that sends log messages to parent\n */\nconst workerLogger = {\n info: (message: string) => sendMessage({ type: 'log', level: 'info', message }),\n debug: (message: string) => sendMessage({ type: 'log', level: 'debug', message }),\n error: (message: string) => sendMessage({ type: 'log', level: 'error', message }),\n warn: (message: string) => sendMessage({ type: 'log', level: 'warn', message }),\n};\n\n/**\n * Main worker execution function\n * Returns the result of the rollout function or throws an error\n */\nasync function runWorker(config: WorkerConfig): Promise<any> {\n // Set environment variables\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = value;\n }\n\n workerLogger.debug('Building user file...');\n const moduleText = await buildFile(config.filePath, {\n externalPackages: config.externalPackages,\n dynamicImportsToSkip: config.dynamicImportsToSkip,\n });\n\n workerLogger.debug('Loading user file...');\n loadModule({\n filename: config.filePath,\n moduleText,\n });\n\n // Select the appropriate rollout function\n const selectedFunction = selectRolloutFunction(config.functionName);\n workerLogger.debug(`Selected function: ${selectedFunction.name}`);\n\n // Initialize Laminar\n const urlWithoutSlash = config.baseUrl.replace(/\\/$/, '').replace(/:\\d{1,5}$/g, '');\n const baseHttpUrl = `${urlWithoutSlash}:${config.httpPort}`;\n\n if (!Laminar.initialized()) {\n workerLogger.debug('Initializing Laminar...');\n Laminar.initialize({\n projectApiKey: config.projectApiKey,\n baseUrl: config.baseUrl,\n baseHttpUrl,\n httpPort: config.httpPort,\n grpcPort: config.grpcPort,\n disableBatch: true,\n });\n }\n\n // Execute the rollout function with args\n workerLogger.debug('Executing rollout function...');\n\n const orderedArgs = Array.isArray(config.args)\n ? config.args\n : selectedFunction.params.map(param => {\n // Handle destructured parameters by reconstructing the object from nested properties\n if (param.nested && param.nested.length > 0) {\n const reconstructed: Record<string, any> = {};\n for (const nestedParam of param.nested) {\n reconstructed[nestedParam.name] = (config.args as Record<string, any>)[nestedParam.name];\n }\n return reconstructed;\n }\n // Regular parameter\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (config.args as Record<string, any>)[param.name];\n });\n workerLogger.info(\n `Calling function ${selectedFunction.name} with args: ${JSON.stringify(orderedArgs)}`,\n );\n\n const rawResult = await selectedFunction.fn(...orderedArgs);\n\n // Consume the result if it's a stream to ensure background processing completes\n workerLogger.debug('Consuming result (if stream)...');\n const result = await consumeStreamResult(rawResult);\n\n workerLogger.info('Rollout function completed successfully');\n\n return result;\n}\n\n/**\n * Read configuration from stdin and start worker\n * Centralized exit point for the worker process\n */\nconst main = () => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n let configReceived = false;\n\n // This function is called anyway, so it can be async.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n rl.on('line', async (line: string) => {\n if (configReceived) {\n return;\n }\n\n try {\n const config: WorkerConfig = JSON.parse(line);\n configReceived = true;\n rl.close();\n\n // Execute the worker and handle result/errors\n try {\n const result = await runWorker(config);\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Send result back to parent\n sendMessage({ type: 'result', data: result });\n\n // Exit successfully\n process.exit(0);\n } catch (error: any) {\n\n\n workerLogger.error(`Error in worker: ${error instanceof Error ? error.message : error}`);\n\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Exit with error code\n process.exit(1);\n }\n } catch (error: any) {\n sendMessage({\n type: 'error',\n error: `Failed to parse config: ${error instanceof Error ? error.message : error}`,\n });\n process.exit(1);\n }\n });\n\n rl.on('close', () => {\n if (!configReceived) {\n sendMessage({\n type: 'error',\n error: 'No configuration received on stdin',\n });\n process.exit(1);\n }\n });\n};\n\n/**\n * Handle graceful shutdown on SIGTERM/SIGINT\n */\nconst handleShutdown = () => {\n if (Laminar.initialized()) {\n Laminar.shutdown().catch((error: any) => {\n workerLogger.error(\n `Error during Laminar shutdown: ${error instanceof Error ? error.message : error}`,\n );\n }).finally(() => {\n process.exit(0);\n });\n } else {\n process.exit(0);\n }\n};\n\n// Register signal handlers\nprocess.on('SIGTERM', handleShutdown);\nprocess.on('SIGINT', handleShutdown);\n\n// Start the worker\ntry {\n main();\n} catch (error: any) {\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n process.exit(1);\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "../../dist-
|
|
1
|
+
import "../../dist-oYGT08tL.mjs";
|
|
2
2
|
import "../../utils-CWdehUXP.mjs";
|
|
3
|
-
import { l as Laminar, p as consumeStreamResult } from "../../decorators-
|
|
3
|
+
import { l as Laminar, p as consumeStreamResult } from "../../decorators-DQcJtTyJ.mjs";
|
|
4
4
|
import { buildFile, loadModule, selectRolloutFunction } from "./build.mjs";
|
|
5
5
|
import * as readline from "readline";
|
|
6
6
|
|
|
@@ -85,7 +85,6 @@ async function runWorker(config) {
|
|
|
85
85
|
workerLogger.debug("Consuming result (if stream)...");
|
|
86
86
|
const result = await consumeStreamResult(rawResult);
|
|
87
87
|
workerLogger.info("Rollout function completed successfully");
|
|
88
|
-
workerLogger.debug(`Result: ${JSON.stringify(result, null, 2)}`);
|
|
89
88
|
return result;
|
|
90
89
|
}
|
|
91
90
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["reconstructed: Record<string, any>","config: WorkerConfig","error: any"],"sources":["../../../src/cli/worker/index.ts"],"sourcesContent":["import * as readline from 'readline';\n\nimport { Laminar } from '../../laminar';\nimport { consumeStreamResult } from '../../opentelemetry-lib/tracing/stream-utils';\nimport { buildFile, loadModule, selectRolloutFunction } from './build';\n\n/**\n * Message types sent from child to parent via stdout\n */\ninterface LogMessage {\n type: 'log';\n level: 'info' | 'debug' | 'error' | 'warn';\n message: string;\n}\n\ninterface ResultMessage {\n type: 'result';\n data: any;\n}\n\ninterface ErrorMessage {\n type: 'error';\n error: string;\n stack?: string;\n}\n\ntype WorkerMessage = LogMessage | ResultMessage | ErrorMessage;\n\n/**\n * Configuration received from parent via stdin\n */\nexport interface WorkerConfig {\n filePath: string;\n functionName?: string;\n args: Record<string, any> | any[];\n env: Record<string, string>;\n cacheServerPort: number;\n baseUrl: string;\n projectApiKey?: string;\n httpPort: number;\n grpcPort: number;\n externalPackages?: string[];\n dynamicImportsToSkip?: string[];\n}\n\n/**\n * Prefix for worker protocol messages to distinguish from user console.log output\n */\nconst WORKER_MESSAGE_PREFIX = '__LMNR_WORKER__:';\n\n/**\n * Sends a message to parent process via stdout\n * Uses a special prefix to distinguish from user's console.log output\n */\nfunction sendMessage(message: WorkerMessage): void {\n console.log(WORKER_MESSAGE_PREFIX + JSON.stringify(message));\n}\n\n/**\n * Logger that sends log messages to parent\n */\nconst workerLogger = {\n info: (message: string) => sendMessage({ type: 'log', level: 'info', message }),\n debug: (message: string) => sendMessage({ type: 'log', level: 'debug', message }),\n error: (message: string) => sendMessage({ type: 'log', level: 'error', message }),\n warn: (message: string) => sendMessage({ type: 'log', level: 'warn', message }),\n};\n\n/**\n * Main worker execution function\n * Returns the result of the rollout function or throws an error\n */\nasync function runWorker(config: WorkerConfig): Promise<any> {\n // Set environment variables\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = value;\n }\n\n workerLogger.debug('Building user file...');\n const moduleText = await buildFile(config.filePath, {\n externalPackages: config.externalPackages,\n dynamicImportsToSkip: config.dynamicImportsToSkip,\n });\n\n workerLogger.debug('Loading user file...');\n loadModule({\n filename: config.filePath,\n moduleText,\n });\n\n // Select the appropriate rollout function\n const selectedFunction = selectRolloutFunction(config.functionName);\n workerLogger.debug(`Selected function: ${selectedFunction.name}`);\n\n // Initialize Laminar\n const urlWithoutSlash = config.baseUrl.replace(/\\/$/, '').replace(/:\\d{1,5}$/g, '');\n const baseHttpUrl = `${urlWithoutSlash}:${config.httpPort}`;\n\n if (!Laminar.initialized()) {\n workerLogger.debug('Initializing Laminar...');\n Laminar.initialize({\n projectApiKey: config.projectApiKey,\n baseUrl: config.baseUrl,\n baseHttpUrl,\n httpPort: config.httpPort,\n grpcPort: config.grpcPort,\n disableBatch: true,\n });\n }\n\n // Execute the rollout function with args\n workerLogger.debug('Executing rollout function...');\n\n const orderedArgs = Array.isArray(config.args)\n ? config.args\n : selectedFunction.params.map(param => {\n // Handle destructured parameters by reconstructing the object from nested properties\n if (param.nested && param.nested.length > 0) {\n const reconstructed: Record<string, any> = {};\n for (const nestedParam of param.nested) {\n reconstructed[nestedParam.name] = (config.args as Record<string, any>)[nestedParam.name];\n }\n return reconstructed;\n }\n // Regular parameter\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (config.args as Record<string, any>)[param.name];\n });\n workerLogger.info(\n `Calling function ${selectedFunction.name} with args: ${JSON.stringify(orderedArgs)}`,\n );\n\n const rawResult = await selectedFunction.fn(...orderedArgs);\n\n // Consume the result if it's a stream to ensure background processing completes\n workerLogger.debug('Consuming result (if stream)...');\n const result = await consumeStreamResult(rawResult);\n\n workerLogger.info('Rollout function completed successfully');\n workerLogger.debug(`Result: ${JSON.stringify(result, null, 2)}`);\n\n return result;\n}\n\n/**\n * Read configuration from stdin and start worker\n * Centralized exit point for the worker process\n */\nconst main = () => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n let configReceived = false;\n\n // This function is called anyway, so it can be async.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n rl.on('line', async (line: string) => {\n if (configReceived) {\n return;\n }\n\n try {\n const config: WorkerConfig = JSON.parse(line);\n configReceived = true;\n rl.close();\n\n // Execute the worker and handle result/errors\n try {\n const result = await runWorker(config);\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Send result back to parent\n sendMessage({ type: 'result', data: result });\n\n // Exit successfully\n process.exit(0);\n } catch (error: any) {\n\n\n workerLogger.error(`Error in worker: ${error instanceof Error ? error.message : error}`);\n\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Exit with error code\n process.exit(1);\n }\n } catch (error: any) {\n sendMessage({\n type: 'error',\n error: `Failed to parse config: ${error instanceof Error ? error.message : error}`,\n });\n process.exit(1);\n }\n });\n\n rl.on('close', () => {\n if (!configReceived) {\n sendMessage({\n type: 'error',\n error: 'No configuration received on stdin',\n });\n process.exit(1);\n }\n });\n};\n\n/**\n * Handle graceful shutdown on SIGTERM/SIGINT\n */\nconst handleShutdown = () => {\n if (Laminar.initialized()) {\n Laminar.shutdown().catch((error: any) => {\n workerLogger.error(\n `Error during Laminar shutdown: ${error instanceof Error ? error.message : error}`,\n );\n }).finally(() => {\n process.exit(0);\n });\n } else {\n process.exit(0);\n }\n};\n\n// Register signal handlers\nprocess.on('SIGTERM', handleShutdown);\nprocess.on('SIGINT', handleShutdown);\n\n// Start the worker\ntry {\n main();\n} catch (error: any) {\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n process.exit(1);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["reconstructed: Record<string, any>","config: WorkerConfig","error: any"],"sources":["../../../src/cli/worker/index.ts"],"sourcesContent":["import * as readline from 'readline';\n\nimport { Laminar } from '../../laminar';\nimport { consumeStreamResult } from '../../opentelemetry-lib/tracing/stream-utils';\nimport { buildFile, loadModule, selectRolloutFunction } from './build';\n\n/**\n * Message types sent from child to parent via stdout\n */\ninterface LogMessage {\n type: 'log';\n level: 'info' | 'debug' | 'error' | 'warn';\n message: string;\n}\n\ninterface ResultMessage {\n type: 'result';\n data: any;\n}\n\ninterface ErrorMessage {\n type: 'error';\n error: string;\n stack?: string;\n}\n\ntype WorkerMessage = LogMessage | ResultMessage | ErrorMessage;\n\n/**\n * Configuration received from parent via stdin\n */\nexport interface WorkerConfig {\n filePath: string;\n functionName?: string;\n args: Record<string, any> | any[];\n env: Record<string, string>;\n cacheServerPort: number;\n baseUrl: string;\n projectApiKey?: string;\n httpPort: number;\n grpcPort: number;\n externalPackages?: string[];\n dynamicImportsToSkip?: string[];\n}\n\n/**\n * Prefix for worker protocol messages to distinguish from user console.log output\n */\nconst WORKER_MESSAGE_PREFIX = '__LMNR_WORKER__:';\n\n/**\n * Sends a message to parent process via stdout\n * Uses a special prefix to distinguish from user's console.log output\n */\nfunction sendMessage(message: WorkerMessage): void {\n console.log(WORKER_MESSAGE_PREFIX + JSON.stringify(message));\n}\n\n/**\n * Logger that sends log messages to parent\n */\nconst workerLogger = {\n info: (message: string) => sendMessage({ type: 'log', level: 'info', message }),\n debug: (message: string) => sendMessage({ type: 'log', level: 'debug', message }),\n error: (message: string) => sendMessage({ type: 'log', level: 'error', message }),\n warn: (message: string) => sendMessage({ type: 'log', level: 'warn', message }),\n};\n\n/**\n * Main worker execution function\n * Returns the result of the rollout function or throws an error\n */\nasync function runWorker(config: WorkerConfig): Promise<any> {\n // Set environment variables\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = value;\n }\n\n workerLogger.debug('Building user file...');\n const moduleText = await buildFile(config.filePath, {\n externalPackages: config.externalPackages,\n dynamicImportsToSkip: config.dynamicImportsToSkip,\n });\n\n workerLogger.debug('Loading user file...');\n loadModule({\n filename: config.filePath,\n moduleText,\n });\n\n // Select the appropriate rollout function\n const selectedFunction = selectRolloutFunction(config.functionName);\n workerLogger.debug(`Selected function: ${selectedFunction.name}`);\n\n // Initialize Laminar\n const urlWithoutSlash = config.baseUrl.replace(/\\/$/, '').replace(/:\\d{1,5}$/g, '');\n const baseHttpUrl = `${urlWithoutSlash}:${config.httpPort}`;\n\n if (!Laminar.initialized()) {\n workerLogger.debug('Initializing Laminar...');\n Laminar.initialize({\n projectApiKey: config.projectApiKey,\n baseUrl: config.baseUrl,\n baseHttpUrl,\n httpPort: config.httpPort,\n grpcPort: config.grpcPort,\n disableBatch: true,\n });\n }\n\n // Execute the rollout function with args\n workerLogger.debug('Executing rollout function...');\n\n const orderedArgs = Array.isArray(config.args)\n ? config.args\n : selectedFunction.params.map(param => {\n // Handle destructured parameters by reconstructing the object from nested properties\n if (param.nested && param.nested.length > 0) {\n const reconstructed: Record<string, any> = {};\n for (const nestedParam of param.nested) {\n reconstructed[nestedParam.name] = (config.args as Record<string, any>)[nestedParam.name];\n }\n return reconstructed;\n }\n // Regular parameter\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return (config.args as Record<string, any>)[param.name];\n });\n workerLogger.info(\n `Calling function ${selectedFunction.name} with args: ${JSON.stringify(orderedArgs)}`,\n );\n\n const rawResult = await selectedFunction.fn(...orderedArgs);\n\n // Consume the result if it's a stream to ensure background processing completes\n workerLogger.debug('Consuming result (if stream)...');\n const result = await consumeStreamResult(rawResult);\n\n workerLogger.info('Rollout function completed successfully');\n\n return result;\n}\n\n/**\n * Read configuration from stdin and start worker\n * Centralized exit point for the worker process\n */\nconst main = () => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n let configReceived = false;\n\n // This function is called anyway, so it can be async.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n rl.on('line', async (line: string) => {\n if (configReceived) {\n return;\n }\n\n try {\n const config: WorkerConfig = JSON.parse(line);\n configReceived = true;\n rl.close();\n\n // Execute the worker and handle result/errors\n try {\n const result = await runWorker(config);\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Send result back to parent\n sendMessage({ type: 'result', data: result });\n\n // Exit successfully\n process.exit(0);\n } catch (error: any) {\n\n\n workerLogger.error(`Error in worker: ${error instanceof Error ? error.message : error}`);\n\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n\n if (Laminar.initialized()) {\n await Laminar.flush();\n }\n\n // Exit with error code\n process.exit(1);\n }\n } catch (error: any) {\n sendMessage({\n type: 'error',\n error: `Failed to parse config: ${error instanceof Error ? error.message : error}`,\n });\n process.exit(1);\n }\n });\n\n rl.on('close', () => {\n if (!configReceived) {\n sendMessage({\n type: 'error',\n error: 'No configuration received on stdin',\n });\n process.exit(1);\n }\n });\n};\n\n/**\n * Handle graceful shutdown on SIGTERM/SIGINT\n */\nconst handleShutdown = () => {\n if (Laminar.initialized()) {\n Laminar.shutdown().catch((error: any) => {\n workerLogger.error(\n `Error during Laminar shutdown: ${error instanceof Error ? error.message : error}`,\n );\n }).finally(() => {\n process.exit(0);\n });\n } else {\n process.exit(0);\n }\n};\n\n// Register signal handlers\nprocess.on('SIGTERM', handleShutdown);\nprocess.on('SIGINT', handleShutdown);\n\n// Start the worker\ntry {\n main();\n} catch (error: any) {\n sendMessage({\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n process.exit(1);\n}\n"],"mappings":"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"}
|
package/dist/cli.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const require_chunk = require('./chunk-BrXtsOCC.cjs');
|
|
3
|
-
const require_dist = require('./dist-
|
|
3
|
+
const require_dist = require('./dist-DozF0Nrf.cjs');
|
|
4
4
|
const require_utils = require('./utils-dnHn-Dz-.cjs');
|
|
5
5
|
const require_proxy_to_lmnr_cli = require('./proxy-to-lmnr-cli-CJG5N8gb.cjs');
|
|
6
6
|
let path = require("path");
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as __require, r as __toESM, t as __commonJSMin } from "./chunk-Bxrnaw5U.mjs";
|
|
3
|
-
import { n as version, t as LaminarClient } from "./dist-
|
|
3
|
+
import { n as version, t as LaminarClient } from "./dist-oYGT08tL.mjs";
|
|
4
4
|
import { i as getDirname, s as initializeLogger } from "./utils-CWdehUXP.mjs";
|
|
5
5
|
import { t as proxyToLmnrCli } from "./proxy-to-lmnr-cli-CdCqjYUJ.mjs";
|
|
6
6
|
import * as path from "path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __require } from "./chunk-Bxrnaw5U.mjs";
|
|
2
|
-
import { n as version, t as LaminarClient } from "./dist-
|
|
2
|
+
import { n as version, t as LaminarClient } from "./dist-oYGT08tL.mjs";
|
|
3
3
|
import { A as SPAN_SDK_VERSION, C as SESSION_ID, D as SPAN_LANGUAGE_VERSION, E as SPAN_INSTRUMENTATION_SOURCE, M as TRACE_HAS_BROWSER_SESSION, N as TRACE_TYPE, O as SPAN_OUTPUT, P as USER_ID, S as ROLLOUT_SESSION_ID, T as SPAN_INPUT, _ as ASSOCIATION_PROPERTIES_OVERRIDES, b as PARENT_SPAN_IDS_PATH, c as loadEnv, d as otelSpanIdToUUID, f as otelTraceIdToUUID, g as ASSOCIATION_PROPERTIES, h as validateTracingConfig, j as SPAN_TYPE, k as SPAN_PATH, l as metadataToAttributes, m as tryToOtelSpanContext, o as getOtelEnvVar, p as parseOtelHeaders, r as deserializeLaminarSpanContext, s as initializeLogger, t as NIL_UUID, u as newUUID, w as SPAN_IDS_PATH, x as PARENT_SPAN_PATH } from "./utils-CWdehUXP.mjs";
|
|
4
4
|
import { DiagConsoleLogger, DiagLogLevel, ROOT_CONTEXT, context, createContextKey, diag, isSpanContextValid, trace } from "@opentelemetry/api";
|
|
5
5
|
import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
|
|
@@ -820,179 +820,211 @@ var LaminarContextManager = class {
|
|
|
820
820
|
const logger$10 = initializeLogger();
|
|
821
821
|
const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
|
|
822
822
|
const DEFAULT_CC_PROXY_PORT = 45667;
|
|
823
|
-
const CC_PROXY_PORT_ATTEMPTS =
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
let
|
|
823
|
+
const CC_PROXY_PORT_ATTEMPTS = 50;
|
|
824
|
+
const FOUNDRY_BASE_URL_ENV = "ANTHROPIC_FOUNDRY_BASE_URL";
|
|
825
|
+
const FOUNDRY_RESOURCE_ENV = "ANTHROPIC_FOUNDRY_RESOURCE";
|
|
826
|
+
const FOUNDRY_USE_ENV = "CLAUDE_CODE_USE_FOUNDRY";
|
|
827
|
+
const activeProxyServers = /* @__PURE__ */ new Set();
|
|
828
|
+
let globalShutdownRegistered = false;
|
|
829
829
|
/**
|
|
830
|
-
*
|
|
830
|
+
* Check if environment variable value is truthy (equals '1')
|
|
831
831
|
*/
|
|
832
|
-
|
|
833
|
-
return new Promise((resolve) => {
|
|
834
|
-
let currentAttempt = 0;
|
|
835
|
-
const tryPort = (port) => {
|
|
836
|
-
const server = net.createServer();
|
|
837
|
-
server.once("error", () => {
|
|
838
|
-
server.close();
|
|
839
|
-
currentAttempt++;
|
|
840
|
-
if (currentAttempt < attempts) tryPort(startPort + currentAttempt);
|
|
841
|
-
else resolve(null);
|
|
842
|
-
});
|
|
843
|
-
server.once("listening", () => {
|
|
844
|
-
server.close(() => {
|
|
845
|
-
resolve(port);
|
|
846
|
-
});
|
|
847
|
-
});
|
|
848
|
-
server.listen(port, "127.0.0.1");
|
|
849
|
-
};
|
|
850
|
-
tryPort(startPort);
|
|
851
|
-
});
|
|
852
|
-
}
|
|
832
|
+
const isTruthyEnv = (value) => value === "1";
|
|
853
833
|
/**
|
|
854
|
-
*
|
|
834
|
+
* Resolve target URL from environment dictionary with process.env fallback.
|
|
835
|
+
*
|
|
836
|
+
* This is the single source of truth for determining the target URL for the proxy.
|
|
837
|
+
*
|
|
838
|
+
* Resolution order (highest to lowest priority):
|
|
839
|
+
* 1. HTTPS_PROXY - if set, use as target (our proxy will forward to it)
|
|
840
|
+
* 2. HTTP_PROXY - if set, use as target (our proxy will forward to it)
|
|
841
|
+
* 3. Third-party provider URLs (e.g., Foundry):
|
|
842
|
+
* - If CLAUDE_CODE_USE_FOUNDRY is truthy:
|
|
843
|
+
* - Use ANTHROPIC_FOUNDRY_BASE_URL, or
|
|
844
|
+
* - Construct from ANTHROPIC_FOUNDRY_RESOURCE
|
|
845
|
+
* 4. ANTHROPIC_BASE_URL - standard Anthropic API base URL
|
|
846
|
+
* 5. Fall back to default (https://api.anthropic.com)
|
|
847
|
+
*
|
|
848
|
+
* For each environment variable, checks envDict first, then process.env as fallback.
|
|
849
|
+
*
|
|
850
|
+
* @param envDict - Dictionary of environment variables (e.g., from options.env)
|
|
851
|
+
* @param fallback - Fallback URL if no other source found (default: DEFAULT_ANTHROPIC_BASE_URL)
|
|
852
|
+
* @returns Resolved target URL, or null if provider is misconfigured
|
|
855
853
|
*/
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
socket.once("error", () => {
|
|
875
|
-
socket.destroy();
|
|
876
|
-
setTimeout(checkPort, 100);
|
|
877
|
-
});
|
|
878
|
-
socket.connect(port, "127.0.0.1");
|
|
879
|
-
};
|
|
880
|
-
checkPort();
|
|
881
|
-
});
|
|
882
|
-
}
|
|
854
|
+
const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL) => {
|
|
855
|
+
const getEnvValue = (key) => envDict[key] || process.env[key];
|
|
856
|
+
const httpsProxy = getEnvValue("HTTPS_PROXY");
|
|
857
|
+
if (httpsProxy) return httpsProxy.replace(/\/$/, "");
|
|
858
|
+
const httpProxy = getEnvValue("HTTP_PROXY");
|
|
859
|
+
if (httpProxy) return httpProxy.replace(/\/$/, "");
|
|
860
|
+
if (isTruthyEnv(getEnvValue(FOUNDRY_USE_ENV))) {
|
|
861
|
+
const foundryBaseUrl = getEnvValue(FOUNDRY_BASE_URL_ENV);
|
|
862
|
+
if (foundryBaseUrl) return foundryBaseUrl.replace(/\/$/, "");
|
|
863
|
+
const foundryResource = getEnvValue(FOUNDRY_RESOURCE_ENV);
|
|
864
|
+
if (foundryResource) return `https://${foundryResource}.services.ai.azure.com/anthropic`;
|
|
865
|
+
logger$10.error(`${FOUNDRY_USE_ENV} is set but neither ${FOUNDRY_BASE_URL_ENV} nor ${FOUNDRY_RESOURCE_ENV} is configured. Microsoft Foundry requires one of these values.`);
|
|
866
|
+
return null;
|
|
867
|
+
}
|
|
868
|
+
const anthropicBaseUrl = getEnvValue("ANTHROPIC_BASE_URL");
|
|
869
|
+
if (anthropicBaseUrl) return anthropicBaseUrl.replace(/\/$/, "");
|
|
870
|
+
return fallback;
|
|
871
|
+
};
|
|
883
872
|
/**
|
|
884
|
-
*
|
|
873
|
+
* Get environment variables to remove from subprocess after resolving target URL.
|
|
874
|
+
* These are variables that should not be passed to the subprocess because they
|
|
875
|
+
* would interfere with our proxy setup.
|
|
876
|
+
*
|
|
877
|
+
* @param envDict - Dictionary of environment variables
|
|
878
|
+
* @returns Array of environment variable keys to remove
|
|
885
879
|
*/
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
logger$10.debug(`Unable to stop cc-proxy: ${e instanceof Error ? e.message : String(e)}`);
|
|
893
|
-
}
|
|
894
|
-
if (ccProxyTargetUrl) process.env.ANTHROPIC_BASE_URL = ccProxyTargetUrl;
|
|
895
|
-
ccProxyBaseUrl = null;
|
|
896
|
-
ccProxyTargetUrl = null;
|
|
897
|
-
ccProxyRefCount = 0;
|
|
898
|
-
ccProxyStartupPromise = null;
|
|
899
|
-
}
|
|
880
|
+
const getEnvVarsToRemove = (envDict) => {
|
|
881
|
+
const toRemove = ["HTTPS_PROXY", "HTTP_PROXY"];
|
|
882
|
+
const getEnvValue = (key) => envDict[key] || process.env[key];
|
|
883
|
+
if (isTruthyEnv(getEnvValue(FOUNDRY_USE_ENV))) toRemove.push(FOUNDRY_RESOURCE_ENV);
|
|
884
|
+
return toRemove;
|
|
885
|
+
};
|
|
900
886
|
/**
|
|
901
|
-
*
|
|
887
|
+
* Find an available port starting from the given port
|
|
902
888
|
*/
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
889
|
+
const findAvailablePort = (startPort, attempts) => new Promise((resolve) => {
|
|
890
|
+
let currentAttempt = 0;
|
|
891
|
+
const tryPort = (port) => {
|
|
892
|
+
const server = net.createServer();
|
|
893
|
+
server.once("error", () => {
|
|
894
|
+
server.close();
|
|
895
|
+
currentAttempt++;
|
|
896
|
+
if (currentAttempt < attempts) tryPort(startPort + currentAttempt);
|
|
897
|
+
else resolve(null);
|
|
908
898
|
});
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
899
|
+
server.once("listening", () => {
|
|
900
|
+
server.close(() => {
|
|
901
|
+
resolve(port);
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
server.listen(port, "127.0.0.1");
|
|
905
|
+
};
|
|
906
|
+
tryPort(startPort);
|
|
907
|
+
});
|
|
912
908
|
/**
|
|
913
|
-
*
|
|
909
|
+
* Wait for a port to be available
|
|
914
910
|
*/
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
911
|
+
const waitForPort = (port, timeoutMs = 5e3) => new Promise((resolve) => {
|
|
912
|
+
const deadline = Date.now() + timeoutMs;
|
|
913
|
+
const checkPort = () => {
|
|
914
|
+
if (Date.now() >= deadline) {
|
|
915
|
+
resolve(false);
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
const socket = new net.Socket();
|
|
919
|
+
socket.setTimeout(200);
|
|
920
|
+
socket.once("connect", () => {
|
|
921
|
+
socket.destroy();
|
|
922
|
+
resolve(true);
|
|
923
|
+
});
|
|
924
|
+
socket.once("timeout", () => {
|
|
925
|
+
socket.destroy();
|
|
926
|
+
setTimeout(checkPort, 100);
|
|
927
|
+
});
|
|
928
|
+
socket.once("error", () => {
|
|
929
|
+
socket.destroy();
|
|
930
|
+
setTimeout(checkPort, 100);
|
|
931
|
+
});
|
|
932
|
+
socket.connect(port, "127.0.0.1");
|
|
933
|
+
};
|
|
934
|
+
checkPort();
|
|
935
|
+
});
|
|
918
936
|
/**
|
|
919
|
-
*
|
|
937
|
+
* Register global cleanup on process exit for all active proxies
|
|
920
938
|
*/
|
|
921
|
-
|
|
922
|
-
if (
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
ccProxyRefCount++;
|
|
928
|
-
logger$10.debug(`Reusing existing proxy, ref count: ${ccProxyRefCount}`);
|
|
929
|
-
return ccProxyBaseUrl;
|
|
930
|
-
}
|
|
931
|
-
ccProxyStartupPromise = (async () => {
|
|
932
|
-
try {
|
|
933
|
-
const port = await findAvailablePort(DEFAULT_CC_PROXY_PORT, CC_PROXY_PORT_ATTEMPTS);
|
|
934
|
-
if (port === null) {
|
|
935
|
-
logger$10.warn("Unable to allocate port for cc-proxy.");
|
|
936
|
-
return null;
|
|
937
|
-
}
|
|
938
|
-
const targetUrl = ccProxyTargetUrl || process.env.ANTHROPIC_ORIGINAL_BASE_URL || env.ANTHROPIC_BASE_URL || process.env.ANTHROPIC_BASE_URL || DEFAULT_ANTHROPIC_BASE_URL;
|
|
939
|
-
logger$10.debug(`Using anthropic base url: ${targetUrl}`);
|
|
940
|
-
ccProxyTargetUrl = targetUrl;
|
|
941
|
-
process.env.ANTHROPIC_ORIGINAL_BASE_URL = targetUrl;
|
|
942
|
-
try {
|
|
943
|
-
const { runServer } = __require("@lmnr-ai/claude-code-proxy");
|
|
944
|
-
logger$10.debug(`Running cc-proxy server on port ${port} with target url ${targetUrl}`);
|
|
945
|
-
runServer(targetUrl, port);
|
|
939
|
+
const registerGlobalProxyShutdown = () => {
|
|
940
|
+
if (!globalShutdownRegistered) {
|
|
941
|
+
process.on("exit", () => {
|
|
942
|
+
logger$10.debug("process.on(\"exit\") called - stopping all active proxies");
|
|
943
|
+
for (const proxyServer of activeProxyServers) try {
|
|
944
|
+
proxyServer.stopServer();
|
|
946
945
|
} catch (e) {
|
|
947
|
-
logger$10.
|
|
948
|
-
return null;
|
|
946
|
+
logger$10.debug(`Failed to stop proxy: ${e instanceof Error ? e.message : String(e)}`);
|
|
949
947
|
}
|
|
948
|
+
activeProxyServers.clear();
|
|
949
|
+
});
|
|
950
|
+
globalShutdownRegistered = true;
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
/**
|
|
954
|
+
* Create and start a new claude-code proxy server instance
|
|
955
|
+
* Each call creates an independent proxy on a unique port
|
|
956
|
+
*/
|
|
957
|
+
const createProxyInstance = async ({ env }) => {
|
|
958
|
+
try {
|
|
959
|
+
const port = await findAvailablePort(DEFAULT_CC_PROXY_PORT, CC_PROXY_PORT_ATTEMPTS);
|
|
960
|
+
if (port === null) {
|
|
961
|
+
logger$10.warn("Unable to allocate port for cc-proxy.");
|
|
962
|
+
return null;
|
|
963
|
+
}
|
|
964
|
+
const targetUrl = resolveTargetUrlFromEnv(env);
|
|
965
|
+
if (!targetUrl) {
|
|
966
|
+
logger$10.warn("Unable to resolve target URL for cc-proxy (provider misconfigured).");
|
|
967
|
+
return null;
|
|
968
|
+
}
|
|
969
|
+
logger$10.debug(`Creating proxy instance on port ${port} targeting: ${targetUrl}`);
|
|
970
|
+
try {
|
|
971
|
+
const { ProxyServer } = __require("@lmnr-ai/claude-code-proxy");
|
|
972
|
+
const proxyServer = new ProxyServer(port);
|
|
973
|
+
proxyServer.runServer(targetUrl);
|
|
950
974
|
if (!await waitForPort(port)) {
|
|
951
975
|
logger$10.warn(`cc-proxy failed to start on port ${port}`);
|
|
952
|
-
|
|
953
|
-
stopServer();
|
|
976
|
+
proxyServer.stopServer();
|
|
954
977
|
return null;
|
|
955
978
|
}
|
|
956
979
|
const proxyBaseUrl = `http://127.0.0.1:${port}`;
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
process.env.ANTHROPIC_BASE_URL = proxyBaseUrl;
|
|
960
|
-
registerProxyShutdown();
|
|
980
|
+
activeProxyServers.add(proxyServer);
|
|
981
|
+
registerGlobalProxyShutdown();
|
|
961
982
|
logger$10.info(`Started claude proxy server on: ${proxyBaseUrl}`);
|
|
962
|
-
return
|
|
963
|
-
|
|
964
|
-
|
|
983
|
+
return {
|
|
984
|
+
server: proxyServer,
|
|
985
|
+
baseUrl: proxyBaseUrl,
|
|
986
|
+
port,
|
|
987
|
+
targetUrl
|
|
988
|
+
};
|
|
989
|
+
} catch (e) {
|
|
990
|
+
logger$10.warn(`Unable to start cc-proxy: ${e instanceof Error ? e.message : String(e)}`);
|
|
991
|
+
return null;
|
|
965
992
|
}
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
|
|
993
|
+
} catch (e) {
|
|
994
|
+
logger$10.warn(`Failed to create proxy instance: ${e instanceof Error ? e.message : String(e)}`);
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
};
|
|
969
998
|
/**
|
|
970
|
-
*
|
|
999
|
+
* Stop a specific proxy instance
|
|
971
1000
|
*/
|
|
972
|
-
|
|
973
|
-
if (
|
|
974
|
-
|
|
975
|
-
logger$10.debug(`
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
logger$10.debug(
|
|
1001
|
+
const stopProxyInstance = (instance) => {
|
|
1002
|
+
if (!instance) return;
|
|
1003
|
+
try {
|
|
1004
|
+
logger$10.debug(`Stopping proxy instance on port ${instance.port}`);
|
|
1005
|
+
instance.server.stopServer();
|
|
1006
|
+
activeProxyServers.delete(instance.server);
|
|
1007
|
+
} catch (e) {
|
|
1008
|
+
logger$10.debug(`Failed to stop proxy instance: ${e instanceof Error ? e.message : String(e)}`);
|
|
980
1009
|
}
|
|
981
|
-
}
|
|
1010
|
+
};
|
|
982
1011
|
/**
|
|
983
|
-
* Force stop
|
|
1012
|
+
* Force stop all active proxy servers
|
|
984
1013
|
* Used during shutdown to ensure cleanup
|
|
985
1014
|
*/
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1015
|
+
const forceReleaseProxy = () => {
|
|
1016
|
+
logger$10.debug(`Force stopping all ${activeProxyServers.size} active proxy servers`);
|
|
1017
|
+
for (const proxyServer of activeProxyServers) try {
|
|
1018
|
+
proxyServer.stopServer();
|
|
1019
|
+
} catch (e) {
|
|
1020
|
+
logger$10.debug(`Failed to stop proxy: ${e instanceof Error ? e.message : String(e)}`);
|
|
990
1021
|
}
|
|
991
|
-
|
|
1022
|
+
activeProxyServers.clear();
|
|
1023
|
+
};
|
|
992
1024
|
/**
|
|
993
1025
|
* Get the current span context payload for proxy
|
|
994
1026
|
*/
|
|
995
|
-
|
|
1027
|
+
const getSpanContextPayload = () => {
|
|
996
1028
|
const currentSpan = trace.getSpan(LaminarContextManager.getContext());
|
|
997
1029
|
if (!currentSpan || !currentSpan.spanContext().isRemote && !currentSpan.isRecording()) return null;
|
|
998
1030
|
const spanContext = currentSpan.spanContext();
|
|
@@ -1018,31 +1050,28 @@ function getSpanContextPayload() {
|
|
|
1018
1050
|
span_path: spanPath,
|
|
1019
1051
|
laminar_url: laminarUrl || "https://api.lmnr.ai"
|
|
1020
1052
|
};
|
|
1021
|
-
}
|
|
1053
|
+
};
|
|
1022
1054
|
/**
|
|
1023
|
-
*
|
|
1055
|
+
* Set the trace context for a specific proxy instance
|
|
1024
1056
|
*/
|
|
1025
|
-
|
|
1057
|
+
const setTraceToProxyInstance = async (instance) => {
|
|
1058
|
+
if (!instance) return;
|
|
1026
1059
|
const payload = getSpanContextPayload();
|
|
1027
1060
|
if (!payload) return;
|
|
1028
1061
|
try {
|
|
1029
|
-
|
|
1030
|
-
setCurrentTrace({
|
|
1062
|
+
await instance.server.setCurrentTrace({
|
|
1031
1063
|
traceId: payload.trace_id,
|
|
1032
1064
|
spanId: payload.span_id,
|
|
1033
1065
|
projectApiKey: payload.project_api_key,
|
|
1034
1066
|
spanIdsPath: payload.span_ids_path,
|
|
1035
1067
|
spanPath: payload.span_path,
|
|
1036
1068
|
laminarUrl: payload.laminar_url
|
|
1037
|
-
}).catch((error) => {
|
|
1038
|
-
logger$10.debug("Failed to set trace context to proxy: " + (error instanceof Error ? error.message : String(error)));
|
|
1039
|
-
}).finally(() => {
|
|
1040
|
-
logger$10.debug("Set trace context to proxy");
|
|
1041
1069
|
});
|
|
1070
|
+
logger$10.debug(`Set trace context to proxy on port ${instance.port}`);
|
|
1042
1071
|
} catch (e) {
|
|
1043
|
-
logger$10.debug(
|
|
1072
|
+
logger$10.debug(`Unable to set trace context to proxy on port ${instance.port}: ` + (e instanceof Error ? e.message : String(e)));
|
|
1044
1073
|
}
|
|
1045
|
-
}
|
|
1074
|
+
};
|
|
1046
1075
|
|
|
1047
1076
|
//#endregion
|
|
1048
1077
|
//#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/index.ts
|
|
@@ -1063,17 +1092,29 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1063
1092
|
span.setAttribute(SPAN_INPUT, JSON.stringify({ prompt: typeof params.prompt === "string" ? params.prompt : "<stream>" }));
|
|
1064
1093
|
const generator = async function* () {
|
|
1065
1094
|
const collected = [];
|
|
1095
|
+
let proxyInstance = null;
|
|
1066
1096
|
try {
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1097
|
+
const mergedEnv = {
|
|
1098
|
+
...process.env,
|
|
1099
|
+
...params.options?.env ?? {}
|
|
1100
|
+
};
|
|
1101
|
+
const targetUrl = resolveTargetUrlFromEnv(mergedEnv);
|
|
1102
|
+
proxyInstance = await createProxyInstance({ env: mergedEnv });
|
|
1103
|
+
if (proxyInstance && targetUrl) {
|
|
1104
|
+
logger$9.debug(`Using proxy on port ${proxyInstance.port}`);
|
|
1105
|
+
await Laminar.withSpan(span, async () => {
|
|
1106
|
+
logger$9.debug("Setting trace to proxy instance...");
|
|
1107
|
+
await setTraceToProxyInstance(proxyInstance);
|
|
1074
1108
|
});
|
|
1075
|
-
|
|
1076
|
-
|
|
1109
|
+
const varsToRemove = getEnvVarsToRemove(mergedEnv);
|
|
1110
|
+
if (!params.options) params.options = {};
|
|
1111
|
+
if (!params.options.env) params.options.env = {};
|
|
1112
|
+
params.options.env = { ...mergedEnv };
|
|
1113
|
+
params.options.env.ANTHROPIC_BASE_URL = proxyInstance.baseUrl;
|
|
1114
|
+
params.options.env.ANTHROPIC_ORIGINAL_BASE_URL = targetUrl;
|
|
1115
|
+
for (const varName of varsToRemove) delete params.options.env[varName];
|
|
1116
|
+
if (params.options.env.CLAUDE_CODE_USE_FOUNDRY === "1") params.options.env.ANTHROPIC_FOUNDRY_BASE_URL = proxyInstance.baseUrl;
|
|
1117
|
+
} else logger$9.debug("No claude proxy server available. Proceeding without proxy.");
|
|
1077
1118
|
const originalGenerator = originalQuery(params);
|
|
1078
1119
|
for await (const message of originalGenerator) {
|
|
1079
1120
|
collected.push(message);
|
|
@@ -1085,7 +1126,7 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1085
1126
|
});
|
|
1086
1127
|
throw error;
|
|
1087
1128
|
} finally {
|
|
1088
|
-
|
|
1129
|
+
stopProxyInstance(proxyInstance);
|
|
1089
1130
|
span.setAttribute(SPAN_OUTPUT, JSON.stringify(collected));
|
|
1090
1131
|
span.end();
|
|
1091
1132
|
}
|
|
@@ -4851,4 +4892,4 @@ function observeExperimentalDecorator(config) {
|
|
|
4851
4892
|
|
|
4852
4893
|
//#endregion
|
|
4853
4894
|
export { getTracer as a, initializeLaminarInstrumentations as c, LaminarContextManager as d, TracingLevel as f, withTracingLevel as i, Laminar as l, stringifyPromptForTelemetry as m, observeDecorator as n, getTracerProvider as o, consumeStreamResult as p, observeExperimentalDecorator as r, LaminarSpanProcessor as s, observe as t, instrumentClaudeAgentQuery as u };
|
|
4854
|
-
//# sourceMappingURL=decorators-
|
|
4895
|
+
//# sourceMappingURL=decorators-DQcJtTyJ.mjs.map
|