add gregory grubbs ai stuff

This commit is contained in:
Peter Tillemans 2025-08-13 12:10:40 +02:00
parent 0081b2ec37
commit c0a3ae4a24

478
init.org
View file

@ -1,3 +1,4 @@
#+TITLE: My Emacs Configuration
#+PROPERTY: header-args :tangle yes
#+PROPERTY: header-args:emacs-lisp :lexical yes :tangle yes :comments nil :padline yes
@ -1573,85 +1574,88 @@ importing and exporting confluence pages.
** Mu4e Configuration
#+BEGIN_SRC emacs-lisp
(setq snm/mu4e-load-path (concat
(file-name-parent-directory
(file-name-directory
(executable-find "mu")))
"share/emacs/site-lisp/mu4e"))
(defvar snm/mu4e-load-path nil)
(if (executable-find "mu")
(let ((snm/mu4e-load-path (concat
(file-name-parent-directory
(file-name-directory
(executable-find "mu")))
"share/emacs/site-lisp/mu4e")))
(use-package mu4e
:load-path snm/mu4e-load-path
(use-package mu4e
:load-path snm/mu4e-load-path
;"/usr/share/emacs/site-lisp/mu4e"
:config
:config
;; use mu4e for e-mail in emacs
(setq mail-user-agent 'mu4e-user-agent)
;; use mu4e for e-mail in emacs
(setq mail-user-agent 'mu4e-user-agent)
(setq mu4e-drafts-folder "/[Gmail].Drafts")
(setq mu4e-sent-folder "/[Gmail].Sent Mail")
(setq mu4e-trash-folder "/[Gmail].Trash")
(setq mu4e-drafts-folder "/[Gmail].Drafts")
(setq mu4e-sent-folder "/[Gmail].Sent Mail")
(setq mu4e-trash-folder "/[Gmail].Trash")
;; don't save message to Sent Messages, Gmail/IMAP takes care of this
(setq mu4e-sent-messages-behavior 'delete)
;; don't save message to Sent Messages, Gmail/IMAP takes care of this
(setq mu4e-sent-messages-behavior 'delete)
;; (See the documentation for `mu4e-sent-messages-behavior' if you have
;; additional non-Gmail addresses and want assign them different
;; behavior.)
;; (See the documentation for `mu4e-sent-messages-behavior' if you have
;; additional non-Gmail addresses and want assign them different
;; behavior.)
;; setup some handy shortcuts
;; you can quickly switch to your Inbox -- press ``ji''
;; then, when you want archive some messages, move them to
;; the 'All Mail' folder by pressing ``ma''.
;; setup some handy shortcuts
;; you can quickly switch to your Inbox -- press ``ji''
;; then, when you want archive some messages, move them to
;; the 'All Mail' folder by pressing ``ma''.
(setq mu4e-maildir-shortcuts
'( (:maildir "/INBOX" :key ?i)
(:maildir "/[Gmail].Sent Mail" :key ?s)
(:maildir "/[Gmail].Trash" :key ?t)
(:maildir "/[Gmail].All Mail" :key ?a)))
(setq mu4e-maildir-shortcuts
'( (:maildir "/INBOX" :key ?i)
(:maildir "/[Gmail].Sent Mail" :key ?s)
(:maildir "/[Gmail].Trash" :key ?t)
(:maildir "/[Gmail].All Mail" :key ?a)))
(add-to-list 'mu4e-bookmarks
;; ':favorite t' i.e, use this one for the modeline
'(:query "maildir:/inbox" :name "Inbox" :key ?i :favorite t))
(add-to-list 'mu4e-bookmarks
;; ':favorite t' i.e, use this one for the modeline
'(:query "maildir:/inbox" :name "Inbox" :key ?i :favorite t))
;; allow for updating mail using 'U' in the main view:
(setq mu4e-get-mail-command "offlineimap")
;; allow for updating mail using 'U' in the main view:
(setq mu4e-get-mail-command "offlineimap")
;; something about ourselves
(setq
user-mail-address "pti@snamellit.com"
user-full-name "Peter Tillemans"
message-signature
(concat
"Peter Tillemans\n"
"Snamellit BV\n"
"http://www.smamellit.com\n"))
;; something about ourselves
(setq
user-mail-address "pti@snamellit.com"
user-full-name "Peter Tillemans"
message-signature
(concat
"Peter Tillemans\n"
"Snamellit BV\n"
"http://www.smamellit.com\n"))
;; sending mail -- replace USERNAME with your gmail username
;; also, make sure the gnutls command line utils are installed
;; package 'gnutls-bin' in Debian/Ubuntu
;; sending mail -- replace USERNAME with your gmail username
;; also, make sure the gnutls command line utils are installed
;; package 'gnutls-bin' in Debian/Ubuntu
(require 'smtpmail)
(setq
message-send-mail-function 'smtpmail-send-it
starttls-use-gnutls t
smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
smtpmail-auth-credentials
'(("smtp.gmail.com" 587 "pti@snamellit.com" (auth-source-pass-get 'secret "snamellit/imap.gmail.com")))
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587)
(require 'smtpmail)
(setq
message-send-mail-function 'smtpmail-send-it
starttls-use-gnutls t
smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
smtpmail-auth-credentials
'(("smtp.gmail.com" 587 "pti@snamellit.com" (auth-source-pass-get 'secret "snamellit/imap.gmail.com")))
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587)
;; alternatively, for emacs-24 you can use:
;;(setq message-send-mail-function 'smtpmail-send-it
;; smtpmail-stream-type 'starttls
;; smtpmail-default-smtp-server "smtp.gmail.com"
;; smtpmail-smtp-server "smtp.gmail.com"
;; smtpmail-smtp-service 587)
;; alternatively, for emacs-24 you can use:
;;(setq message-send-mail-function 'smtpmail-send-it
;; smtpmail-stream-type 'starttls
;; smtpmail-default-smtp-server "smtp.gmail.com"
;; smtpmail-smtp-server "smtp.gmail.com"
;; smtpmail-smtp-service 587)
;; don't keep message buffers around
(setq message-kill-buffer-on-exit t)
;; don't keep message buffers around
(setq message-kill-buffer-on-exit t)
)
)
))
#+END_SRC
#+RESULTS:
@ -3111,32 +3115,194 @@ integration in Emacs.
*** Load and Configure Model
#+BEGIN_SRC emacs-lisp
(use-package gptel
:ensure t
:commands (gptel)
:config
(setq gptel-default-mode 'org-mode
gptel-expert-commands t
gptel-track-media t
gptel-include-reasoning 'ignore
gptel-log-level 'info
gptel--debug nil)
(use-package gptel
:ensure t
;:commands (gptel)
:demand t
:config
(setq gptel-default-mode 'org-mode
gptel-expert-commands t
gptel-track-media t
gptel-include-reasoning 'ignore
gptel-log-level 'info
gptel--debug nil)
(add-to-list 'gptel-prompt-prefix-alist `(org-mode . ,(concat "*** pti " (format-time-string "[%Y-%m-%d]") "\n")))
;; follow output
(add-hook 'gptel-post-stream-hook 'gptel-auto-scroll)
;; move to next prompt after response
(add-hook 'gptel-post-response-functions 'gptel-end-of-response)
)
(add-to-list 'gptel-prompt-prefix-alist `(org-mode . ,(concat "*** pti " (format-time-string "[%Y-%m-%d]") "\n")))
;; follow output
(add-hook 'gptel-post-stream-hook 'gptel-auto-scroll)
;; move to next prompt after response
(add-hook 'gptel-post-response-functions 'gptel-end-of-response)
(use-package gptel-curl)
(use-package gptel-transient)
(use-package gptel-integrations)
(require 'gptel-curl)
(require 'gptel-transient)
(require 'gptel-integrations)
(setq gptel-api-key openai-api-key)
(gptel-make-gemini "Gemini" :key gemini-api-key :stream t)
(gptel-make-anthropic "Claude" :stream t :key anthropic-api-key)
(gptel-make-ollama "Qwen Coder"
:models '(qwen2.5-coder:14b
:description "QWen 2.5 Coder 14b"))
(gptel-make-tool
:function (lambda (url)
(with-current-buffer (url-retrieve-synchronously url)
(goto-char (point-min)) (forward-paragraph)
(let ((dom (libxml-parse-html-region (point) (point-max))))
(run-at-time 0 nil #'kill-buffer (current-buffer))
(with-temp-buffer
(shr-insert-document dom)
(buffer-substring-no-properties (point-min) (point-max))))))
:name "read_url"
:description "Fetch and read the contents of a URL"
:args (list '(:name "url"
:type "string"
:description "The URL to read"))
:category "web")
(gptel-make-tool
:function (lambda (buffer text)
(with-current-buffer (get-buffer-create buffer)
(save-excursion
(goto-char (point-max))
(insert text)))
(format "Appended text to buffer %s" buffer))
:name "append_to_buffer"
:description "Append text to the an Emacs buffer. If the buffer does not exist, it will be created."
:args (list '(:name "buffer"
:type "string"
:description "The name of the buffer to append text to.")
'(:name "text"
:type "string"
:description "The text to append to the buffer."))
:category "emacs")
;; Message buffer logging tool
(gptel-make-tool
:function (lambda (text)
(message "%s" text)
(format "Message sent: %s" text))
:name "echo_message"
:description "Send a message to the *Messages* buffer"
:args (list '(:name "text"
:type "string"
:description "The text to send to the messages buffer"))
:category "emacs")
;; buffer retrieval tool
(gptel-make-tool
:function (lambda (buffer)
(unless (buffer-live-p (get-buffer buffer))
(error "Error: buffer %s is not live." buffer))
(with-current-buffer buffer
(buffer-substring-no-properties (point-min) (point-max))))
:name "read_buffer"
:description "Return the contents of an Emacs buffer"
:args (list '(:name "buffer"
:type "string"
:description "The name of the buffer whose contents are to be retrieved"))
:category "emacs")
(gptel-make-tool
:function (lambda (directory)
(mapconcat #'identity
(directory-files directory)
"\n"))
:name "list_directory"
:description "List the contents of a given directory"
:args (list '(:name "directory"
:type "string"
:description "The path to the directory to list"))
:category "filesystem")
(gptel-make-tool
:function (lambda (parent name)
(condition-case nil
(progn
(make-directory (expand-file-name name parent) t)
(format "Directory %s created/verified in %s" name parent))
(error (format "Error creating directory %s in %s" name parent))))
:name "make_directory"
:description "Create a new directory with the given name in the specified parent directory"
:args (list '(:name "parent"
:type "string"
:description "The parent directory where the new directory should be created, e.g. /tmp")
'(:name "name"
:type "string"
:description "The name of the new directory to create, e.g. testdir"))
:category "filesystem")
(gptel-make-tool
:function (lambda (path filename content)
(let ((full-path (expand-file-name filename path)))
(with-temp-buffer
(insert content)
(write-file full-path))
(format "Created file %s in %s" filename path)))
:name "create_file"
:description "Create a new file with the specified content"
:args (list '(:name "path"
:type "string"
:description "The directory where to create the file")
'(:name "filename"
:type "string"
:description "The name of the file to create")
'(:name "content"
:type "string"
:description "The content to write to the file"))
:category "filesystem")
(gptel-make-tool
:function (lambda (filepath)
(with-temp-buffer
(insert-file-contents (expand-file-name filepath))
(buffer-string)))
:name "read_file"
:description "Read and display the contents of a file"
:args (list '(:name "filepath"
:type "string"
:description "Path to the file to read. Supports relative paths and ~."))
:category "filesystem")
)
#+END_SRC
#+RESULTS:
*** TODO Load MCP.el
placeholder
check [[https://www.youtube.com/watch?v=Hkih7jaqOnE&t=544s][Agentic LLM use in Emacs using Model Context Protocol (MCP)]] of
Gregg Grubbs for examples what to put here.
#+BEGIN_SRC emacs-lisp :tangle no
(use-package mcp
:ensure t
:after gptel
:custom (mcp-hub-servers
`(("filesystem" . (:command "npx" :args ("-y" "@modelcontextprotocol/server-filesystem" "/home/lizqwer/MyProject/")))
("fetch" . (:command "uvx" :args ("mcp-server-fetch")))
("qdrant" . (:url "http://localhost:8000/sse"))
("graphlit" . (
:command "npx"
:args ("-y" "graphlit-mcp-server")
:env (
:GRAPHLIT_ORGANIZATION_ID "your-organization-id"
:GRAPHLIT_ENVIRONMENT_ID "your-environment-id"
:GRAPHLIT_JWT_SECRET "your-jwt-secret")))))
:config (require 'mcp-hub)
:hook (after-init . mcp-hub-start-all-server))
#+END_SRC
*** Load jwiegley/gptel-prompts for prompt composability
This package offers an alternative way to manage your ~gptel-directives~ variable, using files rather than customizing the variable directly.
@ -3206,152 +3372,6 @@ file itself to use what is easiest to maintain in the editor.
NOTE: If you wish to use the Prompt Poet format, you will need to
install the Emacs dependencies yaml and templatel.
*** Models
#+BEGIN_SRC emacs-lisp
(setq gptel-api-key openai-api-key)
(gptel-make-gemini "Gemini" :key gemini-api-key :stream t)
(gptel-make-anthropic "Claude" :stream t :key anthropic-api-key)
(gptel-make-ollama "Qwen Coder"
:models '(qwen2.5-coder:14b
:description "QWen 2.5 Coder 14b"))
#+END_SRC
#+RESULTS:
: #s(gptel-ollama "Qwen Coder" "localhost:11434" nil "http" nil "/api/chat" nil (qwen2.5-coder:14b :description QWen\ 2.5\ Coder\ 14b) "http://localhost:11434/api/chat" nil nil nil)
*** Tools
#+BEGIN_SRC emacs-lisp
;; define some tools for gptel
(gptel-make-tool
:function (lambda (url)
(with-current-buffer (url-retrieve-synchronously url)
(goto-char (point-min)) (forward-paragraph)
(let ((dom (libxml-parse-html-region (point) (point-max))))
(run-at-time 0 nil #'kill-buffer (current-buffer))
(with-temp-buffer
(shr-insert-document dom)
(buffer-substring-no-properties (point-min) (point-max))))))
:name "read_url"
:description "Fetch and read the contents of a URL"
:args (list '(:name "url"
:type "string"
:description "The URL to read"))
:category "web")
(gptel-make-tool
:function (lambda (buffer text)
(with-current-buffer (get-buffer-create buffer)
(save-excursion
(goto-char (point-max))
(insert text)))
(format "Appended text to buffer %s" buffer))
:name "append_to_buffer"
:description "Append text to the an Emacs buffer. If the buffer does not exist, it will be created."
:args (list '(:name "buffer"
:type "string"
:description "The name of the buffer to append text to.")
'(:name "text"
:type "string"
:description "The text to append to the buffer."))
:category "emacs")
;; Message buffer logging tool
(gptel-make-tool
:function (lambda (text)
(message "%s" text)
(format "Message sent: %s" text))
:name "echo_message"
:description "Send a message to the *Messages* buffer"
:args (list '(:name "text"
:type "string"
:description "The text to send to the messages buffer"))
:category "emacs")
;; buffer retrieval tool
(gptel-make-tool
:function (lambda (buffer)
(unless (buffer-live-p (get-buffer buffer))
(error "Error: buffer %s is not live." buffer))
(with-current-buffer buffer
(buffer-substring-no-properties (point-min) (point-max))))
:name "read_buffer"
:description "Return the contents of an Emacs buffer"
:args (list '(:name "buffer"
:type "string"
:description "The name of the buffer whose contents are to be retrieved"))
:category "emacs")
(gptel-make-tool
:function (lambda (directory)
(mapconcat #'identity
(directory-files directory)
"\n"))
:name "list_directory"
:description "List the contents of a given directory"
:args (list '(:name "directory"
:type "string"
:description "The path to the directory to list"))
:category "filesystem")
(gptel-make-tool
:function (lambda (parent name)
(condition-case nil
(progn
(make-directory (expand-file-name name parent) t)
(format "Directory %s created/verified in %s" name parent))
(error (format "Error creating directory %s in %s" name parent))))
:name "make_directory"
:description "Create a new directory with the given name in the specified parent directory"
:args (list '(:name "parent"
:type "string"
:description "The parent directory where the new directory should be created, e.g. /tmp")
'(:name "name"
:type "string"
:description "The name of the new directory to create, e.g. testdir"))
:category "filesystem")
(gptel-make-tool
:function (lambda (path filename content)
(let ((full-path (expand-file-name filename path)))
(with-temp-buffer
(insert content)
(write-file full-path))
(format "Created file %s in %s" filename path)))
:name "create_file"
:description "Create a new file with the specified content"
:args (list '(:name "path"
:type "string"
:description "The directory where to create the file")
'(:name "filename"
:type "string"
:description "The name of the file to create")
'(:name "content"
:type "string"
:description "The content to write to the file"))
:category "filesystem")
(gptel-make-tool
:function (lambda (filepath)
(with-temp-buffer
(insert-file-contents (expand-file-name filepath))
(buffer-string)))
:name "read_file"
:description "Read and display the contents of a file"
:args (list '(:name "filepath"
:type "string"
:description "Path to the file to read. Supports relative paths and ~."))
:category "filesystem")
#+END_SRC
** Copilot Support
#+BEGIN_SRC emacs-lisp