Path: blob/main/extensions/copilot/src/platform/otel/common/genAiAttributes.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45// gen_ai.operation.name values6export const GenAiOperationName = {7CHAT: 'chat',8INVOKE_AGENT: 'invoke_agent',9EXECUTE_TOOL: 'execute_tool',10EMBEDDINGS: 'embeddings',11/** Extension-specific: standalone markdown content event */12CONTENT_EVENT: 'content_event',13/** Extension-specific: hook command execution */14EXECUTE_HOOK: 'execute_hook',15} as const;1617// gen_ai.provider.name values18export const GenAiProviderName = {19GITHUB: 'github',20OPENAI: 'openai',21ANTHROPIC: 'anthropic',22AZURE_AI_OPENAI: 'azure.ai.openai',23GEMINI: 'gemini',24} as const;2526// gen_ai.token.type values27export const GenAiTokenType = {28INPUT: 'input',29OUTPUT: 'output',30} as const;3132// gen_ai.tool.type values33export const GenAiToolType = {34FUNCTION: 'function',35EXTENSION: 'extension',36} as const;3738/**39* OTel GenAI semantic convention attribute keys.40* @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md41*/42export const GenAiAttr = {43// Core44OPERATION_NAME: 'gen_ai.operation.name',45PROVIDER_NAME: 'gen_ai.provider.name',4647// Request48REQUEST_MODEL: 'gen_ai.request.model',49REQUEST_TEMPERATURE: 'gen_ai.request.temperature',50REQUEST_MAX_TOKENS: 'gen_ai.request.max_tokens',51REQUEST_TOP_P: 'gen_ai.request.top_p',52REQUEST_FREQUENCY_PENALTY: 'gen_ai.request.frequency_penalty',53REQUEST_PRESENCE_PENALTY: 'gen_ai.request.presence_penalty',54REQUEST_SEED: 'gen_ai.request.seed',55REQUEST_STOP_SEQUENCES: 'gen_ai.request.stop_sequences',5657// Response58RESPONSE_MODEL: 'gen_ai.response.model',59RESPONSE_ID: 'gen_ai.response.id',60RESPONSE_FINISH_REASONS: 'gen_ai.response.finish_reasons',6162// Usage63USAGE_INPUT_TOKENS: 'gen_ai.usage.input_tokens',64USAGE_OUTPUT_TOKENS: 'gen_ai.usage.output_tokens',65USAGE_CACHE_READ_INPUT_TOKENS: 'gen_ai.usage.cache_read.input_tokens',66USAGE_CACHE_CREATION_INPUT_TOKENS: 'gen_ai.usage.cache_creation.input_tokens',67/** Custom: reasoning/thinking token count (not yet standardized in GenAI conventions) */68USAGE_REASONING_TOKENS: 'gen_ai.usage.reasoning_tokens',6970// Conversation71CONVERSATION_ID: 'gen_ai.conversation.id',72OUTPUT_TYPE: 'gen_ai.output.type',7374// Token type (for metrics)75TOKEN_TYPE: 'gen_ai.token.type',7677// Agent78AGENT_NAME: 'gen_ai.agent.name',79AGENT_ID: 'gen_ai.agent.id',80AGENT_VERSION: 'gen_ai.agent.version',81AGENT_DESCRIPTION: 'gen_ai.agent.description',8283// Tool84TOOL_NAME: 'gen_ai.tool.name',85TOOL_TYPE: 'gen_ai.tool.type',86TOOL_CALL_ID: 'gen_ai.tool.call.id',87TOOL_DESCRIPTION: 'gen_ai.tool.description',88TOOL_CALL_ARGUMENTS: 'gen_ai.tool.call.arguments',89TOOL_CALL_RESULT: 'gen_ai.tool.call.result',9091// Content (opt-in)92INPUT_MESSAGES: 'gen_ai.input.messages',93OUTPUT_MESSAGES: 'gen_ai.output.messages',94SYSTEM_INSTRUCTIONS: 'gen_ai.system_instructions',95TOOL_DEFINITIONS: 'gen_ai.tool.definitions',96} as const;9798/**99* Extension-specific attribute keys (custom namespace).100*/101export const CopilotChatAttr = {102LOCATION: 'copilot_chat.location',103INTENT: 'copilot_chat.intent',104TURN_INDEX: 'copilot_chat.turn.index',105TURN_COUNT: 'copilot_chat.turn_count',106TOOL_CALL_ROUND: 'copilot_chat.tool_call_round',107API_TYPE: 'copilot_chat.api_type',108FETCHER: 'copilot_chat.fetcher',109DEBUG_NAME: 'copilot_chat.debug_name',110ENDPOINT_TYPE: 'copilot_chat.endpoint_type',111MAX_PROMPT_TOKENS: 'copilot_chat.request.max_prompt_tokens',112TIME_TO_FIRST_TOKEN: 'copilot_chat.time_to_first_token',113SESSION_ID: 'copilot_chat.session_id',114SERVER_REQUEST_ID: 'copilot_chat.server_request_id',115CANCELED: 'copilot_chat.canceled',116/** Extended thinking/reasoning content (content-gated) */117REASONING_CONTENT: 'copilot_chat.reasoning_content',118/** User's actual typed message text, extracted from prompt context */119USER_REQUEST: 'copilot_chat.user_request',120/** Resolved context section (code snippets, file contents, etc.) */121PROMPT_CONTEXT: 'copilot_chat.prompt_context',122/** Custom instructions section */123PROMPT_INSTRUCTIONS: 'copilot_chat.prompt_instructions',124/** VS Code chat session ID from CapturingToken — the definitive session identifier */125CHAT_SESSION_ID: 'copilot_chat.chat_session_id',126/** Parent chat session ID for linking child sessions (e.g., title, categorization) to their parent */127PARENT_CHAT_SESSION_ID: 'copilot_chat.parent_chat_session_id',128/** Debug log label for child sessions (e.g., 'title', 'categorization', 'runSubagent') */129DEBUG_LOG_LABEL: 'copilot_chat.debug_log_label',130/** Markdown content for standalone content events */131MARKDOWN_CONTENT: 'copilot_chat.markdown_content',132/** Edit source: inline_chat, chat_editing, chat_editing_hunk, apply_patch, replace_string, code_mapper */133EDIT_SOURCE: 'copilot_chat.edit.source',134/** Edit outcome: accepted, rejected, saved, unknown */135EDIT_OUTCOME: 'copilot_chat.edit.outcome',136/** Language identifier of the document */137LANGUAGE_ID: 'copilot_chat.language_id',138/** Time delay in milliseconds between acceptance and measurement */139TIME_DELAY_MS: 'copilot_chat.time_delay_ms',140/** Whether additional unactioned edits remain */141HAS_REMAINING_EDITS: 'copilot_chat.has_remaining_edits',142/** Git branch name (HEAD) */143REPO_HEAD_BRANCH_NAME: 'copilot_chat.repo.head_branch_name',144/** Git commit hash (HEAD) */145REPO_HEAD_COMMIT_HASH: 'copilot_chat.repo.head_commit_hash',146/** Normalized remote fetch URL */147REPO_REMOTE_URL: 'copilot_chat.repo.remote_url',148/** File path relative to the repository root */149FILE_RELATIVE_PATH: 'copilot_chat.file.relative_path',150/** Hook type / event name (e.g. PreToolUse, PostToolUse, Stop) */151HOOK_TYPE: 'copilot_chat.hook_type',152/** Serialized hook command input (truncated; emitters may or may not gate on captureContent — used by the Agent Debug Log panel) */153HOOK_INPUT: 'copilot_chat.hook_input',154/** Serialized hook command output (truncated; emitters may or may not gate on captureContent — used by the Agent Debug Log panel) */155HOOK_OUTPUT: 'copilot_chat.hook_output',156/** Hook result kind: 'success', 'error', or 'non_blocking_error' */157HOOK_RESULT_KIND: 'copilot_chat.hook_result_kind',158/** Custom chat mode name (when a custom mode is active) */159MODE_NAME: 'copilot_chat.mode_name',160/** Aggregated session cost in USD (Claude agent) */161TOTAL_COST_USD: 'copilot_chat.total_cost_usd',162} as const;163164export type EditSource = 'inline_chat' | 'chat_editing' | 'chat_editing_hunk' | 'apply_patch' | 'replace_string' | 'code_mapper';165export type EditOutcome = 'accepted' | 'rejected' | 'saved' | 'unknown';166167/**168* Standard OTel attributes used alongside GenAI attributes.169*/170export const StdAttr = {171ERROR_TYPE: 'error.type',172SERVER_ADDRESS: 'server.address',173SERVER_PORT: 'server.port',174} as const;175176/**177* Attribute keys emitted by the Copilot CLI SDK's native OTel instrumentation178* (read by the bridge processor and the debug panel; the extension itself does179* not produce these).180*/181export const CopilotCliSdkAttr = {182HOOK_TYPE: 'github.copilot.hook.type',183HOOK_INVOCATION_ID: 'github.copilot.hook.invocation_id',184} as const;185186187