@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.
@@ -1,7 +1,7 @@
1
1
  const require_chunk = require('../../chunk-BrXtsOCC.cjs');
2
- require('../../dist-TqD6UrQB.cjs');
2
+ require('../../dist-DozF0Nrf.cjs');
3
3
  require('../../utils-dnHn-Dz-.cjs');
4
- const require_decorators = require('../../decorators-BMu8FLY8.cjs');
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-yFPIkWoB.mjs";
1
+ import "../../dist-oYGT08tL.mjs";
2
2
  import "../../utils-CWdehUXP.mjs";
3
- import { l as Laminar, p as consumeStreamResult } from "../../decorators-BNkfMc8I.mjs";
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-TqD6UrQB.cjs');
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-yFPIkWoB.mjs";
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-yFPIkWoB.mjs";
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 = 5;
824
- let ccProxyBaseUrl = null;
825
- let ccProxyTargetUrl = null;
826
- let ccProxyShutdownRegistered = false;
827
- let ccProxyRefCount = 0;
828
- let ccProxyStartupPromise = null;
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
- * Find an available port starting from the given port
830
+ * Check if environment variable value is truthy (equals '1')
831
831
  */
832
- function findAvailablePort(startPort, attempts) {
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
- * Wait for a port to be available
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
- function waitForPort(port, timeoutMs = 5e3) {
857
- return new Promise((resolve) => {
858
- const deadline = Date.now() + timeoutMs;
859
- const checkPort = () => {
860
- if (Date.now() >= deadline) {
861
- resolve(false);
862
- return;
863
- }
864
- const socket = new net.Socket();
865
- socket.setTimeout(200);
866
- socket.once("connect", () => {
867
- socket.destroy();
868
- resolve(true);
869
- });
870
- socket.once("timeout", () => {
871
- socket.destroy();
872
- setTimeout(checkPort, 100);
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
- * Stop the claude-code proxy server
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
- function stopCcProxy() {
887
- try {
888
- const { stopServer } = __require("@lmnr-ai/claude-code-proxy");
889
- logger$10.debug("Stopping cc-proxy...");
890
- stopServer();
891
- } catch (e) {
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
- * Register cleanup on process exit
887
+ * Find an available port starting from the given port
902
888
  */
903
- function registerProxyShutdown() {
904
- if (!ccProxyShutdownRegistered) {
905
- process.on("exit", () => {
906
- logger$10.debug("process.on(\"exit\") called");
907
- stopCcProxy();
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
- ccProxyShutdownRegistered = true;
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
- * Get the current proxy base URL if running
909
+ * Wait for a port to be available
914
910
  */
915
- function getProxyBaseUrl() {
916
- return ccProxyBaseUrl;
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
- * Start the claude-code proxy server with reference counting
937
+ * Register global cleanup on process exit for all active proxies
920
938
  */
921
- async function startProxy({ env }) {
922
- if (ccProxyStartupPromise !== null) {
923
- logger$10.debug("Waiting for ongoing proxy startup to complete");
924
- await ccProxyStartupPromise;
925
- }
926
- if (ccProxyBaseUrl !== null) {
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.warn(`Unable to start cc-proxy: ${e instanceof Error ? e.message : String(e)}`);
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
- const { stopServer } = __require("@lmnr-ai/claude-code-proxy");
953
- stopServer();
976
+ proxyServer.stopServer();
954
977
  return null;
955
978
  }
956
979
  const proxyBaseUrl = `http://127.0.0.1:${port}`;
957
- ccProxyBaseUrl = proxyBaseUrl;
958
- ccProxyRefCount = 1;
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 proxyBaseUrl;
963
- } finally {
964
- ccProxyStartupPromise = null;
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
- return ccProxyStartupPromise;
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
- * Release/stop the claude-code proxy server with reference counting
999
+ * Stop a specific proxy instance
971
1000
  */
972
- function releaseProxy() {
973
- if (ccProxyRefCount > 0) {
974
- ccProxyRefCount--;
975
- logger$10.debug(`Decremented proxy ref count to: ${ccProxyRefCount}`);
976
- }
977
- if (ccProxyRefCount === 0 && ccProxyBaseUrl !== null) {
978
- stopCcProxy();
979
- logger$10.debug("Stopped claude proxy server (ref count reached 0)");
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 the claude-code proxy server, ignoring reference count
1012
+ * Force stop all active proxy servers
984
1013
  * Used during shutdown to ensure cleanup
985
1014
  */
986
- function forceReleaseProxy() {
987
- if (ccProxyBaseUrl !== null) {
988
- stopCcProxy();
989
- logger$10.debug("Force stopped claude proxy server");
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
- function getSpanContextPayload() {
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
- * Publish the current span context to the proxy server
1055
+ * Set the trace context for a specific proxy instance
1024
1056
  */
1025
- function setTraceToProxy() {
1057
+ const setTraceToProxyInstance = async (instance) => {
1058
+ if (!instance) return;
1026
1059
  const payload = getSpanContextPayload();
1027
1060
  if (!payload) return;
1028
1061
  try {
1029
- const { setCurrentTrace } = __require("@lmnr-ai/claude-code-proxy");
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("Unable to set trace context to proxy: " + (e instanceof Error ? e.message : String(e)));
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
- await startProxy({ env: params.options?.env ?? process.env });
1068
- const proxyBaseUrl = getProxyBaseUrl();
1069
- logger$9.debug(`getProxyBaseUrl() result: ${proxyBaseUrl}`);
1070
- if (proxyBaseUrl) {
1071
- Laminar.withSpan(span, () => {
1072
- logger$9.debug("Setting trace to proxy...");
1073
- setTraceToProxy();
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
- if (params.options?.env) params.options.env.ANTHROPIC_BASE_URL = proxyBaseUrl;
1076
- } else logger$9.debug("No claude proxy server found. Skipping span context publication.");
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
- releaseProxy();
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-BNkfMc8I.mjs.map
4895
+ //# sourceMappingURL=decorators-DQcJtTyJ.mjs.map