summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-03-06 21:02:03 -0600
committerCraig Jennings <c@cjennings.net>2026-03-06 21:02:03 -0600
commitfb4905714fb7f3a0dc316157da24794c1708dfe8 (patch)
treeaa2458c7e5230d4f849a405f53d1674864279dea
parent873269cdea6a0c93f7eb25acabce8b72f8be6126 (diff)
refactor(gptel): move config defuns to top level, rebind keys, set reasoning
- Move cj/gptel--fresh-org-prefix, cj/gptel--refresh-org-prefix, cj/gptel-backend-and-model, cj/gptel-insert-model-heading out of use-package :config to top level (fixes byte-compile warnings) - Set gptel-include-reasoning to "*AI-Reasoning*" buffer - Rebind rewrite to C-; a r, clear context to C-; a c - Update todo.org with completed cleanup items Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
-rw-r--r--modules/ai-config.el73
-rw-r--r--todo.org23
2 files changed, 44 insertions, 52 deletions
diff --git a/modules/ai-config.el b/modules/ai-config.el
index 5f6c48dc..0df2a050 100644
--- a/modules/ai-config.el
+++ b/modules/ai-config.el
@@ -23,7 +23,7 @@
;; - Save conversations with C-; a s, load previous ones with C-; a l
;; - Clear the conversation and start over with C-; a x
;; Or in any buffer:
-;; - Add directive as above, and select a region to rewrite with C-; a &.
+;; - Add directive as above, and select a region to rewrite with C-; a r.
;;
;;; Code:
@@ -268,8 +268,9 @@ Works for any buffer, whether it's visiting a file or not."
(gptel-default-mode 'org-mode)
(gptel-expert-commands t)
(gptel-track-media t)
- ;; TODO: add reasoning to a buffer. See docstring.
- (gptel-include-reasoning 'ignore)
+ ;; Options: t (include + resend), 'ignore (show but don't resend),
+ ;; nil (discard), or a buffer name to redirect reasoning to
+ (gptel-include-reasoning "*AI-Reasoning*")
(gptel-log-level 'info)
(gptel--debug nil)
:config
@@ -279,43 +280,37 @@ Works for any buffer, whether it's visiting a file or not."
(setq gptel-confirm-tool-calls nil) ;; allow tool access by default
-
-
-;;; -------------------------- Org Header Construction --------------------------
-
- ;; Dynamic user prefix for org-mode heading (string, refreshed just before send)
- (defun cj/gptel--fresh-org-prefix ()
- "Generate a fresh org-mode header with current timestamp for user messages."
- (concat "* " user-login-name " " (format-time-string "[%Y-%m-%d %H:%M:%S]") "\n"))
-
- ;; Initialize as a string (GPTel expectation)
+ ;; Initialize org-mode user prefix and wire up hooks
(setf (alist-get 'org-mode gptel-prompt-prefix-alist)
(cj/gptel--fresh-org-prefix))
-
- ;; Refresh immediately before each send for accurate timestamp
- (defun cj/gptel--refresh-org-prefix (&rest _)
- "Update the org-mode prefix with fresh timestamp before sending message."
- (setf (alist-get 'org-mode gptel-prompt-prefix-alist)
- (cj/gptel--fresh-org-prefix)))
(advice-add 'gptel-send :before #'cj/gptel--refresh-org-prefix)
+ (add-hook 'gptel-post-response-functions #'cj/gptel-insert-model-heading))
- ;; AI header on each reply: (e.g. "*** AI: <model> [timestamp]")
- (defun cj/gptel-backend-and-model ()
- "Return backend, model, and timestamp as a single string."
- (let* ((backend (pcase (bound-and-true-p gptel-backend)
- ((and v (pred vectorp)) (aref v 1)) ;; display name if vector
- (_ "AI")))
- (model (format "%s" (or (bound-and-true-p gptel-model) "")))
- (ts (format-time-string "[%Y-%m-%d %H:%M:%S]")))
- (format "%s: %s %s" backend model ts)))
-
- (defun cj/gptel-insert-model-heading (response-begin-pos _response-end-pos)
- "Insert an Org heading for the AI reply at RESPONSE-BEGIN-POS."
- (save-excursion
- (goto-char response-begin-pos)
- (insert (format "* %s\n" (cj/gptel-backend-and-model)))))
+;;; -------------------------- Org Header Construction --------------------------
- (add-hook 'gptel-post-response-functions #'cj/gptel-insert-model-heading))
+(defun cj/gptel--fresh-org-prefix ()
+ "Generate a fresh org-mode header with current timestamp for user messages."
+ (concat "* " user-login-name " " (format-time-string "[%Y-%m-%d %H:%M:%S]") "\n"))
+
+(defun cj/gptel--refresh-org-prefix (&rest _)
+ "Update the org-mode prefix with fresh timestamp before sending message."
+ (setf (alist-get 'org-mode gptel-prompt-prefix-alist)
+ (cj/gptel--fresh-org-prefix)))
+
+(defun cj/gptel-backend-and-model ()
+ "Return backend, model, and timestamp as a single string."
+ (let* ((backend (pcase (bound-and-true-p gptel-backend)
+ ((and v (pred vectorp)) (aref v 1))
+ (_ "AI")))
+ (model (format "%s" (or (bound-and-true-p gptel-model) "")))
+ (ts (format-time-string "[%Y-%m-%d %H:%M:%S]")))
+ (format "%s: %s %s" backend model ts)))
+
+(defun cj/gptel-insert-model-heading (response-begin-pos _response-end-pos)
+ "Insert an Org heading for the AI reply at RESPONSE-BEGIN-POS."
+ (save-excursion
+ (goto-char response-begin-pos)
+ (insert (format "* %s\n" (cj/gptel-backend-and-model)))))
;;; ---------------------------- Toggle GPTel Window ----------------------------
@@ -396,8 +391,8 @@ Works for any buffer, whether it's visiting a file or not."
"l" #'cj/gptel-load-conversation ;; load and continue conversation
"m" #'cj/gptel-change-model ;; change the LLM model
"p" #'gptel-system-prompt ;; change prompt
- "&" #'gptel-rewrite ;; rewrite a region of code/text
- "r" #'cj/gptel-context-clear ;; remove all context
+ "r" #'gptel-rewrite ;; rewrite a region of code/text
+ "c" #'cj/gptel-context-clear ;; clear all context
"s" #'cj/gptel-save-conversation ;; save conversation
"t" #'cj/toggle-gptel ;; toggles the ai-assistant window
"x" #'cj/gptel-clear-buffer) ;; clears the assistant buffer
@@ -414,8 +409,8 @@ Works for any buffer, whether it's visiting a file or not."
"C-; a l" "load conversation"
"C-; a m" "change model"
"C-; a p" "change prompt"
- "C-; a &" "rewrite region"
- "C-; a r" "clear context"
+ "C-; a r" "rewrite region"
+ "C-; a c" "clear context"
"C-; a s" "save conversation"
"C-; a t" "toggle window"
"C-; a x" "clear buffer"))
diff --git a/todo.org b/todo.org
index b76b276b..e71def90 100644
--- a/todo.org
+++ b/todo.org
@@ -151,37 +151,34 @@ See cleanup task below for full list of issues.
*** TODO [#C] Clean up ai-config.el
-**** Stale model list
+**** DONE Stale model list
~claude-opus-4-1-20250805~ and ~claude-3-5-sonnet-20241022~ are superseded.
Update to current model IDs (claude-opus-4-6, claude-sonnet-4-6, etc.).
-**** ~gptel-backend~ set twice
+**** DONE ~gptel-backend~ set twice
Lines 284 and 295 both do ~(setq gptel-backend gptel-claude-backend)~. Remove one.
-**** Dead code: ~cj/gptel-backends~ defvar
+**** DONE Dead code: ~cj/gptel-backends~ defvar
Static alist at line 287 duplicates ~cj/gptel--available-backends~ (line 105)
which dynamically builds the same thing. ~cj/gptel-backends~ is unused — delete it.
-**** Functions defined inside ~:config~ block
+**** DONE Functions defined inside ~:config~ block
~cj/gptel--fresh-org-prefix~, ~cj/gptel--refresh-org-prefix~,
~cj/gptel-backend-and-model~, ~cj/gptel-insert-model-heading~ are defined inside
use-package :config. Move outside like the other helpers for visibility and
byte-compilation.
-**** ~gptel-confirm-tool-calls~ set to nil
-Allows LLMs to execute tool calls without confirmation. Intentional security
-trade-off — document or reconsider.
-
-**** ~gptel-include-reasoning~ set to ~'ignore~
-Suppresses reasoning output from thinking models (o1, Claude extended thinking).
-Comment says TODO. Decide whether to enable.
+**** DONE ~gptel-include-reasoning~ set to ~'ignore~
+Changed to ~"*AI-Reasoning*"~ — reasoning redirected to a separate buffer to
+keep conversations clean while remaining reviewable. Not re-sent as context
+(saves API tokens). Can be toggled per-session via gptel menu (~C-; a M~).
**** ~gptel-magit~ loads on every magit open
Hook ~(magit-mode . gptel-magit-install)~ runs every magit session even when
AI commit messages aren't needed. Minor overhead.
-**** Rewrite bound to ~&~ — unusual mnemonic
-~gptel-rewrite~ bound to ~M-a &~. ~w~ is free in the keymap and more intuitive.
+**** DONE Rewrite bound to ~&~ — unusual mnemonic
+Rewrite moved to ~C-; a r~, clear context moved to ~C-; a c~.
**File:** modules/ai-config.el