# Copyright (c) Metis. All rights reserved.

"""Mantisdk Semantic Conventions for Tracing.

Canonical source for all attribute key constants used across the SDK.
Organized by namespace:

- insight.*:       Primary namespace for Insight UI display
- langfuse.*:      Compatibility namespace for Langfuse SDK spans
- gen_ai.*:        OpenTelemetry GenAI semantic conventions
- openinference.*: OpenInference (Arize) conventions
- mantis.*:        MantisDK custom attributes
- claude.*:        Claude Agent SDK-specific attributes

See: insight/packages/shared/src/server/otel/attributeAliases.ts

Usage::

    import mantisdk.tracing as tracing

    with tracing.trace("my-task", input=query) as span:
        span.set_attribute(tracing.semconv.USER_ID, "user-123")
        span.set_attribute(tracing.semconv.SESSION_ID, "session-456")
        result = do_work()
        span.set_attribute(tracing.semconv.TRACE_OUTPUT, result)
"""

# =============================================================================
# Insight Trace Attributes (Primary Namespace)
# =============================================================================
TRACE_NAME = "insight.trace.name"
TRACE_INPUT = "insight.trace.input"
TRACE_OUTPUT = "insight.trace.output"
TRACE_METADATA = "insight.trace.metadata"
TRACE_TAGS = "insight.trace.tags"
TRACE_PUBLIC = "insight.trace.public"

# Aliases matching attributes.py naming convention
INSIGHT_TRACE_NAME = TRACE_NAME
INSIGHT_TRACE_INPUT = TRACE_INPUT
INSIGHT_TRACE_OUTPUT = TRACE_OUTPUT
INSIGHT_TRACE_METADATA = TRACE_METADATA
INSIGHT_TRACE_TAGS = TRACE_TAGS
INSIGHT_TRACE_PUBLIC = TRACE_PUBLIC

# =============================================================================
# User & Session
# =============================================================================
USER_ID = "insight.user.id"
SESSION_ID = "insight.session.id"

INSIGHT_TRACE_USER_ID = USER_ID
INSIGHT_TRACE_SESSION_ID = SESSION_ID

# =============================================================================
# Run tracking (for Mantis Runs)
# =============================================================================
RUN_ID = "insight.run.id"
RUN_NAME = "insight.run.name"

# =============================================================================
# Environment & Version
# =============================================================================
ENVIRONMENT = "insight.environment"
RELEASE = "insight.release"
VERSION = "insight.version"

INSIGHT_ENVIRONMENT = ENVIRONMENT
INSIGHT_RELEASE = RELEASE
INSIGHT_VERSION = VERSION

# =============================================================================
# Insight Observation Attributes (Primary Namespace)
# =============================================================================
OBSERVATION_TYPE = "insight.observation.type"
OBSERVATION_INPUT = "insight.observation.input"
OBSERVATION_OUTPUT = "insight.observation.output"
OBSERVATION_METADATA = "insight.observation.metadata"
OBSERVATION_LEVEL = "insight.observation.level"
OBSERVATION_STATUS_MESSAGE = "insight.observation.status_message"

INSIGHT_OBSERVATION_TYPE = OBSERVATION_TYPE
INSIGHT_OBSERVATION_INPUT = OBSERVATION_INPUT
INSIGHT_OBSERVATION_OUTPUT = OBSERVATION_OUTPUT
INSIGHT_OBSERVATION_METADATA = OBSERVATION_METADATA
INSIGHT_OBSERVATION_LEVEL = OBSERVATION_LEVEL
INSIGHT_OBSERVATION_STATUS_MESSAGE = OBSERVATION_STATUS_MESSAGE

# =============================================================================
# Model & Generation attributes
# =============================================================================
MODEL_NAME = "insight.observation.model.name"
MODEL_PARAMETERS = "insight.observation.model.parameters"

INSIGHT_OBSERVATION_MODEL = MODEL_NAME
INSIGHT_OBSERVATION_MODEL_PARAMETERS = MODEL_PARAMETERS


