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))))))))))))))