axiom
Version:
Axiom AI SDK provides - an API to wrap your AI calls with observability instrumentation. - offline evals
3,269 lines • 103 kB
JavaScript
import {
isValidName
} from "./chunk-X2LH7XLM.js";
import {
__publicField,
init_esm_shims
} from "./chunk-4VNFFUM5.js";
// src/otel/utils/redaction.ts
init_esm_shims();
import { context, propagation } from "@opentelemetry/api";
// src/otel/withSpanBaggageKey.ts
init_esm_shims();
var WITHSPAN_BAGGAGE_KEY = "__withspan_gen_ai_call";
var WITHSPAN_REDACTION_POLICY_KEY = "__withspan_redaction_policy";
// src/otel/utils/redaction.ts
var RedactionPolicy = {
/**
* Includes message content on chat spans, and mirrors tool
* payload on tool spans for more convenient querying.
*/
AxiomDefault: {
captureMessageContent: "full",
mirrorToolPayloadOnToolSpan: true
},
/**
* Redacts message content on chat spans, and does not put
* tool payload on tool spans.
*/
OpenTelemetryDefault: {
captureMessageContent: "off",
mirrorToolPayloadOnToolSpan: false
}
};
var AXIOM_AI_REDACTION_KEY = Symbol.for("__axiom_ai_redaction__");
function getGlobalRedactionPolicy() {
return globalThis[AXIOM_AI_REDACTION_KEY];
}
function getEffectiveRedactionPolicy(globalPolicy, localPolicy) {
return {
captureMessageContent: localPolicy?.captureMessageContent ?? globalPolicy?.captureMessageContent ?? RedactionPolicy.AxiomDefault.captureMessageContent,
mirrorToolPayloadOnToolSpan: localPolicy?.mirrorToolPayloadOnToolSpan ?? globalPolicy?.mirrorToolPayloadOnToolSpan ?? RedactionPolicy.AxiomDefault.mirrorToolPayloadOnToolSpan
};
}
function getRedactionPolicy() {
return getEffectiveRedactionPolicy(getGlobalRedactionPolicy(), getPerCallRedactionPolicy());
}
function handleMaybeRedactedAttribute(span, attribute, value, captureMessageContent) {
if (captureMessageContent === "full") {
span.setAttribute(attribute, value);
}
}
function getPerCallRedactionPolicy() {
const baggage = propagation.getBaggage(context.active()) || propagation.createBaggage();
const serializedPolicy = baggage.getEntry(WITHSPAN_REDACTION_POLICY_KEY)?.value;
if (!serializedPolicy) {
return void 0;
}
try {
return JSON.parse(serializedPolicy);
} catch (error) {
console.warn("[AxiomAI] Failed to parse redaction policy from baggage:", error);
return void 0;
}
}
// src/otel/initAxiomAI.ts
init_esm_shims();
import { trace } from "@opentelemetry/api";
// package.json
var package_default = {
name: "axiom",
version: "0.37.0",
type: "module",
author: "Axiom, Inc.",
contributors: [
"Islam Shehata <islam@axiom.co>",
"Chris Ehrlich <chris@axiom.co>",
"Gabriel de Andrade <gabriel@axiom.co>"
],
scripts: {
dev: "tsup --watch",
build: "tsup && chmod +x dist/bin.js",
format: "prettier --write .",
"format:check": "prettier --check .",
lint: "eslint './**/*.{js,ts}'",
typecheck: "tsc --noEmit",
test: "vitest run",
"test:watch": "vitest --watch",
publint: "npx publint"
},
types: "./dist/index.d.ts",
main: "./dist/index.cjs",
module: "./dist/index.js",
bin: {
axiom: "./dist/bin.js"
},
exports: {
"./ai": {
import: {
types: "./dist/index.d.ts",
default: "./dist/index.js"
},
require: {
types: "./dist/index.d.cts",
default: "./dist/index.cjs"
}
},
"./ai/evals": {
import: {
types: "./dist/evals.d.ts",
default: "./dist/evals.js"
},
require: {
types: "./dist/evals.d.cts",
default: "./dist/evals.cjs"
}
},
"./ai/config": {
import: {
types: "./dist/config.d.ts",
default: "./dist/config.js"
},
require: {
types: "./dist/config.d.cts",
default: "./dist/config.cjs"
}
},
"./ai/feedback": {
import: {
types: "./dist/feedback.d.ts",
default: "./dist/feedback.js"
},
require: {
types: "./dist/feedback.d.cts",
default: "./dist/feedback.cjs"
}
}
},
keywords: [
"axiom",
"logging",
"ai",
"otel",
"opentelemetry"
],
repository: {
type: "git",
url: "git+https://github.com/axiomhq/ai.git",
directory: "packages/ai"
},
license: "MIT",
dependencies: {
"@next/env": "^15.4.2",
"@opentelemetry/auto-instrumentations-node": "^0.60.1",
"@opentelemetry/context-async-hooks": "^2.0.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.202.0",
"@opentelemetry/resources": "^2.0.1",
"@opentelemetry/sdk-trace-node": "^2.0.1",
"@opentelemetry/semantic-conventions": "^1.37.0",
"@sinclair/typebox": "^0.34.37",
c12: "^2.0.4",
commander: "^14.0.0",
defu: "^6.1.4",
handlebars: "^4.7.8",
nanoid: "^5.1.5",
open: "^10.1.0",
"vite-tsconfig-paths": "^5.1.4",
vitest: "^4.0.0"
},
peerDependencies: {
"@opentelemetry/api": "^1.9.0",
zod: "^3.25.0 || ^4.0.0"
},
devDependencies: {
"@ai-sdk/anthropicv1": "npm:@ai-sdk/anthropic@^1.2.12",
"@ai-sdk/anthropicv2": "npm:@ai-sdk/anthropic@^2.0.44",
"@ai-sdk/openaiv1": "npm:@ai-sdk/openai@^1.3.24",
"@ai-sdk/openaiv2": "npm:@ai-sdk/openai@^2.0.67",
"@ai-sdk/providerv1": "npm:@ai-sdk/provider@^1.1.3",
"@ai-sdk/providerv2": "npm:@ai-sdk/provider@^2.0.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.0.1",
"@opentelemetry/sdk-trace-base": "^2.0.1",
"@opentelemetry/sdk-trace-node": "^2.0.1",
"@repo/eslint-config": "workspace:*",
"@types/node": "^22.15.29",
"@vitest/coverage-v8": "^4.0.0",
aiv4: "npm:ai@^4.3.19",
aiv5: "npm:ai@^5.0.93",
esbuild: "^0.25.8",
eslint: "catalog:",
msw: "^2.12.2",
prettier: "catalog:",
tinyrainbow: "^2.0.0",
tsup: "catalog:",
typescript: "catalog:",
vitest: "catalog:",
zod: "catalog:"
},
files: [
"dist"
],
packageManager: "pnpm@10.16.1"
};
// src/otel/initAxiomAI.ts
var AXIOM_AI_SCOPE_KEY = Symbol.for("__axiom_ai_scope__");
function extractTracerScope(tracer) {
const tracerAny = tracer;
const name = tracerAny._instrumentationScope?.name || tracerAny.instrumentationLibrary?.name || package_default.name;
const version = tracerAny._instrumentationScope?.version || tracerAny.instrumentationLibrary?.version || package_default.version;
return { name, version };
}
function initAxiomAI(config) {
const newScope = extractTracerScope(config.tracer);
const existingScope = globalThis[AXIOM_AI_SCOPE_KEY];
if (existingScope && existingScope.name === newScope.name && existingScope.version === newScope.version) {
return;
}
if (existingScope) {
console.warn(
`[AxiomAI] initAxiomAI() called multiple times with different scopes. Previous: ${existingScope.name}@${existingScope.version}, New: ${newScope.name}@${newScope.version}`
);
}
globalThis[AXIOM_AI_SCOPE_KEY] = newScope;
if (config.redactionPolicy) {
globalThis[AXIOM_AI_REDACTION_KEY] = config.redactionPolicy;
}
}
function getGlobalTracer() {
const scope = globalThis[AXIOM_AI_SCOPE_KEY];
if (!scope) {
const isDebug = process.env.AXIOM_DEBUG === "true";
if (!isDebug) {
console.warn(
"[AxiomAI] AXIOM_AI_SCOPE_KEY is undefined. This probably means that initAxiomAI() was never called. Make sure to call initAxiomAI({ tracer }) in your instrumentation setup."
);
}
}
let { name, version } = scope || { name: package_default.name, version: package_default.version };
if (!name || !version) {
name = package_default.name;
version = package_default.version;
if (!name || !version) {
name = "axiom";
version = "unknown";
}
}
return trace.getTracer(name, version);
}
function resetAxiomAI() {
globalThis[AXIOM_AI_SCOPE_KEY] = void 0;
globalThis[AXIOM_AI_REDACTION_KEY] = void 0;
}
// src/otel/withSpan.ts
init_esm_shims();
import {
context as context3,
propagation as propagation3,
trace as trace3,
SpanStatusCode as SpanStatusCode3
} from "@opentelemetry/api";
// src/otel/utils/wrapperUtils.ts
init_esm_shims();
import {
trace as trace2,
context as context2,
propagation as propagation2,
SpanStatusCode as SpanStatusCode2
} from "@opentelemetry/api";
// src/otel/semconv/attributes.ts
init_esm_shims();
import {
ATTR_ERROR_TYPE,
ATTR_HTTP_RESPONSE_STATUS_CODE
} from "@opentelemetry/semantic-conventions";
// src/otel/semconv/eval_proposal.ts
init_esm_shims();
var ATTR_EVAL_ID = "eval.id";
var ATTR_EVAL_NAME = "eval.name";
var ATTR_EVAL_VERSION = "eval.version";
var ATTR_EVAL_TYPE = "eval.type";
var ATTR_EVAL_TAGS = "eval.tags";
var ATTR_EVAL_BASELINE_ID = "eval.baseline.id";
var ATTR_EVAL_BASELINE_NAME = "eval.baseline.name";
var ATTR_EVAL_BASELINE_VERSION = "eval.baseline.version";
var ATTR_EVAL_METADATA = "eval.metadata";
var ATTR_EVAL_CAPABILITY_NAME = "eval.capability.name";
var ATTR_EVAL_STEP_NAME = "eval.step.name";
var ATTR_EVAL_COLLECTION_ID = "eval.collection.id";
var ATTR_EVAL_COLLECTION_SIZE = "eval.collection.size";
var ATTR_EVAL_COLLECTION_NAME = "eval.collection.name";
var ATTR_EVAL_CONFIG_FLAGS = "eval.config.flags";
var ATTR_EVAL_CASE_INDEX = "eval.case.index";
var ATTR_EVAL_CASE_INPUT = "eval.case.input";
var ATTR_EVAL_CASE_OUTPUT = "eval.case.output";
var ATTR_EVAL_CASE_EXPECTED = "eval.case.expected";
var ATTR_EVAL_CASE_SCORES = "eval.case.scores";
var ATTR_EVAL_CASE_METADATA = "eval.case.metadata";
var ATTR_EVAL_TASK_OUTPUT = "eval.task.output";
var ATTR_EVAL_TASK_NAME = "eval.task.name";
var ATTR_EVAL_TASK_TYPE = "eval.task.type";
var ATTR_EVAL_RUN_ID = "eval.run.id";
var ATTR_EVAL_SCORE_NAME = "eval.score.name";
var ATTR_EVAL_SCORE_VALUE = "eval.score.value";
var ATTR_EVAL_SCORE_THRESHOLD = "eval.score.threshold";
var ATTR_EVAL_SCORE_PASSED = "eval.score.passed";
var ATTR_EVAL_SCORE_IS_BOOLEAN = "eval.score.is_boolean";
var ATTR_EVAL_SCORE_METADATA = "eval.score.metadata";
var ATTR_EVAL_USER_NAME = "eval.user.name";
var ATTR_EVAL_USER_EMAIL = "eval.user.email";
// src/otel/semconv/attributes.ts
import {
ATTR_ERROR_MESSAGE,
ATTR_GEN_AI_AGENT_DESCRIPTION,
ATTR_GEN_AI_AGENT_ID,
ATTR_GEN_AI_AGENT_NAME,
ATTR_GEN_AI_CONVERSATION_ID,
ATTR_GEN_AI_INPUT_MESSAGES,
ATTR_GEN_AI_OPERATION_NAME,
ATTR_GEN_AI_OUTPUT_MESSAGES,
ATTR_GEN_AI_OUTPUT_TYPE,
ATTR_GEN_AI_PROVIDER_NAME,
ATTR_GEN_AI_REQUEST_CHOICE_COUNT,
ATTR_GEN_AI_REQUEST_ENCODING_FORMATS,
ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY,
ATTR_GEN_AI_REQUEST_MAX_TOKENS,
ATTR_GEN_AI_REQUEST_MODEL,
ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY,
ATTR_GEN_AI_REQUEST_SEED,
ATTR_GEN_AI_REQUEST_STOP_SEQUENCES,
ATTR_GEN_AI_REQUEST_TEMPERATURE,
ATTR_GEN_AI_REQUEST_TOP_K,
ATTR_GEN_AI_REQUEST_TOP_P,
ATTR_GEN_AI_RESPONSE_FINISH_REASONS,
ATTR_GEN_AI_RESPONSE_ID,
ATTR_GEN_AI_RESPONSE_MODEL,
ATTR_GEN_AI_TOOL_CALL_ID,
ATTR_GEN_AI_TOOL_DESCRIPTION,
ATTR_GEN_AI_TOOL_NAME,
ATTR_GEN_AI_TOOL_TYPE,
ATTR_GEN_AI_USAGE_INPUT_TOKENS,
ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,
GEN_AI_OPERATION_NAME_VALUE_CHAT,
GEN_AI_OPERATION_NAME_VALUE_CREATE_AGENT,
GEN_AI_OPERATION_NAME_VALUE_EMBEDDINGS,
GEN_AI_OPERATION_NAME_VALUE_EXECUTE_TOOL,
GEN_AI_OPERATION_NAME_VALUE_GENERATE_CONTENT,
GEN_AI_OPERATION_NAME_VALUE_INVOKE_AGENT,
GEN_AI_OUTPUT_TYPE_VALUE_IMAGE,
GEN_AI_OUTPUT_TYPE_VALUE_JSON,
GEN_AI_OUTPUT_TYPE_VALUE_SPEECH,
GEN_AI_OUTPUT_TYPE_VALUE_TEXT,
GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,
GEN_AI_PROVIDER_NAME_VALUE_AWS_BEDROCK,
GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_INFERENCE,
GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_OPENAI,
GEN_AI_PROVIDER_NAME_VALUE_COHERE,
GEN_AI_PROVIDER_NAME_VALUE_DEEPSEEK,
GEN_AI_PROVIDER_NAME_VALUE_GCP_GEMINI,
GEN_AI_PROVIDER_NAME_VALUE_GCP_GEN_AI,
GEN_AI_PROVIDER_NAME_VALUE_GCP_VERTEX_AI,
GEN_AI_PROVIDER_NAME_VALUE_GROQ,
GEN_AI_PROVIDER_NAME_VALUE_IBM_WATSONX_AI,
GEN_AI_PROVIDER_NAME_VALUE_MISTRAL_AI,
GEN_AI_PROVIDER_NAME_VALUE_OPENAI,
GEN_AI_PROVIDER_NAME_VALUE_PERPLEXITY,
GEN_AI_PROVIDER_NAME_VALUE_X_AI
} from "@opentelemetry/semantic-conventions/incubating";
var ATTR_AXIOM_GEN_AI_SCHEMA_URL = "axiom.gen_ai.schema_url";
var ATTR_AXIOM_GEN_AI_SDK_NAME = "axiom.gen_ai.sdk.name";
var ATTR_AXIOM_GEN_AI_SDK_VERSION = "axiom.gen_ai.sdk.version";
var ATTR_GEN_AI_CAPABILITY_NAME = "gen_ai.capability.name";
var ATTR_GEN_AI_STEP_NAME = "gen_ai.step.name";
var ATTR_GEN_AI_TOOL_ARGUMENTS = "gen_ai.tool.arguments";
var ATTR_GEN_AI_TOOL_MESSAGE = "gen_ai.tool.message";
var GEN_AI_PROVIDER_NAME_VALUE_ASSEMBLYAI = "assemblyai";
var GEN_AI_PROVIDER_NAME_VALUE_CEREBRAS = "cerebras";
var GEN_AI_PROVIDER_NAME_VALUE_DEEPGRAM = "deepgram";
var GEN_AI_PROVIDER_NAME_VALUE_DEEPINFRA = "deepinfra";
var GEN_AI_PROVIDER_NAME_VALUE_ELEVENLABS = "elevenlabs";
var GEN_AI_PROVIDER_NAME_VALUE_FAL = "fal";
var GEN_AI_PROVIDER_NAME_VALUE_FIREWORKS = "fireworks";
var GEN_AI_PROVIDER_NAME_VALUE_GLADIA = "gladia";
var GEN_AI_PROVIDER_NAME_VALUE_HUME = "hume";
var GEN_AI_PROVIDER_NAME_VALUE_LMNT = "lmnt";
var GEN_AI_PROVIDER_NAME_VALUE_LUMA = "luma";
var GEN_AI_PROVIDER_NAME_VALUE_REPLICATE = "replicate";
var GEN_AI_PROVIDER_NAME_VALUE_REVAI = "revai";
var GEN_AI_PROVIDER_NAME_VALUE_TOGETHERAI = "togetherai";
var GEN_AI_PROVIDER_NAME_VALUE_VERCEL = "vercel";
var Attr = {
__EXPERIMENTAL_Flag: (flagName) => `flag.${flagName}`,
__EXPERIMENTAL_Fact: (factName) => `fact.${factName}`,
Axiom: {
GenAI: {
SchemaURL: ATTR_AXIOM_GEN_AI_SCHEMA_URL,
SDK: {
Name: ATTR_AXIOM_GEN_AI_SDK_NAME,
Version: ATTR_AXIOM_GEN_AI_SDK_VERSION
}
}
},
GenAI: {
PromptMetadata: {
ID: "axiom.gen_ai.prompt.id",
Name: "axiom.gen_ai.prompt.name",
Slug: "axiom.gen_ai.prompt.slug",
Version: "axiom.gen_ai.prompt.version"
},
/**
* These two are used to identify the span
*/
Capability: {
Name: ATTR_GEN_AI_CAPABILITY_NAME
},
Step: {
Name: ATTR_GEN_AI_STEP_NAME
},
Provider: {
Name: ATTR_GEN_AI_PROVIDER_NAME,
Name_Values: {
Anthropic: GEN_AI_PROVIDER_NAME_VALUE_ANTHROPIC,
AssemblyAI: GEN_AI_PROVIDER_NAME_VALUE_ASSEMBLYAI,
AWSBedrock: GEN_AI_PROVIDER_NAME_VALUE_AWS_BEDROCK,
AzureAIInference: GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_INFERENCE,
AzureAIOpenAI: GEN_AI_PROVIDER_NAME_VALUE_AZURE_AI_OPENAI,
Cerebras: GEN_AI_PROVIDER_NAME_VALUE_CEREBRAS,
Cohere: GEN_AI_PROVIDER_NAME_VALUE_COHERE,
Deepgram: GEN_AI_PROVIDER_NAME_VALUE_DEEPGRAM,
DeepInfra: GEN_AI_PROVIDER_NAME_VALUE_DEEPINFRA,
Deepseek: GEN_AI_PROVIDER_NAME_VALUE_DEEPSEEK,
ElevenLabs: GEN_AI_PROVIDER_NAME_VALUE_ELEVENLABS,
Fal: GEN_AI_PROVIDER_NAME_VALUE_FAL,
Fireworks: GEN_AI_PROVIDER_NAME_VALUE_FIREWORKS,
GCPGemini: GEN_AI_PROVIDER_NAME_VALUE_GCP_GEMINI,
GCPGenAI: GEN_AI_PROVIDER_NAME_VALUE_GCP_GEN_AI,
GCPVertexAI: GEN_AI_PROVIDER_NAME_VALUE_GCP_VERTEX_AI,
Gladia: GEN_AI_PROVIDER_NAME_VALUE_GLADIA,
Groq: GEN_AI_PROVIDER_NAME_VALUE_GROQ,
Hume: GEN_AI_PROVIDER_NAME_VALUE_HUME,
IBMWatsonxAI: GEN_AI_PROVIDER_NAME_VALUE_IBM_WATSONX_AI,
Lmnt: GEN_AI_PROVIDER_NAME_VALUE_LMNT,
Luma: GEN_AI_PROVIDER_NAME_VALUE_LUMA,
MistralAI: GEN_AI_PROVIDER_NAME_VALUE_MISTRAL_AI,
OpenAI: GEN_AI_PROVIDER_NAME_VALUE_OPENAI,
Perplexity: GEN_AI_PROVIDER_NAME_VALUE_PERPLEXITY,
Replicate: GEN_AI_PROVIDER_NAME_VALUE_REPLICATE,
RevAI: GEN_AI_PROVIDER_NAME_VALUE_REVAI,
TogetherAI: GEN_AI_PROVIDER_NAME_VALUE_TOGETHERAI,
Vercel: GEN_AI_PROVIDER_NAME_VALUE_VERCEL,
XAI: GEN_AI_PROVIDER_NAME_VALUE_X_AI
}
},
/**
* Regular attributes
*/
Agent: {
Description: ATTR_GEN_AI_AGENT_DESCRIPTION,
// not yet used by axiom-ai
ID: ATTR_GEN_AI_AGENT_ID,
// not yet used by axiom-ai
Name: ATTR_GEN_AI_AGENT_NAME
// not yet used by axiom-ai
},
Conversation: {
ID: ATTR_GEN_AI_CONVERSATION_ID
// not yet used by axiom-ai, anyway probably needs to be provided by user
},
Input: {
Messages: ATTR_GEN_AI_INPUT_MESSAGES
},
Operation: {
Name: ATTR_GEN_AI_OPERATION_NAME,
Name_Values: {
/**
* Note that "text_completion" is deprecated in favor of "chat" for both OpenAI and Anthropic
*/
Chat: GEN_AI_OPERATION_NAME_VALUE_CHAT,
CreateAgent: GEN_AI_OPERATION_NAME_VALUE_CREATE_AGENT,
Embeddings: GEN_AI_OPERATION_NAME_VALUE_EMBEDDINGS,
ExecuteTool: GEN_AI_OPERATION_NAME_VALUE_EXECUTE_TOOL,
GenerateContent: GEN_AI_OPERATION_NAME_VALUE_GENERATE_CONTENT,
InvokeAgent: GEN_AI_OPERATION_NAME_VALUE_INVOKE_AGENT
}
},
Output: {
Messages: ATTR_GEN_AI_OUTPUT_MESSAGES,
Type: ATTR_GEN_AI_OUTPUT_TYPE,
Type_Values: {
Text: GEN_AI_OUTPUT_TYPE_VALUE_TEXT,
Json: GEN_AI_OUTPUT_TYPE_VALUE_JSON,
Image: GEN_AI_OUTPUT_TYPE_VALUE_IMAGE,
Speech: GEN_AI_OUTPUT_TYPE_VALUE_SPEECH
}
},
/**
* The provider that is hosting the model, eg AWS Bedrock
* There doesn't seem to be a semconv for this
*/
Request: {
ChoiceCount: ATTR_GEN_AI_REQUEST_CHOICE_COUNT,
// not yet used by axiom-ai
EncodingFormats: ATTR_GEN_AI_REQUEST_ENCODING_FORMATS,
// not yet used by axiom-ai
FrequencyPenalty: ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY,
MaxTokens: ATTR_GEN_AI_REQUEST_MAX_TOKENS,
/**
* The model you asked for
*/
Model: ATTR_GEN_AI_REQUEST_MODEL,
PresencePenalty: ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY,
Seed: ATTR_GEN_AI_REQUEST_SEED,
StopSequences: ATTR_GEN_AI_REQUEST_STOP_SEQUENCES,
Temperature: ATTR_GEN_AI_REQUEST_TEMPERATURE,
TopK: ATTR_GEN_AI_REQUEST_TOP_K,
TopP: ATTR_GEN_AI_REQUEST_TOP_P
},
Response: {
FinishReasons: ATTR_GEN_AI_RESPONSE_FINISH_REASONS,
ID: ATTR_GEN_AI_RESPONSE_ID,
/**
* The model that was actually used (might be different bc routing) - only ever get this from the response, otherwise omit
*/
Model: ATTR_GEN_AI_RESPONSE_MODEL
// somehow not landing on the span for google models? check up on this...
},
Tool: {
CallID: ATTR_GEN_AI_TOOL_CALL_ID,
Description: ATTR_GEN_AI_TOOL_DESCRIPTION,
Name: ATTR_GEN_AI_TOOL_NAME,
Type: ATTR_GEN_AI_TOOL_TYPE,
/**
* Note, OTel Semantic Convention suggest only putting tool inputs/outputs on the parent chat span
* But we at least want to give users THE OPTION to put them on the tool spans themselves as well
* Because it enables a lot of things with querying
* @see https://github.com/open-telemetry/semantic-conventions/releases/tag/v1.37.0
*/
Arguments: ATTR_GEN_AI_TOOL_ARGUMENTS,
/**
* Note, OTel Semantic Convention suggest only putting tool inputs/outputs on the parent chat span
* But we at least want to give users THE OPTION to put them on the tool spans themselves as well
* Because it enables a lot of things with querying
* @see https://github.com/open-telemetry/semantic-conventions/releases/tag/v1.37.0
*/
Message: ATTR_GEN_AI_TOOL_MESSAGE
},
Usage: {
InputTokens: ATTR_GEN_AI_USAGE_INPUT_TOKENS,
OutputTokens: ATTR_GEN_AI_USAGE_OUTPUT_TOKENS
}
},
Eval: {
ID: ATTR_EVAL_ID,
Name: ATTR_EVAL_NAME,
Version: ATTR_EVAL_VERSION,
Type: ATTR_EVAL_TYPE,
Baseline: {
ID: ATTR_EVAL_BASELINE_ID,
Name: ATTR_EVAL_BASELINE_NAME,
Version: ATTR_EVAL_BASELINE_VERSION
},
Capability: {
Name: ATTR_EVAL_CAPABILITY_NAME
},
Step: {
Name: ATTR_EVAL_STEP_NAME
},
Tags: ATTR_EVAL_TAGS,
Metadata: ATTR_EVAL_METADATA,
Collection: {
ID: ATTR_EVAL_COLLECTION_ID,
Name: ATTR_EVAL_COLLECTION_NAME,
Size: ATTR_EVAL_COLLECTION_SIZE
},
Config: {
Flags: ATTR_EVAL_CONFIG_FLAGS
},
Run: {
ID: ATTR_EVAL_RUN_ID
},
Case: {
Index: ATTR_EVAL_CASE_INDEX,
Input: ATTR_EVAL_CASE_INPUT,
Output: ATTR_EVAL_CASE_OUTPUT,
Expected: ATTR_EVAL_CASE_EXPECTED,
Scores: ATTR_EVAL_CASE_SCORES,
Metadata: ATTR_EVAL_CASE_METADATA
},
Task: {
Output: ATTR_EVAL_TASK_OUTPUT,
Name: ATTR_EVAL_TASK_NAME,
Type: ATTR_EVAL_TASK_TYPE
},
Score: {
Name: ATTR_EVAL_SCORE_NAME,
Value: ATTR_EVAL_SCORE_VALUE,
Threshold: ATTR_EVAL_SCORE_THRESHOLD,
Passed: ATTR_EVAL_SCORE_PASSED,
IsBoolean: ATTR_EVAL_SCORE_IS_BOOLEAN,
Metadata: ATTR_EVAL_SCORE_METADATA
},
User: {
Name: ATTR_EVAL_USER_NAME,
Email: ATTR_EVAL_USER_EMAIL
}
},
Error: {
Type: ATTR_ERROR_TYPE,
Message: ATTR_ERROR_MESSAGE
},
HTTP: {
Response: {
StatusCode: ATTR_HTTP_RESPONSE_STATUS_CODE
}
}
};
// src/schema.ts
init_esm_shims();
var SCHEMA_VERSION = "0.0.2";
var SCHEMA_BASE_URL = "https://axiom.co/ai/schemas/";
var SCHEMA_URL = `${SCHEMA_BASE_URL}${SCHEMA_VERSION}`;
// src/otel/startActiveSpan.ts
init_esm_shims();
import { SpanStatusCode } from "@opentelemetry/api";
var createStartActiveSpan = (tracer) => async (name, options, fn, callbacks) => {
return tracer.startActiveSpan(name, { ...options ?? {} }, async (span) => {
try {
const result = await fn(span);
callbacks?.onSuccess?.(span);
return result;
} catch (error) {
callbacks?.onError?.(error, span);
if (error instanceof Error) {
span.recordException(error);
span.setStatus({
code: SpanStatusCode.ERROR,
message: error.message
});
}
throw error;
} finally {
callbacks?.onFinally?.(span);
if (!callbacks?.manualEnd) {
span.end();
}
}
});
};
// src/otel/utils/wrapperUtils.ts
function ensureNumber(value) {
const v = typeof value === "number" ? value : typeof value === "string" ? Number(value) : void 0;
if (Number.isNaN(v)) return void 0;
if (v === Infinity || v === -Infinity) return void 0;
return v;
}
function classifyError(err) {
if (err == null) return void 0;
if (err instanceof Error) {
const name = err.name.toLowerCase();
if (name.includes("timeout")) return "timeout";
if (name.includes("abort")) return "timeout";
if (name.includes("network") || name.includes("fetch")) return "network";
if (name.includes("validation")) return "validation";
if (name.includes("auth")) return "authentication";
if (name.includes("parse") || name.includes("json")) return "parsing";
if (name.includes("permission") || name.includes("forbidden")) return "authorization";
if (name.includes("rate") && name.includes("limit")) return "rate_limit";
if (name.includes("quota") || name.includes("limit")) return "quota_exceeded";
return void 0;
}
return void 0;
}
function classifyToolError(err, span) {
if (err instanceof Error) {
span.recordException(err);
} else {
span.recordException({
message: String(err),
name: "UnknownError"
});
}
span.setStatus({
code: SpanStatusCode2.ERROR,
message: err instanceof Error ? err.message : String(err)
});
let errorType = "unknown";
let statusCode;
if (err && typeof err === "object") {
const errObj = err;
const name = errObj.name?.toLowerCase() || "";
const message = errObj.message?.toLowerCase() || "";
if (name.includes("timeout") || name.includes("abort") || message.includes("timeout")) {
errorType = "timeout";
} else if (name.includes("validation") || errObj.code === "VALIDATION_ERROR" || message.includes("validation")) {
errorType = "validation";
} else if (name.includes("fetch") || name.includes("network") || message.includes("network") || message.includes("fetch failed")) {
errorType = "network";
statusCode = errObj.status || errObj.code;
} else if (name.includes("auth") || message.includes("auth") || message.includes("unauthorized")) {
errorType = "authentication";
} else if (name.includes("permission") || name.includes("forbidden") || message.includes("forbidden")) {
errorType = "authorization";
} else if (name.includes("rate") && (name.includes("limit") || message.includes("rate limit"))) {
errorType = "rate_limit";
} else if (name.includes("quota") || message.includes("quota") || message.includes("limit exceeded")) {
errorType = "quota_exceeded";
} else if (name.includes("parse") || name.includes("json") || message.includes("json") || message.includes("parse")) {
errorType = "parsing";
}
}
span.setAttribute(Attr.Error.Type, errorType);
if (err instanceof Error && err.message) {
span.setAttribute(Attr.Error.Message, err.message);
}
if (statusCode !== void 0) {
span.setAttribute(Attr.HTTP.Response.StatusCode, statusCode);
}
}
function isNoOpTracerProvider() {
const provider = trace2.getTracerProvider();
if (provider.constructor.name === "NoopTracerProvider") {
return true;
}
if (typeof provider.getTracer !== "function") {
return true;
}
return false;
}
function getTracer() {
const tracer = getGlobalTracer();
if (isNoOpTracerProvider()) {
const isDebug = process.env.AXIOM_DEBUG === "true";
if (!isDebug) {
console.warn(
"[AxiomAI] No TracerProvider registered - spans will be no-op. Make sure to call initAxiomAI() after your OpenTelemetry SDK has started (sdk.start())."
);
}
}
return tracer;
}
function createGenAISpanName(operation, suffix) {
return suffix ? `${operation} ${suffix}` : operation;
}
function setScopeAttributes(span) {
const bag = propagation2.getActiveBaggage();
if (bag) {
const capability = bag.getEntry("capability")?.value;
if (capability) {
span.setAttribute(Attr.GenAI.Capability.Name, capability);
}
const step = bag.getEntry("step")?.value;
if (step) {
span.setAttribute(Attr.GenAI.Step.Name, step);
}
}
}
function setAxiomBaseAttributes(span) {
span.setAttributes({
[Attr.Axiom.GenAI.SchemaURL]: SCHEMA_URL,
[Attr.Axiom.GenAI.SDK.Name]: package_default.name,
[Attr.Axiom.GenAI.SDK.Version]: package_default.version
});
}
function setBaseAttributes(span, provider, modelId) {
span.setAttributes({
[Attr.GenAI.Operation.Name]: Attr.GenAI.Operation.Name_Values.Chat,
[Attr.GenAI.Request.Model]: modelId
});
const systemValue = mapVercelSDKProviderToOTelProvider(provider);
if (systemValue) {
span.setAttribute(Attr.GenAI.Provider.Name, systemValue);
}
setAxiomBaseAttributes(span);
}
function setRequestParameterAttributes(span, params) {
const {
maxTokens,
frequencyPenalty,
presencePenalty,
temperature,
topP,
topK,
seed,
stopSequences
} = params;
if (maxTokens !== void 0) {
span.setAttribute(Attr.GenAI.Request.MaxTokens, maxTokens);
}
if (frequencyPenalty !== void 0) {
span.setAttribute(Attr.GenAI.Request.FrequencyPenalty, frequencyPenalty);
}
if (presencePenalty !== void 0) {
span.setAttribute(Attr.GenAI.Request.PresencePenalty, presencePenalty);
}
if (temperature !== void 0) {
span.setAttribute(Attr.GenAI.Request.Temperature, temperature);
}
if (topP !== void 0) {
span.setAttribute(Attr.GenAI.Request.TopP, topP);
}
if (topK !== void 0) {
span.setAttribute(Attr.GenAI.Request.TopK, topK);
}
if (seed !== void 0) {
span.setAttribute(Attr.GenAI.Request.Seed, seed);
}
if (stopSequences && stopSequences.length > 0) {
span.setAttribute(Attr.GenAI.Request.StopSequences, JSON.stringify(stopSequences));
}
}
function createStreamChildSpan(parentSpan, operationName) {
const tracer = getTracer();
const ctx = context2.active();
const spanContext = trace2.setSpan(ctx, parentSpan);
const childSpan = tracer.startSpan(operationName, void 0, spanContext);
return childSpan;
}
function recordSpanError(span, err) {
if (err instanceof Error) {
span.recordException(err);
} else {
span.recordException({
message: String(err),
name: "UnknownError"
});
}
span.setStatus({
code: SpanStatusCode2.ERROR,
message: err instanceof Error ? err.message : String(err)
});
const errorType = classifyError(err);
span.setAttribute(Attr.Error.Type, errorType ?? "unknown");
if (err instanceof Error && err.message) {
span.setAttribute(Attr.Error.Message, err.message);
}
if (err && typeof err === "object" && "status" in err) {
span.setAttribute(Attr.HTTP.Response.StatusCode, err.status);
}
}
async function withSpanHandling(modelId, operation, options) {
const bag = propagation2.getActiveBaggage();
const isWithinWithSpan = bag?.getEntry(WITHSPAN_BAGGAGE_KEY)?.value === "true";
const spanContext = options?.version === "v2" ? { version: "v2", originalPrompt: [], originalV2Prompt: void 0 } : { version: "v1", originalPrompt: [], rawCall: void 0 };
const name = createGenAISpanName(Attr.GenAI.Operation.Name_Values.Chat, modelId);
if (isWithinWithSpan) {
const activeSpan = trace2.getActiveSpan();
if (!activeSpan) {
throw new Error("Expected active span when within withSpan");
}
activeSpan.updateName(name);
const lease = {
owned: false,
end: () => {
}
// No-op: we don't own this span
};
try {
return await operation(activeSpan, spanContext, lease);
} catch (err) {
recordSpanError(activeSpan, err);
throw err;
}
} else {
const tracer = getTracer();
const startActiveSpan = createStartActiveSpan(tracer);
return startActiveSpan(
name,
null,
async (span) => {
const lease = {
owned: true,
end: () => span.end()
};
return await operation(span, spanContext, lease);
},
{
manualEnd: options?.streaming ?? false,
onError: (err, span) => {
const errorType = classifyError(err);
span.setAttribute(Attr.Error.Type, errorType ?? "unknown");
if (err instanceof Error && err.message) {
span.setAttribute(Attr.Error.Message, err.message);
}
if (err && typeof err === "object" && "status" in err) {
span.setAttribute(Attr.HTTP.Response.StatusCode, err.status);
}
}
}
);
}
}
function determineOutputTypeV1(options) {
if (options.responseFormat?.type) {
switch (options.responseFormat.type) {
case "json":
return Attr.GenAI.Output.Type_Values.Json;
case "text":
return Attr.GenAI.Output.Type_Values.Text;
}
}
if (options.mode?.type === "object-json" || options.mode?.type === "object-tool") {
return Attr.GenAI.Output.Type_Values.Json;
}
if (options.mode?.type === "regular") {
return Attr.GenAI.Output.Type_Values.Text;
}
return void 0;
}
function determineOutputTypeV2(options) {
if (options.responseFormat?.type) {
switch (options.responseFormat.type) {
case "json":
return Attr.GenAI.Output.Type_Values.Json;
case "text":
return Attr.GenAI.Output.Type_Values.Text;
}
}
return void 0;
}
function mapVercelSDKProviderToOTelProvider(vercelSDKProvider) {
if (vercelSDKProvider === "openai-compatible") {
return void 0;
}
switch (vercelSDKProvider) {
case "amazon-bedrock":
return Attr.GenAI.Provider.Name_Values.AWSBedrock;
case "anthropic":
case "anthropic.messages":
return Attr.GenAI.Provider.Name_Values.Anthropic;
case "assemblyai":
case "assemblyai.transcription":
return Attr.GenAI.Provider.Name_Values.AssemblyAI;
case "deepgram":
case "deepgram.transcription":
return Attr.GenAI.Provider.Name_Values.Deepgram;
case "gateway":
return Attr.GenAI.Provider.Name_Values.Vercel;
case "gladia":
case "gladia.transcription":
return Attr.GenAI.Provider.Name_Values.Gladia;
case "google":
case "google.generative-ai":
return Attr.GenAI.Provider.Name_Values.GCPGemini;
case "groq":
return Attr.GenAI.Provider.Name_Values.Groq;
case "mistral":
return Attr.GenAI.Provider.Name_Values.MistralAI;
case "openai":
return Attr.GenAI.Provider.Name_Values.OpenAI;
case "perplexity":
return Attr.GenAI.Provider.Name_Values.Perplexity;
case "replicate":
return Attr.GenAI.Provider.Name_Values.Replicate;
case "revai":
case "revai.transcription":
return Attr.GenAI.Provider.Name_Values.RevAI;
case "togetherai":
return Attr.GenAI.Provider.Name_Values.TogetherAI;
case "xai":
return Attr.GenAI.Provider.Name_Values.XAI;
// startswith + fall through
default: {
if (vercelSDKProvider.startsWith("azure.")) {
return Attr.GenAI.Provider.Name_Values.AzureAIOpenAI;
}
if (vercelSDKProvider.startsWith("cerebras.")) {
return Attr.GenAI.Provider.Name_Values.Cerebras;
}
if (vercelSDKProvider.startsWith("cohere.")) {
return Attr.GenAI.Provider.Name_Values.Cohere;
}
if (vercelSDKProvider.startsWith("deepinfra.")) {
return Attr.GenAI.Provider.Name_Values.DeepInfra;
}
if (vercelSDKProvider.startsWith("deepseek.")) {
return Attr.GenAI.Provider.Name_Values.Deepseek;
}
if (vercelSDKProvider.startsWith("elevenlabs.")) {
return Attr.GenAI.Provider.Name_Values.ElevenLabs;
}
if (vercelSDKProvider.startsWith("fal.")) {
return Attr.GenAI.Provider.Name_Values.Fal;
}
if (vercelSDKProvider.startsWith("fireworks.")) {
return Attr.GenAI.Provider.Name_Values.Fireworks;
}
if (vercelSDKProvider.startsWith("google.vertex.")) {
return Attr.GenAI.Provider.Name_Values.GCPVertexAI;
}
if (vercelSDKProvider.startsWith("groq.")) {
return Attr.GenAI.Provider.Name_Values.Groq;
}
if (vercelSDKProvider.startsWith("hume.")) {
return Attr.GenAI.Provider.Name_Values.Hume;
}
if (vercelSDKProvider.startsWith("lmnt.")) {
return Attr.GenAI.Provider.Name_Values.Lmnt;
}
if (vercelSDKProvider.startsWith("luma.")) {
return Attr.GenAI.Provider.Name_Values.Luma;
}
if (vercelSDKProvider.startsWith("mistral.")) {
return Attr.GenAI.Provider.Name_Values.MistralAI;
}
if (vercelSDKProvider.startsWith("openai.")) {
return Attr.GenAI.Provider.Name_Values.OpenAI;
}
if (vercelSDKProvider.startsWith("vercel.")) {
return Attr.GenAI.Provider.Name_Values.Vercel;
}
if (vercelSDKProvider.startsWith("vertex.anthropic.")) {
return Attr.GenAI.Provider.Name_Values.GCPVertexAI;
}
if (vercelSDKProvider.startsWith("xai.")) {
return Attr.GenAI.Provider.Name_Values.XAI;
}
const s = vercelSDKProvider.split(".");
if (s.length === 2) {
return s[0];
}
return void 0;
}
}
}
// src/otel/withSpan.ts
function withSpan(meta, fn, opts) {
const tracer = opts?.tracer ?? getTracer();
const span = tracer.startSpan("chat");
const spanContext = trace3.setSpan(context3.active(), span);
return context3.with(spanContext, async () => {
const capabilityValidation = isValidName(meta.capability);
if (!capabilityValidation.valid) {
console.warn(`[AxiomAI] Invalid capability name: ${capabilityValidation.error}. `);
}
const stepValidation = isValidName(meta.step);
if (!stepValidation.valid) {
console.warn(`[AxiomAI] Invalid step name: ${stepValidation.error}. `);
}
if (!span.isRecording()) {
const provider = trace3.getTracerProvider();
const providerIsNoOp = provider.constructor.name === "NoopTracerProvider";
if (providerIsNoOp) {
const isDebug = process.env.AXIOM_DEBUG === "true";
if (!isDebug) {
console.warn(
"[AxiomAI] No TracerProvider registered - spans are no-op. Make sure to call initAxiomAI() after your OpenTelemetry SDK has started."
);
}
}
}
const bag = propagation3.createBaggage({
capability: { value: meta.capability },
step: { value: meta.step },
// TODO: maybe we can just check the active span name instead?
[WITHSPAN_BAGGAGE_KEY]: { value: "true" },
// Mark that we're inside withSpan
// Store serialized redaction policy if provided
...opts?.redactionPolicy && {
[WITHSPAN_REDACTION_POLICY_KEY]: { value: JSON.stringify(opts.redactionPolicy) }
}
});
const ctx = propagation3.setBaggage(context3.active(), bag);
let spanEnded = false;
const safeEndSpan = () => {
if (!spanEnded) {
spanEnded = true;
span.end();
}
};
const timeoutMs = opts?.timeoutMs ?? 6e5;
const timeoutId = setTimeout(() => {
safeEndSpan();
}, timeoutMs);
try {
const result = await context3.with(ctx, () => fn(span));
if (result instanceof Response && result.body) {
if (result.body.locked) {
console.warn("[AxiomAI] Response body is already locked, cannot instrument stream");
clearTimeout(timeoutId);
safeEndSpan();
return result;
}
const originalReader = result.body.getReader();
const wrappedStream = new ReadableStream({
async pull(controller) {
try {
const { value, done } = await context3.with(ctx, () => originalReader.read());
if (done) {
originalReader.releaseLock?.();
clearTimeout(timeoutId);
span.setStatus({ code: SpanStatusCode3.OK });
safeEndSpan();
controller.close();
} else {
controller.enqueue(value);
}
} catch (err) {
originalReader.releaseLock?.();
clearTimeout(timeoutId);
span.recordException(err);
span.setStatus({
code: SpanStatusCode3.ERROR,
message: err instanceof Error ? err.message : String(err)
});
safeEndSpan();
controller.error(err);
}
},
async cancel(reason) {
try {
originalReader.releaseLock?.();
clearTimeout(timeoutId);
if (reason instanceof Error) {
span.recordException(reason);
} else if (reason) {
span.recordException({ message: String(reason), name: "CancelError" });
}
span.setStatus({
code: SpanStatusCode3.ERROR,
message: reason instanceof Error ? reason.message : String(reason)
});
safeEndSpan();
await originalReader.cancel(reason);
} catch (_err) {
}
}
});
return new Response(wrappedStream, {
status: result.status,
statusText: result.statusText,
headers: result.headers
});
}
if (result && typeof result === "object" && "textStream" in result) {
console.warn(
"[AxiomAI] Detected streaming object with textStream. For proper span lifecycle, call .toUIMessageStreamResponse() or similar inside withSpan, not after."
);
clearTimeout(timeoutId);
safeEndSpan();
return result;
}
clearTimeout(timeoutId);
span.setStatus({ code: SpanStatusCode3.OK });
safeEndSpan();
return result;
} catch (err) {
clearTimeout(timeoutId);
span.recordException(err);
span.setStatus({
code: SpanStatusCode3.ERROR,
message: err instanceof Error ? err.message : String(err)
});
safeEndSpan();
throw err;
}
});
}
// src/otel/middleware.ts
init_esm_shims();
import "@opentelemetry/api";
// src/otel/completionUtils.ts
init_esm_shims();
// src/otel/utils/contentSanitizer.ts
init_esm_shims();
import { createHash } from "crypto";
function extractImageMetadata(url) {
if (url.startsWith("data:")) {
const [header, base64Data] = url.split(",");
const formatMatch = header.match(/data:image\/(\w+)/);
const format = formatMatch?.[1];
const sizeBytes = base64Data ? Math.floor(base64Data.length * 3 / 4) : 0;
const hash = base64Data ? createHash("sha256").update(base64Data).digest("hex").slice(0, 16) : "unknown";
return {
format,
size_bytes: sizeBytes,
hash,
is_data_url: true
};
} else {
const hash = createHash("sha256").update(url).digest("hex").slice(0, 16);
return {
hash,
is_data_url: false
};
}
}
function sanitizeImageUrl(url, detail) {
const metadata = extractImageMetadata(url);
if (metadata.is_data_url) {
const formatPart = metadata.format ? `:${metadata.format}` : "";
const sizePart = metadata.size_bytes ? `:${metadata.size_bytes}b` : "";
return {
url: `[IMAGE${formatPart}${sizePart}:${metadata.hash}]`,
detail,
...metadata
};
} else {
return {
url,
detail,
...metadata
};
}
}
function sanitizeMultimodalContent(content) {
if (Array.isArray(content)) {
return content.map((part) => {
if (part && typeof part === "object" && "type" in part && part.type === "image_url") {
const imagePart = part;
if (imagePart.image_url?.url) {
return {
...part,
image_url: sanitizeImageUrl(imagePart.image_url.url, imagePart.image_url.detail)
};
}
}
return part;
});
}
return content;
}
// src/otel/completionUtils.ts
function createSimpleCompletion({ text }) {
const assistantMessage = {
role: "assistant",
content: text ?? ""
};
return [assistantMessage];
}
// src/util/promptUtils.ts
init_esm_shims();
function appendToolCalls(prompt, toolCalls, toolResults, assistantContent) {
const updatedPrompt = [...prompt];
updatedPrompt.push({
role: "assistant",
content: assistantContent || null,
tool_calls: toolCalls.map((toolCall) => ({
id: toolCall.toolCallId,
function: {
name: toolCall.toolName,
arguments: typeof toolCall.args === "string" ? toolCall.args : JSON.stringify(toolCall.args)
},
type: "function"
}))
});
for (const toolCall of toolCalls) {
const realToolResult = toolResults.get(toolCall.toolName);
if (realToolResult) {
updatedPrompt.push({
role: "tool",
tool_call_id: toolCall.toolCallId,
content: JSON.stringify(realToolResult)
});
}
}
return updatedPrompt;
}
function extractToolResultsFromRawPrompt(rawPrompt) {
const toolResultsMap = /* @__PURE__ */ new Map();
if (!Array.isArray(rawPrompt)) {
return toolResultsMap;
}
for (const message of rawPrompt) {
if (message?.role === "user" && Array.isArray(message.parts)) {
for (const part of message.parts) {
if (part?.functionResponse) {
const functionResponse = part.functionResponse;
if (functionResponse.name && functionResponse.response) {
toolResultsMap.set(
functionResponse.name,
functionResponse.response.content || functionResponse.response
);
}
}
}
}
if (message?.role === "tool" && message?.tool_call_id && message?.content) {
}
}
return toolResultsMap;
}
function extractToolResultsFromPromptV2(prompt) {
const idToName = /* @__PURE__ */ new Map();
const results = /* @__PURE__ */ new Map();
for (const message of prompt) {
if (message.role === "assistant" && Array.isArray(message.content)) {
for (const part of message.content) {
if (part.type === "tool-call") {
idToName.set(part.toolCallId, part.toolName);
}
}
}
}
for (const message of prompt) {
if (message.role === "tool" && Array.isArray(message.content)) {
for (const part of message.content) {
if (part.toolCallId && part.output !== void 0) {
const toolName = idToName.get(part.toolCallId);
if (toolName) {
results.set(toolName, part.output);
}
}
}
}
}
return results;
}
// src/otel/utils/normalized.ts
init_esm_shims();
function normalizeV1ToolCall(toolCall) {
return {
toolCallId: toolCall.toolCallId,
toolName: toolCall.toolName,
args: typeof toolCall.args === "string" ? toolCall.args : JSON.stringify(toolCall.args),
toolCallType: "function"
};
}
function normalizeV2ToolCall(toolCall) {
return {
toolCallId: toolCall.toolCallId,
toolName: toolCall.toolName,
args: typeof toolCall.input === "string" ? toolCall.input.replace(/:\s+/g, ":") : JSON.stringify(toolCall.input),
toolCallType: "function"
};
}
function normalizeV1ToolCalls(toolCalls) {
return toolCalls.map(normalizeV1ToolCall);
}
function normalizeV2ToolCalls(toolCalls) {
return toolCalls.map(normalizeV2ToolCall);
}
function promptV1ToOpenAI(prompt) {
const results = [];
for (const message of prompt) {
switch (message.role) {
case "system":
results.push({
role: "system",
content: message.content
});
break;
case "assistant":
const textPart = message.content.find((part) => part.type === "text");
const toolCallParts = message.content.filter(
(part) => part.type === "tool-call"
);
results.push({
role: "assistant",
content: textPart?.text || null,
...toolCallParts.length > 0 ? {
tool_calls: toolCallParts.map((part) => ({
id: part.toolCallId,
function: {
name: part.toolName,
arguments: JSON.stringify(part.args)
},
type: "function"
}))
} : {}
});
break;
case "user":
results.push({
role: "user",
content: message.content.map((part) => {
switch (part.type) {
case "text":
return {
type: "text",
text: part.text
};
case "image":
return {
type: "image_url",
image_url: {
url: part.image.toString()
}
};
default:
return {
type: "text",
text: `[${part.type}]` + (typeof part === "object" && part !== null ? JSON.stringify(part) : String(part))
};
}
})
});
break;
case "tool":
for (const part of message.content) {
results.push({
role: "tool",
tool_call_id: part.toolCallId,
content: JSON.stringify(part.result)
});
}
break;
}
}
return results;
}
function promptV2ToOpenAI(prompt) {
const results = [];
for (const message of prompt) {
switch (message.role) {
case "system":
results.push({
role: "system",
content: message.content
});
break;
case "assistant":
const textContent = message.content.find(
(part) => part.type === "text"
);
const toolCalls = message.content.filter(
(part) => part.type === "tool-call"
);
results.push({
role: "assistant",
content: textContent?.text || null,
...toolCalls.length > 0 ? {
tool_calls: toolCalls.map((part) => ({
id: part.toolCallId,
function: {
name: part.toolName,
arguments: typeof part.input === "string" ? part.input : JSON.stringify(part.input)
},
type: "function"
}))
} : {}
});
break;
case "user":
results.push({
role: "user",
content: message.content.map((part) => {
switch (part.type) {
case "text":
return {
type: "text",
text: part.text
};
case "image":
return {
type: "image_url",
image_url: {
url: part.image.toString()
}
};
default:
return part;
}
})
});
break;
case "tool":
for (const part of message.content) {
results.push({
role: "tool",
tool_call_id: part.toolCallId,
content: formatV2ToolCallOutput(part.output)
});
}
break;
}
}
return results;
}
function formatV2ToolCallOutput(output) {
switch (output.type) {
case "text":
return output.value;
case "json":
return typeof output.value === "string" ? output.value : JSON.stringify(output.value);
case "error-text":
return output.value;
case "error-json":
return typeof output.value === "string" ? output.value : JSON.stringify(output.value);
case "content":
return JSON.stringify(output.value);
}
}
// src/otel/streaming/aggregators.ts
init_esm_shims();
// src/util/currentUnixTime.ts
init_esm_shims();
function currentUnixTime() {
return Date.now() / 1e3;
}
// src/otel/streaming/aggregators.ts
var ToolCallAggregator = class {
constructor() {
__publicField(this, "calls", {});
}
handleChunk(chunk) {
switch (chunk.type) {
case "tool-call":
this.calls[chunk.toolCallId] = {
toolCallType: chunk.toolCallType,
toolCallId: chunk.toolCallId,
toolName: chunk.toolName,
args: chunk.args
};
break;
case "tool-call-delta":
if (!this.calls[chunk.toolCallId]) {
this.calls[chunk.toolCallId] = {
toolCallType: chunk.toolCallType,
toolCallId: chunk.toolCallId,
toolName: chunk.toolName,
args: ""
};
}
this.calls[chunk.toolCallId].args += chunk.argsTextDelta;
break;
}
}
get result() {
return Object.values(this.calls);
}
};
var TextAggregator = class {
constructor() {
__publicField(this, "content", "");
}
feed(chunk) {
if (chunk.type === "text-delta") {
this.content += chunk.textDelta;
}
}
get text() {
return this.content || void 0;
}
};
var StreamStats = class {
constructor() {
__publicField(this, "startTime");
__publicField(this, "timeToFirstToken");
__publicField(this, "_usage");
__publicField(this, "_finishReason");
__publicField(this, "_responseId");
__publicField(this, "_responseModelId");
this.startTime = currentUnixTime();
}
feed(chunk) {
if (this.timeToFirstToken === void 0) {
this.timeToFirstToken = currentUnixTime() - this.startTime;
}
switch (chunk.type) {
case "response-metadata":
if (chunk.id) {
this._responseId = chunk.id;
}
if (chunk.modelId) {
this._responseModelId = chunk.modelId;
}
break;
case "finish":
this._usage = chunk.usage;
this._finishReason = chunk.finishReason;
break;
}
}
get result() {
return {
response: this._responseId || this._responseModelId ? {
id: this._responseId,
modelId: this._responseModelId
} : void 0,
finishReason: this._finishReason,
usage: this._usage
};
}
get firstTokenTime() {
return this.timeToFirstToken;
}
};
var ToolCallAggregatorV2 = class {
constructor() {
__publicField(this, "calls", {});
}
handleChunk(chunk) {
if (chunk.type === "tool-call") {
this.calls[chunk.toolCallId] = chunk;
}
}
get result() {
return Object.values(this.calls);
}
};
var TextAggregatorV2 = class {
constructor() {
__publicField(this, "content", "");
}
feed(chunk) {
switch (chunk.type) {
case "text-start":
this.content = "";
break;
case "text-delta":
this.content += chunk.delta;
break;
case "text-end":
break;
}
}
get text() {
return this.content || void 0;
}
};
var StreamStatsV2 = class {
constructor() {
__publicField(this, "startTime");
__publicField(this, "timeToFirstToken");
__publicField(this, "_usage");
__publicField(this, "_finishReason");
__publicField(this, "_responseMetadata");
this.startTime = currentUnixTime();
}
feed(chunk) {
if (this.timeToFirstToken === void 0) {
this.timeToFirstToken = currentUnixTime() - this.startTime;
}
switch (chunk.type) {
case "response-metadata":
this._responseMetadata = {
id: chunk.id,
modelId: chunk.modelId,
timestamp: chunk.timestamp
};
break;
case "finish":
this._usage = chunk.usage;
this._finishReason = chunk.finishReason;
break;
}
}
get result() {
return {
response: this._responseMetadata,
finishReason: this._finishReason,
usage: this._usage
};
}
get firstTokenTime() {
return this.timeToFirstToken;
}
};
// src/otel/middleware.ts
var appendPromptMetadataToSpan = (span, messages) => {
const lastMessage = messages?.[messages.length - 1];
let axiomMeta;
if ("providerMetadata" in lastMessage) {
axiomMeta = lastMessage?.providerMetadata?._axiomMeta;
} else if ("providerOptions" in lastMessage) {
axiomMeta = lastMessage?.providerOptions?._axiomMeta;
}
if (axiomMeta) {
if (axiomMeta.id) span.setAttribute(Attr.GenAI.PromptMetadata.ID, axiomMeta.id);
if (axiomMeta.name) span.setAttribute(Attr.GenAI.PromptMetadata.Name, axiomMeta.name);
if (axiomMeta.slug) span.setAttribute(Attr.GenAI.PromptMetadata.Slug, axiomMeta.slug);
if (axiomMeta.version) span.setAttribute(Attr.GenAI.PromptMetadata.Version, axiomMeta.version);
}
};
function axiomAIMiddlewareV1() {
return {
wrapGenerate: async ({ doGenerate, params, model }) => {
return withSpanHandling(
model.modelId,
async (span, commonContext, _lease) => {
const context4 = commonContext;
appendPromptMetadataToSpan(span, params.prompt);
setScopeAttributes(span);
setPreCallAttributesV1(span, params, context4, model);
const res = await doGenerate();
context4.rawCall = res.rawCall;
await setPostCallAttributesV1(span, res, context4, model);
return res;
},
{ version: "v1" }
);
},
wrapStream: async ({ doStream, params, model }) => {
return withSpanHandling(
model.modelId,
async (span, commonContext, lease) => {
const context4 = commonContext;
appendPromptMetadataToSpan(span, params.prompt);
setScopeAttributes(span);
setPreCallAttributesV1(span, params, context4, model);
const { stream, ...head } = await doStream();
const childSpan = createStreamChildSpan(span, `chat ${model.modelId} stream`);
const stats = new StreamStats();
const toolAggregator = new ToolCallAggregator();
const textAggregator = new TextAggregator();
return {
...head,
stream: stream.pipeThrough(
new TransformStream({
transform(chunk, controller) {
try {
stats.feed(chunk);
toolAggregator.handleChunk(chunk);
textAggregator.feed(chunk);
controller.enqueue(chunk);
} catch (err) {
classifyToolError(err, childSpan);
childSpan.end();
if (lease.owned) lease.end();
controller.error(err);
}
},
async flush(controller) {
try {
await setPostCallAttributesV1(
span,
{
...head,
...stats.result,
toolCalls: toolAggregator.result.length > 0 ? toolAggregator.result : void 0,
text: textAggregator.text
},
context4,
model
);
childSpan.end();
if (lease.owned) lease.end();
controller.terminate();
} catch (err) {
classifyToolError(err, childSpan);
childSpan.end();
if (lease.owned) lease.end();
controller.error(err);
}
}
})
)
};
},
{ streaming: true, version: "v1" }
// Don't auto-end span, we'll end it when stream completes
);
}
};
}
function axiomAIMiddleware(config) {
if (config.model.specificationVersion === "v1") {
return axiomAIMiddlewareV1();
} else if (config.model.specificationVersion === "v2") {
return axiomAIMiddlewareV2();
} else {
console.warn(
// @ts-expect-error - not allowed at type level, but users can still do it...
`Unsupported model specification version: ${JSON.stringify(config.model.specificationVersion)}. Creating no-op middleware instead.`
);
return {};
}
}
function axiomAIMiddlewareV2() {
return {
wrapGenerate: async ({ doGenerate, params, model }) => {
return withSpanHandling(
model.modelId,
async (span, commonContext, _lease) => {
const context4 = commonContext;
appendPromptMetadataToSpan(span, params.prompt);
setScopeAttributes(span);
setPreCallAttributesV2(span, params, context4, model);
const res = await doGenerate();
await setPostCallAttributesV2(span, res, context4, model);
return res;
},
{ version: "v2" }
);
},
wrapStream: async ({ doStream, params, model }) => {
return withSpanHandling(
model.modelId,
async (span, commonContext, lease) => {
const context4 = commonContext;
appendPromptMetadataToSpan(span, params.prompt);
setScopeAttributes(span);
setPreCallAttributesV2(span, params, context4, model);
const ret = await doStream();
const childSpan = createStreamChildSpan(span, `chat ${model.modelId} stream`);
const stats = new StreamStatsV2();
const toolAggregator = new ToolCallAggregatorV2();
const textAggregator = new TextAggregatorV2();
return {
...ret,
stream: ret.stream.pipeThrough(
new TransformStream({
transform(chunk, controller) {
try {
stats.feed(chunk);
toolAggregator.handleChunk(chunk);
textAggregator.feed(chunk);
controller.enqueue(chunk);
} catch (err) {
classifyToolError(err, childSpan);
childSpan.end();
if (lease.owned) lease.end();
controller.error(err);
}
},
async flush(controller) {
try {
const streamResult = {
...stats.result,
content: [
...textAggregator.text ? [{ type: "text", text: textAggregator.text }] : [],
...toolAggregator.result
]
};
await setPostCallAttributesV2(span, streamResult, context4, model);
childSpan.end();
if (lease.owned) lease.end();
controller.terminate();
} catch (err) {
classifyToolError(err, childSpan);
childSpan.end();
if (lease.owned) lease.end();
controller.error(err);
}
}
})
)
};
},
{ streaming: true, version: "v2" }
// Don't auto-end span, we'll end it when stream completes
);
}
};
}
function setPreCallAttributesV1(span, options, context4, model) {
const redactionPolicy = getRedactionPolicy();
const {
prompt,
maxTokens,
frequencyPenalty,
presencePenalty,
temperature,
topP,
topK,
seed,
stopSequences,
responseFormat,
mode
} = options;
const processedPrompt = promptV1ToOpenAI(prompt);
context4.originalPrompt = processedPrompt;
handleMaybeRedactedAttribute(
span,
Attr.GenAI.Input.Messages,
JSON.stringify(sanitizeMultimodalContent(processedPrompt)),
redactionPolicy.captureMessageContent
);
setBaseAttributes(span, model.provider, model.modelId);
const outputType = determineOutputTypeV1({ responseFormat, mode });
if (outputType) {
span.setAttribute(Attr.GenAI.Output.Type, outputType);
}
setRequestParameterAttributes(span, {
maxTokens,
frequencyPenalty,
presencePenalty,
temperature,
topP,
topK,
seed,
stopSequences
});
}
async function setPostCallAttributesV1(span, result, context4, _model) {
const redactionPolicy = getRedactionPolicy();
if (result.toolCalls && result.toolCalls.length > 0) {
const originalPrompt = context4.originalPrompt || [];
const normalizedToolCalls = normalizeV1ToolCalls(result.toolCalls);
const toolResultsMap = context4.rawCall?.rawPrompt ? extractToolResultsFromRawPrompt(context4.rawCall.rawPrompt) : /* @__PURE__ */ new Map();
const updatedPrompt = appendToolCalls(
originalPrompt,
normalizedToolCalls,
toolResultsMap,
result.text
);
handleMaybeRedactedAttribute(
span,
Attr.GenAI.Input.Messages,
JSON.stringify(sanitizeMultimodalContent(updatedPrompt)),
redactionPolicy.captureMessageContent
);
}
if (result.text) {
const completion = createSimpleCompletion({
text: result.text
});
handleMaybeRedactedAttribute(
span,
Attr.GenAI.Output.Messages,
JSON.stringify(completion),
redactionPolicy.captureMessageContent
);
}
if (result.response?.id) {
span.setAttribute(Attr.GenAI.Response.ID, result.response.id);
}
if (result.response?.modelId) {
span.setAttribute(Attr.GenAI.Response.Model, result.response.modelId);
}
const inputTokens = ensureNumber(result.usage?.promptTokens);
if (inputTokens !== void 0) {
span.setAttribute(Attr.GenAI.Usage.InputTokens, inputTokens);
}
const outputTokens = ensureNumber(result.usage?.completionTokens);
if (outputTokens !== void 0) {
span.setAttribute(Attr.GenAI.Usage.OutputTokens, outputTokens);
}
if (result.finishReason) {
span.setAttribute(Attr.GenAI.Response.FinishReasons, JSON.stringify([result.finishReason]));
}
}
function setPreCallAttributesV2(span, options, context4, model) {
const redactionPolicy = getRedactionPolicy();
setBaseAttributes(span, model.provider, model.modelId);
const outputType = determineOutputTypeV2(options);
if (outputType) {
span.setAttribute(Attr.GenAI.Output.Type, outputType);
}
setRequestParameterAttributes(span, {
maxTokens: options.maxOutputTokens,
frequencyPenalty: options.frequencyPenalty,
presencePenalty: options.presencePenalty,
temperature: options.temperature,
topP: options.topP,
topK: options.topK,
seed: options.seed,
stopSequences: options.stopSequences
});
const processedPrompt = promptV2ToOpenAI(options.prompt);
context4.originalV2Prompt = options.prompt;
context4.originalPrompt = processedPrompt;
handleMaybeRedactedAttribute(
span,
Attr.GenAI.Input.Messages,
JSON.stringify(sanitizeMultimodalContent(processedPrompt)),
redactionPolicy.captureMessageContent
);
}
async function setPostCallAttributesV2(span, result, context4, _model) {
const redactionPolicy = getRedactionPolicy();
const toolCalls = result.content?.filter(
(c) => c.type === "tool-call"
);
const alreadySet = span.attributes?.[Attr.GenAI.Response.FinishReasons] !== void 0;
if (!alreadySet) {
if (result.response?.id) {
span.setAttribute(Attr.GenAI.Response.ID, result.response.id);
}
if (result.response?.modelId) {
span.setAttribute(Attr.GenAI.Response.Model, result.response.modelId);
}
const inputTokens = ensureNumber(result.usage?.inputTokens);
if (inputTokens !== void 0) {
span.setAttribute(Attr.GenAI.Usage.InputTokens, inputTokens);
}
const outputTokens = ensureNumber(result.usage?.outputTokens);
if (outputTokens !== void 0) {
span.setAttribute(Attr.GenAI.Usage.OutputTokens, outputTokens);
}
}
if (toolCalls && toolCalls.length > 0) {
const originalPrompt = context4.originalPrompt || [];
const normalizedToolCalls = normalizeV2ToolCalls(toolCalls);
const toolResultsMap = extractToolResultsFromPromptV2(context4.originalV2Prompt || []);
const textContent = result.content?.find((c) => c.type === "text");
const assistantText = textContent?.type === "text" ? textContent.text : void 0;
const updatedPrompt = appendToolCalls(
originalPrompt,
normalizedToolCalls,
toolResultsMap,
assistantText
);
handleMaybeRedactedAttribute(
span,
Attr.GenAI.Input.Messages,
JSON.stringify(sanitizeMultimodalContent(updatedPrompt)),
redactionPolicy.captureMessageContent
);
}
if (result.content && result.content.length > 0) {
await processToolCallsAndCreateSpansV2(span, result.content);
} else if (result.finishReason) {
const completion = createSimpleCompletion({
text: ""
});
handleMaybeRedactedAttribute(
span,
Attr.GenAI.Output.Messages,
JSON.stringify(completion),
redactionPolicy.captureMessageContent
);
}
if (result.finishReason && !alreadySet) {
span.setAttribute(Attr.GenAI.Response.FinishReasons, JSON.stringify([result.finishReason]));
}
}
async function processToolCallsAndCreateSpansV2(parentSpan, content) {
const redactionPolicy = getRedactionPolicy();
const textContent = content.find((c) => c.type === "text");
const assistantText = textContent?.type === "text" ? textContent.text : void 0;
const toolCalls = content.filter((c) => c.type === "tool-call");
if (toolCalls.length === 0) {
const completion = [
{
role: "assistant",
content: sanitizeMultimodalContent(
content.length === 1 && assistantText ? assistantText : content
)
}
];
handleMaybeRedactedAttribute(
parentSpan,
Attr.GenAI.Output.Messages,
JSON.stringify(completion),
redactionPolicy.captureMessageContent
);
}
}
// src/otel/vercel.ts
init_esm_shims();
// src/otel/AxiomWrappedLanguageModelV1.ts
init_esm_shims();
function isLanguageModelV1(model) {
return model != null && typeof model === "object" && "specificationVersion" in model && "provider" in model && "modelId" in model && model.specificationVersion === "v1" && typeof model.provider === "string" && typeof model.modelId === "string";
}
var AxiomWrappedLanguageModelV1 = class {
constructor(model) {
const middleware = axiomAIMiddlewareV1();
return {
specificationVersion: model.specificationVersion,
provider: model.provider,
modelId: model.modelId,
defaultObjectGenerationMode: model.defaultObjectGenerationMode,
supportsImageUrls: model.supportsImageUrls,
supportsStructuredOutputs: model.supportsStructuredOutputs,
supportsUrl: model.supportsUrl?.bind(model),
doGenerate: async (params) => {
return middleware.wrapGenerate({
doGenerate: () => model.doGenerate(params),
doStream: () => model.doStream(params),
params,
model
});
},
doStream: async (params) => {
return middleware.wrapStream({
doGenerate: () => model.doGenerate(params),
doStream: () => model.doStream(params),
params,
model
});
}
};
}
};
// src/otel/AxiomWrappedLanguageModelV2.ts
init_esm_shims();
function isLanguageModelV2(model) {
return model?.specificationVersion === "v2" && typeof model?.provider === "string" && typeof model?.modelId === "string";
}
var AxiomWrappedLanguageModelV2 = class {
constructor(model) {
const middleware = axiomAIMiddlewareV2();
return {
specificationVersion: model.specificationVersion,
provider: model.provider,
modelId: model.modelId,
supportedUrls: model.supportedUrls,
doGenerate: async (params) => {
return middleware.wrapGenerate({
doGenerate: () => model.doGenerate(params),
doStream: () => model.doStream(params),
params,
model
});
},
doStream: async (params) => {
return middleware.wrapStream({
doGenerate: () => model.doGenerate(params),
doStream: () => model.doStream(params),
params,
model
});
}
};
}
};
// src/otel/vercel.ts
function wrapAISDKModel(model) {
if (isLanguageModelV2(model)) {
return new AxiomWrappedLanguageModelV2(model);
} else if (isLanguageModelV1(model)) {
return new AxiomWrappedLanguageModelV1(model);
} else {
console.warn("Unsupported AI SDK model. Not wrapping.");
return model;
}
}
// src/app-scope.ts
init_esm_shims();
// src/evals/context/global-flags.ts
init_esm_shims();
var GLOBAL_OVERRIDES_SYMBOL = Symbol.for("axiom.global_flag_overrides");
function getRoot() {
return globalThis[GLOBAL_OVERRIDES_SYMBOL] ?? {};
}
function setRoot(val) {
globalThis[GLOBAL_OVERRIDES_SYMBOL] = val;
}
function setGlobalFlagOverrides(overrides) {
setRoot(overrides);
}
function getGlobalFlagOverrides() {
return getRoot();
}
// src/evals/context/storage.ts
init_esm_shims();
import { trace as trace4 } from "@opentelemetry/api";
// src/evals/context/manager.ts
init_esm_shims();
import { createRequire } from "module";
var CONTEXT_MANAGER_SYMBOL = Symbol.for("axiom.context_manager");
function getGlobalContextManager() {
return globalThis[CONTEXT_MANAGER_SYMBOL];
}
function setGlobalContextManager(manager) {
globalThis[CONTEXT_MANAGER_SYMBOL] = manager;
}
var isNodeJS = typeof process !== "undefined" && !!process.versions?.node;
function getContextManager() {
const existing = getGlobalContextManager();
if (existing) return existing;
let manager;
if (isNodeJS) {
try {
let AsyncLocalStorage;
const req = createRequire(import.meta.url);
try {
AsyncLocalStorage = req("node:async_hooks").AsyncLocalStorage;
} catch {
AsyncLocalStorage = req("async_hooks").AsyncLocalStorage;
}
manager = new AsyncLocalStorage();
} catch (error) {
console.warn("AsyncLocalStorage not available, using fallback context manager:", error);
manager = createFallbackManager();
}
} else {
console.warn("AsyncLocalStorage not available, using fallback context manager");
manager = createFallbackManager();
}
setGlobalContextManager(manager);
return manager;
}
function createFallbackManager() {
let currentContext = null;
return {
getStore: () => currentContext,
run: (value, fn) => {
const prev = currentContext;
currentContext = value;
try {
return fn();
} finally {
currentContext = prev;
}
}
};
}
function createAsyncHook(_name) {
return {
get() {
const manager = getContextManager();
if (manager.getStore) {
return manager.getStore();
}
return void 0;
},
run(value, fn) {
const manager = getContextManager();
return manager.run(value, fn);
}
};
}
// src/evals/context/storage.ts
var CONFIG_SCOPE_SYMBOL = Symbol.for("axiom.eval.configScope");
function getGlobalConfigScope() {
return globalThis[CONFIG_SCOPE_SYMBOL];
}
function setGlobalConfigScope(scope) {
globalThis[CONFIG_SCOPE_SYMBOL] = scope;
}
var AXIOM_CONFIG_SYMBOL = Symbol.for("axiom.eval.config");
function getAxiomConfig() {
return globalThis[AXIOM_CONFIG_SYMBOL];
}
function setAxiomConfig(config) {
globalThis[AXIOM_CONFIG_SYMBOL] = config;
}
var EVAL_CONTEXT = createAsyncHook("eval-context");
function getEvalContext() {
const ctx = EVAL_CONTEXT.get();
if (!ctx) {
return {
flags: {},
facts: {},
pickedFlags: void 0,
outOfScopeFlags: void 0
};
}
return {
flags: ctx.flags,
facts: ctx.facts,
pickedFlags: ctx.pickedFlags,
outOfScopeFlags: ctx.outOfScopeFlags,
parent: ctx.parent,
overrides: ctx.overrides,
accessedFlagKeys: ctx.accessedFlagKeys
};
}
function updateEvalContext(flags, facts) {
const current = EVAL_CONTEXT.get();
if (!current) {
return;
}
if (flags) {
Object.assign(current.flags, flags);
if (!current.accessedFlagKeys) current.accessedFlagKeys = [];
for (const key of Object.keys(flags)) {
if (!current.accessedFlagKeys.includes(key)) {
current.accessedFlagKeys.push(key);
}
}
}
if (facts) {
Object.assign(current.facts, facts);
}
}
function parseStackTrace(stack) {
const lines = stack.split("\n");
const frames = [];
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed || !trimmed.startsWith("at ")) {
continue;
}
if (trimmed.includes("node_modules") || trimmed.includes("node:internal") || trimmed.includes("addOutOfScopeFlag") || trimmed.includes("storage.ts") || // Keep app-scope.ts frames that aren't the flag() function itself
trimmed.includes("app-scope.ts") && (trimmed.includes("flag (") || trimmed.includes("flag2 ("))) {
continue;
}
frames.push(trimmed.replace("at ", ""));
}
return frames.slice(0, 5);
}
function addOutOfScopeFlag(flagPath) {
const current = EVAL_CONTEXT.get();
if (!current) {
console.warn("addOutOfScopeFlag called outside of evaluation context");
return;
}
if (!current.outOfScopeFlags) {
current.outOfScopeFlags = [];
}
const stack = new Error().stack || "";
const stackTrace = parseStackTrace(stack);
current.outOfScopeFlags.push({
flagPath,
accessedAt: Date.now(),
stackTrace
});
}
function putOnSpan(kind, key, value) {
const span = trace4.getActiveSpan();
if (span?.isRecording()) {
span.setAttributes({ [`${kind}.${key}`]: value });
}
}
function withEvalContext(options = {}, fn) {
const { initialFlags = {}, pickedFlags = [] } = options;
return EVAL_CONTEXT.run(
{
flags: { ...initialFlags },
facts: {},
pickedFlags,
outOfScopeFlags: [],
accessedFlagKeys: []
},
fn
);
}
function setConfigScope(scope) {
const current = EVAL_CONTEXT.get();
if (current) {
current.configScope = scope;
}
setGlobalConfigScope(scope);
}
function getConfigScope() {
const current = EVAL_CONTEXT.get();
return current?.configScope ?? getGlobalConfigScope();
}
// src/validate-flags.ts
init_esm_shims();
import "zod";
// src/cli/utils/format-zod-errors.ts
init_esm_shims();
import "zod";
function formatZodErrors(error) {
const issues = error.issues;
const messages = [];
for (const issue of issues) {
const path = issue.path.join(".");
const message = formatIssueMessage(issue, path);
messages.push(` \u2022 ${message}`);
}
return messages.join("\n");
}
function formatIssueMessage(issue, path) {
switch (issue.code) {
case "invalid_type":
return `flag '${path}' expected ${issue.expected}, got ${JSON.stringify(issue.received)} (${typeof issue.received})`;
case "too_small":
if (issue.type === "number" || issue.origin === "number") {
return `flag '${path}' must be >= ${issue.minimum}, got ${issue.received}`;
}
return `flag '${path}' is too small: ${issue.message}`;
case "too_big":
if (issue.type === "number") {
return `flag '${path}' must be <= ${issue.maximum}, got ${issue.received}`;
}
return `flag '${path}' is too big: ${issue.message}`;
case "invalid_enum_value":
const options = issue.options.map((opt) => `"${opt}"`).join(", ");
return `flag '${path}' must be one of: ${options}, got "${issue.received}"`;
case "invalid_value":
if (issue.values && Array.isArray(issue.values)) {
const values = issue.values.map((val) => `"${val}"`).join(", ");
return `flag '${path}' must be one of: ${values}`;
}
return `flag '${path}': ${issue.message}`;
case "unrecognized_keys":
const keys = issue.keys || [];
if (keys.length === 1) {
return `unrecognized flag '${keys[0]}'`;
} else if (keys.length > 1) {
const keysList = keys.map((key) => `'${key}'`).join(", ");
return `unrecognized flags ${keysList}`;
}
return `unrecognized keys in flags`;
case "custom":
return `flag '${path}': ${issue.message}`;
default:
return `flag '${path}': ${issue.message}`;
}
}
function generateFlagExamples(error) {
const examples = [];
for (const issue of error.issues) {
const path = issue.path.join(".");
const example = generateExampleForIssue(issue, path);
if (example && !examples.includes(example)) {
examples.push(example);
}
}
return examples.slice(0, 3);
}
function generateExampleForIssue(issue, path) {
switch (issue.code) {
case "invalid_type":
if (issue.expected === "number") {
return `--flag.${path}=0.7`;
}
if (issue.expected === "boolean") {
return `--flag.${path}=true`;
}
if (issue.expected === "string") {
return `--flag.${path}="value"`;
}
break;
case "too_small":
if (typeof issue.minimum === "number" || typeof issue.minimum === "bigint") {
return `--flag.${path}=${issue.minimum}`;
}
break;
case "too_big":
if (typeof issue.maximum === "number" || typeof issue.maximum === "bigint") {
return `--flag.${path}=${issue.maximum}`;
}
break;
case "invalid_enum_value":
if (issue.options.length > 0) {
return `--flag.${path}=${issue.options[0]}`;
}
break;
case "invalid_value":
if (issue.values && Array.isArray(issue.values) && issue.values.length > 0) {
return `--flag.${path}=${String(issue.values[0])}`;
}
break;
}
return null;
}
// src/util/dot-path.ts
init_esm_shims();
import { z } from "zod";
// src/util/zod-internals.ts
init_esm_shims();
function isZodV4Schema(schema) {
if (!schema || typeof schema !== "object") return false;
const s = schema;
return "_zod" in s;
}
function assertZodV4(schema, context4) {
if (!isZodV4Schema(schema)) {
throw new Error(
`[AxiomAI] Zod v4 schemas are required (detected in ${context4}). Found unsupported Zod version.`
);
}
}
function getDef(schema) {
if (!schema || typeof schema !== "object") return void 0;
const s = schema;
if (s._zod && typeof s._zod === "object") {
const zod = s._zod;
if (zod.def && typeof zod.def === "object") {
return zod.def;
}
}
return void 0;
}
function getDefRawType(def) {
if (!def) return void 0;
const raw = def.type;
if (raw == null) return void 0;
return typeof raw === "string" ? raw : String(raw);
}
var KNOWN_KINDS = /* @__PURE__ */ new Set([
"object",
"optional",
"default",
"nullable",
"readonly",
"prefault",
"nonoptional",
"catch",
"array",
"record",
"union",
"discriminatedunion"
]);
function getKind(schemaOrDef) {
const def = schemaOrDef && typeof schemaOrDef === "object" && "type" in schemaOrDef ? schemaOrDef : getDef(schemaOrDef);
const raw = getDefRawType(def);
if (!raw) return void 0;
const normalized = raw.toLowerCase();
return KNOWN_KINDS.has(normalized) ? normalized : "other";
}
function isObjectSchema(schema) {
if (!schema || typeof schema !== "object") return false;
if ("shape" in schema && typeof schema.shape === "object") {
return true;
}
return getKind(schema) === "object";
}
function getInnerType(schema) {
const def = getDef(schema);
return def?.innerType;
}
function getArrayElement(schema) {
const def = getDef(schema);
return def?.element;
}
function getShape(schema) {
if (!schema || typeof schema !== "object") return void 0;
const s = schema;
if (s.shape && typeof s.shape === "object") {
return s.shape;
}
return void 0;
}
function getDefaultValue(schema) {
const def = getDef(schema);
return def?.defaultValue;
}
var TRANSPARENT_WRAPPERS = [
"optional",
"nullable",
"default",
"readonly",
"prefault",
"nonoptional",
"catch"
// transparent for schema structure, but alters error behavior
];
function unwrapTransparent(schema) {
let current = schema;
for (let i = 0; i < 10; i++) {
const kind = getKind(current);
if (!kind) break;
if (TRANSPARENT_WRAPPERS.includes(kind)) {
const inner = getInnerType(current);
if (!inner) break;
current = inner;
continue;
}
break;
}
return current;
}
// src/util/dot-path.ts
function parsePath(path) {
return path.split(".");
}
function dotNotationToNested(dotNotationObject) {
const result = {};
for (const [dotPath, value] of Object.entries(dotNotationObject)) {
const segments = parsePath(dotPath);
let current = result;
for (let i = 0; i < segments.length; i++) {
const segment = segments[i];
if (i === segments.length - 1) {
current[segment] = value;
} else {
if (!(segment in current) || typeof current[segment] !== "object") {
current[segment] = {};
}
current = current[segment];
}
}
}
return result;
}
function flattenObject(obj, prefix = "") {
const result = {};
for (const [key, value] of Object.entries(obj)) {
const newKey = prefix ? `${prefix}.${key}` : key;
if (value && typeof value === "object" && !Array.isArray(value)) {
Object.assign(result, flattenObject(value, newKey));
} else {
result[newKey] = value;
}
}
return result;
}
function isValidPath(schema, segments) {
let currentSchema = schema;
for (let i = 0; i < segments.length; i++) {
const segment = segments[i];
const shape = getShape(currentSchema);
if (!shape || !(segment in shape)) {
return false;
}
if (i < segments.length - 1) {
const nextSchema = shape[segment];
const unwrappedSchema = unwrapTransparent(nextSchema);
if (!isObjectSchema(unwrappedSchema)) {
return false;
}
currentSchema = unwrappedSchema;
}
}
return true;
}
function getValueAtPath(obj, segments) {
let current = obj;
for (const segment of segments) {
if (current == null || typeof current !== "object" || !(segment in current)) {
return void 0;
}
current = current[segment];
}
return current;
}
function findSchemaAtPath(rootSchema, segments) {
if (!rootSchema || segments.length === 0) return void 0;
let current = rootSchema;
if (segments.length > 0) {
const rootShape = getShape(current);
if (!rootShape || !(segments[0] in rootShape)) {
return void 0;
}
current = rootShape[segments[0]];
for (let i = 1; i < segments.length; i++) {
const segment = segments[i];
const def = getDef(current);
if (!def) {
return void 0;
}
current = unwrapTransparent(current);
if (!isObjectSchema(current)) {
return void 0;
}
const shape = getShape(current);
if (!shape) {
return void 0;
}
const nextSchema = shape[segment];
if (!nextSchema) {
return void 0;
}
current = nextSchema;
}
return current;
}
return current;
}
function buildSchemaForPath(rootSchema, segments) {
const pathKey = segments.join(".");
const leafSchema = findSchemaAtPath(rootSchema, segments);
if (!leafSchema) {
throw new Error(`Cannot find schema for path: ${pathKey}`);
}
let currentSchema = leafSchema;
for (let i = segments.length - 1; i >= 0; i--) {
const segment = segments[i];
const objectSchema = z.object({ [segment]: currentSchema });
currentSchema = objectSchema.partial().strict();
}
return currentSchema;
}
// src/util/deep-partial-schema.ts
init_esm_shims();
import { z as z2 } from "zod";
function makeDeepPartial(schema) {
const shape = schema.shape;
const newShape = {};
for (const [key, value] of Object.entries(shape)) {
newShape[key] = makeDeepPartialField(value);
}
return z2.object(newShape);
}
function makeDeepPartialField(fieldSchema) {
const kind = getKind(fieldSchema);
if (isObjectSchema(fieldSchema)) {
const partialObject = makeDeepPartial(fieldSchema);
return partialObject.optional();
}
if (kind === "optional") {
const inner = getInnerType(fieldSchema);
if (inner && isObjectSchema(inner)) {
const partialInner = makeDeepPartial(inner);
return partialInner.optional();
}
return fieldSchema;
}
if (kind === "nullable") {
const inner = getInnerType(fieldSchema);
if (inner && isObjectSchema(inner)) {
const partialInner = makeDeepPartial(inner);
return partialInner.nullable().optional();
}
return fieldSchema.optional();
}
if (kind === "default") {
const inner = getInnerType(fieldSchema);
const defaultValue = getDefaultValue(fieldSchema);
if (inner && isObjectSchema(inner)) {
const partialInner = makeDeepPartial(inner);
return partialInner.default(defaultValue);
}
return fieldSchema.optional();
}
if (kind === "array") {
const element = getArrayElement(fieldSchema);
if (element && isObjectSchema(element)) {
const partialElement = makeDeepPartial(element);
return z2.array(partialElement).optional();
}
return fieldSchema.optional();
}
return fieldSchema.optional();
}
// src/validate-flags.ts
function validateCliFlags(flagSchema) {
assertZodV4(flagSchema, "flagSchema");
const globalOverrides = getGlobalFlagOverrides();
if (Object.keys(globalOverrides).length === 0) {
return;
}
validateFlags(flagSchema, globalOverrides);
}
function validateFlags(flagSchema, globalOverrides) {
for (const [dotPath, _value] of Object.entries(globalOverrides)) {
const segments = parsePath(dotPath);
if (!isValidPath(flagSchema, segments)) {
console.error("\u274C Invalid CLI flags:");
console.error(` \u2022 flag '${dotPath}': Invalid flag path`);
console.error("\n\u{1F527} Fix your CLI flags and try again.\n");
process.exit(1);
}
}
const nestedObject = dotNotationToNested(globalOverrides);
const deepPartialSchema = makeDeepPartial(flagSchema);
const result = deepPartialSchema.safeParse(nestedObject);
if (!result.success) {
console.error("\u274C Invalid CLI flags:");
console.error(formatZodErrors(result.error));
const examples = generateFlagExamples(result.error);
if (examples.length > 0) {
console.error("\n\u{1F4A1} Valid examples:");
examples.forEach((example) => console.error(` ${example}`));
}
console.error("\n\u{1F527} Fix your CLI flags and try again.\n");
process.exit(1);
}
}
// src/app-scope.ts
import { trace as trace5 } from "@opentelemetry/api";
import "zod";
// src/otel/utils/to-otel-attribute.ts
init_esm_shims();
import "@opentelemetry/api";
function toHomogeneousArray(input) {
if (input.length === 0) return void 0;
const converted = [];
const types = /* @__PURE__ */ new Set();
for (const item of input) {
const converted_item = toOtelPrimitive(item);
if (converted_item !== void 0) {
converted.push(converted_item);
types.add(typeof converted_item);
}
}
if (converted.length === 0) return void 0;
if (types.size > 1) {
return converted.map((item) => String(item));
}
return converted;
}
function toOtelPrimitive(v) {
switch (typeof v) {
case "string":
return v;
case "number":
return Number.isFinite(v) ? v : void 0;
case "boolean":
return v;
case "bigint":
if (v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) {
return Number(v);
}
return v.toString();
case "function":
case "symbol":
case "undefined":
return void 0;
case "object":
if (v === null) return void 0;
if (v instanceof Date) return v.toISOString();
if (v instanceof Error) return v.message;
return safeStringify(v);
}
}
function safeStringify(obj) {
try {
const s = JSON.stringify(
obj,
(_k, val) => typeof val === "bigint" ? Number(val) : val instanceof Date ? val.toISOString() : val
);
if (s === "{}") {
if (obj instanceof Map) {
return JSON.stringify(Object.fromEntries(obj));
}
if (obj instanceof Set) {
return JSON.stringify(Array.from(obj));
}
}
return s ?? void 0;
} catch {
try {
const t = obj?.toString?.();
return typeof t === "string" ? t : void 0;
} catch {
return void 0;
}
}
}
function toOtelAttribute(input) {
switch (typeof input) {
case "string":
return input;
case "number":
return Number.isFinite(input) ? input : void 0;
case "boolean":
return input;
case "bigint":
if (input >= Number.MIN_SAFE_INTEGER && input <= Number.MAX_SAFE_INTEGER) {
return Number(input);
}
return input.toString();
case "function":
case "symbol":
case "undefined":
return void 0;
}
if (Array.isArray(input)) {
return toHomogeneousArray(input);
}
if (input instanceof Date) {
return input.toISOString();
}
if (input === null) return void 0;
return safeStringify(input);
}
// src/otel/index.ts
init_esm_shims();
// src/app-scope.ts
function isPickedFlag(flagPath, pickedFlags) {
if (!pickedFlags) {
return true;
}
if (pickedFlags.length === 0) {
return true;
}
return pickedFlags.some((picked) => {
if (flagPath === picked) {
return true;
}
if (flagPath.startsWith(picked + ".")) {
return true;
}
return false;
});
}
function assertNoUnions(schema, path = "schema") {
if (!schema) return;
const kind = getKind(schema);
if (!kind) return;
if (kind === "default" || kind === "optional" || kind === "nullable") {
const innerType = getInnerType(schema);
return assertNoUnions(innerType, path);
}
if (kind === "union" || kind === "discriminatedunion") {
throw new Error(`[AxiomAI] Union types are not supported in flag schemas (found at "${path}")`);
}
if (kind === "object") {
const shape = getShape(schema);
if (shape) {
for (const [k, v] of Object.entries(shape)) {
assertNoUnions(v, `${path}.${k}`);
}
}
} else if (kind === "array") {
const innerType = getInnerType(schema);
if (innerType) {
assertNoUnions(innerType, `${path}[]`);
}
} else if (kind === "record") {
const def = getDef(schema);
const valueType = def?.valueType;
if (valueType) {
assertNoUnions(valueType, `${path}{}`);
}
}
}
function ensureAllDefaults(schema, path = "") {
const missingDefaults = [];
function checkDefaults(current, currentPath) {
if (!current) return;
const kind = getKind(current);
if (!kind) return;
const def = getDef(current);
const hasDefault = def?.defaultValue !== void 0;
if (kind === "default") {
return;
}
if (kind === "optional" || kind === "nullable") {
const innerType = getInnerType(current);
return checkDefaults(innerType, currentPath);
}
if (kind === "record") {
throw new Error(
`[AxiomAI] ZodRecord is not supported in flag schemas (found at "${currentPath || "root"}")
All flag fields must have known keys and defaults. Consider using z.object() instead.`
);
}
if (kind === "object") {
if (hasDefault) {
return;
}
const shape = getShape(current);
if (shape) {
for (const [k, v] of Object.entries(shape)) {
const nextPath = currentPath ? `${currentPath}.${k}` : k;
checkDefaults(v, nextPath);
}
}
return;
}
if (kind === "array") {
if (!hasDefault) {
missingDefaults.push(currentPath || "root");
}
return;
}
if (!hasDefault) {
missingDefaults.push(currentPath || "root");
}
}
checkDefaults(schema, path);
if (missingDefaults.length > 0) {
throw new Error(
`[AxiomAI] All flag fields must have defaults. Missing defaults for:
` + missingDefaults.map((p) => ` - ${p}`).join("\n") + `
Add .default(value) to these fields or to their parent objects.`
);
}
}
function createAppScope(config) {
const flagSchemaConfig = config?.flagSchema;
const factSchemaConfig = config?.factSchema;
if (flagSchemaConfig) {
assertZodV4(flagSchemaConfig, "flagSchema");
}
if (factSchemaConfig) {
assertZodV4(factSchemaConfig, "factSchema");
}
if (flagSchemaConfig) {
assertNoUnions(flagSchemaConfig, "flagSchema");
}
if (flagSchemaConfig) {
ensureAllDefaults(flagSchemaConfig);
}
if (flagSchemaConfig) {
validateCliFlags(flagSchemaConfig);
}
function isNamespaceAccess(segments) {
if (!flagSchemaConfig || segments.length === 0) return false;
if (segments.length === 1) {
return flagSchemaConfig.shape ? segments[0] in flagSchemaConfig.shape : false;
}
const schema = findSchemaAtPath(flagSchemaConfig, segments);
return isObjectSchema(schema);
}
function buildObjectWithDefaults(schema) {
if (!schema) return void 0;
const kind = getKind(schema);
if (!kind) return void 0;
const directDefault = extractDefault(schema);
if (directDefault !== void 0) {
return directDefault;
}
if (kind === "object") {
const shape = getShape(schema);
if (shape) {
const result = {};
for (const [key, fieldSchema] of Object.entries(shape)) {
const fieldValue = buildObjectWithDefaults(fieldSchema);
result[key] = fieldValue;
}
return result;
}
}
return void 0;
}
function extractDefault(schema) {
if (!schema) return void 0;
let current = schema;
for (let i = 0; i < 10; i++) {
const def = getDef(current);
if (!def) break;
if (def.defaultValue !== void 0) {
return typeof def.defaultValue === "function" ? def.defaultValue() : def.defaultValue;
}
const inner = getInnerType(current);
if (inner) {
current = inner;
} else {
break;
}
}
return void 0;
}
function validateFinalFlagValue(dotPath, value) {
if (!flagSchemaConfig) return { ok: true, parsed: value };
const segments = parsePath(dotPath);
const fieldSchema = findSchemaAtPath(flagSchemaConfig, segments);
if (fieldSchema) {
const direct = fieldSchema.safeParse(value);
if (direct.success) return { ok: true, parsed: direct.data };
return { ok: false };
}
const hasValidNamespace = flagSchemaConfig.shape && segments[0] in flagSchemaConfig.shape;
if (!hasValidNamespace) {
return { ok: true, parsed: value };
}
const nested = dotNotationToNested({ [dotPath]: value });
const nestedResult = flagSchemaConfig.strict().partial().safeParse(nested);
if (nestedResult.success) {
const parsed = getValueAtPath(nestedResult.data, segments) ?? value;
return { ok: true, parsed };
}
return { ok: true, parsed: value };
}
function hasUndefinedLeaves(obj) {
if (obj === void 0) return true;
if (obj === null || typeof obj !== "object") return false;
return Object.values(obj).some(
(v) => typeof v === "object" && v !== null ? hasUndefinedLeaves(v) : v === void 0
);
}
function flag(path) {
const segments = parsePath(path);
const ctx = getEvalContext();
const globalOverrides = getGlobalFlagOverrides();
if (!isPickedFlag(path, ctx.pickedFlags)) {
addOutOfScopeFlag(path);
}
let finalValue;
let source;
if (path in globalOverrides) {
finalValue = globalOverrides[path];
source = "cli";
} else if (path in ctx.flags) {
finalValue = ctx.flags[path];
source = "ctx";
} else {
if (!flagSchemaConfig) {
console.error(`[AxiomAI] Invalid flag: "${path}"`);
return void 0;
}
const hasValidNamespace = flagSchemaConfig.shape && segments[0] in flagSchemaConfig.shape;
if (!hasValidNamespace) {
console.error(`[AxiomAI] Invalid flag: "${path}"`);
return void 0;
}
const schemaForPath = findSchemaAtPath(flagSchemaConfig, segments);
if (!schemaForPath) {
const namespaceSchema = findSchemaAtPath(flagSchemaConfig, [segments[0]]);
if (namespaceSchema) {
const namespaceObject = buildObjectWithDefaults(namespaceSchema);
if (namespaceObject && typeof namespaceObject === "object") {
finalValue = getValueAtPath(namespaceObject, segments.slice(1));
}
}
if (finalValue === void 0) {
console.error(`[AxiomAI] Invalid flag: "${path}"`);
return void 0;
}
} else if (isNamespaceAccess(segments)) {
finalValue = buildObjectWithDefaults(schemaForPath);
if (finalValue === void 0 || hasUndefinedLeaves(finalValue)) {
const nsSchema = findSchemaAtPath(flagSchemaConfig, [segments[0]]);
if (nsSchema) {
const nsObj = buildObjectWithDefaults(nsSchema);
if (nsObj && typeof nsObj === "object") {
const extracted = getValueAtPath(nsObj, segments.slice(1));
if (extracted !== void 0) {
finalValue = extracted;
}
}
}
}
if (finalValue === void 0) {
console.error(`[AxiomAI] Invalid flag: "${path}"`);
return void 0;
}
} else {
finalValue = extractDefault(schemaForPath);
if (finalValue === void 0) {
const nsSchema = findSchemaAtPath(flagSchemaConfig, [segments[0]]);
if (nsSchema) {
const nsObj = buildObjectWithDefaults(nsSchema);
if (nsObj && typeof nsObj === "object") {
finalValue = getValueAtPath(nsObj, segments.slice(1));
}
}
if (finalValue === void 0) {
console.error(`[AxiomAI] Invalid flag: "${path}"`);
return void 0;
}
}
}
source = "schema";
}
if (source !== "schema") {
const validation = validateFinalFlagValue(path, finalValue);
if (!validation.ok) {
console.error(`[AxiomAI] Invalid flag: "${path}" - value does not match schema`);
}
}
updateEvalContext({ [path]: finalValue });
const span = trace5.getActiveSpan();
if (span?.isRecording()) {
const attr = toOtelAttribute(finalValue);
if (attr) {
span.setAttribute(Attr.__EXPERIMENTAL_Flag(path), attr);
}
}
return finalValue;
}
function fact(name, value) {
let finalValue = value;
if (factSchemaConfig) {
const segments = parsePath(name);
let success = true;
if (!isValidPath(factSchemaConfig, segments)) {
success = false;
} else {
try {
const pathSchema = buildSchemaForPath(factSchemaConfig, segments);
const nested = dotNotationToNested({ [name]: value });
const result = pathSchema.safeParse(nested);
if (!result.success) {
success = false;
} else {
finalValue = getValueAtPath(result.data, segments) ?? value;
}
} catch (_error) {
success = false;
}
}
if (!success) {
console.error(`[AxiomAI] Invalid fact: "${name}"`);
}
}
updateEvalContext(void 0, { [name]: finalValue });
const span = trace5.getActiveSpan();
if (span?.isRecording()) {
const attr = toOtelAttribute(finalValue);
if (attr) {
span.setAttribute(Attr.__EXPERIMENTAL_Fact(name), attr);
}
}
}
function overrideFlags(partial) {
const ctx = getEvalContext();
Object.assign(ctx.flags, partial);
}
function withFlags(overrides, fn) {
const ctx = getEvalContext();
const originalFlags = { ...ctx.flags };
Object.assign(ctx.flags, overrides);
try {
return fn();
} finally {
Object.keys(ctx.flags).forEach((key) => delete ctx.flags[key]);
Object.assign(ctx.flags, originalFlags);
}
}
const pickFlags = ((...args) => {
return args[0] && Array.isArray(args[0]) ? args[0] : args;
});
function flattenToDot(obj, prefix = [], out = {}) {
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
for (const [k, v] of Object.entries(obj)) {
flattenToDot(v, [...prefix, k], out);
}
} else {
if (prefix.length > 0) {
out[prefix.join(".")] = obj;
}
}
return out;
}
function getAllDefaultFlags() {
if (!flagSchemaConfig) return {};
const defaultsObj = buildObjectWithDefaults(flagSchemaConfig);
if (defaultsObj && typeof defaultsObj === "object") {
return flattenToDot(defaultsObj);
}
return {};
}
const scope = {
flag,
fact,
overrideFlags,
withFlags,
pickFlags,
getAllDefaultFlags
};
setConfigScope(scope);
return scope;
}
export {
setGlobalFlagOverrides,
getGlobalFlagOverrides,
formatZodErrors,
generateFlagExamples,
assertZodV4,
parsePath,
dotNotationToNested,
flattenObject,
isValidPath,
makeDeepPartial,
Attr,
createStartActiveSpan,
RedactionPolicy,
getRedactionPolicy,
handleMaybeRedactedAttribute,
initAxiomAI,
getGlobalTracer,
resetAxiomAI,
classifyToolError,
getTracer,
setScopeAttributes,
setAxiomBaseAttributes,
withSpan,
axiomAIMiddlewareV1,
axiomAIMiddleware,
axiomAIMiddlewareV2,
wrapAISDKModel,
createAppScope,
getAxiomConfig,
setAxiomConfig,
EVAL_CONTEXT,
getEvalContext,
putOnSpan,
withEvalContext,
getConfigScope
};
//# sourceMappingURL=chunk-PZCJLQFO.js.map