Function: gptel--handle-post-tool

gptel--handle-post-tool is a natively compiled function defined in gptel.el.

Signature

(gptel--handle-post-tool FSM)

Documentation

Run gptel-post-tool-call-functions for FSM.

Also run the request-local :post-tool functions.

Source Code

;; Defined in /nix/store/q3r7g81pvghw7a523kjk2k2zih3pfk8z-emacs-packages-deps/share/emacs/site-lisp/elpa/gptel-20261002.545/gptel.el
(defun gptel--handle-post-tool (fsm)
  "Run `gptel-post-tool-call-functions' for FSM.

Also run the request-local :post-tool functions."
  (let* ((info (gptel-fsm-info fsm))
         (buffer (plist-get info :buffer))
         (post-tool (plist-get info :post-tool)))
    (when (buffer-local-value 'gptel-post-tool-call-functions buffer)
      (let ((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-post-tool-call-functions
           (lambda (hook-func)
             (prog1 nil
               (dolist (tool-call (plist-get info :tool-use))
                 (let* ((name (plist-get tool-call :name))
                        (args (plist-get tool-call :args))
                        (hook-func-result
                         (with-demoted-errors "gptel-post-tool-call hook error: %S"
                           (funcall hook-func
                                    (nconc (list :name name :args args
                                                 :result (plist-get tool-call :result))
                                           hook-func-args)))))
                   (if (plist-get hook-func-result :stop)
                       (let ((reason (or (plist-get hook-func-result :stop-reason)
                                         (concat "Request stopped by post-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))
                     ;; 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
                         (cl-loop       ; Update results sent to callback
                          for call in (plist-get info :tool-result)
                          for (spec stored-args _) = call
                          when (and (equal (gptel-tool-name spec) name)
                                    (null (cl-set-difference
                                           stored-args args :test #'equal)))
                          do (setf (caddr call) result) and return nil
                          finally
                          (display-warning
                           '(gptel tools)
                           (format "Tool %s: Could not replace tool results" name)))
                         ;; Update results sent to LLM
                         (plist-put tool-call :result result))))))))))))
    (when post-tool
      (mapc (lambda (f) (funcall f info)) (plist-get info :post-tool))
      (plist-put info :post-tool nil))))