diff --git a/configs/init-ai.el b/configs/init-ai.el index 3037de7..9981617 100644 --- a/configs/init-ai.el +++ b/configs/init-ai.el @@ -39,13 +39,41 @@ "minimax-m2.5:cloud" "qwen3-coder-next:cloud")) - ;; Backend opencode-go: suscripción OpenCode Go vía endpoint OpenAI-compatible + ;; Backend opencode-go: suscripción OpenCode Go vía endpoint OpenAI-compatible. + ;; Las versiones actuales de opencode guardan el login de consola en su base + ;; de datos SQLite (token OAuth + organización activa), no en auth.json. + (defconst kj-opencode-db-file + (expand-file-name "~/.local/share/opencode/opencode.db") + "Ruta de la base de datos SQLite de opencode.") + + (defun kj-opencode-console-credentials () + "Return (TOKEN . ORG-ID) for opencode's active console account." + (when (and (fboundp 'sqlite-select) + (file-readable-p kj-opencode-db-file)) + (ignore-errors + (let ((db (sqlite-open kj-opencode-db-file t))) + (unwind-protect + (when-let* ((row (car (sqlite-select + db + "select a.access_token, s.active_org_id \ +from account_state s join account a on a.id = s.active_account_id \ +limit 1")))) + (cons (nth 0 row) (nth 1 row))) + (sqlite-close db)))))) + (defun kj-opencode-go-key () - "Return the OpenCode Go API key from opencode's auth file." - (let ((auth (with-temp-buffer - (insert-file-contents "~/.local/share/opencode/auth.json") - (json-parse-buffer :object-type 'alist)))) - (alist-get 'key (alist-get 'opencode-go auth)))) + "Return the credential to use for the OpenCode Go backend." + (or (car (kj-opencode-console-credentials)) + (getenv "OPENCODE_CONSOLE_TOKEN") + (let ((auth (with-temp-buffer + (insert-file-contents "~/.local/share/opencode/auth.json") + (json-parse-buffer :object-type 'alist)))) + (alist-get 'key (alist-get 'opencode-go auth))))) + + (defun kj-opencode-go-org-id () + "Return opencode's active workspace id, when available." + (or (cdr (kj-opencode-console-credentials)) + (getenv "OPENCODE_ORG_ID"))) (defvar-local kj-opencode-session-id nil "Stable OpenCode session id for this conversation buffer.") @@ -65,10 +93,12 @@ (kj-opencode-go-new-session-id)))) (defun kj-opencode-go-header (info) - "Auth plus per-conversation session header for the OpenCode Go backends." + "Auth, workspace and per-conversation session headers for OpenCode Go." (append (when-let* ((key (gptel--get-api-key))) `(("Authorization" . ,(concat "Bearer " key)))) + (when-let* ((org (kj-opencode-go-org-id))) + `(("x-opencode-org-id" . ,org))) `(("x-opencode-session" . ,(kj-opencode-go-session-id info))))) (gptel-make-openai "OpenCode Go" @@ -77,30 +107,23 @@ :key #'kj-opencode-go-key :header #'kj-opencode-go-header :stream t - :models '(minimax-m3 minimax-m2.7 minimax-m2.5 - kimi-k3 kimi-k2.7-code kimi-k2.6 longcat-2.0 kimi-k2.5 - glm-5.3-flash glm-5.3 glm-5.2 glm-5.1 glm-5 - deepseek-v4-pro deepseek-v4-flash deepseek-v4-flash-vision-exp - qwen3.8-max qwen3.7-max qwen3.7-plus qwen3.6-plus qwen3.5-plus - mimo-v2-pro mimo-v2-omni mimo-v2.5-pro mimo-v2.5 - hy3 hy3-preview - gpt-5.6-luna grok-4.5 grok-4.6 - muse-spark-1.2-contributor)) - - ;; Modelos gratuitos de OpenCode Go, servidos vía el endpoint /zen/v1 - (gptel-make-openai "OpenCode Free" - :host "opencode.ai" - :endpoint "/zen/v1/chat/completions" - :key #'kj-opencode-go-key - :header #'kj-opencode-go-header - :stream t - :models '(big-pickle deepseek-v4-flash-free muse-spark-1.2-contributor-free - mimo-v2.5-free hy3-free nemotron-3-ultra-free - nemotron-3.5-lightning-free laguna-s-2.1-free)) + :models '(deepseek-v4.1-flash deepseek-v4-pro + glm-5.1 glm-5.2 glm-5.3 glm-5.3-flash + grok-4.6 grok-4.7 + mimo-v2.5 mimo-v2.5-pro mimo-v2.6-flash mimo-v2.6-pro + minimax-m2.5 minimax-m2.7 minimax-m3 + kimi-k2.6 kimi-k2.7-code kimi-k3 + longcat-2.0 + qwen3.6-plus qwen3.7-plus qwen3.7-max qwen3.8-flash qwen3.8-max + gpt-5.6-luna gpt-6-luna claude-haiku-5-5 + hy3 hy4-preview omen-alpha step-5-preview + beam-free minimax-m3.1-flash-free longcat-2.5-preview-free + muse-spark-1.2-contributor muse-spark-1.3-contributor + gemini-4-argon-contributor)) ;; Backend y modelo por defecto (setq gptel-backend (gptel-get-backend "OpenCode Go") - gptel-model 'mimo-v2.5-free) + gptel-model 'mimo-v2.6-flash) (setq gptel-default-mode 'markdown-mode gptel-prompt-prefix-alist