# ============================================================================ # OpenViking Helm Chart Values # Cluster: fastpass (Talos Kubernetes) # Wave: 8 (after Harbor at Wave 7) # Pilot scope: Two corpora (hermes/ skills, personal/homelab/) # ============================================================================ # # KEY CONSTRAINT: Vault (~/friday) is the CANONICAL source of truth. # OpenViking's index is a derived cache, rebuilt from vault source files. # If index and vault ever diverge, vault wins and re-index runs. # See inbox/ryan/2026-08-13-openviking-pilot-deployment-plan.md for full context. # replicaCount: 1 image: repository: ghcr.io/volcengine/openviking # Pin to a stable release tag (not "latest" for production-ish pilot) tag: v0.3.17 pullPolicy: IfNotPresent imagePullSecrets: [] nameOverride: "" fullnameOverride: "" serviceAccount: create: false annotations: {} name: "" podAnnotations: {} podLabels: app: openviking wave: "8" # Security context: run as non-root if the image supports it podSecurityContext: {} securityContext: {} # Service: ClusterIP (no direct external exposure; MCP proxy handles agent access) service: type: ClusterIP port: 1933 # ============================================================================ # Ingress: enabled, INTERNAL-ONLY # Constraint from Phase 0 (Ryan's decision, 2026-08-13): # Standard nginx-ingress fronting the service (consistent with Harbor pattern), # but internal DNS only — no external/public DNS entry, no public-facing cert-manager issuer. # Use internal CA / self-signed cert to get ingress consistency without expanding public attack surface. # ============================================================================ ingress: enabled: true className: nginx annotations: # Internal cert-manager cluster issuer (DNS-01 via Cloudflare) cert-manager.io/cluster-issuer: "letsencrypt-prod" # Block external DNS registration (internal only) external-dns.alpha.kubernetes.io/enabled: "false" hosts: - host: openviking.local.mk-labs.cloud paths: - path: / pathType: Prefix tls: - secretName: openviking-tls hosts: - openviking.local.mk-labs.cloud # ============================================================================ # Resources: start conservative, tune after pilot # ============================================================================ resources: limits: cpu: "2" memory: 4Gi requests: cpu: 500m memory: 1Gi # ============================================================================ # Persistence: RocksDB index + workspace # Storage class: px-fa-direct-access (Portworx direct access to Pure FlashArray) # Rationale (from Phase 0 / t_77b3ff79): 40+ days of proven production history on fastpass, # RocksDB-optimized (direct block access, not NFS), RAID 6 durability via FlashArray. # Access mode: ReadWriteOnce (single replica only — RocksDB does not support concurrent access) # Update strategy: Recreate (no rolling updates; single-replica RocksDB workload) # ============================================================================ persistence: enabled: true storageClass: px-fa-direct-access accessMode: ReadWriteOnce size: 30Gi # 30Gi provides headroom for ~6 months of pilot corpus growth (~2GB actual use at launch) existingClaim: "" mountPath: /app/.openviking # Pod disruption budget: single replica, no HA # Explicit Recreate strategy (handled via Deployment patch in ArgoCD Application) podDisruptionBudget: {} # ============================================================================ # Bot feature: disabled (scope out vikingbot for this phase) # ============================================================================ bot: enabled: false # ============================================================================ # OpenViking server configuration (ov.conf) # Rendered into a ConfigMap mounted at ${persistence.mountPath}/ov.conf # ============================================================================ config: storage: workspace: "" # Defaults to /app/.openviking/openviking_workspace vectordb: name: context backend: local project: default agfs: backend: local timeout: 10 log: level: INFO output: stdout server: host: "0.0.0.0" port: 1933 workers: 1 # root_api_key injected via environment variable + ExternalSecret root_api_key: "${OPENVIKING_ROOT_API_KEY}" cors_origins: - "*" # ============================================================================ # Embedding configuration (dense) # Provider: openai-compatible endpoint (local llama-server router) # Model: nomic-embed-text-v1.5-Q4_K_M (137M params, 768-dim, local inference) # Endpoint: http://astro-orbiter:8002/v1 (folded into existing astro-orbiter router per t_eb36eb2e) # No cloud key needed; internal unauthenticated endpoint # ============================================================================ embedding: dense: provider: "openai" api_base: "http://astro-orbiter:8002/v1" api_key: "${OPENVIKING_EMBEDDING_API_KEY}" # Placeholder: "local-nomic" or similar model: "nomic-embed-text-v1.5" dimension: 768 input: "text" max_concurrent: 5 # max_input_tokens caps the raw text tokens OpenViking sends per chunk to the # embedding model. astro-orbiter's llama.cpp router hard-caps nomic-embed-text-v1.5's # effective context at 2048 tokens regardless of ctx-size config (known llama.cpp # nomic-bert limitation, not fixable via server flags). OpenViking's chunker was # observed producing 2000-3400 token chunks, well over that ceiling, causing # `400 exceed_context_size_error, n_ctx: 2048` and endless circuit-breaker re-enqueues. # Set well under 2048 (1536) to leave headroom: OpenViking's chunk-time token # estimator is not the same tokenizer llama.cpp uses to count context, so token # counts won't match 1:1 between the two. Approved by Ryan as lowest-risk fix # (option 1 of 3) vs. touching the astro-orbiter serving stack further. # # ROOT CAUSE (2026-08-15 incident): 1536 was still not low enough. Observed # llama.cpp actual n_prompt_tokens vs. OpenViking's own max_input_tokens=1536 # estimate ratio ranged 1.35x-1.86x across real ingested chunks (see homelab # re-ingest circuit-breaker errors, e.g. estimate 1536 -> actual 2860 tokens, # 2124, 2088, 2066... all > 2048 n_ctx ceiling). OpenViking's estimator # (likely a chars/4 or similar heuristic) undercounts vs. llama.cpp's real # BPE/wordpiece tokenizer for this corpus's content (dense code/config # snippets tokenize denser than the estimator assumes). Lowering to 1536 alone # does not hold for all chunks; using worst-observed ratio (1.86x) with margin, # 2048 / 1.86 ~= 1100, rounded down further for safety across untested # corpora -> 1024. max_input_tokens: 1024 # ============================================================================ # VLM / Summarization configuration (L0/L1/L2 generation) # Provider: openai-compatible endpoint (local llama-server router) # Model: Llama-3.1-8B (already resident on astro-orbiter per Phase 0 analysis) # Endpoint: http://astro-orbiter:8002/v1 (same router as embedding) # No cloud key needed; internal unauthenticated endpoint # max_concurrent: 4 (recommend capping background indexing load on shared VLM) # ============================================================================ vlm: api_base: "http://astro-orbiter:8002/v1" api_key: "${OPENVIKING_VLM_API_KEY}" # Placeholder: "local-llama" or similar # Fixed 2026-08-15: "llama3.1-8b" does not exist on astro-orbiter's /v1/models # (caused every summarization call to fail with 400 model not found, endless # circuit-breaker retries). Actual served model id/alias confirmed via # /home/hermes/git/homelab/ansible/playbooks/day2_add_nomic_embed.yml and # day2_per_model_ctx_size.yml: "Meta-Llama-3.1-8B-Instruct-Q4_K_M". model: "Meta-Llama-3.1-8B-Instruct-Q4_K_M" provider: "openai" temperature: 0.0 max_retries: 2 thinking: false max_concurrent: 4 # Cap background indexing pressure on shared VLM # ============================================================================ # Extra environment variables: secrets from ExternalSecret # Injected by ArgoCD Application via kustomize or helm hook # ============================================================================ extraEnv: - name: OPENVIKING_ROOT_API_KEY valueFrom: secretKeyRef: name: openviking-credentials key: root_api_key - name: OPENVIKING_EMBEDDING_API_KEY valueFrom: secretKeyRef: name: openviking-credentials key: embedding_api_key - name: OPENVIKING_VLM_API_KEY valueFrom: secretKeyRef: name: openviking-credentials key: vlm_api_key # ============================================================================ # Probes # ============================================================================ livenessProbe: httpGet: path: /health port: http initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: http initialDelaySeconds: 15 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 nodeSelector: {} tolerations: [] affinity: {}