Function: gptel--handle-pre-tool
gptel--handle-pre-tool is a natively compiled function defined in
gptel.el.
Signature
(gptel--handle-pre-tool FSM)
Documentation
Run gptel-pre-tool-call-functions for FSM.
Source Code
;; Defined in /nix/store/q3r7g81pvghw7a523kjk2k2zih3pfk8z-emacs-packages-deps/share/emacs/site-lisp/elpa/gptel-20261002.545/gptel.el
(defun gptel--handle-pre-tool (fsm)
"Run `gptel-pre-tool-call-functions' for FSM."
(let* ((info (gptel-fsm-info fsm))
(buffer (plist-get info :buffer)))
(when (buffer-local-value 'gptel-pre-tool-call-functions buffer)
;; This function might run many times, so only act on the remaining tool calls.
(let ((tool-use (cl-remove-if (lambda (tc) (plist-get tc :result))
(plist-get info :tool-use)))
(hook-func-args (list :buffer (buffer-name buffer)
:backend (plist-get info :backend)
:model (plist-get info :model))))
(with-current-buffer buffer
(run-hook-wrapped ; Run pre tool call functions
'gptel-pre-tool-call-functions
(lambda (hook-func)
(prog1 nil
(dolist (tool-call tool-use)
(let* ((name (plist-get tool-call :name))
(args (plist-get tool-call :args))
(hook-func-result
(with-demoted-errors "gptel-pre-tool-call hook error: %S"
(funcall hook-func (nconc (list :name name :args args)
hook-func-args)))))
(if (plist-get hook-func-result :stop) ; Stop the request immediately
(let ((reason (or (plist-get hook-func-result :stop-reason)
(concat "Request stopped by pre-tool-call hook "
(and (symbolp hook-func)
(symbol-name hook-func))
" (tool \"" name "\")"))))
(plist-put info :stop-reason reason)
(plist-put info :status "Stopped by hook")
(plist-put info :error reason))
;; if hook-func returns :confirm, add the check
(when-let* ((confirm-tail
(plist-member hook-func-result :confirm)))
(plist-put tool-call :confirm (cadr confirm-tail)))
;; if hook-func returns :args or :name, replace in the call
(when (or (plist-get hook-func-result :args)
(plist-get hook-func-result :name))
;; Merge with args in the messages array sent to the LLM
(gptel--inject-tool-call
(plist-get info :backend) (plist-get info :data)
tool-call hook-func-result)
;; Merge with the tool-call in tool-use that actually runs
(gptel--merge-plists tool-call hook-func-result))
;; TODO(tool-hooks): :block behavior not final!
(let ((blockp (plist-get hook-func-result :block))
(result (plist-get hook-func-result :result)))
(when blockp
(plist-put tool-call :error t)
(setq result
(concat "<tool_call_error>\n"
(if (stringp blockp) blockp
(format "Tool %s blocked by user" name))
"\n</tool_call_error>")))
(when result
(gptel--process-tool-call
fsm (cl-find-if (lambda (ts) (equal (gptel-tool-name ts) name))
(plist-get info :tools))
tool-call result))))))))))))))