# ============================================================
# oGMemory Unified Configuration Reference
# ============================================================
#
# This is the single reference template for all deployment modes.
# Copy and edit for your use case:
#
#   Local dev:  cp config/ogmem.reference.yaml ogmem.yaml
#   Docker:     cp config/ogmem.reference.yaml deploy/ogmemory.yaml
#
# Mode annotations:
#   [all]     — applies to all modes
#   [local]   — local development only
#   [docker]  — Docker deployment (uses ${ENV_VAR} from deploy.env)
#
# Priority: YAML value > env var > code default
# ============================================================

# ---- LLM Configuration [all] ----
llm:
  provider: openai                # [all] mock / openai / openai-cached
  api_key: "your-api-key"        # [local] your key; [docker] use "${LLM_API_KEY}"
  # api_key_command:             # [all] 1Password / vault integration
  #   command: ["/usr/local/bin/op", "read", "op://team/ogmemory/api-key"]
  base_url: "https://api.openai.com/v1"  # [local] your endpoint; [docker] use "${LLM_BASE_URL}"
  model: "gpt-4o-mini"           # [local] your model; [docker] use "${LLM_MODEL}"
  temperature: 0.1               # [all] recommended: 0-0.1 for deterministic extraction
  max_tokens: 4096               # [all]
  json_mode: false               # [all]
  # reasoning_effort: "medium"  # [all] optional; sent only when configured
  # is_reasoning_model: true     # [all] optional override; null means auto-detect
  # extra_body:                  # [all] arbitrary OpenAI-compatible provider options
  #   thinking: {type: enabled}

# ---- Embedding Configuration [all] ----
embedding:
  # provider: null               # [all] defaults to llm.provider
  model: "text-embedding-v4"     # [all]
  base_url: "https://api.openai.com/v1"  # [all] defaults to llm.base_url
  api_key: null                  # [all] defaults to llm.api_key
  # api_key_command:
  #   command: ["/usr/local/bin/op", "read", "op://team/ogmemory/embedding-api-key"]
  multimodal: false              # [all] true for VolcEngine /doubao embeddings
  # st_model: "BAAI/bge-m3"     # [local] Sentence Transformer local model (overrides API embedding)

# ---- Vector Database [all] ----
vector_db:
  type: chroma                   # [local] memory (quickstart) / chroma / opengauss
                                  # [docker] opengauss (recommended for production)
  # --- Chroma (local) ---
  chroma_persist_dir: ".ogmem_data/chroma"  # [local]
  # chroma_collection: "contextengine"
  # --- OpenGauss (docker / production) ---
  # connection_string: "host=127.0.0.1 port=8799 dbname=postgres user=gaussdb password=CHANGE_ME"
  dimension: 1024                # [all]
  table_name: vector_index       # [all]
  pool_size: 5                   # [all]

# ---- HTTP Service [all] ----
service:
  http_port: 8090                # [all]
  workers: 2                     # [all]
  # http_ip_allowlist: ["127.0.0.1", "10.0.0.0/8"]  # [all]
  # http_ip_allowlist_trust_proxy: false              # [all]
  # http_trusted_proxies: ["127.0.0.1"]               # [all]

# ---- MCP Server [all] ----
mcp:
  enabled: true
  host: "127.0.0.1"
  port: 8091
  path: "/mcp"
  default_toolset: "read-only"
  enable_write_tools: false
  enable_delete_tools: false
  enable_runtime_tools: false
  enable_diagnostic_tools: false
  max_request_bytes: 1048576
  max_sse_connections: 64
  max_response_chars: 50000
  collection_limit: 50
  allowed_origins: []
  allowed_hosts: ["127.0.0.1", "localhost"]

# ---- Storage Backend [all] ----
storage:
  backend: sql                   # [all] agfs / sql (recommended: sql)
  connection_string: "host=127.0.0.1 port=5432 dbname=ogmemory user=postgres password=postgres"  # [local]
  pool_size: 5                   # [all]
  trace_max_turn_events: 128     # [all] first + newest events retained per finalized turn (2-1024)

# ---- Paths [local] ----
paths:
  data_root: .ogmem_data         # [local] all runtime data (chroma/, agfs/, logs/)

