axiom
Version:
Axiom AI SDK provides an API to wrap your AI calls with observability instrumentation.
1 lines • 592 kB
Source Map (JSON)
{"version":3,"sources":["../src/evals.ts","../src/evals/eval.ts","../src/otel/semconv/attributes.ts","../src/otel/semconv/eval_proposal.ts","../src/otel/semconv/semconv_incubating.ts","../src/evals/instrument.ts","../src/evals/git-info.ts","../src/evals/reporter.ts"],"sourcesContent":["// Eval functionality - marked as UNSAFE as these APIs are experimental\nexport { Eval as experimental_Eval } from './evals/eval';\nexport type {\n EvalTask as experimental_EvalTask,\n EvalParams as experimental_EvalParams,\n EvalReport as experimental_EvalReport,\n} from './evals/eval.types';\n\nexport { AxiomReporter as experimental_AxiomReporter } from './evals/reporter';\n","import { afterAll, describe, it } from 'vitest';\nimport { context, SpanStatusCode, trace, type Context } from '@opentelemetry/api';\nimport { customAlphabet } from 'nanoid';\n\nimport { Attr } from '../otel/semconv/attributes';\nimport { startSpan, flush } from './instrument';\nimport { getGitUserInfo } from './git-info';\nimport type { CollectionRecord, EvalParams, EvalReport, EvalTask } from './eval.types';\nimport type { Score } from '../scorers/scorer.types';\n\ndeclare module 'vitest' {\n interface TaskMeta {\n eval?: EvalReport;\n }\n}\n\nconst DEFAULT_TIMEOUT = 10000;\n\nconst nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);\n\n/**\n * Creates and registers an evaluation suite with the given name and parameters.\n *\n * This function sets up a complete evaluation pipeline that will run your {@link EvalTask}\n * against a dataset, score the results, and provide detailed {@link EvalReport} reporting.\n *\n * @experimental This API is experimental and may change in future versions.\n *\n * @param name - Human-readable name for the evaluation suite\n * @param params - {@link EvalParams} configuration parameters for the evaluation\n *\n * @example\n * ```typescript\n * import { experimental_Eval as Eval } from 'axiom/ai/evals';\n *\n * Eval('Text Generation Quality', {\n * data: async () => [\n * { input: 'Explain photosynthesis', expected: 'Plants convert light to energy...' },\n * { input: 'What is gravity?', expected: 'Gravity is a fundamental force...' }\n * ],\n * task: async (input) => {\n * const result = await generateText({\n * model: yourModel,\n * prompt: input\n * });\n * return result.text;\n * },\n * scorers: [similarityScorer, factualAccuracyScorer],\n * threshold: 0.7\n * });\n * ```\n */\nexport const Eval = (name: string, params: EvalParams): void => {\n registerEval(name, params).catch(console.error);\n};\n\nasync function registerEval(\n evalName: string,\n opts: EvalParams,\n vitestOpts: { modifier?: 'only' | 'skip' } = {},\n) {\n const describeFn = vitestOpts.modifier === 'skip' ? describe.skip : describe;\n const datasetPromise = vitestOpts.modifier === 'skip' ? Promise.resolve([]) : opts.data();\n const user = getGitUserInfo();\n\n const result = await describeFn(\n evalName,\n async () => {\n const dataset = await datasetPromise;\n\n // ID must be returned after evaluation is registered at Axiom\n // TODO: send api request to register evaluation in Axiom\n const id = nanoid();\n\n const suiteSpan = startSpan(`eval ${evalName}-${id}`, {\n attributes: {\n [Attr.GenAI.Operation.Name]: 'eval',\n [Attr.Eval.ID]: id,\n [Attr.Eval.Name]: evalName,\n [Attr.Eval.Type]: 'regression', // TODO: where to get experiment type value from?\n [Attr.Eval.Tags]: [], // TODO: where to get experiment tags from?\n [Attr.Eval.Trials]: 1, // TODO: implement trials\n [Attr.Eval.Collection.Name]: 'unknown', // TODO: where to get dataset name from?\n [Attr.Eval.Collection.Split]: 'unknown', // TODO: where to get dataset split value from?\n [Attr.Eval.Collection.Size]: dataset.length,\n // user info\n [Attr.Eval.User.Name]: user?.name,\n [Attr.Eval.User.Email]: user?.email,\n },\n });\n const suiteContext = trace.setSpan(context.active(), suiteSpan);\n\n afterAll(async () => {\n const tags: string[] = ['offline'];\n suiteSpan.setAttribute(Attr.Eval.Tags, JSON.stringify(tags));\n\n // end root span\n suiteSpan.setStatus({ code: SpanStatusCode.OK });\n suiteSpan.end();\n await flush();\n });\n\n await it.concurrent.for(dataset.map((d, index) => ({ ...d, index })))(\n evalName,\n async (data: { index: number } & CollectionRecord, { task }) => {\n const caseName = data.name ?? `${evalName}_${data.index}`;\n const start = performance.now();\n const caseSpan = startSpan(\n `case ${caseName}`,\n {\n attributes: {\n [Attr.GenAI.Operation.Name]: 'eval.case',\n [Attr.Eval.Case.ID]: caseName,\n [Attr.Eval.Case.Index]: data.index,\n [Attr.Eval.Case.Input]:\n typeof data.input === 'string' ? data.input : JSON.stringify(data.input),\n [Attr.Eval.Case.Expected]:\n typeof data.expected === 'string' ? data.expected : JSON.stringify(data.expected),\n // user info\n ['eval.user.name']: user?.name,\n ['eval.user.email']: user?.email,\n },\n },\n suiteContext,\n );\n const caseContext = trace.setSpan(context.active(), caseSpan);\n\n try {\n const { output, duration } = await runTask(caseContext, {\n index: data.index,\n expected: data.expected,\n input: data.input,\n scorers: opts.scorers,\n task: opts.task,\n threshold: opts.threshold,\n });\n\n // run scorers\n const scoreList: Score[] = await Promise.all(\n opts.scorers.map(async (scorer) => {\n const scorerSpan = startSpan(\n `score ${scorer.name}`,\n {\n attributes: {\n [Attr.GenAI.Operation.Name]: 'eval.score',\n },\n },\n caseContext,\n );\n\n const start = performance.now();\n const result = await scorer({\n input: data.input,\n output,\n expected: data.expected,\n });\n\n const duration = Math.round(performance.now() - start);\n const scoreValue = result.score as number;\n const passed = scoreValue >= opts.threshold;\n let hasError: string | false = false;\n\n scorerSpan.setAttributes({\n [Attr.Eval.Score.Name]: scorer.name,\n [Attr.Eval.Score.Value]: scoreValue,\n [Attr.Eval.Score.Threshold]: opts.threshold,\n [Attr.Eval.Score.Passed]: passed,\n });\n\n if (!passed) {\n hasError = `Score didn't pass`;\n scorerSpan.setStatus({\n code: SpanStatusCode.ERROR,\n message: hasError,\n });\n } else {\n scorerSpan.setStatus({ code: SpanStatusCode.OK });\n }\n scorerSpan.end();\n\n return {\n ...result,\n metadata: { duration, startedAt: start, error: hasError || null },\n };\n }),\n );\n\n const scores = Object.fromEntries(scoreList.map((s) => [s.name, s]));\n\n // set case output\n caseSpan.setAttributes({\n [Attr.Eval.Case.Output]: typeof output === 'string' ? output : JSON.stringify(output),\n [Attr.Eval.Case.Scores]: JSON.stringify(scores),\n });\n caseSpan.setStatus({ code: SpanStatusCode.OK });\n\n task.meta.eval = {\n index: data.index,\n name: evalName,\n expected: data.expected,\n input: data.input,\n output: output as string,\n scores,\n status: 'success',\n errors: [],\n duration,\n startedAt: start,\n threshold: opts.threshold,\n };\n } catch (e) {\n caseSpan.recordException(e as Error);\n caseSpan.setStatus({ code: SpanStatusCode.ERROR });\n\n task.meta.eval = {\n name: evalName,\n index: data.index,\n expected: data.expected,\n input: data.input,\n output: e as string,\n scores: {},\n status: 'fail',\n errors: [e as any],\n startedAt: start,\n duration: Math.round(performance.now() - start),\n threshold: opts.threshold,\n };\n throw e;\n } finally {\n caseSpan.end();\n }\n },\n );\n },\n DEFAULT_TIMEOUT,\n );\n\n return result;\n}\n\nconst joinArrayOfUnknownResults = (results: unknown[]): unknown => {\n return results.reduce((acc, result) => {\n if (typeof result === 'string' || typeof result === 'number' || typeof result === 'boolean') {\n return `${acc}${result}`;\n }\n throw new Error(\n `Cannot display results of stream: stream contains non-string, non-number, non-boolean chunks.`,\n );\n }, '');\n};\n\nconst executeTask = async <TInput, TExpected, TOutput>(\n task: EvalTask<TInput, TExpected>,\n input: TInput,\n expected: TExpected,\n): Promise<TOutput> => {\n const taskResultOrStream = await task(input, expected);\n\n if (\n typeof taskResultOrStream === 'object' &&\n taskResultOrStream &&\n Symbol.asyncIterator in taskResultOrStream\n ) {\n const chunks: TOutput[] = [];\n\n for await (const chunk of taskResultOrStream) {\n chunks.push(chunk);\n }\n\n return joinArrayOfUnknownResults(chunks) as TOutput;\n }\n\n return taskResultOrStream;\n};\n\nconst runTask = async <TInput, TExpected>(\n caseContext: Context,\n opts: {\n index: number;\n input: TInput;\n expected: TExpected | undefined;\n threshold: number;\n } & Omit<EvalParams, 'data'>,\n) => {\n const taskName = opts.task.name ?? 'anonymous';\n // start task span\n const taskSpan = startSpan(\n `task`,\n {\n attributes: {\n [Attr.GenAI.Operation.Name]: 'eval.task',\n [Attr.Eval.Task.Name]: taskName,\n [Attr.Eval.Task.Type]: 'llm_completion', // TODO: How to determine task type?\n [Attr.Eval.Task.Trial]: 1,\n },\n },\n caseContext,\n );\n\n const { output, duration } = await context.with(\n trace.setSpan(context.active(), taskSpan),\n async () => {\n const start = performance.now();\n const output = await executeTask(opts.task, opts.input, opts.expected);\n const duration = Math.round(performance.now() - start);\n // set task output\n taskSpan.setAttributes({\n [Attr.Eval.Task.Output]: JSON.stringify(output),\n });\n\n taskSpan.setStatus({ code: SpanStatusCode.OK });\n taskSpan.end();\n\n return { output, duration };\n },\n );\n\n return {\n output,\n duration,\n };\n};\n","import {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n} from '@opentelemetry/semantic-conventions';\n\nimport {\n ATTR_EVAL_CASE_ID,\n ATTR_EVAL_CASE_INDEX,\n ATTR_EVAL_CASE_EXPECTED,\n ATTR_EVAL_CASE_INPUT,\n ATTR_EVAL_CASE_OUTPUT,\n ATTR_EVAL_CASE_METADATA,\n ATTR_EVAL_CASE_SCORES,\n ATTR_EVAL_SCORE_PASSED,\n ATTR_EVAL_SCORE_VALUE,\n ATTR_EVAL_SCORE_NAME,\n ATTR_EVAL_SCORE_THRESHOLD,\n ATTR_EVAL_SCORE_METADATA,\n ATTR_EVAL_TASK_TRIAL,\n ATTR_EVAL_TASK_TYPE,\n ATTR_EVAL_TASK_NAME,\n ATTR_EVAL_TASK_OUTPUT,\n ATTR_EVAL_COLLECTION_NAME,\n ATTR_EVAL_COLLECTION_SIZE,\n ATTR_EVAL_COLLECTION_SPLIT,\n ATTR_EVAL_ID,\n ATTR_EVAL_BASE_ID,\n ATTR_EVAL_BASE_NAME,\n ATTR_EVAL_NAME,\n ATTR_EVAL_TAGS,\n ATTR_EVAL_TRIALS,\n ATTR_EVAL_TYPE,\n ATTR_EVAL_VERSION,\n ATTR_EVAL_COLLECTION_ID,\n ATTR_EVAL_USER_NAME,\n ATTR_EVAL_USER_EMAIL,\n} from './eval_proposal';\n\nimport {\n ATTR_GEN_AI_USAGE_INPUT_TOKENS,\n ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,\n ATTR_GEN_AI_REQUEST_MODEL,\n ATTR_GEN_AI_RESPONSE_MODEL,\n ATTR_GEN_AI_OPERATION_NAME,\n GEN_AI_SYSTEM_VALUE_ANTHROPIC,\n GEN_AI_OPERATION_NAME_VALUE_CHAT,\n ATTR_GEN_AI_REQUEST_MAX_TOKENS,\n ATTR_GEN_AI_OUTPUT_TYPE,\n GEN_AI_OUTPUT_TYPE_VALUE_JSON,\n GEN_AI_OUTPUT_TYPE_VALUE_SPEECH,\n GEN_AI_OUTPUT_TYPE_VALUE_TEXT,\n GEN_AI_OUTPUT_TYPE_VALUE_IMAGE,\n ATTR_GEN_AI_SYSTEM,\n GEN_AI_SYSTEM_VALUE_OPENAI,\n GEN_AI_SYSTEM_VALUE_AWS_BEDROCK,\n GEN_AI_SYSTEM_VALUE_AZURE_AI_INFERENCE,\n GEN_AI_SYSTEM_VALUE_AZURE_AI_OPENAI,\n GEN_AI_SYSTEM_VALUE_COHERE,\n GEN_AI_SYSTEM_VALUE_DEEPSEEK,\n GEN_AI_SYSTEM_VALUE_GCP_GEMINI,\n GEN_AI_SYSTEM_VALUE_GCP_GEN_AI,\n GEN_AI_SYSTEM_VALUE_GCP_VERTEX_AI,\n GEN_AI_SYSTEM_VALUE_GROQ,\n GEN_AI_SYSTEM_VALUE_IBM_WATSONX_AI,\n GEN_AI_SYSTEM_VALUE_MISTRAL_AI,\n GEN_AI_SYSTEM_VALUE_PERPLEXITY,\n GEN_AI_SYSTEM_VALUE_XAI,\n ATTR_GEN_AI_RESPONSE_ID,\n ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY,\n ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY,\n ATTR_GEN_AI_REQUEST_TEMPERATURE,\n ATTR_GEN_AI_REQUEST_TOP_P,\n ATTR_GEN_AI_REQUEST_TOP_K,\n ATTR_GEN_AI_REQUEST_SEED,\n ATTR_GEN_AI_REQUEST_STOP_SEQUENCES,\n GEN_AI_OPERATION_NAME_VALUE_EXECUTE_TOOL,\n ATTR_GEN_AI_COMPLETION,\n ATTR_GEN_AI_PROMPT,\n ATTR_GEN_AI_TOOL_CALL_ID,\n ATTR_GEN_AI_TOOL_NAME,\n ATTR_GEN_AI_TOOL_TYPE,\n ATTR_GEN_AI_REQUEST_CHOICE_COUNT,\n ATTR_GEN_AI_RESPONSE_FINISH_REASONS,\n ATTR_GEN_AI_CONVERSATION_ID,\n ATTR_GEN_AI_TOOL_DESCRIPTION,\n ATTR_GEN_AI_DATA_SOURCE_ID,\n GEN_AI_OPERATION_NAME_VALUE_CREATE_AGENT,\n GEN_AI_OPERATION_NAME_VALUE_INVOKE_AGENT,\n GEN_AI_OPERATION_NAME_VALUE_EMBEDDINGS,\n GEN_AI_OPERATION_NAME_VALUE_GENERATE_CONTENT,\n ATTR_GEN_AI_AGENT_DESCRIPTION,\n ATTR_GEN_AI_AGENT_ID,\n ATTR_GEN_AI_AGENT_NAME,\n ATTR_GEN_AI_REQUEST_ENCODING_FORMATS,\n ATTR_ERROR_MESSAGE,\n} from './semconv_incubating';\n\nexport const SCHEMA_VERSION = '0.0.1';\nexport const SCHEMA_BASE_URL = 'https://axiom.co/ai/schemas/';\n\n/**\n * When adding something new here, please:\n * 1. Make sure it doesn't already exist as part of OTel Semantic Conventions (use that instead)\n * 2. Make sure to use standard naming schema, ie snake_case\n * 3. If a specific feature has an attribute you would like to use, extract it to the shared section\n *\n * Also Experimental Attributes should always be imported here and then used from the CustomAttributes object\n * because they are unstable.\n *\n * @see: https://github.com/open-telemetry/opentelemetry-js/tree/c89cb38d0fec39d54cf3fcb35c429a8129e9c909/semantic-conventions#unstable-semconv\n */\nexport const Attr = {\n Axiom: {\n GenAI: {\n SchemaURL: 'axiom.gen_ai.schema_url',\n SDK: {\n Name: 'axiom.gen_ai.sdk.name',\n Version: 'axiom.gen_ai.sdk.version',\n },\n },\n },\n GenAI: {\n PromptMetadata: {\n ID: 'axiom.gen_ai.prompt.id',\n Name: 'axiom.gen_ai.prompt.name',\n Slug: 'axiom.gen_ai.prompt.slug',\n Version: 'axiom.gen_ai.prompt.version',\n },\n /**\n * These two are used to identify the span\n */\n Capability: {\n Name: 'gen_ai.capability.name', // proprietary to axiom-ai\n },\n Step: {\n Name: 'gen_ai.step.name', // proprietary to axiom-ai\n },\n /**\n * Regular attributes\n */\n Agent: {\n Description: ATTR_GEN_AI_AGENT_DESCRIPTION, // not yet used by axiom-ai\n ID: ATTR_GEN_AI_AGENT_ID, // not yet used by axiom-ai\n Name: ATTR_GEN_AI_AGENT_NAME, // not yet used by axiom-ai\n },\n Completion: ATTR_GEN_AI_COMPLETION, // OTel suggests to use events API for this now\n Conversation: {\n ID: ATTR_GEN_AI_CONVERSATION_ID, // not yet used by axiom-ai, anyway probably needs to be provided by user\n },\n DataSource: {\n ID: ATTR_GEN_AI_DATA_SOURCE_ID, // not used in axiom-ai yet\n },\n Operation: {\n Name: ATTR_GEN_AI_OPERATION_NAME,\n Name_Values: {\n /**\n * Note that \"text_completion\" is deprecated in favor of \"chat\" for both OpenAI and Anthropic\n */\n Chat: GEN_AI_OPERATION_NAME_VALUE_CHAT,\n CreateAgent: GEN_AI_OPERATION_NAME_VALUE_CREATE_AGENT,\n Embeddings: GEN_AI_OPERATION_NAME_VALUE_EMBEDDINGS,\n ExecuteTool: GEN_AI_OPERATION_NAME_VALUE_EXECUTE_TOOL,\n GenerateContent: GEN_AI_OPERATION_NAME_VALUE_GENERATE_CONTENT,\n InvokeAgent: GEN_AI_OPERATION_NAME_VALUE_INVOKE_AGENT,\n },\n },\n Output: {\n Type: ATTR_GEN_AI_OUTPUT_TYPE,\n Type_Values: {\n Text: GEN_AI_OUTPUT_TYPE_VALUE_TEXT,\n Json: GEN_AI_OUTPUT_TYPE_VALUE_JSON,\n Image: GEN_AI_OUTPUT_TYPE_VALUE_IMAGE,\n Speech: GEN_AI_OUTPUT_TYPE_VALUE_SPEECH,\n },\n },\n /**\n * The provider that is hosting the model, eg AWS Bedrock\n * There doesn't seem to be a semconv for this\n */\n Prompt: ATTR_GEN_AI_PROMPT, // OTel suggests to use the events api for this\n Request: {\n ChoiceCount: ATTR_GEN_AI_REQUEST_CHOICE_COUNT, // not yet used by axiom-ai\n EncodingFormats: ATTR_GEN_AI_REQUEST_ENCODING_FORMATS, // not yet used by axiom-ai\n FrequencyPenalty: ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY,\n MaxTokens: ATTR_GEN_AI_REQUEST_MAX_TOKENS,\n /**\n * The model you asked for\n */\n Model: ATTR_GEN_AI_REQUEST_MODEL,\n PresencePenalty: ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY,\n Seed: ATTR_GEN_AI_REQUEST_SEED,\n StopSequences: ATTR_GEN_AI_REQUEST_STOP_SEQUENCES,\n Temperature: ATTR_GEN_AI_REQUEST_TEMPERATURE,\n TopK: ATTR_GEN_AI_REQUEST_TOP_K,\n TopP: ATTR_GEN_AI_REQUEST_TOP_P,\n },\n Response: {\n FinishReasons: ATTR_GEN_AI_RESPONSE_FINISH_REASONS,\n ID: ATTR_GEN_AI_RESPONSE_ID,\n /**\n * The model that was actually used (might be different bc routing) - only ever get this from the response, otherwise omit\n */\n Model: ATTR_GEN_AI_RESPONSE_MODEL, // somehow not landing on the span for google models? check up on this...\n },\n /**\n * From OTel docs:\n * ```\n * Multiple systems, including Azure OpenAI and Gemini, are accessible\n * by OpenAI client libraries. In such cases, the gen_ai.system is set\n * to openai based on the instrumentation's best knowledge, instead of\n * the actual system.\n * ```\n */\n System: ATTR_GEN_AI_SYSTEM, // not yet used by axiom-ai\n System_Values: {\n Anthropic: GEN_AI_SYSTEM_VALUE_ANTHROPIC,\n AWSBedrock: GEN_AI_SYSTEM_VALUE_AWS_BEDROCK,\n AzureAIInference: GEN_AI_SYSTEM_VALUE_AZURE_AI_INFERENCE,\n AzureAIOpenAI: GEN_AI_SYSTEM_VALUE_AZURE_AI_OPENAI,\n Cohere: GEN_AI_SYSTEM_VALUE_COHERE,\n Deepseek: GEN_AI_SYSTEM_VALUE_DEEPSEEK,\n GCPGemini: GEN_AI_SYSTEM_VALUE_GCP_GEMINI,\n GCPGenAI: GEN_AI_SYSTEM_VALUE_GCP_GEN_AI,\n GCPVertexAI: GEN_AI_SYSTEM_VALUE_GCP_VERTEX_AI,\n Groq: GEN_AI_SYSTEM_VALUE_GROQ,\n IBMWatsonxAI: GEN_AI_SYSTEM_VALUE_IBM_WATSONX_AI,\n MistralAI: GEN_AI_SYSTEM_VALUE_MISTRAL_AI,\n OpenAI: GEN_AI_SYSTEM_VALUE_OPENAI,\n Perplexity: GEN_AI_SYSTEM_VALUE_PERPLEXITY,\n XAI: GEN_AI_SYSTEM_VALUE_XAI,\n },\n Tool: {\n CallID: ATTR_GEN_AI_TOOL_CALL_ID,\n Description: ATTR_GEN_AI_TOOL_DESCRIPTION,\n Name: ATTR_GEN_AI_TOOL_NAME,\n Type: ATTR_GEN_AI_TOOL_TYPE,\n /**\n * Note, OTel Semantic Convention puts these on `gen_ai.choice` events\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-events/#event-gen_aichoice\n */\n Arguments: 'gen_ai.tool.arguments',\n /**\n * Note, OTel Semantic Convention puts these on `gen_ai.tool.message` events\n */\n Message: 'gen_ai.tool.message',\n },\n Usage: {\n InputTokens: ATTR_GEN_AI_USAGE_INPUT_TOKENS,\n OutputTokens: ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,\n },\n },\n Eval: {\n ID: ATTR_EVAL_ID,\n Name: ATTR_EVAL_NAME,\n Type: ATTR_EVAL_TYPE,\n Version: ATTR_EVAL_VERSION,\n BaseID: ATTR_EVAL_BASE_ID,\n BaseName: ATTR_EVAL_BASE_NAME,\n Trials: ATTR_EVAL_TRIALS,\n Tags: ATTR_EVAL_TAGS,\n Collection: {\n ID: ATTR_EVAL_COLLECTION_ID,\n Name: ATTR_EVAL_COLLECTION_NAME,\n Split: ATTR_EVAL_COLLECTION_SPLIT,\n Size: ATTR_EVAL_COLLECTION_SIZE,\n },\n Case: {\n ID: ATTR_EVAL_CASE_ID,\n Index: ATTR_EVAL_CASE_INDEX,\n Input: ATTR_EVAL_CASE_INPUT,\n Output: ATTR_EVAL_CASE_OUTPUT,\n Expected: ATTR_EVAL_CASE_EXPECTED,\n Scores: ATTR_EVAL_CASE_SCORES,\n Metadata: ATTR_EVAL_CASE_METADATA,\n },\n Task: {\n Output: ATTR_EVAL_TASK_OUTPUT,\n Name: ATTR_EVAL_TASK_NAME,\n Type: ATTR_EVAL_TASK_TYPE,\n Trial: ATTR_EVAL_TASK_TRIAL,\n },\n Score: {\n Name: ATTR_EVAL_SCORE_NAME,\n Value: ATTR_EVAL_SCORE_VALUE,\n Threshold: ATTR_EVAL_SCORE_THRESHOLD,\n Passed: ATTR_EVAL_SCORE_PASSED,\n Metadata: ATTR_EVAL_SCORE_METADATA,\n },\n User: {\n Name: ATTR_EVAL_USER_NAME,\n Email: ATTR_EVAL_USER_EMAIL,\n },\n },\n Error: {\n Type: ATTR_ERROR_TYPE,\n Message: ATTR_ERROR_MESSAGE,\n },\n HTTP: {\n Response: {\n StatusCode: ATTR_HTTP_RESPONSE_STATUS_CODE,\n },\n },\n} as const;\n","// experiment\nexport const ATTR_EVAL_ID = 'eval.id' as const;\nexport const ATTR_EVAL_NAME = 'eval.name' as const;\nexport const ATTR_EVAL_TYPE = 'eval.type' as const;\nexport const ATTR_EVAL_TAGS = 'eval.tags' as const;\nexport const ATTR_EVAL_VERSION = 'eval.version' as const;\nexport const ATTR_EVAL_TRIALS = 'eval.trials' as const;\nexport const ATTR_EVAL_BASE_ID = 'eval.base_id' as const;\nexport const ATTR_EVAL_BASE_NAME = 'eval.base_name' as const;\n// collection\nexport const ATTR_EVAL_COLLECTION_ID = 'eval.collection.id' as const;\nexport const ATTR_EVAL_COLLECTION_SIZE = 'eval.collection.size' as const;\nexport const ATTR_EVAL_COLLECTION_NAME = 'eval.collection.name' as const;\nexport const ATTR_EVAL_COLLECTION_SPLIT = 'eval.collection.split' as const;\n// case\nexport const ATTR_EVAL_CASE_ID = 'eval.case.id' as const;\nexport const ATTR_EVAL_CASE_INDEX = 'eval.case.index' as const;\nexport const ATTR_EVAL_CASE_INPUT = 'eval.case.input' as const;\nexport const ATTR_EVAL_CASE_OUTPUT = 'eval.case.output' as const;\nexport const ATTR_EVAL_CASE_EXPECTED = 'eval.case.expected' as const;\nexport const ATTR_EVAL_CASE_SCORES = 'eval.case.scores' as const;\nexport const ATTR_EVAL_CASE_METADATA = 'eval.case.metadata' as const;\n// task\nexport const ATTR_EVAL_TASK_OUTPUT = 'eval.task.output' as const;\nexport const ATTR_EVAL_TASK_NAME = 'eval.task.name' as const;\nexport const ATTR_EVAL_TASK_TYPE = 'eval.task.type' as const;\nexport const ATTR_EVAL_TASK_TRIAL = 'eval.task.trial' as const;\n// score\nexport const ATTR_EVAL_SCORE_NAME = 'eval.score.name' as const;\nexport const ATTR_EVAL_SCORE_VALUE = 'eval.score.value' as const;\nexport const ATTR_EVAL_SCORE_THRESHOLD = 'eval.score.threshold' as const;\nexport const ATTR_EVAL_SCORE_PASSED = 'eval.score.passed' as const;\nexport const ATTR_EVAL_SCORE_SCORER = 'eval.score.scorer' as const;\nexport const ATTR_EVAL_SCORE_METADATA = 'eval.score.metadata' as const;\n// user\nexport const ATTR_EVAL_USER_NAME = 'eval.user.name';\nexport const ATTR_EVAL_USER_EMAIL = 'eval.user.email';\n","/**\n * ==========================================================================================================\n * 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 AXIOM NOTE 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨\n * ==========================================================================================================\n * This is copy/pasted from the `@opentelemetry/semantic-conventions` package.\n * Because incubating semantic conventions are no longer experted.\n *\n * Currently at 1.36.0\n *\n * @see: https://github.com/open-telemetry/opentelemetry-js/blob/main/semantic-conventions/src/experimental_attributes.ts\n * ==========================================================================================================\n * 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 AXIOM NOTE 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨\n * ==========================================================================================================\n */\n\n/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//----------------------------------------------------------------------------------------------------------\n// DO NOT EDIT, this is an Auto-generated file from scripts/semconv/templates/registry/stable/attributes.ts.j2\n//----------------------------------------------------------------------------------------------------------\n\n/**\n * This attribute represents the state of the application.\n *\n * @example created\n *\n * @note The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ANDROID_APP_STATE = 'android.app.state' as const;\n\n/**\n * Enum value \"background\" for attribute {@link ATTR_ANDROID_APP_STATE}.\n *\n * Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state.\n *\n * @experimental This enum value is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ANDROID_APP_STATE_VALUE_BACKGROUND = 'background' as const;\n\n/**\n * Enum value \"created\" for attribute {@link ATTR_ANDROID_APP_STATE}.\n *\n * Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time.\n *\n * @experimental This enum value is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ANDROID_APP_STATE_VALUE_CREATED = 'created' as const;\n\n/**\n * Enum value \"foreground\" for attribute {@link ATTR_ANDROID_APP_STATE}.\n *\n * Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states.\n *\n * @experimental This enum value is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ANDROID_APP_STATE_VALUE_FOREGROUND = 'foreground' as const;\n\n/**\n * Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels).\n *\n * @example 33\n * @example 32\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ANDROID_OS_API_LEVEL = 'android.os.api_level' as const;\n\n/**\n * Deprecated. Use `android.app.state` body field instead.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n *\n * @deprecated Use `android.app.state` body field instead.\n */\nexport const ATTR_ANDROID_STATE = 'android.state' as const;\n\n/**\n * Enum value \"background\" for attribute {@link ATTR_ANDROID_STATE}.\n *\n * Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state.\n *\n * @experimental This enum value is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ANDROID_STATE_VALUE_BACKGROUND = 'background' as const;\n\n/**\n * Enum value \"created\" for attribute {@link ATTR_ANDROID_STATE}.\n *\n * Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time.\n *\n * @experimental This enum value is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ANDROID_STATE_VALUE_CREATED = 'created' as const;\n\n/**\n * Enum value \"foreground\" for attribute {@link ATTR_ANDROID_STATE}.\n *\n * Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states.\n *\n * @experimental This enum value is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ANDROID_STATE_VALUE_FOREGROUND = 'foreground' as const;\n\n/**\n * A unique identifier representing the installation of an application on a specific device\n *\n * @example 2ab2916d-a51f-4ac8-80ee-45ac31a28092\n *\n * @note Its value **SHOULD** persist across launches of the same application installation, including through application upgrades.\n * It **SHOULD** change if the application is uninstalled or if all applications of the vendor are uninstalled.\n * Additionally, users might be able to reset this value (e.g. by clearing application data).\n * If an app is installed multiple times on the same device (e.g. in different accounts on Android), each `app.installation.id` **SHOULD** have a different value.\n * If multiple OpenTelemetry SDKs are used within the same application, they **SHOULD** use the same value for `app.installation.id`.\n * Hardware IDs (e.g. serial number, IMEI, MAC address) **MUST NOT** be used as the `app.installation.id`.\n *\n * For iOS, this value **SHOULD** be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor).\n *\n * For Android, examples of `app.installation.id` implementations include:\n *\n * - [Firebase Installation ID](https://firebase.google.com/docs/projects/manage-installations).\n * - A globally unique UUID which is persisted across sessions in your application.\n * - [App set ID](https://developer.android.com/identity/app-set-id).\n * - [`Settings.getString(Settings.Secure.ANDROID_ID)`](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID).\n *\n * More information about Android identifier best practices can be found [here](https://developer.android.com/training/articles/user-data-ids).\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_APP_INSTALLATION_ID = 'app.installation.id' as const;\n\n/**\n * The x (horizontal) coordinate of a screen coordinate, in screen pixels.\n *\n * @example 0\n * @example 131\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_APP_SCREEN_COORDINATE_X = 'app.screen.coordinate.x' as const;\n\n/**\n * The y (vertical) component of a screen coordinate, in screen pixels.\n *\n * @example 12\n * @example 99\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_APP_SCREEN_COORDINATE_Y = 'app.screen.coordinate.y' as const;\n\n/**\n * An identifier that uniquely differentiates this widget from other widgets in the same application.\n *\n * @example f9bc787d-ff05-48ad-90e1-fca1d46130b3\n * @example submit_order_1829\n *\n * @note A widget is an application component, typically an on-screen visual GUI element.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_APP_WIDGET_ID = 'app.widget.id' as const;\n\n/**\n * The name of an application widget.\n *\n * @example submit\n * @example attack\n * @example Clear Cart\n *\n * @note A widget is an application component, typically an on-screen visual GUI element.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_APP_WIDGET_NAME = 'app.widget.name' as const;\n\n/**\n * The provenance filename of the built attestation which directly relates to the build artifact filename. This filename **SHOULD** accompany the artifact at publish time. See the [SLSA Relationship](https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations) specification for more information.\n *\n * @example golang-binary-amd64-v0.1.0.attestation\n * @example docker-image-amd64-v0.1.0.intoto.json1\n * @example release-1.tar.gz.attestation\n * @example file-name-package.tar.gz.intoto.json1\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ARTIFACT_ATTESTATION_FILENAME = 'artifact.attestation.filename' as const;\n\n/**\n * The full [hash value (see glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), of the built attestation. Some envelopes in the [software attestation space](https://github.com/in-toto/attestation/tree/main/spec) also refer to this as the **digest**.\n *\n * @example 1b31dfcd5b7f9267bf2ff47651df1cfb9147b9e4df1f335accf65b4cda498408\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ARTIFACT_ATTESTATION_HASH = 'artifact.attestation.hash' as const;\n\n/**\n * The id of the build [software attestation](https://slsa.dev/attestation-model).\n *\n * @example 123\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ARTIFACT_ATTESTATION_ID = 'artifact.attestation.id' as const;\n\n/**\n * The human readable file name of the artifact, typically generated during build and release processes. Often includes the package name and version in the file name.\n *\n * @example golang-binary-amd64-v0.1.0\n * @example docker-image-amd64-v0.1.0\n * @example release-1.tar.gz\n * @example file-name-package.tar.gz\n *\n * @note This file name can also act as the [Package Name](https://slsa.dev/spec/v1.0/terminology#package-model)\n * in cases where the package ecosystem maps accordingly.\n * Additionally, the artifact [can be published](https://slsa.dev/spec/v1.0/terminology#software-supply-chain)\n * for others, but that is not a guarantee.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ARTIFACT_FILENAME = 'artifact.filename' as const;\n\n/**\n * The full [hash value (see glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), often found in checksum.txt on a release of the artifact and used to verify package integrity.\n *\n * @example 9ff4c52759e2c4ac70b7d517bc7fcdc1cda631ca0045271ddd1b192544f8a3e9\n *\n * @note The specific algorithm used to create the cryptographic hash value is\n * not defined. In situations where an artifact has multiple\n * cryptographic hashes, it is up to the implementer to choose which\n * hash value to set here; this should be the most secure hash algorithm\n * that is suitable for the situation and consistent with the\n * corresponding attestation. The implementer can then provide the other\n * hash values through an additional set of attribute extensions as they\n * deem necessary.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ARTIFACT_HASH = 'artifact.hash' as const;\n\n/**\n * The [Package URL](https://github.com/package-url/purl-spec) of the [package artifact](https://slsa.dev/spec/v1.0/terminology#package-model) provides a standard way to identify and locate the packaged artifact.\n *\n * @example pkg:github/package-url/purl-spec@1209109710924\n * @example pkg:npm/foo@12.12.3\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ARTIFACT_PURL = 'artifact.purl' as const;\n\n/**\n * The version of the artifact.\n *\n * @example v0.1.0\n * @example 1.2.1\n * @example 122691-build\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_ARTIFACT_VERSION = 'artifact.version' as const;\n\n/**\n * The unique identifier of the AWS Bedrock Guardrail. A [guardrail](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) helps safeguard and prevent unwanted behavior from model responses or user messages.\n *\n * @example sgi5gkybzqak\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_BEDROCK_GUARDRAIL_ID = 'aws.bedrock.guardrail.id' as const;\n\n/**\n * The unique identifier of the AWS Bedrock Knowledge base. A [knowledge base](https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html) is a bank of information that can be queried by models to generate more relevant responses and augment prompts.\n *\n * @example XFWUPB9PAW\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_BEDROCK_KNOWLEDGE_BASE_ID = 'aws.bedrock.knowledge_base.id' as const;\n\n/**\n * The JSON-serialized value of each item in the `AttributeDefinitions` request field.\n *\n * @example [\"{ \"AttributeName\": \"string\", \"AttributeType\": \"string\" }\"]\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS =\n 'aws.dynamodb.attribute_definitions' as const;\n\n/**\n * The value of the `AttributesToGet` request parameter.\n *\n * @example [\"lives\", \"id\"]\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_ATTRIBUTES_TO_GET = 'aws.dynamodb.attributes_to_get' as const;\n\n/**\n * The value of the `ConsistentRead` request parameter.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_CONSISTENT_READ = 'aws.dynamodb.consistent_read' as const;\n\n/**\n * The JSON-serialized value of each item in the `ConsumedCapacity` response field.\n *\n * @example [\"{ \"CapacityUnits\": number, \"GlobalSecondaryIndexes\": { \"string\" : { \"CapacityUnits\": number, \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } }, \"LocalSecondaryIndexes\": { \"string\" : { \"CapacityUnits\": number, \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } }, \"ReadCapacityUnits\": number, \"Table\": { \"CapacityUnits\": number, \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number }, \"TableName\": \"string\", \"WriteCapacityUnits\": number }\"]\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_CONSUMED_CAPACITY = 'aws.dynamodb.consumed_capacity' as const;\n\n/**\n * The value of the `Count` response parameter.\n *\n * @example 10\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_COUNT = 'aws.dynamodb.count' as const;\n\n/**\n * The value of the `ExclusiveStartTableName` request parameter.\n *\n * @example Users\n * @example CatsTable\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_EXCLUSIVE_START_TABLE =\n 'aws.dynamodb.exclusive_start_table' as const;\n\n/**\n * The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field.\n *\n * @example [\"{ \"Create\": { \"IndexName\": \"string\", \"KeySchema\": [ { \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" }, \"ProvisionedThroughput\": { \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } }\"]\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES =\n 'aws.dynamodb.global_secondary_index_updates' as const;\n\n/**\n * The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field\n *\n * @example [\"{ \"IndexName\": \"string\", \"KeySchema\": [ { \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" }, \"ProvisionedThroughput\": { \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } }\"]\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES =\n 'aws.dynamodb.global_secondary_indexes' as const;\n\n/**\n * The value of the `IndexName` request parameter.\n *\n * @example name_to_group\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_INDEX_NAME = 'aws.dynamodb.index_name' as const;\n\n/**\n * The JSON-serialized value of the `ItemCollectionMetrics` response field.\n *\n * @example { \"string\" : [ { \"ItemCollectionKey\": { \"string\" : { \"B\": blob, \"BOOL\": boolean, \"BS\": [ blob ], \"L\": [ \"AttributeValue\" ], \"M\": { \"string\" : \"AttributeValue\" }, \"N\": \"string\", \"NS\": [ \"string\" ], \"NULL\": boolean, \"S\": \"string\", \"SS\": [ \"string\" ] } }, \"SizeEstimateRangeGB\": [ number ] } ] }\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_ITEM_COLLECTION_METRICS =\n 'aws.dynamodb.item_collection_metrics' as const;\n\n/**\n * The value of the `Limit` request parameter.\n *\n * @example 10\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_LIMIT = 'aws.dynamodb.limit' as const;\n\n/**\n * The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field.\n *\n * @example [\"{ \"IndexArn\": \"string\", \"IndexName\": \"string\", \"IndexSizeBytes\": number, \"ItemCount\": number, \"KeySchema\": [ { \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" } }\"]\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES =\n 'aws.dynamodb.local_secondary_indexes' as const;\n\n/**\n * The value of the `ProjectionExpression` request parameter.\n *\n * @example Title\n * @example Title, Price, Color\n * @example Title, Description, RelatedItems, ProductReviews\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_PROJECTION = 'aws.dynamodb.projection' as const;\n\n/**\n * The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter.\n *\n * @example 1.0\n * @example 2.0\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_PROVISIONED_READ_CAPACITY =\n 'aws.dynamodb.provisioned_read_capacity' as const;\n\n/**\n * The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter.\n *\n * @example 1.0\n * @example 2.0\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY =\n 'aws.dynamodb.provisioned_write_capacity' as const;\n\n/**\n * The value of the `ScanIndexForward` request parameter.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_SCAN_FORWARD = 'aws.dynamodb.scan_forward' as const;\n\n/**\n * The value of the `ScannedCount` response parameter.\n *\n * @example 50\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_SCANNED_COUNT = 'aws.dynamodb.scanned_count' as const;\n\n/**\n * The value of the `Segment` request parameter.\n *\n * @example 10\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_SEGMENT = 'aws.dynamodb.segment' as const;\n\n/**\n * The value of the `Select` request parameter.\n *\n * @example ALL_ATTRIBUTES\n * @example COUNT\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_SELECT = 'aws.dynamodb.select' as const;\n\n/**\n * The number of items in the `TableNames` response parameter.\n *\n * @example 20\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_TABLE_COUNT = 'aws.dynamodb.table_count' as const;\n\n/**\n * The keys in the `RequestItems` object field.\n *\n * @example [\"Users\", \"Cats\"]\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_TABLE_NAMES = 'aws.dynamodb.table_names' as const;\n\n/**\n * The value of the `TotalSegments` request parameter.\n *\n * @example 100\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_DYNAMODB_TOTAL_SEGMENTS = 'aws.dynamodb.total_segments' as const;\n\n/**\n * The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html).\n *\n * @example arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_ECS_CLUSTER_ARN = 'aws.ecs.cluster.arn' as const;\n\n/**\n * The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).\n *\n * @example arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_ECS_CONTAINER_ARN = 'aws.ecs.container.arn' as const;\n\n/**\n * The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task.\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_AWS_ECS_LAUNCHTYPE = 'aws.ecs.launchtype' as const;\n\n/**\n * Enum value \"ec2\" for attribute {@link ATTR_AWS_ECS_LAUNCHTYPE}.\n *\n * @experimental This enum value is experimental and is subject to breaking changes in minor releases of `@opentelemetry/s