// lib/config/defineConfig.ts
function defineConfig(config) {
  return config;
}

// lib/config/loader.ts
import { existsSync } from "fs";
import { resolve } from "path";
import { pathToFileURL } from "url";

// lib/config.ts
var isServerSide = typeof window === "undefined";
var SERVER_PORT = isServerSide ? process.env?.AGENT_HEALTH_PORT || "4001" : "4001";
var BACKEND_URL = isServerSide ? `http://localhost:${SERVER_PORT}` : "";
var browserEnv = {};
if (typeof window !== "undefined" && typeof document !== "undefined") {
  try {
    browserEnv = import.meta?.env || {};
  } catch {
  }
}
var getEnvVar = (key, defaultValue) => {
  if (isServerSide) {
    return process.env?.[key] || defaultValue || "";
  }
  return browserEnv[key] || defaultValue || "";
};
var ENV_CONFIG = {
  // Backend server - empty string means relative URLs
  backendUrl: BACKEND_URL,
  // API endpoints (derived from backend URL)
  judgeApiUrl: `${BACKEND_URL}/api/judge`,
  storageApiUrl: `${BACKEND_URL}/api/storage`,
  agentProxyUrl: `${BACKEND_URL}/api/agent`,
  openSearchProxyUrl: `${BACKEND_URL}/api/opensearch/logs`,
  // AWS/Bedrock
  awsRegion: getEnvVar("AWS_REGION", "us-east-1"),
  awsProfile: getEnvVar("AWS_PROFILE", "default"),
  bedrockModelId: getEnvVar("BEDROCK_MODEL_ID", "anthropic.claude-3-5-sonnet-20241022-v2:0"),
  // OpenSearch Logs (for fetching agent observability data)
  openSearchLogsEndpoint: getEnvVar("OPENSEARCH_LOGS_ENDPOINT", ""),
  openSearchLogsUsername: getEnvVar("OPENSEARCH_LOGS_USERNAME", ""),
  openSearchLogsPassword: getEnvVar("OPENSEARCH_LOGS_PASSWORD", ""),
  openSearchLogsTracesIndex: getEnvVar("OPENSEARCH_LOGS_TRACES_INDEX", "otel-v1-apm-span-*"),
  openSearchLogsIndex: getEnvVar("OPENSEARCH_LOGS_INDEX", "ml-commons-logs-*"),
  // ML-Commons agent endpoint
  mlcommonsEndpoint: getEnvVar("MLCOMMONS_ENDPOINT", "http://localhost:9200/_plugins/_ml/agents/{agent_id}/_execute/stream"),
  // ML-Commons agent headers
  mlcommonsHeaderOpenSearchUrl: getEnvVar("MLCOMMONS_HEADER_OPENSEARCH_URL", ""),
  mlcommonsHeaderAuthorization: getEnvVar("MLCOMMONS_HEADER_AUTHORIZATION", ""),
  mlcommonsHeaderAwsRegion: getEnvVar("MLCOMMONS_HEADER_AWS_REGION", ""),
  mlcommonsHeaderAwsServiceName: getEnvVar("MLCOMMONS_HEADER_AWS_SERVICE_NAME", "es"),
  mlcommonsHeaderAwsAccessKeyId: getEnvVar("MLCOMMONS_HEADER_AWS_ACCESS_KEY_ID", ""),
  mlcommonsHeaderAwsSecretAccessKey: getEnvVar("MLCOMMONS_HEADER_AWS_SECRET_ACCESS_KEY", ""),
  mlcommonsHeaderAwsSessionToken: getEnvVar("MLCOMMONS_HEADER_AWS_SESSION_TOKEN", ""),
  // Travel Planner multi-agent endpoint (OTel Demo in Docker)
  travelPlannerEndpoint: getEnvVar("TRAVEL_PLANNER_ENDPOINT", "http://localhost:3000"),
  // OpenAI-compatible (optional - for OpenAI-compatible judge/agent endpoints)
  openaiCompatibleApiKey: getEnvVar("OPENAI_COMPATIBLE_API_KEY", ""),
  openaiCompatibleEndpoint: getEnvVar("OPENAI_COMPATIBLE_ENDPOINT", "http://localhost:4000/v1/chat/completions"),
  // Observio Sample Agent endpoint
  observioEndpoint: getEnvVar("OBSERVIO_ENDPOINT", "http://localhost:3001/run-agent"),
  // Claude Code Telemetry (optional - for OTEL traces from Claude Code)
  claudeCodeTelemetryEnabled: getEnvVar("CLAUDE_CODE_TELEMETRY_ENABLED", "false") === "true",
  otelExporterEndpoint: getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT", ""),
  otelServiceName: getEnvVar("OTEL_SERVICE_NAME", "claude-code-agent"),
  otelExporterProtocol: getEnvVar("OTEL_EXPORTER_OTLP_PROTOCOL", ""),
  otelExporterHeaders: getEnvVar("OTEL_EXPORTER_OTLP_HEADERS", "")
};