# ---- AGFS (internal) [docker] ----
agfs:
  base_url: "http://127.0.0.1:1833"   # [all] AGFS server address
  mount_prefix: "/local/plugin"        # [docker]

# ---- Index Service [all] ----
index:
  interval: 15                   # [all] polling interval (seconds)
  workers: 1                     # [all]

# ---- Identity / Multi-tenant [all] ----
identity:
  account_id: "acct-demo"        # [all]
  user_id: "u-alice"             # [all]
  agent_id: "main"               # [all]

# ---- Authentication [all] ----
auth:
  role_control_enabled: false    # [all] enable for multi-tenant
  # root_api_key: "root-secret-key-change-me"     # [all]
  # admin_api_keys:                                # [all]
  #   - "acct-company-a:admin-key-for-a"
  #   - "acct-company-b:admin-key-for-b"

# ---- Agent Sharing [all] ----
sharing:
  agent_shared_mode: "off"       # [all] off / user
  # agent_shared_list:           # [all]
  #   - "agent-shared-sales"
  #   - "agent-shared-support"

# ---- Memory Extraction [all] ----
memory:
  extraction:
    mode: lazy                    # [all] eager / lazy (lazy = ReAct loop with read tools)
  # after_turn_threshold: 200    # [all] tokens before auto-extraction
  # rolling_compress_enabled: true
  # compact_prepare_token_ttl: 300
  # directory_summary_enabled: false
  # prefetch_enabled: false
  # prefetch_top_k: 5
  # session_state_bridge_enabled: true
  # session_state_sync_interval_turns: 1
  # topic_detection_enabled: false
  # compression_quality_enabled: false
  # compression_quality_persist_metadata: false

# ---- Agent Skill Sedimentation [AGFS or SQL, opt-in] ----
# AGFS sedimentation currently supports one oGMemory service process.
# SQL remains required for coordinated processing across multiple instances.
# Set service.workers: 1 when enabling it with storage.backend: agfs.
skills:
  sedimentation:
    enabled: false
    # Generate Example IR from the first successful trace and render it in SKILL.md.
    worked_examples_enabled: false
    # Skill-first: each high-quality trace may create or update a reviewed skill.
    min_evidence_turns: 1
    min_distinct_sessions: 1
    turn_score_threshold: 0.85
    publish_score_threshold: 0.90
    semantic_update_threshold: 0.92
    semantic_hold_threshold: 0.80
    scan_interval_seconds: 60
    lease_seconds: 300
    max_attempts: 5
    candidate_limit: 200
    catalog_scan_limit: 10000
    max_evidence_turns: 20
    max_trace_chars: 32768
    max_prompt_chars: 65536
    retry_base_seconds: 30
    retry_cap_seconds: 3600
    batch_size: 20
    account_workers: 2
    search_scan_limit: 1000
    # Trace hooks must set OGMEM_TRACE_CAPTURE_CONTENT=1. Turns without
    # non-empty user and assistant content are rejected before any LLM call.
    # reviewer_provider: openai
    # reviewer_model: gpt-4o-mini
    # sync_target: ~/.agents/skills

# ---- Hybrid retrieval [openGauss + SQL canonical storage, opt-in] ----
# Requires the openGauss BM25 access method and <&> operator. The configured
# database role must be able to create/alter the versioned lexical tables,
# indexes, and generation sequence. Rolling mixed-version workers are
# unsupported: upgrade and stop every old vector-only outbox worker before
# enabling this flag, and do not start one
# while hybrid is enabled. Historical rebuilds stream bounded pages in one
# background worker; the first read per owner scope fails closed until ready.
retrieval:
  hybrid_enabled: false
  vector_top_k: 100
  lexical_top_k: 50
  rrf_k: 60
  semantic_weight: 1.0
  lexical_weight: 1.0
  backfill_page_size: 500
  lexical:
    provider: opengauss_native
    options:
      # Projection/checkpoint tables use opengauss_connection_string (or the
      # vector openGauss DSN); canonical outbox state gates reads fail-closed.
      table_name: lexical_index_opengauss_native
      query_timeout_ms: 5000
      max_query_chars: 32768

# ---- Cache [all] ----
cache:
  enabled: true                  # [all]
  max_size: 1000                 # [all]