{ config, lib, inputs, ... }: 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.6-sol" = { name = "GPT-5.6 Sol"; }; "gpt-5.6-terra" = { name = "GPT-5.6 Terra"; }; "gpt-5.6-luna" = { name = "GPT-5.6 Luna"; }; }; }; anthropic = { options = { baseURL = "https://api.langdock.com/anthropic/eu/v1"; apiKey = config.sops.placeholder.langdock_api_key; }; models = { "claude-opus-5-default" = { name = "Opus 5"; }; "claude-opus-4-8-default" = { name = "Opus 4.8"; }; "claude-sonnet-5-default" = { name = "Sonnet 5"; }; }; whitelist = ["claude-opus-4-8-default" "claude-opus-5-default" "claude-sonnet-5-default"]; }; # 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; # Export the decrypted langdock API key as an env var (work config only). # The secret lives in a runtime file, so we read it at shell startup rather # than baking it into the Nix store via home.sessionVariables. programs.zsh.initContent = lib.mkIf cfg.workMode '' if [ -r "${config.sops.secrets.langdock_api_key.path}" ]; then export LANGDOCK_API_KEY="$(cat "${config.sops.secrets.langdock_api_key.path}")" fi ''; }; }