// lib/constants.ts
var CONNECTOR_TYPE_INFO = {
  "agui-streaming": {
    label: "AG-UI Streaming",
    description: "AG-UI protocol over SSE. Use for ML-Commons and AG-UI compatible agents.",
    serverOnly: false
  },
  "rest": {
    label: "REST",
    description: "Standard HTTP POST. Agent receives JSON, returns JSON. No streaming.",
    serverOnly: false
  },
  "openai-compatible": {
    label: "OpenAI Compatible",
    description: "OpenAI chat completions format (POST /v1/chat/completions). Works with LiteLLM, Ollama, vLLM.",
    serverOnly: false
  },
  "subprocess": {
    label: "Subprocess",
    description: "Runs a CLI command as a child process. Server-only \u2014 use the CLI or benchmark runner.",
    serverOnly: true
  },
  "claude-code": {
    label: "Claude Code",
    description: "Invokes the Claude Code CLI. Server-only \u2014 use the CLI or benchmark runner.",
    serverOnly: true
  },
  "pi": {
    label: "Pi (pi.dev)",
    description: "Invokes the pi.dev coding agent CLI. Server-only \u2014 use the CLI or benchmark runner.",
    serverOnly: true
  },
  "strands": {
    label: "Amazon Strands",
    description: "Amazon Strands agent framework via Bedrock Agent Runtime API. Server-only \u2014 requires AWS SDK.",
    serverOnly: true
  },
  "langgraph": {
    label: "LangGraph (REST)",
    description: "LangGraph agent via direct REST API. Use for non-AG-UI LangGraph instances.",
    serverOnly: false
  },
  "mock": {
    label: "Mock",
    description: "Built-in demo agent for testing. No real endpoint needed.",
    serverOnly: false
  }
};
var VALID_CONNECTOR_TYPES = Object.keys(CONNECTOR_TYPE_INFO);
var BROWSER_SAFE_CONNECTORS = Object.entries(CONNECTOR_TYPE_INFO).filter(([, info]) => !info.serverOnly).map(([type]) => type);
function getClaudeCodeConnectorEnv() {
  const env = {
    AWS_PROFILE: ENV_CONFIG.awsProfile || "Bedrock",
    CLAUDE_CODE_USE_BEDROCK: "1",
    AWS_REGION: ENV_CONFIG.awsRegion || "us-west-2",
    DISABLE_PROMPT_CACHING: "1",
    DISABLE_ERROR_REPORTING: "1"
  };
  if (ENV_CONFIG.claudeCodeTelemetryEnabled && ENV_CONFIG.otelExporterEndpoint) {
    env.CLAUDE_CODE_ENABLE_TELEMETRY = "1";
    env.OTEL_EXPORTER_OTLP_ENDPOINT = ENV_CONFIG.otelExporterEndpoint;
    env.OTEL_SERVICE_NAME = ENV_CONFIG.otelServiceName;
    if (ENV_CONFIG.otelExporterProtocol) {
      env.OTEL_EXPORTER_OTLP_PROTOCOL = ENV_CONFIG.otelExporterProtocol;
    }
    if (ENV_CONFIG.otelExporterHeaders) {
      env.OTEL_EXPORTER_OTLP_HEADERS = ENV_CONFIG.otelExporterHeaders;
    }
  } else {
    env.DISABLE_TELEMETRY = "1";
  }
  return env;
}
var DEFAULT_CONFIG = {
  agents: [
    {
      key: "demo",
      name: "Demo Agent",
      endpoint: "mock://demo",
      description: "Mock agent for testing (simulated responses)",
      connectorType: "mock",
      headers: {},
      useTraces: false
    },
    {
      key: "observio",
      name: "Observio Sample Agent",
      endpoint: ENV_CONFIG.observioEndpoint || "http://localhost:3001/run-agent",
      description: "Observio sample agent \u2014 ReAct pattern with LangGraph and Bedrock. Start with: cd observio-sample-agent && npm run start:ag-ui",
      connectorType: "agui-streaming",
      headers: {},
      useTraces: true,
      // OTel `service.name` differs from the agent key for the observio sample
      // agent (see observio-sample-agent/src/telemetry/provider.ts), so the
      // Agent Traces page translates `prefs:agentFilter == 'observio'` to a
      // service-name filter of 'observio-sample-agent' at query time.
      traceServiceName: "observio-sample-agent"
    },
    {
      key: "claude-code",
      name: "Claude Code",
      endpoint: "claude",
      description: "Claude Code CLI agent (requires claude command installed)",
      connectorType: "claude-code",
      headers: {},
      useTraces: ENV_CONFIG.claudeCodeTelemetryEnabled && !!ENV_CONFIG.otelExporterEndpoint,
      connectorConfig: { env: getClaudeCodeConnectorEnv() }
    },
    {
      key: "strands",
      name: "Amazon Strands",
      endpoint: "${STRANDS_AGENT_ID}",
      description: "Amazon Strands agent framework (Bedrock Agent Runtime)",
      connectorType: "strands",
      headers: {},
      useTraces: false,
      connectorConfig: {
        agentAliasId: "${STRANDS_ALIAS_ID:-TSTALIASID}",
        region: "${AWS_REGION:-us-east-1}"
      },
      enabled: false
    },
    {
      key: "pi",
      name: "Pi (pi.dev)",
      endpoint: "pi",
      description: "Pi.dev coding agent with Agent Health package (requires pi CLI installed)",
      connectorType: "pi",
      headers: {},
      useTraces: false,
      connectorConfig: {
        packagePath: "./observio-sample-agent/pi-package"
      },
      enabled: false
    },
    {
      key: "langgraph-rest",
      name: "LangGraph (REST)",
      endpoint: "${LANGGRAPH_API_ENDPOINT:-http://localhost:8000}",
      description: "LangGraph agent via direct REST API",
      connectorType: "langgraph",
      headers: {},
      useTraces: false,
      enabled: false
    }
  ],
  models: {
    "demo-model": {
      model_id: "mock://demo-model",
      display_name: "Demo Model",
      provider: "demo",
      context_window: 2e5,
      max_output_tokens: 4096
    },
    "claude-opus-4.6": {
      model_id: "us.anthropic.claude-opus-4-6-v1",
      display_name: "Claude Opus 4.6",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 128e3
    },
    "claude-sonnet-4.6": {
      model_id: "us.anthropic.claude-sonnet-4-6",
      display_name: "Claude Sonnet 4.6",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 64e3
    },
    "claude-haiku-4.5": {
      model_id: "us.anthropic.claude-haiku-4-5-20251001-v1:0",
      display_name: "Claude Haiku 4.5",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 64e3
    },
    "claude-opus-4.5": {
      model_id: "us.anthropic.claude-opus-4-5-20251101-v1:0",
      display_name: "Claude Opus 4.5",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 64e3
    },
    "claude-opus-4.1": {
      model_id: "us.anthropic.claude-opus-4-1-20250805-v1:0",
      display_name: "Claude Opus 4.1",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 32e3
    },
    "claude-opus-4": {
      model_id: "us.anthropic.claude-opus-4-20250514-v1:0",
      display_name: "Claude Opus 4",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 32e3
    },
    "claude-sonnet-4.5": {
      model_id: "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
      display_name: "Claude Sonnet 4.5",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 4096
    },
    "claude-sonnet-4": {
      model_id: "us.anthropic.claude-sonnet-4-20250514-v1:0",
      display_name: "Claude Sonnet 4",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 4096
    },
    "claude-haiku-3.5": {
      model_id: "us.anthropic.claude-3-5-haiku-20241022-v1:0",
      display_name: "Claude Haiku 3.5",
      provider: "bedrock",
      context_window: 2e5,
      max_output_tokens: 4096
    },
    "claude-code-judge": {
      model_id: "claude-code-judge",
      display_name: "Claude Code (Judge)",
      provider: "claude-code",
      context_window: 2e5,
      max_output_tokens: 16384
    },
    "agentic-claude-code": {
      model_id: "agentic-claude-code",
      display_name: "Claude Code (Agentic)",
      provider: "agentic",
      context_window: 2e5,
      max_output_tokens: 16384
    },
    "agentic-custom": {
      model_id: "agentic-custom",
      display_name: "Custom Agentic Judge",
      provider: "agentic",
      context_window: 2e5,
      max_output_tokens: 16384
    },
    "gpt-4o": {
      model_id: "gpt-4o",
      display_name: "GPT-4o",
      provider: "openai-compatible",
      context_window: 128e3,
      max_output_tokens: 4096
    },
    "deepseek-r1:8b": {
      model_id: "deepseek-r1:8b",
      display_name: "DeepSeek R1 8B (Ollama)",
      provider: "openai-compatible",
      context_window: 128e3,
      max_output_tokens: 8192
    },
    "gemma3:12b": {
      model_id: "gemma3:12b",
      display_name: "Gemma 3 12B (Ollama)",
      provider: "openai-compatible",
      context_window: 128e3,
      max_output_tokens: 8192
    }
  },
  defaults: {
    retry_attempts: 2,
    retry_delay_ms: 1e3
  }
};