# =============================================================================
# Observation types (values for OBSERVATION_TYPE)
# =============================================================================
class ObservationType:
    """Valid values for the OBSERVATION_TYPE attribute."""

    SPAN = "span"
    GENERATION = "generation"
    EVENT = "event"


# =============================================================================
# Observation levels (values for OBSERVATION_LEVEL)
# =============================================================================
class ObservationLevel:
    """Valid values for the OBSERVATION_LEVEL attribute."""

    DEBUG = "DEBUG"
    DEFAULT = "DEFAULT"
    WARNING = "WARNING"
    ERROR = "ERROR"


# =============================================================================
# Langfuse Trace Attributes (Compatibility)
# =============================================================================
LANGFUSE_TRACE_NAME = "langfuse.trace.name"
LANGFUSE_TRACE_USER_ID = "user.id"
LANGFUSE_TRACE_SESSION_ID = "session.id"
LANGFUSE_TRACE_TAGS = "langfuse.trace.tags"
LANGFUSE_TRACE_PUBLIC = "langfuse.trace.public"
LANGFUSE_TRACE_METADATA = "langfuse.trace.metadata"
LANGFUSE_TRACE_INPUT = "langfuse.trace.input"
LANGFUSE_TRACE_OUTPUT = "langfuse.trace.output"

# =============================================================================
# Langfuse Observation Attributes (Compatibility)
# =============================================================================
LANGFUSE_OBSERVATION_TYPE = "langfuse.observation.type"
LANGFUSE_OBSERVATION_METADATA = "langfuse.observation.metadata"
LANGFUSE_OBSERVATION_LEVEL = "langfuse.observation.level"
LANGFUSE_OBSERVATION_STATUS_MESSAGE = "langfuse.observation.status_message"
LANGFUSE_OBSERVATION_INPUT = "langfuse.observation.input"
LANGFUSE_OBSERVATION_OUTPUT = "langfuse.observation.output"

# =============================================================================
# Langfuse Generation Attributes (Compatibility)
# =============================================================================
LANGFUSE_OBSERVATION_COMPLETION_START_TIME = "langfuse.observation.completion_start_time"
LANGFUSE_OBSERVATION_MODEL = "langfuse.observation.model.name"
LANGFUSE_OBSERVATION_MODEL_PARAMETERS = "langfuse.observation.model.parameters"
LANGFUSE_OBSERVATION_USAGE_DETAILS = "langfuse.observation.usage_details"
LANGFUSE_OBSERVATION_COST_DETAILS = "langfuse.observation.cost_details"
LANGFUSE_OBSERVATION_PROMPT_NAME = "langfuse.observation.prompt.name"
LANGFUSE_OBSERVATION_PROMPT_VERSION = "langfuse.observation.prompt.version"

# =============================================================================
# Langfuse General Attributes (Compatibility)
# =============================================================================
LANGFUSE_ENVIRONMENT = "langfuse.environment"
LANGFUSE_RELEASE = "langfuse.release"
LANGFUSE_VERSION = "langfuse.version"

# =============================================================================
# OpenTelemetry GenAI Semantic Conventions
# https://opentelemetry.io/docs/specs/semconv/gen-ai/
# =============================================================================
GEN_AI_OPERATION_NAME = "gen_ai.operation.name"
GEN_AI_SYSTEM = "gen_ai.system"
GEN_AI_REQUEST_MODEL = "gen_ai.request.model"
GEN_AI_RESPONSE_MODEL = "gen_ai.response.model"
GEN_AI_REQUEST_TEMPERATURE = "gen_ai.request.temperature"
GEN_AI_REQUEST_MAX_TOKENS = "gen_ai.request.max_tokens"
GEN_AI_RESPONSE_FINISH_REASONS = "gen_ai.response.finish_reasons"
GEN_AI_CONVERSATION_ID = "gen_ai.conversation.id"

