{ config, lib, ... }: let cfg = config.dot.llm.opencode; in { options.dot.llm.opencode = { enableConfig = lib.mkOption { type = lib.types.bool; default = false; description = "Enable managed OpenCode configuration"; }; workMode = lib.mkEnableOption "work-specific opencode configuration"; }; config = lib.mkIf cfg.enableConfig { # Declare the sops secret sops.secrets.langdock_api_key = { # Uses defaultSopsFile from secrets.nix }; # Create the OpenCode config.json template with secret substitution sops.templates."opencode/opencode.json" = { content = builtins.toJSON (let baseConfig = { "$schema" = "https://opencode.ai/config.json"; default_agent = "plan"; }; workConfig = { enabled_providers = [ "anthropic" "langdock-openai" "ollama" ]; model = "anthropic/claude-opus-4-6-default"; small_model = "anthropic/claude-haiku-4-5-20251001"; provider = { langdock-openai = { npm = "@ai-sdk/openai-compatible"; name = "Langdock OpenAI"; options = { baseURL = "https://api.langdock.com/openai/eu/v1"; apiKey = config.sops.placeholder.langdock_api_key; }; models = { "gpt-5.2" = { name = "GPT-5.2"; }; "gpt-5-mini" = { name = "GPT-5 mini"; }; }; }; anthropic = { options = { baseURL = "https://api.langdock.com/anthropic/eu/v1"; apiKey = config.sops.placeholder.langdock_api_key; }; models = { "claude-opus-4-6-default" = { name = "Opus 4.6"; }; "claude-sonnet-4-6-default" = { name = "Sonnet 4.6"; }; "claude-haiku-4-5-20251001" = { name = "Haiku 4.5"; }; }; whitelist = [ "claude-opus-4-6-default" "claude-sonnet-4-6-default" "claude-haiku-4-5-20251001"]; }; ollama = { npm = "@ai-sdk/openai-compatible"; name = "Ollama (Local)"; options = { baseURL = "http://192.168.11.23:11434/v1"; }; models = { "qwen3-coder:30b" = { name = "Qwen 3 Coder 30B"; }; "codellama:34b-instruct" = { name = "CodeLlama 34B Instruct"; }; }; }; }; }; personalConfig = { plugin = [ "opencode-gemini-auth@latest" ]; model = "google/gemini-3-pro-preview"; small_model = "google/gemini-3-flash-preview"; enabled_providers = [ "google" ]; }; in # Merge base config with the selected mode config baseConfig // (if cfg.workMode then workConfig else personalConfig) ); }; # Link the generated config to the expected location xdg.configFile."opencode/opencode.json".source = config.lib.file.mkOutOfStoreSymlink config.sops.templates."opencode/opencode.json".path; }; }