// lib/portConfig.ts
var DEFAULT_BACKEND_PORT = 4001;
function resolveBackendPort() {
  const port = process.env.AGENT_HEALTH_PORT;
  if (port) {
    const parsed = parseInt(port, 10);
    if (!isNaN(parsed)) return parsed;
  }
  return DEFAULT_BACKEND_PORT;
}

// lib/config/loader.ts
var DEFAULT_SERVER_CONFIG = {
  port: resolveBackendPort(),
  reuseExistingServer: !process.env.CI,
  startTimeout: 3e4
};
var CONFIG_FILE_NAMES = [
  "agent-health.config.ts",
  "agent-health.config.js",
  "agent-health.config.mjs"
];
var SERVER_JSON_CONFIG_FILENAME = "agent-health.config.json";
function hasServerJsonConfig(cwd = process.cwd()) {
  return existsSync(resolve(cwd, SERVER_JSON_CONFIG_FILENAME));
}
function findConfigFile(cwd = process.cwd()) {
  for (const fileName of CONFIG_FILE_NAMES) {
    const filePath = resolve(cwd, fileName);
    if (existsSync(filePath)) {
      const format = fileName.endsWith(".ts") ? "typescript" : "javascript";
      return { path: filePath, format, exists: true };
    }
  }
  return null;
}
function toAgentConfig(userAgent) {
  return {
    key: userAgent.key,
    name: userAgent.name,
    endpoint: userAgent.endpoint,
    description: userAgent.description,
    enabled: userAgent.enabled ?? true,
    headers: userAgent.headers ?? {},
    useTraces: userAgent.useTraces ?? false,
    connectorType: userAgent.connectorType,
    connectorConfig: userAgent.connectorConfig,
    hooks: userAgent.hooks
  };
}
function toModelConfig(userModel) {
  return [
    userModel.key,
    {
      model_id: userModel.model_id,
      display_name: userModel.display_name,
      provider: userModel.provider ?? "bedrock",
      context_window: userModel.context_window ?? 2e5,
      max_output_tokens: userModel.max_output_tokens ?? 4096
    }
  ];
}
function mergeConfigs(userConfig, defaultConfig) {
  const shouldExtend = userConfig.extends !== false;
  let agents;
  if (shouldExtend) {
    const agentMap = /* @__PURE__ */ new Map();
    for (const agent of defaultConfig.agents) {
      agentMap.set(agent.key, agent);
    }
    for (const userAgent of userConfig.agents ?? []) {
      agentMap.set(userAgent.key, toAgentConfig(userAgent));
    }
    agents = Array.from(agentMap.values());
  } else {
    agents = (userConfig.agents ?? []).map(toAgentConfig);
  }
  let models;
  if (shouldExtend) {
    models = { ...defaultConfig.models };
    for (const userModel of userConfig.models ?? []) {
      const [key, config] = toModelConfig(userModel);
      models[key] = config;
    }
  } else {
    models = {};
    for (const userModel of userConfig.models ?? []) {
      const [key, config] = toModelConfig(userModel);
      models[key] = config;
    }
  }
  const connectors = userConfig.connectors ?? [];
  const testCases = userConfig.testCases ? Array.isArray(userConfig.testCases) ? userConfig.testCases : [userConfig.testCases] : [];
  const reporters = userConfig.reporters ?? [["console"]];
  const judge = userConfig.judge ?? {
    provider: "bedrock",
    model: "claude-sonnet-4"
  };
  const server = {
    ...DEFAULT_SERVER_CONFIG,
    ...userConfig.server
  };
  const telemetry = userConfig.telemetry ?? {};
  return {
    server,
    agents,
    models,
    connectors,
    testCases,
    reporters,
    judge,
    telemetry
  };
}
async function loadUserConfig(configPath) {
  try {
    const fileUrl = pathToFileURL(configPath).href;
    const module = await import(fileUrl);
    return module.default ?? module;
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    throw new Error(`Failed to load config file ${configPath}: ${message}`);
  }
}
var cachedConfig = null;
var cachedConfigPath = null;
async function loadConfig(cwd = process.cwd(), force = false) {
  const configFile = findConfigFile(cwd);
  if (!force && cachedConfig && cachedConfigPath === configFile?.path) {
    return cachedConfig;
  }
  let userConfig = {};
  if (configFile) {
    console.log(`[Config] Loading ${configFile.path}`);
    userConfig = await loadUserConfig(configFile.path);
  } else if (hasServerJsonConfig(cwd)) {
    console.log(
      `[Config] No code config (agent-health.config.{ts,js,mjs}); server JSON config (${SERVER_JSON_CONFIG_FILENAME}) detected and loaded by server services. Using built-in defaults for agents/models.`
    );
  } else {
    console.log("[Config] No config file found, using defaults + environment variables");
  }
  const resolved = mergeConfigs(userConfig, DEFAULT_CONFIG);
  cachedConfig = resolved;
  cachedConfigPath = configFile?.path ?? null;
  console.log(`[Config] Loaded ${resolved.agents.length} agents, ${Object.keys(resolved.models).length} models`);
  return resolved;
}
function loadConfigSync(cwd = process.cwd()) {
  if (cachedConfig) {
    return cachedConfig;
  }
  return {
    server: DEFAULT_SERVER_CONFIG,
    agents: DEFAULT_CONFIG.agents,
    models: DEFAULT_CONFIG.models,
    connectors: [],
    testCases: [],
    reporters: [["console"]],
    judge: { provider: "bedrock", model: "claude-sonnet-4" },
    telemetry: {}
  };
}
function clearConfigCache() {
  cachedConfig = null;
  cachedConfigPath = null;
}
function getConfigFileInfo(cwd = process.cwd()) {
  return findConfigFile(cwd);
}
export {
  DEFAULT_SERVER_CONFIG,
  clearConfigCache,
  defineConfig,
  findConfigFile,
  getConfigFileInfo,
  loadConfig,
  loadConfigSync
};
