UNPKG

axiom

Version:

Axiom AI SDK provides - an API to wrap your AI calls with observability instrumentation. - offline evals - online evals

262 lines (256 loc) 8.24 kB
// src/otel/utils/redaction.ts import { context, propagation } from "@opentelemetry/api"; // src/otel/withSpanBaggageKey.ts 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 import { trace } from "@opentelemetry/api"; // package.json var package_default = { name: "axiom", version: "0.51.1", 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 && typedoc && pnpm check:vitest-entrypoints", "check:vitest-entrypoints": "node ./scripts/check-vitest-entrypoints.mjs", format: "prettier --write .", "format:check": "prettier --check .", lint: "eslint './**/*.{js,ts}'", typecheck: "tsc --noEmit", test: "vitest run", "test:watch": "vitest --watch", "test:wrangler-smoke": "pnpm build && vitest run --config vitest.smoke.config.ts", publint: "npx publint" }, types: "./dist/index.d.ts", main: "./dist/index.js", module: "./dist/index.js", bin: { axiom: "./dist/bin.js" }, exports: { "./ai": { types: "./dist/index.d.ts", default: "./dist/index.js" }, "./ai/evals": { types: "./dist/evals.d.ts", default: "./dist/evals.js" }, "./ai/evals/online": { types: "./dist/evals/online.d.ts", default: "./dist/evals/online.js" }, "./ai/scorers": { types: "./dist/scorers/scorers.d.ts", default: "./dist/scorers/scorers.js" }, "./ai/scorers/aggregations": { types: "./dist/scorers/aggregations.d.ts", default: "./dist/scorers/aggregations.js" }, "./ai/config": { types: "./dist/config.d.ts", default: "./dist/config.js" }, "./ai/feedback": { types: "./dist/feedback.d.ts", default: "./dist/feedback.js" } }, 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.38.0", "@sinclair/typebox": "^0.34.37", c12: "^3.3.3", 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", typescript: ">=5.4", zod: "^3.25.0 || ^4.0.0" }, peerDependenciesMeta: { typescript: { optional: true } }, devDependencies: { "@ai-sdk/anthropicv1": "npm:@ai-sdk/anthropic@^1.2.12", "@ai-sdk/anthropicv2": "npm:@ai-sdk/anthropic@^2.0.57", "@ai-sdk/anthropicv3": "npm:@ai-sdk/anthropic@^3.0.9", "@ai-sdk/openaiv1": "npm:@ai-sdk/openai@^1.3.24", "@ai-sdk/openaiv2": "npm:@ai-sdk/openai@^2.0.88", "@ai-sdk/openaiv3": "npm:@ai-sdk/openai@^3.0.7", "@ai-sdk/providerv1": "npm:@ai-sdk/provider@^1.1.3", "@ai-sdk/providerv2": "npm:@ai-sdk/provider@^2.0.1", "@ai-sdk/providerv3": "npm:@ai-sdk/provider@^3.0.2", "@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.118", aiv6: "npm:ai@^6.0.6", esbuild: "^0.25.8", eslint: "catalog:", msw: "^2.12.2", prettier: "catalog:", tinyrainbow: "^2.0.0", tsup: "catalog:", typedoc: "^0.28.17", "typedoc-plugin-markdown": "^4.10.0", 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; } export { WITHSPAN_BAGGAGE_KEY, WITHSPAN_REDACTION_POLICY_KEY, package_default, RedactionPolicy, getRedactionPolicy, handleMaybeRedactedAttribute, initAxiomAI, getGlobalTracer, resetAxiomAI }; //# sourceMappingURL=chunk-PU64TWX4.js.map