{"version":3,"sources":["../../../node_modules/.pnpm/tsup@8.5.0_jiti@2.6.1_postcss@8.5.6_tsx@4.20.4_typescript@5.9.2/node_modules/tsup/assets/cjs_shims.js","../src/evals/context/manager.ts","../src/evals/context/global-flags.ts","../src/cli/utils/format-zod-errors.ts","../src/util/zod-internals.ts","../src/util/dot-path.ts","../src/util/deep-partial-schema.ts","../src/validate-flags.ts","../src/otel/utils/to-otel-attribute.ts","../src/otel/withSpanBaggageKey.ts","../src/otel/semconv/eval_proposal.ts","../src/otel/semconv/attributes.ts","../src/schema.ts","../src/otel/startActiveSpan.ts","../package.json","../src/otel/utils/redaction.ts","../src/otel/initAxiomAI.ts","../src/otel/utils/wrapperUtils.ts","../src/util/name-validation-runtime.ts","../src/otel/withSpan.ts","../src/otel/utils/contentSanitizer.ts","../src/otel/completionUtils.ts","../src/util/promptUtils.ts","../src/otel/utils/normalized.ts","../src/util/currentUnixTime.ts","../src/otel/streaming/aggregators.ts","../src/otel/middleware.ts","../src/otel/AxiomWrappedLanguageModelV1.ts","../src/otel/AxiomWrappedLanguageModelV2.ts","../src/otel/AxiomWrappedLanguageModelV3.ts","../src/otel/vercel.ts","../src/otel/index.ts","../src/app-scope.ts","../src/evals/context/storage.ts","../src/config/resolver.ts","../src/util/errors.ts","../src/cli/auth/types.ts","../src/cli/auth/config.ts","../src/cli/auth/oauth.ts","../src/cli/auth/api.ts","../src/cli/auth/callback-server.ts","../src/cli/auth/global-auth.ts","../src/cli/auth/index.ts","../src/config/index.ts","../src/config/loader.ts","../src/evals/instrument.ts","../../../node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js","../../../node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.js","../src/evals/reporter.console-utils.ts","../src/context.ts","../src/cli/utils/eval-context-runner.ts","../src/cli/utils/parse-flag-overrides.ts","../src/cli/utils/glob-utils.ts","../src/cli/commands/eval.command.ts","../src/evals/reporter.ts","../src/evals.ts","../src/evals/eval.ts","../src/evals/git-info.ts","../src/evals/aggregations.ts","../src/evals/eval.service.ts","../src/utils/fetcher.ts","../src/util/traces.ts","../src/util/deep-equal.ts","../src/util/tryCatch.ts","../src/evals/name-validation-runtime.ts","../src/evals/scorer.types.ts","../src/evals/scorer.factory.ts","../src/evals/normalize-score.ts","../src/evals/deprecated.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n  typeof document === 'undefined'\n    ? new URL(`file:${__filename}`).href\n    : (document.currentScript && document.currentScript.src) ||\n      new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { createRequire } from 'node:module';\n\ninterface ContextManager<T = any> {\n  getStore(): T | undefined;\n  run<R>(value: T, fn: () => R): R;\n}\n\nconst CONTEXT_MANAGER_SYMBOL = Symbol.for('axiom.context_manager');\n\nfunction getGlobalContextManager(): ContextManager | undefined {\n  return (globalThis as any)[CONTEXT_MANAGER_SYMBOL];\n}\n\nfunction setGlobalContextManager(manager: ContextManager): void {\n  (globalThis as any)[CONTEXT_MANAGER_SYMBOL] = manager;\n}\n\nconst isNodeJS = typeof process !== 'undefined' && !!process.versions?.node;\n\nfunction getContextManager(): ContextManager {\n  // Check global Symbol registry cache first (shared across VM contexts)\n  const existing = getGlobalContextManager();\n  if (existing) return existing;\n\n  let manager: ContextManager;\n\n  if (isNodeJS) {\n    try {\n      // Resolve AsyncLocalStorage in both ESM and CJS Node contexts without bundler interference\n      let AsyncLocalStorage: any;\n\n      // Use createRequire to obtain a require in ESM\n      const req = createRequire(import.meta.url);\n      try {\n        AsyncLocalStorage = req('node:async_hooks').AsyncLocalStorage;\n      } catch {\n        AsyncLocalStorage = req('async_hooks').AsyncLocalStorage;\n      }\n\n      manager = new AsyncLocalStorage();\n    } catch (error) {\n      // Fallback if AsyncLocalStorage cannot be loaded\n      console.warn('AsyncLocalStorage not available, using fallback context manager:', error);\n      manager = createFallbackManager();\n    }\n  } else {\n    // Browser/CF Workers - simple fallback (no warning needed here)\n    console.warn('AsyncLocalStorage not available, using fallback context manager');\n    manager = createFallbackManager();\n  }\n\n  // Cache using Symbol to share across VM contexts\n  setGlobalContextManager(manager);\n\n  return manager;\n}\n\nfunction createFallbackManager(): ContextManager {\n  let currentContext: any = null;\n  return {\n    getStore: () => currentContext,\n    run: <R>(value: any, fn: () => R): R => {\n      const prev = currentContext;\n      currentContext = value;\n      try {\n        return fn();\n      } finally {\n        currentContext = prev;\n      }\n    },\n  };\n}\n\nexport function createAsyncHook<T>(_name: string) {\n  return {\n    get(): T | undefined {\n      const manager = getContextManager();\n      if (manager.getStore) {\n        return manager.getStore();\n      }\n      return undefined;\n    },\n    run<R>(value: T, fn: () => R): R {\n      const manager = getContextManager();\n      return manager.run(value, fn);\n    },\n  };\n}\n\n/**\n * Reset the context manager singleton for tests.\n * This clears the global cache and forces a new AsyncLocalStorage instance to be created.\n * Useful for test isolation when needed.\n */\nexport function __resetContextManagerForTests(): void {\n  delete (globalThis as any)[CONTEXT_MANAGER_SYMBOL];\n}\n","/**\n * Global flag overrides storage for CLI flag functionality.\n * Uses globalThis for process-wide flag persistence.\n */\n\nconst GLOBAL_OVERRIDES_SYMBOL = Symbol.for('axiom.global_flag_overrides');\n\nfunction getRoot(): Record<string, any> {\n  return (globalThis as any)[GLOBAL_OVERRIDES_SYMBOL] ?? {};\n}\n\nfunction setRoot(val: Record<string, any>): void {\n  (globalThis as any)[GLOBAL_OVERRIDES_SYMBOL] = val;\n}\n\n/**\n * Set global flag overrides (called by CLI) - persists until cleared\n */\nexport function setGlobalFlagOverrides(overrides: Record<string, any>): void {\n  setRoot(overrides);\n}\n\n/**\n * Get global flag overrides (called by flag functions)\n */\nexport function getGlobalFlagOverrides(): Record<string, any> {\n  return getRoot();\n}\n\n/**\n * Clear global flag overrides (for testing)\n */\nexport function clearGlobalFlagOverrides(): void {\n  setRoot({});\n}\n","import { type ZodError } from 'zod';\nimport type { ZodIssue } from 'zod/v3';\nimport type { $ZodIssue } from 'zod/v4/core';\n\n/**\n * Format ZodError issues into user-friendly CLI error messages\n */\nexport function formatZodErrors(error: ZodError): string {\n  const issues = error.issues;\n  const messages: string[] = [];\n\n  for (const issue of issues) {\n    const path = issue.path.join('.');\n    const message = formatIssueMessage(issue, path);\n    messages.push(`  • ${message}`);\n  }\n\n  return messages.join('\\n');\n}\n\nfunction formatIssueMessage(issue: any, path: string): string {\n  switch (issue.code) {\n    case 'invalid_type':\n      return `flag '${path}' expected ${issue.expected}, got ${JSON.stringify(issue.received)} (${typeof issue.received})`;\n\n    case 'too_small':\n      if (issue.type === 'number' || issue.origin === 'number') {\n        return `flag '${path}' must be >= ${issue.minimum}, got ${issue.received}`;\n      }\n      return `flag '${path}' is too small: ${issue.message}`;\n\n    case 'too_big':\n      if (issue.type === 'number') {\n        return `flag '${path}' must be <= ${issue.maximum}, got ${issue.received}`;\n      }\n      return `flag '${path}' is too big: ${issue.message}`;\n\n    case 'invalid_enum_value':\n      const options = issue.options.map((opt: any) => `\"${opt}\"`).join(', ');\n      return `flag '${path}' must be one of: ${options}, got \"${issue.received}\"`;\n\n    case 'invalid_value':\n      // Handle enum validation errors\n      if (issue.values && Array.isArray(issue.values)) {\n        const values = issue.values.map((val: any) => `\"${val}\"`).join(', ');\n        return `flag '${path}' must be one of: ${values}`;\n      }\n      return `flag '${path}': ${issue.message}`;\n\n    case 'unrecognized_keys':\n      // Handle unrecognized keys properly, especially when path is empty\n      const keys = issue.keys || [];\n      if (keys.length === 1) {\n        return `unrecognized flag '${keys[0]}'`;\n      } else if (keys.length > 1) {\n        const keysList = keys.map((key: string) => `'${key}'`).join(', ');\n        return `unrecognized flags ${keysList}`;\n      }\n      return `unrecognized keys in flags`;\n\n    case 'custom':\n      return `flag '${path}': ${issue.message}`;\n\n    default:\n      return `flag '${path}': ${issue.message}`;\n  }\n}\n\n/**\n * Create helpful examples for CLI usage based on validation errors\n */\nexport function generateFlagExamples(error: ZodError): string[] {\n  const examples: string[] = [];\n\n  for (const issue of error.issues) {\n    const path = issue.path.join('.');\n    const example = generateExampleForIssue(issue, path);\n    if (example && !examples.includes(example)) {\n      examples.push(example);\n    }\n  }\n\n  return examples.slice(0, 3); // Limit to 3 examples\n}\n\nfunction generateExampleForIssue(issue: ZodIssue | $ZodIssue, path: string): string | null {\n  switch (issue.code) {\n    case 'invalid_type':\n      if (issue.expected === 'number') {\n        return `--flag.${path}=0.7`;\n      }\n      if (issue.expected === 'boolean') {\n        return `--flag.${path}=true`;\n      }\n      if (issue.expected === 'string') {\n        return `--flag.${path}=\"value\"`;\n      }\n      break;\n\n    case 'too_small':\n      if (typeof issue.minimum === 'number' || typeof issue.minimum === 'bigint') {\n        return `--flag.${path}=${issue.minimum}`;\n      }\n      break;\n\n    case 'too_big':\n      if (typeof issue.maximum === 'number' || typeof issue.maximum === 'bigint') {\n        return `--flag.${path}=${issue.maximum}`;\n      }\n      break;\n\n    case 'invalid_enum_value':\n      if (issue.options.length > 0) {\n        return `--flag.${path}=${issue.options[0]}`;\n      }\n      break;\n\n    case 'invalid_value':\n      if (issue.values && Array.isArray(issue.values) && issue.values.length > 0) {\n        return `--flag.${path}=${String(issue.values[0])}`;\n      }\n      break;\n  }\n\n  return null;\n}\n","import type { ZodObject, ZodType } from 'zod';\n\n/**\n * Detect if a schema is from Zod v4.\n * v4 schemas have `_zod`, v3 schemas only have `_def`.\n */\nexport function isZodV4Schema(schema: unknown): boolean {\n  if (!schema || typeof schema !== 'object') return false;\n  const s = schema as Record<string, unknown>;\n  return '_zod' in s;\n}\n\n/**\n * Assert that a schema is from Zod v4, throwing a helpful error if it isn't.\n */\nexport function assertZodV4(schema: unknown, context: string): void {\n  if (!isZodV4Schema(schema)) {\n    throw new Error(\n      `[AxiomAI] Zod v4 schemas are required (detected in ${context}). Found unsupported Zod version.`,\n    );\n  }\n}\n\n/** Normalized schema kinds we care about */\nexport type ZodKind =\n  | 'object'\n  | 'optional'\n  | 'default'\n  | 'nullable'\n  | 'readonly'\n  | 'prefault'\n  | 'nonoptional'\n  | 'catch'\n  | 'array'\n  | 'record'\n  | 'union'\n  | 'discriminatedunion'\n  | 'other';\n\n/** Minimal internal def shape we access (Zod v4) */\ninterface ZodInternalDef {\n  type?: unknown;\n  innerType?: ZodType<unknown>;\n  element?: ZodType<unknown>;\n  defaultValue?: unknown;\n  shape?: Record<string, ZodType<unknown>>;\n  valueType?: ZodType<unknown>;\n}\n\n/**\n * Get the internal def object from a Zod v4 schema.\n */\nexport function getDef(schema: unknown): ZodInternalDef | undefined {\n  if (!schema || typeof schema !== 'object') return undefined;\n\n  const s = schema as Record<string, unknown>;\n\n  if (s._zod && typeof s._zod === 'object') {\n    const zod = s._zod as Record<string, unknown>;\n    if (zod.def && typeof zod.def === 'object') {\n      return zod.def as ZodInternalDef;\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Get the raw type string from a def (Zod v4).\n */\nfunction getDefRawType(def: ZodInternalDef | undefined): string | undefined {\n  if (!def) return undefined;\n  const raw = def.type;\n  if (raw == null) return undefined;\n  return typeof raw === 'string' ? raw : String(raw);\n}\n\nconst KNOWN_KINDS = new Set<ZodKind>([\n  'object',\n  'optional',\n  'default',\n  'nullable',\n  'readonly',\n  'prefault',\n  'nonoptional',\n  'catch',\n  'array',\n  'record',\n  'union',\n  'discriminatedunion',\n]);\n\n/**\n * Get the normalized ZodKind from a schema or def (Zod v4).\n */\nexport function getKind(schemaOrDef: unknown): ZodKind | undefined {\n  // If it looks like a def already (has type), use it directly\n  const def =\n    schemaOrDef && typeof schemaOrDef === 'object' && 'type' in schemaOrDef\n      ? (schemaOrDef as ZodInternalDef)\n      : getDef(schemaOrDef);\n\n  const raw = getDefRawType(def);\n  if (!raw) return undefined;\n\n  const normalized = raw.toLowerCase();\n  return KNOWN_KINDS.has(normalized as ZodKind) ? (normalized as ZodKind) : 'other';\n}\n\n/**\n * Check if a schema is an object schema (has shape).\n */\nexport function isObjectSchema(schema: unknown): schema is ZodObject<Record<string, ZodType>> {\n  if (!schema || typeof schema !== 'object') return false;\n\n  if ('shape' in schema && typeof (schema as Record<string, unknown>).shape === 'object') {\n    return true;\n  }\n\n  return getKind(schema) === 'object';\n}\n\n/**\n * Get the innerType from wrapper schemas (optional, nullable, default).\n */\nexport function getInnerType(schema: unknown): ZodType<unknown> | undefined {\n  const def = getDef(schema);\n  return def?.innerType;\n}\n\n/**\n * Get the element type from array schemas.\n */\nexport function getArrayElement(schema: unknown): ZodType<unknown> | undefined {\n  const def = getDef(schema);\n  return def?.element;\n}\n\n/**\n * Get the shape from an object schema (Zod v4).\n */\nexport function getShape(schema: unknown): Record<string, ZodType<unknown>> | undefined {\n  if (!schema || typeof schema !== 'object') return undefined;\n\n  // Direct shape property (Zod v4)\n  const s = schema as Record<string, unknown>;\n  if (s.shape && typeof s.shape === 'object') {\n    return s.shape as Record<string, ZodType<unknown>>;\n  }\n\n  return undefined;\n}\n\n/**\n * Get the default value from a schema wrapped in ZodDefault.\n */\nexport function getDefaultValue(schema: unknown): unknown {\n  const def = getDef(schema);\n  return def?.defaultValue;\n}\n\nconst TRANSPARENT_WRAPPERS = [\n  'optional',\n  'nullable',\n  'default',\n  'readonly',\n  'prefault',\n  'nonoptional',\n  'catch', // transparent for schema structure, but alters error behavior\n];\n\n/**\n * Unwrap transparent wrappers (optional, nullable, default) to get the core schema.\n * Useful when you need to check the underlying type.\n */\nexport function unwrapTransparent(schema: ZodType<unknown>): ZodType<unknown> {\n  let current: unknown = schema;\n\n  for (let i = 0; i < 10; i++) {\n    const kind = getKind(current);\n    if (!kind) break;\n\n    if (TRANSPARENT_WRAPPERS.includes(kind)) {\n      const inner = getInnerType(current);\n      if (!inner) break;\n      current = inner;\n      continue;\n    }\n    break;\n  }\n\n  return current as ZodType<unknown>;\n}\n","import { type ZodObject, type ZodSchema, type ZodType, z } from 'zod';\nimport { getDef, getShape, isObjectSchema, unwrapTransparent } from './zod-internals';\n\n/**\n * Parse a dot notation path into segments.\n * @param path - Dot notation path like \"ui.theme\" or \"api.timeout\"\n * @returns Array of path segments\n */\nexport function parsePath(path: string): string[] {\n  return path.split('.');\n}\n\n/**\n * Transform dot notation object to nested object structure.\n * Example: {\"ui.theme\": \"dark\", \"config.name\": \"test\"}\n * -> {ui: {theme: \"dark\"}, config: {name: \"test\"}}\n */\nexport function dotNotationToNested(\n  dotNotationObject: Record<string, unknown>,\n): Record<string, unknown> {\n  const result: Record<string, unknown> = {};\n\n  for (const [dotPath, value] of Object.entries(dotNotationObject)) {\n    const segments = parsePath(dotPath);\n    let current: Record<string, unknown> = result;\n\n    for (let i = 0; i < segments.length; i++) {\n      const segment = segments[i];\n\n      if (i === segments.length - 1) {\n        // Last segment - set the value\n        current[segment] = value;\n      } else {\n        // Intermediate segment - ensure object exists\n        if (!(segment in current) || typeof current[segment] !== 'object') {\n          current[segment] = {};\n        }\n        current = current[segment] as Record<string, unknown>;\n      }\n    }\n  }\n\n  return result;\n}\n\n/**\n * Flatten nested object to dot notation.\n * Example: {ui: {theme: \"dark\"}, config: {name: \"test\"}}\n * -> {\"ui.theme\": \"dark\", \"config.name\": \"test\"}\n */\nexport function flattenObject(obj: Record<string, unknown>, prefix = ''): Record<string, unknown> {\n  const result: Record<string, unknown> = {};\n\n  for (const [key, value] of Object.entries(obj)) {\n    const newKey = prefix ? `${prefix}.${key}` : key;\n\n    if (value && typeof value === 'object' && !Array.isArray(value)) {\n      Object.assign(result, flattenObject(value as Record<string, unknown>, newKey));\n    } else {\n      result[newKey] = value;\n    }\n  }\n\n  return result;\n}\n\n/**\n * Check if a dot notation path exists in the schema.\n */\nexport function isValidPath(\n  schema: ZodObject<Record<string, ZodType>>,\n  segments: string[],\n): boolean {\n  let currentSchema: ZodType = schema;\n\n  for (let i = 0; i < segments.length; i++) {\n    const segment = segments[i];\n    const shape = getShape(currentSchema);\n\n    if (!shape || !(segment in shape)) {\n      return false;\n    }\n\n    if (i < segments.length - 1) {\n      // Not the last segment, should be a ZodObject\n      const nextSchema = shape[segment];\n\n      // Handle wrapped schemas (ZodDefault, ZodOptional, etc.)\n      const unwrappedSchema = unwrapTransparent(nextSchema);\n\n      if (!isObjectSchema(unwrappedSchema)) {\n        return false;\n      }\n\n      currentSchema = unwrappedSchema;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Get value at a specific path in a nested object.\n */\nexport function getValueAtPath(obj: unknown, segments: string[]): unknown {\n  let current = obj;\n  for (const segment of segments) {\n    if (current == null || typeof current !== 'object' || !(segment in current)) {\n      return undefined;\n    }\n    current = (current as Record<string, unknown>)[segment];\n  }\n  return current;\n}\n\n/**\n * Helper function to traverse schema object to find the field schema at a specific path.\n */\nexport function findSchemaAtPath(\n  rootSchema: ZodObject<Record<string, ZodType>> | undefined,\n  segments: string[],\n): ZodSchema | undefined {\n  if (!rootSchema || segments.length === 0) return undefined;\n\n  let current: ZodType = rootSchema;\n\n  // ZodObject root - start with the shape\n  if (segments.length > 0) {\n    const rootShape = getShape(current);\n    if (!rootShape || !(segments[0] in rootShape)) {\n      return undefined;\n    }\n    current = rootShape[segments[0]];\n\n    // Continue with remaining segments starting from index 1\n    for (let i = 1; i < segments.length; i++) {\n      const segment = segments[i];\n      const def = getDef(current);\n      if (!def) {\n        return undefined;\n      }\n\n      // Unwrap transparent wrappers (ZodDefault, ZodOptional, ZodNullable, etc.)\n      current = unwrapTransparent(current);\n      if (!isObjectSchema(current)) {\n        return undefined;\n      }\n      const shape = getShape(current);\n      if (!shape) {\n        return undefined;\n      }\n      const nextSchema = shape[segment];\n      if (!nextSchema) {\n        return undefined;\n      }\n      current = nextSchema;\n    }\n    return current as ZodSchema;\n  }\n\n  return current as ZodSchema;\n}\n\n/**\n * Build a schema that validates only a specific path within a larger schema structure.\n * This allows validation of partial nested objects where only the target field is required.\n *\n * For example, for path \"ui.theme.colors.primary\":\n * - Creates: z.object({ ui: z.object({ theme: z.object({ colors: z.object({ primary: leafSchema }).partial() }).partial() }).partial() }).strict()\n * - This allows recording just { ui: { theme: { colors: { primary: value } } } } without requiring siblings\n *\n * @param rootSchema - The root ZodObject schema\n * @param segments - Path segments (e.g. ['ui', 'theme', 'colors', 'primary'])\n * @returns A schema that validates the specific path with partial validation for siblings\n */\nexport function buildSchemaForPath(\n  rootSchema: ZodObject<Record<string, ZodType>>,\n  segments: string[],\n): ZodSchema {\n  const pathKey = segments.join('.');\n\n  // Find the leaf schema for the target field\n  const leafSchema = findSchemaAtPath(rootSchema, segments);\n  if (!leafSchema) {\n    throw new Error(`Cannot find schema for path: ${pathKey}`);\n  }\n\n  // Build the schema from leaf back to root, making siblings optional at each level\n  let currentSchema: ZodSchema = leafSchema;\n\n  // Work backwards through the segments\n  for (let i = segments.length - 1; i >= 0; i--) {\n    const segment = segments[i];\n\n    // Create an object schema with just this segment\n    const objectSchema = z.object({ [segment]: currentSchema });\n\n    // Make it partial (so siblings aren't required) and strict (so unknown keys are rejected)\n    currentSchema = objectSchema.partial().strict();\n  }\n\n  return currentSchema;\n}\n","import { type ZodObject, type ZodType, z } from 'zod';\nimport {\n  getKind,\n  getInnerType,\n  getArrayElement,\n  isObjectSchema,\n  getDefaultValue,\n} from './zod-internals';\n\n/**\n * Recursively makes all properties of a ZodObject schema optional (deep partial).\n * This is needed because Zod 4 removed the deprecated `.deepPartial()` method.\n *\n * When validating CLI flag overrides, we only want to validate the flags that are\n * provided, not require all nested objects to be fully specified.\n */\nexport function makeDeepPartial(schema: ZodObject<Record<string, ZodType>>): ZodType {\n  const shape = schema.shape;\n  const newShape: Record<string, ZodType> = {};\n\n  for (const [key, value] of Object.entries(shape)) {\n    newShape[key] = makeDeepPartialField(value as ZodType);\n  }\n\n  return z.object(newShape);\n}\n\n/**\n * Apply deep partial semantics to a single field of an object shape.\n */\nfunction makeDeepPartialField(fieldSchema: ZodType): ZodType {\n  const kind = getKind(fieldSchema);\n\n  // Plain object field - recurse and make optional\n  if (isObjectSchema(fieldSchema)) {\n    const partialObject = makeDeepPartial(fieldSchema as ZodObject<Record<string, ZodType>>);\n    return partialObject.optional();\n  }\n\n  // Optional wrapper - check if inner type is an object\n  if (kind === 'optional') {\n    const inner = getInnerType(fieldSchema);\n    if (inner && isObjectSchema(inner)) {\n      const partialInner = makeDeepPartial(inner as ZodObject<Record<string, ZodType>>);\n      return partialInner.optional();\n    }\n    // Already optional and not an object - preserve as-is\n    return fieldSchema;\n  }\n\n  // Nullable wrapper - check if inner type is an object\n  if (kind === 'nullable') {\n    const inner = getInnerType(fieldSchema);\n    if (inner && isObjectSchema(inner)) {\n      const partialInner = makeDeepPartial(inner as ZodObject<Record<string, ZodType>>);\n      return partialInner.nullable().optional();\n    }\n    // Nullable non-object - just make optional\n    return fieldSchema.optional();\n  }\n\n  // Default wrapper - check if inner type is an object\n  if (kind === 'default') {\n    const inner = getInnerType(fieldSchema);\n    const defaultValue = getDefaultValue(fieldSchema);\n\n    if (inner && isObjectSchema(inner)) {\n      const partialInner = makeDeepPartial(inner as ZodObject<Record<string, ZodType>>);\n      // Reapply the default on the deep-partialled object, preserving function references for lazy defaults\n      return (partialInner as ZodObject<Record<string, ZodType>>).default(defaultValue as any);\n    }\n    // Non-object with default - make optional to allow partial validation\n    return fieldSchema.optional();\n  }\n\n  // Array wrapper - deep partial the element type if it's an object\n  if (kind === 'array') {\n    const element = getArrayElement(fieldSchema);\n    if (element && isObjectSchema(element)) {\n      const partialElement = makeDeepPartial(element as ZodObject<Record<string, ZodType>>);\n      return z.array(partialElement).optional();\n    }\n    // Array of non-objects - just make optional\n    return fieldSchema.optional();\n  }\n\n  // All other field types - just make optional\n  return fieldSchema.optional();\n}\n","import { type ZodObject } from 'zod';\nimport { getGlobalFlagOverrides } from './evals/context/global-flags';\nimport { formatZodErrors, generateFlagExamples } from './cli/utils/format-zod-errors';\nimport { dotNotationToNested, isValidPath, parsePath } from './util/dot-path';\nimport { makeDeepPartial } from './util/deep-partial-schema';\nimport { assertZodV4 } from './util/zod-internals';\n\n/**\n * Validate CLI flag overrides against a schema early in eval execution.\n * Call this at the top of your eval file to fail fast on invalid flags.\n *\n * @param flagSchema - Zod schema to validate CLI flags against\n * @throws Error with helpful message if validation fails\n */\nexport function validateCliFlags(flagSchema: ZodObject<any>): void {\n  assertZodV4(flagSchema, 'flagSchema');\n  const globalOverrides = getGlobalFlagOverrides();\n\n  if (Object.keys(globalOverrides).length === 0) {\n    // No CLI flags provided, nothing to validate\n    return;\n  }\n\n  validateFlags(flagSchema, globalOverrides);\n}\n\nfunction validateFlags(flagSchema: ZodObject<any>, globalOverrides: Record<string, any>): void {\n  // First pass: check all paths exist in schema\n  for (const [dotPath, _value] of Object.entries(globalOverrides)) {\n    const segments = parsePath(dotPath);\n    if (!isValidPath(flagSchema, segments)) {\n      console.error('❌ Invalid CLI flags:');\n      console.error(`  • flag '${dotPath}': Invalid flag path`);\n      console.error('\\n🔧 Fix your CLI flags and try again.\\n');\n      process.exit(1);\n    }\n  }\n\n  // Second pass: validate values using nested object approach with deep partial\n  // This allows providing only some flags without requiring all nested objects\n  const nestedObject = dotNotationToNested(globalOverrides);\n  const deepPartialSchema = makeDeepPartial(flagSchema);\n  const result = deepPartialSchema.safeParse(nestedObject);\n\n  if (!result.success) {\n    console.error('❌ Invalid CLI flags:');\n    console.error(formatZodErrors(result.error));\n\n    const examples = generateFlagExamples(result.error);\n    if (examples.length > 0) {\n      console.error('\\n💡 Valid examples:');\n      examples.forEach((example) => console.error(`  ${example}`));\n    }\n\n    console.error('\\n🔧 Fix your CLI flags and try again.\\n');\n    process.exit(1);\n  }\n}\n","import { type AttributeValue } from '@opentelemetry/api';\n\nfunction toHomogeneousArray(input: unknown[]): AttributeValue | undefined {\n  if (input.length === 0) return undefined;\n\n  const converted: (string | number | boolean)[] = [];\n  const types = new Set<string>();\n\n  for (const item of input) {\n    const converted_item = toOtelPrimitive(item);\n    if (converted_item !== undefined) {\n      converted.push(converted_item);\n      types.add(typeof converted_item);\n    }\n  }\n\n  if (converted.length === 0) return undefined;\n\n  if (types.size > 1) {\n    return converted.map((item) => String(item)) as AttributeValue;\n  }\n\n  return converted as AttributeValue;\n}\n\nfunction toOtelPrimitive(v: unknown): string | number | boolean | undefined {\n  switch (typeof v) {\n    case 'string':\n      return v;\n    case 'number':\n      return Number.isFinite(v) ? v : undefined;\n    case 'boolean':\n      return v;\n    case 'bigint':\n      if (v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) {\n        return Number(v);\n      }\n      return v.toString();\n    case 'function':\n    case 'symbol':\n    case 'undefined':\n      return undefined;\n    case 'object':\n      if (v === null) return undefined;\n      if (v instanceof Date) return v.toISOString();\n      if (v instanceof Error) return v.message;\n      // fallback: stringify object-ish values\n      return safeStringify(v);\n  }\n}\n\nfunction safeStringify(obj: unknown): string | undefined {\n  try {\n    // Convert BigInt -> Number inside objects so JSON.stringify won't throw.\n    // Functions/undefined are dropped by JSON rules.\n    const s = JSON.stringify(obj, (_k, val) =>\n      typeof val === 'bigint' ? Number(val) : val instanceof Date ? val.toISOString() : val,\n    );\n    // Avoid empty/meaningless \"{}\" for Map/Set—stringify those explicitly\n    if (s === '{}') {\n      if (obj instanceof Map) {\n        return JSON.stringify(Object.fromEntries(obj));\n      }\n      if (obj instanceof Set) {\n        return JSON.stringify(Array.from(obj));\n      }\n    }\n    return s ?? undefined;\n  } catch {\n    // As a last resort, use toString() if present\n    try {\n      const t = (obj as any)?.toString?.();\n      return typeof t === 'string' ? t : undefined;\n    } catch {\n      return undefined;\n    }\n  }\n}\n\nexport function toOtelAttribute(input: unknown): AttributeValue | undefined {\n  // primitives fast-path\n  switch (typeof input) {\n    case 'string':\n      return input;\n    case 'number':\n      return Number.isFinite(input) ? input : undefined;\n    case 'boolean':\n      return input;\n    case 'bigint':\n      if (input >= Number.MIN_SAFE_INTEGER && input <= Number.MAX_SAFE_INTEGER) {\n        return Number(input);\n      }\n      return input.toString();\n    case 'function':\n    case 'symbol':\n    case 'undefined':\n      return undefined;\n  }\n\n  // arrays -> homogeneous array of primitives\n  if (Array.isArray(input)) {\n    return toHomogeneousArray(input);\n  }\n\n  // date -> ISO string\n  if (input instanceof Date) {\n    return input.toISOString();\n  }\n\n  // null / objects -> JSON string\n  if (input === null) return undefined;\n  return safeStringify(input);\n}\n","/**\n * We need a way to know that we're inside `withSpan`\n * Because we don't own `generateText` and similar functions,\n * we use OTel Baggage to propagate this information. Another\n * consideration might be to use AsyncLocalStorage in Node and\n * some kind of KV in workerd.\n */\nexport const WITHSPAN_BAGGAGE_KEY = '__withspan_gen_ai_call';\nexport const WITHSPAN_REDACTION_POLICY_KEY = '__withspan_redaction_policy';\n","// experiment\nexport const ATTR_EVAL_ID = 'eval.id' as const;\nexport const ATTR_EVAL_NAME = 'eval.name' as const;\nexport const ATTR_EVAL_VERSION = 'eval.version' as const;\nexport const ATTR_EVAL_TYPE = 'eval.type' as const;\nexport const ATTR_EVAL_TAGS = 'eval.tags' as const;\nexport const ATTR_EVAL_BASELINE_ID = 'eval.baseline.id' as const;\nexport const ATTR_EVAL_BASELINE_NAME = 'eval.baseline.name' as const;\nexport const ATTR_EVAL_BASELINE_VERSION = 'eval.baseline.version' as const;\nexport const ATTR_EVAL_METADATA = 'eval.metadata' as const;\nexport const ATTR_EVAL_TRIALS = 'eval.trials' as const;\n// capability\nexport const ATTR_EVAL_CAPABILITY_NAME = 'eval.capability.name' as const;\nexport const ATTR_EVAL_STEP_NAME = 'eval.step.name' as const;\n// collection\nexport const ATTR_EVAL_COLLECTION_ID = 'eval.collection.id' as const;\nexport const ATTR_EVAL_COLLECTION_SIZE = 'eval.collection.size' as const;\nexport const ATTR_EVAL_COLLECTION_NAME = 'eval.collection.name' as const;\n// config\nexport const ATTR_EVAL_CONFIG_FLAGS = 'eval.config.flags' as const;\n// case\nexport const ATTR_EVAL_CASE_INDEX = 'eval.case.index' as const;\nexport const ATTR_EVAL_CASE_INPUT = 'eval.case.input' as const;\nexport const ATTR_EVAL_CASE_OUTPUT = 'eval.case.output' as const;\nexport const ATTR_EVAL_CASE_EXPECTED = 'eval.case.expected' as const;\nexport const ATTR_EVAL_CASE_SCORES = 'eval.case.scores' as const;\nexport const ATTR_EVAL_CASE_METADATA = 'eval.case.metadata' as const;\nexport const ATTR_EVAL_CASE_TRIALS = 'eval.case.trials' as const;\n// trial\nexport const ATTR_EVAL_TRIAL_INDEX = 'eval.trial.index' as const;\nexport const ATTR_EVAL_TRIAL_ERROR = 'eval.trial.error' as const;\n// task\nexport const ATTR_EVAL_TASK_OUTPUT = 'eval.task.output' as const;\nexport const ATTR_EVAL_TASK_NAME = 'eval.task.name' as const;\nexport const ATTR_EVAL_TASK_TYPE = 'eval.task.type' as const;\n// run\nexport const ATTR_EVAL_RUN_ID = 'eval.run.id' as const;\n// score\nexport const ATTR_EVAL_SCORE_NAME = 'eval.score.name' as const;\nexport const ATTR_EVAL_SCORE_VALUE = 'eval.score.value' as const;\nexport const ATTR_EVAL_SCORE_THRESHOLD = 'eval.score.threshold' as const;\nexport const ATTR_EVAL_SCORE_PASSED = 'eval.score.passed' as const;\nexport const ATTR_EVAL_SCORE_IS_BOOLEAN = 'eval.score.is_boolean' as const;\nexport const ATTR_EVAL_SCORE_SCORER = 'eval.score.scorer' as const;\nexport const ATTR_EVAL_SCORE_METADATA = 'eval.score.metadata' as const;\nexport const ATTR_EVAL_SCORE_AGGREGATION = 'eval.score.aggregation' as const;\nexport const ATTR_EVAL_SCORE_TRIALS = 'eval.score.trials' as const;\n// online\nexport const ATTR_EVAL_ONLINE_SCORERS_TOTAL = 'eval.online.scorers.total' as const;\nexport const ATTR_EVAL_ONLINE_SCORERS_RAN = 'eval.online.scorers.ran' as const;\nexport const ATTR_EVAL_ONLINE_SCORERS_SAMPLED_OUT = 'eval.online.scorers.sampled_out' as const;\nexport const ATTR_EVAL_ONLINE_SCORERS_FAILED = 'eval.online.scorers.failed' as const;\n// user\nexport const ATTR_EVAL_USER_NAME = 'eval.user.name';\nexport const ATTR_EVAL_USER_EMAIL = 'eval.user.email';\n","import {\n  ATTR_ERROR_TYPE,\n  ATTR_HTTP_RESPONSE_STATUS_CODE,\n} from '@opentelemetry/semantic-conventions';\n\nimport {\n  ATTR_EVAL_CASE_INDEX,\n  ATTR_EVAL_CASE_EXPECTED,\n  ATTR_EVAL_CASE_INPUT,\n  ATTR_EVAL_CASE_OUTPUT,\n  ATTR_EVAL_CASE_METADATA,\n  ATTR_EVAL_CASE_SCORES,\n  ATTR_EVAL_CASE_TRIALS,\n  ATTR_EVAL_SCORE_PASSED,\n  ATTR_EVAL_SCORE_IS_BOOLEAN,\n  ATTR_EVAL_SCORE_VALUE,\n  ATTR_EVAL_SCORE_NAME,\n  ATTR_EVAL_SCORE_THRESHOLD,\n  ATTR_EVAL_SCORE_METADATA,\n  ATTR_EVAL_SCORE_AGGREGATION,\n  ATTR_EVAL_SCORE_TRIALS,\n  ATTR_EVAL_TASK_TYPE,\n  ATTR_EVAL_TASK_NAME,\n  ATTR_EVAL_TASK_OUTPUT,\n  ATTR_EVAL_COLLECTION_NAME,\n  ATTR_EVAL_COLLECTION_SIZE,\n  ATTR_EVAL_ID,\n  ATTR_EVAL_BASELINE_ID,\n  ATTR_EVAL_BASELINE_NAME,\n  ATTR_EVAL_BASELINE_VERSION,\n  ATTR_EVAL_NAME,\n  ATTR_EVAL_TAGS,\n  ATTR_EVAL_TYPE,\n  ATTR_EVAL_TRIALS,\n  ATTR_EVAL_TRIAL_INDEX,\n  ATTR_EVAL_TRIAL_ERROR,\n  ATTR_EVAL_COLLECTION_ID,\n  ATTR_EVAL_USER_NAME,\n  ATTR_EVAL_USER_EMAIL,\n  ATTR_EVAL_VERSION,\n  ATTR_EVAL_RUN_ID,\n  ATTR_EVAL_METADATA,\n  ATTR_EVAL_CONFIG_FLAGS,\n  ATTR_EVAL_CAPABILITY_NAME,\n  ATTR_EVAL_STEP_NAME,\n  ATTR_EVAL_ONLINE_SCORERS_TOTAL,\n  ATTR_EVAL_ONLINE_SCORERS_RAN,\n  ATTR_EVAL_ONLINE_SCORERS_SAMPLED_OUT,\n  ATTR_EVAL_ONLINE_SCORERS_FAILED,\n} from './eval_proposal';\n\nimport {\n  ATTR_ERROR_MESSAGE,\n  ATTR_GEN_AI_AGENT_DESCRIPTION,\n  ATTR_GEN_AI_AGENT_ID,\n  ATTR_GEN_AI_AGENT_NAME,\n  ATTR_GEN_AI_CONVERSATION_ID,\n  ATTR_GEN_AI_INPUT_MESSAGES,\n  ATTR_GEN_AI_OPERATION_NAME,\n  ATTR_GEN_AI_OUTPUT_MESSAGES,\n  ATTR_GEN_AI_OUTPUT_TYPE,\n  ATTR_GEN_AI_PROVIDER_NAME,\n  ATTR_GEN_AI_REQUEST_CHOICE_COUNT,\n  ATTR_GEN_AI_REQUEST_ENCODING_FORMATS,\n  ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY,\n  ATTR_GEN_AI_REQUEST_MAX_TOKENS,\n  ATTR_GEN_AI_REQUEST_MODEL,\n  ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY,\n  ATTR_GEN_AI_REQUEST_SEED,\n  ATTR_GEN_AI_REQUEST_STOP_SEQUENCES,\n  ATTR_GEN_AI_REQUEST_TEMPERATURE,\n  ATTR_GEN_AI_REQUEST_TOP_K,\n  ATTR_GEN_AI_REQUEST_TOP_P,\n  ATTR_GEN_AI_RESPONSE_FINISH_REASONS,\n  ATTR_GEN_AI_RESPONSE_ID,\n  ATTR_GEN_AI_RESPONSE_MODEL,\n  ATTR_GEN_AI_TOOL_CALL_ID,\n  ATTR_GEN_AI_TOOL_DESCRIPTION,\n  ATTR_GEN_AI_TOOL_NAME,\n  ATTR_GEN_AI_TOOL_TYPE,\n  ATTR_GEN_AI_USAGE_INPUT_TOKENS,\n  ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,\n  GEN_AI_OPERATION_NAME_VALUE_CHAT,\n  GEN_AI_OPERATION_NAME_VALUE_CREATE_AGENT,\n  GEN_AI_OPERATION_NAME_VALUE_EMBEDDINGS,\n  GEN_AI_OPERATION_NAME_VALUE_EXECUTE_TOOL,\n  GEN_AI_OPERATION_NAME_VALUE_GENERATE_CONTENT,\n  GEN_AI_OPERATION_NAME_VALUE_INVOKE_AGENT,\n  GEN_AI_OUTPUT_TYPE_VALUE_IMAGE,\n  GEN_AI_OUTPUT_TYPE_VALUE_JSON,\n  GEN_AI_OUTPUT_TYPE_VALUE_SPEECH,\n  GEN_AI_OUTPUT_TYPE_VALUE_TEXT,\n  GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,\n  GEN_AI_PROVIDER_NAME_VALUE_AWS_BEDROCK,\n  GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_INFERENCE,\n  GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_OPENAI,\n  GEN_AI_PROVIDER_NAME_VALUE_COHERE,\n  GEN_AI_PROVIDER_NAME_VALUE_DEEPSEEK,\n  GEN_AI_PROVIDER_NAME_VALUE_GCP_GEMINI,\n  GEN_AI_PROVIDER_NAME_VALUE_GCP_GEN_AI,\n  GEN_AI_PROVIDER_NAME_VALUE_GCP_VERTEX_AI,\n  GEN_AI_PROVIDER_NAME_VALUE_GROQ,\n  GEN_AI_PROVIDER_NAME_VALUE_IBM_WATSONX_AI,\n  GEN_AI_PROVIDER_NAME_VALUE_MISTRAL_AI,\n  GEN_AI_PROVIDER_NAME_VALUE_OPENAI,\n  GEN_AI_PROVIDER_NAME_VALUE_PERPLEXITY,\n  GEN_AI_PROVIDER_NAME_VALUE_X_AI,\n} from '@opentelemetry/semantic-conventions/incubating';\n\n/**\n * PROPRIETARY ATTRIBUTES (o11y)\n *\n * @see: https://axiom.co/docs/ai-engineering/semantic-conventions\n */\n\nconst ATTR_AXIOM_GEN_AI_SCHEMA_URL = 'axiom.gen_ai.schema_url';\nconst ATTR_AXIOM_GEN_AI_SDK_NAME = 'axiom.gen_ai.sdk.name';\nconst ATTR_AXIOM_GEN_AI_SDK_VERSION = 'axiom.gen_ai.sdk.version';\nconst ATTR_GEN_AI_CAPABILITY_NAME = 'gen_ai.capability.name';\nconst ATTR_GEN_AI_STEP_NAME = 'gen_ai.step.name';\nconst ATTR_GEN_AI_TOOL_ARGUMENTS = 'gen_ai.tool.arguments'; // deprecated by OTel\nconst ATTR_GEN_AI_TOOL_MESSAGE = 'gen_ai.tool.message'; // deprecated by OTel\n\nconst GEN_AI_PROVIDER_NAME_VALUE_ASSEMBLYAI = 'assemblyai';\nconst GEN_AI_PROVIDER_NAME_VALUE_CEREBRAS = 'cerebras';\nconst GEN_AI_PROVIDER_NAME_VALUE_DEEPGRAM = 'deepgram';\nconst GEN_AI_PROVIDER_NAME_VALUE_DEEPINFRA = 'deepinfra';\nconst GEN_AI_PROVIDER_NAME_VALUE_ELEVENLABS = 'elevenlabs';\nconst GEN_AI_PROVIDER_NAME_VALUE_FAL = 'fal';\nconst GEN_AI_PROVIDER_NAME_VALUE_FIREWORKS = 'fireworks';\nconst GEN_AI_PROVIDER_NAME_VALUE_GLADIA = 'gladia';\nconst GEN_AI_PROVIDER_NAME_VALUE_HUME = 'hume';\nconst GEN_AI_PROVIDER_NAME_VALUE_LMNT = 'lmnt';\nconst GEN_AI_PROVIDER_NAME_VALUE_LUMA = 'luma';\nconst GEN_AI_PROVIDER_NAME_VALUE_REPLICATE = 'replicate';\nconst GEN_AI_PROVIDER_NAME_VALUE_REVAI = 'revai';\nconst GEN_AI_PROVIDER_NAME_VALUE_TOGETHERAI = 'togetherai';\nconst GEN_AI_PROVIDER_NAME_VALUE_VERCEL = 'vercel';\n\n/**\n * When adding something new here, please:\n * 1. Make sure it doesn't already exist as part of OTel Semantic Conventions (use that instead)\n * 2. Make sure to use standard naming schema, ie snake_case\n * 3. If a specific feature has an attribute you would like to use, extract it to the shared section\n *\n * Also Experimental Attributes should always be imported here and then used from the CustomAttributes object\n * because they are unstable.\n *\n * @see: https://github.com/open-telemetry/opentelemetry-js/tree/c89cb38d0fec39d54cf3fcb35c429a8129e9c909/semantic-conventions#unstable-semconv\n */\nexport const Attr = {\n  __EXPERIMENTAL_Flag: (flagName: string) => `flag.${flagName}`,\n  __EXPERIMENTAL_Fact: (factName: string) => `fact.${factName}`,\n  Axiom: {\n    GenAI: {\n      SchemaURL: ATTR_AXIOM_GEN_AI_SCHEMA_URL,\n      SDK: {\n        Name: ATTR_AXIOM_GEN_AI_SDK_NAME,\n        Version: ATTR_AXIOM_GEN_AI_SDK_VERSION,\n      },\n    },\n  },\n  GenAI: {\n    PromptMetadata: {\n      ID: 'axiom.gen_ai.prompt.id',\n      Name: 'axiom.gen_ai.prompt.name',\n      Slug: 'axiom.gen_ai.prompt.slug',\n      Version: 'axiom.gen_ai.prompt.version',\n    },\n    /**\n     * These two are used to identify the span\n     */\n    Capability: {\n      Name: ATTR_GEN_AI_CAPABILITY_NAME,\n    },\n    Step: {\n      Name: ATTR_GEN_AI_STEP_NAME,\n    },\n    Provider: {\n      Name: ATTR_GEN_AI_PROVIDER_NAME,\n      Name_Values: {\n        Anthropic: GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,\n        AssemblyAI: GEN_AI_PROVIDER_NAME_VALUE_ASSEMBLYAI,\n        AWSBedrock: GEN_AI_PROVIDER_NAME_VALUE_AWS_BEDROCK,\n        AzureAIInference: GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_INFERENCE,\n        AzureAIOpenAI: GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_OPENAI,\n        Cerebras: GEN_AI_PROVIDER_NAME_VALUE_CEREBRAS,\n        Cohere: GEN_AI_PROVIDER_NAME_VALUE_COHERE,\n        Deepgram: GEN_AI_PROVIDER_NAME_VALUE_DEEPGRAM,\n        DeepInfra: GEN_AI_PROVIDER_NAME_VALUE_DEEPINFRA,\n        Deepseek: GEN_AI_PROVIDER_NAME_VALUE_DEEPSEEK,\n        ElevenLabs: GEN_AI_PROVIDER_NAME_VALUE_ELEVENLABS,\n        Fal: GEN_AI_PROVIDER_NAME_VALUE_FAL,\n        Fireworks: GEN_AI_PROVIDER_NAME_VALUE_FIREWORKS,\n        GCPGemini: GEN_AI_PROVIDER_NAME_VALUE_GCP_GEMINI,\n        GCPGenAI: GEN_AI_PROVIDER_NAME_VALUE_GCP_GEN_AI,\n        GCPVertexAI: GEN_AI_PROVIDER_NAME_VALUE_GCP_VERTEX_AI,\n        Gladia: GEN_AI_PROVIDER_NAME_VALUE_GLADIA,\n        Groq: GEN_AI_PROVIDER_NAME_VALUE_GROQ,\n        Hume: GEN_AI_PROVIDER_NAME_VALUE_HUME,\n        IBMWatsonxAI: GEN_AI_PROVIDER_NAME_VALUE_IBM_WATSONX_AI,\n        Lmnt: GEN_AI_PROVIDER_NAME_VALUE_LMNT,\n        Luma: GEN_AI_PROVIDER_NAME_VALUE_LUMA,\n        MistralAI: GEN_AI_PROVIDER_NAME_VALUE_MISTRAL_AI,\n        OpenAI: GEN_AI_PROVIDER_NAME_VALUE_OPENAI,\n        Perplexity: GEN_AI_PROVIDER_NAME_VALUE_PERPLEXITY,\n        Replicate: GEN_AI_PROVIDER_NAME_VALUE_REPLICATE,\n        RevAI: GEN_AI_PROVIDER_NAME_VALUE_REVAI,\n        TogetherAI: GEN_AI_PROVIDER_NAME_VALUE_TOGETHERAI,\n        Vercel: GEN_AI_PROVIDER_NAME_VALUE_VERCEL,\n        XAI: GEN_AI_PROVIDER_NAME_VALUE_X_AI,\n      },\n    },\n    /**\n     * Regular attributes\n     */\n    Agent: {\n      Description: ATTR_GEN_AI_AGENT_DESCRIPTION, // not yet used by axiom-ai\n      ID: ATTR_GEN_AI_AGENT_ID, // not yet used by axiom-ai\n      Name: ATTR_GEN_AI_AGENT_NAME, // not yet used by axiom-ai\n    },\n    Conversation: {\n      ID: ATTR_GEN_AI_CONVERSATION_ID, // not yet used by axiom-ai, anyway probably needs to be provided by user\n    },\n    Input: {\n      Messages: ATTR_GEN_AI_INPUT_MESSAGES,\n    },\n    Operation: {\n      Name: ATTR_GEN_AI_OPERATION_NAME,\n      Name_Values: {\n        /**\n         * Note that \"text_completion\" is deprecated in favor of \"chat\" for both OpenAI and Anthropic\n         */\n        Chat: GEN_AI_OPERATION_NAME_VALUE_CHAT,\n        CreateAgent: GEN_AI_OPERATION_NAME_VALUE_CREATE_AGENT,\n        Embeddings: GEN_AI_OPERATION_NAME_VALUE_EMBEDDINGS,\n        ExecuteTool: GEN_AI_OPERATION_NAME_VALUE_EXECUTE_TOOL,\n        GenerateContent: GEN_AI_OPERATION_NAME_VALUE_GENERATE_CONTENT,\n        InvokeAgent: GEN_AI_OPERATION_NAME_VALUE_INVOKE_AGENT,\n      },\n    },\n    Output: {\n      Messages: ATTR_GEN_AI_OUTPUT_MESSAGES,\n      Type: ATTR_GEN_AI_OUTPUT_TYPE,\n      Type_Values: {\n        Text: GEN_AI_OUTPUT_TYPE_VALUE_TEXT,\n        Json: GEN_AI_OUTPUT_TYPE_VALUE_JSON,\n        Image: GEN_AI_OUTPUT_TYPE_VALUE_IMAGE,\n        Speech: GEN_AI_OUTPUT_TYPE_VALUE_SPEECH,\n      },\n    },\n    /**\n     * The provider that is hosting the model, eg AWS Bedrock\n     * There doesn't seem to be a semconv for this\n     */\n    Request: {\n      ChoiceCount: ATTR_GEN_AI_REQUEST_CHOICE_COUNT, // not yet used by axiom-ai\n      EncodingFormats: ATTR_GEN_AI_REQUEST_ENCODING_FORMATS, // not yet used by axiom-ai\n      FrequencyPenalty: ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY,\n      MaxTokens: ATTR_GEN_AI_REQUEST_MAX_TOKENS,\n      /**\n       * The model you asked for\n       */\n      Model: ATTR_GEN_AI_REQUEST_MODEL,\n      PresencePenalty: ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY,\n      Seed: ATTR_GEN_AI_REQUEST_SEED,\n      StopSequences: ATTR_GEN_AI_REQUEST_STOP_SEQUENCES,\n      Temperature: ATTR_GEN_AI_REQUEST_TEMPERATURE,\n      TopK: ATTR_GEN_AI_REQUEST_TOP_K,\n      TopP: ATTR_GEN_AI_REQUEST_TOP_P,\n    },\n    Response: {\n      FinishReasons: ATTR_GEN_AI_RESPONSE_FINISH_REASONS,\n      ID: ATTR_GEN_AI_RESPONSE_ID,\n      /**\n       * The model that was actually used (might be different bc routing) - only ever get this from the response, otherwise omit\n       */\n      Model: ATTR_GEN_AI_RESPONSE_MODEL, // somehow not landing on the span for google models? check up on this...\n    },\n    Tool: {\n      CallID: ATTR_GEN_AI_TOOL_CALL_ID,\n      Description: ATTR_GEN_AI_TOOL_DESCRIPTION,\n      Name: ATTR_GEN_AI_TOOL_NAME,\n      Type: ATTR_GEN_AI_TOOL_TYPE,\n      /**\n       * Note, OTel Semantic Convention suggest only putting tool inputs/outputs on the parent chat span\n       * But we at least want to give users THE OPTION to put them on the tool spans themselves as well\n       * Because it enables a lot of things with querying\n       * @see https://github.com/open-telemetry/semantic-conventions/releases/tag/v1.37.0\n       */\n      Arguments: ATTR_GEN_AI_TOOL_ARGUMENTS,\n      /**\n       * Note, OTel Semantic Convention suggest only putting tool inputs/outputs on the parent chat span\n       * But we at least want to give users THE OPTION to put them on the tool spans themselves as well\n       * Because it enables a lot of things with querying\n       * @see https://github.com/open-telemetry/semantic-conventions/releases/tag/v1.37.0\n       */\n      Message: ATTR_GEN_AI_TOOL_MESSAGE,\n    },\n    Usage: {\n      InputTokens: ATTR_GEN_AI_USAGE_INPUT_TOKENS,\n      OutputTokens: ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,\n    },\n  },\n  Eval: {\n    ID: ATTR_EVAL_ID,\n    Name: ATTR_EVAL_NAME,\n    Version: ATTR_EVAL_VERSION,\n    Type: ATTR_EVAL_TYPE,\n    Trials: ATTR_EVAL_TRIALS,\n    Baseline: {\n      ID: ATTR_EVAL_BASELINE_ID,\n      Name: ATTR_EVAL_BASELINE_NAME,\n      Version: ATTR_EVAL_BASELINE_VERSION,\n    },\n    Capability: {\n      Name: ATTR_EVAL_CAPABILITY_NAME,\n    },\n    Step: {\n      Name: ATTR_EVAL_STEP_NAME,\n    },\n    Tags: ATTR_EVAL_TAGS,\n    Metadata: ATTR_EVAL_METADATA,\n    Online: {\n      Scorers: {\n        Total: ATTR_EVAL_ONLINE_SCORERS_TOTAL,\n        Ran: ATTR_EVAL_ONLINE_SCORERS_RAN,\n        SampledOut: ATTR_EVAL_ONLINE_SCORERS_SAMPLED_OUT,\n        Failed: ATTR_EVAL_ONLINE_SCORERS_FAILED,\n      },\n    },\n    Collection: {\n      ID: ATTR_EVAL_COLLECTION_ID,\n      Name: ATTR_EVAL_COLLECTION_NAME,\n      Size: ATTR_EVAL_COLLECTION_SIZE,\n    },\n    Config: {\n      Flags: ATTR_EVAL_CONFIG_FLAGS,\n    },\n    Run: {\n      ID: ATTR_EVAL_RUN_ID,\n    },\n    Trial: {\n      Index: ATTR_EVAL_TRIAL_INDEX,\n      Error: ATTR_EVAL_TRIAL_ERROR,\n    },\n    Case: {\n      Index: ATTR_EVAL_CASE_INDEX,\n      Input: ATTR_EVAL_CASE_INPUT,\n      Output: ATTR_EVAL_CASE_OUTPUT,\n      Expected: ATTR_EVAL_CASE_EXPECTED,\n      Scores: ATTR_EVAL_CASE_SCORES,\n      Metadata: ATTR_EVAL_CASE_METADATA,\n      Trials: ATTR_EVAL_CASE_TRIALS,\n    },\n    Task: {\n      Output: ATTR_EVAL_TASK_OUTPUT,\n      Name: ATTR_EVAL_TASK_NAME,\n      Type: ATTR_EVAL_TASK_TYPE,\n    },\n    Score: {\n      Name: ATTR_EVAL_SCORE_NAME,\n      Value: ATTR_EVAL_SCORE_VALUE,\n      Threshold: ATTR_EVAL_SCORE_THRESHOLD,\n      Passed: ATTR_EVAL_SCORE_PASSED,\n      IsBoolean: ATTR_EVAL_SCORE_IS_BOOLEAN,\n      Metadata: ATTR_EVAL_SCORE_METADATA,\n      Aggregation: ATTR_EVAL_SCORE_AGGREGATION,\n      Trials: ATTR_EVAL_SCORE_TRIALS,\n    },\n    User: {\n      Name: ATTR_EVAL_USER_NAME,\n      Email: ATTR_EVAL_USER_EMAIL,\n    },\n  },\n  Error: {\n    Type: ATTR_ERROR_TYPE,\n    Message: ATTR_ERROR_MESSAGE,\n  },\n  HTTP: {\n    Response: {\n      StatusCode: ATTR_HTTP_RESPONSE_STATUS_CODE,\n    },\n  },\n} as const;\n","export const SCHEMA_VERSION = '0.0.2';\nexport const SCHEMA_BASE_URL = 'https://axiom.co/ai/schemas/';\nexport const SCHEMA_URL = `${SCHEMA_BASE_URL}${SCHEMA_VERSION}`;\n","import { type Span, type SpanOptions, SpanStatusCode, type Tracer } from '@opentelemetry/api';\n\ninterface Callbacks {\n  onSuccess?: (span: Span) => void;\n  onError?: (error: unknown, span: Span) => void;\n  onFinally?: (span: Span) => void;\n  /**\n   * If true, the operation will call span.end() manually.\n   * Used for streaming operations where the span should remain open until stream consumption completes.\n   */\n  manualEnd?: boolean;\n}\n\nexport const createStartActiveSpan =\n  (tracer: Tracer) =>\n  async <T>(\n    name: string,\n    options: SpanOptions | null,\n    fn: (span: Span) => Promise<T>,\n    callbacks?: Callbacks,\n  ): Promise<T> => {\n    return tracer.startActiveSpan(name, { ...(options ?? {}) }, async (span) => {\n      try {\n        const result = await fn(span);\n\n        callbacks?.onSuccess?.(span);\n\n        return result;\n      } catch (error) {\n        callbacks?.onError?.(error, span);\n\n        if (error instanceof Error) {\n          span.recordException(error);\n          span.setStatus({\n            code: SpanStatusCode.ERROR,\n            message: error.message,\n          });\n        }\n\n        throw error;\n      } finally {\n        callbacks?.onFinally?.(span);\n\n        // Only auto-end the span if manualEnd is not set\n        // For streaming operations, the operation itself will call span.end() when the stream completes\n        if (!callbacks?.manualEnd) {\n          span.end();\n        }\n      }\n    });\n  };\n","{\n  \"name\": \"axiom\",\n  \"version\": \"0.46.1\",\n  \"type\": \"module\",\n  \"author\": \"Axiom, Inc.\",\n  \"contributors\": [\n    \"Islam Shehata <islam@axiom.co>\",\n    \"Chris Ehrlich <chris@axiom.co>\",\n    \"Gabriel de Andrade <gabriel@axiom.co>\"\n  ],\n  \"scripts\": {\n    \"dev\": \"tsup --watch\",\n    \"build\": \"tsup && chmod +x dist/bin.js && pnpm check:vitest-entrypoints\",\n    \"check:vitest-entrypoints\": \"node ./scripts/check-vitest-entrypoints.mjs\",\n    \"format\": \"prettier --write .\",\n    \"format:check\": \"prettier --check .\",\n    \"lint\": \"eslint './**/*.{js,ts}'\",\n    \"typecheck\": \"tsc --noEmit\",\n    \"test\": \"vitest run\",\n    \"test:watch\": \"vitest --watch\",\n    \"publint\": \"npx publint\"\n  },\n  \"types\": \"./dist/index.d.ts\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"bin\": {\n    \"axiom\": \"./dist/bin.js\"\n  },\n  \"exports\": {\n    \"./ai\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./ai/evals\": {\n      \"import\": {\n        \"types\": \"./dist/evals.d.ts\",\n        \"default\": \"./dist/evals.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/evals.d.cts\",\n        \"default\": \"./dist/evals.cjs\"\n      }\n    },\n    \"./ai/evals/aggregations\": {\n      \"import\": {\n        \"types\": \"./dist/evals/aggregations.d.ts\",\n        \"default\": \"./dist/evals/aggregations.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/evals/aggregations.d.cts\",\n        \"default\": \"./dist/evals/aggregations.cjs\"\n      }\n    },\n    \"./ai/evals/scorers\": {\n      \"import\": {\n        \"types\": \"./dist/evals/scorers.d.ts\",\n        \"default\": \"./dist/evals/scorers.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/evals/scorers.d.cts\",\n        \"default\": \"./dist/evals/scorers.cjs\"\n      }\n    },\n    \"./ai/evals/online\": {\n      \"import\": {\n        \"types\": \"./dist/evals/online.d.ts\",\n        \"default\": \"./dist/evals/online.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/evals/online.d.cts\",\n        \"default\": \"./dist/evals/online.cjs\"\n      }\n    },\n    \"./ai/config\": {\n      \"import\": {\n        \"types\": \"./dist/config.d.ts\",\n        \"default\": \"./dist/config.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/config.d.cts\",\n        \"default\": \"./dist/config.cjs\"\n      }\n    },\n    \"./ai/feedback\": {\n      \"import\": {\n        \"types\": \"./dist/feedback.d.ts\",\n        \"default\": \"./dist/feedback.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/feedback.d.cts\",\n        \"default\": \"./dist/feedback.cjs\"\n      }\n    }\n  },\n  \"keywords\": [\n    \"axiom\",\n    \"logging\",\n    \"ai\",\n    \"otel\",\n    \"opentelemetry\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/axiomhq/ai.git\",\n    \"directory\": \"packages/ai\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@next/env\": \"^15.4.2\",\n    \"@opentelemetry/auto-instrumentations-node\": \"^0.60.1\",\n    \"@opentelemetry/context-async-hooks\": \"^2.0.1\",\n    \"@opentelemetry/exporter-trace-otlp-http\": \"^0.202.0\",\n    \"@opentelemetry/resources\": \"^2.0.1\",\n    \"@opentelemetry/sdk-trace-node\": \"^2.0.1\",\n    \"@opentelemetry/semantic-conventions\": \"^1.38.0\",\n    \"@sinclair/typebox\": \"^0.34.37\",\n    \"c12\": \"^3.3.3\",\n    \"commander\": \"^14.0.0\",\n    \"defu\": \"^6.1.4\",\n    \"handlebars\": \"^4.7.8\",\n    \"nanoid\": \"^5.1.5\",\n    \"open\": \"^10.1.0\",\n    \"vite-tsconfig-paths\": \"^5.1.4\",\n    \"vitest\": \"^4.0.0\"\n  },\n  \"peerDependencies\": {\n    \"@opentelemetry/api\": \"^1.9.0\",\n    \"zod\": \"^3.25.0 || ^4.0.0\"\n  },\n  \"devDependencies\": {\n    \"@ai-sdk/anthropicv1\": \"npm:@ai-sdk/anthropic@^1.2.12\",\n    \"@ai-sdk/anthropicv2\": \"npm:@ai-sdk/anthropic@^2.0.57\",\n    \"@ai-sdk/anthropicv3\": \"npm:@ai-sdk/anthropic@^3.0.9\",\n    \"@ai-sdk/openaiv1\": \"npm:@ai-sdk/openai@^1.3.24\",\n    \"@ai-sdk/openaiv2\": \"npm:@ai-sdk/openai@^2.0.88\",\n    \"@ai-sdk/openaiv3\": \"npm:@ai-sdk/openai@^3.0.7\",\n    \"@ai-sdk/providerv1\": \"npm:@ai-sdk/provider@^1.1.3\",\n    \"@ai-sdk/providerv2\": \"npm:@ai-sdk/provider@^2.0.1\",\n    \"@ai-sdk/providerv3\": \"npm:@ai-sdk/provider@^3.0.2\",\n    \"@opentelemetry/api\": \"^1.9.0\",\n    \"@opentelemetry/core\": \"^2.0.1\",\n    \"@opentelemetry/sdk-trace-base\": \"^2.0.1\",\n    \"@opentelemetry/sdk-trace-node\": \"^2.0.1\",\n    \"@repo/eslint-config\": \"workspace:*\",\n    \"@types/node\": \"^22.15.29\",\n    \"@vitest/coverage-v8\": \"^4.0.0\",\n    \"aiv4\": \"npm:ai@^4.3.19\",\n    \"aiv5\": \"npm:ai@^5.0.118\",\n    \"aiv6\": \"npm:ai@^6.0.6\",\n    \"esbuild\": \"^0.25.8\",\n    \"eslint\": \"catalog:\",\n    \"msw\": \"^2.12.2\",\n    \"prettier\": \"catalog:\",\n    \"tinyrainbow\": \"^2.0.0\",\n    \"tsup\": \"catalog:\",\n    \"typescript\": \"catalog:\",\n    \"vitest\": \"catalog:\",\n    \"zod\": \"catalog:\"\n  },\n  \"files\": [\n    \"dist\"\n  ],\n  \"packageManager\": \"pnpm@10.16.1\"\n}\n","import { context, propagation, type Baggage, type Span } from '@opentelemetry/api';\nimport { WITHSPAN_REDACTION_POLICY_KEY } from '../withSpanBaggageKey';\n\ntype CaptureMessageContent = 'full' | 'off';\n\nexport type AxiomAIRedactionPolicy = {\n  captureMessageContent?: CaptureMessageContent;\n  mirrorToolPayloadOnToolSpan?: boolean;\n};\n\nexport const RedactionPolicy = {\n  /**\n   * Includes message content on chat spans, and mirrors tool\n   * payload on tool spans for more convenient querying.\n   */\n  AxiomDefault: {\n    captureMessageContent: 'full',\n    mirrorToolPayloadOnToolSpan: true,\n  },\n  /**\n   * Redacts message content on chat spans, and does not put\n   * tool payload on tool spans.\n   */\n  OpenTelemetryDefault: {\n    captureMessageContent: 'off',\n    mirrorToolPayloadOnToolSpan: false,\n  },\n} as const satisfies Record<string, AxiomAIRedactionPolicy>;\n\n// Global key to store redaction policy across all execution contexts\nexport const AXIOM_AI_REDACTION_KEY = Symbol.for('__axiom_ai_redaction__');\n\n/**\n * Get the globally stored redaction policy\n * @returns The global redaction policy or undefined if not set\n */\nfunction getGlobalRedactionPolicy(): AxiomAIRedactionPolicy | undefined {\n  return (globalThis as any)[AXIOM_AI_REDACTION_KEY];\n}\n\n/**\n * Resolves the effective redaction policy by merging global and per-call policies.\n * Per-call policies take precedence over global policies.\n *\n * @param globalPolicy - The global redaction policy from initAxiomAI\n * @param localPolicy - The per-call redaction policy from withSpan or middleware\n * @returns The effective redaction policy with all fields resolved\n */\nfunction getEffectiveRedactionPolicy(\n  globalPolicy?: AxiomAIRedactionPolicy,\n  localPolicy?: AxiomAIRedactionPolicy,\n): AxiomAIRedactionPolicy {\n  // Per-call policy overrides global policy, with defaults\n  return {\n    captureMessageContent:\n      localPolicy?.captureMessageContent ??\n      globalPolicy?.captureMessageContent ??\n      RedactionPolicy.AxiomDefault.captureMessageContent,\n    mirrorToolPayloadOnToolSpan:\n      localPolicy?.mirrorToolPayloadOnToolSpan ??\n      globalPolicy?.mirrorToolPayloadOnToolSpan ??\n      RedactionPolicy.AxiomDefault.mirrorToolPayloadOnToolSpan,\n  };\n}\n\n/**\n * Get the active redaction policy\n */\nexport function getRedactionPolicy() {\n  return getEffectiveRedactionPolicy(getGlobalRedactionPolicy(), getPerCallRedactionPolicy());\n}\n\n/**\n * Conditionally sets a span attribute based on the capture message content policy.\n * When policy is 'off', the attribute is not set at all.\n *\n * @param span - The OpenTelemetry span to set the attribute on\n * @param attribute - The attribute name/key\n * @param value - The attribute value\n * @param captureMessageContent - The capture policy ('full' sets attribute, 'off' skips it)\n */\nexport function handleMaybeRedactedAttribute(\n  span: Span,\n  attribute: string,\n  value: any,\n  captureMessageContent?: CaptureMessageContent,\n): void {\n  if (captureMessageContent === 'full') {\n    span.setAttribute(attribute, value);\n  }\n\n  // For 'off', don't set the attribute at all\n  // Future: Could add callback-based redaction here\n}\n\n/**\n * Extracts the per-call redaction policy from OpenTelemetry baggage context.\n * This allows middleware and tools to access redaction policies passed via withSpan.\n *\n * @returns The per-call redaction policy or undefined if not set\n */\nfunction getPerCallRedactionPolicy(): AxiomAIRedactionPolicy | undefined {\n  const baggage: Baggage = propagation.getBaggage(context.active()) || propagation.createBaggage();\n  const serializedPolicy = baggage.getEntry(WITHSPAN_REDACTION_POLICY_KEY)?.value;\n\n  if (!serializedPolicy) {\n    return undefined;\n  }\n\n  try {\n    return JSON.parse(serializedPolicy) as AxiomAIRedactionPolicy;\n  } catch (error) {\n    console.warn('[AxiomAI] Failed to parse redaction policy from baggage:', error);\n    return undefined;\n  }\n}\n","import type { Tracer } from '@opentelemetry/api';\nimport { trace } from '@opentelemetry/api';\nimport packageJson from '../../package.json';\nimport { AXIOM_AI_REDACTION_KEY, type AxiomAIRedactionPolicy } from './utils/redaction';\n\n// Global key to store tracer scope information across all execution contexts\nconst AXIOM_AI_SCOPE_KEY = Symbol.for('__axiom_ai_scope__');\n\ninterface TracerScope {\n  name: string;\n  version?: string;\n}\n\n/**\n * Extract scope information from a tracer, with fallback to package.json\n */\nfunction extractTracerScope(tracer: Tracer): TracerScope {\n  const tracerAny = tracer as any;\n\n  // Guard access to private fields with optional chaining\n  // Note: These are internal OTEL fields that may change in future versions\n  // _instrumentationScope is modern, instrumentationLibrary is legacy (<1.16)\n  const name =\n    tracerAny._instrumentationScope?.name ||\n    tracerAny.instrumentationLibrary?.name ||\n    packageJson.name;\n\n  const version =\n    tracerAny._instrumentationScope?.version ||\n    tracerAny.instrumentationLibrary?.version ||\n    packageJson.version;\n\n  return { name, version };\n}\n\n/**\n * Register this in your `instrumentation.ts` to set up axiom.\n * This function stores the tracer's scope information globally to enable Context Propagation\n * and Instrumentation Scope. The tracer will be available across all execution contexts including Next.js.\n *\n * This function is idempotent - calling it multiple times with the same scope has no additional cost.\n *\n * @param config\n * @param config.tracer - The tracer that you are using in your application.\n * @param config.redactionPolicy - Optional redaction policy to control what data is captured in spans.\n */\nexport function initAxiomAI(config: { tracer: Tracer; redactionPolicy?: AxiomAIRedactionPolicy }) {\n  const newScope = extractTracerScope(config.tracer);\n  const existingScope = (globalThis as any)[AXIOM_AI_SCOPE_KEY] as TracerScope | undefined;\n\n  // Check if already initialized with same scope (idempotent behavior)\n  if (\n    existingScope &&\n    existingScope.name === newScope.name &&\n    existingScope.version === newScope.version\n  ) {\n    return;\n  }\n\n  // Warn about double initialization with different scopes\n  if (existingScope) {\n    console.warn(\n      '[AxiomAI] initAxiomAI() called multiple times with different scopes. ' +\n        `Previous: ${existingScope.name}@${existingScope.version}, ` +\n        `New: ${newScope.name}@${newScope.version}`,\n    );\n  }\n\n  // Store scope information globally (works across Next.js contexts)\n  (globalThis as any)[AXIOM_AI_SCOPE_KEY] = newScope;\n\n  // Store redaction policy globally if provided\n  if (config.redactionPolicy) {\n    (globalThis as any)[AXIOM_AI_REDACTION_KEY] = config.redactionPolicy;\n  }\n}\n\n/**\n * Get a tracer using the globally stored scope information\n * Fall back to package.json defaults if not set\n */\nexport function getGlobalTracer(): Tracer {\n  // Get stored scope information or fall back to package defaults\n  const scope = (globalThis as any)[AXIOM_AI_SCOPE_KEY] as TracerScope | undefined;\n\n  // Warn if initAxiomAI was never called\n  if (!scope) {\n    const isDebug = process.env.AXIOM_DEBUG === 'true';\n    if (!isDebug) {\n      console.warn(\n        '[AxiomAI] AXIOM_AI_SCOPE_KEY is undefined. This probably means that ' +\n          'initAxiomAI() was never called. ' +\n          'Make sure to call initAxiomAI({ tracer }) in your instrumentation setup.',\n      );\n    }\n  }\n\n  let { name, version } = scope || { name: packageJson.name, version: packageJson.version };\n\n  if (!name || !version) {\n    name = packageJson.name;\n    version = packageJson.version;\n    if (!name || !version) {\n      name = 'axiom';\n      version = 'unknown';\n    }\n  }\n\n  // Use OpenTelemetry's standard global provider mechanism\n  return trace.getTracer(name, version);\n}\n\n/**\n * Reset AxiomAI configuration (useful for testing)\n */\nexport function resetAxiomAI() {\n  (globalThis as any)[AXIOM_AI_SCOPE_KEY] = undefined;\n  (globalThis as any)[AXIOM_AI_REDACTION_KEY] = undefined;\n}\n","import {\n  trace,\n  context,\n  propagation,\n  type Span,\n  type Tracer,\n  SpanStatusCode,\n  type AttributeValue,\n} from '@opentelemetry/api';\nimport { Attr } from '../semconv/attributes';\nimport { SCHEMA_URL } from '../../schema';\nimport { WITHSPAN_BAGGAGE_KEY } from '../withSpanBaggageKey';\nimport { createStartActiveSpan } from '../startActiveSpan';\n\nimport { getGlobalTracer } from '../initAxiomAI';\nimport packageJson from '../../../package.json';\nimport type { OpenAIMessage } from '../vercelTypes';\nimport type { LanguageModelV2Prompt } from '@ai-sdk/providerv2';\nimport type { LanguageModelV3Prompt } from '@ai-sdk/providerv3';\n\n/**\n * Common span context discriminated union for V1, V2 and V3\n */\ntype GenAiSpanContext =\n  | {\n      version: 'v1';\n      originalPrompt: OpenAIMessage[];\n      rawCall?: {\n        rawPrompt?: unknown[];\n        rawSettings?: unknown;\n      };\n    }\n  | {\n      version: 'v2';\n      originalPrompt: OpenAIMessage[];\n      originalV2Prompt?: LanguageModelV2Prompt;\n    }\n  | {\n      version: 'v3';\n      originalPrompt: OpenAIMessage[];\n      originalV3Prompt?: LanguageModelV3Prompt;\n    };\n\nexport type GenAiSpanContextV1 = Extract<GenAiSpanContext, { version: 'v1' }>;\nexport type GenAiSpanContextV2 = Extract<GenAiSpanContext, { version: 'v2' }>;\nexport type GenAiSpanContextV3 = Extract<GenAiSpanContext, { version: 'v3' }>;\n\n/**\n * SpanLease represents ownership of a span's lifecycle\n * - owned: true means the middleware created the span and must end it\n * - owned: false means the span is owned by withSpan and middleware must NOT end it\n */\nexport interface SpanLease {\n  owned: boolean;\n  end: () => void;\n}\n\n/**\n * Safely converts a value to a number, handling string inputs from providers.\n * Some AI providers may return token counts as strings instead of numbers.\n *\n * @returns The numeric value, or undefined if the input is not a valid number\n */\nexport function ensureNumber(value: unknown): number | undefined {\n  const v =\n    typeof value === 'number' ? value : typeof value === 'string' ? Number(value) : undefined;\n  if (Number.isNaN(v)) return undefined;\n  if (v === Infinity || v === -Infinity) return undefined;\n  return v;\n}\n\n/**\n * Classifies errors into low-cardinality types for OpenTelemetry error.type attribute\n * Reference: OTel spec § 7.22.5 for error.type guidelines\n *\n * Uses explicit mapping for useful error types, avoiding generic built-in errors\n * that are not actionable for observability dashboards.\n *\n * @returns string for actionable error types, undefined for unclassifiable errors\n */\nfunction classifyError(err: unknown): string | undefined {\n  if (err == null) return undefined;\n\n  if (err instanceof Error) {\n    const name = err.name.toLowerCase();\n\n    // Explicit mapping for actionable error types\n    if (name.includes('timeout')) return 'timeout';\n    if (name.includes('abort')) return 'timeout'; // AbortError often means timeout\n    if (name.includes('network') || name.includes('fetch')) return 'network';\n    if (name.includes('validation')) return 'validation';\n    if (name.includes('auth')) return 'authentication';\n    if (name.includes('parse') || name.includes('json')) return 'parsing';\n    if (name.includes('permission') || name.includes('forbidden')) return 'authorization';\n    if (name.includes('rate') && name.includes('limit')) return 'rate_limit';\n    if (name.includes('quota') || name.includes('limit')) return 'quota_exceeded';\n\n    // Skip generic built-in errors (TypeError, ReferenceError, etc.)\n    // They're not useful for observability dashboards\n    return undefined;\n  }\n\n  return undefined; // Handles primitives thrown as errors\n}\n\n/**\n * Classifies tool-specific errors using duck-typing for cross-vendor compatibility\n * Handles node-fetch version differences and external API error patterns\n *\n * @param err The error to classify\n * @param span The span to set error attributes on\n */\nexport function classifyToolError(err: unknown, span: Span): void {\n  // Enhanced error handling for OpenTelemetry compliance\n  if (err instanceof Error) {\n    span.recordException(err); // Error objects are compatible with Exception interface\n  } else {\n    // Convert primitives to compatible format\n    span.recordException({\n      message: String(err),\n      name: 'UnknownError',\n    });\n  }\n\n  span.setStatus({\n    code: SpanStatusCode.ERROR,\n    message: err instanceof Error ? err.message : String(err),\n  });\n\n  let errorType = 'unknown';\n  let statusCode: string | number | undefined;\n\n  // Duck-type check for common error patterns (don't rely on inheritance)\n  if (err && typeof err === 'object') {\n    const errObj = err as any;\n    const name = errObj.name?.toLowerCase() || '';\n    const message = errObj.message?.toLowerCase() || '';\n\n    if (name.includes('timeout') || name.includes('abort') || message.includes('timeout')) {\n      errorType = 'timeout';\n    } else if (\n      name.includes('validation') ||\n      errObj.code === 'VALIDATION_ERROR' ||\n      message.includes('validation')\n    ) {\n      errorType = 'validation';\n    } else if (\n      name.includes('fetch') ||\n      name.includes('network') ||\n      message.includes('network') ||\n      message.includes('fetch failed')\n    ) {\n      errorType = 'network';\n      // Handle both node-fetch v2 (.code) and v3 (.status) patterns\n      statusCode = errObj.status || errObj.code;\n    } else if (\n      name.includes('auth') ||\n      message.includes('auth') ||\n      message.includes('unauthorized')\n    ) {\n      errorType = 'authentication';\n    } else if (\n      name.includes('permission') ||\n      name.includes('forbidden') ||\n      message.includes('forbidden')\n    ) {\n      errorType = 'authorization';\n    } else if (\n      name.includes('rate') &&\n      (name.includes('limit') || message.includes('rate limit'))\n    ) {\n      errorType = 'rate_limit';\n    } else if (\n      name.includes('quota') ||\n      message.includes('quota') ||\n      message.includes('limit exceeded')\n    ) {\n      errorType = 'quota_exceeded';\n    } else if (\n      name.includes('parse') ||\n      name.includes('json') ||\n      message.includes('json') ||\n      message.includes('parse')\n    ) {\n      errorType = 'parsing';\n    }\n  }\n\n  // MANDATORY: Standard OpenTelemetry error attributes\n  span.setAttribute(Attr.Error.Type, errorType);\n  if (err instanceof Error && err.message) {\n    span.setAttribute(Attr.Error.Message, err.message);\n  }\n\n  // Standard HTTP attributes for network errors\n  if (statusCode !== undefined) {\n    span.setAttribute(Attr.HTTP.Response.StatusCode, statusCode as AttributeValue);\n  }\n}\n\n/**\n * Check if the current tracer provider is a no-op\n * Uses safer detection that works with bundling/minification\n */\nfunction isNoOpTracerProvider(): boolean {\n  const provider = trace.getTracerProvider();\n\n  // Check constructor name (may fail with bundling/minification)\n  if (provider.constructor.name === 'NoopTracerProvider') {\n    return true;\n  }\n\n  // Check if getTracer method exists before calling it (for test mocks)\n  if (typeof (provider as any).getTracer !== 'function') {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Gets the appropriate tracer instance using global scope or fallbacks\n */\nexport function getTracer(): Tracer {\n  const tracer = getGlobalTracer();\n\n  if (isNoOpTracerProvider()) {\n    const isDebug = process.env.AXIOM_DEBUG === 'true';\n    if (!isDebug) {\n      console.warn(\n        '[AxiomAI] No TracerProvider registered - spans will be no-op. ' +\n          'Make sure to call initAxiomAI() after your OpenTelemetry SDK has started (sdk.start()).',\n      );\n    }\n  }\n\n  return tracer;\n}\n\n/**\n * Creates a standardized span name for GenAI operations\n */\nfunction createGenAISpanName(operation: string, suffix?: string): string {\n  return suffix ? `${operation} ${suffix}` : operation;\n}\n\n/**\n * Sets common scope attributes on a span from baggage\n */\nexport function setScopeAttributes(span: Span): void {\n  const bag = propagation.getActiveBaggage();\n\n  if (bag) {\n    const capability = bag.getEntry('capability')?.value;\n    if (capability) {\n      span.setAttribute(Attr.GenAI.Capability.Name, capability);\n    }\n\n    const step = bag.getEntry('step')?.value;\n    if (step) {\n      span.setAttribute(Attr.GenAI.Step.Name, step);\n    }\n\n    const conversationId = bag.getEntry('conversationId')?.value;\n    if (conversationId) {\n      span.setAttribute(Attr.GenAI.Conversation.ID, conversationId);\n    }\n  }\n}\n\n/**\n * Sets Axiom-specific base attributes on a span\n */\nexport function setAxiomBaseAttributes(span: Span): void {\n  span.setAttributes({\n    [Attr.Axiom.GenAI.SchemaURL]: SCHEMA_URL,\n    [Attr.Axiom.GenAI.SDK.Name]: packageJson.name,\n    [Attr.Axiom.GenAI.SDK.Version]: packageJson.version,\n  });\n}\n\n/**\n * Sets common base attributes on a span\n */\nexport function setBaseAttributes(span: Span, provider: string, modelId: string): void {\n  span.setAttributes({\n    [Attr.GenAI.Operation.Name]: Attr.GenAI.Operation.Name_Values.Chat,\n    [Attr.GenAI.Request.Model]: modelId,\n  });\n\n  const systemValue = mapVercelSDKProviderToOTelProvider(provider);\n  if (systemValue) {\n    span.setAttribute(Attr.GenAI.Provider.Name, systemValue);\n  }\n\n  setAxiomBaseAttributes(span);\n}\n\n/**\n * Sets common request parameter attributes on a span\n */\nexport function setRequestParameterAttributes(\n  span: Span,\n  params: {\n    maxTokens?: number;\n    frequencyPenalty?: number;\n    presencePenalty?: number;\n    temperature?: number;\n    topP?: number;\n    topK?: number;\n    seed?: number;\n    stopSequences?: string[];\n  },\n): void {\n  const {\n    maxTokens,\n    frequencyPenalty,\n    presencePenalty,\n    temperature,\n    topP,\n    topK,\n    seed,\n    stopSequences,\n  } = params;\n\n  if (maxTokens !== undefined) {\n    span.setAttribute(Attr.GenAI.Request.MaxTokens, maxTokens);\n  }\n  if (frequencyPenalty !== undefined) {\n    span.setAttribute(Attr.GenAI.Request.FrequencyPenalty, frequencyPenalty);\n  }\n  if (presencePenalty !== undefined) {\n    span.setAttribute(Attr.GenAI.Request.PresencePenalty, presencePenalty);\n  }\n  if (temperature !== undefined) {\n    span.setAttribute(Attr.GenAI.Request.Temperature, temperature);\n  }\n  if (topP !== undefined) {\n    span.setAttribute(Attr.GenAI.Request.TopP, topP);\n  }\n  if (topK !== undefined) {\n    span.setAttribute(Attr.GenAI.Request.TopK, topK);\n  }\n  if (seed !== undefined) {\n    span.setAttribute(Attr.GenAI.Request.Seed, seed);\n  }\n  if (stopSequences && stopSequences.length > 0) {\n    span.setAttribute(Attr.GenAI.Request.StopSequences, JSON.stringify(stopSequences));\n  }\n}\n\n/**\n * Creates a child span for stream processing\n * This provides granular visibility into stream consumption phases\n */\nexport function createStreamChildSpan(parentSpan: Span, operationName: string): Span {\n  const tracer = getTracer();\n\n  // Create child span by setting parent context\n  const ctx = context.active();\n  const spanContext = trace.setSpan(ctx, parentSpan);\n  const childSpan = tracer.startSpan(operationName, undefined, spanContext);\n\n  return childSpan;\n}\n\n/**\n * Records an error on a span with proper classification and attributes\n * Consolidates all error handling logic in one place\n */\nfunction recordSpanError(span: Span, err: unknown): void {\n  // Enhanced error handling for OpenTelemetry compliance\n  if (err instanceof Error) {\n    span.recordException(err);\n  } else {\n    span.recordException({\n      message: String(err),\n      name: 'UnknownError',\n    });\n  }\n\n  span.setStatus({\n    code: SpanStatusCode.ERROR,\n    message: err instanceof Error ? err.message : String(err),\n  });\n\n  // MANDATORY: Add OpenTelemetry error attributes for cross-vendor compatibility\n  const errorType = classifyError(err);\n  span.setAttribute(Attr.Error.Type, errorType ?? 'unknown');\n\n  // OPTIONAL: Add human-readable error message\n  if (err instanceof Error && err.message) {\n    span.setAttribute(Attr.Error.Message, err.message);\n  }\n\n  // For Vercel AI SDK specific errors, add HTTP status if available\n  if (err && typeof err === 'object' && 'status' in err) {\n    span.setAttribute(Attr.HTTP.Response.StatusCode, err.status as AttributeValue);\n  }\n}\n\n/**\n * Common span handling logic for V1, V2 and V3\n * Returns a SpanLease that indicates whether the middleware owns the span\n */\nexport async function withSpanHandling<T>(\n  modelId: string,\n  operation: (span: Span, context: GenAiSpanContext, lease: SpanLease) => Promise<T>,\n  options?: { streaming?: boolean; version?: 'v1' | 'v2' | 'v3' },\n): Promise<T> {\n  const bag = propagation.getActiveBaggage();\n  const isWithinWithSpan = bag?.getEntry(WITHSPAN_BAGGAGE_KEY)?.value === 'true';\n\n  const spanContext: GenAiSpanContext =\n    options?.version === 'v3'\n      ? { version: 'v3', originalPrompt: [], originalV3Prompt: undefined }\n      : options?.version === 'v2'\n        ? { version: 'v2', originalPrompt: [], originalV2Prompt: undefined }\n        : { version: 'v1', originalPrompt: [], rawCall: undefined };\n\n  const name = createGenAISpanName(Attr.GenAI.Operation.Name_Values.Chat, modelId);\n\n  if (isWithinWithSpan) {\n    // Reuse existing span created by withSpan - we don't own it\n    const activeSpan = trace.getActiveSpan();\n    if (!activeSpan) {\n      throw new Error('Expected active span when within withSpan');\n    }\n    activeSpan.updateName(name);\n\n    const lease: SpanLease = {\n      owned: false,\n      end: () => {}, // No-op: we don't own this span\n    };\n\n    try {\n      return await operation(activeSpan, spanContext, lease);\n    } catch (err) {\n      recordSpanError(activeSpan, err);\n      throw err;\n    }\n  } else {\n    // Create new span - we own it\n    const tracer = getTracer();\n    const startActiveSpan = createStartActiveSpan(tracer);\n\n    return startActiveSpan(\n      name,\n      null,\n      async (span) => {\n        const lease: SpanLease = {\n          owned: true,\n          end: () => span.end(),\n        };\n        return await operation(span, spanContext, lease);\n      },\n      {\n        manualEnd: options?.streaming ?? false,\n        onError: (err, span) => {\n          // createStartActiveSpan already calls span.recordException()\n          // We only need to add our custom error classification attributes\n          const errorType = classifyError(err);\n          span.setAttribute(Attr.Error.Type, errorType ?? 'unknown');\n\n          if (err instanceof Error && err.message) {\n            span.setAttribute(Attr.Error.Message, err.message);\n          }\n\n          if (err && typeof err === 'object' && 'status' in err) {\n            span.setAttribute(Attr.HTTP.Response.StatusCode, err.status as AttributeValue);\n          }\n        },\n      },\n    );\n  }\n}\n\n/**\n * Sets common response attributes on a span\n */\nexport function setResponseAttributes(\n  span: Span,\n  response: {\n    id?: string;\n    modelId?: string;\n    usage?: {\n      inputTokens?: number;\n      outputTokens?: number;\n      promptTokens?: number;\n      completionTokens?: number;\n    };\n    finishReason?: string;\n  },\n): void {\n  if (response.id) {\n    span.setAttribute(Attr.GenAI.Response.ID, response.id);\n  }\n  if (response.modelId) {\n    span.setAttribute(Attr.GenAI.Response.Model, response.modelId);\n  }\n\n  if (response.usage) {\n    // Handle both V1 and V2 usage formats\n    const inputTokens = ensureNumber(response.usage.inputTokens ?? response.usage.promptTokens);\n    const outputTokens = ensureNumber(\n      response.usage.outputTokens ?? response.usage.completionTokens,\n    );\n\n    if (inputTokens !== undefined) {\n      span.setAttribute(Attr.GenAI.Usage.InputTokens, inputTokens);\n    }\n    if (outputTokens !== undefined) {\n      span.setAttribute(Attr.GenAI.Usage.OutputTokens, outputTokens);\n    }\n  }\n\n  if (response.finishReason) {\n    span.setAttribute(Attr.GenAI.Response.FinishReasons, JSON.stringify([response.finishReason]));\n  }\n}\n\n/**\n * Determines output type from response format - V1 version\n */\nexport function determineOutputTypeV1(options: {\n  responseFormat?: { type?: string };\n  mode?: { type?: string };\n}): string | undefined {\n  if (options.responseFormat?.type) {\n    switch (options.responseFormat.type) {\n      case 'json':\n        return Attr.GenAI.Output.Type_Values.Json;\n      case 'text':\n        return Attr.GenAI.Output.Type_Values.Text;\n    }\n  }\n\n  if (options.mode?.type === 'object-json' || options.mode?.type === 'object-tool') {\n    return Attr.GenAI.Output.Type_Values.Json;\n  }\n\n  if (options.mode?.type === 'regular') {\n    return Attr.GenAI.Output.Type_Values.Text;\n  }\n\n  return undefined;\n}\n\n/**\n * Determines output type from response format - V2 version\n */\nexport function determineOutputTypeV2(options: {\n  responseFormat?: { type?: string };\n}): string | undefined {\n  if (options.responseFormat?.type) {\n    switch (options.responseFormat.type) {\n      case 'json':\n        return Attr.GenAI.Output.Type_Values.Json;\n      case 'text':\n        return Attr.GenAI.Output.Type_Values.Text;\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Determines output type from response format - V3 version\n * V3 uses the same response format structure as V2\n */\nexport function determineOutputTypeV3(options: {\n  responseFormat?: { type?: string };\n}): string | undefined {\n  if (options.responseFormat?.type) {\n    switch (options.responseFormat.type) {\n      case 'json':\n        return Attr.GenAI.Output.Type_Values.Json;\n      case 'text':\n        return Attr.GenAI.Output.Type_Values.Text;\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Maps AI SDK provider IDs to OpenTelemetry gen_ai.provider.name values\n *\n * @param vercelSDKProvider - The provider ID from the AI SDK\n * @returns The corresponding `gen_ai.provider.name` value, or `undefined` if no match is found\n */\nexport function mapVercelSDKProviderToOTelProvider(vercelSDKProvider: string): string | undefined {\n  if (vercelSDKProvider === 'openai-compatible') {\n    // we don't know the real provider\n    return undefined;\n  }\n\n  // exact matches\n  switch (vercelSDKProvider) {\n    case 'amazon-bedrock':\n      return Attr.GenAI.Provider.Name_Values.AWSBedrock;\n    case 'anthropic':\n    case 'anthropic.messages':\n      return Attr.GenAI.Provider.Name_Values.Anthropic;\n    case 'assemblyai':\n    case 'assemblyai.transcription':\n      return Attr.GenAI.Provider.Name_Values.AssemblyAI;\n    case 'deepgram':\n    case 'deepgram.transcription':\n      return Attr.GenAI.Provider.Name_Values.Deepgram;\n    case 'gateway': // `import { gateway } from 'ai'`\n      return Attr.GenAI.Provider.Name_Values.Vercel;\n    case 'gladia':\n    case 'gladia.transcription':\n      return Attr.GenAI.Provider.Name_Values.Gladia;\n    case 'google':\n    case 'google.generative-ai':\n      return Attr.GenAI.Provider.Name_Values.GCPGemini;\n    case 'groq':\n      return Attr.GenAI.Provider.Name_Values.Groq;\n    case 'mistral':\n      return Attr.GenAI.Provider.Name_Values.MistralAI;\n    case 'openai':\n      return Attr.GenAI.Provider.Name_Values.OpenAI;\n    case 'perplexity':\n      return Attr.GenAI.Provider.Name_Values.Perplexity;\n    case 'replicate':\n      return Attr.GenAI.Provider.Name_Values.Replicate;\n    case 'revai':\n    case 'revai.transcription':\n      return Attr.GenAI.Provider.Name_Values.RevAI;\n    case 'togetherai':\n      return Attr.GenAI.Provider.Name_Values.TogetherAI;\n    case 'xai':\n      return Attr.GenAI.Provider.Name_Values.XAI;\n\n    // startswith + fall through\n    default: {\n      if (vercelSDKProvider.startsWith('azure.')) {\n        return Attr.GenAI.Provider.Name_Values.AzureAIOpenAI;\n      }\n      if (vercelSDKProvider.startsWith('cerebras.')) {\n        return Attr.GenAI.Provider.Name_Values.Cerebras;\n      }\n      if (vercelSDKProvider.startsWith('cohere.')) {\n        return Attr.GenAI.Provider.Name_Values.Cohere;\n      }\n      if (vercelSDKProvider.startsWith('deepinfra.')) {\n        return Attr.GenAI.Provider.Name_Values.DeepInfra;\n      }\n      if (vercelSDKProvider.startsWith('deepseek.')) {\n        return Attr.GenAI.Provider.Name_Values.Deepseek;\n      }\n      if (vercelSDKProvider.startsWith('elevenlabs.')) {\n        return Attr.GenAI.Provider.Name_Values.ElevenLabs;\n      }\n      if (vercelSDKProvider.startsWith('fal.')) {\n        return Attr.GenAI.Provider.Name_Values.Fal;\n      }\n      if (vercelSDKProvider.startsWith('fireworks.')) {\n        return Attr.GenAI.Provider.Name_Values.Fireworks;\n      }\n      if (vercelSDKProvider.startsWith('google.vertex.')) {\n        return Attr.GenAI.Provider.Name_Values.GCPVertexAI;\n      }\n      if (vercelSDKProvider.startsWith('groq.')) {\n        return Attr.GenAI.Provider.Name_Values.Groq;\n      }\n      if (vercelSDKProvider.startsWith('hume.')) {\n        return Attr.GenAI.Provider.Name_Values.Hume;\n      }\n      if (vercelSDKProvider.startsWith('lmnt.')) {\n        return Attr.GenAI.Provider.Name_Values.Lmnt;\n      }\n      if (vercelSDKProvider.startsWith('luma.')) {\n        return Attr.GenAI.Provider.Name_Values.Luma;\n      }\n      if (vercelSDKProvider.startsWith('mistral.')) {\n        return Attr.GenAI.Provider.Name_Values.MistralAI;\n      }\n      if (vercelSDKProvider.startsWith('openai.')) {\n        return Attr.GenAI.Provider.Name_Values.OpenAI;\n      }\n      if (vercelSDKProvider.startsWith('vercel.')) {\n        return Attr.GenAI.Provider.Name_Values.Vercel;\n      }\n      if (vercelSDKProvider.startsWith('vertex.anthropic.')) {\n        return Attr.GenAI.Provider.Name_Values.GCPVertexAI;\n      }\n      if (vercelSDKProvider.startsWith('xai.')) {\n        return Attr.GenAI.Provider.Name_Values.XAI;\n      }\n\n      // most other openai-compatible providers use {providerName}.{chat|completion|embedding|image}\n      const s = vercelSDKProvider.split('.');\n      if (s.length === 2) {\n        return s[0];\n      }\n\n      // For unknown providers, don't set the attribute\n      return undefined;\n    }\n  }\n}\n","/**\n * Validates that a name contains only allowed characters (A-Z, a-z, 0-9, -, _)\n * and is not empty.\n *\n * @returns Object with validation result and optional error message\n */\nexport function isValidName(name: string): { valid: true } | { valid: false; error: string } {\n  if (name === '') {\n    return { valid: false, error: 'Name cannot be empty' };\n  }\n\n  const validPattern = /^[A-Za-z0-9_-]+$/;\n  if (!validPattern.test(name)) {\n    return {\n      valid: false,\n      error: `Invalid character in \"${name}\". Only A-Z, a-z, 0-9, -, _ allowed`,\n    };\n  }\n\n  return { valid: true };\n}\n","import {\n  context,\n  propagation,\n  trace,\n  SpanStatusCode,\n  type Span,\n  type Baggage,\n  type Tracer,\n} from '@opentelemetry/api';\n\nimport { WITHSPAN_BAGGAGE_KEY, WITHSPAN_REDACTION_POLICY_KEY } from './withSpanBaggageKey';\nimport { getTracer } from './utils/wrapperUtils';\nimport type { AxiomAIRedactionPolicy } from './utils/redaction';\nimport type { ValidateName } from '../util/name-validation';\nimport { isValidName } from '../util/name-validation-runtime';\n\n/**\n * Metadata for categorizing and tracking spans within the AI application.\n */\ntype WithSpanMeta = {\n  /** High-level capability being performed (e.g., 'text_generation', 'chat', 'analysis') */\n  capability: string;\n  /** Specific step within the capability (e.g., 'generate_response', 'summarize', 'extract') */\n  step: string;\n  /** Optional conversation ID to correlate spans across a multi-turn conversation */\n  conversationId?: string;\n};\n\n/**\n * Wrap Vercel AI SDK functions like `generateText` and `streamText` in an OpenTelemetry span.\n *\n * Automatically detects and handles different response types:\n * - **Response streams**: Keeps span alive during entire stream consumption\n * - **Streaming objects**: Warns about incorrect usage patterns\n * - **Regular objects**: Ends span immediately after function completion\n *\n * The span name will be updated by the AI SDK middleware from 'chat'\n * to a model-specific name like 'chat gpt-4o-mini' when used with wrapped models.\n *\n * @param meta - Span metadata for categorization and tracking\n * @param meta.capability - High-level capability being performed (e.g., 'customer_support', 'meeting_summarizer')\n * @param meta.step - Specific step within the capability (e.g., 'categorize_message', 'transcribe_audio')\n * @param fn - Function to execute within the span context. Receives the span as a parameter so you can add additional attributes.\n * @param opts - Optional configuration\n * @param opts.tracer - Custom OpenTelemetry tracer instance. Defaults to the tracer provided by `initAxiomAI`.\n * @param opts.timeoutMs - Timeout for abandoned streams. Defaults to 600,000 (10 minutes).\n * @param opts.redactionPolicy - Optional redaction policy to override global policy for this span.\n *\n * @returns Promise that resolves to the same value as the wrapped function\n *\n * @example \n * // Non-streaming usage\n * const result = await withSpan(\n *   { capability: 'text_generation', step: 'generate' },\n *   async (span) => {\n *     span.setAttribute('user.id', userId); // can set attributes on the span\n *     const result = await generateObject({ model, prompt });\n *     // can do something with the result here, eg set additional attributes\n *     return result\n *   }\n * );\n *\n * @example \n * // Streaming usage with `@ai-sdk/react` in the frontend\n * ```ts\n * const response = withSpan(\n *   { capability: 'chat', step: 'stream_chat' },\n *   async (span) => {\n *     span.setAttribute('user.id', userId);\n *     const result = streamText({ model, messages });\n *     return result.toUIMessageStreamResponse();\n *   }\n * );\n * ```\n * \n * @example \n * // Streaming usage with express\n * ```ts\n * await withSpan(\n *   { capability: 'chat', step: 'stream_chat' },\n *   async (span) => {\n *     span.setAttribute('user.id', userId);\n *\n *     const { textStream } = streamText({ model, messages });\n *\n *     // Keep span open during entire stream consumption\n *     for await (const chunk of textStream) {\n *       res.write(chunk);\n *     }\n *   }\n * );\n\n * res.end();\n * ```\n */\n/**\n * Options for withSpan configuration.\n */\nexport type WithSpanOptions = {\n  /** Custom OpenTelemetry tracer instance */\n  tracer?: Tracer;\n  /** Timeout for abandoned streams (default: 600,000ms / 10 minutes) */\n  timeoutMs?: number;\n  /** Redaction policy to override global policy for this span */\n  redactionPolicy?: AxiomAIRedactionPolicy;\n};\n\nexport function withSpan<Return, Capability extends string = string, Step extends string = string>(\n  meta: WithSpanMeta & {\n    capability: ValidateName<Capability>;\n    step: ValidateName<Step>;\n  },\n  fn: (span: Span) => Promise<Return>,\n  opts?: WithSpanOptions,\n): Promise<Return> {\n  const tracer = opts?.tracer ?? getTracer();\n\n  // Create span manually to control its lifecycle\n  const span = tracer.startSpan('chat');\n  const spanContext = trace.setSpan(context.active(), span);\n\n  return context.with(spanContext, async () => {\n    const capabilityValidation = isValidName(meta.capability);\n    if (!capabilityValidation.valid) {\n      console.warn(`[AxiomAI] Invalid capability name: ${capabilityValidation.error}. `);\n    }\n\n    const stepValidation = isValidName(meta.step);\n    if (!stepValidation.valid) {\n      console.warn(`[AxiomAI] Invalid step name: ${stepValidation.error}. `);\n    }\n\n    if (!span.isRecording()) {\n      const provider = trace.getTracerProvider();\n      const providerIsNoOp = provider.constructor.name === 'NoopTracerProvider';\n\n      // We don't warn for other non-recording cases (sampling=DROP, etc.) as those may be intentional\n      if (providerIsNoOp) {\n        const isDebug = process.env.AXIOM_DEBUG === 'true';\n        if (!isDebug) {\n          console.warn(\n            '[AxiomAI] No TracerProvider registered - spans are no-op. Make sure to call initAxiomAI() after your OpenTelemetry SDK has started.',\n          );\n        }\n      }\n    }\n\n    const bag: Baggage = propagation.createBaggage({\n      capability: { value: meta.capability },\n      step: { value: meta.step },\n      // TODO: maybe we can just check the active span name instead?\n      [WITHSPAN_BAGGAGE_KEY]: { value: 'true' }, // Mark that we're inside withSpan\n      // Store serialized redaction policy if provided\n      ...(opts?.redactionPolicy && {\n        [WITHSPAN_REDACTION_POLICY_KEY]: { value: JSON.stringify(opts.redactionPolicy) },\n      }),\n      // Store conversation ID if provided\n      ...(meta.conversationId && {\n        conversationId: { value: meta.conversationId },\n      }),\n    });\n\n    const ctx = propagation.setBaggage(context.active(), bag);\n\n    let spanEnded = false;\n    const safeEndSpan = () => {\n      if (!spanEnded) {\n        spanEnded = true;\n        span.end();\n      }\n    };\n\n    // Timeout fallback for abandoned streams\n    const timeoutMs = opts?.timeoutMs ?? 600_000; // 10 minutes default\n    const timeoutId = setTimeout(() => {\n      safeEndSpan();\n    }, timeoutMs);\n\n    try {\n      const result = await context.with(ctx, () => fn(span));\n\n      // Auto-detect Response streams and keep span alive during consumption\n      if (result instanceof Response && result.body) {\n        // Check if body is already locked\n        if (result.body.locked) {\n          console.warn('[AxiomAI] Response body is already locked, cannot instrument stream');\n          clearTimeout(timeoutId);\n          safeEndSpan();\n          return result;\n        }\n\n        const originalReader = result.body.getReader();\n        const wrappedStream = new ReadableStream({\n          async pull(controller) {\n            try {\n              const { value, done } = await context.with(ctx, () => originalReader.read());\n              if (done) {\n                originalReader.releaseLock?.();\n                clearTimeout(timeoutId);\n                span.setStatus({ code: SpanStatusCode.OK });\n                safeEndSpan();\n                controller.close();\n              } else {\n                controller.enqueue(value);\n              }\n            } catch (err) {\n              originalReader.releaseLock?.();\n              clearTimeout(timeoutId);\n              span.recordException(err as Error);\n              span.setStatus({\n                code: SpanStatusCode.ERROR,\n                message: err instanceof Error ? err.message : String(err),\n              });\n              safeEndSpan();\n              controller.error(err);\n            }\n          },\n          async cancel(reason: unknown) {\n            try {\n              originalReader.releaseLock?.();\n              clearTimeout(timeoutId);\n              if (reason instanceof Error) {\n                span.recordException(reason);\n              } else if (reason) {\n                span.recordException({ message: String(reason), name: 'CancelError' });\n              }\n              span.setStatus({\n                code: SpanStatusCode.ERROR,\n                message: reason instanceof Error ? reason.message : String(reason),\n              });\n              safeEndSpan();\n              await originalReader.cancel(reason);\n            } catch (_err) {\n              // Ignore cancel errors\n            }\n          },\n        });\n\n        return new Response(wrappedStream, {\n          status: result.status,\n          statusText: result.statusText,\n          headers: result.headers,\n        }) as Return;\n      }\n\n      // Auto-detect Vercel AI SDK streaming objects (streamText returns object with textStream)\n      if (result && typeof result === 'object' && 'textStream' in result) {\n        console.warn(\n          '[AxiomAI] Detected streaming object with textStream. For proper span lifecycle, call .toUIMessageStreamResponse() or similar inside withSpan, not after.',\n        );\n        clearTimeout(timeoutId);\n        safeEndSpan(); // End span immediately to prevent memory leak\n        return result;\n      }\n\n      // Non-stream path: end span immediately\n      clearTimeout(timeoutId);\n      span.setStatus({ code: SpanStatusCode.OK });\n      safeEndSpan();\n      return result;\n    } catch (err) {\n      clearTimeout(timeoutId);\n      span.recordException(err as Error);\n      span.setStatus({\n        code: SpanStatusCode.ERROR,\n        message: err instanceof Error ? err.message : String(err),\n      });\n      safeEndSpan();\n      throw err;\n    }\n  });\n}\n","/**\n * Utilities for sanitizing multimodal content in telemetry data\n * Replaces large binary content with metadata while preserving structure\n */\n\nimport { createHash } from 'crypto';\n\ninterface ImageMetadata {\n  format?: string;\n  size_bytes?: number;\n  hash: string;\n  is_data_url: boolean;\n  dimensions?: string;\n}\n\n/**\n * Extracts metadata from an image URL (data URL or external URL)\n */\nfunction extractImageMetadata(url: string): ImageMetadata {\n  if (url.startsWith('data:')) {\n    // Parse data URL: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...\n    const [header, base64Data] = url.split(',');\n    const formatMatch = header.match(/data:image\\/(\\w+)/);\n    const format = formatMatch?.[1];\n\n    // Estimate size from base64 data\n    const sizeBytes = base64Data ? Math.floor((base64Data.length * 3) / 4) : 0;\n\n    // Create a short hash of the content for identification\n    const hash = base64Data\n      ? createHash('sha256').update(base64Data).digest('hex').slice(0, 16)\n      : 'unknown';\n\n    return {\n      format,\n      size_bytes: sizeBytes,\n      hash,\n      is_data_url: true,\n    };\n  } else {\n    // External URL - create hash of the URL itself\n    const hash = createHash('sha256').update(url).digest('hex').slice(0, 16);\n    return {\n      hash,\n      is_data_url: false,\n    };\n  }\n}\n\n/**\n * Sanitizes an image URL by replacing large data URLs with metadata\n */\nfunction sanitizeImageUrl(url: string, detail?: string) {\n  const metadata = extractImageMetadata(url);\n\n  if (metadata.is_data_url) {\n    // Replace data URL with reference\n    const formatPart = metadata.format ? `:${metadata.format}` : '';\n    const sizePart = metadata.size_bytes ? `:${metadata.size_bytes}b` : '';\n    return {\n      url: `[IMAGE${formatPart}${sizePart}:${metadata.hash}]`,\n      detail,\n      ...metadata,\n    };\n  } else {\n    // Keep external URLs but add metadata\n    return {\n      url,\n      detail,\n      ...metadata,\n    };\n  }\n}\n\ntype SanitizedContent<T> = T extends readonly unknown[] ? unknown[] : T;\n\n/**\n * Sanitizes any multimodal content for telemetry purposes\n * This is the main function that should be used throughout the codebase\n */\nexport function sanitizeMultimodalContent<T>(content: T): SanitizedContent<T> {\n  if (Array.isArray(content)) {\n    return content.map((part) => {\n      if (part && typeof part === 'object' && 'type' in part && part.type === 'image_url') {\n        const imagePart = part;\n        if (imagePart.image_url?.url) {\n          return {\n            ...part,\n            image_url: sanitizeImageUrl(imagePart.image_url.url, imagePart.image_url.detail),\n          };\n        }\n      }\n      return part;\n    }) as SanitizedContent<T>;\n  }\n\n  return content as SanitizedContent<T>;\n}\n","/**\n * Utility functions for formatting tool calls in completion array format\n */\n\nimport type { LanguageModelV1FunctionToolCall } from '@ai-sdk/providerv1';\nimport { sanitizeMultimodalContent } from './utils/contentSanitizer';\nimport type {\n  CompletionArray,\n  FormatToolCallsOptions,\n  FormattedCompletionResult,\n} from './completionTypes';\nimport type { OpenAIMessage, OpenAIAssistantMessage, OpenAIToolMessage } from './vercelTypes';\n\n/**\n * Converts OpenAI messages to completion array format\n */\nfunction convertToCompletionMessages(messages: OpenAIMessage[]): OpenAIMessage[] {\n  return messages.map((message): OpenAIMessage => {\n    switch (message.role) {\n      case 'system':\n        return {\n          role: 'system',\n          content: message.content,\n        };\n\n      case 'user':\n        return {\n          role: 'user',\n          content: sanitizeMultimodalContent(message.content) as string | any[],\n        };\n\n      case 'assistant':\n        return {\n          role: 'assistant',\n          content: sanitizeMultimodalContent(message.content) as string | null,\n          tool_calls: message.tool_calls?.map((toolCall) => ({\n            id: toolCall.id,\n            type: 'function' as const,\n            function: {\n              name: toolCall.function.name,\n              arguments: toolCall.function.arguments,\n            },\n          })),\n        };\n\n      case 'tool':\n        return {\n          role: 'tool',\n          content: message.content,\n          tool_call_id: message.tool_call_id,\n        };\n\n      default:\n        throw new Error(`Unknown message role: ${(message as any).role}`);\n    }\n  });\n}\n\n/**\n * Creates tool result messages from tool execution results\n */\nfunction createToolResultMessages(\n  toolResults: Array<{\n    toolCallId: string;\n    result: unknown;\n  }>,\n): OpenAIToolMessage[] {\n  return toolResults.map((result) => ({\n    role: 'tool' as const,\n    content: typeof result.result === 'string' ? result.result : JSON.stringify(result.result),\n    tool_call_id: result.toolCallId,\n  }));\n}\n\n/**\n * Main function to format tool calls in completion array format\n * Transforms AI SDK tool calls into the completion array structure\n */\nexport function formatToolCallsInCompletion(\n  options: FormatToolCallsOptions,\n): FormattedCompletionResult {\n  const { promptMessages = [], text, toolCalls = [], toolResults = [] } = options;\n\n  // Convert prompt messages to completion format\n  const historyMessages = convertToCompletionMessages(promptMessages);\n\n  // Create assistant message with tool calls\n  const assistantMessage: OpenAIAssistantMessage = {\n    role: 'assistant',\n    content: text ?? (toolCalls.length > 0 ? null : ''),\n  };\n\n  // Add tool calls if present\n  if (toolCalls.length > 0) {\n    assistantMessage.tool_calls = toolCalls.map((toolCall) => ({\n      id: toolCall.id,\n      type: 'function' as const,\n      function: {\n        name: toolCall.toolName,\n        arguments: toolCall.args,\n      },\n    }));\n  }\n\n  // Create tool result messages\n  const toolMessages = createToolResultMessages(toolResults);\n\n  // Build complete completion array\n  const completion: CompletionArray = [...historyMessages, assistantMessage, ...toolMessages];\n\n  return {\n    completion,\n    assistantMessage,\n    toolMessages,\n  };\n}\n\n/**\n * Creates a simple completion array with just assistant text response\n * Used for V1 model wrapper where tool calls are handled separately\n */\nexport function createSimpleCompletion({ text }: { text?: string }): CompletionArray {\n  // Create assistant message with text only\n  const assistantMessage: OpenAIAssistantMessage = {\n    role: 'assistant',\n    content: text ?? '',\n  };\n\n  return [assistantMessage];\n}\n\n/**\n * Formats V2 tool calls for completion array\n * Convenience function for V2 model wrapper\n */\nexport function formatV2ToolCallsInCompletion({\n  promptMessages = [],\n  text,\n  toolCalls = [],\n}: {\n  promptMessages?: OpenAIMessage[];\n  text?: string;\n  toolCalls?: Array<{\n    toolCallId: string;\n    toolName: string;\n    args: unknown;\n  }>;\n}): CompletionArray {\n  // Convert prompt messages\n  const historyMessages = convertToCompletionMessages(promptMessages);\n\n  // Create assistant message\n  const assistantMessage: OpenAIAssistantMessage = {\n    role: 'assistant',\n    content: text ?? (toolCalls.length > 0 ? null : ''),\n  };\n\n  // Add tool calls if present\n  if (toolCalls.length > 0) {\n    assistantMessage.tool_calls = toolCalls.map((toolCall) => ({\n      id: toolCall.toolCallId,\n      type: 'function' as const,\n      function: {\n        name: toolCall.toolName,\n        arguments:\n          typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args),\n      },\n    }));\n  }\n\n  return [...historyMessages, assistantMessage];\n}\n\n/**\n * Aggregates tool call chunks for streaming responses\n * Handles partial tool calls and builds complete tool call objects\n */\nexport function aggregateStreamingToolCalls(\n  chunks: Array<{\n    toolCallId?: string;\n    toolName?: string;\n    argsTextDelta?: string;\n  }>,\n): LanguageModelV1FunctionToolCall[] {\n  const toolCallMap = new Map<\n    string,\n    {\n      toolCallId: string;\n      toolName: string;\n      args: string;\n    }\n  >();\n\n  for (const chunk of chunks) {\n    if (!chunk.toolCallId) continue;\n\n    const existing = toolCallMap.get(chunk.toolCallId);\n    if (existing) {\n      // Append args delta\n      existing.args += chunk.argsTextDelta || '';\n    } else {\n      // Create new tool call entry\n      toolCallMap.set(chunk.toolCallId, {\n        toolCallId: chunk.toolCallId,\n        toolName: chunk.toolName || '',\n        args: chunk.argsTextDelta || '',\n      });\n    }\n  }\n\n  return Array.from(toolCallMap.values()).map((call) => ({\n    ...call,\n    toolCallType: 'function' as const,\n  }));\n}\n","import type { LanguageModelV1FunctionToolCall } from '@ai-sdk/providerv1';\nimport type { NormalizedToolCall } from '../otel/utils/normalized';\nimport type { LanguageModelV2Prompt } from '@ai-sdk/providerv2';\nimport type { LanguageModelV3Prompt } from '@ai-sdk/providerv3';\nimport type { OpenAIMessage } from '../otel/vercelTypes';\n\nexport type ToolResultMap = Map<string, unknown>;\n\n/**\n * Appends tool calls and their results to a conversation prompt.\n *\n * This function takes an existing conversation prompt and adds:\n * 1. An assistant message containing the tool calls\n * 2. Tool result messages for each tool call with results\n *\n * @param prompt - The existing conversation prompt\n * @param toolCalls - The tool calls made by the assistant\n * @param toolResults - Map of tool names to their results\n * @param assistantContent - Optional assistant message content to include with tool calls\n * @returns Updated prompt with tool calls and results appended\n */\nexport function appendToolCalls(\n  prompt: OpenAIMessage[],\n  toolCalls: LanguageModelV1FunctionToolCall[] | NormalizedToolCall[],\n  toolResults: ToolResultMap,\n  assistantContent?: string | null,\n): OpenAIMessage[] {\n  const updatedPrompt = [...prompt];\n\n  // Add assistant message with tool calls\n  updatedPrompt.push({\n    role: 'assistant',\n    content: assistantContent || null,\n    tool_calls: toolCalls.map((toolCall) => ({\n      id: toolCall.toolCallId,\n      function: {\n        name: toolCall.toolName,\n        arguments:\n          typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args),\n      },\n      type: 'function',\n    })),\n  });\n\n  // Add tool result messages with real data\n  for (const toolCall of toolCalls) {\n    const realToolResult = toolResults.get(toolCall.toolName);\n\n    if (realToolResult) {\n      updatedPrompt.push({\n        role: 'tool',\n        tool_call_id: toolCall.toolCallId,\n        content: JSON.stringify(realToolResult),\n      });\n    }\n  }\n\n  return updatedPrompt;\n}\n\n/**\n * Extracts tool results from a raw prompt array.\n *\n * Searches through different message formats to find tool results:\n * - Google AI format: user messages with functionResponse parts\n * - OpenAI format: tool role messages (future enhancement)\n *\n * @param rawPrompt - The raw prompt array from the model provider\n * @returns Map of tool names to their results\n */\n// TODO: @cje - This should be typed based on the specific provider's raw prompt format\n// but it needs to handle multiple providers (Google AI, OpenAI, etc.)\nexport function extractToolResultsFromRawPrompt(rawPrompt: any[]): Map<string, unknown> {\n  const toolResultsMap = new Map<string, unknown>();\n\n  if (!Array.isArray(rawPrompt)) {\n    return toolResultsMap;\n  }\n\n  // Look for tool results in different message formats\n  for (const message of rawPrompt) {\n    // Google AI format: user message with functionResponse parts\n    if (message?.role === 'user' && Array.isArray(message.parts)) {\n      for (const part of message.parts) {\n        if (part?.functionResponse) {\n          const functionResponse = part.functionResponse;\n          if (functionResponse.name && functionResponse.response) {\n            // Store by function name since that's what we have access to\n            toolResultsMap.set(\n              functionResponse.name,\n              functionResponse.response.content || functionResponse.response,\n            );\n          }\n        }\n      }\n    }\n\n    // OpenAI format: tool role messages with tool_call_id\n    if (message?.role === 'tool' && message?.tool_call_id && message?.content) {\n      // For OpenAI format, we'd need to map back from tool_call_id to tool name\n      // This is more complex as we'd need to track the tool calls first\n      // For now, we'll skip this but it could be implemented later\n    }\n  }\n\n  return toolResultsMap;\n}\n\n/**\n * Extracts tool results from a V2 prompt structure.\n *\n * V2 prompts use a \"parts\" array structure where:\n * - Tool calls are in assistant messages as 'tool-call' parts\n * - Tool results are in 'tool' role messages as 'tool-result' parts with 'output' property\n *\n * @param prompt - The V2 prompt array\n * @returns Map of tool names to their results\n */\nexport function extractToolResultsFromPromptV2(\n  prompt: LanguageModelV2Prompt,\n): Map<string, unknown> {\n  const idToName = new Map<string, string>();\n  const results = new Map<string, unknown>();\n\n  // 1. Collect tool-call ids → names from assistant messages\n  for (const message of prompt) {\n    if (message.role === 'assistant' && Array.isArray(message.content)) {\n      for (const part of message.content) {\n        if (part.type === 'tool-call') {\n          idToName.set(part.toolCallId, part.toolName);\n        }\n      }\n    }\n  }\n\n  // 2. Collect tool results from tool role messages\n  for (const message of prompt) {\n    if (message.role === 'tool' && Array.isArray(message.content)) {\n      for (const part of message.content) {\n        // In V2, tool result parts have toolCallId and result properties\n        if (part.toolCallId && part.output !== undefined) {\n          const toolName = idToName.get(part.toolCallId);\n          if (toolName) {\n            results.set(toolName, part.output);\n          }\n        }\n      }\n    }\n  }\n\n  return results;\n}\n\n/**\n * Extracts tool results from a V3 prompt structure.\n *\n * V3 prompts are very similar to V2 but with slightly different typing:\n * - Tool calls are in assistant messages as 'tool-call' parts\n * - Tool results are in 'tool' role messages as 'tool-result' parts with 'output' property\n * - Also includes 'tool-approval-response' parts which we skip\n *\n * @param prompt - The V3 prompt array\n * @returns Map of tool names to their results\n */\nexport function extractToolResultsFromPromptV3(\n  prompt: LanguageModelV3Prompt,\n): Map<string, unknown> {\n  const idToName = new Map<string, string>();\n  const results = new Map<string, unknown>();\n\n  // 1. Collect tool-call ids → names from assistant messages\n  for (const message of prompt) {\n    if (message.role === 'assistant' && Array.isArray(message.content)) {\n      for (const part of message.content) {\n        if (part.type === 'tool-call') {\n          idToName.set(part.toolCallId, part.toolName);\n        }\n      }\n    }\n  }\n\n  // 2. Collect tool results from tool role messages\n  for (const message of prompt) {\n    if (message.role === 'tool' && Array.isArray(message.content)) {\n      for (const part of message.content) {\n        // In V3, tool result parts have toolCallId and output properties\n        // Skip tool-approval-response parts\n        if (part.type === 'tool-result' && part.toolCallId && part.output !== undefined) {\n          const toolName = idToName.get(part.toolCallId);\n          if (toolName) {\n            results.set(toolName, part.output);\n          }\n        }\n      }\n    }\n  }\n\n  return results;\n}\n","import type {\n  LanguageModelV1Prompt,\n  LanguageModelV1FunctionToolCall,\n  LanguageModelV1TextPart,\n  LanguageModelV1ToolCallPart,\n} from '@ai-sdk/providerv1';\nimport type {\n  LanguageModelV2Prompt,\n  LanguageModelV2ToolCall,\n  LanguageModelV2TextPart,\n  LanguageModelV2ToolCallPart,\n  LanguageModelV2ToolResultOutput,\n} from '@ai-sdk/providerv2';\nimport type {\n  LanguageModelV3Prompt,\n  LanguageModelV3ToolCall,\n  LanguageModelV3TextPart,\n  LanguageModelV3ToolCallPart,\n  LanguageModelV3ToolResultOutput,\n} from '@ai-sdk/providerv3';\nimport type { OpenAIMessage, OpenAIContentPart } from '../vercelTypes';\n\n/**\n * Normalized tool call interface that can represent both V1 and V2 tool calls\n */\nexport interface NormalizedToolCall {\n  toolCallId: string;\n  toolName: string;\n  args: string; // Always a JSON string for consistency\n  toolCallType: 'function';\n}\n\n/**\n * Normalized result interface for both V1 and V2 generation results\n */\nexport interface NormalizedResult {\n  text?: string;\n  toolCalls?: NormalizedToolCall[];\n  response?: { id?: string; modelId?: string };\n  usage?: {\n    promptTokens?: number;\n    completionTokens?: number;\n    inputTokens?: number;\n    outputTokens?: number;\n  };\n  finishReason?: string;\n}\n\n/**\n * Normalizes a V1 tool call to the common format\n */\nfunction normalizeV1ToolCall(toolCall: LanguageModelV1FunctionToolCall): NormalizedToolCall {\n  return {\n    toolCallId: toolCall.toolCallId,\n    toolName: toolCall.toolName,\n    args: typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args),\n    toolCallType: 'function',\n  };\n}\n\n/**\n * Normalizes a V2 tool call to the common format\n */\nfunction normalizeV2ToolCall(toolCall: LanguageModelV2ToolCall): NormalizedToolCall {\n  return {\n    toolCallId: toolCall.toolCallId,\n    toolName: toolCall.toolName,\n    args:\n      typeof toolCall.input === 'string'\n        ? toolCall.input.replace(/:\\s+/g, ':')\n        : JSON.stringify(toolCall.input),\n    toolCallType: 'function',\n  };\n}\n\n/**\n * Normalizes an array of V1 tool calls\n */\nexport function normalizeV1ToolCalls(\n  toolCalls: LanguageModelV1FunctionToolCall[],\n): NormalizedToolCall[] {\n  return toolCalls.map(normalizeV1ToolCall);\n}\n\n/**\n * Normalizes an array of V2 tool calls\n */\nexport function normalizeV2ToolCalls(toolCalls: LanguageModelV2ToolCall[]): NormalizedToolCall[] {\n  return toolCalls.map(normalizeV2ToolCall);\n}\n\n/**\n * Normalizes a V3 tool call to the common format\n * V3 tool calls use `input` as a JSON string (similar to V2 but always string)\n */\nfunction normalizeV3ToolCall(toolCall: LanguageModelV3ToolCall): NormalizedToolCall {\n  return {\n    toolCallId: toolCall.toolCallId,\n    toolName: toolCall.toolName,\n    args: toolCall.input, // V3 input is always a string\n    toolCallType: 'function',\n  };\n}\n\n/**\n * Normalizes an array of V3 tool calls\n */\nexport function normalizeV3ToolCalls(toolCalls: LanguageModelV3ToolCall[]): NormalizedToolCall[] {\n  return toolCalls.map(normalizeV3ToolCall);\n}\n\n/**\n * Converts a V1 prompt to OpenAI message format\n */\nexport function promptV1ToOpenAI(prompt: LanguageModelV1Prompt): OpenAIMessage[] {\n  const results: OpenAIMessage[] = [];\n\n  for (const message of prompt) {\n    switch (message.role) {\n      case 'system':\n        results.push({\n          role: 'system',\n          content: message.content,\n        });\n        break;\n\n      case 'assistant':\n        const textPart = message.content.find((part) => part.type === 'text') as\n          | LanguageModelV1TextPart\n          | undefined;\n        const toolCallParts = message.content.filter(\n          (part) => part.type === 'tool-call',\n        ) as LanguageModelV1ToolCallPart[];\n\n        results.push({\n          role: 'assistant',\n          content: textPart?.text || null,\n          ...(toolCallParts.length > 0\n            ? {\n                tool_calls: toolCallParts.map((part) => ({\n                  id: part.toolCallId,\n                  function: {\n                    name: part.toolName,\n                    arguments: JSON.stringify(part.args),\n                  },\n                  type: 'function',\n                })),\n              }\n            : {}),\n        });\n        break;\n\n      case 'user':\n        results.push({\n          role: 'user',\n          content: message.content.map((part): OpenAIContentPart => {\n            switch (part.type) {\n              case 'text':\n                return {\n                  type: 'text',\n                  text: part.text,\n                };\n              case 'image':\n                return {\n                  type: 'image_url',\n                  image_url: {\n                    url: part.image.toString(),\n                  },\n                };\n              default:\n                // Convert unknown content types to text for compatibility\n                return {\n                  type: 'text',\n                  text:\n                    `[${part.type}]` +\n                    (typeof part === 'object' && part !== null\n                      ? JSON.stringify(part)\n                      : String(part)),\n                };\n            }\n          }),\n        });\n        break;\n\n      case 'tool':\n        for (const part of message.content) {\n          results.push({\n            role: 'tool',\n            tool_call_id: part.toolCallId,\n            content: JSON.stringify(part.result),\n          });\n        }\n        break;\n    }\n  }\n\n  return results;\n}\n\n/**\n * Converts a V2 prompt to OpenAI message format\n */\nexport function promptV2ToOpenAI(prompt: LanguageModelV2Prompt): OpenAIMessage[] {\n  const results: OpenAIMessage[] = [];\n\n  for (const message of prompt) {\n    switch (message.role) {\n      case 'system':\n        results.push({\n          role: 'system',\n          content: message.content,\n        });\n        break;\n\n      case 'assistant':\n        const textContent = message.content.find(\n          (part): part is LanguageModelV2TextPart => part.type === 'text',\n        );\n        const toolCalls = message.content.filter(\n          (part): part is LanguageModelV2ToolCallPart => part.type === 'tool-call',\n        );\n\n        results.push({\n          role: 'assistant',\n          content: textContent?.text || null,\n          ...(toolCalls.length > 0\n            ? {\n                tool_calls: toolCalls.map((part) => ({\n                  id: part.toolCallId,\n                  function: {\n                    name: part.toolName,\n                    arguments:\n                      typeof part.input === 'string' ? part.input : JSON.stringify(part.input),\n                  },\n                  type: 'function',\n                })),\n              }\n            : {}),\n        });\n        break;\n\n      case 'user':\n        results.push({\n          role: 'user',\n          content: message.content.map((part: any) => {\n            switch (part.type) {\n              case 'text':\n                return {\n                  type: 'text',\n                  text: part.text,\n                };\n              case 'image':\n                return {\n                  type: 'image_url',\n                  image_url: {\n                    url: part.image.toString(),\n                  },\n                };\n              default:\n                // Handle unknown content types by passing them through\n                return part as any;\n            }\n          }),\n        });\n        break;\n\n      case 'tool':\n        for (const part of message.content) {\n          results.push({\n            role: 'tool',\n            tool_call_id: part.toolCallId,\n            content: formatV2ToolCallOutput(part.output),\n          });\n        }\n        break;\n    }\n  }\n\n  return results;\n}\n\nfunction formatV2ToolCallOutput(output: LanguageModelV2ToolResultOutput) {\n  switch (output.type) {\n    case 'text':\n      return output.value;\n    case 'json':\n      return typeof output.value === 'string' ? output.value : JSON.stringify(output.value);\n    case 'error-text':\n      return output.value;\n    case 'error-json':\n      return typeof output.value === 'string' ? output.value : JSON.stringify(output.value);\n    case 'content':\n      return JSON.stringify(output.value);\n  }\n}\n\n/**\n * Converts a V3 prompt to OpenAI message format\n * V3 is very similar to V2 but with slightly different type structure\n */\nexport function promptV3ToOpenAI(prompt: LanguageModelV3Prompt): OpenAIMessage[] {\n  const results: OpenAIMessage[] = [];\n\n  for (const message of prompt) {\n    switch (message.role) {\n      case 'system':\n        results.push({\n          role: 'system',\n          content: message.content,\n        });\n        break;\n\n      case 'assistant':\n        const textContent = message.content.find(\n          (part): part is LanguageModelV3TextPart => part.type === 'text',\n        );\n        const toolCalls = message.content.filter(\n          (part): part is LanguageModelV3ToolCallPart => part.type === 'tool-call',\n        );\n\n        results.push({\n          role: 'assistant',\n          content: textContent?.text || null,\n          ...(toolCalls.length > 0\n            ? {\n                tool_calls: toolCalls.map((part) => ({\n                  id: part.toolCallId,\n                  function: {\n                    name: part.toolName,\n                    // V3 input can be unknown (usually object), convert to string\n                    arguments:\n                      typeof part.input === 'string' ? part.input : JSON.stringify(part.input),\n                  },\n                  type: 'function',\n                })),\n              }\n            : {}),\n        });\n        break;\n\n      case 'user':\n        results.push({\n          role: 'user',\n          content: message.content.map((part: any) => {\n            switch (part.type) {\n              case 'text':\n                return {\n                  type: 'text',\n                  text: part.text,\n                };\n              case 'file':\n                // V3 files - represent as text with media type info\n                return {\n                  type: 'text',\n                  text: `[file: ${part.mediaType}]`,\n                };\n              default:\n                // Handle unknown content types by passing them through\n                return part as any;\n            }\n          }),\n        });\n        break;\n\n      case 'tool':\n        for (const part of message.content) {\n          // Skip tool-approval-response parts - they don't have output\n          if (part.type === 'tool-result') {\n            results.push({\n              role: 'tool',\n              tool_call_id: part.toolCallId,\n              content: formatV3ToolCallOutput(part.output),\n            });\n          }\n        }\n        break;\n    }\n  }\n\n  return results;\n}\n\nfunction formatV3ToolCallOutput(output: LanguageModelV3ToolResultOutput) {\n  switch (output.type) {\n    case 'text':\n      return output.value;\n    case 'json':\n      return typeof output.value === 'string' ? output.value : JSON.stringify(output.value);\n    case 'error-text':\n      return output.value;\n    case 'error-json':\n      return typeof output.value === 'string' ? output.value : JSON.stringify(output.value);\n    case 'content':\n      return JSON.stringify(output.value);\n    case 'execution-denied':\n      return output.reason ?? 'Execution denied';\n  }\n}\n","export function currentUnixTime(): number {\n  return Date.now() / 1000;\n}\n","import {\n  type LanguageModelV1StreamPart,\n  type LanguageModelV1FunctionToolCall,\n  type LanguageModelV1FinishReason,\n} from '@ai-sdk/providerv1';\n\nimport {\n  type LanguageModelV2StreamPart,\n  type LanguageModelV2ToolCall,\n  type LanguageModelV2FinishReason,\n  type LanguageModelV2Usage,\n  type LanguageModelV2ResponseMetadata,\n} from '@ai-sdk/providerv2';\n\nimport {\n  type LanguageModelV3StreamPart,\n  type LanguageModelV3ToolCall,\n  type LanguageModelV3FinishReason,\n  type LanguageModelV3Usage,\n  type LanguageModelV3ResponseMetadata,\n} from '@ai-sdk/providerv3';\n\nimport { currentUnixTime } from '../../util/currentUnixTime';\n\n// V1-specific aggregators (the original ones)\nexport class ToolCallAggregator {\n  private readonly calls: Record<string, LanguageModelV1FunctionToolCall> = {};\n\n  handleChunk(chunk: LanguageModelV1StreamPart): void {\n    switch (chunk.type) {\n      case 'tool-call':\n        this.calls[chunk.toolCallId] = {\n          toolCallType: chunk.toolCallType,\n          toolCallId: chunk.toolCallId,\n          toolName: chunk.toolName,\n          args: chunk.args,\n        };\n        break;\n      case 'tool-call-delta':\n        if (!this.calls[chunk.toolCallId]) {\n          this.calls[chunk.toolCallId] = {\n            toolCallType: chunk.toolCallType,\n            toolCallId: chunk.toolCallId,\n            toolName: chunk.toolName,\n            args: '',\n          };\n        }\n        this.calls[chunk.toolCallId].args += chunk.argsTextDelta;\n        break;\n    }\n  }\n\n  get result(): LanguageModelV1FunctionToolCall[] {\n    return Object.values(this.calls);\n  }\n}\n\nexport class TextAggregator {\n  private content = '';\n\n  feed(chunk: LanguageModelV1StreamPart): void {\n    if (chunk.type === 'text-delta') {\n      this.content += chunk.textDelta;\n    }\n  }\n\n  get text(): string | undefined {\n    return this.content || undefined;\n  }\n}\n\nexport class StreamStats {\n  private startTime: number;\n  private timeToFirstToken?: number;\n  private _usage?: { promptTokens: number; completionTokens: number };\n  private _finishReason?: LanguageModelV1FinishReason;\n  private _responseId?: string;\n  private _responseModelId?: string;\n\n  constructor() {\n    this.startTime = currentUnixTime();\n  }\n\n  feed(chunk: LanguageModelV1StreamPart): void {\n    // Track time to first token on any chunk\n    if (this.timeToFirstToken === undefined) {\n      this.timeToFirstToken = currentUnixTime() - this.startTime;\n    }\n\n    switch (chunk.type) {\n      case 'response-metadata':\n        if (chunk.id) {\n          this._responseId = chunk.id;\n        }\n        if (chunk.modelId) {\n          this._responseModelId = chunk.modelId;\n        }\n\n        break;\n      case 'finish':\n        this._usage = chunk.usage;\n        this._finishReason = chunk.finishReason;\n        break;\n    }\n  }\n\n  get result() {\n    return {\n      response:\n        this._responseId || this._responseModelId\n          ? {\n              id: this._responseId,\n              modelId: this._responseModelId,\n            }\n          : undefined,\n      finishReason: this._finishReason,\n      usage: this._usage,\n    };\n  }\n\n  get firstTokenTime(): number | undefined {\n    return this.timeToFirstToken;\n  }\n}\n\n// V2-specific aggregators\nexport class ToolCallAggregatorV2 {\n  private readonly calls: Record<string, LanguageModelV2ToolCall> = {};\n\n  handleChunk(chunk: LanguageModelV2StreamPart): void {\n    if (chunk.type === 'tool-call') {\n      this.calls[chunk.toolCallId] = chunk;\n    }\n  }\n\n  get result(): LanguageModelV2ToolCall[] {\n    return Object.values(this.calls);\n  }\n}\n\nexport class TextAggregatorV2 {\n  private content = '';\n\n  feed(chunk: LanguageModelV2StreamPart): void {\n    // TODO: @cje - is this enough?\n    switch (chunk.type) {\n      case 'text-start':\n        this.content = '';\n        break;\n      case 'text-delta':\n        this.content += chunk.delta;\n        break;\n      case 'text-end':\n        break;\n    }\n  }\n\n  get text(): string | undefined {\n    return this.content || undefined;\n  }\n}\n\nexport class StreamStatsV2 {\n  private startTime: number;\n  private timeToFirstToken?: number;\n  private _usage?: LanguageModelV2Usage;\n  private _finishReason?: LanguageModelV2FinishReason;\n  private _responseMetadata?: LanguageModelV2ResponseMetadata;\n\n  constructor() {\n    this.startTime = currentUnixTime();\n  }\n\n  feed(chunk: LanguageModelV2StreamPart): void {\n    // Track time to first token on any chunk\n    if (this.timeToFirstToken === undefined) {\n      this.timeToFirstToken = currentUnixTime() - this.startTime;\n    }\n\n    switch (chunk.type) {\n      case 'response-metadata':\n        this._responseMetadata = {\n          id: chunk.id,\n          modelId: chunk.modelId,\n          timestamp: chunk.timestamp,\n        };\n        break;\n      case 'finish':\n        this._usage = chunk.usage;\n        this._finishReason = chunk.finishReason;\n        break;\n    }\n  }\n\n  get result() {\n    return {\n      response: this._responseMetadata,\n      finishReason: this._finishReason,\n      usage: this._usage,\n    };\n  }\n\n  get firstTokenTime(): number | undefined {\n    return this.timeToFirstToken;\n  }\n}\n\n// V3-specific aggregators\nexport class ToolCallAggregatorV3 {\n  private readonly calls: Record<string, LanguageModelV3ToolCall> = {};\n  private readonly pendingInputs: Record<string, { toolName: string; input: string }> = {};\n\n  handleChunk(chunk: LanguageModelV3StreamPart): void {\n    switch (chunk.type) {\n      case 'tool-call':\n        this.calls[chunk.toolCallId] = chunk;\n        break;\n      case 'tool-input-start':\n        this.pendingInputs[chunk.id] = { toolName: chunk.toolName, input: '' };\n        break;\n      case 'tool-input-delta':\n        if (this.pendingInputs[chunk.id]) {\n          this.pendingInputs[chunk.id].input += chunk.delta;\n        }\n        break;\n      case 'tool-input-end':\n        // Tool input streaming completed - the full tool-call chunk will follow\n        break;\n    }\n  }\n\n  get result(): LanguageModelV3ToolCall[] {\n    return Object.values(this.calls);\n  }\n}\n\nexport class TextAggregatorV3 {\n  private content = '';\n\n  feed(chunk: LanguageModelV3StreamPart): void {\n    switch (chunk.type) {\n      case 'text-start':\n        this.content = '';\n        break;\n      case 'text-delta':\n        this.content += chunk.delta;\n        break;\n      case 'text-end':\n        break;\n    }\n  }\n\n  get text(): string | undefined {\n    return this.content || undefined;\n  }\n}\n\nexport class StreamStatsV3 {\n  private startTime: number;\n  private timeToFirstToken?: number;\n  private _usage?: LanguageModelV3Usage;\n  private _finishReason?: LanguageModelV3FinishReason;\n  private _responseMetadata?: LanguageModelV3ResponseMetadata;\n\n  constructor() {\n    this.startTime = currentUnixTime();\n  }\n\n  feed(chunk: LanguageModelV3StreamPart): void {\n    // Track time to first token on any chunk\n    if (this.timeToFirstToken === undefined) {\n      this.timeToFirstToken = currentUnixTime() - this.startTime;\n    }\n\n    switch (chunk.type) {\n      case 'response-metadata':\n        this._responseMetadata = {\n          id: chunk.id,\n          modelId: chunk.modelId,\n          timestamp: chunk.timestamp,\n        };\n        break;\n      case 'finish':\n        this._usage = chunk.usage;\n        this._finishReason = chunk.finishReason;\n        break;\n    }\n  }\n\n  get result() {\n    return {\n      response: this._responseMetadata,\n      finishReason: this._finishReason,\n      usage: this._usage,\n    };\n  }\n\n  get firstTokenTime(): number | undefined {\n    return this.timeToFirstToken;\n  }\n}\n","import {\n  type LanguageModelV1,\n  type LanguageModelV1CallOptions,\n  type LanguageModelV1Prompt,\n  type LanguageModelV1StreamPart,\n} from '@ai-sdk/providerv1';\nimport {\n  type LanguageModelV2,\n  type LanguageModelV2CallOptions,\n  type LanguageModelV2Middleware,\n  type LanguageModelV2StreamPart,\n  type LanguageModelV2Content,\n  type LanguageModelV2ToolCall,\n  type LanguageModelV2Usage,\n  type LanguageModelV2ResponseMetadata,\n  type LanguageModelV2FinishReason,\n  type LanguageModelV2Prompt,\n} from '@ai-sdk/providerv2';\nimport {\n  type LanguageModelV3,\n  type LanguageModelV3CallOptions,\n  type LanguageModelV3Middleware,\n  type LanguageModelV3StreamPart,\n  type LanguageModelV3Content,\n  type LanguageModelV3ToolCall,\n  type LanguageModelV3Usage,\n  type LanguageModelV3ResponseMetadata,\n  type LanguageModelV3FinishReason,\n  type LanguageModelV3Prompt,\n} from '@ai-sdk/providerv3';\nimport { type LanguageModelV1Middleware } from 'aiv4';\n\nimport { type Span } from '@opentelemetry/api';\nimport { Attr } from './semconv/attributes';\nimport { createSimpleCompletion } from './completionUtils';\nimport {\n  appendToolCalls,\n  extractToolResultsFromPromptV2,\n  extractToolResultsFromPromptV3,\n  extractToolResultsFromRawPrompt,\n} from '../util/promptUtils';\nimport { sanitizeMultimodalContent } from './utils/contentSanitizer';\nimport {\n  setScopeAttributes,\n  setBaseAttributes,\n  setRequestParameterAttributes,\n  withSpanHandling,\n  determineOutputTypeV1,\n  determineOutputTypeV2,\n  determineOutputTypeV3,\n  classifyToolError,\n  createStreamChildSpan,\n  ensureNumber,\n  type GenAiSpanContextV1,\n  type GenAiSpanContextV2,\n  type GenAiSpanContextV3,\n} from './utils/wrapperUtils';\nimport {\n  promptV1ToOpenAI,\n  promptV2ToOpenAI,\n  promptV3ToOpenAI,\n  normalizeV1ToolCalls,\n  normalizeV2ToolCalls,\n  normalizeV3ToolCalls,\n} from './utils/normalized';\nimport {\n  ToolCallAggregator,\n  TextAggregator,\n  StreamStats,\n  ToolCallAggregatorV2,\n  TextAggregatorV2,\n  StreamStatsV2,\n  ToolCallAggregatorV3,\n  TextAggregatorV3,\n  StreamStatsV3,\n} from './streaming/aggregators';\nimport type { AxiomPromptMetadata } from '../types/metadata';\nimport { getRedactionPolicy, handleMaybeRedactedAttribute } from './utils/redaction';\n\nexport interface AxiomTelemetryConfig {\n  // Future configuration options can be added here\n}\n\nconst appendPromptMetadataToSpan = (\n  span: Span,\n  messages: LanguageModelV1Prompt | LanguageModelV2Prompt | LanguageModelV3Prompt,\n) => {\n  const lastMessage = messages?.[messages.length - 1];\n\n  let axiomMeta: AxiomPromptMetadata | undefined;\n\n  if ('providerMetadata' in lastMessage) {\n    axiomMeta = lastMessage?.providerMetadata?._axiomMeta as AxiomPromptMetadata | undefined;\n  } else if ('providerOptions' in lastMessage) {\n    axiomMeta = lastMessage?.providerOptions?._axiomMeta as AxiomPromptMetadata | undefined;\n  }\n\n  if (axiomMeta) {\n    if (axiomMeta.id) span.setAttribute(Attr.GenAI.PromptMetadata.ID, axiomMeta.id);\n    if (axiomMeta.name) span.setAttribute(Attr.GenAI.PromptMetadata.Name, axiomMeta.name);\n    if (axiomMeta.slug) span.setAttribute(Attr.GenAI.PromptMetadata.Slug, axiomMeta.slug);\n    if (axiomMeta.version) span.setAttribute(Attr.GenAI.PromptMetadata.Version, axiomMeta.version);\n  }\n};\n\n/**\n * Creates Axiom telemetry middleware for LanguageModelV1\n */\nexport function axiomAIMiddlewareV1(/* _config?: AxiomTelemetryConfig */): LanguageModelV1Middleware {\n  return {\n    wrapGenerate: async ({ doGenerate, params, model }) => {\n      return withSpanHandling(\n        model.modelId,\n        async (span, commonContext, _lease) => {\n          const context = commonContext as GenAiSpanContextV1;\n\n          appendPromptMetadataToSpan(span, params.prompt);\n\n          // Pre-call setup\n          setScopeAttributes(span);\n          setPreCallAttributesV1(span, params, context, model);\n\n          const res = await doGenerate();\n\n          // Store rawCall data in context for access in post-call processing\n          context.rawCall = res.rawCall as { rawPrompt?: any[]; rawSettings?: any };\n\n          // Post-call processing\n          await setPostCallAttributesV1(span, res, context, model);\n\n          return res;\n        },\n        { version: 'v1' },\n      );\n    },\n\n    wrapStream: async ({ doStream, params, model }) => {\n      return withSpanHandling(\n        model.modelId,\n        async (span, commonContext, lease) => {\n          const context = commonContext as GenAiSpanContextV1;\n\n          appendPromptMetadataToSpan(span, params.prompt);\n\n          // Pre-call setup\n          setScopeAttributes(span);\n          setPreCallAttributesV1(span, params, context, model);\n\n          const { stream, ...head } = await doStream();\n\n          // Create child span for stream processing (provides granular visibility)\n          const childSpan = createStreamChildSpan(span, `chat ${model.modelId} stream`);\n\n          const stats = new StreamStats();\n          const toolAggregator = new ToolCallAggregator();\n          const textAggregator = new TextAggregator();\n\n          return {\n            ...head,\n            stream: stream.pipeThrough(\n              new TransformStream({\n                transform(chunk: LanguageModelV1StreamPart, controller) {\n                  try {\n                    stats.feed(chunk);\n                    toolAggregator.handleChunk(chunk);\n                    textAggregator.feed(chunk);\n\n                    controller.enqueue(chunk);\n                  } catch (err) {\n                    classifyToolError(err, childSpan);\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.error(err);\n                  }\n                },\n                async flush(controller) {\n                  try {\n                    await setPostCallAttributesV1(\n                      span,\n                      {\n                        ...head,\n                        ...stats.result,\n                        toolCalls:\n                          toolAggregator.result.length > 0 ? toolAggregator.result : undefined,\n                        text: textAggregator.text,\n                      },\n                      context,\n                      model,\n                    );\n\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.terminate();\n                  } catch (err) {\n                    classifyToolError(err, childSpan);\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.error(err);\n                  }\n                },\n              }),\n            ),\n          };\n        },\n        { streaming: true, version: 'v1' }, // Don't auto-end span, we'll end it when stream completes\n      );\n    },\n  };\n}\n\n/**\n * Creates unified Axiom telemetry middleware that works with V1, V2 and V3 models\n */\nexport function axiomAIMiddleware(config: { model: LanguageModelV1 }): LanguageModelV1Middleware;\nexport function axiomAIMiddleware(config: { model: LanguageModelV2 }): LanguageModelV2Middleware;\nexport function axiomAIMiddleware(config: { model: LanguageModelV3 }): LanguageModelV3Middleware;\nexport function axiomAIMiddleware(config: {\n  model: LanguageModelV1 | LanguageModelV2 | LanguageModelV3;\n}) {\n  if (config.model.specificationVersion === 'v1') {\n    return axiomAIMiddlewareV1();\n  } else if (config.model.specificationVersion === 'v2') {\n    return axiomAIMiddlewareV2();\n  } else if (config.model.specificationVersion === 'v3') {\n    return axiomAIMiddlewareV3();\n  } else {\n    console.warn(\n      // @ts-expect-error - not allowed at type level, but users can still do it...\n      `Unsupported model specification version: ${JSON.stringify(config.model.specificationVersion)}. Creating no-op middleware instead.`,\n    );\n    return {};\n  }\n}\n\n/**\n * Creates Axiom telemetry middleware for LanguageModelV2\n */\nexport function axiomAIMiddlewareV2(/* _config?: AxiomTelemetryConfig */): LanguageModelV2Middleware {\n  return {\n    wrapGenerate: async ({ doGenerate, params, model }) => {\n      return withSpanHandling(\n        model.modelId,\n        async (span, commonContext, _lease) => {\n          const context = commonContext as GenAiSpanContextV2;\n\n          appendPromptMetadataToSpan(span, params.prompt);\n\n          // Pre-call setup\n          setScopeAttributes(span);\n          setPreCallAttributesV2(span, params, context, model);\n\n          const res = await doGenerate();\n\n          // Post-call processing\n          await setPostCallAttributesV2(span, res, context, model);\n\n          return res;\n        },\n        { version: 'v2' },\n      );\n    },\n\n    wrapStream: async ({ doStream, params, model }) => {\n      return withSpanHandling(\n        model.modelId,\n        async (span, commonContext, lease) => {\n          const context = commonContext as GenAiSpanContextV2;\n\n          appendPromptMetadataToSpan(span, params.prompt);\n\n          // Pre-call setup\n          setScopeAttributes(span);\n          setPreCallAttributesV2(span, params, context, model);\n\n          const ret = await doStream();\n\n          // Create child span for stream processing (provides granular visibility)\n          const childSpan = createStreamChildSpan(span, `chat ${model.modelId} stream`);\n\n          const stats = new StreamStatsV2();\n          const toolAggregator = new ToolCallAggregatorV2();\n          const textAggregator = new TextAggregatorV2();\n\n          return {\n            ...ret,\n            stream: ret.stream.pipeThrough(\n              new TransformStream({\n                transform(chunk: LanguageModelV2StreamPart, controller) {\n                  try {\n                    stats.feed(chunk);\n                    toolAggregator.handleChunk(chunk);\n                    textAggregator.feed(chunk);\n\n                    controller.enqueue(chunk);\n                  } catch (err) {\n                    classifyToolError(err, childSpan);\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.error(err);\n                  }\n                },\n                async flush(controller) {\n                  try {\n                    const streamResult = {\n                      ...stats.result,\n                      content: [\n                        ...(textAggregator.text\n                          ? [{ type: 'text' as const, text: textAggregator.text }]\n                          : []),\n                        ...toolAggregator.result,\n                      ],\n                    };\n\n                    await setPostCallAttributesV2(span, streamResult, context, model);\n\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.terminate();\n                  } catch (err) {\n                    classifyToolError(err, childSpan);\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.error(err);\n                  }\n                },\n              }),\n            ),\n          };\n        },\n        { streaming: true, version: 'v2' }, // Don't auto-end span, we'll end it when stream completes\n      );\n    },\n  };\n}\n\n// V1 helper functions (extracted from AxiomWrappedLanguageModelV1)\nfunction setPreCallAttributesV1(\n  span: Span,\n  options: LanguageModelV1CallOptions,\n  context: GenAiSpanContextV1,\n  model: LanguageModelV1,\n) {\n  const redactionPolicy = getRedactionPolicy();\n\n  const {\n    prompt,\n    maxTokens,\n    frequencyPenalty,\n    presencePenalty,\n    temperature,\n    topP,\n    topK,\n    seed,\n    stopSequences,\n    responseFormat,\n    mode,\n  } = options;\n\n  // Set prompt attributes (full conversation history)\n  const processedPrompt = promptV1ToOpenAI(prompt);\n  context.originalPrompt = processedPrompt;\n\n  handleMaybeRedactedAttribute(\n    span,\n    Attr.GenAI.Input.Messages,\n    JSON.stringify(sanitizeMultimodalContent(processedPrompt)),\n    redactionPolicy.captureMessageContent,\n  );\n\n  setBaseAttributes(span, model.provider, model.modelId);\n\n  const outputType = determineOutputTypeV1({ responseFormat, mode });\n  if (outputType) {\n    span.setAttribute(Attr.GenAI.Output.Type, outputType);\n  }\n\n  setRequestParameterAttributes(span, {\n    maxTokens,\n    frequencyPenalty,\n    presencePenalty,\n    temperature,\n    topP,\n    topK,\n    seed,\n    stopSequences,\n  });\n}\n\nasync function setPostCallAttributesV1(\n  span: Span,\n  result: any,\n  context: GenAiSpanContextV1,\n  _model: LanguageModelV1,\n) {\n  const redactionPolicy = getRedactionPolicy();\n\n  // Update prompt to include tool calls and tool results if they exist\n  if (result.toolCalls && result.toolCalls.length > 0) {\n    const originalPrompt = context.originalPrompt || [];\n\n    // Normalize the tool calls to the common format\n    const normalizedToolCalls = normalizeV1ToolCalls(result.toolCalls);\n\n    // Note: rawCall might not be available in middleware, handle gracefully\n    const toolResultsMap = context.rawCall?.rawPrompt\n      ? extractToolResultsFromRawPrompt(context.rawCall.rawPrompt as any[])\n      : new Map();\n\n    const updatedPrompt = appendToolCalls(\n      originalPrompt,\n      normalizedToolCalls,\n      toolResultsMap,\n      result.text,\n    );\n\n    handleMaybeRedactedAttribute(\n      span,\n      Attr.GenAI.Input.Messages,\n      JSON.stringify(sanitizeMultimodalContent(updatedPrompt)),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n\n  // Create simple completion array with just assistant text\n  if (result.text) {\n    const completion = createSimpleCompletion({\n      text: result.text,\n    });\n    handleMaybeRedactedAttribute(\n      span,\n      Attr.GenAI.Output.Messages,\n      JSON.stringify(completion),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n\n  if (result.response?.id) {\n    span.setAttribute(Attr.GenAI.Response.ID, result.response.id);\n  }\n  if (result.response?.modelId) {\n    span.setAttribute(Attr.GenAI.Response.Model, result.response.modelId);\n  }\n\n  const inputTokens = ensureNumber(result.usage?.promptTokens);\n  if (inputTokens !== undefined) {\n    span.setAttribute(Attr.GenAI.Usage.InputTokens, inputTokens);\n  }\n\n  const outputTokens = ensureNumber(result.usage?.completionTokens);\n  if (outputTokens !== undefined) {\n    span.setAttribute(Attr.GenAI.Usage.OutputTokens, outputTokens);\n  }\n\n  if (result.finishReason) {\n    span.setAttribute(Attr.GenAI.Response.FinishReasons, JSON.stringify([result.finishReason]));\n  }\n}\n\n// V2 helper functions (extracted from AxiomWrappedLanguageModelV2)\nfunction setPreCallAttributesV2(\n  span: Span,\n  options: LanguageModelV2CallOptions,\n  context: GenAiSpanContextV2,\n  model: LanguageModelV2,\n) {\n  const redactionPolicy = getRedactionPolicy();\n\n  setBaseAttributes(span, model.provider, model.modelId);\n\n  const outputType = determineOutputTypeV2(options);\n  if (outputType) {\n    span.setAttribute(Attr.GenAI.Output.Type, outputType);\n  }\n\n  setRequestParameterAttributes(span, {\n    maxTokens: options.maxOutputTokens,\n    frequencyPenalty: options.frequencyPenalty,\n    presencePenalty: options.presencePenalty,\n    temperature: options.temperature,\n    topP: options.topP,\n    topK: options.topK,\n    seed: options.seed,\n    stopSequences: options.stopSequences,\n  });\n\n  const processedPrompt = promptV2ToOpenAI(options.prompt);\n\n  // Store both the original V2 prompt and processed prompt for later use\n  context.originalV2Prompt = options.prompt;\n  context.originalPrompt = processedPrompt;\n\n  handleMaybeRedactedAttribute(\n    span,\n    Attr.GenAI.Input.Messages,\n    JSON.stringify(sanitizeMultimodalContent(processedPrompt)),\n    redactionPolicy.captureMessageContent,\n  );\n}\n\nasync function setPostCallAttributesV2(\n  span: Span,\n  result: {\n    response?: LanguageModelV2ResponseMetadata;\n    finishReason?: LanguageModelV2FinishReason;\n    usage?: LanguageModelV2Usage;\n    content?: Array<LanguageModelV2Content>;\n  },\n  context: GenAiSpanContextV2,\n  _model: LanguageModelV2,\n) {\n  const redactionPolicy = getRedactionPolicy();\n\n  // Check if we have tool calls in this response\n  const toolCalls = result.content?.filter(\n    (c) => c.type === 'tool-call',\n  ) as LanguageModelV2ToolCall[];\n\n  // Only set response metadata once per span to prevent overwriting when generateText() makes multiple calls\n  const alreadySet = (span as any).attributes?.[Attr.GenAI.Response.FinishReasons] !== undefined;\n\n  if (!alreadySet) {\n    if (result.response?.id) {\n      span.setAttribute(Attr.GenAI.Response.ID, result.response.id);\n    }\n    if (result.response?.modelId) {\n      span.setAttribute(Attr.GenAI.Response.Model, result.response.modelId);\n    }\n\n    const inputTokens = ensureNumber(result.usage?.inputTokens);\n    if (inputTokens !== undefined) {\n      span.setAttribute(Attr.GenAI.Usage.InputTokens, inputTokens);\n    }\n\n    const outputTokens = ensureNumber(result.usage?.outputTokens);\n    if (outputTokens !== undefined) {\n      span.setAttribute(Attr.GenAI.Usage.OutputTokens, outputTokens);\n    }\n  }\n\n  // Update prompt to include tool calls and tool results if they exist\n  if (toolCalls && toolCalls.length > 0) {\n    const originalPrompt = context.originalPrompt || [];\n\n    const normalizedToolCalls = normalizeV2ToolCalls(toolCalls);\n\n    // Extract real tool results from the original V2 prompt structure\n    const toolResultsMap = extractToolResultsFromPromptV2(context.originalV2Prompt || []);\n\n    // Extract assistant text content from the response\n    const textContent = result.content?.find((c) => c.type === 'text');\n    const assistantText = textContent?.type === 'text' ? textContent.text : undefined;\n\n    // Use the standard prompt utility to append tool calls\n    const updatedPrompt = appendToolCalls(\n      originalPrompt,\n      normalizedToolCalls,\n      toolResultsMap,\n      assistantText,\n    );\n\n    // Update the prompt attribute with the complete conversation history\n    handleMaybeRedactedAttribute(\n      span,\n      Attr.GenAI.Input.Messages,\n      JSON.stringify(sanitizeMultimodalContent(updatedPrompt)),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n\n  // Process tool calls and create child spans\n  if (result.content && result.content.length > 0) {\n    await processToolCallsAndCreateSpansV2(span, result.content);\n  } else if (result.finishReason) {\n    // For non-tool responses, still create completion array\n    const completion = createSimpleCompletion({\n      text: '',\n    });\n    handleMaybeRedactedAttribute(\n      span,\n      Attr.GenAI.Output.Messages,\n      JSON.stringify(completion),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n\n  // Store finish reason separately as per semantic conventions (only on first call to prevent overwriting)\n  if (result.finishReason && !alreadySet) {\n    span.setAttribute(Attr.GenAI.Response.FinishReasons, JSON.stringify([result.finishReason]));\n  }\n}\n\nasync function processToolCallsAndCreateSpansV2(\n  parentSpan: Span,\n  content: Array<LanguageModelV2Content>,\n): Promise<void> {\n  const redactionPolicy = getRedactionPolicy();\n\n  // Extract text and tool calls from content\n  const textContent = content.find((c) => c.type === 'text');\n  const assistantText = textContent?.type === 'text' ? textContent.text : undefined;\n  const toolCalls = content.filter((c) => c.type === 'tool-call') as LanguageModelV2ToolCall[];\n\n  // Only set completion for final responses without tool calls\n  if (toolCalls.length === 0) {\n    // Create completion with multimodal content support\n    const completion = [\n      {\n        role: 'assistant' as const,\n        content: sanitizeMultimodalContent(\n          content.length === 1 && assistantText ? assistantText : content,\n        ),\n      },\n    ];\n\n    // Set completion array as span attribute\n    handleMaybeRedactedAttribute(\n      parentSpan,\n      Attr.GenAI.Output.Messages,\n      JSON.stringify(completion),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n}\n\n/**\n * Creates Axiom telemetry middleware for LanguageModelV3\n */\nexport function axiomAIMiddlewareV3(/* _config?: AxiomTelemetryConfig */): LanguageModelV3Middleware {\n  return {\n    specificationVersion: 'v3',\n\n    wrapGenerate: async ({ doGenerate, params, model }) => {\n      return withSpanHandling(\n        model.modelId,\n        async (span, commonContext, _lease) => {\n          const context = commonContext as GenAiSpanContextV3;\n\n          appendPromptMetadataToSpan(span, params.prompt);\n\n          // Pre-call setup\n          setScopeAttributes(span);\n          setPreCallAttributesV3(span, params, context, model);\n\n          const res = await doGenerate();\n\n          // Post-call processing\n          await setPostCallAttributesV3(span, res, context, model);\n\n          return res;\n        },\n        { version: 'v3' },\n      );\n    },\n\n    wrapStream: async ({ doStream, params, model }) => {\n      return withSpanHandling(\n        model.modelId,\n        async (span, commonContext, lease) => {\n          const context = commonContext as GenAiSpanContextV3;\n\n          appendPromptMetadataToSpan(span, params.prompt);\n\n          // Pre-call setup\n          setScopeAttributes(span);\n          setPreCallAttributesV3(span, params, context, model);\n\n          const ret = await doStream();\n\n          // Create child span for stream processing (provides granular visibility)\n          const childSpan = createStreamChildSpan(span, `chat ${model.modelId} stream`);\n\n          const stats = new StreamStatsV3();\n          const toolAggregator = new ToolCallAggregatorV3();\n          const textAggregator = new TextAggregatorV3();\n\n          return {\n            ...ret,\n            stream: ret.stream.pipeThrough(\n              new TransformStream({\n                transform(chunk: LanguageModelV3StreamPart, controller) {\n                  try {\n                    stats.feed(chunk);\n                    toolAggregator.handleChunk(chunk);\n                    textAggregator.feed(chunk);\n\n                    controller.enqueue(chunk);\n                  } catch (err) {\n                    classifyToolError(err, childSpan);\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.error(err);\n                  }\n                },\n                async flush(controller) {\n                  try {\n                    const statsResult = stats.result;\n\n                    await setPostCallAttributesV3(\n                      span,\n                      {\n                        response: statsResult.response,\n                        finishReason: statsResult.finishReason,\n                        usage: statsResult.usage,\n                        content:\n                          toolAggregator.result.length > 0\n                            ? toolAggregator.result\n                            : textAggregator.text\n                              ? [{ type: 'text' as const, text: textAggregator.text }]\n                              : [],\n                        warnings: [],\n                      },\n                      context,\n                      model,\n                    );\n\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.terminate();\n                  } catch (err) {\n                    classifyToolError(err, childSpan);\n                    childSpan.end();\n                    if (lease.owned) lease.end();\n                    controller.error(err);\n                  }\n                },\n              }),\n            ),\n          };\n        },\n        { streaming: true, version: 'v3' },\n      );\n    },\n  };\n}\n\n// V3 helper functions\nfunction setPreCallAttributesV3(\n  span: Span,\n  options: LanguageModelV3CallOptions,\n  context: GenAiSpanContextV3,\n  model: LanguageModelV3,\n) {\n  const redactionPolicy = getRedactionPolicy();\n\n  setBaseAttributes(span, model.provider, model.modelId);\n\n  const outputType = determineOutputTypeV3(options);\n  if (outputType) {\n    span.setAttribute(Attr.GenAI.Output.Type, outputType);\n  }\n\n  setRequestParameterAttributes(span, {\n    maxTokens: options.maxOutputTokens,\n    frequencyPenalty: options.frequencyPenalty,\n    presencePenalty: options.presencePenalty,\n    temperature: options.temperature,\n    topP: options.topP,\n    topK: options.topK,\n    seed: options.seed,\n    stopSequences: options.stopSequences,\n  });\n\n  const processedPrompt = promptV3ToOpenAI(options.prompt);\n\n  // Store both the original V3 prompt and processed prompt for later use\n  context.originalV3Prompt = options.prompt;\n  context.originalPrompt = processedPrompt;\n\n  handleMaybeRedactedAttribute(\n    span,\n    Attr.GenAI.Input.Messages,\n    JSON.stringify(sanitizeMultimodalContent(processedPrompt)),\n    redactionPolicy.captureMessageContent,\n  );\n}\n\nasync function setPostCallAttributesV3(\n  span: Span,\n  result: {\n    response?: LanguageModelV3ResponseMetadata;\n    finishReason?: LanguageModelV3FinishReason;\n    usage?: LanguageModelV3Usage;\n    content?: Array<LanguageModelV3Content>;\n    warnings: Array<unknown>;\n  },\n  context: GenAiSpanContextV3,\n  _model: LanguageModelV3,\n) {\n  const redactionPolicy = getRedactionPolicy();\n\n  // Check if we have tool calls in this response\n  const toolCalls = result.content?.filter(\n    (c) => c.type === 'tool-call',\n  ) as LanguageModelV3ToolCall[];\n\n  // Only set response metadata once per span to prevent overwriting when generateText() makes multiple calls\n  const alreadySet = (span as any).attributes?.[Attr.GenAI.Response.FinishReasons] !== undefined;\n\n  if (!alreadySet) {\n    if (result.response?.id) {\n      span.setAttribute(Attr.GenAI.Response.ID, result.response.id);\n    }\n    if (result.response?.modelId) {\n      span.setAttribute(Attr.GenAI.Response.Model, result.response.modelId);\n    }\n\n    // V3 has structured token usage - extract totals for OTel attributes\n    // TODO: When OTel semantic conventions add support for cached/reasoning tokens,\n    // add these attributes:\n    // - result.usage?.inputTokens.cacheRead -> gen_ai.usage.cache_read_tokens (or similar)\n    // - result.usage?.inputTokens.cacheWrite -> gen_ai.usage.cache_write_tokens (or similar)\n    // - result.usage?.inputTokens.noCache -> gen_ai.usage.no_cache_tokens (or similar)\n    // - result.usage?.outputTokens.reasoning -> gen_ai.usage.reasoning_tokens (or similar)\n    // - result.usage?.outputTokens.text -> gen_ai.usage.text_tokens (or similar)\n    // Access: result.usage?.inputTokens.cacheRead, result.usage?.outputTokens.reasoning, etc.\n    const inputTokens = ensureNumber(result.usage?.inputTokens?.total);\n    if (inputTokens !== undefined) {\n      span.setAttribute(Attr.GenAI.Usage.InputTokens, inputTokens);\n    }\n\n    const outputTokens = ensureNumber(result.usage?.outputTokens?.total);\n    if (outputTokens !== undefined) {\n      span.setAttribute(Attr.GenAI.Usage.OutputTokens, outputTokens);\n    }\n  }\n\n  // Update prompt to include tool calls and tool results if they exist\n  if (toolCalls && toolCalls.length > 0) {\n    const originalPrompt = context.originalPrompt || [];\n\n    const normalizedToolCalls = normalizeV3ToolCalls(toolCalls);\n\n    // Extract real tool results from the original V3 prompt structure\n    const toolResultsMap = extractToolResultsFromPromptV3(context.originalV3Prompt || []);\n\n    // Extract assistant text content from the response\n    const textContent = result.content?.find((c) => c.type === 'text');\n    const assistantText = textContent?.type === 'text' ? textContent.text : undefined;\n\n    // Use the standard prompt utility to append tool calls\n    const updatedPrompt = appendToolCalls(\n      originalPrompt,\n      normalizedToolCalls,\n      toolResultsMap,\n      assistantText,\n    );\n\n    // Update the prompt attribute with the complete conversation history\n    handleMaybeRedactedAttribute(\n      span,\n      Attr.GenAI.Input.Messages,\n      JSON.stringify(sanitizeMultimodalContent(updatedPrompt)),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n\n  // Process content and create completion\n  if (result.content && result.content.length > 0) {\n    await processToolCallsAndCreateSpansV3(span, result.content);\n  } else if (result.finishReason) {\n    // For non-tool responses, still create completion array\n    const completion = createSimpleCompletion({\n      text: '',\n    });\n    handleMaybeRedactedAttribute(\n      span,\n      Attr.GenAI.Output.Messages,\n      JSON.stringify(completion),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n\n  // Store finish reason - V3 uses { unified, raw } structure, use unified for OTel\n  // TODO: When OTel adds support for raw finish reasons, consider adding:\n  // - result.finishReason.raw -> gen_ai.response.raw_finish_reason (or similar)\n  // Access: result.finishReason?.raw\n  if (result.finishReason && !alreadySet) {\n    span.setAttribute(\n      Attr.GenAI.Response.FinishReasons,\n      JSON.stringify([result.finishReason.unified]),\n    );\n  }\n}\n\nasync function processToolCallsAndCreateSpansV3(\n  parentSpan: Span,\n  content: Array<LanguageModelV3Content>,\n): Promise<void> {\n  const redactionPolicy = getRedactionPolicy();\n\n  // Extract text and tool calls from content\n  const textContent = content.find((c) => c.type === 'text');\n  const assistantText = textContent?.type === 'text' ? textContent.text : undefined;\n  const toolCalls = content.filter((c) => c.type === 'tool-call') as LanguageModelV3ToolCall[];\n\n  // TODO: When OTel adds support for tool approval flow, track these:\n  // - tool-approval-request stream parts with approvalId, toolCallId\n  // - tool-approval-response parts in tool messages\n  // Access: content.filter(c => c.type === 'tool-approval-request')\n  // Also track dynamic/providerExecuted flags on tool calls:\n  // - toolCall.dynamic -> gen_ai.tool.dynamic (or similar)\n  // - toolCall.providerExecuted -> gen_ai.tool.provider_executed (or similar)\n\n  // Only set completion for final responses without tool calls\n  if (toolCalls.length === 0) {\n    // Create completion with multimodal content support\n    // Filter out V3-specific content types that aren't text\n    const sanitizableContent = content.filter(\n      (c) =>\n        c.type === 'text' ||\n        c.type === 'reasoning' ||\n        c.type === 'file' ||\n        c.type === 'source' ||\n        c.type === 'tool-result',\n    );\n\n    const completion = [\n      {\n        role: 'assistant' as const,\n        content: sanitizeMultimodalContent(\n          sanitizableContent.length === 1 && assistantText ? assistantText : sanitizableContent,\n        ),\n      },\n    ];\n\n    // Set completion array as span attribute\n    handleMaybeRedactedAttribute(\n      parentSpan,\n      Attr.GenAI.Output.Messages,\n      JSON.stringify(completion),\n      redactionPolicy.captureMessageContent,\n    );\n  }\n}\n","import { type LanguageModelV1, type LanguageModelV1CallOptions } from '@ai-sdk/providerv1';\nimport { axiomAIMiddlewareV1 } from './middleware';\n\nexport function isLanguageModelV1(model: unknown): model is LanguageModelV1 {\n  return (\n    model != null &&\n    typeof model === 'object' &&\n    'specificationVersion' in model &&\n    'provider' in model &&\n    'modelId' in model &&\n    (model as any).specificationVersion === 'v1' &&\n    typeof (model as any).provider === 'string' &&\n    typeof (model as any).modelId === 'string'\n  );\n}\n\n/**\n * Wraps a LanguageModelV1 to provide OpenTelemetry instrumentation.\n *\n * Internally uses Axiom's telemetry middleware while maintaining a simple class-based API.\n *\n * @example\n * ```typescript\n * import { AxiomWrappedLanguageModelV1 } from '@axiom/ai';\n * import { openai } from '@ai-sdk/openai';\n *\n * const model = new AxiomWrappedLanguageModelV1(openai('gpt-3.5-turbo'));\n * ```\n *\n * For advanced use cases, you can also use the middleware directly:\n * ```typescript\n * import { wrapLanguageModel } from 'ai';\n * import { createAxiomTelemetryV1 } from '@axiom/ai';\n *\n * const model = wrapLanguageModel({\n *   model: yourV1Model,\n *   middleware: createAxiomTelemetryV1(),\n * });\n * ```\n */\nexport class AxiomWrappedLanguageModelV1 {\n  constructor(model: LanguageModelV1) {\n    const middleware = axiomAIMiddlewareV1();\n\n    // Return the wrapped model directly from constructor\n    return {\n      specificationVersion: model.specificationVersion,\n      provider: model.provider,\n      modelId: model.modelId,\n      defaultObjectGenerationMode: model.defaultObjectGenerationMode,\n      supportsImageUrls: model.supportsImageUrls,\n      supportsStructuredOutputs: model.supportsStructuredOutputs,\n      supportsUrl: model.supportsUrl?.bind(model),\n\n      doGenerate: async (params: LanguageModelV1CallOptions) => {\n        return middleware.wrapGenerate!({\n          doGenerate: () => model.doGenerate(params),\n          doStream: () => model.doStream(params),\n          params,\n          model,\n        });\n      },\n\n      doStream: async (params: LanguageModelV1CallOptions) => {\n        return middleware.wrapStream!({\n          doGenerate: () => model.doGenerate(params),\n          doStream: () => model.doStream(params),\n          params,\n          model,\n        });\n      },\n    } as LanguageModelV1;\n  }\n}\n","import { type LanguageModelV2, type LanguageModelV2CallOptions } from '@ai-sdk/providerv2';\nimport { axiomAIMiddlewareV2 } from './middleware';\n\nexport function isLanguageModelV2(model: any): model is LanguageModelV2 {\n  return (\n    model?.specificationVersion === 'v2' &&\n    typeof model?.provider === 'string' &&\n    typeof model?.modelId === 'string'\n  );\n}\n\n/**\n * Wraps a LanguageModelV2 to provide OpenTelemetry instrumentation.\n *\n * Internally uses Axiom's telemetry middleware while maintaining a simple class-based API.\n *\n * @example\n * ```typescript\n * import { AxiomWrappedLanguageModelV2 } from '@axiom/ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n *\n * const model = new AxiomWrappedLanguageModelV2(anthropic('claude-3-haiku-20240307'));\n * ```\n *\n * For advanced use cases, you can also use the middleware directly:\n * ```typescript\n * import { wrapLanguageModel } from 'ai';\n * import { createAxiomTelemetryV2 } from '@axiom/ai';\n *\n * const model = wrapLanguageModel({\n *   model: yourV2Model,\n *   middleware: createAxiomTelemetryV2(),\n * });\n * ```\n */\nexport class AxiomWrappedLanguageModelV2 {\n  constructor(model: LanguageModelV2) {\n    const middleware = axiomAIMiddlewareV2();\n\n    // Return the wrapped model directly from constructor\n    return {\n      specificationVersion: model.specificationVersion,\n      provider: model.provider,\n      modelId: model.modelId,\n      supportedUrls: model.supportedUrls,\n\n      doGenerate: async (params: LanguageModelV2CallOptions) => {\n        return middleware.wrapGenerate!({\n          doGenerate: () => model.doGenerate(params),\n          doStream: () => model.doStream(params),\n          params,\n          model,\n        });\n      },\n\n      doStream: async (params: LanguageModelV2CallOptions) => {\n        return middleware.wrapStream!({\n          doGenerate: () => model.doGenerate(params),\n          doStream: () => model.doStream(params),\n          params,\n          model,\n        });\n      },\n    } as LanguageModelV2;\n  }\n}\n","import { type LanguageModelV3, type LanguageModelV3CallOptions } from '@ai-sdk/providerv3';\nimport { axiomAIMiddlewareV3 } from './middleware';\n\nexport function isLanguageModelV3(model: unknown): model is LanguageModelV3 {\n  return (\n    model != null &&\n    typeof model === 'object' &&\n    'specificationVersion' in model &&\n    'provider' in model &&\n    'modelId' in model &&\n    (model as any).specificationVersion === 'v3' &&\n    typeof (model as any).provider === 'string' &&\n    typeof (model as any).modelId === 'string'\n  );\n}\n\n/**\n * Wraps a LanguageModelV3 to provide OpenTelemetry instrumentation.\n *\n * Internally uses Axiom's telemetry middleware while maintaining a simple class-based API.\n *\n * @example\n * ```typescript\n * import { AxiomWrappedLanguageModelV3 } from '@axiom/ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n *\n * const model = new AxiomWrappedLanguageModelV3(anthropic('claude-sonnet-4-20250514'));\n * ```\n *\n * For advanced use cases, you can also use the middleware directly:\n * ```typescript\n * import { wrapLanguageModel } from 'ai';\n * import { createAxiomTelemetryV3 } from '@axiom/ai';\n *\n * const model = wrapLanguageModel({\n *   model: yourV3Model,\n *   middleware: createAxiomTelemetryV3(),\n * });\n * ```\n */\nexport class AxiomWrappedLanguageModelV3 {\n  constructor(model: LanguageModelV3) {\n    const middleware = axiomAIMiddlewareV3();\n\n    // Return the wrapped model directly from constructor\n    return {\n      specificationVersion: model.specificationVersion,\n      provider: model.provider,\n      modelId: model.modelId,\n      supportedUrls: model.supportedUrls,\n\n      doGenerate: async (params: LanguageModelV3CallOptions) => {\n        return middleware.wrapGenerate!({\n          doGenerate: () => model.doGenerate(params),\n          doStream: () => model.doStream(params),\n          params,\n          model,\n        });\n      },\n\n      doStream: async (params: LanguageModelV3CallOptions) => {\n        return middleware.wrapStream!({\n          doGenerate: () => model.doGenerate(params),\n          doStream: () => model.doStream(params),\n          params,\n          model,\n        });\n      },\n    } as LanguageModelV3;\n  }\n}\n","import { type LanguageModelV1 } from '@ai-sdk/providerv1';\nimport { type LanguageModelV2 } from '@ai-sdk/providerv2';\nimport { type LanguageModelV3 } from '@ai-sdk/providerv3';\n\nimport { AxiomWrappedLanguageModelV1, isLanguageModelV1 } from './AxiomWrappedLanguageModelV1';\nimport { AxiomWrappedLanguageModelV2, isLanguageModelV2 } from './AxiomWrappedLanguageModelV2';\nimport { AxiomWrappedLanguageModelV3, isLanguageModelV3 } from './AxiomWrappedLanguageModelV3';\n\n/**\n * Wraps an AI SDK model to provide OpenTelemetry instrumentation.\n *\n * Supports AI SDK v4 (LanguageModelV1), v5 (LanguageModelV2) and v6 (LanguageModelV3) models.\n *\n * @param model - Language model implementing LanguageModelV1, LanguageModelV2 or LanguageModelV3 interface\n * @returns Wrapped model with identical interface but added instrumentation\n */\nexport function wrapAISDKModel<T extends LanguageModelV1 | LanguageModelV2 | LanguageModelV3>(\n  model: T,\n): T {\n  if (isLanguageModelV3(model)) {\n    return new AxiomWrappedLanguageModelV3(model) as never as T;\n  } else if (isLanguageModelV2(model)) {\n    return new AxiomWrappedLanguageModelV2(model) as never as T;\n  } else if (isLanguageModelV1(model)) {\n    return new AxiomWrappedLanguageModelV1(model) as never as T;\n  } else {\n    console.warn('Unsupported AI SDK model. Not wrapping.');\n    return model;\n  }\n}\n","export { withSpan } from './withSpan';\nexport { wrapAISDKModel } from './vercel';\nexport { Attr } from './semconv/attributes';\n","import { getGlobalFlagOverrides } from './evals/context/global-flags';\nimport {\n  getEvalContext,\n  updateEvalContext,\n  addOutOfScopeFlag,\n  setConfigScope,\n} from './evals/context/storage';\nimport { validateCliFlags } from './validate-flags';\nimport {\n  parsePath,\n  dotNotationToNested,\n  isValidPath,\n  getValueAtPath,\n  buildSchemaForPath,\n  findSchemaAtPath,\n} from './util/dot-path';\nimport {\n  getDef,\n  getKind,\n  getInnerType,\n  getShape,\n  isObjectSchema,\n  assertZodV4,\n} from './util/zod-internals';\nimport { trace } from '@opentelemetry/api';\nimport { type z, type ZodObject, type ZodDefault, type ZodSchema } from 'zod';\nimport { toOtelAttribute } from './otel/utils/to-otel-attribute';\nimport { Attr } from './otel';\n\ntype DefaultMaxDepth = 8;\n\n// Helper to recursively check if a schema has defaults (including nested objects)\ntype HasDefaults<S> = S extends { _zod: { def: { defaultValue: unknown } } }\n  ? true\n  : S extends ZodObject<infer Shape>\n    ? {\n        [K in keyof Shape]: HasDefaults<Shape[K]>;\n      } extends Record<keyof Shape, true>\n      ? true\n      : false\n    : false;\n\n// Helper type to extract the underlying ZodObject from ZodDefault wrapper\ntype UnwrapSchema<T> = T extends ZodDefault<infer U> ? U : T;\n\n// Helper to check if ALL fields in a schema have defaults\ntype AllFieldsHaveDefaults<Schema> =\n  // First check if the schema itself has an object-level default\n  Schema extends { _zod: { def: { defaultValue: unknown } } }\n    ? true\n    : // Otherwise recursively check if all fields have defaults\n      HasDefaults<UnwrapSchema<Schema>>;\n\ninterface AppScopeConfig<\n  FlagSchema extends ZodObject<any> | undefined = undefined,\n  FactSchema extends ZodObject<any> | undefined = undefined,\n> {\n  flagSchema: FlagSchema;\n  factSchema?: FactSchema;\n}\n\n/**\n * Recursive type to extract all possible paths from an object type.\n * Uses stack-based depth limiting for better performance.\n *\n * @template T - The object type to extract paths from\n * @template Stack - Internal stack counter (do not set manually)\n * @template MaxDepth - Maximum recursion depth (default: 8 for good balance)\n */\ntype ObjectPaths<\n  T,\n  Stack extends unknown[] = [],\n  MaxDepth extends number = DefaultMaxDepth,\n> = Stack['length'] extends MaxDepth\n  ? never\n  : T extends object\n    ? {\n        [K in keyof T]-?: K extends string | number\n          ? `${K}` | `${K}.${ObjectPaths<T[K], [1, ...Stack], MaxDepth>}`\n          : never;\n      }[keyof T]\n    : never;\n\n// Type to get value at a specific path in an object\ntype ObjectPathValue<T, P extends string> = P extends keyof T\n  ? T[P]\n  : P extends `${infer K}.${infer Rest}`\n    ? K extends keyof T\n      ? ObjectPathValue<T[K], Rest>\n      : never\n    : never;\n\n/**\n * Generate deep nested paths from flag schema.\n *\n * @template T - ZodObject to extract paths from\n * @template MaxDepth - Maximum recursion depth (default: 8, override for deeper nesting)\n * @example\n * // Default 8-level depth\n * type Paths = DotPaths<MySchema>\n *\n * // Custom depth for deeper nesting (impacts performance)\n * type DeepPaths = DotPaths<MySchema, 12>\n */\nexport type DotPaths<T extends ZodObject<any>, MaxDepth extends number = DefaultMaxDepth> = {\n  [NS in keyof T['shape']]:\n    | (string & NS) // Include the namespace itself\n    | {\n        [P in ObjectPaths<\n          z.output<UnwrapSchema<T['shape'][NS]>>,\n          [],\n          MaxDepth\n        >]: `${string & NS}.${P}`;\n      }[ObjectPaths<z.output<UnwrapSchema<T['shape'][NS]>>, [], MaxDepth>];\n}[keyof T['shape']];\n\ntype PathValue<T extends ZodObject<any>, P extends string> = P extends `${infer NS}.${infer Rest}`\n  ? NS extends keyof T['shape']\n    ? ObjectPathValue<z.output<UnwrapSchema<T['shape'][NS]>>, Rest>\n    : never\n  : P extends keyof T['shape']\n    ? z.output<UnwrapSchema<T['shape'][P]>>\n    : never;\n\ntype DotNotationFlagFunction<FS extends ZodObject<any> | undefined> =\n  FS extends ZodObject<any> ? <P extends DotPaths<FS>>(path: P) => PathValue<FS, P> : never;\n\ntype FactFunction<SC extends ZodObject<any> | undefined> =\n  SC extends ZodObject<any>\n    ? <P extends DotPaths<SC> & string>(name: P, value: PathValue<SC, P>) => void\n    : never;\n\ntype OverrideFlagsFunction<FS extends ZodObject<any> | undefined> =\n  FS extends ZodObject<any>\n    ? (partial: { [K in DotPaths<FS>]?: PathValue<FS, K> }) => void\n    : (partial: Record<string, any>) => void;\n\ntype WithFlagsFunction<FS extends ZodObject<any> | undefined> =\n  FS extends ZodObject<any>\n    ? <T>(overrides: { [K in DotPaths<FS>]?: PathValue<FS, K> }, fn: () => T) => T\n    : <T>(overrides: Record<string, any>, fn: () => T) => T;\n\ntype PickFlagsFunction<FS extends ZodObject<any> | undefined> =\n  FS extends ZodObject<any>\n    ? {\n        // Spread arguments: pickFlags2('foo', 'bar')\n        <K extends ReadonlyArray<DotPaths<FS> & string>>(...paths: K): K;\n        // Array argument: pickFlags2(['foo', 'bar'])\n        <K extends ReadonlyArray<DotPaths<FS> & string>>(paths: K): K;\n      }\n    : never;\n\nexport interface AppScope<\n  FS extends ZodObject<any> | undefined,\n  SC extends ZodObject<any> | undefined,\n> {\n  flag: DotNotationFlagFunction<FS>;\n  fact: FactFunction<SC>;\n  overrideFlags: OverrideFlagsFunction<FS>;\n  withFlags: WithFlagsFunction<FS>;\n  pickFlags: PickFlagsFunction<FS>;\n  getAllDefaultFlags: () => Record<string, any>;\n}\n\n/**\n * Check if a flag path is covered by the picked flags.\n * @param flagPath - The flag path to check (e.g., 'foo', 'foo.bar')\n * @param pickedFlags - Array of picked flag paths\n * @returns true if the flag is covered by picked flags\n */\nexport function isPickedFlag(flagPath: string, pickedFlags?: string[]): boolean {\n  if (!pickedFlags) {\n    // If no picked flags are provided, all flags are allowed\n    return true;\n  }\n\n  if (pickedFlags.length === 0) {\n    // If no flags are picked, all flags are allowed\n    return true;\n  }\n\n  return pickedFlags.some((picked) => {\n    // Exact match\n    if (flagPath === picked) {\n      return true;\n    }\n    // Nested match: flagPath starts with picked flag followed by a dot\n    if (flagPath.startsWith(picked + '.')) {\n      return true;\n    }\n    return false;\n  });\n}\n\n// Helper to recursively validate that schemas don't contain union types\nfunction assertNoUnions(schema: unknown, path = 'schema'): void {\n  if (!schema) return;\n\n  const kind = getKind(schema);\n  if (!kind) return;\n\n  // Unwrap transparent containers\n  if (kind === 'default' || kind === 'optional' || kind === 'nullable') {\n    const innerType = getInnerType(schema);\n    return assertNoUnions(innerType, path);\n  }\n\n  // Hard-fail on unions\n  if (kind === 'union' || kind === 'discriminatedunion') {\n    throw new Error(`[AxiomAI] Union types are not supported in flag schemas (found at \"${path}\")`);\n  }\n\n  // Recurse into compound types\n  if (kind === 'object') {\n    const shape = getShape(schema);\n    if (shape) {\n      for (const [k, v] of Object.entries(shape)) {\n        assertNoUnions(v, `${path}.${k}`);\n      }\n    }\n  } else if (kind === 'array') {\n    const innerType = getInnerType(schema);\n    if (innerType) {\n      assertNoUnions(innerType, `${path}[]`);\n    }\n  } else if (kind === 'record') {\n    const def = getDef(schema);\n    const valueType = def?.valueType;\n    if (valueType) {\n      assertNoUnions(valueType, `${path}{}`);\n    }\n  }\n}\n\n/**\n * Recursively verify that all leaf fields in the schema have defaults.\n * Throws with a detailed error message listing all paths missing defaults.\n * TODO: this should probably be in an adapter, not the core lib...\n */\nfunction ensureAllDefaults(schema: unknown, path = ''): void {\n  const missingDefaults: string[] = [];\n\n  function checkDefaults(current: unknown, currentPath: string): void {\n    if (!current) return;\n\n    const kind = getKind(current);\n    if (!kind) return;\n\n    const def = getDef(current);\n    const hasDefault = def?.defaultValue !== undefined;\n\n    // Unwrap transparent containers and check their inner type\n    if (kind === 'default') {\n      // This has a default, we're done - no need to check inner type\n      return;\n    }\n\n    if (kind === 'optional' || kind === 'nullable') {\n      // Transparent wrappers - check inner type\n      const innerType = getInnerType(current);\n      return checkDefaults(innerType, currentPath);\n    }\n\n    // ZodRecord is not allowed\n    if (kind === 'record') {\n      throw new Error(\n        `[AxiomAI] ZodRecord is not supported in flag schemas (found at \"${currentPath || 'root'}\")\\n` +\n          `All flag fields must have known keys and defaults. Consider using z.object() instead.`,\n      );\n    }\n\n    // For objects: if there's an object-level default, we're good\n    // Otherwise, recursively check all fields\n    if (kind === 'object') {\n      if (hasDefault) {\n        // Object-level default covers all nested fields\n        return;\n      }\n\n      const shape = getShape(current);\n      if (shape) {\n        for (const [k, v] of Object.entries(shape)) {\n          const nextPath = currentPath ? `${currentPath}.${k}` : k;\n          checkDefaults(v, nextPath);\n        }\n      }\n      return;\n    }\n\n    // For arrays: arrays are leaf types (no per-index access)\n    // Just check if the array schema itself has a default\n    if (kind === 'array') {\n      if (!hasDefault) {\n        missingDefaults.push(currentPath || 'root');\n      }\n      return;\n    }\n\n    // For all other types (primitives, etc): must have a default\n    if (!hasDefault) {\n      missingDefaults.push(currentPath || 'root');\n    }\n  }\n\n  checkDefaults(schema, path);\n\n  if (missingDefaults.length > 0) {\n    throw new Error(\n      `[AxiomAI] All flag fields must have defaults. Missing defaults for:\\n` +\n        missingDefaults.map((p) => `  - ${p}`).join('\\n') +\n        `\\n\\nAdd .default(value) to these fields or to their parent objects.`,\n    );\n  }\n}\n\n/**\n * Create a new application-level evaluation scope.\n *\n * @param config.flagSchema A zod object describing the schema for flags **(required)**\n * @param config.factSchema A zod object describing the schema for facts (optional)\n *\n * @example\n * import { z } from 'zod';\n *\n * const { flag, fact, withFlags, pickFlags, overrideFlags } = createAppScope({\n *   flagSchema: z.object({\n *     ui: z.object({\n *       darkMode: z.boolean().default(false),\n *       theme:    z.object({\n *         primary: z.string().default('#00f'),\n *       }),\n *     }),\n *     api: z.object({ \n       endpoint: z.string().default('/api') \n     }),\n *   }),\n *   factSchema: z.object({\n *     userAction: z.string(),\n *     timing: z.number(),\n *   }),\n * });\n *\n * // Typed flag access\n * const dark = flag('ui.darkMode'); // inferred boolean\n * const theme = flag('ui.theme'); // entire object\n * const primary = flag('ui.theme.primary'); // '#00f'\n * const endpoint = flag('api.endpoint'); // uses schema default\n *\n * // Typed fact recording\n * fact('userAction', 'clicked_button');\n * fact('timing', 1250);\n *\n * // Temporarily override flags for a block of code\n * withFlags({ 'ui.darkMode': true }, () => {\n *   // code here, `ui.darkMode` will be true in this block and reset after\n * });\n *\n * // Override flags globally for the current evaluation run\n * overrideFlags({ 'api.endpoint': '/custom' });\n */\n// Overload: Require all fields to have defaults (compile-time check)\nexport function createAppScope<\n  FlagSchema extends ZodObject<any>,\n  FactSchema extends ZodObject<any> | undefined = undefined,\n>(\n  config: AllFieldsHaveDefaults<FlagSchema> extends true\n    ? AppScopeConfig<FlagSchema, FactSchema>\n    : {\n        flagSchema: FlagSchema;\n        factSchema?: FactSchema;\n        __error__: 'createAppScope: flagSchema must have .default() for all leaf fields';\n      },\n): AppScope<FlagSchema, FactSchema>;\n\n// Implementation signature: Keep broad for internal use\nexport function createAppScope<\n  FlagSchema extends ZodObject<any> | undefined = undefined,\n  FactSchema extends ZodObject<any> | undefined = undefined,\n>(config: AppScopeConfig<FlagSchema, FactSchema>): AppScope<FlagSchema, FactSchema> {\n  // Store schemas for runtime validation\n  const flagSchemaConfig = config?.flagSchema;\n  const factSchemaConfig = config?.factSchema;\n\n  // Reject Zod v3 schemas\n  if (flagSchemaConfig) {\n    assertZodV4(flagSchemaConfig, 'flagSchema');\n  }\n  if (factSchemaConfig) {\n    assertZodV4(factSchemaConfig, 'factSchema');\n  }\n\n  // reject union types\n  if (flagSchemaConfig) {\n    assertNoUnions(flagSchemaConfig, 'flagSchema');\n  }\n\n  // Ensure all fields have defaults\n  if (flagSchemaConfig) {\n    ensureAllDefaults(flagSchemaConfig);\n  }\n\n  // CLI validation with dot notation support\n  if (flagSchemaConfig) {\n    validateCliFlags(flagSchemaConfig);\n  }\n\n  // Helper to check if a path represents a namespace access (no dots after first segment)\n  function isNamespaceAccess(segments: string[]): boolean {\n    if (!flagSchemaConfig || segments.length === 0) return false;\n\n    // For root namespace (like 'ui'), check if it exists in the ZodObject shape\n    if (segments.length === 1) {\n      return flagSchemaConfig.shape ? segments[0] in flagSchemaConfig.shape : false;\n    }\n\n    // For nested paths (like 'app.ui.layout'), need to check if the path points to an object schema\n    const schema = findSchemaAtPath(flagSchemaConfig, segments);\n    return isObjectSchema(schema);\n  }\n\n  // Helper function to check if a schema has complete defaults at runtime\n  // This mirrors the compile-time AllFieldsHaveDefaults<> type\n\n  // Recursively build object with all defaults from a Zod schema\n  function buildObjectWithDefaults(schema: unknown): unknown {\n    if (!schema) return undefined;\n\n    const kind = getKind(schema);\n    if (!kind) return undefined;\n\n    // `directDefault`: default for the entire object\n    // If this is not present, we try to construct the defaults from child fields (recursively)\n    const directDefault = extractDefault(schema);\n    if (directDefault !== undefined) {\n      return directDefault;\n    }\n\n    // We can only collect defaults from child fields if we're dealing with an object (for a scalar, there are no children)\n    if (kind === 'object') {\n      const shape = getShape(schema);\n      if (shape) {\n        const result: Record<string, unknown> = {};\n\n        for (const [key, fieldSchema] of Object.entries(shape)) {\n          const fieldValue = buildObjectWithDefaults(fieldSchema);\n          result[key] = fieldValue;\n        }\n\n        return result;\n      }\n    }\n\n    // No direct default, and it's not an object\n    return undefined;\n  }\n\n  function extractDefault(schema: unknown): unknown {\n    if (!schema) return undefined;\n\n    // Unwrap transparent containers first, checking for defaults at each level\n    let current: unknown = schema;\n\n    for (let i = 0; i < 10; i++) {\n      const def = getDef(current);\n      if (!def) break;\n\n      // Check for default value at current level\n      if (def.defaultValue !== undefined) {\n        return typeof def.defaultValue === 'function' ? def.defaultValue() : def.defaultValue;\n      }\n\n      // Unwrap one level if possible\n      const inner = getInnerType(current);\n      if (inner) {\n        current = inner;\n      } else {\n        // No more wrapping, stop here\n        break;\n      }\n    }\n\n    return undefined;\n  }\n\n  function validateFinalFlagValue(\n    dotPath: string,\n    value: unknown,\n  ): { ok: true; parsed: unknown } | { ok: false } {\n    if (!flagSchemaConfig) return { ok: true, parsed: value };\n\n    const segments = parsePath(dotPath);\n\n    // 1. Fast-path: validate directly with field-level schema\n    const fieldSchema = findSchemaAtPath(flagSchemaConfig, segments);\n    if (fieldSchema) {\n      const direct = (fieldSchema as ZodSchema<any>).safeParse(value);\n      if (direct.success) return { ok: true, parsed: direct.data };\n      // If we have a field schema but validation failed, this is a real error\n      return { ok: false };\n    }\n\n    // 2. If we don't have a field schema, check if the path is even valid in our schema\n    // Don't validate values for paths that don't exist in the schema - just pass them through\n    const hasValidNamespace = flagSchemaConfig.shape && segments[0] in flagSchemaConfig.shape;\n    if (!hasValidNamespace) {\n      // Invalid namespace - pass through without validation (for backward compatibility with fallback values)\n      return { ok: true, parsed: value };\n    }\n\n    // 3. For valid namespaces but invalid paths, try nested object validation\n    const nested = dotNotationToNested({ [dotPath]: value });\n    const nestedResult = flagSchemaConfig.strict().partial().safeParse(nested);\n    if (nestedResult.success) {\n      const parsed = getValueAtPath(nestedResult.data, segments) ?? value;\n      return { ok: true, parsed };\n    }\n\n    // 4. If nested validation failed but the namespace is valid, allow it for backward compatibility\n    return { ok: true, parsed: value };\n  }\n\n  function hasUndefinedLeaves(obj: unknown): boolean {\n    if (obj === undefined) return true;\n    if (obj === null || typeof obj !== 'object') return false;\n    return Object.values(obj).some((v) =>\n      typeof v === 'object' && v !== null ? hasUndefinedLeaves(v) : v === undefined,\n    );\n  }\n\n  /**\n   * Get flag value with dot notation path support and schema validation.\n   * All flag fields must have .default() values in the schema.\n   * Precedence: CLI overrides -> Context overrides -> Schema defaults → Error\n   *\n   * @param path - Dot notation path to the flag (e.g., 'ui.theme' or 'api.timeout')\n   * @returns The flag value or undefined if path is invalid\n   */\n  function flag<P extends string>(path: P): unknown {\n    const segments = parsePath(path);\n\n    const ctx = getEvalContext();\n    const globalOverrides = getGlobalFlagOverrides();\n\n    if (!isPickedFlag(path, ctx.pickedFlags)) {\n      addOutOfScopeFlag(path);\n    }\n\n    let finalValue: any;\n    let source: 'cli' | 'ctx' | 'schema' | undefined;\n\n    // Flag precedence order:\n    // 1. CLI overrides (getGlobalFlagOverrides)\n    // 2. Eval context overrides (getEvalContext().flags)\n    // 3. Schema/object defaults\n    // 4. undefined + console.error\n\n    // 1. Check CLI overrides first (highest priority)\n    if (path in globalOverrides) {\n      finalValue = globalOverrides[path];\n      source = 'cli';\n    }\n    // 2. Check context overrides (from withFlags() or overrideFlags)\n    else if (path in ctx.flags) {\n      finalValue = ctx.flags[path];\n      source = 'ctx';\n    }\n    // 3. Resolve from schema\n    else {\n      if (!flagSchemaConfig) {\n        console.error(`[AxiomAI] Invalid flag: \"${path}\"`);\n        return undefined;\n      }\n\n      // Check valid namespace\n      const hasValidNamespace = flagSchemaConfig.shape && segments[0] in flagSchemaConfig.shape;\n      if (!hasValidNamespace) {\n        console.error(`[AxiomAI] Invalid flag: \"${path}\"`);\n        return undefined;\n      }\n\n      const schemaForPath = findSchemaAtPath(flagSchemaConfig, segments);\n\n      // If schema path doesn't exist, try extracting from parent object-level defaults\n      if (!schemaForPath) {\n        const namespaceSchema = findSchemaAtPath(flagSchemaConfig, [segments[0]]);\n        if (namespaceSchema) {\n          const namespaceObject = buildObjectWithDefaults(namespaceSchema);\n          if (namespaceObject && typeof namespaceObject === 'object') {\n            finalValue = getValueAtPath(namespaceObject, segments.slice(1));\n          }\n        }\n\n        if (finalValue === undefined) {\n          console.error(`[AxiomAI] Invalid flag: \"${path}\"`);\n          return undefined;\n        }\n      }\n      // Check if this is a namespace access (returning whole objects)\n      else if (isNamespaceAccess(segments)) {\n        finalValue = buildObjectWithDefaults(schemaForPath);\n\n        // If buildObjectWithDefaults fails or returns incomplete object, try extracting from parent defaults\n        if (finalValue === undefined || hasUndefinedLeaves(finalValue)) {\n          const nsSchema = findSchemaAtPath(flagSchemaConfig, [segments[0]]);\n          if (nsSchema) {\n            const nsObj = buildObjectWithDefaults(nsSchema);\n            if (nsObj && typeof nsObj === 'object') {\n              const extracted = getValueAtPath(nsObj, segments.slice(1));\n              if (extracted !== undefined) {\n                finalValue = extracted;\n              }\n            }\n          }\n        }\n\n        if (finalValue === undefined) {\n          console.error(`[AxiomAI] Invalid flag: \"${path}\"`);\n          return undefined;\n        }\n      }\n      // Leaf access: try field-level default first\n      else {\n        finalValue = extractDefault(schemaForPath);\n\n        // If no field-level default, try extracting from parent object-level default\n        if (finalValue === undefined) {\n          const nsSchema = findSchemaAtPath(flagSchemaConfig, [segments[0]]);\n          if (nsSchema) {\n            const nsObj = buildObjectWithDefaults(nsSchema);\n            if (nsObj && typeof nsObj === 'object') {\n              finalValue = getValueAtPath(nsObj, segments.slice(1));\n            }\n          }\n\n          if (finalValue === undefined) {\n            console.error(`[AxiomAI] Invalid flag: \"${path}\"`);\n            return undefined;\n          }\n        }\n      }\n\n      source = 'schema';\n    }\n\n    // Validate only overrides (schema values are pre-validated)\n    if (source !== 'schema') {\n      const validation = validateFinalFlagValue(path, finalValue);\n      if (!validation.ok) {\n        console.error(`[AxiomAI] Invalid flag: \"${path}\" - value does not match schema`);\n      }\n    }\n\n    updateEvalContext({ [path]: finalValue });\n\n    const span = trace.getActiveSpan();\n    if (span?.isRecording()) {\n      const attr = toOtelAttribute(finalValue);\n      if (attr) {\n        span.setAttribute(Attr.__EXPERIMENTAL_Flag(path), attr);\n      }\n    }\n\n    return finalValue;\n  }\n\n  /**\n   * Record a typed fact value for tracking and telemetry with dot notation support.\n   * @param name - The fact name/key\n   */\n  function fact<N extends string>(name: N, value: unknown): void {\n    let finalValue = value;\n\n    // Validate with schema if provided (but only log errors for now to match tests)\n    if (factSchemaConfig) {\n      const segments = parsePath(name);\n\n      let success = true;\n      // Fast path check - validate path exists in schema before creating nested object\n      if (!isValidPath(factSchemaConfig, segments)) {\n        success = false;\n      } else {\n        try {\n          // Build a schema specific to this path that makes sibling fields optional\n          const pathSchema = buildSchemaForPath(factSchemaConfig, segments);\n\n          // Convert dot notation to nested object for validation\n          const nested = dotNotationToNested({ [name]: value });\n          const result = pathSchema.safeParse(nested);\n\n          if (!result.success) {\n            success = false;\n          } else {\n            finalValue = getValueAtPath(result.data, segments) ?? value;\n          }\n        } catch (_error) {\n          // buildSchemaForPath can throw if schema structure is invalid\n          success = false;\n        }\n      }\n\n      if (!success) {\n        console.error(`[AxiomAI] Invalid fact: \"${name}\"`);\n      }\n    }\n\n    updateEvalContext(undefined, { [name]: finalValue });\n\n    const span = trace.getActiveSpan();\n    if (span?.isRecording()) {\n      const attr = toOtelAttribute(finalValue);\n      if (attr) {\n        span.setAttribute(Attr.__EXPERIMENTAL_Fact(name), attr);\n      }\n    }\n  }\n\n  /**\n   * Override flag values for the current evaluation context with type safety.\n   * @param partial - Typed flag overrides that must match the flag schema paths and types\n   */\n  function overrideFlags(partial: Record<string, any>): void {\n    const ctx = getEvalContext();\n    Object.assign(ctx.flags, partial);\n  }\n\n  /**\n   * Execute code with temporary flag overrides, automatically restoring original values.\n   * @param overrides - Typed flag overrides that must match the flag schema paths and types\n   * @param fn - Function to execute with the overridden flags\n   * @returns The return value of the executed function\n   */\n  function withFlags<T>(overrides: Record<string, any>, fn: () => T): T {\n    const ctx = getEvalContext();\n    const originalFlags = { ...ctx.flags };\n\n    // Apply overrides\n    Object.assign(ctx.flags, overrides);\n\n    try {\n      return fn();\n    } finally {\n      // Restore original flags by clearing and reassigning\n      Object.keys(ctx.flags).forEach((key) => delete ctx.flags[key]);\n      Object.assign(ctx.flags, originalFlags);\n    }\n  }\n\n  const pickFlags = ((...args: any[]) => {\n    // Handle both array and spread arguments\n    return args[0] && Array.isArray(args[0]) ? args[0] : args;\n  }) as PickFlagsFunction<FlagSchema>;\n\n  function flattenToDot(obj: any, prefix: string[] = [], out: Record<string, any> = {}) {\n    if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n      for (const [k, v] of Object.entries(obj)) {\n        flattenToDot(v, [...prefix, k], out);\n      }\n    } else {\n      if (prefix.length > 0) {\n        out[prefix.join('.')] = obj;\n      }\n    }\n    return out;\n  }\n\n  function getAllDefaultFlags(): Record<string, any> {\n    if (!flagSchemaConfig) return {};\n    const defaultsObj = buildObjectWithDefaults(flagSchemaConfig);\n    if (defaultsObj && typeof defaultsObj === 'object') {\n      return flattenToDot(defaultsObj as Record<string, any>);\n    }\n    return {};\n  }\n\n  const scope = {\n    flag: flag as any as DotNotationFlagFunction<FlagSchema>,\n    fact: fact as any as FactFunction<FactSchema>,\n    overrideFlags: overrideFlags as any as OverrideFlagsFunction<FlagSchema>,\n    withFlags: withFlags as any as WithFlagsFunction<FlagSchema>,\n    pickFlags,\n    getAllDefaultFlags,\n  } as AppScope<FlagSchema, FactSchema>;\n\n  // Expose scope to current eval context for downstream collection (suite-end summaries)\n  setConfigScope(scope as any);\n\n  return scope;\n}\n","import { trace } from '@opentelemetry/api';\nimport { createAsyncHook } from './manager';\nimport { type createAppScope } from '../../app-scope';\nimport type { ResolvedAxiomConfig } from '../../config/index';\nimport type { OutOfScopeFlagAccess } from '../eval.types';\n\n// Global fallback for config scope when called outside of eval context (e.g., module import time)\nconst CONFIG_SCOPE_SYMBOL = Symbol.for('axiom.eval.configScope');\nfunction getGlobalConfigScope(): ReturnType<typeof createAppScope> | undefined {\n  return (globalThis as any)[CONFIG_SCOPE_SYMBOL];\n}\nfunction setGlobalConfigScope(scope: ReturnType<typeof createAppScope>) {\n  (globalThis as any)[CONFIG_SCOPE_SYMBOL] = scope;\n}\n\n// Global storage for axiom config (accessible from reporters)\nconst AXIOM_CONFIG_SYMBOL = Symbol.for('axiom.eval.config');\nexport function getAxiomConfig(): ResolvedAxiomConfig | undefined {\n  return (globalThis as any)[AXIOM_CONFIG_SYMBOL];\n}\nexport function setAxiomConfig(config: ResolvedAxiomConfig) {\n  (globalThis as any)[AXIOM_CONFIG_SYMBOL] = config;\n}\n\n// Mini-context for in-process access\nexport const EVAL_CONTEXT = createAsyncHook<{\n  flags: Record<string, any>;\n  facts: Record<string, any>;\n  configScope?: ReturnType<typeof createAppScope>;\n  pickedFlags?: string[];\n  outOfScopeFlags?: OutOfScopeFlagAccess[];\n  parent?: EvalContextData<any, any>;\n  overrides?: Record<string, any>;\n  accessedFlagKeys?: string[];\n}>('eval-context');\n\nexport interface EvalContextData<Flags = any, Facts = any> {\n  flags: Partial<Flags>;\n  facts: Partial<Facts>;\n  configScope?: ReturnType<typeof createAppScope>;\n  pickedFlags?: string[];\n  outOfScopeFlags?: OutOfScopeFlagAccess[];\n  parent?: EvalContextData<Flags, Facts>;\n  overrides?: Record<string, any>;\n  accessedFlagKeys?: string[];\n}\n\nexport function getEvalContext<\n  Flags extends Record<string, unknown> = any,\n  Facts extends Record<string, unknown> = any,\n>(): EvalContextData<Flags, Facts> {\n  const ctx = EVAL_CONTEXT.get();\n  if (!ctx) {\n    // Return empty context if none exists\n    return {\n      flags: {} as Partial<Flags>,\n      facts: {} as Partial<Facts>,\n      pickedFlags: undefined,\n      outOfScopeFlags: undefined,\n    };\n  }\n  return {\n    flags: ctx.flags as Partial<Flags>,\n    facts: ctx.facts as Partial<Facts>,\n    pickedFlags: ctx.pickedFlags,\n    outOfScopeFlags: ctx.outOfScopeFlags,\n    parent: ctx.parent,\n    overrides: ctx.overrides,\n    accessedFlagKeys: ctx.accessedFlagKeys,\n  };\n}\n\nexport function updateEvalContext(flags?: Record<string, any>, facts?: Record<string, any>) {\n  const current = EVAL_CONTEXT.get();\n  if (!current) {\n    // Silently return - this is expected when running capabilities outside of eval\n    return;\n  }\n\n  // Mutate the existing context (safe within the same async context)\n  if (flags) {\n    Object.assign(current.flags, flags);\n    // Track accessed flag keys for runtime reporting\n    if (!current.accessedFlagKeys) current.accessedFlagKeys = [];\n    for (const key of Object.keys(flags)) {\n      if (!current.accessedFlagKeys.includes(key)) {\n        current.accessedFlagKeys.push(key);\n      }\n    }\n  }\n  if (facts) {\n    Object.assign(current.facts, facts);\n  }\n}\n\n/**\n * Parse stack trace to extract relevant frames, filtering out internal/framework frames\n */\nfunction parseStackTrace(stack: string): string[] {\n  const lines = stack.split('\\n');\n  const frames: string[] = [];\n\n  for (const line of lines) {\n    const trimmed = line.trim();\n\n    if (!trimmed || !trimmed.startsWith('at ')) {\n      continue;\n    }\n\n    // filter out frames that users likely don't care about\n    if (\n      trimmed.includes('node_modules') ||\n      trimmed.includes('node:internal') ||\n      trimmed.includes('addOutOfScopeFlag') ||\n      trimmed.includes('storage.ts') ||\n      // Keep app-scope.ts frames that aren't the flag() function itself\n      (trimmed.includes('app-scope.ts') &&\n        (trimmed.includes('flag (') || trimmed.includes('flag2 (')))\n    ) {\n      continue;\n    }\n\n    frames.push(trimmed.replace('at ', ''));\n  }\n\n  return frames.slice(0, 5);\n}\n\nexport function addOutOfScopeFlag(flagPath: string) {\n  const current = EVAL_CONTEXT.get();\n  if (!current) {\n    console.warn('addOutOfScopeFlag called outside of evaluation context');\n    return;\n  }\n\n  if (!current.outOfScopeFlags) {\n    current.outOfScopeFlags = [];\n  }\n\n  const stack = new Error().stack || '';\n  const stackTrace = parseStackTrace(stack);\n\n  current.outOfScopeFlags.push({\n    flagPath,\n    accessedAt: Date.now(),\n    stackTrace,\n  });\n}\n\n// Helper: write to current span + context\nexport function putOnSpan(kind: 'flag' | 'fact', key: string, value: any) {\n  const span = trace.getActiveSpan();\n  if (span?.isRecording()) {\n    span.setAttributes({ [`${kind}.${key}`]: value });\n  }\n}\n\n/**\n * Resolve a flag value by walking the parent chain, checking overrides first\n */\nexport function resolveFlagValue<V>(ctx: EvalContextData<any, any>, key: string): V {\n  // First check current context overrides\n  if (ctx.overrides && key in ctx.overrides) {\n    return ctx.overrides[key] as V;\n  }\n\n  // Then check current context flags\n  if (key in ctx.flags) {\n    return ctx.flags[key] as V;\n  }\n\n  // Walk up the parent chain\n  if (ctx.parent) {\n    return resolveFlagValue(ctx.parent, key);\n  }\n\n  // This should not happen\n  // Return undefined as a fallback\n  console.error(`[AxiomAI] Flag \"${key}\" not found in context, returning undefined`);\n  return undefined as V;\n}\n\n/**\n * Create an overlay context that inherits from the current context\n * but isolates overrides to this specific execution context.\n */\nfunction createOverlayContext(overrides: Record<string, any>): any {\n  const current = EVAL_CONTEXT.get();\n  if (!current) {\n    if (process.env.NODE_ENV !== 'test') {\n      console.warn('createOverlayContext called outside of evaluation context');\n    }\n    return {\n      flags: { ...overrides },\n      facts: {},\n      pickedFlags: [],\n      outOfScopeFlags: [],\n      overrides: { ...overrides },\n    };\n  }\n\n  // Create merged flags for backwards compatibility\n  const mergedFlags = { ...current.flags, ...overrides };\n\n  return {\n    ...current,\n    flags: mergedFlags,\n    parent: current,\n    overrides: { ...overrides },\n  };\n}\n\n/**\n * Execute a function with flag overrides that are isolated to the execution context.\n * This creates an overlay context that inherits from the current context but isolates\n * the overrides to prevent them from leaking to sibling operations.\n */\nexport function withFlagOverrides<T>(overrides: Record<string, any>, fn: () => T): T {\n  const overlayContext = createOverlayContext(overrides);\n\n  // Write overridden flags to span for observability\n  for (const [key, value] of Object.entries(overrides)) {\n    putOnSpan('flag', key, value);\n  }\n\n  return EVAL_CONTEXT.run(overlayContext, fn);\n}\n\nexport function withEvalContext<T>(\n  options: {\n    initialFlags?: Record<string, any>;\n    pickedFlags?: string[];\n  } = {},\n  fn: () => T,\n): T {\n  const { initialFlags = {}, pickedFlags = [] } = options;\n  return EVAL_CONTEXT.run(\n    {\n      flags: { ...initialFlags },\n      facts: {},\n      pickedFlags,\n      outOfScopeFlags: [],\n      accessedFlagKeys: [],\n    },\n    fn,\n  );\n}\n\n/**\n * Set the config scope for the current evaluation context.\n * This makes the scope available for global flag/fact access.\n *\n * Also stores a global fallback so suite-end summary can access schema defaults\n * even if createAppScope ran outside the active async context.\n */\nexport function setConfigScope(scope: ReturnType<typeof createAppScope>) {\n  const current = EVAL_CONTEXT.get();\n  if (current) {\n    current.configScope = scope;\n  }\n  // Always set global fallback\n  setGlobalConfigScope(scope);\n}\n\n/**\n * Get the config scope from the current evaluation context.\n * Falls back to global scope when no context is active.\n */\nexport function getConfigScope(): ReturnType<typeof createAppScope> | undefined {\n  const current = EVAL_CONTEXT.get();\n  return current?.configScope ?? getGlobalConfigScope();\n}\n\n/**\n * Get the picked flags from the current evaluation context.\n * Returns undefined if no picked flags are set or if called outside eval context.\n */\nexport function getPickedFlags(): string[] | undefined {\n  return EVAL_CONTEXT.get()?.pickedFlags;\n}\n","import type { AxiomEvalInstrumentationOptions, ResolvedAxiomConfig } from './index';\n\n/**\n * Builds a resources URL under the assumption that the API URL is in the format of https://api.axiom.co by replacing the subdomain with app.\n * @param urlString - The API URL\n * @returns The resources URL\n */\nconst buildConsoleUrl = (urlString: string) => {\n  const url = new URL(urlString);\n\n  return `${url.protocol}//app.${url.host.split('api.').at(-1)}`;\n};\n\n/**\n * Resolve Axiom connection settings from resolved config.\n *\n * Since the config is already resolved with defaults merged, we can directly\n * access the properties without fallback chains.\n *\n * @param config - The resolved configuration\n * @returns Resolved connection settings\n */\nexport function resolveAxiomConnection(\n  config: ResolvedAxiomConfig,\n  consoleUrlOverride?: string,\n): AxiomEvalInstrumentationOptions & { consoleEndpointUrl: string } {\n  const consoleEndpointUrl = consoleUrlOverride ?? buildConsoleUrl(config.eval.url);\n  // Use edgeUrl for ingest/query operations, falling back to url if not specified\n  const edgeUrl = config.eval.edgeUrl || config.eval.url;\n\n  return {\n    url: config.eval.url,\n    edgeUrl,\n    consoleEndpointUrl: consoleEndpointUrl,\n    token: config.eval.token,\n    dataset: config.eval.dataset,\n    orgId: config.eval.orgId,\n  };\n}\n\nexport type AxiomConnectionResolvedConfig = ReturnType<typeof resolveAxiomConnection>;\n","export class AxiomCLIError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = 'AxiomCLIError';\n  }\n}\n\nfunction getCircularReplacer() {\n  const seen = new WeakSet();\n  return (_k: string, v: any) => {\n    if (typeof v === 'object' && v !== null) {\n      if (seen.has(v)) return '[Circular]';\n      seen.add(v);\n    }\n    return v;\n  };\n}\n\nfunction safeJson(x: any) {\n  try {\n    return JSON.stringify(x, getCircularReplacer());\n  } catch {\n    return String(x);\n  }\n}\n\nexport function errorToString(err: unknown) {\n  try {\n    if (typeof err === 'string') return err;\n\n    if (err instanceof Error) {\n      return err.stack ?? err.message;\n    }\n\n    if (typeof err === 'object' && err !== null) {\n      const msg = (err as any).message;\n      const json = safeJson(err);\n      return msg ? `${msg} (${json})` : json;\n    }\n\n    return String(err);\n  } catch {\n    return '[unserializable error]';\n  }\n}\n","export interface Profile {\n  url: string;\n  token: string;\n  org_id: string;\n}\n\nexport interface Config {\n  active_profile?: string;\n  profiles: Record<string, Profile>;\n}\n\nexport interface OAuthTokenResponse {\n  access_token: string;\n  token_type: string;\n  expires_in?: number;\n  refresh_token?: string;\n  scope?: string;\n}\n\nexport interface Organization {\n  id: string;\n  name: string;\n  slug?: string;\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport type { Config, Profile } from './types';\n\nconst CONFIG_FILENAME = 'config.json';\nconst CONFIG_DIR_NAME = 'axiom';\n\n/**\n * Gets the OS-appropriate config directory path.\n * - Linux/Unix: ~/.config/axiom\n * - macOS: ~/Library/Application Support/axiom\n * - Windows: %APPDATA%\\axiom\n */\nexport function getConfigDir(): string {\n  const platform = process.platform;\n  const homeDir = os.homedir();\n\n  // Linux/Unix: ~/.config/axiom (or $XDG_CONFIG_HOME/axiom if set)\n  const xdgConfigHome = process.env.XDG_CONFIG_HOME;\n  if (xdgConfigHome) {\n    return path.join(xdgConfigHome, CONFIG_DIR_NAME);\n  }\n\n  if (platform === 'win32') {\n    // Windows: %APPDATA%\\axiom\n    const appData = process.env.APPDATA;\n    if (appData) {\n      return path.join(appData, CONFIG_DIR_NAME);\n    }\n    // Fallback to home directory if APPDATA is not set\n    return path.join(homeDir, 'AppData', 'Roaming', CONFIG_DIR_NAME);\n  }\n\n  return path.join(homeDir, '.config', CONFIG_DIR_NAME);\n}\n\n/**\n * Gets the full path to the config file.\n */\nexport function getGlobalConfigPath(): string {\n  return path.join(getConfigDir(), CONFIG_FILENAME);\n}\n\nexport async function loadGlobalConfig(): Promise<Config> {\n  const configPath = getGlobalConfigPath();\n  try {\n    const content = await fs.readFile(configPath, 'utf-8');\n    return JSON.parse(content);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n      return { profiles: {} };\n    }\n    throw error;\n  }\n}\n\nexport async function saveGlobalConfig(config: Config): Promise<void> {\n  const configPath = getGlobalConfigPath();\n  const configDir = path.dirname(configPath);\n  const content = JSON.stringify(config, null, 2);\n\n  // Ensure config directory exists\n  await fs.mkdir(configDir, { recursive: true, mode: 0o700 });\n\n  // Write config file\n  await fs.writeFile(configPath, content, 'utf-8');\n\n  // Set restrictive permissions (read/write for owner only)\n  // Note: chmod is a no-op on Windows, but that's fine\n  await fs.chmod(configPath, 0o600);\n}\n\nexport function getActiveProfile(config: Config): Profile | null {\n  // Get from config\n  const profileName = config.active_profile;\n  if (!profileName) return null;\n\n  const profile = config.profiles[profileName];\n  if (!profile) return null;\n\n  return profile;\n}\n","import { randomBytes, createHash } from 'crypto';\nimport type { OAuthTokenResponse } from './types';\n\nconst OAUTH_CLIENT_ID = '264d906a404efc209b027f6595e6b616';\nconst OAUTH_AUTH_PATH = '/oauth/authorize';\nconst OAUTH_TOKEN_PATH = '/oauth/token';\n\nexport interface BuildAuthUrlParams {\n  redirectUri: string;\n  state: string;\n  codeChallenge: string;\n}\n\nexport interface ExchangeCodeParams {\n  code: string;\n  redirectUri: string;\n  codeVerifier: string;\n}\n\nexport class OAuth {\n  constructor(private readonly oauthBaseUrl: string) {}\n\n  static generateCodeVerifier(): string {\n    return randomBytes(32).toString('base64url');\n  }\n\n  static generateCodeChallenge(verifier: string): string {\n    return createHash('sha256').update(verifier).digest('base64url');\n  }\n\n  static generateState(): string {\n    return randomBytes(16).toString('hex');\n  }\n\n  public buildAuthUrl(params: BuildAuthUrlParams): string {\n    const url = new URL(OAUTH_AUTH_PATH, this.oauthBaseUrl);\n    url.searchParams.set('client_id', OAUTH_CLIENT_ID);\n    url.searchParams.set('redirect_uri', params.redirectUri);\n    url.searchParams.set('response_type', 'code');\n    url.searchParams.set('state', params.state);\n    url.searchParams.set('code_challenge', params.codeChallenge);\n    url.searchParams.set('code_challenge_method', 'S256');\n    url.searchParams.set('scope', '*');\n    return url.toString();\n  }\n\n  public async exchangeCodeForToken(params: ExchangeCodeParams): Promise<string> {\n    const tokenUrl = new URL(OAUTH_TOKEN_PATH, this.oauthBaseUrl);\n\n    const body = new URLSearchParams({\n      grant_type: 'authorization_code',\n      client_id: OAUTH_CLIENT_ID,\n      code: params.code,\n      redirect_uri: params.redirectUri,\n      code_verifier: params.codeVerifier,\n    });\n\n    const response = await fetch(tokenUrl.toString(), {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/x-www-form-urlencoded',\n      },\n      body: body.toString(),\n    });\n\n    if (!response.ok) {\n      const errorText = await response.text();\n      throw new Error(`Token exchange failed: ${response.status} ${errorText}`);\n    }\n\n    const data: OAuthTokenResponse = await response.json();\n    return data.access_token;\n  }\n}\n","import { AxiomCLIError } from '../../util/errors';\nimport type { Organization } from './types';\n\nexport async function fetchOrganizations(\n  token: string,\n  apiBaseUrl: string,\n): Promise<Organization[]> {\n  const response = await fetch(`${apiBaseUrl}/v2/orgs`, {\n    headers: {\n      Authorization: `Bearer ${token}`,\n      'Content-Type': 'application/json',\n    },\n  });\n\n  if (!response.ok) {\n    throw new AxiomCLIError(\n      `Failed to fetch organizations: ${response.status} ${response.statusText}`,\n    );\n  }\n\n  const data = await response.json();\n  return data as Organization[];\n}\n\nexport async function verifyToken(\n  token: string,\n  orgId: string,\n  apiBaseUrl: string,\n): Promise<boolean> {\n  const response = await fetch(`${apiBaseUrl}/v2/user`, {\n    headers: {\n      Authorization: `Bearer ${token}`,\n      'X-Axiom-Org-Id': orgId,\n      'Content-Type': 'application/json',\n    },\n  });\n\n  return response.ok;\n}\n","import http, { type IncomingMessage, type ServerResponse } from 'http';\nimport type { AddressInfo } from 'net';\n\nfunction escapeHtml(text: string): string {\n  const map: Record<string, string> = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#039;',\n    '`': '&#96;',\n  };\n  return text.replace(/[&<>\"']/g, (m) => map[m] || m);\n}\n\nconst SVG_LOGO = `<svg width=\"124\" height=\"24\" viewBox=\"0 0 124 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"logo\">\n<path d=\"M42.9919 16.8116H36.3696L35.5537 19.1572C35.4209 19.539 34.9714 19.8513 34.5548 19.8513H30.9779C30.5614 19.8513 30.3459 19.5449 30.499 19.1703L36.9816 3.31644C37.1346 2.9419 37.6009 2.63546 38.0174 2.63546H41.3718C41.7883 2.63546 42.2541 2.94207 42.4067 3.3168L48.8634 19.17C49.016 19.5447 48.8 19.8513 48.3835 19.8513H44.8067C44.3901 19.8513 43.9406 19.539 43.8078 19.1572L42.9919 16.8116ZM41.8232 13.4223L39.6807 7.18148L37.5383 13.4223H41.8232ZM64.1105 19.8513C63.694 19.8513 63.1767 19.5694 62.9611 19.2247L59.9029 14.3369L56.8447 19.2247C56.6291 19.5694 56.1119 19.8513 55.6953 19.8513H51.3392C50.9227 19.8513 50.7754 19.5801 51.0119 19.2486L56.8978 11.0013L51.5315 3.24414C51.2999 2.90937 51.4513 2.63546 51.8679 2.63546H55.89C56.3066 2.63546 56.8268 2.91563 57.0461 3.25807L59.9029 7.71959L62.7343 3.25955C62.9522 2.9163 63.4713 2.63546 63.8879 2.63546H67.938C68.3545 2.63546 68.5048 2.90868 68.272 3.24261L62.8801 10.9743L68.7935 19.2489C69.0303 19.5802 68.8832 19.8513 68.4666 19.8513H64.1105ZM76.525 19.119C76.525 19.5218 76.1841 19.8513 75.7675 19.8513H72.5522C72.1356 19.8513 71.7947 19.5218 71.7947 19.119V3.36771C71.7947 2.96498 72.1356 2.63546 72.5522 2.63546H75.7675C76.1841 2.63546 76.525 2.96498 76.525 3.36771V19.119ZM79.3736 11.1896C79.3736 6.18625 83.2688 2.15134 89.2511 2.15134C95.2334 2.15134 99.1289 6.18625 99.1289 11.1896C99.1289 16.2199 95.2334 20.2548 89.2511 20.2548C83.2688 20.2548 79.3736 16.2199 79.3736 11.1896ZM94.2873 11.1896C94.2873 8.58038 92.3953 6.21307 89.2511 6.21307C86.1349 6.21307 84.2149 8.58038 84.2149 11.1896C84.2149 13.7989 86.1349 16.2199 89.2511 16.2199C92.3675 16.2199 94.2873 13.7989 94.2873 11.1896ZM119.318 19.8513C118.902 19.8513 118.517 19.5245 118.463 19.1251L117.225 9.89847L113.65 19.1652C113.505 19.5426 113.045 19.8513 112.628 19.8513H111.055C110.638 19.8513 110.179 19.5423 110.034 19.1645L106.457 9.81766L105.218 19.125C105.165 19.5245 104.781 19.8513 104.364 19.8513H101.344C100.927 19.8513 100.633 19.5249 100.69 19.1259L102.932 3.3609C102.988 2.96191 103.376 2.63546 103.792 2.63546H106.59C107.007 2.63546 107.469 2.94351 107.617 3.32002L111.827 14.041L116.064 3.31949C116.213 2.94327 116.676 2.63546 117.092 2.63546H119.89C120.307 2.63546 120.694 2.96191 120.751 3.3609L122.993 19.1259C123.05 19.5249 122.755 19.8513 122.339 19.8513H119.318ZM23.9616 15.6531L18.8054 6.97021C18.5689 6.57115 17.9863 6.24465 17.5106 6.24465H14.2915C13.5433 6.24465 13.2365 5.73171 13.6097 5.1048L15.375 2.13986C15.5151 1.90455 15.5148 1.61487 15.3743 1.37981C15.2337 1.14476 14.9741 1 14.6933 1H10.2025C9.72681 1 9.14291 1.32577 8.90491 1.72395L0.17865 16.3217C-0.0594434 16.7199 -0.0595348 17.3715 0.178285 17.7698L2.42362 21.5297C2.79777 22.1561 3.41129 22.1569 3.78699 21.5313L5.54143 18.6103C5.91722 17.9847 6.53065 17.9854 6.9048 18.6119L8.49538 21.2754C8.7332 21.6737 9.317 21.9995 9.79273 21.9995H20.1698C20.6455 21.9995 21.2293 21.6737 21.4672 21.2754L23.959 17.1028C24.1968 16.7045 24.198 16.0521 23.9616 15.6531ZM16.9981 15.2352C17.3699 15.8629 17.0619 16.3765 16.3136 16.3765H8.24192C7.49372 16.3765 7.1876 15.864 7.56175 15.2375L11.6007 8.47417C11.9748 7.84772 12.5869 7.84774 12.9611 8.47421L16.9981 15.2352Z\" fill=\"#121224\"/>\n</svg>`;\n\nfunction renderCallbackPage(error?: string): string {\n  const errorClass = error ? ' class=\"error\"' : '';\n  const errorMessage = error ? escapeHtml(error) : '';\n\n  return `<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <title>Axiom</title>\n    <link rel=\"icon\" href=\"https://app.axiom.co/static/favicon.ico\">\n    <meta name=\"description\" content=\"Axiom CLI\">\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n    <style>\n        html,\n        body,\n        .root {\n            width: 100%;\n            height: 100%;\n            text-rendering: optimizeLegibility;\n            -webkit-font-smoothing: antialiased;\n        }\n        body {\n            color: #334155;\n            font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;\n            font-size: 14px;\n            font-weight: 500;\n            font-variant: tabular-nums;\n            line-height: 1.5;\n            background-color: #fff;\n            font-feature-settings: \"tnum\";\n            margin: 0;\n        }\n        h1,\n        h2,\n        h3,\n        h4,\n        h5,\n        h6 {\n            margin-top: 0;\n            margin-bottom: .5em;\n            font-weight: 500;\n        }\n        p {\n            margin-top: 0;\n            margin-bottom: 1em;\n        }\n        h2 {\n            font-size: 16px;\n            font-weight: 600;\n        }\n        .root {\n            display: flex;\n            align-items: center;\n            justify-content: center;\n        }\n        .logo {\n            width: 92px;\n            float: left;\n            position: absolute;\n            top: 16px;\n            left: 16px;\n        }\n        .center p {\n            padding: 8px 0;\n        }\n        .error .center {\n            color: #bf0e08;\n        }\n    </style>\n</head>\n<body${errorClass}>\n    <div class=\"root\">\n        <a class=\"\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://axiom.co\">\n          ${SVG_LOGO}\n        </svg>\n        </a>\n        <div class=\"center\">\n            ${\n              error\n                ? `<h2 id=\"msg\">Login failed</h2>\n            <p id=\"details\">${errorMessage}</p>`\n                : `<h2 id=\"msg\">Login successful</h2>\n            <p id=\"details\">You can close this page and return to your CLI.</p>`\n            }\n        </div>\n    </div>\n    <script>\n        window.history.replaceState({}, '', \\`\\${window.location.pathname}\\`);\n    </script>\n</body>\n</html>`;\n}\n\nexport interface CallbackServerResult {\n  server: http.Server;\n  port: number;\n  url: string;\n}\n\nexport async function startCallbackServer(): Promise<CallbackServerResult> {\n  return new Promise((resolve) => {\n    const server = http.createServer();\n    server.listen(0, '127.0.0.1', () => {\n      const address = server.address() as AddressInfo;\n      resolve({\n        server,\n        port: address.port,\n        url: `http://127.0.0.1:${address.port}`,\n      });\n    });\n  });\n}\n\nexport interface CallbackResult {\n  code: string;\n}\n\nexport async function waitForCallback(\n  server: http.Server,\n  expectedState: string,\n): Promise<CallbackResult> {\n  return new Promise((resolve, reject) => {\n    const timeout = setTimeout(\n      () => {\n        server.close();\n        reject(new Error('Authentication timeout after 5 minutes'));\n      },\n      5 * 60 * 1000,\n    ); // 5 minute timeout\n\n    server.on('request', (req: IncomingMessage, res: ServerResponse) => {\n      const url = new URL(req.url || '', `http://${req.headers.host}`);\n      const code = url.searchParams.get('code');\n      const state = url.searchParams.get('state');\n      const error = url.searchParams.get('error');\n      const errorDescription = url.searchParams.get('error_description');\n\n      if (error) {\n        const errorMsg = errorDescription || error;\n        res.writeHead(400, { 'Content-Type': 'text/html' });\n        res.end(renderCallbackPage(errorMsg));\n        clearTimeout(timeout);\n        server.close();\n        reject(new Error(`OAuth error: ${errorMsg}`));\n        return;\n      }\n\n      if (!code || !state) {\n        res.writeHead(400, { 'Content-Type': 'text/html' });\n        res.end(renderCallbackPage('Missing code or state parameter'));\n        return;\n      }\n\n      if (state !== expectedState) {\n        res.writeHead(400, { 'Content-Type': 'text/html' });\n        res.end(renderCallbackPage('Invalid state parameter (CSRF protection)'));\n        clearTimeout(timeout);\n        server.close();\n        reject(new Error('Invalid state parameter'));\n        return;\n      }\n\n      res.writeHead(200, { 'Content-Type': 'text/html' });\n      res.end(renderCallbackPage());\n\n      clearTimeout(timeout);\n      server.close();\n      resolve({ code });\n    });\n  });\n}\n","import { loadGlobalConfig, getActiveProfile } from './config';\n\nexport interface AuthContext {\n  readonly token: string;\n  readonly url: string;\n  readonly orgId: string;\n}\n\n/**\n * Module-level store for auth context.\n * This provides explicit, type-safe access to auth credentials.\n */\nlet authContext: AuthContext | null = null;\n\n/**\n * Gets the current auth context.\n * Returns null if auth hasn't been set up yet.\n */\nexport function getAuthContext(): AuthContext | null {\n  return authContext;\n}\n\n/**\n * Sets up authentication context by loading config and storing it.\n *\n * @throws {AxiomCLIError} If no active profile is found\n */\nexport async function setupGlobalAuth(): Promise<AuthContext | null> {\n  const config = await loadGlobalConfig();\n  const profile = getActiveProfile(config);\n  if (profile) {\n    // Store in module-level context for explicit access\n    authContext = {\n      token: profile.token,\n      url: profile.url,\n      orgId: profile.org_id,\n    };\n  }\n\n  return authContext;\n}\n\n/**\n * Resets the auth context (useful for testing).\n */\nexport function resetAuthContext(): void {\n  authContext = null;\n}\n","export * from './types';\nexport * from './config';\nexport * from './oauth';\nexport * from './api';\nexport * from './callback-server';\nexport * from './global-auth';\n","import type { TracerProvider } from '@opentelemetry/api';\nimport { type z } from 'zod';\nimport { AxiomCLIError } from '../util/errors';\nimport { getAuthContext } from '../cli/auth';\n\n/**\n * Utility type to make all properties in T required recursively.\n * Keeps the types as-is but removes the optionality.\n */\ntype DeepRequired<T> =\n  T extends Array<infer U>\n    ? Array<U>\n    : T extends (...args: any[]) => any\n      ? T\n      : T extends object\n        ? {\n            [P in keyof T]-?: DeepRequired<T[P]>;\n          }\n        : T;\n\n/**\n * Axiom API connection configuration\n */\nexport interface AxiomConnectionConfig {\n  /**\n   * Axiom API URL\n   * @default 'https://api.axiom.co'\n   * @example 'https://api.axiom.co'\n   */\n  url?: string;\n\n  /**\n   * Axiom Edge URL for ingest and query operations.\n   * When set, this URL is used for sending traces and querying data,\n   * while the regular `url` is used for API/console operations.\n   * Falls back to `url` if not specified.\n   * @example 'https://eu-central-1.aws.edge.axiom.co'\n   */\n  edgeUrl?: string;\n\n  /**\n   * Axiom API token (can be undefined if not set)\n   * @example process.env.AXIOM_TOKEN\n   */\n  token?: string | undefined;\n\n  /**\n   * Axiom dataset name\n   * @example process.env.AXIOM_DATASET\n   */\n  dataset?: string;\n\n  /**\n   * Axiom organization ID\n   * @example process.env.AXIOM_ORG_ID\n   */\n  orgId?: string;\n}\n\n/**\n * Options passed to the instrumentation hook\n * - url: string\n * - token: string\n * - dataset: string\n */\nexport interface AxiomEvalInstrumentationOptions {\n  url: string;\n  edgeUrl: string;\n  token: string;\n  dataset: string;\n  orgId?: string;\n}\n\n/**\n * Result returned from the instrumentation hook\n */\nexport interface AxiomEvalInstrumentationResult {\n  /**\n   * TracerProvider to be flushed when eval finishes.\n   *\n   * If you use the NodeSDK or register your provider globally, you don't need to return it\n   * here as the NodeSDK automatically flushes the global provider.\n   *\n   * Only return a provider if you want Axiom to explicitly flush it for you and it's not\n   * registered as the global tracer provider.\n   */\n  provider?: TracerProvider;\n}\n\nexport type SyncAxiomEvalInstrumentationHook = (\n  options: AxiomEvalInstrumentationOptions,\n) => AxiomEvalInstrumentationResult;\n\nexport type AsyncAxiomEvalInstrumentationHook = (\n  options: AxiomEvalInstrumentationOptions,\n) => Promise<AxiomEvalInstrumentationResult>;\n\n/**\n * Hook function to initialize application OpenTelemetry instrumentation.\n * Called before eval execution with resolved Axiom connection details.\n *\n * @param options - Configuration options\n * @param options.url - Axiom API URL\n * @param options.token - Axiom API token\n * @param options.dataset - Axiom dataset name\n * @returns TracerProvider or Promise resolving to TracerProvider\n *\n * @example\n * ```typescript\n * instrumentation: ({ url, token, dataset }) => {\n *   return setupAppInstrumentation({ url, token, dataset });\n * }\n * ```\n */\nexport type AxiomEvalInstrumentationHook = (\n  options: AxiomEvalInstrumentationOptions,\n) => AxiomEvalInstrumentationResult | Promise<AxiomEvalInstrumentationResult>;\n\n/**\n * Axiom AI SDK base configuration (user-facing, all optional)\n */\nexport const DEFAULT_EVAL_INCLUDE = ['**/*.eval.{ts,js,mts,mjs,cts,cjs}'] as const;\n\nexport interface AxiomConfigBase {\n  /**\n   * Eval configuration settings\n   *\n   * @example\n   * ```typescript\n   * eval: {\n   *   url: process.env.AXIOM_URL,\n   *   token: process.env.AXIOM_TOKEN,\n   *   dataset: process.env.AXIOM_DATASET\n   * }\n   * ```\n   */\n  eval?: AxiomConnectionConfig & {\n    /**\n     * Zod schema for flag validation.\n     * When provided, CLI flags (--flag.*) are validated against this schema\n     * before eval execution begins.\n     *\n     * @example\n     * ```typescript\n     * import { z } from 'zod';\n     *\n     * export default defineConfig({\n     *   eval: {\n     *     flagSchema: z.object({\n     *       model: z.object({\n     *         temperature: z.number().min(0).max(2).default(0.7),\n     *         name: z.string().default('gpt-4o'),\n     *       }),\n     *     }),\n     *   }\n     * });\n     * ```\n     */\n    flagSchema?: z.ZodObject<any> | null;\n    /**\n     * Optional hook to initialize application OpenTelemetry instrumentation.\n     * Called before eval execution with resolved Axiom connection details.\n     * Return your configured tracer provider/tracer (or void) after registering them.\n     */\n    instrumentation?: AxiomEvalInstrumentationHook | null;\n    /**\n     * Timeout for eval execution in milliseconds\n     * @default 60000\n     */\n    timeoutMs?: number;\n    /**\n     * Glob patterns to include when running evals\n     * @default ['**\\/*.eval.{ts,js,mts,mjs,cts,cjs}']\n     * @example ['**\\/*.eval.ts', 'tests/**\\/*.test.ts']\n     */\n    include?: string[];\n    /**\n     * Glob patterns to exclude when running evals\n     * @default ['**\\/node_modules/**', '**\\/dist/**', '**\\/build/**']\n     * @example ['**\\/node_modules/**', '**\\/.next/**']\n     */\n    exclude?: string[];\n  };\n}\n\n/**\n * Resolved Axiom AI SDK configuration with all required keys.\n * This is the type returned after merging user config with defaults.\n *\n * Uses DeepRequired to ensure all optional properties from AxiomConfigBase\n * become required, preventing missing properties in the resolved config.\n */\nexport type ResolvedAxiomConfig = DeepRequired<AxiomConfigBase>;\n\n/**\n * Axiom AI SDK configuration with optional environment-specific overrides.\n *\n * Supports c12 environment overrides using $development, $production, etc.\n *\n * @example\n * ```typescript\n * export default defineConfig({\n *   eval: {\n *     url: process.env.AXIOM_URL,\n *     token: process.env.AXIOM_TOKEN,\n *     dataset: process.env.AXIOM_DATASET,\n *   },\n * })\n * ```\n */\nexport interface AxiomConfig extends AxiomConfigBase {\n  /**\n   * Allow c12 environment-specific overrides ($development, $production, $test etc.)\n   * but don't show them in autocomplete for now\n   */\n  [key: `$${string}`]: Partial<AxiomConfigBase> | undefined;\n}\n\n/**\n * Type-safe helper for defining Axiom configuration.\n *\n * @param config - The configuration object\n * @returns The same configuration object with type checking\n *\n * @example\n * ```typescript\n * import { defineConfig } from 'axiom/ai/config';\n *\n * export default defineConfig({\n *   eval: {\n *     url: process.env.AXIOM_URL,\n *     token: process.env.AXIOM_TOKEN,\n *     dataset: process.env.AXIOM_DATASET,\n *     include: ['**\\/*.eval.{ts,js}'],\n *     instrumentation: ({ url, token, dataset }) => setupAppInstrumentation({ url, token, dataset }),\n *   },\n * });\n * ```\n */\nexport function defineConfig(config: AxiomConfig): AxiomConfig {\n  return config;\n}\n\n/**\n * Create partial default configuration from auth context or environment variables.\n * Does not throw if required values are missing - validation happens after merge.\n *\n * @returns Partial configuration with defaults and auth/env var values\n * @internal\n */\nexport function createPartialDefaults(): Partial<AxiomConfigBase> {\n  // Try to get auth context first (available when running via CLI)\n  // Fall back to process.env for backward compatibility (e.g., when used outside CLI)\n  let token: string | undefined;\n  let url: string | undefined;\n  let orgId: string | undefined;\n\n  try {\n    const authContext = getAuthContext();\n    if (authContext) {\n      token = authContext.token;\n      url = authContext.url;\n      orgId = authContext.orgId;\n    }\n  } catch {\n    // Auth context not available, fall back to env vars\n  }\n\n  // Fall back to process.env if auth context not available\n  token = token || process.env.AXIOM_TOKEN;\n  url = url || process.env.AXIOM_URL;\n  orgId = orgId || process.env.AXIOM_ORG_ID;\n\n  // Edge URL for ingest and query operations\n  const edgeUrl = process.env.AXIOM_EDGE_URL;\n\n  return {\n    eval: {\n      url: url || 'https://api.axiom.co',\n      edgeUrl: edgeUrl,\n      orgId,\n      token,\n      dataset: process.env.AXIOM_DATASET,\n      flagSchema: undefined,\n      instrumentation: null,\n      include: [...DEFAULT_EVAL_INCLUDE],\n      exclude: [],\n      timeoutMs: 60_000,\n    },\n  };\n}\n\n/**\n * Validates and returns a fully resolved Axiom configuration.\n *\n * @param config - Partial configuration to validate\n * @returns Fully resolved configuration with all required fields\n * @throws {AxiomCLIError} If required fields are missing or invalid\n * @internal\n */\nexport function validateConfig(config: Partial<AxiomConfigBase>): ResolvedAxiomConfig {\n  const errors: string[] = [];\n  const isDebug = process.env.AXIOM_DEBUG === 'true';\n\n  if (!isDebug) {\n    if (!config.eval?.token) {\n      errors.push(\n        'eval.token is required (set in axiom.config.ts or AXIOM_TOKEN environment variable)',\n      );\n    }\n    if (!config.eval?.dataset) {\n      errors.push(\n        'eval.dataset is required (set in axiom.config.ts or AXIOM_DATASET environment variable)',\n      );\n    }\n\n    if (!config.eval?.url) {\n      console.log(\n        'eval.url was not specified. Defaulting to `https://api.axiom.co`. Please set it in axiom.config.ts or AXIOM_URL environment variable if you want to use a different endpoint.',\n      );\n    }\n  }\n\n  const instrumentation = config.eval?.instrumentation;\n  if (\n    instrumentation !== null &&\n    instrumentation !== undefined &&\n    typeof instrumentation !== 'function'\n  ) {\n    errors.push(\n      'eval.instrumentation must be a function returning OTEL setup information or null.',\n    );\n  }\n\n  if (errors.length > 0) {\n    throw new AxiomCLIError(`Invalid Axiom configuration:\\n  - ${errors.join('\\n  - ')}`);\n  }\n\n  return config as ResolvedAxiomConfig;\n}\n","import { loadConfig as c12LoadConfig } from 'c12';\nimport { defu } from 'defu';\nimport {\n  createPartialDefaults,\n  validateConfig,\n  type AxiomConfig,\n  type ResolvedAxiomConfig,\n} from './index';\nimport { AxiomCLIError, errorToString } from '../util/errors';\n\n/**\n * Custom merger that uses defu but overrides include/exclude arrays instead of merging them\n */\nfunction customMerger(target: any, source: any): any {\n  const merged = defu(source, target);\n\n  // If source explicitly has eval.include, override it instead of merging\n  if (source?.eval && 'include' in source.eval) {\n    merged.eval.include = source.eval.include;\n  }\n\n  // If source explicitly has eval.flagSchema, use it directly (defu mangles Zod objects)\n  if (source?.eval && 'flagSchema' in source.eval) {\n    merged.eval.flagSchema = source.eval.flagSchema;\n  }\n\n  return merged;\n}\n\n/**\n * Result of loading a config file\n */\nexport interface LoadConfigResult {\n  config: ResolvedAxiomConfig;\n}\n\n/**\n * Load Axiom configuration from axiom.config.ts (or .js, .mjs, etc.)\n *\n * @param cwd - The directory to search for config file (defaults to process.cwd())\n * @returns The loaded config and the path to the config file (if found)\n *\n * @example\n * ```typescript\n * const { config } = await loadConfig();\n * ```\n */\nexport async function loadConfig(cwd: string = process.cwd()): Promise<LoadConfigResult> {\n  try {\n    const defaults = createPartialDefaults();\n\n    const result = await c12LoadConfig<AxiomConfig>({\n      name: 'axiom',\n      cwd,\n      // Support common config file extensions\n      configFile: 'axiom.config',\n      // Don't use defaultConfig - we'll merge manually to control array behavior\n      // Disable configs other than .ts/.js/.mts/.mjs/.cts/.cjs\n      rcFile: false,\n      globalRc: false,\n      packageJson: false,\n      giget: false,\n    });\n\n    // Manually merge with defaults, overriding `include` instead of merging\n    const mergedConfig = customMerger(defaults, result.config);\n    const validatedConfig = validateConfig(mergedConfig);\n\n    return {\n      config: validatedConfig,\n    };\n  } catch (error) {\n    if (error instanceof AxiomCLIError) {\n      throw error;\n    }\n    // c12 throws if config file has errors\n    throw new AxiomCLIError(`Failed to load config file: ${errorToString(error)}`);\n  }\n}\n","import { BatchSpanProcessor, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';\nimport { resourceFromAttributes } from '@opentelemetry/resources';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport {\n  context,\n  trace,\n  type Context,\n  type Span,\n  type SpanOptions,\n  SpanStatusCode,\n  type Tracer,\n  type TracerProvider,\n} from '@opentelemetry/api';\nimport { initAxiomAI } from '../../src/otel/initAxiomAI';\nimport type {\n  AxiomEvalInstrumentationHook,\n  AxiomEvalInstrumentationOptions,\n  AxiomEvalInstrumentationResult,\n  ResolvedAxiomConfig,\n} from '../config/index';\nimport { resolveAxiomConnection } from '../config/resolver';\nimport { AxiomCLIError, errorToString } from '../util/errors';\nimport { loadConfig } from '../config/loader';\n\n// Lazily initialized tracer provider and exporter\nlet axiomProvider: NodeTracerProvider | undefined;\nlet axiomTracer: Tracer | undefined;\nlet userProvider: TracerProvider | undefined;\n\nlet initializationPromise: Promise<void> | null = null;\nlet initialized = false;\n\nasync function resolveInstrumentationHook(\n  config: ResolvedAxiomConfig,\n): Promise<AxiomEvalInstrumentationHook | null> {\n  if (config.eval.instrumentation) {\n    return config.eval.instrumentation;\n  }\n\n  try {\n    const { config: loadedConfig } = await loadConfig(process.cwd());\n    return (loadedConfig.eval.instrumentation ?? null) as AxiomEvalInstrumentationHook | null;\n  } catch (error) {\n    throw new AxiomCLIError(\n      `Failed to reload instrumentation from config: ${errorToString(error)}`,\n    );\n  }\n}\n\nasync function runInstrumentationHook(\n  hook: AxiomEvalInstrumentationHook,\n  options: AxiomEvalInstrumentationOptions,\n): Promise<AxiomEvalInstrumentationResult | void> {\n  try {\n    return await hook(options);\n  } catch (error) {\n    throw new AxiomCLIError(`Failed to execute instrumentation hook: ${errorToString(error)}`);\n  }\n}\n\nfunction setupEvalProvider(connection: ReturnType<typeof resolveAxiomConnection>) {\n  const headers: Record<string, string> = {\n    'X-Axiom-Dataset': connection.dataset,\n    ...(connection.orgId ? { 'X-AXIOM-ORG-ID': connection.orgId } : {}),\n  };\n\n  if (connection.token) {\n    headers.Authorization = `Bearer ${connection.token}`;\n  }\n\n  // Use edgeUrl for trace ingestion\n  const collectorOptions = {\n    url: `${connection.edgeUrl}/v1/traces`,\n    headers,\n    concurrencyLimit: 10,\n  };\n\n  const exporter = new OTLPTraceExporter(collectorOptions);\n\n  const processor = new BatchSpanProcessor(exporter, {\n    maxQueueSize: 2048,\n    maxExportBatchSize: 512,\n    scheduledDelayMillis: 5000,\n    exportTimeoutMillis: 30000,\n  });\n\n  axiomProvider = new NodeTracerProvider({\n    resource: resourceFromAttributes({\n      ['service.name']: 'axiom',\n      ['service.version']: __SDK_VERSION__,\n    }),\n    spanProcessors: [processor],\n  });\n\n  axiomTracer = axiomProvider.getTracer('axiom', __SDK_VERSION__);\n}\n\nexport async function initInstrumentation(config: {\n  enabled: boolean;\n  config: ResolvedAxiomConfig;\n}): Promise<void> {\n  if (initialized) {\n    return;\n  }\n\n  if (initializationPromise) {\n    await initializationPromise;\n    return;\n  }\n\n  initializationPromise = (async () => {\n    if (!config.enabled) {\n      axiomTracer = trace.getTracer('axiom', __SDK_VERSION__);\n      initialized = true;\n      return;\n    }\n\n    const connection = resolveAxiomConnection(config.config);\n    const hook = await resolveInstrumentationHook(config.config);\n    let hookResult: AxiomEvalInstrumentationResult | void = undefined;\n\n    if (hook) {\n      config.config.eval.instrumentation = hook;\n      hookResult = await runInstrumentationHook(hook, {\n        dataset: connection.dataset,\n        token: connection.token,\n        url: connection.url,\n        edgeUrl: connection.edgeUrl,\n        orgId: connection.orgId,\n      });\n\n      userProvider = hookResult?.provider ?? userProvider;\n    }\n\n    setupEvalProvider(connection);\n\n    if (!hook) {\n      // Fall back to default behaviour by registering our provider globally\n      axiomProvider?.register();\n      if (axiomTracer) {\n        initAxiomAI({ tracer: axiomTracer });\n      }\n    }\n\n    initialized = true;\n  })();\n\n  try {\n    await initializationPromise;\n  } finally {\n    initializationPromise = null;\n  }\n}\n\nexport const flush = async () => {\n  if (initializationPromise) {\n    await initializationPromise;\n  }\n\n  const tasks: Array<Promise<unknown>> = [];\n\n  if (axiomProvider) {\n    tasks.push(axiomProvider.forceFlush());\n  }\n\n  const candidateProviders = new Set<TracerProvider>();\n  if (userProvider) {\n    candidateProviders.add(userProvider);\n  }\n\n  const globalProvider = trace.getTracerProvider();\n  if (globalProvider) {\n    candidateProviders.add(globalProvider);\n  }\n\n  for (const provider of candidateProviders) {\n    const flushFn = (provider as any).forceFlush;\n    if (typeof flushFn === 'function') {\n      tasks.push(\n        flushFn.call(provider).catch((error: unknown) => {\n          console.warn('[AxiomAI] Failed to flush tracer provider:', errorToString(error));\n        }),\n      );\n    }\n  }\n\n  if (tasks.length > 0) {\n    await Promise.all(tasks);\n  }\n};\n\n/**\n * Ensure instrumentation is initialized with the given config.\n * Call this from within test context before using startSpan.\n */\nexport async function ensureInstrumentationInitialized(\n  config: ResolvedAxiomConfig,\n  options: { enabled?: boolean } = {},\n): Promise<void> {\n  if (initialized) {\n    return;\n  }\n\n  const enabled = options.enabled ?? true;\n  await initInstrumentation({ enabled, config });\n}\n\nconst getEvalTracer = (): Tracer => {\n  if (!axiomTracer) {\n    throw new Error(\n      'Eval tracer not initialized. Ensure ensureInstrumentationInitialized() was awaited before starting spans.',\n    );\n  }\n\n  return axiomTracer;\n};\n\nexport const startSpan = (name: string, opts: SpanOptions, context?: Context) => {\n  if (!initialized || !axiomTracer) {\n    throw new Error(\n      'Instrumentation not initialized. This is likely a bug - instrumentation should be initialized before startSpan is called.',\n    );\n  }\n  return getEvalTracer().startSpan(name, opts, context);\n};\n\nexport const startActiveSpan = async <T>(\n  name: string,\n  options: SpanOptions,\n  fn: (span: Span) => Promise<T>,\n  parentContext?: Context,\n): Promise<T> => {\n  const span = startSpan(name, options, parentContext);\n\n  return context.with(trace.setSpan(context.active(), span), async () => {\n    try {\n      const result = await fn(span);\n      span.setStatus({ code: SpanStatusCode.OK });\n      return result;\n    } catch (error) {\n      span.recordException(error as Error);\n      span.setStatus({\n        code: SpanStatusCode.ERROR,\n        message: error instanceof Error ? error.message : String(error),\n      });\n      throw error;\n    } finally {\n      span.end();\n    }\n  });\n};\n","// src/index.ts\nvar f = {\n  reset: [0, 0],\n  bold: [1, 22, \"\\x1B[22m\\x1B[1m\"],\n  dim: [2, 22, \"\\x1B[22m\\x1B[2m\"],\n  italic: [3, 23],\n  underline: [4, 24],\n  inverse: [7, 27],\n  hidden: [8, 28],\n  strikethrough: [9, 29],\n  black: [30, 39],\n  red: [31, 39],\n  green: [32, 39],\n  yellow: [33, 39],\n  blue: [34, 39],\n  magenta: [35, 39],\n  cyan: [36, 39],\n  white: [37, 39],\n  gray: [90, 39],\n  bgBlack: [40, 49],\n  bgRed: [41, 49],\n  bgGreen: [42, 49],\n  bgYellow: [43, 49],\n  bgBlue: [44, 49],\n  bgMagenta: [45, 49],\n  bgCyan: [46, 49],\n  bgWhite: [47, 49],\n  blackBright: [90, 39],\n  redBright: [91, 39],\n  greenBright: [92, 39],\n  yellowBright: [93, 39],\n  blueBright: [94, 39],\n  magentaBright: [95, 39],\n  cyanBright: [96, 39],\n  whiteBright: [97, 39],\n  bgBlackBright: [100, 49],\n  bgRedBright: [101, 49],\n  bgGreenBright: [102, 49],\n  bgYellowBright: [103, 49],\n  bgBlueBright: [104, 49],\n  bgMagentaBright: [105, 49],\n  bgCyanBright: [106, 49],\n  bgWhiteBright: [107, 49]\n}, h = Object.entries(f);\nfunction a(n) {\n  return String(n);\n}\na.open = \"\";\na.close = \"\";\nvar B = /* @__PURE__ */ h.reduce(\n  (n, [e]) => (n[e] = a, n),\n  { isColorSupported: !1 }\n);\nfunction m() {\n  return { ...B };\n}\nfunction C(n = !1) {\n  let e = typeof process != \"undefined\" ? process : void 0, i = (e == null ? void 0 : e.env) || {}, g = (e == null ? void 0 : e.argv) || [];\n  return !(\"NO_COLOR\" in i || g.includes(\"--no-color\")) && (\"FORCE_COLOR\" in i || g.includes(\"--color\") || (e == null ? void 0 : e.platform) === \"win32\" || n && i.TERM !== \"dumb\" || \"CI\" in i) || typeof window != \"undefined\" && !!window.chrome;\n}\nfunction p(n = !1) {\n  let e = C(n), i = (r, t, c, o) => {\n    let l = \"\", s = 0;\n    do\n      l += r.substring(s, o) + c, s = o + t.length, o = r.indexOf(t, s);\n    while (~o);\n    return l + r.substring(s);\n  }, g = (r, t, c = r) => {\n    let o = (l) => {\n      let s = String(l), b = s.indexOf(t, r.length);\n      return ~b ? r + i(s, t, c, b) + t : r + s + t;\n    };\n    return o.open = r, o.close = t, o;\n  }, u = {\n    isColorSupported: e\n  }, d = (r) => `\\x1B[${r}m`;\n  for (let [r, t] of h)\n    u[r] = e ? g(\n      d(t[0]),\n      d(t[1]),\n      t[2]\n    ) : a;\n  return u;\n}\n\nexport {\n  m as a,\n  C as b,\n  p as c\n};\n","import {\n  a as e,\n  b as t,\n  c as o\n} from \"./chunk-BVHSVHOK.js\";\n\n// src/node.ts\nimport { isatty as s } from \"tty\";\nvar r = process.env.FORCE_TTY !== void 0 || s(1);\nfunction n() {\n  return t(r);\n}\nfunction a() {\n  return o(r);\n}\nvar u = o(r);\nexport {\n  a as createColors,\n  u as default,\n  e as getDefaultColors,\n  n as isSupported\n};\n","import c from 'tinyrainbow';\n\nimport type {\n  Case,\n  Evaluation,\n  FlagDiff,\n  MetaWithCase,\n  MetaWithEval,\n  OutOfScopeFlag,\n  RegistrationStatus,\n  OutOfScopeFlagAccess,\n} from './eval.types';\nimport type { TestSuite, TestCase } from 'vitest/node';\nimport type { Score } from './scorer.types';\nimport { flattenObject } from '../util/dot-path';\nimport type { AxiomConnectionResolvedConfig } from '../config/resolver';\n\n/** Convert score value to number (handles boolean scores from normalizeScore) */\nfunction scoreToNumber(score: Score['score']): number {\n  if (typeof score === 'boolean') return score ? 1 : 0;\n  return score ?? 0;\n}\n\nexport type SuiteData = {\n  version: string;\n  name: string;\n  file: string;\n  duration: string;\n  baseline: Evaluation | undefined | null;\n  configFlags?: string[];\n  flagConfig?: Record<string, any>;\n  defaultFlagConfig?: Record<string, any>;\n  runId: string;\n  orgId?: string;\n  cases: Array<{\n    index: number;\n    scores: Record<string, Score>;\n    outOfScopeFlags?: OutOfScopeFlagAccess[];\n    errors?: Error[] | null;\n    runtimeFlags?: any;\n  }>;\n  outOfScopeFlags?: OutOfScopeFlag[];\n  registrationStatus?: RegistrationStatus;\n};\n\nexport type Logger = (message?: string, ...optionalParams: any[]) => void;\n\nexport function formatPercentage(value: number): string {\n  if (!Number.isFinite(value)) {\n    return 'N/A';\n  }\n  return Number(value * 100).toFixed(2) + '%';\n}\n\nexport function formatDiff(current: number, baseline: number) {\n  if (!Number.isFinite(current) || !Number.isFinite(baseline)) {\n    return { text: 'N/A', color: c.dim };\n  }\n  const diff = current - baseline;\n  const diffText = (diff >= 0 ? '+' : '') + formatPercentage(diff);\n  const color = diff > 0 ? c.green : diff < 0 ? c.red : c.dim;\n  return { text: diffText, color };\n}\n\nexport function truncate(str: string, max: number): string {\n  return str.length > max ? str.slice(0, max) + '…' : str;\n}\n\nexport function stringify(value: any): string {\n  try {\n    if (typeof value === 'string') return value;\n    return JSON.stringify(value);\n  } catch {\n    return String(value);\n  }\n}\n\nexport function getCaseFingerprint(\n  input: string | Record<string, any>,\n  expected: string | Record<string, any>,\n): string {\n  const inputStr = typeof input === 'string' ? input : JSON.stringify(input);\n  const expectedStr = typeof expected === 'string' ? expected : JSON.stringify(expected);\n  return JSON.stringify({ input: inputStr, expected: expectedStr });\n}\n\nexport function printEvalNameAndFileName(\n  testSuite: TestSuite,\n  meta: MetaWithEval,\n  logger: Logger = console.log,\n) {\n  const cwd = process.cwd();\n\n  logger(\n    ' ',\n    c.bgCyan(c.black(` ${testSuite.project.name} `)),\n    c.bgBlue(c.black(` ${meta.evaluation.name}-${meta.evaluation.version} `)),\n    c.dim(`(${testSuite.children.size} cases)`),\n  );\n\n  logger(' ', c.dim(testSuite.module.moduleId.replace(cwd, '')));\n}\n\nexport function printBaselineNameAndVersion(testMeta: MetaWithEval, logger: Logger = console.log) {\n  if (testMeta.evaluation.baseline) {\n    logger(\n      ' ',\n      ' baseline ',\n      c.bgMagenta(\n        c.black(` ${testMeta.evaluation.baseline.name}-${testMeta.evaluation.baseline.version} `),\n      ),\n    );\n  } else {\n    logger(' ', c.bgWhite(c.blackBright(' baseline: ')), 'none');\n  }\n\n  logger('');\n}\n\nexport function printRuntimeFlags(testMeta: MetaWithCase, logger: Logger = console.log) {\n  if (testMeta.case.runtimeFlags && Object.keys(testMeta.case.runtimeFlags).length > 0) {\n    const entries = Object.entries(testMeta.case.runtimeFlags);\n    logger('   ', c.dim('runtime flags'));\n    for (const [k, v] of entries) {\n      switch (v.kind) {\n        case 'replaced': {\n          const valText = truncate(stringify(v.value), 80);\n          const defText = truncate(stringify(v.default), 80);\n          logger('     ', `${k}: ${valText} (default: ${defText})`);\n          break;\n        }\n        case 'introduced': {\n          const valText = truncate(stringify(v.value), 80);\n          logger('     ', `${k}: ${valText} (no default)`);\n          break;\n        }\n      }\n    }\n  }\n}\n\nexport function printTestCaseCountStartDuration(\n  testSuite: TestSuite,\n  startTime: number,\n  duration: string,\n  trials?: number,\n  logger: Logger = console.log,\n) {\n  logger(' ');\n  const trialsLabel = trials && trials > 1 ? ` (${trials} trials each)` : '';\n  logger(' ', c.dim('Cases'), `${testSuite.children.size}${trialsLabel}`);\n  logger(' ', c.dim('Start at'), new Date(startTime).toTimeString());\n  logger(' ', c.dim('Duration'), `${duration}s`);\n}\n\nexport function printTestCaseSuccessOrFailed(\n  testMeta: MetaWithCase,\n  ok: boolean,\n  logger: Logger = console.log,\n) {\n  const index = testMeta.case.index;\n\n  if (ok) {\n    logger(' ', c.yellow(` \\u2714 case ${index}:`));\n  } else {\n    logger(' ', c.red(` \\u2716 case ${index}: failed`));\n    for (const e of testMeta.case.errors ?? []) {\n      logger('', e.message);\n    }\n  }\n}\n\nexport function printTestCaseScores(\n  testMeta: MetaWithCase,\n  baselineCase: Case | null | undefined,\n  logger: Logger = console.log,\n) {\n  const scores = testMeta.case.scores;\n  const keys = Object.keys(scores);\n\n  if (keys.length === 0) {\n    return;\n  }\n\n  const maxNameLength = Math.max(...keys.map((k) => k.length));\n\n  keys.forEach((k) => {\n    const scoreData = scores[k];\n    const hasError = scoreData.metadata?.error;\n    const v = scoreToNumber(scoreData.score);\n\n    const rawCurrent = hasError ? 'N/A' : formatPercentage(v);\n    const paddedCurrent = rawCurrent.padStart(7);\n    const coloredCurrent = hasError ? c.dim(paddedCurrent) : c.magentaBright(paddedCurrent);\n\n    const paddedName = k.padEnd(maxNameLength);\n\n    if (baselineCase?.scores[k]) {\n      const baselineScoreValue = baselineCase.scores[k].value;\n      const rawBaseline = formatPercentage(baselineScoreValue);\n      const paddedBaseline = rawBaseline === 'N/A' ? rawBaseline : rawBaseline.padStart(7);\n      const coloredBaseline =\n        rawBaseline === 'N/A' ? c.dim(paddedBaseline) : c.blueBright(paddedBaseline);\n\n      const { text: diffText, color: diffColor } = formatDiff(v, baselineScoreValue);\n      const paddedDiff = diffText.padStart(8);\n\n      logger(\n        `    ${paddedName}  ${coloredBaseline} → ${coloredCurrent}  ${\n          hasError ? c.dim('(scorer not run)') : c.dim('(') + diffColor(paddedDiff) + c.dim(')')\n        }`,\n      );\n    } else {\n      logger(`    ${paddedName}  ${coloredCurrent} ${hasError ? c.dim('(scorer not run)') : ''}`);\n    }\n  });\n}\n\nexport function printOutOfScopeFlags(testMeta: MetaWithCase, logger: Logger = console.log) {\n  if (testMeta.case.outOfScopeFlags && testMeta.case.outOfScopeFlags.length > 0) {\n    const pickedFlagsText = testMeta.case.pickedFlags\n      ? `(picked: ${testMeta.case.pickedFlags.map((f) => `'${f}'`).join(', ')})`\n      : '(none)';\n    logger('   ', c.yellow(`⚠ Out-of-scope flags: ${pickedFlagsText}`));\n    testMeta.case.outOfScopeFlags.forEach((flag) => {\n      const timeStr = new Date(flag.accessedAt).toLocaleTimeString();\n      logger('     ', `${flag.flagPath} (at ${timeStr})`);\n\n      // Show top stack trace frames\n      if (flag.stackTrace && flag.stackTrace.length > 0) {\n        flag.stackTrace.forEach((frame, i) => {\n          const prefix = i === flag.stackTrace.length - 1 ? ' └─' : ' ├─';\n          logger('     ', c.dim(`${prefix} ${frame}`));\n        });\n      }\n    });\n  }\n}\n\nexport function printCaseResult(\n  test: TestCase,\n  baselineCasesByFingerprint: Map<string, Case[]>,\n  matchedIndices: Set<number>,\n  logger: Logger = console.log,\n) {\n  const ok = test.ok();\n  const testMeta = test.meta() as MetaWithCase;\n\n  if (!testMeta?.case) {\n    return;\n  }\n\n  printTestCaseSuccessOrFailed(testMeta, ok, logger);\n\n  const fingerprint = getCaseFingerprint(testMeta.case.input, testMeta.case.expected);\n  const baselineCases = baselineCasesByFingerprint.get(fingerprint);\n  const baselineCase = baselineCases?.shift();\n\n  if (baselineCase) {\n    matchedIndices.add(baselineCase.index);\n  }\n\n  printTestCaseScores(testMeta, baselineCase, logger);\n\n  printRuntimeFlags(testMeta, logger);\n\n  printOutOfScopeFlags(testMeta, logger);\n}\n\nexport function printOrphanedBaselineCases(\n  baseline: Evaluation,\n  matchedIndices: Set<number>,\n  logger: Logger = console.log,\n) {\n  const orphanedCases = baseline.cases.filter((c) => !matchedIndices.has(c.index));\n\n  if (orphanedCases.length === 0) {\n    return;\n  }\n\n  logger('');\n  logger(' ', c.yellow('Orphaned baseline cases:'));\n\n  for (const orphanedCase of orphanedCases) {\n    logger(\n      ' ',\n      c.dim(\n        `case ${orphanedCase.index}: ${truncate(orphanedCase.input, 50)} (score: ${truncate(\n          JSON.stringify(orphanedCase.scores),\n          50,\n        )})`,\n      ),\n    );\n    // We could print detailed scores here if we want, similar to printTestCaseScores\n    // But just listing them is probably enough for now, or using a simplified format\n    const keys = Object.keys(orphanedCase.scores);\n    if (keys.length > 0) {\n      const maxNameLength = Math.max(...keys.map((k) => k.length));\n\n      keys.forEach((k) => {\n        const scoreData = orphanedCase.scores[k];\n        const rawScore = formatPercentage(scoreData.value);\n        const paddedName = k.padEnd(maxNameLength);\n        const paddedScore = rawScore.padStart(7);\n\n        logger(`    ${paddedName}  ${c.blueBright(paddedScore)}`);\n      });\n    }\n  }\n}\n\nexport function printConfigHeader(logger: Logger = console.log) {\n  logger('');\n  logger(' ', c.bgWhite(c.blackBright(' Config ')));\n}\n\nexport function printResultLink(\n  testMeta: MetaWithCase,\n  axiomUrl: string,\n  logger: Logger = console.log,\n) {\n  const url = `${axiomUrl}/evaluations/${testMeta.evaluation.name}/${testMeta.evaluation.id}`;\n  logger(\n    ' ',\n    `see results for ${testMeta.evaluation.name}-${testMeta.evaluation.version} at ${url}`,\n  );\n}\n\nexport const reporterDate = (d: Date) => {\n  const date = d.toISOString().slice(0, 10); // \"2025-10-03\"\n  const hours = d.getUTCHours().toString().padStart(2, '0');\n  const minutes = d.getUTCMinutes().toString().padStart(2, '0');\n  return `${date}, ${hours}:${minutes} UTC`;\n};\n\nexport function printGlobalFlagOverrides(\n  overrides: Record<string, any>,\n  defaults: Record<string, any>,\n  logger: Logger = console.log,\n) {\n  if (Object.keys(overrides).length === 0) {\n    logger('');\n    logger(c.dim('Flag overrides: (none)'));\n    logger('');\n    return;\n  }\n\n  logger('');\n  logger('Flag overrides:');\n  for (const [key, value] of Object.entries(overrides)) {\n    const defaultValue = defaults[key];\n    const valueStr = JSON.stringify(value);\n    const defaultStr = defaultValue !== undefined ? JSON.stringify(defaultValue) : 'none';\n    logger(`  • ${key}: ${valueStr} ${c.dim(`(default: ${defaultStr})`)}`);\n  }\n  logger('');\n}\n\nexport function printSuiteBox({\n  suite,\n  scorerAverages,\n  calculateBaselineScorerAverage,\n  flagDiff,\n  logger = console.log,\n}: {\n  suite: SuiteData;\n  scorerAverages: Record<string, number>;\n  calculateBaselineScorerAverage: (baseline: Evaluation, scorerName: string) => number | null;\n  flagDiff: Array<FlagDiff>;\n  logger?: Logger;\n}) {\n  const filename = suite.file.split('/').pop();\n\n  logger('┌─');\n  logger(`│  ${c.blue(suite.name)} ${c.gray(`(${filename})`)}`);\n  logger('├─');\n\n  const scorerNames = Object.keys(scorerAverages);\n  const maxNameLength = Math.max(...scorerNames.map((name) => name.length));\n\n  const allCasesErrored = (scorerName: string) => {\n    return suite.cases.every((caseData) => caseData.scores[scorerName]?.metadata?.error);\n  };\n\n  for (const scorerName of scorerNames) {\n    const avg = scorerAverages[scorerName];\n    const paddedName = scorerName.padEnd(maxNameLength);\n    const hasAllErrors = allCasesErrored(scorerName);\n\n    const baselineAvg = suite.baseline\n      ? calculateBaselineScorerAverage(suite.baseline, scorerName)\n      : null;\n\n    if (baselineAvg !== null) {\n      const currentPercent = hasAllErrors ? c.dim('N/A') : formatPercentage(avg);\n      const baselinePercent = formatPercentage(baselineAvg);\n      const { text: diffText, color: diffColor } = formatDiff(avg, baselineAvg);\n\n      const paddedBaseline = baselinePercent.padStart(7);\n      const paddedCurrent = hasAllErrors ? currentPercent : currentPercent.padStart(7);\n      const diffDisplay = hasAllErrors\n        ? c.dim('all cases failed')\n        : diffColor(diffText.padStart(8));\n\n      logger(\n        `│  ${paddedName}  ${c.blueBright(paddedBaseline)} → ${hasAllErrors ? paddedCurrent : c.magentaBright(paddedCurrent)}  (${diffDisplay})`,\n      );\n    } else {\n      const currentPercent = hasAllErrors ? c.red('N/A (all cases failed)') : formatPercentage(avg);\n      logger(`│   • ${paddedName}  ${currentPercent}`);\n    }\n  }\n\n  logger('├─');\n\n  if (suite.baseline) {\n    const baselineTimestamp = suite.baseline.runAt\n      ? reporterDate(new Date(suite.baseline.runAt))\n      : 'unknown time';\n    logger(\n      `│  Baseline: ${suite.baseline.name}-${suite.baseline.version} ${c.gray(`(${baselineTimestamp})`)}`,\n    );\n  } else {\n    logger(`│  Baseline: ${c.gray('(none)')}`);\n  }\n\n  const hasConfigChanges = flagDiff.length > 0;\n\n  logger('│  Config changes:', hasConfigChanges ? '' : c.gray('(none)'));\n  if (hasConfigChanges) {\n    for (const { flag, current, baseline, default: defaultVal } of flagDiff) {\n      logger(`│   • ${flag}: ${current ?? '<not set>'}`);\n      if (defaultVal !== undefined) {\n        logger(`│       ${c.gray(`default: ${defaultVal}`)}`);\n      }\n      if (suite.baseline) {\n        logger(`│       ${c.gray(`baseline: ${baseline ?? '<not set>'}`)}`);\n      }\n    }\n  }\n\n  if (suite.outOfScopeFlags && suite.outOfScopeFlags.length > 0) {\n    const pickedFlagsText =\n      suite.configFlags && suite.configFlags.length > 0\n        ? suite.configFlags.map((f) => `'${f}'`).join(', ')\n        : 'none';\n    logger('│');\n    logger(`│  ${c.yellow('⚠ Out-of-scope flags')} ${c.gray(`(picked: ${pickedFlagsText})`)}:`);\n    for (const flag of suite.outOfScopeFlags) {\n      const lastStackTraceFrame = flag.stackTrace[0];\n      const lastStackTraceFnName = lastStackTraceFrame.split(' ').shift();\n      const lastStackTraceFile = lastStackTraceFrame.split('/').pop()?.slice(0, -1);\n      logger(\n        `│   • ${flag.flagPath} ${c.gray(`at ${lastStackTraceFnName} (${lastStackTraceFile})`)}`,\n      );\n    }\n  }\n\n  logger('└─');\n}\n\n/**\n * Calculate average scores per scorer for a suite\n */\nexport function calculateScorerAverages(suite: SuiteData): Record<string, number> {\n  const scorerTotals: Record<string, { sum: number; count: number }> = {};\n\n  for (const caseData of suite.cases) {\n    for (const [scorerName, score] of Object.entries(caseData.scores)) {\n      if (!scorerTotals[scorerName]) {\n        scorerTotals[scorerName] = { sum: 0, count: 0 };\n      }\n      if (!score.metadata?.error) {\n        scorerTotals[scorerName].sum += scoreToNumber(score.score);\n        scorerTotals[scorerName].count += 1;\n      }\n    }\n  }\n\n  const averages: Record<string, number> = {};\n  for (const [scorerName, totals] of Object.entries(scorerTotals)) {\n    averages[scorerName] = totals.count > 0 ? totals.sum / totals.count : 0;\n  }\n\n  return averages;\n}\n\n/**\n * Calculate average score for a specific scorer from baseline data\n */\nexport function calculateBaselineScorerAverage(\n  baseline: Evaluation,\n  scorerName: string,\n): number | null {\n  const scores: number[] = [];\n\n  for (const caseData of baseline.cases) {\n    if (caseData.scores[scorerName]) {\n      scores.push(caseData.scores[scorerName].value);\n    }\n  }\n\n  if (scores.length === 0) return null;\n\n  const sum = scores.reduce((acc, val) => acc + val, 0);\n  return sum / scores.length;\n}\n\n/**\n * Calculate flag diff between current run vs baseline and defaults (filtered by configFlags).\n * Shows a diff if current differs from at least one of baseline or default.\n */\nexport function calculateFlagDiff(suite: SuiteData): Array<FlagDiff> {\n  if (!suite.configFlags || suite.configFlags.length === 0) {\n    return [];\n  }\n\n  const diffs: Array<FlagDiff> = [];\n\n  const currentConfig = suite.flagConfig || {};\n  const baselineConfig = suite.baseline?.flagConfig || {};\n  const defaultConfig = suite.defaultFlagConfig || {};\n\n  const currentFlat = flattenObject(currentConfig);\n  const baselineFlat = flattenObject(baselineConfig);\n  const defaultFlat = flattenObject(defaultConfig);\n\n  const allKeys = new Set([\n    ...Object.keys(currentFlat),\n    ...Object.keys(baselineFlat),\n    ...Object.keys(defaultFlat),\n  ]);\n\n  for (const key of allKeys) {\n    const isInScope = suite.configFlags.some((pattern) => key.startsWith(pattern));\n    if (!isInScope) continue;\n\n    const currentValue = currentFlat[key];\n    const baselineValue = baselineFlat[key];\n    const defaultValue = defaultFlat[key];\n\n    const currentStr = currentValue !== undefined ? JSON.stringify(currentValue) : undefined;\n    const baselineStr = baselineValue !== undefined ? JSON.stringify(baselineValue) : undefined;\n    const defaultStr = defaultValue !== undefined ? JSON.stringify(defaultValue) : undefined;\n\n    const diffFromBaseline = suite.baseline && currentStr !== baselineStr;\n    const diffFromDefault = currentStr !== defaultStr;\n\n    if (diffFromBaseline || diffFromDefault) {\n      diffs.push({\n        flag: key,\n        current: currentStr,\n        baseline: suite.baseline ? baselineStr : undefined,\n        default: defaultStr,\n      });\n    }\n  }\n\n  return diffs;\n}\n\nexport function printFinalReport({\n  suiteData,\n  config,\n  registrationStatus,\n  isDebug,\n  logger = console.log,\n}: {\n  suiteData: SuiteData[];\n  config?: AxiomConnectionResolvedConfig;\n  registrationStatus: Array<{ name: string; registered: boolean; error?: string }>;\n  isDebug?: boolean;\n  logger?: Logger;\n}) {\n  logger('');\n  logger(c.bgBlue(c.white(' FINAL EVALUATION REPORT ')));\n  logger('');\n\n  const runId = suiteData[0]?.runId;\n  const orgId = suiteData[0]?.orgId;\n\n  const anyRegistered = registrationStatus.some((s) => s.registered);\n  const anyFailed = registrationStatus.some((s) => !s.registered);\n  const allFailed = registrationStatus.length > 0 && registrationStatus.every((s) => !s.registered);\n  const hasAnyScores = suiteData.some((suite) =>\n    suite.cases.some((caseData) => Object.keys(caseData.scores ?? {}).length > 0),\n  );\n  const shouldPrintSuiteBoxes = isDebug || !allFailed || hasAnyScores;\n\n  if (shouldPrintSuiteBoxes) {\n    for (const suite of suiteData) {\n      const scorerAverages = calculateScorerAverages(suite);\n      const flagDiff = calculateFlagDiff(suite);\n      printSuiteBox({\n        suite,\n        scorerAverages,\n        calculateBaselineScorerAverage,\n        flagDiff,\n        logger,\n      });\n      logger('');\n    }\n  }\n\n  if (anyRegistered && orgId && config?.consoleEndpointUrl) {\n    if (suiteData.length === 1) {\n      const suite = suiteData[0];\n      const baselineParam = suite.baseline?.traceId ? `?baselineId=${suite.baseline.traceId}` : '';\n      logger('View eval result:');\n      logger(\n        `${config.consoleEndpointUrl}/${orgId}/ai/evaluations/${suite.name}/${suite.version}${baselineParam}`,\n      );\n    } else {\n      logger('View full report:');\n      logger(`${config.consoleEndpointUrl}/${orgId}/ai/evaluations?runId=${runId}`);\n    }\n  } else if (isDebug) {\n    logger(c.dim('Results not uploaded to Axiom (debug mode)'));\n  } else {\n    logger('Results not available in Axiom UI (registration failed)');\n  }\n\n  if (anyFailed) {\n    logger('');\n    for (const status of registrationStatus) {\n      if (!status.registered) {\n        logger(c.yellow(`⚠️  Warning: Failed to register \"${status.name}\" with Axiom`));\n        if (status.error) {\n          logger(c.dim(`   Error: ${status.error}`));\n        }\n        logger(c.dim(`   Results for this evaluation will not be available in the Axiom UI.`));\n      }\n    }\n  }\n}\n","import { getEvalContext, putOnSpan, EVAL_CONTEXT } from './evals/context/storage';\n\n/**\n * Override flag values for the current evaluation context with trace-specific isolation.\n * Now creates overlay contexts to prevent overrides from leaking to sibling operations.\n *\n * @internal - For framework use only. Use scope.overrideFlags() for typed flag access.\n * @param partial - Partial flag overrides\n */\nexport function overrideFlags(partial: Record<string, any>): void {\n  const current = getEvalContext();\n\n  if (!current) {\n    if (process.env.NODE_ENV !== 'test') {\n      console.warn('overrideFlags called outside of evaluation context');\n    }\n    return;\n  }\n\n  // Create overlay context instead of mutating the current one\n  const overlayContext = {\n    ...current,\n    flags: { ...current.flags, ...partial }, // Merge for backwards compatibility\n    parent: current,\n    overrides: { ...partial },\n  };\n\n  // We need to update the current ALS context in place\n  const currentCtx = EVAL_CONTEXT.get();\n  if (currentCtx) {\n    // Update current context to overlay\n    Object.assign(currentCtx, overlayContext);\n  }\n\n  // Write all overridden flags to span\n  for (const [key, value] of Object.entries(partial)) {\n    putOnSpan('flag', key, value);\n  }\n}\n","import { overrideFlags } from '../../context';\nimport { withEvalContext } from '../../evals/context/storage';\nimport { setGlobalFlagOverrides } from '../../evals/context/global-flags';\nimport type { FlagOverrides } from './parse-flag-overrides';\n\n/**\n * Run evaluation with flag overrides applied to the context.\n * This ensures flag overrides are established before any test files load.\n *\n * @param overrides - Flag overrides from CLI parsing\n * @param runFn - Function that runs the evaluation (typically runVitest)\n */\nexport async function runEvalWithContext<T>(\n  overrides: FlagOverrides,\n  runFn: () => Promise<T>,\n): Promise<T> {\n  setGlobalFlagOverrides(overrides);\n\n  return withEvalContext({ initialFlags: overrides }, async () => {\n    // TODO: is this necessary? given the `setGlobalFlagOverrides` call above?\n    if (Object.keys(overrides).length > 0) {\n      overrideFlags(overrides);\n    }\n\n    return runFn();\n  });\n}\n","import { type ZodError, type ZodObject, type z } from 'zod';\nimport { formatZodErrors, generateFlagExamples } from './format-zod-errors.js';\nimport { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { dotNotationToNested, isValidPath, parsePath } from '../../util/dot-path.js';\nimport { makeDeepPartial } from '../../util/deep-partial-schema.js';\nimport { assertZodV4 } from '../../util/zod-internals.js';\n\nexport interface FlagOverrides {\n  [key: string]: any;\n}\n\nconst FLAG_RE = /^--flag\\.([^=]+)(?:=(.*))?$/;\nconst CONFIG_RE = /^--flags-config(?:=(.*))?$/;\n\nfunction ensureNoSpaceSeparatedSyntax(\n  flagName: string,\n  value: string | undefined,\n  nextToken: string | undefined,\n  flagType: 'flag' | 'config',\n): void {\n  if (value === undefined && nextToken !== undefined) {\n    if (\n      flagType === 'flag' &&\n      !nextToken.startsWith('-') &&\n      nextToken !== 'true' &&\n      nextToken !== 'false'\n    ) {\n      console.error(`❌ Invalid syntax: --flag.${flagName} ${nextToken}`);\n      console.error(`💡 Use: --flag.${flagName}=${nextToken}`);\n      process.exit(1);\n    } else if (flagType === 'config' && !nextToken.startsWith('-')) {\n      console.error(`❌ Invalid syntax: --flags-config ${nextToken}`);\n      console.error(`💡 Use: --flags-config=${nextToken}`);\n      process.exit(1);\n    }\n  }\n}\n\n/**\n * Extract and validate flag overrides using a Zod schema\n */\nexport function extractAndValidateFlagOverrides<S extends z.ZodObject<any>>(\n  argv: string[],\n  flagSchema?: S,\n): {\n  cleanedArgv: string[];\n  overrides: S extends ZodObject<any> ? z.output<S> : FlagOverrides;\n} {\n  if (flagSchema) {\n    assertZodV4(flagSchema, 'flagSchema');\n  }\n\n  const { cleanedArgv, overrides } = extractOverrides(argv);\n\n  if (flagSchema && Object.keys(overrides).length > 0) {\n    // Use deep partial schema - allows partial nested objects\n    const deepPartialSchema = makeDeepPartial(flagSchema as ZodObject<any>);\n    const result = deepPartialSchema.safeParse(overrides);\n\n    if (!result.success) {\n      console.error('❌ Invalid flags:');\n      console.error(formatZodErrors(result.error));\n\n      const examples = generateFlagExamples(result.error);\n      if (examples.length > 0) {\n        console.error('\\n💡 Examples:');\n        examples.forEach((example) => console.error(`  ${example}`));\n      }\n\n      process.exit(1);\n    }\n\n    return { cleanedArgv, overrides: result.data as any };\n  }\n\n  return { cleanedArgv, overrides: overrides as any };\n}\n\nexport type FlagValidationError =\n  | { type: 'invalid_path'; path: string }\n  | { type: 'invalid_value'; zodError: ZodError };\n\nexport interface FlagValidationResult {\n  success: boolean;\n  errors: FlagValidationError[];\n}\n\n/**\n * Validate already-parsed flag overrides against a Zod schema.\n * Returns validation result without side effects (no console output, no process.exit).\n *\n * @param overrides - Flag overrides in dot-notation form (e.g., { 'model.temperature': 0.7 })\n * @param flagSchema - Zod schema to validate against\n * @returns Validation result with any errors found\n */\nexport function collectFlagValidationErrors(\n  overrides: FlagOverrides,\n  flagSchema?: unknown,\n): FlagValidationResult {\n  // No schema provided = no validation, any flags allowed\n  if (!flagSchema || Object.keys(overrides).length === 0) {\n    return { success: true, errors: [] };\n  }\n\n  assertZodV4(flagSchema, 'flagSchema');\n\n  const schema = flagSchema as any;\n  const errors: FlagValidationError[] = [];\n\n  // First pass: check all paths exist in schema\n  for (const dotPath of Object.keys(overrides)) {\n    const segments = parsePath(dotPath);\n    if (!isValidPath(schema, segments)) {\n      errors.push({ type: 'invalid_path', path: dotPath });\n    }\n  }\n\n  // If there are invalid paths, don't proceed to value validation\n  if (errors.length > 0) {\n    return { success: false, errors };\n  }\n\n  // Second pass: validate values using nested object approach with deep partial\n  // This allows providing only some flags without requiring all nested objects\n  const nestedObject = dotNotationToNested(overrides);\n  const deepPartialSchema = makeDeepPartial(schema);\n  const result = deepPartialSchema.safeParse(nestedObject);\n\n  if (!result.success) {\n    errors.push({ type: 'invalid_value', zodError: result.error });\n  }\n\n  return { success: errors.length === 0, errors };\n}\n\n/**\n * Print flag validation errors to console and exit.\n */\nexport function printFlagValidationErrorsAndExit(errors: FlagValidationError[]): never {\n  console.error('❌ Invalid CLI flags:');\n\n  for (const error of errors) {\n    if (error.type === 'invalid_path') {\n      console.error(`  • flag '${error.path}': Invalid flag path`);\n    } else {\n      console.error(formatZodErrors(error.zodError));\n\n      const examples = generateFlagExamples(error.zodError);\n      if (examples.length > 0) {\n        console.error('\\n💡 Valid examples:');\n        examples.forEach((example) => console.error(`  ${example}`));\n      }\n    }\n  }\n\n  process.exit(1);\n}\n\n/**\n * Validate already-parsed flag overrides against a Zod schema.\n * Use this when you have flag overrides in dot-notation form (e.g., { 'model.temperature': 0.7 })\n * and want to validate them against a schema before running evals.\n *\n * @param overrides - Flag overrides in dot-notation form\n * @param flagSchema - Zod schema to validate against\n */\nexport function validateFlagOverrides(overrides: FlagOverrides, flagSchema?: unknown): void {\n  const result = collectFlagValidationErrors(overrides, flagSchema);\n  if (!result.success) {\n    printFlagValidationErrorsAndExit(result.errors);\n  }\n}\n\n/**\n * Coerce string values to appropriate types.\n * Priority: boolean -> number -> JSON -> string\n */\nfunction coerceValue(raw: string): any {\n  // Handle explicit boolean strings\n  if (raw === 'true') return true;\n  if (raw === 'false') return false;\n\n  // Try number conversion\n  const num = Number(raw);\n  if (!Number.isNaN(num) && raw.trim() === num.toString()) {\n    return num;\n  }\n\n  // Try JSON parsing (for objects/arrays)\n  try {\n    return JSON.parse(raw);\n  } catch {\n    // Fallback to string\n    return raw;\n  }\n}\n\n/**\n * Load and parse a JSON config file\n */\nfunction loadConfigFile(path: string): any {\n  const abs = resolve(process.cwd(), path);\n  try {\n    const contents = readFileSync(abs, 'utf8');\n    const parsed = JSON.parse(contents);\n\n    if (typeof parsed !== 'object' || Array.isArray(parsed) || parsed === null) {\n      console.error(\n        `❌ Flags config must be a JSON object, got ${Array.isArray(parsed) ? 'array' : typeof parsed}`,\n      );\n      process.exit(1);\n    }\n\n    return parsed;\n  } catch (err: any) {\n    console.error(`❌ Could not read or parse flags config \"${path}\": ${err.message}`);\n    process.exit(1);\n  }\n}\n\n/**\n * Extract flag overrides with support for both CLI flags and config files.\n *\n * Supports CLI flags:\n * - --flag.temperature=0.9\n * - --flag.dryRun=true | false\n * - --flag.foo={\"bar\":1} (JSON literal)\n * - --flag.bare (interpreted as true)\n *\n * Or config file:\n * - --flags-config=path/to/config.json\n *\n * Enforces exclusive mode - cannot use both --flags-config and --flag.* together.\n */\nexport function extractOverrides(argv: string[]): {\n  cleanedArgv: string[];\n  overrides: FlagOverrides;\n} {\n  const cleanedArgv: string[] = [];\n  const overrides: FlagOverrides = {};\n  let configPath: string | null = null;\n  let hasCliFlags = false;\n  let configPathCount = 0;\n\n  for (let i = 0; i < argv.length; i++) {\n    const token = argv[i];\n    const configMatch = token.match(CONFIG_RE);\n    const flagMatch = token.match(FLAG_RE);\n\n    if (configMatch) {\n      // Handle --flags-config\n      configPathCount++;\n      if (configPathCount > 1) {\n        console.error('❌ Only one --flags-config can be supplied.');\n        process.exit(1);\n      }\n\n      const value = configMatch[1]; // undefined means no equals sign\n      const nextToken = argv.length > i + 1 ? argv[i + 1] : undefined;\n\n      ensureNoSpaceSeparatedSyntax('flags-config', value, nextToken, 'config');\n\n      if (!value) {\n        console.error('❌ --flags-config requires a file path');\n        console.error('💡 Use: --flags-config=path/to/config.json');\n        process.exit(1);\n      }\n\n      configPath = value;\n\n      // Don't add to cleanedArgv\n    } else if (flagMatch) {\n      // Handle --flag.*\n      hasCliFlags = true;\n\n      const key = flagMatch[1];\n      const value = flagMatch[2]; // undefined means bare flag (boolean true)\n      const nextToken = argv.length > i + 1 ? argv[i + 1] : undefined;\n\n      ensureNoSpaceSeparatedSyntax(key, value, nextToken, 'flag');\n\n      // If no value, treat as boolean true\n      const finalValue = value === undefined ? 'true' : value;\n      overrides[key] = coerceValue(finalValue);\n\n      // Don't add to cleanedArgv\n    } else {\n      cleanedArgv.push(token);\n    }\n  }\n\n  if (configPath && hasCliFlags) {\n    console.error('❌ Cannot use both --flags-config and --flag.* arguments together.');\n    console.error('Choose one approach:');\n    console.error('  • Config file: --flags-config=my-flags.json');\n    console.error('  • CLI flags: --flag.temperature=0.9 --flag.model=gpt-4o');\n    process.exit(1);\n  }\n\n  if (configPath) {\n    const configOverrides = loadConfigFile(configPath);\n    return { cleanedArgv, overrides: configOverrides };\n  }\n\n  return { cleanedArgv, overrides };\n}\n","/**\n * Simple glob detection utility\n * Detects if a string contains glob pattern characters\n */\nexport function isGlob(str: string): boolean {\n  // Check for glob characters: * ? [ ] { } !\n  return /[*?[\\]{}!]/.test(str);\n}\n","import { Command, Argument, Option } from 'commander';\nimport { customAlphabet } from 'nanoid';\nimport { lstatSync } from 'node:fs';\nimport { runEvalWithContext } from '../utils/eval-context-runner';\nimport { validateFlagOverrides, type FlagOverrides } from '../utils/parse-flag-overrides';\nimport { isGlob } from '../utils/glob-utils';\nimport { loadConfig } from '../../config/loader';\nimport { AxiomCLIError } from '../../util/errors';\nimport { getAuthContext } from '../auth/global-auth';\nimport c from 'tinyrainbow';\n\nconst createRunId = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 10);\n\n// Module-level storage for console URL override\nlet consoleUrl: string | undefined;\nexport function getConsoleUrl(): string | undefined {\n  return consoleUrl;\n}\n/**\n * Gets default token from auth context or falls back to env var\n */\nfunction getDefaultToken(value: unknown): string | undefined {\n  if (typeof value === 'string') {\n    return value;\n  }\n  const authContext = getAuthContext();\n  return authContext?.token || process.env.AXIOM_TOKEN;\n}\n\n/**\n * Gets default URL from auth context or falls back to env var\n */\nfunction getDefaultUrl(value: unknown): string {\n  if (typeof value === 'string') {\n    return value;\n  }\n  const authContext = getAuthContext();\n  return authContext?.url || process.env.AXIOM_URL || 'https://api.axiom.co';\n}\n\n/**\n * Gets default organization id from auth context or falls back to env var\n */\nfunction getDefaultOrgId(value: unknown): string | undefined {\n  if (typeof value === 'string') {\n    return value;\n  }\n  const authContext = getAuthContext();\n  return authContext?.orgId ?? process.env.AXIOM_ORG_ID;\n}\n\nexport const loadEvalCommand = (program: Command, flagOverrides: FlagOverrides = {}) => {\n  return program.addCommand(\n    new Command('eval')\n      .description('run evals locally')\n      .addArgument(\n        new Argument('[target]', 'file, directory, glob pattern, or eval name').default(\n          '.',\n          'any *.eval.ts file in current directory',\n        ),\n      )\n      .option('-w, --watch true', 'keep server running and watch for changes', false)\n      .option('-t, --token <TOKEN>', 'axiom token', getDefaultToken)\n      .option('-d, --dataset <DATASET>', 'axiom dataset name')\n      .option('-u, --url <AXIOM URL>', 'axiom url', getDefaultUrl)\n      .option('-o, --org-id <ORG ID>', 'axiom organization id', getDefaultOrgId)\n      .option('-b, --baseline <BASELINE ID>', 'id of baseline evaluation to compare against')\n      .option('--debug', 'run locally without any network operations', false)\n      .option('--list', 'list evaluations and test cases without running them', false)\n      /** Hides the option from the help output, but still allows it to be passed */\n      .addOption(new Option('-c, --console-url <URL>', 'console url override').hideHelp())\n      .action(async (target: string, options) => {\n        try {\n          // Propagate debug mode to processes that we can't reach otherwise (e.g., reporter, app instrumentation)\n          if (options.debug) {\n            process.env.AXIOM_DEBUG = 'true';\n          }\n\n          let include: string[] = [];\n          let exclude: string[] | undefined;\n          let testNamePattern: RegExp | undefined;\n\n          const isGlobPattern = isGlob(target);\n\n          // Load config file first to get defaults\n          const { config: loadedConfig } = await loadConfig('.');\n\n          // Validate CLI flags against schema\n          validateFlagOverrides(flagOverrides, loadedConfig.eval.flagSchema);\n\n          // Override config with CLI options if provided\n          const config = {\n            ...loadedConfig,\n            eval: {\n              ...loadedConfig.eval,\n              ...(options.token && { token: options.token }),\n              ...(options.url && { url: options.url }),\n              ...(options.dataset && { dataset: options.dataset }),\n              ...(options.orgId && { orgId: options.orgId }),\n            },\n          };\n\n          if (isGlobPattern) {\n            // Handle glob patterns like \"**/*.eval.ts\" or \"**/my-feature/*\"\n            include = [target];\n          } else {\n            try {\n              // Try to treat as file/directory path\n              const stat = lstatSync(target);\n              if (stat.isDirectory()) {\n                include = config?.eval?.include || [];\n              } else {\n                // Single file\n                include = [target];\n              }\n            } catch {\n              // Path doesn't exist, treat as eval name\n              testNamePattern = new RegExp(target, 'i');\n              // Use config include patterns when searching by name\n              include = config?.eval?.include || [];\n            }\n          }\n\n          exclude = config?.eval?.exclude;\n\n          if (!config?.eval?.instrumentation) {\n            console.warn(\n              c.yellow(\n                '⚠ App instrumentation (`eval.instrumentation` in `axiom.config.ts`) not configured. Using default provider.',\n              ),\n            );\n            console.log('');\n          }\n\n          const runId = createRunId();\n\n          consoleUrl = options.consoleUrl;\n\n          // Dynamic import to avoid loading vitest at CLI startup (breaks `npx axiom login`)\n          let runVitestModule;\n          try {\n            runVitestModule = await import('../../evals/run-vitest');\n          } catch (err: unknown) {\n            if (\n              err &&\n              typeof err === 'object' &&\n              'code' in err &&\n              (err.code === 'ERR_MODULE_NOT_FOUND' || err.code === 'MODULE_NOT_FOUND')\n            ) {\n              throw new AxiomCLIError('Failed to load vitest.');\n            }\n            throw err;\n          }\n          const { runVitest } = runVitestModule;\n\n          await runEvalWithContext(flagOverrides, async () => {\n            return runVitest('.', {\n              watch: options.watch,\n              baseline: options.baseline,\n              include,\n              exclude,\n              testNamePattern,\n              debug: options.debug,\n              list: options.list,\n              overrides: flagOverrides,\n              config,\n              runId,\n              consoleUrl: options.consoleUrl,\n            });\n          });\n        } catch (error) {\n          if (error instanceof AxiomCLIError) {\n            console.error(`\\n❌ ${error.message}\\n`);\n            process.exit(1);\n          }\n          throw error;\n        }\n      }),\n  );\n};\n","import type { SerializedError } from 'vitest';\nimport type { Reporter, TestCase, TestModule, TestRunEndReason, TestSuite } from 'vitest/node';\n\nimport { getAxiomConfig } from './context/storage';\nimport type { EvaluationReport, MetaWithCase, MetaWithEval, Case } from './eval.types';\nimport {\n  printBaselineNameAndVersion,\n  printEvalNameAndFileName,\n  printFinalReport,\n  printGlobalFlagOverrides,\n  printTestCaseCountStartDuration,\n  type SuiteData,\n  printOrphanedBaselineCases,\n  getCaseFingerprint,\n  printCaseResult,\n} from './reporter.console-utils';\nimport { resolveAxiomConnection, type AxiomConnectionResolvedConfig } from '../config/resolver';\nimport { getConsoleUrl } from '../cli/commands/eval.command';\nimport { dotNotationToNested, flattenObject } from '../util/dot-path';\n\n/**\n * Custom Vitest reporter for Axiom AI evaluations.\n *\n * This reporter collects evaluation results and scores from tests\n * and processes them for further analysis and reporting.\n *\n */\nexport class AxiomReporter implements Reporter {\n  startTime: number = 0;\n  start: number = 0;\n  private _endOfRunConfigEnd: EvaluationReport['configEnd'] | undefined;\n  private _suiteData: SuiteData[] = [];\n  private _printedFlagOverrides = false;\n  private _config: AxiomConnectionResolvedConfig | undefined;\n\n  onTestRunStart() {\n    this.start = performance.now();\n    this.startTime = new Date().getTime();\n\n    // Store resourcesUrl from config\n    const config = getAxiomConfig();\n    if (config) {\n      this._config = resolveAxiomConnection(config, getConsoleUrl());\n    }\n  }\n\n  async onTestSuiteReady(_testSuite: TestSuite) {\n    const meta = _testSuite.meta() as MetaWithEval;\n    if (_testSuite.state() === 'skipped' || !meta?.evaluation) {\n      return;\n    }\n\n    // Print flag overrides once when defaults become available\n    // (we don't have them in `onTestRunStart`)\n    if (!this._printedFlagOverrides) {\n      const defaultsFromConfigEnd = meta.evaluation.configEnd?.flags ?? {};\n      const overridesFromConfigEnd = meta.evaluation.configEnd?.overrides ?? {};\n\n      if (Object.keys(overridesFromConfigEnd).length > 0) {\n        printGlobalFlagOverrides(overridesFromConfigEnd, defaultsFromConfigEnd);\n      }\n      this._printedFlagOverrides = true;\n    }\n\n    // capture end-of-run config snapshot (first non-empty wins)\n    if (meta.evaluation.configEnd && !this._endOfRunConfigEnd) {\n      this._endOfRunConfigEnd = meta.evaluation.configEnd;\n    }\n  }\n\n  onTestCaseReady(test: TestCase) {\n    const meta = test.meta() as MetaWithCase;\n\n    // TODO: there seem to be some cases where `meta` is undefined\n    // maybe we get here to early?\n    if (!meta.case) return;\n  }\n\n  async onTestSuiteResult(testSuite: TestSuite) {\n    const meta = testSuite.meta() as MetaWithEval;\n    // test suite won't have any meta because its skipped or failed before setup\n    if (testSuite.state() === 'skipped' || !meta?.evaluation) {\n      return;\n    }\n\n    // capture end-of-run config snapshot (first non-empty wins)\n    if (meta.evaluation.configEnd && !this._endOfRunConfigEnd) {\n      this._endOfRunConfigEnd = meta.evaluation.configEnd;\n    }\n\n    const durationSeconds = Number((performance.now() - this.start) / 1000).toFixed(2);\n\n    const cases: SuiteData['cases'] = [];\n    for (const test of testSuite.children) {\n      if (test.type !== 'test') continue;\n\n      const testMeta = test.meta() as MetaWithCase;\n      if (!testMeta?.case) continue;\n\n      cases.push({\n        index: testMeta.case.index,\n        scores: testMeta.case.scores,\n        outOfScopeFlags: testMeta.case.outOfScopeFlags,\n        errors: testMeta.case.errors,\n        runtimeFlags: testMeta.case.runtimeFlags,\n      });\n    }\n\n    const cwd = process.cwd();\n    const relativePath = testSuite.module.moduleId.replace(cwd, '').replace(/^\\//, '');\n\n    // Collect suite data for final report\n    let suiteBaseline = meta.evaluation.baseline;\n\n    let flagConfig = meta.evaluation.flagConfig;\n    if (meta.evaluation.configEnd) {\n      const defaults = meta.evaluation.configEnd.flags ?? {};\n      const overrides = meta.evaluation.configEnd.overrides ?? {};\n      const defaultsFlat = flattenObject(defaults);\n      const overridesFlat = flattenObject(overrides);\n      flagConfig = dotNotationToNested({ ...defaultsFlat, ...overridesFlat });\n    }\n\n    const defaultFlagConfig = meta.evaluation.configEnd?.flags;\n\n    this._suiteData.push({\n      version: meta.evaluation.version,\n      name: meta.evaluation.name,\n      file: relativePath,\n      duration: durationSeconds + 's',\n      baseline: suiteBaseline || null,\n      configFlags: meta.evaluation.configFlags,\n      flagConfig,\n      defaultFlagConfig,\n      runId: meta.evaluation.runId,\n      orgId: meta.evaluation.orgId,\n      cases,\n      outOfScopeFlags: meta.evaluation.outOfScopeFlags,\n      registrationStatus: meta.evaluation.registrationStatus,\n    });\n\n    printEvalNameAndFileName(testSuite, meta);\n    printBaselineNameAndVersion(meta);\n\n    printTestCaseCountStartDuration(\n      testSuite,\n      this.startTime,\n      durationSeconds,\n      meta.evaluation.trials,\n    );\n\n    const matchedBaselineIndices = new Set<number>();\n    const baselineCasesByFingerprint = new Map<string, Case[]>();\n\n    if (suiteBaseline) {\n      for (const c of suiteBaseline.cases) {\n        const fp = getCaseFingerprint(c.input, c.expected);\n        const cases = baselineCasesByFingerprint.get(fp) || [];\n        cases.push(c);\n        baselineCasesByFingerprint.set(fp, cases);\n      }\n    }\n\n    for (const test of testSuite.children) {\n      if (test.type !== 'test') continue;\n      printCaseResult(test, baselineCasesByFingerprint, matchedBaselineIndices);\n    }\n\n    if (suiteBaseline) {\n      printOrphanedBaselineCases(suiteBaseline, matchedBaselineIndices);\n    }\n\n    console.log('');\n  }\n\n  async onTestRunEnd(\n    _testModules: ReadonlyArray<TestModule>,\n    _errors: ReadonlyArray<SerializedError>,\n    _reason: TestRunEndReason,\n  ) {\n    const shouldClear = !process.env.CI && process.stdout.isTTY !== false;\n\n    if (shouldClear) {\n      process.stdout.write('\\x1b[2J\\x1b[0f'); // Clear screen and move cursor to top\n    }\n\n    const registrationStatus = this._suiteData.map((suite) => ({\n      name: suite.name,\n      registered: suite.registrationStatus?.status === 'success',\n      error:\n        suite.registrationStatus?.status === 'failed' ? suite.registrationStatus.error : undefined,\n    }));\n\n    const isDebug = process.env.AXIOM_DEBUG === 'true';\n\n    printFinalReport({\n      suiteData: this._suiteData,\n      config: this._config,\n      registrationStatus,\n      isDebug,\n    });\n  }\n}\n","export { Eval } from './evals/eval';\nexport type { EvalTask, EvalParams } from './evals/eval.types';\nexport { AxiomReporter } from './evals/reporter';\n\nexport type { EvalContextData } from './evals/context/storage';\n\nexport type { EvalBuilder } from './evals/builder';\nexport { type Score, type ScorerOptions } from './evals/scorer.types';\n\nimport { createScorer } from './evals/scorer.factory';\nimport { warnScorerDeprecation } from './evals/deprecated';\n\n/** @deprecated Import from 'axiom/ai/evals/scorers' instead. */\nexport const Scorer = ((...args: unknown[]) => {\n  warnScorerDeprecation('axiom/ai/evals');\n  return (createScorer as Function)(...args);\n}) as typeof createScorer;\n\nexport type { Evaluation, Case, Chat, Task } from './evals/eval.types';\n","import { afterAll, beforeAll, describe, inject, it } from 'vitest';\nimport { context, SpanStatusCode, trace, type Context } from '@opentelemetry/api';\nimport { customAlphabet } from 'nanoid';\nimport { withEvalContext, getEvalContext, getConfigScope } from './context/storage';\n\nimport { Attr } from '../otel/semconv/attributes';\nimport type { ResolvedAxiomConfig } from '../config/index';\nimport { startActiveSpan, startSpan, flush, ensureInstrumentationInitialized } from './instrument';\nimport { getGitUserInfo } from './git-info';\nimport type {\n  CollectionRecord,\n  EvalParams,\n  EvalTask,\n  EvaluationReport,\n  EvalCaseReport,\n  RuntimeFlagLog,\n  OutOfScopeFlag,\n  Evaluation,\n  OutOfScopeFlagAccess,\n} from './eval.types';\nimport type { ScoreWithName, ScorerLike, Scorer } from './scorer.types';\nimport { Mean, type Aggregation } from './aggregations';\nimport { EvaluationApiClient, findEvaluationCases } from './eval.service';\nimport { getGlobalFlagOverrides, setGlobalFlagOverrides } from './context/global-flags';\nimport { deepEqual } from '../util/deep-equal';\nimport { dotNotationToNested } from '../util/dot-path';\nimport { AxiomCLIError, errorToString } from '../util/errors';\nimport { tryCatchAsync, toError } from '../util/tryCatch';\nimport type { ValidateName } from '../util/name-validation';\nimport { recordName } from './name-validation-runtime';\n\ndeclare module 'vitest' {\n  interface TestSuiteMeta {\n    evaluation: EvaluationReport;\n  }\n  interface TaskMeta {\n    case: EvalCaseReport;\n    evaluation: EvaluationReport;\n  }\n  export interface ProvidedContext {\n    baseline?: string;\n    debug?: boolean;\n    list?: boolean;\n    overrides?: Record<string, any>;\n    axiomConfig?: ResolvedAxiomConfig;\n    runId: string;\n    consoleUrl?: string;\n  }\n}\n\nconst createVersionId = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 10);\n\ntype RunTaskFailureDetails = {\n  duration: number;\n  outOfScopeFlags: OutOfScopeFlagAccess[];\n  finalFlags: Record<string, any>;\n  overrides?: Record<string, any>;\n};\n\nconst RUN_TASK_FAILURE_DETAILS = Symbol.for('axiom.eval.runTaskFailureDetails');\n\nfunction attachRunTaskFailureDetails(\n  error: unknown,\n  details: RunTaskFailureDetails,\n): Error & { [RUN_TASK_FAILURE_DETAILS]: RunTaskFailureDetails } {\n  const normalized = toError(error) as Error & {\n    [RUN_TASK_FAILURE_DETAILS]?: RunTaskFailureDetails;\n  };\n  normalized[RUN_TASK_FAILURE_DETAILS] = details;\n  return normalized as Error & { [RUN_TASK_FAILURE_DETAILS]: RunTaskFailureDetails };\n}\n\nfunction getRunTaskFailureDetails(error: unknown): RunTaskFailureDetails | undefined {\n  if (typeof error !== 'object' || error === null) {\n    return undefined;\n  }\n  return (error as { [RUN_TASK_FAILURE_DETAILS]?: RunTaskFailureDetails })[\n    RUN_TASK_FAILURE_DETAILS\n  ];\n}\n\n/**\n * Creates and registers an evaluation suite with the given name and parameters.\n *\n * This function sets up a complete evaluation pipeline that will run your {@link EvalTask}\n * against a collection, score the results, and provide detailed {@link EvalCaseReport} reporting.\n *\n *\n * @param name - Human-readable name for the evaluation suite\n * @param params - {@link EvalParams} configuration parameters for the evaluation\n *\n * @example\n * ```typescript\n * import { Eval } from 'axiom/ai/evals';\n *\n * Eval('Text Generation Quality', {\n *   capability: 'capability-name',\n *   data: async () => [\n *     { input: 'Explain photosynthesis', expected: 'Plants convert light to energy...' },\n *     { input: 'What is gravity?', expected: 'Gravity is a fundamental force...' }\n *   ],\n *   task: async ({ input }) => {\n *     const result = await generateText({\n *       model: yourModel,\n *       prompt: input\n *     });\n *     return result.text;\n *   },\n *   scorers: [similarityScorer, factualAccuracyScorer],\n * });\n * ```\n */\nexport function Eval<\n  TInput,\n  TExpected,\n  TOutput,\n  Name extends string = string,\n  Capability extends string = string,\n  Step extends string = string,\n>(\n  name: ValidateName<Name>,\n  params: Omit<EvalParams<TInput, TExpected, TOutput>, 'capability' | 'step'> & {\n    capability: ValidateName<Capability>;\n    step?: ValidateName<Step> | undefined;\n  },\n): void {\n  // Record eval name for validation\n  recordName('eval', name);\n  recordName('capability', params.capability);\n  if (params.step) {\n    recordName('step', params.step);\n  }\n\n  // Record all scorer names for validation\n  if (params.scorers) {\n    for (const scorer of params.scorers) {\n      const scorerName = getScorerName(scorer, '');\n      recordName('scorer', scorerName);\n    }\n  }\n\n  registerEval(name, params as EvalParams<any, any, any>).catch(console.error);\n}\n\n/**\n * Capture full flag configuration filtered by configFlags scope\n */\nfunction captureFlagConfig(configFlags?: string[]): Record<string, any> {\n  if (!configFlags || configFlags.length === 0) {\n    return {};\n  }\n\n  const scope = getConfigScope();\n  const allDefaults = scope?.getAllDefaultFlags?.() ?? {};\n  const overrides = getGlobalFlagOverrides();\n\n  const merged = { ...allDefaults, ...overrides };\n\n  // Filter to only flags in configFlags scope\n  const filtered: Record<string, any> = {};\n  for (const [key, value] of Object.entries(merged)) {\n    const isInScope = configFlags.some((pattern) => key.startsWith(pattern));\n    if (isInScope) {\n      filtered[key] = value;\n    }\n  }\n\n  return dotNotationToNested(filtered);\n}\n\nconst getScorerName = <TScorer extends ScorerLike<any, any, any>>(\n  scorer: TScorer,\n  fallback: string = 'unknown',\n) => {\n  return (scorer as any).name || fallback;\n};\n\nasync function registerEval<\n  TInput extends string | Record<string, any>,\n  TExpected extends string | Record<string, any>,\n  TOutput extends string | Record<string, any>,\n>(evalName: string, opts: EvalParams<TInput, TExpected, TOutput>) {\n  opts.data;\n  const collectionPromise:\n    | readonly CollectionRecord<TInput, TExpected>[]\n    | Promise<readonly CollectionRecord<TInput, TExpected>[]> =\n    typeof opts.data === 'function'\n      ? (\n          opts.data as () =>\n            | readonly CollectionRecord<TInput, TExpected>[]\n            | Promise<readonly CollectionRecord<TInput, TExpected>[]>\n        )()\n      : opts.data;\n  const user = getGitUserInfo();\n\n  // check if user passed a specific baseline id to the CLI\n  const baselineId = inject('baseline');\n  const isDebug = inject('debug');\n  const isList = inject('list');\n  const injectedOverrides = inject('overrides');\n  const axiomConfig = inject('axiomConfig');\n  const runId = inject('runId');\n  const consoleUrl = inject('consoleUrl');\n\n  if (!axiomConfig) {\n    throw new AxiomCLIError('Axiom config not found');\n  }\n\n  const timeoutMs = opts.timeout ?? axiomConfig?.eval.timeoutMs;\n\n  const instrumentationReady = ensureInstrumentationInitialized(axiomConfig, {\n    enabled: !isDebug && !isList,\n  });\n\n  const result = await describe(\n    evalName,\n    async () => {\n      const collection = await collectionPromise;\n\n      const evaluationApiClient = new EvaluationApiClient(axiomConfig, consoleUrl);\n\n      // create a version code\n      const evalVersion = createVersionId();\n      let evalId = ''; // get traceId\n      let suiteStart: number;\n\n      let suiteSpan: ReturnType<typeof startSpan> | undefined;\n      let suiteContext: Context | undefined;\n      let instrumentationError: unknown = undefined;\n      let baseline: Evaluation | null | undefined = undefined;\n\n      // Track out-of-scope flags across all cases for evaluation-level reporting\n      const allOutOfScopeFlags: OutOfScopeFlagAccess[] = [];\n\n      // Track final config snapshot from the last executed case for reporter printing\n      let finalConfigSnapshot:\n        | { flags: Record<string, any>; pickedFlags?: string[]; overrides?: Record<string, any> }\n        | undefined;\n\n      beforeAll(async (suite) => {\n        // Ensure worker process knows CLI overrides\n        if (injectedOverrides && Object.keys(injectedOverrides).length > 0) {\n          try {\n            setGlobalFlagOverrides(injectedOverrides);\n          } catch {}\n        }\n\n        suite.meta.evaluation = {\n          id: evalId,\n          name: evalName,\n          version: evalVersion,\n          runId: runId,\n          orgId: undefined,\n          baseline: baseline ?? undefined,\n          configFlags: opts.configFlags,\n        };\n\n        const [, instrumentationInitError] = await tryCatchAsync(instrumentationReady);\n        if (instrumentationInitError) {\n          instrumentationError = instrumentationInitError;\n        }\n\n        suiteSpan = startSpan(`eval ${evalName}-${evalVersion}`, {\n          attributes: {\n            [Attr.GenAI.Operation.Name]: 'eval',\n            [Attr.Eval.Name]: evalName,\n            [Attr.Eval.Version]: evalVersion,\n            [Attr.Eval.Type]: 'regression', // TODO: where to get experiment type value from?\n            [Attr.Eval.Tags]: JSON.stringify(['offline']),\n            [Attr.Eval.Collection.ID]: 'custom', // TODO: where to get collection split value from?\n            [Attr.Eval.Collection.Name]: 'custom', // TODO: where to get collection name from?\n            [Attr.Eval.Collection.Size]: collection.length,\n            // capability\n            [Attr.Eval.Capability.Name]: opts.capability,\n            [Attr.Eval.Step.Name]: opts.step ?? undefined,\n            // metadata\n            [Attr.Eval.Metadata]: JSON.stringify(opts.metadata),\n            // run\n            [Attr.Eval.Run.ID]: runId,\n            // user info\n            [Attr.Eval.User.Name]: user?.name,\n            [Attr.Eval.User.Email]: user?.email,\n          },\n        });\n        evalId = suiteSpan.spanContext().traceId;\n        suite.meta.evaluation.id = evalId;\n        suiteSpan.setAttribute(Attr.Eval.ID, evalId);\n        suiteContext = trace.setSpan(context.active(), suiteSpan);\n\n        const flagConfig = captureFlagConfig(opts.configFlags);\n        suite.meta.evaluation.flagConfig = flagConfig;\n        const flagConfigJson = JSON.stringify(flagConfig);\n        suiteSpan.setAttribute(Attr.Eval.Config.Flags, flagConfigJson);\n\n        let createEvalResponse;\n        if (!isDebug && !isList) {\n          createEvalResponse = await evaluationApiClient.createEvaluation({\n            id: evalId,\n            name: evalName,\n            capability: opts.capability,\n            step: opts.step,\n            dataset: axiomConfig.eval.dataset,\n            version: evalVersion,\n            baselineId: baselineId ?? undefined,\n            runId: runId,\n            totalCases: collection.length,\n            config: { overrides: injectedOverrides },\n            configTimeoutMs: timeoutMs,\n            metadata: opts.metadata,\n            status: 'running',\n          });\n        }\n\n        const orgId = createEvalResponse?.data?.orgId;\n        const resolvedBaselineId = createEvalResponse?.data?.baselineId;\n\n        // Load baseline if we got a baselineId from the server\n        if (!isDebug && !isList && !!resolvedBaselineId) {\n          const [baselineResult, baselineError] = await tryCatchAsync(() =>\n            findEvaluationCases(resolvedBaselineId, axiomConfig),\n          );\n          if (baselineError) {\n            console.error(`Failed to load baseline: ${errorToString(baselineError)}`);\n            instrumentationError = instrumentationError || baselineError;\n          } else {\n            baseline = baselineResult;\n          }\n        }\n\n        // Update span with baseline info\n        if (baseline) {\n          suiteSpan.setAttribute(Attr.Eval.Baseline.ID, baseline.id);\n          suiteSpan.setAttribute(Attr.Eval.Baseline.Name, baseline.name);\n          suiteSpan.setAttribute(Attr.Eval.Baseline.Version, baseline.version);\n        }\n\n        suite.meta.evaluation = {\n          id: evalId,\n          name: evalName,\n          version: evalVersion,\n          runId: runId,\n          orgId: orgId ?? undefined,\n          baseline: baseline ?? undefined,\n          configFlags: opts.configFlags,\n          registrationStatus: instrumentationError\n            ? {\n                status: 'failed',\n                error: errorToString(instrumentationError),\n              }\n            : { status: 'success' },\n          trials: opts.trials,\n        };\n\n        suiteStart = performance.now();\n      });\n\n      afterAll(async (suite) => {\n        if (instrumentationError) {\n          throw instrumentationError;\n        }\n\n        // Aggregate out-of-scope flags for evaluation-level reporting\n        const flagSummary = new Map<string, OutOfScopeFlag>();\n\n        for (const flag of allOutOfScopeFlags) {\n          if (flagSummary.has(flag.flagPath)) {\n            const existing = flagSummary.get(flag.flagPath)!;\n            existing.count++;\n            existing.firstAccessedAt = Math.min(existing.firstAccessedAt, flag.accessedAt);\n            existing.lastAccessedAt = Math.max(existing.lastAccessedAt, flag.accessedAt);\n          } else {\n            flagSummary.set(flag.flagPath, {\n              flagPath: flag.flagPath,\n              count: 1,\n              firstAccessedAt: flag.accessedAt,\n              lastAccessedAt: flag.accessedAt,\n              stackTrace: flag.stackTrace,\n            });\n          }\n        }\n\n        // Update evaluation report with aggregated out-of-scope flags\n        if (suite.meta.evaluation && suiteSpan) {\n          suite.meta.evaluation.outOfScopeFlags = Array.from(flagSummary.entries()).map(\n            ([_flagPath, stats]) => stats,\n          );\n\n          // Attach end-of-suite config snapshot for reporter printing\n          const allDefaults = getConfigScope()?.getAllDefaultFlags();\n          const pickedFlags = finalConfigSnapshot?.pickedFlags;\n          const overrides = injectedOverrides ?? getGlobalFlagOverrides();\n\n          suite.meta.evaluation.configEnd = {\n            flags: allDefaults,\n            pickedFlags,\n            overrides,\n          };\n        }\n\n        // end root span\n        suiteSpan?.setStatus({ code: SpanStatusCode.OK });\n        suiteSpan?.end();\n\n        // flush traces before updating Evaluation in Axiom\n        const [, flushError] = await tryCatchAsync(flush);\n        if (flushError) {\n          // Update registration status to failed if flush fails\n          if (suite.meta.evaluation) {\n            suite.meta.evaluation.registrationStatus = {\n              status: 'failed',\n              error: errorToString(flushError),\n            };\n          }\n        }\n\n        const durationMs = Math.round(performance.now() - suiteStart);\n\n        const successCases = suite.tasks.filter(\n          (task) => task.meta.case.status === 'success',\n        ).length;\n        const erroredCases = suite.tasks.filter(\n          (task) => task.meta.case.status === 'fail' || task.meta.case.status === 'pending',\n        ).length;\n\n        // signal Axiom that evaluation finished to kick of summary calculations\n        if (!isDebug && !isList) {\n          await evaluationApiClient.updateEvaluation({\n            id: evalId,\n            status: 'completed',\n            totalCases: collection.length,\n            successCases,\n            erroredCases,\n            durationMs,\n          });\n        }\n      });\n\n      type CollectionRecordWithIndex = { index: number } & CollectionRecord<TInput, TExpected>;\n\n      await it.concurrent.for(\n        collection.map((d, index) => ({ ...d, index }) satisfies CollectionRecordWithIndex),\n      )('case', async (data, { task }) => {\n        const start = performance.now();\n        if (!suiteContext) {\n          throw new Error(\n            '[Axiom AI] Suite context not initialized. This is likely a bug – instrumentation should complete before tests run.',\n          );\n        }\n\n        let outOfScopeFlags: OutOfScopeFlagAccess[] = [];\n\n        await startActiveSpan(\n          `case ${data.index}`,\n          {\n            attributes: {\n              [Attr.GenAI.Operation.Name]: 'eval.case',\n              [Attr.Eval.ID]: evalId,\n              [Attr.Eval.Name]: evalName,\n              [Attr.Eval.Version]: evalVersion,\n              [Attr.Eval.Case.Index]: data.index,\n              [Attr.Eval.Case.Input]:\n                typeof data.input === 'string' ? data.input : JSON.stringify(data.input),\n              [Attr.Eval.Case.Expected]:\n                typeof data.expected === 'string' ? data.expected : JSON.stringify(data.expected),\n              [Attr.Eval.Case.Metadata]: data.metadata ? JSON.stringify(data.metadata) : undefined,\n              // user info\n              [Attr.Eval.User.Name]: user?.name,\n              [Attr.Eval.User.Email]: user?.email,\n            },\n          },\n          async (caseSpan) => {\n            const caseContext = trace.setSpan(context.active(), caseSpan);\n            const trials = Math.max(1, opts.trials ?? 1);\n            let intentionalTrialFailureError: Error | undefined;\n            let caseFinalConfigSnapshot:\n              | {\n                  flags: Record<string, any>;\n                  pickedFlags?: string[];\n                  overrides?: Record<string, any>;\n                }\n              | undefined;\n\n            // Set case-level trials attribute\n            caseSpan.setAttribute(Attr.Eval.Case.Trials, trials);\n\n            try {\n              // Accumulators for per-trial scores\n              const perScorerTrials: Record<string, number[]> = {};\n              const trialErrors: Array<string | null> = Array.from({ length: trials }, () => null);\n              const trialFailures: Error[] = [];\n              let lastOutput: TOutput | undefined;\n              let successfulTaskDuration = 0;\n\n              // Run each trial\n              for (let trialIndex = 0; trialIndex < trials; trialIndex++) {\n                try {\n                  await startActiveSpan(\n                    `trial ${trialIndex}`,\n                    {\n                      attributes: {\n                        [Attr.GenAI.Operation.Name]: 'eval.trial',\n                        [Attr.Eval.Trial.Index]: trialIndex,\n                        [Attr.Eval.ID]: evalId,\n                        [Attr.Eval.Name]: evalName,\n                        [Attr.Eval.Version]: evalVersion,\n                      },\n                    },\n                    async (trialSpan) => {\n                      const trialContext = trace.setSpan(context.active(), trialSpan);\n                      try {\n                        const result = await runTask(\n                          trialContext,\n                          {\n                            id: evalId,\n                            version: evalVersion,\n                            name: evalName,\n                          },\n                          {\n                            index: data.index,\n                            input: data.input,\n                            expected: data.expected,\n                            scorers: opts.scorers,\n                            task: opts.task,\n                            metadata: opts.metadata,\n                            configFlags: opts.configFlags,\n                            capability: opts.capability,\n                            step: opts.step,\n                          },\n                        );\n                        const { output, duration } = result;\n                        lastOutput = output;\n                        successfulTaskDuration += duration;\n                        outOfScopeFlags.push(...result.outOfScopeFlags);\n\n                        caseFinalConfigSnapshot = {\n                          flags: result.finalFlags || {},\n                          pickedFlags: opts.configFlags,\n                          overrides: result.overrides,\n                        };\n\n                        // Run scorers inside the trial span\n                        await Promise.all(\n                          opts.scorers.map(async (scorer) => {\n                            const scorerName = getScorerName(scorer);\n                            return startActiveSpan(\n                              `score ${scorerName}`,\n                              {\n                                attributes: {\n                                  [Attr.GenAI.Operation.Name]: 'eval.score',\n                                  [Attr.Eval.Tags]: JSON.stringify(['offline']),\n                                  [Attr.Eval.ID]: evalId,\n                                  [Attr.Eval.Name]: evalName,\n                                  [Attr.Eval.Version]: evalVersion,\n                                  [Attr.Eval.Trial.Index]: trialIndex,\n                                },\n                              },\n                              async (scorerSpan) => {\n                                const scorerStart = performance.now();\n                                try {\n                                  const [result, scorerError] = await tryCatchAsync(() =>\n                                    scorer({\n                                      input: data.input,\n                                      output: output,\n                                      expected: data.expected,\n                                      trialIndex,\n                                    }),\n                                  );\n\n                                  if (scorerError || !result) {\n                                    const scorerDuration = Math.round(\n                                      performance.now() - scorerStart,\n                                    );\n                                    console.error(\n                                      `ERROR: scorer ${scorerName} failed. Cause: \\n`,\n                                      scorerError,\n                                    );\n                                    const msg = errorToString(scorerError);\n                                    const metadata = {\n                                      duration: scorerDuration,\n                                      startedAt: scorerStart,\n                                      error: msg,\n                                    };\n\n                                    // Count scorer failures as zero so failed trials affect aggregation.\n                                    (perScorerTrials[scorerName] ??= []).push(0);\n\n                                    scorerSpan.setAttributes({\n                                      [Attr.Eval.Score.Name]: scorerName,\n                                      [Attr.Eval.Score.Metadata]: JSON.stringify(metadata),\n                                    });\n\n                                    scorerSpan.setStatus({\n                                      code: SpanStatusCode.ERROR,\n                                      message: msg,\n                                    });\n                                    return;\n                                  }\n\n                                  const scoreDuration = Math.round(performance.now() - scorerStart);\n                                  const scoreValue = result.score as number;\n                                  const metadata = Object.assign(\n                                    { duration: scoreDuration, startedAt: scorerStart },\n                                    result.metadata,\n                                  );\n\n                                  // Collect per-trial score\n                                  (perScorerTrials[scorerName] ??= []).push(scoreValue);\n\n                                  // Get aggregation config for span attributes\n                                  const aggregation: Aggregation =\n                                    (scorer as Scorer).aggregation ?? Mean();\n\n                                  scorerSpan.setAttributes({\n                                    [Attr.Eval.Score.Name]: scorerName,\n                                    [Attr.Eval.Score.Value]: scoreValue,\n                                    [Attr.Eval.Score.Metadata]: JSON.stringify(metadata),\n                                    [Attr.Eval.Score.Aggregation]: aggregation.type,\n                                  });\n\n                                  if (metadata.error) {\n                                    const msg = errorToString(metadata.error);\n                                    scorerSpan.setStatus({\n                                      code: SpanStatusCode.ERROR,\n                                      message: msg,\n                                    });\n                                  }\n                                } finally {\n                                  scorerSpan.end();\n                                }\n                              },\n                              trialContext,\n                            );\n                          }),\n                        );\n                      } catch (error) {\n                        const taskFailureDetails = getRunTaskFailureDetails(error);\n                        const failure = toError(error);\n                        const msg = errorToString(failure);\n                        const spanErrorMessage = failure.message || msg;\n                        trialErrors[trialIndex] = msg;\n                        trialFailures.push(failure);\n\n                        trialSpan.setAttributes({\n                          [Attr.Eval.Trial.Error]: spanErrorMessage,\n                        });\n\n                        for (const scorer of opts.scorers) {\n                          const scorerName = getScorerName(scorer);\n                          (perScorerTrials[scorerName] ??= []).push(0);\n                        }\n\n                        if (taskFailureDetails) {\n                          outOfScopeFlags.push(...taskFailureDetails.outOfScopeFlags);\n                          caseFinalConfigSnapshot = {\n                            flags: taskFailureDetails.finalFlags || {},\n                            pickedFlags: opts.configFlags,\n                            overrides: taskFailureDetails.overrides,\n                          };\n                        }\n\n                        // Re-throw so startActiveSpan records the trial span as ERROR.\n                        throw failure;\n                      }\n                    },\n                    caseContext,\n                  );\n                } catch {\n                  // Continue remaining trials after task-level failures.\n                }\n              }\n\n              // Aggregate scores across trials\n              const scores: Record<string, ScoreWithName> = {};\n              for (const scorer of opts.scorers) {\n                const scorerName = getScorerName(scorer);\n                const trialsArr = perScorerTrials[scorerName] ?? [];\n                const aggregation: Aggregation = (scorer as Scorer).aggregation ?? Mean();\n\n                const aggregatedValue = trialsArr.length > 0 ? aggregation.aggregate(trialsArr) : 0;\n\n                scores[scorerName] = {\n                  name: scorerName,\n                  score: aggregatedValue,\n                  trials: trialsArr,\n                  aggregation: aggregation.type,\n                  threshold: aggregation.threshold,\n                  metadata: {},\n                };\n              }\n\n              const output = lastOutput;\n              const failedTrials = trialFailures.length;\n              const succeededTrials = trials - failedTrials;\n              const trialSummary = {\n                total: trials,\n                succeeded: succeededTrials,\n                failed: failedTrials,\n              };\n\n              caseSpan.setAttribute(Attr.Eval.Case.Scores, JSON.stringify(scores ? scores : {}));\n              if (output !== undefined) {\n                caseSpan.setAttribute(\n                  Attr.Eval.Case.Output,\n                  typeof output === 'string' ? output : JSON.stringify(output),\n                );\n              }\n\n              // set task meta for showing result in vitest report\n              task.meta.case = {\n                index: data.index,\n                name: evalName,\n                expected: data.expected,\n                input: data.input,\n                output: output,\n                metadata: data.metadata,\n                scores,\n                status: 'success',\n                errors: [],\n                trialErrors,\n                trialSummary,\n                duration: successfulTaskDuration,\n                startedAt: start,\n                outOfScopeFlags,\n                pickedFlags: opts.configFlags,\n              };\n\n              if (failedTrials > 0) {\n                const error = new Error(\n                  `Eval case ${data.index} failed with ${failedTrials} trial error(s).`,\n                );\n                intentionalTrialFailureError = error;\n                caseSpan.setStatus({\n                  code: SpanStatusCode.ERROR,\n                  message: error.message,\n                });\n                task.meta.case.status = 'fail';\n                task.meta.case.errors = trialFailures;\n                throw error;\n              }\n\n              // Collect out-of-scope flags for evaluation-level aggregation\n              allOutOfScopeFlags.push(...outOfScopeFlags);\n            } catch (e) {\n              console.log(e);\n              const error = toError(e);\n\n              if (e === intentionalTrialFailureError && task.meta.case) {\n                task.meta.case.status = 'fail';\n                task.meta.case.errors = task.meta.case.errors?.length\n                  ? task.meta.case.errors\n                  : [error];\n                allOutOfScopeFlags.push(...outOfScopeFlags);\n                throw e;\n              }\n\n              const ctx = getEvalContext();\n              const ctxOutOfScopeFlags = ctx.outOfScopeFlags || [];\n              if (ctxOutOfScopeFlags.length > 0) {\n                outOfScopeFlags.push(...ctxOutOfScopeFlags);\n              }\n\n              const ctxFlags = ctx.flags || {};\n              if (!caseFinalConfigSnapshot && Object.keys(ctxFlags).length > 0) {\n                caseFinalConfigSnapshot = {\n                  flags: ctxFlags,\n                  pickedFlags: opts.configFlags,\n                  overrides: ctx.overrides,\n                };\n              }\n\n              // Populate scores with error metadata for all scorers that didn't run\n              const failedScores: Record<string, ScoreWithName> = {};\n              for (const scorer of opts.scorers) {\n                const scorerName = getScorerName(scorer);\n                failedScores[scorerName] = {\n                  name: scorerName,\n                  score: 0,\n                  trials: [],\n                  metadata: {\n                    duration: 0,\n                    startedAt: start,\n                    error: error.message,\n                  },\n                };\n              }\n\n              task.meta.case = {\n                name: evalName,\n                index: data.index,\n                expected: data.expected,\n                input: data.input,\n                output: String(e),\n                metadata: data.metadata,\n                scores: failedScores,\n                status: 'fail',\n                errors: [error],\n                startedAt: start,\n                duration: Math.round(performance.now() - start),\n                outOfScopeFlags,\n                pickedFlags: opts.configFlags,\n              };\n\n              allOutOfScopeFlags.push(...outOfScopeFlags);\n              throw e;\n            } finally {\n              // Compute per-case runtime flags report and attach to span/meta\n              try {\n                const accessedFlags: Record<string, any> = caseFinalConfigSnapshot?.flags || {};\n\n                const accessed = Object.keys(accessedFlags);\n                const allDefaults = getConfigScope()?.getAllDefaultFlags?.() ?? {};\n\n                const runtimeFlags: Record<string, RuntimeFlagLog> = {};\n                for (const key of accessed) {\n                  const value = accessedFlags[key];\n                  if (key in allDefaults) {\n                    const replaced = !deepEqual(value, allDefaults[key]);\n                    if (replaced) {\n                      runtimeFlags[key] = { kind: 'replaced', value, default: allDefaults[key] };\n                    }\n                  } else {\n                    runtimeFlags[key] = { kind: 'introduced', value };\n                  }\n                }\n\n                if (!isDebug && Object.keys(runtimeFlags).length > 0) {\n                  const serialized = JSON.stringify(runtimeFlags);\n                  caseSpan.setAttribute('eval.case.config.runtime_flags', serialized);\n                }\n\n                if (task.meta.case) {\n                  task.meta.case.runtimeFlags = runtimeFlags;\n                }\n              } catch {}\n\n              if (caseFinalConfigSnapshot) {\n                finalConfigSnapshot = caseFinalConfigSnapshot;\n              }\n            }\n          },\n          suiteContext,\n        );\n      });\n    },\n    timeoutMs,\n  );\n\n  return result;\n}\n\nconst joinArrayOfUnknownResults = <T extends string | Record<string, any>>(results: T[]): T => {\n  if (results.length === 0) {\n    return '' as unknown as T;\n  }\n\n  // If all results are strings, concatenate them\n  if (results.every((r) => typeof r === 'string')) {\n    return results.join('') as unknown as T;\n  }\n\n  // If we have objects, return the last one (streaming typically overwrites)\n  return results[results.length - 1];\n};\n\nconst executeTask = async <\n  TInput extends string | Record<string, any>,\n  TExpected extends string | Record<string, any>,\n  TOutput extends string | Record<string, any>,\n>(\n  task: EvalTask<TInput, TExpected, TOutput>,\n  input: TInput,\n  expected: TExpected,\n): Promise<TOutput> => {\n  const taskResultOrStream = await task({ input, expected });\n\n  if (\n    typeof taskResultOrStream === 'object' &&\n    taskResultOrStream &&\n    Symbol.asyncIterator in taskResultOrStream\n  ) {\n    const chunks: TOutput[] = [];\n\n    for await (const chunk of taskResultOrStream) {\n      chunks.push(chunk);\n    }\n\n    return joinArrayOfUnknownResults<TOutput>(chunks as TOutput[]);\n  }\n\n  return taskResultOrStream;\n};\n\nconst runTask = async <\n  TInput extends string | Record<string, any>,\n  TExpected extends string | Record<string, any>,\n  TOutput extends string | Record<string, any>,\n>(\n  caseContext: Context,\n  evaluation: {\n    id: string;\n    name: string;\n    version: string;\n  },\n  opts: {\n    index: number;\n    input: TInput;\n    expected: TExpected | undefined;\n  } & Omit<EvalParams<TInput, TExpected, TOutput>, 'data'>,\n) => {\n  const taskName = opts.task.name ?? 'anonymous';\n\n  return startActiveSpan(\n    `task`,\n    {\n      attributes: {\n        [Attr.GenAI.Operation.Name]: 'eval.task',\n        [Attr.Eval.Task.Name]: taskName,\n        [Attr.Eval.Task.Type]: 'llm_completion', // TODO: How to determine task type?\n        [Attr.Eval.ID]: evaluation.id,\n        [Attr.Eval.Name]: evaluation.name,\n        [Attr.Eval.Version]: evaluation.version,\n      },\n    },\n    async (taskSpan) => {\n      // Initialize evaluation context for flag/fact access\n      const { output, duration, outOfScopeFlags, finalFlags, overrides } = await withEvalContext(\n        { pickedFlags: opts.configFlags },\n        async (): Promise<{\n          output: TOutput;\n          duration: number;\n          outOfScopeFlags: OutOfScopeFlagAccess[];\n          finalFlags: Record<string, any>;\n          overrides?: Record<string, any>;\n        }> => {\n          // TODO: EXPERIMENTS - before we were setting config scope if provided here\n          const start = performance.now();\n          try {\n            const output = await executeTask(opts.task, opts.input, opts.expected!);\n            const duration = Math.round(performance.now() - start);\n            // set task output\n            taskSpan.setAttributes({\n              [Attr.Eval.Task.Output]: typeof output === 'string' ? output : JSON.stringify(output),\n            });\n\n            // Get out-of-scope flags from the evaluation context\n            const ctx = getEvalContext();\n            const outOfScopeFlags = ctx.outOfScopeFlags || [];\n\n            return {\n              output,\n              duration,\n              outOfScopeFlags,\n              finalFlags: ctx.flags || {},\n              overrides: ctx.overrides,\n            };\n          } catch (error) {\n            const ctx = getEvalContext();\n            const duration = Math.round(performance.now() - start);\n            throw attachRunTaskFailureDetails(error, {\n              duration,\n              outOfScopeFlags: ctx.outOfScopeFlags || [],\n              finalFlags: ctx.flags || {},\n              overrides: ctx.overrides,\n            });\n          }\n        },\n      );\n\n      return {\n        output,\n        duration,\n        outOfScopeFlags,\n        finalFlags,\n        overrides,\n      };\n    },\n    caseContext,\n  );\n};\n","import { execSync } from 'node:child_process';\n\nexport function getGitUserInfo() {\n  try {\n    const name = execSync('git config --get user.name').toString().trim();\n    const email = execSync('git config --get user.email').toString().trim();\n    return { name, email };\n  } catch {\n    return null; // Git not installed or not configured\n  }\n}\n","/**\n * Aggregation functions for combining scores across multiple trials.\n *\n * Aggregators are functions that return a serializable config plus an `aggregate` function.\n * The config is stored on spans for UI display, while the function performs the actual computation.\n */\n\n/**\n * Base type for aggregation configuration.\n * Contains a `type` identifier and an `aggregate` function for computing the final score.\n */\nexport type Aggregation<T extends string = string> = {\n  type: T;\n  threshold?: number;\n  aggregate: (scores: number[]) => number;\n};\n\n/**\n * Computes the arithmetic mean of all trial scores.\n *\n * @example\n * ```typescript\n * Scorer('accuracy', fn, { aggregation: Mean() })\n * // scores [0.8, 0.6, 0.7] => 0.7\n * ```\n */\nexport const Mean = (): Aggregation<'mean'> => ({\n  type: 'mean' as const,\n  aggregate: (scores: number[]) =>\n    scores.length === 0 ? 0 : scores.reduce((a, b) => a + b, 0) / scores.length,\n});\n\n/**\n * Computes the median of all trial scores.\n *\n * @example\n * ```typescript\n * Scorer('latency', fn, { aggregation: Median() })\n * // scores [0.3, 0.9, 0.5] => 0.5\n * ```\n */\nexport const Median = (): Aggregation<'median'> => ({\n  type: 'median' as const,\n  aggregate: (scores: number[]) => {\n    if (scores.length === 0) return 0;\n    const sorted = [...scores].sort((a, b) => a - b);\n    const mid = Math.floor(sorted.length / 2);\n    return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n  },\n});\n\n/**\n * Returns 1 if at least one trial score meets or exceeds the threshold, 0 otherwise.\n * Also known as \"pass@k\" in evaluation literature.\n *\n * @param opts.threshold - The minimum score required for a trial to pass\n *\n * @example\n * ```typescript\n * Scorer('tool-called', fn, { aggregation: PassAtK({ threshold: 0.8 }) })\n * // scores [0.5, 0.9, 0.6] => 1 (0.9 >= 0.8)\n * // scores [0.5, 0.6, 0.7] => 0 (none >= 0.8)\n * ```\n */\nexport const PassAtK = (opts: { threshold?: number } = {}): Aggregation<'pass@k'> => {\n  const threshold = opts.threshold ?? 1;\n  return {\n    type: 'pass@k' as const,\n    threshold,\n    aggregate: (scores: number[]) => (scores.some((s) => s >= threshold) ? 1 : 0),\n  };\n};\n\n/**\n * Returns 1 if all trial scores meet or exceed the threshold, 0 otherwise.\n * Also known as \"pass^k\" in evaluation literature.\n *\n * @param opts.threshold - The minimum score required for all trials to pass\n *\n * @example\n * ```typescript\n * Scorer('consistency', fn, { aggregation: PassHatK({ threshold: 0.9 }) })\n * // scores [0.95, 0.92, 0.91] => 1 (all >= 0.9)\n * // scores [0.95, 0.85, 0.91] => 0 (0.85 < 0.9)\n * ```\n */\nexport const PassHatK = (opts: { threshold?: number } = {}): Aggregation<'pass^k'> => {\n  const threshold = opts.threshold ?? 1;\n  return {\n    type: 'pass^k' as const,\n    threshold,\n    aggregate: (scores: number[]) =>\n      scores.length === 0 ? 0 : scores.every((s) => s >= threshold) ? 1 : 0,\n  };\n};\n\n/**\n * User-friendly alias for PassAtK.\n * Returns 1 if at least one trial passes, 0 otherwise.\n *\n * @example\n * ```typescript\n * Scorer('tool-called', fn, { aggregation: AtLeastOneTrialPasses({ threshold: 0.8 }) })\n * ```\n */\nexport const AtLeastOneTrialPasses = PassAtK;\n\n/**\n * User-friendly alias for PassHatK.\n * Returns 1 if all trials pass, 0 otherwise.\n *\n * @example\n * ```typescript\n * Scorer('consistency', fn, { aggregation: AllTrialsPass({ threshold: 0.9 }) })\n * ```\n */\nexport const AllTrialsPass = PassHatK;\n","import type { Case, Chat, Evaluation, Task } from './eval.types';\nimport { createFetcher, type Fetcher } from '../utils/fetcher';\nimport type { ResolvedAxiomConfig } from '../config/index';\nimport { resolveAxiomConnection } from '../config/resolver';\nimport { Attr } from '../otel';\nimport { AxiomCLIError } from '../util/errors';\nimport {\n  getCustomOrRegularAttribute,\n  getCustomOrRegularNumber,\n  getCustomOrRegularString,\n} from '../util/traces';\n\nexport interface EvaluationApiConfig {\n  dataset?: string;\n  region?: string;\n  baseUrl?: string;\n  apiUrl?: string;\n  token?: string;\n}\n\nexport type EvaluationStatus = 'running' | 'completed' | 'errored' | 'cancelled';\n\nexport interface EvaluationApiPayloadBase {\n  id: string;\n  name: string;\n  capability: string;\n  step?: string | undefined;\n  dataset: string;\n  baselineId?: string;\n  totalCases?: number;\n  config?: Record<string, unknown>;\n  status: EvaluationStatus;\n  successCases?: number;\n  erroredCases?: number;\n  durationMs?: number;\n  scorerAvgs?: number[];\n  version: string;\n  runId: string;\n  configTimeoutMs: number;\n  metadata?: Record<string, any>;\n}\n\nexport class EvaluationApiClient {\n  private readonly fetcher: Fetcher;\n  constructor(config: ResolvedAxiomConfig, consoleUrl?: string) {\n    const { consoleEndpointUrl, token, orgId } = resolveAxiomConnection(config, consoleUrl);\n\n    this.fetcher = createFetcher({ baseUrl: consoleEndpointUrl, token: token ?? '', orgId });\n  }\n\n  async createEvaluation(evaluation: EvaluationApiPayloadBase) {\n    const resp = await this.fetcher(`/api/v3/evaluations`, {\n      method: 'POST',\n      body: JSON.stringify(evaluation),\n    });\n\n    if (!resp.ok) {\n      const text = await resp.text().catch(() => '');\n      throw new AxiomCLIError(\n        `Failed to create evaluation: ${resp.statusText}${text ? ` - ${text}` : ''}`,\n      );\n    }\n\n    return resp.json();\n  }\n\n  async updateEvaluation(evaluation: Partial<EvaluationApiPayloadBase>) {\n    const resp = await this.fetcher(`/api/v3/evaluations/${evaluation.id}`, {\n      method: 'PATCH',\n      body: JSON.stringify(evaluation),\n    });\n\n    if (!resp.ok) {\n      const text = await resp.text().catch(() => '');\n      throw new AxiomCLIError(\n        `Failed to update evaluation: ${resp.statusText}${text ? ` - ${text}` : ''}`,\n      );\n    }\n\n    // API may return HTTP 200 with an error in the response body\n    const body = await resp.json();\n    if (body.error) {\n      throw new AxiomCLIError(\n        `Failed to update evaluation ${evaluation.id}: ${JSON.stringify(body.error)}`,\n      );\n    }\n\n    return body;\n  }\n}\n\nexport const findEvaluationCases = async (\n  evalId: string,\n  config: ResolvedAxiomConfig,\n): Promise<Evaluation | null> => {\n  const { dataset, edgeUrl, token, orgId } = resolveAxiomConnection(config);\n\n  const apl = `['${dataset}'] | where trace_id == \"${evalId}\" | order by _time`;\n\n  const headers = new Headers({\n    Authorization: `Bearer ${token}`,\n    'Content-Type': 'application/json',\n    ...(orgId ? { 'X-AXIOM-ORG-ID': orgId } : {}),\n  });\n\n  // Use edgeUrl for query operations\n  const resp = await fetch(`${edgeUrl}/v1/datasets/_apl?format=legacy`, {\n    headers: headers,\n    method: 'POST',\n    body: JSON.stringify({ apl }),\n  });\n  const payload = await resp.json();\n\n  if (!resp.ok) {\n    throw new Error(`Failed to query evaluation cases: ${payload.message || resp.statusText}`);\n  }\n\n  return payload.matches.length ? buildSpanTree(payload.matches) : null;\n};\n\ntype DeepPartial<T> = T extends object ? { [P in keyof T]?: DeepPartial<T[P]> } : T;\n\nexport const mapSpanToEval = (span: any): Evaluation => {\n  const flagConfigRaw = getCustomOrRegularAttribute(span.data.attributes, Attr.Eval.Config.Flags);\n  const tagsRaw = getCustomOrRegularAttribute(span.data.attributes, Attr.Eval.Tags);\n\n  const evaluation: DeepPartial<Evaluation> = {\n    id: getCustomOrRegularString(span.data.attributes, Attr.Eval.ID),\n    name: getCustomOrRegularString(span.data.attributes, Attr.Eval.Name),\n    type: getCustomOrRegularString(span.data.attributes, Attr.Eval.Type),\n    version: getCustomOrRegularString(span.data.attributes, Attr.Eval.Version),\n    collection: {\n      name: getCustomOrRegularString(span.data.attributes, Attr.Eval.Collection.Name),\n      size: getCustomOrRegularNumber(span.data.attributes, Attr.Eval.Collection.Size),\n    },\n    baseline: {\n      id: getCustomOrRegularString(span.data.attributes, Attr.Eval.Baseline.ID),\n      name: getCustomOrRegularString(span.data.attributes, Attr.Eval.Baseline.Name),\n    },\n    duration: span.data.duration,\n    status: span.data.status.code,\n    traceId: span.data.trace_id,\n    runAt: span._time,\n    tags: tagsRaw ? (typeof tagsRaw === 'string' ? JSON.parse(tagsRaw) : tagsRaw) : [],\n    user: {\n      name: getCustomOrRegularString(span.data.attributes, Attr.Eval.User.Name),\n      email: getCustomOrRegularString(span.data.attributes, Attr.Eval.User.Email),\n    },\n    cases: [],\n    flagConfig: flagConfigRaw\n      ? typeof flagConfigRaw === 'string'\n        ? JSON.parse(flagConfigRaw)\n        : flagConfigRaw\n      : undefined,\n  };\n\n  // TODO: this is very optimistic!\n  return evaluation as Evaluation;\n};\n\nexport const mapSpanToCase = (item: { _time: string; data: any }): Case => {\n  const data = item.data;\n  // round duration\n  const d = data.duration as string;\n  let duration = '-';\n  if (d.endsWith('s')) {\n    duration = `${Number(d.replace('s', '')).toFixed(2)}s`;\n  } else {\n    duration = d;\n  }\n\n  const scoresRaw = getCustomOrRegularAttribute(data.attributes, Attr.Eval.Case.Scores);\n  const scoresParsed = scoresRaw\n    ? typeof scoresRaw === 'string'\n      ? JSON.parse(scoresRaw)\n      : scoresRaw\n    : {};\n\n  // Normalize scores: convert .score to .value if needed (ScoreWithName uses .score, Case uses .value)\n  // FUTURE: find a better way of handling this\n  const scores: Case['scores'] = {};\n  for (const [name, scoreData] of Object.entries(scoresParsed)) {\n    const s = scoreData as { score?: number; value?: number; metadata?: Record<string, any> };\n    scores[name] = {\n      name,\n      value: s.value ?? s.score ?? 0,\n      metadata: s.metadata ?? {},\n    };\n  }\n\n  const caseData: DeepPartial<Case> = {\n    index: getCustomOrRegularNumber(data.attributes, Attr.Eval.Case.Index),\n    input: getCustomOrRegularString(data.attributes, Attr.Eval.Case.Input),\n    output: getCustomOrRegularString(data.attributes, Attr.Eval.Case.Output),\n    expected: getCustomOrRegularString(data.attributes, Attr.Eval.Case.Expected),\n    duration: duration,\n    status: data.status.code,\n    scores,\n    runAt: item._time,\n    spanId: data.span_id,\n    traceId: data.trace_id,\n  };\n\n  // TODO: this is very optimistic!\n  return caseData as Case;\n};\n\n// compute a root eval with its children spans, results in a usable object of eval, cases, scores and chats\nexport const buildSpanTree = (spans: any[]): Evaluation | null => {\n  if (!spans.length) {\n    return null;\n  }\n\n  // Find the root eval span\n  const evalSpan = spans.find((span) => span.data.attributes.gen_ai.operation.name === 'eval');\n\n  if (!evalSpan) {\n    return null;\n  }\n\n  // Create the root eval structure\n  const rootSpan: Evaluation = mapSpanToEval(evalSpan);\n\n  // Find all case spans and build the tree structure\n  const caseSpans = spans.filter((span) => span.data.name.startsWith('case'));\n\n  for (const caseSpan of caseSpans) {\n    // Convert case data\n    const caseData = mapSpanToCase(caseSpan);\n\n    // Find task spans that belong to this case\n    const taskSpans = spans.filter(\n      (span) =>\n        span.data.name.startsWith('task') && span.data.parent_span_id === caseSpan.data.span_id,\n    );\n\n    if (taskSpans.length > 0) {\n      const taskSpan = taskSpans[0]; // Assuming one task per case\n\n      // Find chat spans that belong to this task\n      const chatSpans = spans.filter(\n        (span) =>\n          span.data.name.startsWith('chat') && span.data.parent_span_id === taskSpan.data.span_id,\n      );\n\n      const chatData: Chat[] = chatSpans.map((chatSpan) => ({\n        operation: getCustomOrRegularString(chatSpan.data.attributes, 'operation') ?? '',\n        capability: getCustomOrRegularString(chatSpan.data.attributes, 'capability') ?? '',\n        step: getCustomOrRegularString(chatSpan.data.attributes, 'step') ?? '',\n        request: {\n          max_token: getCustomOrRegularString(chatSpan.data.attributes, 'request.max_token') ?? '',\n          model: getCustomOrRegularString(chatSpan.data.attributes, 'request.model') ?? '',\n          temperature:\n            getCustomOrRegularNumber(chatSpan.data.attributes, 'request.temperature') ?? 0,\n        },\n        response: {\n          finish_reasons:\n            getCustomOrRegularString(chatSpan.data.attributes, 'response.finish_reasons') ?? '',\n        },\n        usage: {\n          input_tokens:\n            getCustomOrRegularNumber(chatSpan.data.attributes, 'usage.input_tokens') ?? 0,\n          output_tokens:\n            getCustomOrRegularNumber(chatSpan.data.attributes, 'usage.output_tokens') ?? 0,\n        },\n      }));\n\n      // Create task data with chat information\n      const taskData: Task = {\n        name: taskSpan.data.name,\n        output: getCustomOrRegularString(taskSpan.data.attributes, 'output') || '',\n        trial: getCustomOrRegularNumber(taskSpan.data.attributes, 'trial') || 0,\n        type: getCustomOrRegularString(taskSpan.data.attributes, 'type') || '',\n        error: getCustomOrRegularString(taskSpan.data.attributes, 'error') || '',\n        chat: chatData[0] || {\n          operation: '',\n          capability: '',\n          step: '',\n          request: { max_token: '', model: '', temperature: 0 },\n          response: { finish_reasons: '' },\n          usage: { input_tokens: 0, output_tokens: 0 },\n        },\n      };\n\n      caseData.task = taskData;\n    }\n\n    // Find task spans that belong to this case\n    const scoreSpans = spans.filter(\n      (span) =>\n        span.data.attributes.gen_ai.operation.name === 'eval.score' &&\n        span.data.parent_span_id === caseSpan.data.span_id,\n    );\n\n    if (scoreSpans.length > 0) {\n      caseData.scores = {};\n\n      scoreSpans.forEach((score) => {\n        const name = getCustomOrRegularString(score.data.attributes, Attr.Eval.Score.Name) ?? '';\n        const value = getCustomOrRegularNumber(score.data.attributes, Attr.Eval.Score.Value) ?? 0;\n        const metadataRaw = getCustomOrRegularString(\n          score.data.attributes,\n          Attr.Eval.Score.Metadata,\n        );\n        let metadata = {};\n        try {\n          metadata = metadataRaw ? JSON.parse(metadataRaw) : {};\n        } catch {\n          // Ignore error\n        }\n\n        caseData.scores[name] = {\n          name,\n          value,\n          metadata: {\n            error: score.data.attributes.error,\n            ...metadata,\n          },\n        };\n      });\n    }\n\n    rootSpan.cases.push(caseData);\n  }\n\n  rootSpan.cases.sort((a, b) => a.index - b.index);\n\n  return rootSpan;\n};\n","export interface Fetcher {\n  (path: string, options: RequestInit): Promise<Response>;\n}\n\nexport interface FetcherOptions {\n  baseUrl: string;\n  token: string;\n  orgId?: string;\n}\n\nexport const createFetcher = ({\n  baseUrl,\n  token,\n  orgId,\n}: {\n  baseUrl: string;\n  token: string;\n  orgId?: string;\n}): Fetcher => {\n  return (path: string, options: RequestInit) =>\n    fetch(new URL(path, baseUrl).toString(), {\n      ...options,\n      headers: {\n        ...options.headers,\n        'content-type': 'application/json',\n        authorization: `Bearer ${token}`,\n        ...(orgId ? { 'X-AXIOM-ORG-ID': orgId } : {}),\n      },\n    });\n};\n","export function getCustomOrRegularAttribute(obj: unknown, accessKey: string): unknown {\n  if (typeof obj !== 'object' || obj === null) {\n    return undefined;\n  }\n\n  const keyParts = accessKey.split('.');\n  const custom = (obj as Record<string, any>).custom;\n\n  // Try `obj.custom['foo.bar']`\n  if (custom && typeof custom === 'object' && custom !== null && accessKey in custom) {\n    return custom[accessKey];\n  }\n\n  // Try `obj.foo.bar`\n  let current: any = obj;\n  for (const part of keyParts) {\n    if (typeof current !== 'object' || current === null) {\n      return undefined;\n    }\n    current = current[part];\n  }\n\n  return current;\n}\n\nexport function getCustomOrRegularString(obj: unknown, key: string): string | undefined {\n  const value = getCustomOrRegularAttribute(obj, key);\n\n  return typeof value === 'string' ? value : undefined;\n}\n\nexport function getCustomOrRegularNumber(obj: unknown, key: string): number | undefined {\n  const value = getCustomOrRegularAttribute(obj, key);\n\n  if (typeof value === 'number') {\n    return value;\n  }\n\n  if (typeof value === 'string') {\n    const parsed = Number(value);\n\n    return Number.isNaN(parsed) ? undefined : parsed;\n  }\n\n  return undefined;\n}\n","/**\n * Copied from Remeda - https://github.com/remeda/remeda/blob/v2.32.0/packages/remeda/src/isDeepEqual.ts\n */\n\nexport function deepEqual<T>(data: unknown, other: T): data is T {\n  if (data === other) {\n    return true;\n  }\n\n  if (Object.is(data, other)) {\n    // We want to ignore the slight differences between `===` and `Object.is` as\n    // both of them largely define equality from a semantic point-of-view.\n    return true;\n  }\n\n  if (typeof data !== 'object' || typeof other !== 'object') {\n    return false;\n  }\n\n  if (data === null || other === null) {\n    return false;\n  }\n\n  if (Object.getPrototypeOf(data) !== Object.getPrototypeOf(other)) {\n    // If the objects don't share a prototype it's unlikely that they are\n    // semantically equal. It is technically possible to build 2 prototypes that\n    // act the same but are not equal (at the reference level, checked via\n    // `===`) and then create 2 objects that are equal although we would fail on\n    // them. Because this is so unlikely, the optimization we gain here for the\n    // rest of the function by assuming that `other` is of the same type as\n    // `data` is more than worth it.\n    return false;\n  }\n\n  if (Array.isArray(data)) {\n    return isDeepEqualArrays(data, other as unknown as ReadonlyArray<unknown>);\n  }\n\n  if (data instanceof Map) {\n    return isDeepEqualMaps(data, other as unknown as Map<unknown, unknown>);\n  }\n\n  if (data instanceof Set) {\n    return isDeepEqualSets(data, other as unknown as Set<unknown>);\n  }\n\n  if (data instanceof Date) {\n    return data.getTime() === (other as unknown as Date).getTime();\n  }\n\n  if (data instanceof RegExp) {\n    return data.toString() === (other as unknown as RegExp).toString();\n  }\n\n  // At this point we only know that the 2 objects share a prototype and are not\n  // any of the previous types. They could be plain objects (Object.prototype),\n  // they could be classes, they could be other built-ins, or they could be\n  // something weird. We assume that comparing values by keys is enough to judge\n  // their equality.\n\n  if (Object.keys(data).length !== Object.keys(other).length) {\n    return false;\n  }\n\n  for (const [key, value] of Object.entries(data)) {\n    if (!(key in other)) {\n      return false;\n    }\n\n    if (\n      !deepEqual(\n        value,\n        // @ts-expect-error [ts7053] - We already checked that `other` has `key`\n        other[key],\n      )\n    ) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction isDeepEqualArrays(data: ReadonlyArray<unknown>, other: ReadonlyArray<unknown>): boolean {\n  if (data.length !== other.length) {\n    return false;\n  }\n\n  for (const [index, item] of data.entries()) {\n    if (!deepEqual(item, other[index])) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction isDeepEqualMaps(\n  data: ReadonlyMap<unknown, unknown>,\n  other: ReadonlyMap<unknown, unknown>,\n): boolean {\n  if (data.size !== other.size) {\n    return false;\n  }\n\n  for (const [key, value] of data.entries()) {\n    if (!other.has(key)) {\n      return false;\n    }\n\n    if (!deepEqual(value, other.get(key))) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction isDeepEqualSets(data: ReadonlySet<unknown>, other: ReadonlySet<unknown>): boolean {\n  if (data.size !== other.size) {\n    return false;\n  }\n\n  // To ensure we only count each item once we need to \"remember\" which items of\n  // the other set we've already matched against. We do this by creating a copy\n  // of the other set and removing items from it as we find them in the data\n  // set.\n  const otherCopy = [...other];\n\n  for (const dataItem of data) {\n    let isFound = false;\n\n    for (const [index, otherItem] of otherCopy.entries()) {\n      if (deepEqual(dataItem, otherItem)) {\n        isFound = true;\n        otherCopy.splice(index, 1);\n        break;\n      }\n    }\n\n    if (!isFound) {\n      return false;\n    }\n  }\n\n  return true;\n}\n","import { errorToString } from './errors';\n\nexport type TryCatchResult<T, E extends Error = Error> =\n  | [data: T, error: null]\n  | [data: null, error: E | Error];\n\nexport function toError(rawError: unknown, operationName?: string): Error {\n  const processedError = rawError instanceof Error ? rawError : new Error(errorToString(rawError));\n\n  if (operationName) {\n    processedError.message = `Operation \"${operationName}\" failed: ${processedError.message}`;\n  }\n\n  return processedError;\n}\n\nexport function tryCatchSync<T, E extends Error = Error>(\n  fn: () => T,\n  operationName?: string,\n): TryCatchResult<T, E> {\n  try {\n    return [fn(), null];\n  } catch (rawError) {\n    return [null, toError(rawError, operationName)];\n  }\n}\n\nexport async function tryCatchAsync<T, E extends Error = Error>(\n  fn: Promise<T> | (() => T | Promise<T>),\n  operationName?: string,\n): Promise<TryCatchResult<Awaited<T>, E>> {\n  try {\n    const result = typeof fn === 'function' ? fn() : fn;\n    return [await result, null];\n  } catch (rawError) {\n    return [null, toError(rawError, operationName)];\n  }\n}\n\ntype TryCatch = {\n  <T, E extends Error = Error>(\n    fn: Promise<T> | (() => T | Promise<T>),\n    operationName?: string,\n  ): Promise<TryCatchResult<Awaited<T>, E>>;\n  <T, E extends Error = Error>(fn: () => T, operationName?: string): TryCatchResult<T, E>;\n  sync: typeof tryCatchSync;\n  async: typeof tryCatchAsync;\n};\n\nexport const tryCatch = ((fn: unknown, operationName?: string) => {\n  if (typeof fn === 'function') {\n    try {\n      const result = (fn as () => unknown)();\n      if (result instanceof Promise) {\n        return tryCatchAsync(result, operationName);\n      }\n      return [result, null];\n    } catch (rawError) {\n      return [null, toError(rawError, operationName)];\n    }\n  }\n\n  if (fn instanceof Promise) {\n    return tryCatchAsync(fn, operationName);\n  }\n\n  return [fn, null];\n}) as TryCatch;\n\ntryCatch.sync = tryCatchSync;\ntryCatch.async = tryCatchAsync;\n","import { AxiomCLIError } from '../util/errors';\nimport { appendFileSync } from 'node:fs';\nimport { isValidName } from '../util/name-validation-runtime';\n\n/**\n * Records an eval, scorer, capability, or step name\n * Uses a file to work cross-worker\n */\nexport function recordName(kind: 'eval' | 'scorer' | 'capability' | 'step', name: string): void {\n  const registryFile = process.env.AXIOM_NAME_REGISTRY_FILE;\n  if (registryFile) {\n    try {\n      appendFileSync(registryFile, JSON.stringify({ kind, name }) + '\\n', 'utf8');\n    } catch {\n      // Silently fail if we can't write to registry file\n    }\n  }\n}\n\n/**\n * Validates that a name contains only allowed characters (A-Z, a-z, 0-9, -, _)\n * and is not empty. Throws AxiomCLIError if validation fails.\n */\nexport function validateName(name: string, kind: 'eval' | 'scorer' | 'capability' | 'step'): void {\n  const validation = isValidName(name);\n  if (!validation.valid) {\n    throw new AxiomCLIError(`❌ ${kind} name: ${validation.error}`);\n  }\n}\n","import type { Aggregation } from './aggregations';\n\nexport type Score<TMetadata extends Record<string, any> = Record<string, any>> = {\n  score: number | boolean | null;\n  metadata?: TMetadata;\n};\n\n// Internal type used when scorer returns Score with name\nexport type ScoreWithName<TMetadata extends Record<string, any> = Record<string, any>> =\n  Score<TMetadata> & {\n    name: string;\n    /** Per-trial scores when running multiple trials */\n    trials?: number[];\n    /** Aggregation type used (e.g., 'mean', 'pass@k') */\n    aggregation?: string;\n    /** Threshold for pass-based aggregations */\n    threshold?: number;\n  };\n\n/**\n * Configuration options for a scorer.\n */\nexport type ScorerOptions = {\n  /**\n   * Aggregation function for combining scores across multiple trials.\n   * Defaults to Mean() if not specified.\n   */\n  aggregation?: Aggregation;\n};\n\n// Loose type - this is what we REQUIRE\n// (we accept scorers with looser requirements than how we define them)\nexport type ScorerLike<\n  TInput = any,\n  TExpected = any,\n  TOutput = any,\n  TExtra extends Record<string, any> = {},\n  TMetadata extends Record<string, any> = Record<string, any>,\n  TReturn extends Score<TMetadata> | Promise<Score<TMetadata>> =\n    | Score<TMetadata>\n    | Promise<Score<TMetadata>>,\n> = (\n  args: {\n    input?: TInput;\n    expected?: TExpected;\n    output: TOutput;\n    /** Current trial index (0-based) when running multiple trials */\n    trialIndex?: number;\n  } & TExtra,\n) => TReturn;\n\n// Strict type - this is how we DEFINE scorers\nexport type Scorer<\n  TInput = any,\n  TExpected = any,\n  TOutput = any,\n  TExtra extends Record<string, any> = {},\n  TMetadata extends Record<string, any> = Record<string, any>,\n  TReturn extends Score<TMetadata> | Promise<Score<TMetadata>> =\n    | Score<TMetadata>\n    | Promise<Score<TMetadata>>,\n> = ScorerLike<TInput, TExpected, TOutput, TExtra, TMetadata, TReturn> & {\n  readonly name: string; // Name property for telemetry\n  readonly aggregation?: Aggregation; // Aggregation config for trials\n};\n","import type { ValidateName } from '../util/name-validation';\nimport { normalizeBooleanScore } from './normalize-score';\nimport type { Score, Scorer, ScorerOptions } from './scorer.types';\n\n// Helper to force TypeScript to evaluate/simplify types\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\ntype ScorerReturnValue = number | boolean | Score;\ntype AwaitedValue<T> = T extends Promise<infer U> ? U : T;\ntype InferScorerMetadata<T> =\n  AwaitedValue<T> extends Score<infer TMetadata> ? TMetadata : Record<string, any>;\ntype NormalizeScorerReturn<T, TMetadata extends Record<string, any>> =\n  T extends Promise<any> ? Promise<Score<TMetadata>> : Score<TMetadata>;\n\n/**\n * Creates a scorer to be used in evals.\n *\n * Scorers need to return a number or a boolean. If returning a number, it is\n * suggested that this number is between 0 and 1.\n *\n * @example\n * const scorer = createScorer('exact-match',\n *   (args: { output: string; expected: string; }) => {\n *     return args.output === args.expected ? true : false;\n *   }\n * );\n *\n * @example\n * // With aggregation for trials\n * import { PassAtK } from '@axiomhq/ai/evals/aggregations';\n * const scorer = createScorer('tool-called',\n *   (args: { output: string }) => args.output.includes('tool') ? 1 : 0,\n *   { aggregation: PassAtK({ threshold: 0.8 }) }\n * );\n */\nexport function createScorer<\n  TArgs extends Record<string, any> = {},\n  // Use tuple wrapping to prevent distributive conditional types\n  TInput = [TArgs] extends [{ input: infer I }] ? I : unknown,\n  TExpected = [TArgs] extends [{ expected: infer E }] ? Exclude<E, undefined> : unknown,\n  TOutput = [TArgs] extends [{ output: infer O }] ? Exclude<O, undefined> : never,\n  TExtra extends Record<string, any> = Simplify<\n    Omit<TArgs, 'input' | 'expected' | 'output' | 'trialIndex'>\n  >,\n  TReturn extends ScorerReturnValue | Promise<ScorerReturnValue> =\n    | ScorerReturnValue\n    | Promise<ScorerReturnValue>,\n  TName extends string = string,\n>(\n  /**\n   * The name of the scorer\n   */\n  name: ValidateName<TName>,\n  /**\n   * The scorer function. Can be sync or async.\n   */\n  fn: (args: TArgs) => TReturn,\n  /**\n   * Optional configuration for the scorer, including aggregation for trials.\n   */\n  options?: ScorerOptions,\n): [TOutput] extends [never]\n  ? never\n  : Scorer<\n      TInput,\n      TExpected,\n      TOutput,\n      TExtra,\n      InferScorerMetadata<TReturn>,\n      NormalizeScorerReturn<TReturn, InferScorerMetadata<TReturn>>\n    > {\n  const normalizeScore = (res: ScorerReturnValue): Score => {\n    if (typeof res === 'number') {\n      return { score: res };\n    }\n    if (typeof res === 'boolean') {\n      return normalizeBooleanScore(res);\n    }\n    return normalizeBooleanScore(res.score, res.metadata);\n  };\n\n  const scorer: any = (args: TArgs) => {\n    const res = fn(args);\n\n    // If user returned a Promise, handle async\n    if (res instanceof Promise) {\n      return res.then(normalizeScore);\n    }\n\n    // Otherwise handle sync\n    return normalizeScore(res);\n  };\n\n  // Attach name property to function for pre-execution access\n  Object.defineProperty(scorer, 'name', {\n    value: name,\n    configurable: true,\n    enumerable: true,\n  });\n\n  // Attach aggregation config if provided\n  if (options?.aggregation) {\n    Object.defineProperty(scorer, 'aggregation', {\n      value: options.aggregation,\n      configurable: true,\n      enumerable: true,\n    });\n  }\n\n  return scorer as [TOutput] extends [never]\n    ? never\n    : Scorer<\n        TInput,\n        TExpected,\n        TOutput,\n        TExtra,\n        InferScorerMetadata<TReturn>,\n        NormalizeScorerReturn<TReturn, InferScorerMetadata<TReturn>>\n      >;\n}\n","import { Attr } from '../otel/semconv/attributes';\nimport type { Score } from './scorer.types';\n\n/**\n * Normalizes a boolean score to numeric (1/0) and adds eval.score.is_boolean\n * to metadata. Numbers and null pass through unchanged.\n */\nexport function normalizeBooleanScore(\n  score: Score['score'],\n  metadata?: Record<string, unknown>,\n): { score: number | null; metadata?: Record<string, unknown> } {\n  if (typeof score !== 'boolean') {\n    return { score, metadata };\n  }\n  return {\n    score: score ? 1 : 0,\n    metadata: { ...metadata, [Attr.Eval.Score.IsBoolean]: true },\n  };\n}\n","let scorerWarned = false;\n\nexport function warnScorerDeprecation(path: string): void {\n  if (scorerWarned) return;\n  scorerWarned = true;\n  console.warn(\n    `[axiom] Importing Scorer from '${path}' is deprecated. ` +\n      `Use \"import { Scorer } from 'axiom/ai/evals/scorers'\" instead.`,\n  );\n}\n\nlet onlineEvalWarned = false;\n\nexport function warnOnlineEvalDeprecation(): void {\n  if (onlineEvalWarned) return;\n  onlineEvalWarned = true;\n  console.warn(\n    `[axiom] Importing onlineEval from 'axiom/ai' is deprecated. ` +\n      `Use \"import { onlineEval } from 'axiom/ai/evals/online'\" instead.`,\n  );\n}\n"],"mappings":"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","names":["import_zod","import_zod","import_zod","import_api","import_api","import_api","import_api","import_api","import_api","import_api","import_zod","import_api","authContext","import_zod","init_config","c12LoadConfig","init_config","import_api","context","r","s","u","s","f","calculateBaselineScorerAverage","s","import_zod","import_node_fs","import_nanoid","import_node_fs","cases","import_api","a","consoleUrl","s","a","consoleUrl","result","output","metadata","r","duration","outOfScopeFlags"]}