# GenAI Input/Output
GEN_AI_INPUT_MESSAGES = "gen_ai.input.messages"
GEN_AI_OUTPUT_MESSAGES = "gen_ai.output.messages"

# GenAI Usage
GEN_AI_USAGE_INPUT_TOKENS = "gen_ai.usage.input_tokens"
GEN_AI_USAGE_OUTPUT_TOKENS = "gen_ai.usage.output_tokens"
GEN_AI_USAGE_COST = "gen_ai.usage.cost"

# GenAI Tool Attributes
GEN_AI_TOOL_NAME = "gen_ai.tool.name"
GEN_AI_TOOL_CALL_ARGUMENTS = "gen_ai.tool.call.arguments"
GEN_AI_TOOL_CALL_RESULT = "gen_ai.tool.call.result"

# =============================================================================
# OpenInference Semantic Conventions
# https://github.com/Arize-ai/openinference
# =============================================================================
OPENINFERENCE_SPAN_KIND = "openinference.span.kind"

# LLM Attributes
LLM_MODEL_NAME = "llm.model_name"
LLM_INVOCATION_PARAMETERS = "llm.invocation_parameters"
LLM_INPUT_MESSAGES = "llm.input_messages"
LLM_OUTPUT_MESSAGES = "llm.output_messages"
LLM_TOKEN_COUNT_PROMPT = "llm.token_count.prompt"
LLM_TOKEN_COUNT_COMPLETION = "llm.token_count.completion"
LLM_TOKEN_COUNT_TOTAL = "llm.token_count.total"

# Input/Output (general)
INPUT_VALUE = "input.value"
OUTPUT_VALUE = "output.value"

# Tool Attributes
TOOL_NAME = "tool.name"
TOOL_DESCRIPTION = "tool.description"
TOOL_PARAMETERS = "tool.parameters"

# =============================================================================
# OpenInference Span Kind Values
# =============================================================================
SPAN_KIND_LLM = "LLM"
SPAN_KIND_TOOL = "TOOL"
SPAN_KIND_AGENT = "AGENT"
SPAN_KIND_CHAIN = "CHAIN"
SPAN_KIND_EMBEDDING = "EMBEDDING"
SPAN_KIND_RETRIEVER = "RETRIEVER"
SPAN_KIND_RERANKER = "RERANKER"
SPAN_KIND_GUARDRAIL = "GUARDRAIL"
SPAN_KIND_EVALUATOR = "EVALUATOR"

# =============================================================================
# OpenInference MIME Types
# =============================================================================
MIME_TYPE_TEXT = "text/plain"
MIME_TYPE_JSON = "application/json"

# =============================================================================
# OpenInference Extended Attributes
# =============================================================================
INPUT_MIME_TYPE = "input.mime_type"
OUTPUT_MIME_TYPE = "output.mime_type"
LLM_SYSTEM = "llm.system"
LLM_PROVIDER = "llm.provider"

# =============================================================================
# MantisDK Custom Attributes
# =============================================================================
MANTIS_LLM_THINKING = "mantis.llm.thinking"
MANTIS_LLM_COST_USD = "mantis.llm.cost_usd"
MANTIS_DURATION_MS = "mantis.duration_ms"
MANTIS_DURATION_API_MS = "mantis.duration_api_ms"
MANTIS_NUM_TURNS = "mantis.num_turns"
MANTIS_TOOL_IS_ERROR = "mantis.tool.is_error"

# =============================================================================
# Claude-Specific Attributes
# =============================================================================
CLAUDE_API_ERROR = "claude.api_error"
CLAUDE_PARENT_TOOL_USE_ID = "claude.parent_tool_use_id"
CLAUDE_STRUCTURED_OUTPUT = "claude.structured_output"
CLAUDE_THINKING_SIGNATURE = "claude.thinking.signature"
CLAUDE_MESSAGE_UUID = "claude.message.uuid"
CLAUDE_SYSTEM_SUBTYPE = "claude.system.subtype"
CLAUDE_SYSTEM_DATA = "claude.system.data"
