copilot-emacs / copilot.el

An unofficial Copilot plugin for Emacs.
MIT License
1.72k stars 122 forks source link

jsonrpc-error: request id=1 failed:, (jsonrpc-error-message . Timed out) #204

Closed anildigital closed 7 months ago

anildigital commented 7 months ago

When Emacs is started

jsonrpc-error: request id=1 failed:, (jsonrpc-error-message . Timed out)

To ensure normal operation, you should investigate and remove the
cause of the error in your initialization file.  Start Emacs with
the ‘--debug-init’ option to view a complete error backtrace.
Loading /Users/anil/.config/emacs/vendor/copilot.el/copilot-balancer.el (source)...done
Loading /Users/anil/.config/emacs/vendor/copilot.el/copilot.el (source)...done
Copilot agent started.
error in process filter: Unbound slot: jsonrpc-process-connection, "#<jsonrpc-process-connection jsonrpc-process-connection-566d9c44>", -expected-bytes, oref [4 times]

Doing M-x copilot-diagnose

error in process sentinel: Unbound slot: jsonrpc-process-connection, "#<jsonrpc-process-connection jsonrpc-process-connection-49204542>", -events-buffer, oref [4 times]
[jsonrpc] (warning) Sentinel for copilot agent still hasn't run, deleting it! [41 times]

Also debugger logs

Debugger entered--Lisp error: (jsonrpc-error "request id=1 failed:" (jsonrpc-error-message . "Timed out"))
  signal(jsonrpc-error ("request id=1 failed:" (jsonrpc-error-message . "Timed out")))
  jsonrpc-request(#<jsonrpc-process-connection jsonrpc-process-connection-4ecb908a> initialize (:capabilities (:workspace (:workspaceFolders t))))
  (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities (:workspace (:workspaceFolders t)))))
  (cond ((< node-version 16) (user-error "Node 16+ is required but found %s" node-version)) (t (setq copilot--connection (make-instance 'jsonrpc-process-connection :name "copilot" :events-buffer-scrollback-size copilot-log-max :notification-dispatcher #'copilot--handle-notification :process (make-process :name "copilot agent" :command (list copilot-node-executable (concat copilot--base-dir "/dist/agent.js")) :coding 'utf-8-emacs-unix :connection-type 'pipe :stderr (get-buffer-create "*copilot stderr*") :noquery t))) (message "Copilot agent started.") (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities (:workspace (:workspaceFolders t))))) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (let ((buf (current-buffer))) (jsonrpc-async-request copilot--connection 'setEditorInfo (cons ':editorInfo (cons (list ... "Emacs" ... emacs-version) (cons ... ...))) :success-fn #'(lambda (result) (save-current-buffer ... ...)))))))
  (let ((node-version (string-to-number (s-chop-prefix "v" (s-trim (let (...) (unwind-protect ... ...))))))) (cond ((< node-version 16) (user-error "Node 16+ is required but found %s" node-version)) (t (setq copilot--connection (make-instance 'jsonrpc-process-connection :name "copilot" :events-buffer-scrollback-size copilot-log-max :notification-dispatcher #'copilot--handle-notification :process (make-process :name "copilot agent" :command (list copilot-node-executable (concat copilot--base-dir "/dist/agent.js")) :coding 'utf-8-emacs-unix :connection-type 'pipe :stderr (get-buffer-create "*copilot stderr*") :noquery t))) (message "Copilot agent started.") (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities (:workspace ...)))) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (let ((buf (current-buffer))) (jsonrpc-async-request copilot--connection 'setEditorInfo (cons ':editorInfo (cons ... ...)) :success-fn #'(lambda ... ...)))))))
  (if (not (locate-file copilot-node-executable exec-path)) (user-error "Could not find node executable") (let ((node-version (string-to-number (s-chop-prefix "v" (s-trim (let ... ...)))))) (cond ((< node-version 16) (user-error "Node 16+ is required but found %s" node-version)) (t (setq copilot--connection (make-instance 'jsonrpc-process-connection :name "copilot" :events-buffer-scrollback-size copilot-log-max :notification-dispatcher #'copilot--handle-notification :process (make-process :name "copilot agent" :command (list copilot-node-executable ...) :coding 'utf-8-emacs-unix :connection-type 'pipe :stderr (get-buffer-create "*copilot stderr*") :noquery t))) (message "Copilot agent started.") (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities ...))) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (let ((buf ...)) (jsonrpc-async-request copilot--connection 'setEditorInfo (cons ... ...) :success-fn #'...)))))))
  copilot--start-agent()
  (if (copilot--connection-alivep) nil (copilot--start-agent))
  (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source)))))
  (if (-contains-p copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didFocus (list :textDocument (list :uri (copilot--get-uri))))) (add-to-list 'copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source))))))
  (progn (if (-contains-p copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didFocus (list :textDocument (list :uri (copilot--get-uri))))) (add-to-list 'copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source)))))))
  (if (and copilot-mode (eq window (selected-window))) (progn (if (-contains-p copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didFocus (list :textDocument (list :uri (copilot--get-uri))))) (add-to-list 'copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source))))))))
  copilot--on-doc-focus(#<window 3 on .private.el>)
  copilot--mode-enter()
  (if copilot-mode (copilot--mode-enter) (copilot--mode-exit))
  (let ((last-message (current-message))) (setq copilot-mode (cond ((eq arg 'toggle) (not copilot-mode)) ((and (numberp arg) (< arg 1)) nil) (t t))) (if (boundp 'local-minor-modes) (progn (setq local-minor-modes (delq 'copilot-mode local-minor-modes)) (if copilot-mode (progn (setq local-minor-modes (cons 'copilot-mode local-minor-modes)))))) (copilot-clear-overlay) (advice-add 'posn-at-point :before-until #'copilot--posn-advice) (if copilot-mode (copilot--mode-enter) (copilot--mode-exit)) (run-hooks 'copilot-mode-hook (if copilot-mode 'copilot-mode-on-hook 'copilot-mode-off-hook)) (if (called-interactively-p 'any) (progn nil (if (and (current-message) (not (equal last-message (current-message)))) nil (let ((local " in current buffer")) (message "%s %sabled%s" "Copilot mode" (if copilot-mode "en" "dis") local))))))
  copilot-mode()
  (if copilot-mode (copilot--on-doc-focus (selected-window)) (copilot-mode))
  copilot-diagnose()
  eval((copilot-diagnose) nil)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  command-execute(eval-last-sexp)

I tried with following config

(require 'quelpa)
(use-package copilot
  :quelpa (copilot :fetcher github
                   :repo "zerolfx/copilot.el"
                   :branch "main"
                   :files ("dist" "*.el"))
  :config
  (with-eval-after-load 'company
    ;; disable inline previews
    (delq 'company-preview-if-just-one-frontend company-frontends))

  (define-key copilot-completion-map (kbd "<tab>") 'copilot-accept-completion)
  (define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion)

  (add-hook 'prog-mode-hook 'copilot-mode)

  (copilot-diagnose)
  )

Using GNU Emacs 30.0.50 (build 1, aarch64-apple-darwin23.1.0, NS appkit-2487.20 Version 14.1.1 (Build 23B81)) of 2023-11-28

LazerJesus commented 7 months ago

+1 on M1 mac ventura 13.5.1 emacs 30.0.50

installed with straight. dash, s and editorconfig are available.

  (use-package s
    :straight (:host github :repo "magnars/s.el");; :files ("s.el"))
    :ensure t)

  (use-package dash
    :straight (:host github :repo "magnars/dash.el");; :files ("dash.el"))
    :ensure t)

  (use-package editorconfig
    :ensure t
    :config
    (editorconfig-mode 1))

  (use-package copilot
    :straight (:host github :repo "zerolfx/copilot.el" :files ("dist" "*.el"))
    :ensure t)

  (dolist (mode '(python-mode-hook
                  svelte-mode-hook
                  js-mode-hook
                  org-mode-hook))
    (add-hook mode 'copilot-mode))
anildigital commented 7 months ago

@zerolfx Sorry to tag, but is it something obvious? thanks

LazerJesus commented 7 months ago

https://github.com/zerolfx/copilot.el/issues/185 https://github.com/zerolfx/copilot.el/issues/187 seems like a common issue atm. suggested solution is manual install and require. will try and feed back.

LazerJesus commented 7 months ago
  (add-to-list 'load-path  "emcas/straight/repo/copilot.el")
  (require 'copilot)

solves the issue for me, where copilot.el is the name of the folder containing the .el with the same name.

anildigital commented 7 months ago

@LazerJesus I am still getting the following error

For a moment, it shows copilot agent started and then below stacktrace shows up

Debugger entered--Lisp error: (unbound-slot jsonrpc-process-connection "#<jsonrpc-process-connection jsonrpc-process-connection-462218da>" -expected-bytes oref)
  signal(unbound-slot (jsonrpc-process-connection "#<jsonrpc-process-connection jsonrpc-process-connection-462218da>" -expected-bytes oref))
  #f(compiled-function (object class slot-name fn) "Slot unbound is invoked during an attempt to reference an unbound slot.\nOBJECT is the instance of the object being reference.  CLASS is the\nclass of OBJECT, and SLOT-NAME is the offending slot.  This function\nthrows the signal `unbound-slot'.  You can overload this function and\nreturn the value to use in place of the unbound value.\nArgument FN is the function signaling this error.\nUse `slot-boundp' to determine if a slot is bound or not.\n\nIn CLOS, the argument list is (CLASS OBJECT SLOT-NAME), but\nEIEIO can only dispatch on the first argument, so the first two are swapped." #<bytecode 0x4937fc2b1d79c28>)(#<jsonrpc-process-connection jsonrpc-process-connection-462218da> #s(eieio--class :name jsonrpc-process-connection :docstring "A JSONRPC connection over an Emacs process.\nThe following initargs are accepted:\n\n:PROCESS (mandatory), a live running Emacs process object or a\nfunction of no arguments producing one such object.  The process\nrepresents either a pipe connection to locally running process or\na stream connection to a network host.  The remote endpoint is\nexpected to understand JSONRPC messages with basic HTTP-style\nenveloping headers such as \"Content-Length:\".\n\n:ON-SHUTDOWN (optional), a function of one argument, the\nconnection object, called when the process dies." :parents (#s(eieio--class :name jsonrpc-connection :docstring "Base class representing a JSONRPC connection.\nThe following initargs are accepted:\n\n:NAME (mandatory), a string naming the connection\n\n:REQUEST-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC requests.\nCONN is a `jsonrpc-connection' object, method is a symbol, and\nPARAMS is a plist representing a JSON object.  The function is\nexpected to return a JSONRPC result, a plist of (:result\nRESULT) or signal an error of type `jsonrpc-error'.\n\n:NOTIFICATION-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC\nnotifications.  CONN, METHOD and PARAMS are the same as in\n:REQUEST-DISPATCHER." :parents nil :slots ... :index-table #<hash-table eq 9/65 0x43e0a15f ...> :children ... :initarg-tuples ... :class-slots ... :class-allocation-values ... :default-object-cache #<jsonrpc-connection jsonrpc-connection-48233dc6> :options ...)) :slots [#s(cl-slot-descriptor :name name :initform ... :type t :props ...) #s(cl-slot-descriptor :name -request-dispatcher :initform ... :type t :props ...) #s(cl-slot-descriptor :name -notification-dispatcher :initform ... :type t :props ...) #s(cl-slot-descriptor :name last-error :initform ... :type t :props ...) #s(cl-slot-descriptor :name -request-continuations :initform ... :type t :props ...) #s(cl-slot-descriptor :name -events-buffer :initform ... :type t :props ...) #s(cl-slot-descriptor :name -events-buffer-scrollback-size :initform ... :type t :props ...) #s(cl-slot-descriptor :name -deferred-actions :initform ... :type t :props ...) #s(cl-slot-descriptor :name -next-request-id :initform 0 :type t :props ...) #s(cl-slot-descriptor :name -process :initform ... :type t :props ...) #s(cl-slot-descriptor :name -expected-bytes :initform ... :type t :props ...) #s(cl-slot-descriptor :name -on-shutdown :initform ... :type t :props ...)] :index-table #<hash-table eq 12/65 0x47c48933 ...> :children nil :initarg-tuples ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:events-buffer-scrollback-size . -events-buffer-scrollback-size) (:process . -process) (:on-shutdown . -on-shutdown)) :class-slots [] :class-allocation-values [] :default-object-cache #<jsonrpc-process-connection jsonrpc-process-connection-43c66446> :options (:custom-groups nil :documentation "A JSONRPC connection over an Emacs process.\nThe following initargs are accepted:\n\n:PROCESS (mandatory), a live running Emacs process object or a\nfunction of no arguments producing one such object.  The process\nrepresents either a pipe connection to locally running process or\na stream connection to a network host.  The remote endpoint is\nexpected to understand JSONRPC messages with basic HTTP-style\nenveloping headers such as \"Content-Length:\".\n\n:ON-SHUTDOWN (optional), a function of one argument, the\nconnection object, called when the process dies.")) -expected-bytes oref)
  apply(#f(compiled-function (object class slot-name fn) "Slot unbound is invoked during an attempt to reference an unbound slot.\nOBJECT is the instance of the object being reference.  CLASS is the\nclass of OBJECT, and SLOT-NAME is the offending slot.  This function\nthrows the signal `unbound-slot'.  You can overload this function and\nreturn the value to use in place of the unbound value.\nArgument FN is the function signaling this error.\nUse `slot-boundp' to determine if a slot is bound or not.\n\nIn CLOS, the argument list is (CLASS OBJECT SLOT-NAME), but\nEIEIO can only dispatch on the first argument, so the first two are swapped." #<bytecode 0x4937fc2b1d79c28>) #<jsonrpc-process-connection jsonrpc-process-connection-462218da> (#s(eieio--class :name jsonrpc-process-connection :docstring "A JSONRPC connection over an Emacs process.\nThe following initargs are accepted:\n\n:PROCESS (mandatory), a live running Emacs process object or a\nfunction of no arguments producing one such object.  The process\nrepresents either a pipe connection to locally running process or\na stream connection to a network host.  The remote endpoint is\nexpected to understand JSONRPC messages with basic HTTP-style\nenveloping headers such as \"Content-Length:\".\n\n:ON-SHUTDOWN (optional), a function of one argument, the\nconnection object, called when the process dies." :parents (#s(eieio--class :name jsonrpc-connection :docstring "Base class representing a JSONRPC connection.\nThe following initargs are accepted:\n\n:NAME (mandatory), a string naming the connection\n\n:REQUEST-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC requests.\nCONN is a `jsonrpc-connection' object, method is a symbol, and\nPARAMS is a plist representing a JSON object.  The function is\nexpected to return a JSONRPC result, a plist of (:result\nRESULT) or signal an error of type `jsonrpc-error'.\n\n:NOTIFICATION-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC\nnotifications.  CONN, METHOD and PARAMS are the same as in\n:REQUEST-DISPATCHER." :parents nil :slots ... :index-table #<hash-table eq 9/65 0x43e0a15f ...> :children ... :initarg-tuples ... :class-slots ... :class-allocation-values ... :default-object-cache #<jsonrpc-connection jsonrpc-connection-48233dc6> :options ...)) :slots [#s(cl-slot-descriptor :name name :initform ... :type t :props ...) #s(cl-slot-descriptor :name -request-dispatcher :initform ... :type t :props ...) #s(cl-slot-descriptor :name -notification-dispatcher :initform ... :type t :props ...) #s(cl-slot-descriptor :name last-error :initform ... :type t :props ...) #s(cl-slot-descriptor :name -request-continuations :initform ... :type t :props ...) #s(cl-slot-descriptor :name -events-buffer :initform ... :type t :props ...) #s(cl-slot-descriptor :name -events-buffer-scrollback-size :initform ... :type t :props ...) #s(cl-slot-descriptor :name -deferred-actions :initform ... :type t :props ...) #s(cl-slot-descriptor :name -next-request-id :initform 0 :type t :props ...) #s(cl-slot-descriptor :name -process :initform ... :type t :props ...) #s(cl-slot-descriptor :name -expected-bytes :initform ... :type t :props ...) #s(cl-slot-descriptor :name -on-shutdown :initform ... :type t :props ...)] :index-table #<hash-table eq 12/65 0x47c48933 ...> :children nil :initarg-tuples ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:events-buffer-scrollback-size . -events-buffer-scrollback-size) (:process . -process) (:on-shutdown . -on-shutdown)) :class-slots [] :class-allocation-values [] :default-object-cache #<jsonrpc-process-connection jsonrpc-process-connection-43c66446> :options (:custom-groups nil :documentation "A JSONRPC connection over an Emacs process.\nThe following initargs are accepted:\n\n:PROCESS (mandatory), a live running Emacs process object or a\nfunction of no arguments producing one such object.  The process\nrepresents either a pipe connection to locally running process or\na stream connection to a network host.  The remote endpoint is\nexpected to understand JSONRPC messages with basic HTTP-style\nenveloping headers such as \"Content-Length:\".\n\n:ON-SHUTDOWN (optional), a function of one argument, the\nconnection object, called when the process dies.")) -expected-bytes oref))
  slot-unbound(#<jsonrpc-process-connection jsonrpc-process-connection-462218da> #s(eieio--class :name jsonrpc-process-connection :docstring "A JSONRPC connection over an Emacs process.\nThe following initargs are accepted:\n\n:PROCESS (mandatory), a live running Emacs process object or a\nfunction of no arguments producing one such object.  The process\nrepresents either a pipe connection to locally running process or\na stream connection to a network host.  The remote endpoint is\nexpected to understand JSONRPC messages with basic HTTP-style\nenveloping headers such as \"Content-Length:\".\n\n:ON-SHUTDOWN (optional), a function of one argument, the\nconnection object, called when the process dies." :parents (#s(eieio--class :name jsonrpc-connection :docstring "Base class representing a JSONRPC connection.\nThe following initargs are accepted:\n\n:NAME (mandatory), a string naming the connection\n\n:REQUEST-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC requests.\nCONN is a `jsonrpc-connection' object, method is a symbol, and\nPARAMS is a plist representing a JSON object.  The function is\nexpected to return a JSONRPC result, a plist of (:result\nRESULT) or signal an error of type `jsonrpc-error'.\n\n:NOTIFICATION-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC\nnotifications.  CONN, METHOD and PARAMS are the same as in\n:REQUEST-DISPATCHER." :parents nil :slots [... ... ... ... ... ... ... ... ...] :index-table #<hash-table eq 9/65 0x43e0a15f ...> :children (jsonrpc-process-connection) :initarg-tuples (... ... ... ...) :class-slots [] :class-allocation-values [] :default-object-cache #<jsonrpc-connection jsonrpc-connection-48233dc6> :options (:custom-groups nil :documentation "Base class representing a JSONRPC connection.\nThe following initargs are accepted:\n\n:NAME (mandatory), a string naming the connection\n\n:REQUEST-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC requests.\nCONN is a `jsonrpc-connection' object, method is a symbol, and\nPARAMS is a plist representing a JSON object.  The function is\nexpected to return a JSONRPC result, a plist of (:result\nRESULT) or signal an error of type `jsonrpc-error'.\n\n:NOTIFICATION-DISPATCHER (optional), a function of three\narguments (CONN METHOD PARAMS) for handling JSONRPC\nnotifications.  CONN, METHOD and PARAMS are the same as in\n:REQUEST-DISPATCHER."))) :slots [#s(cl-slot-descriptor :name name :initform 'eieio--unbound :type t :props (...)) #s(cl-slot-descriptor :name -request-dispatcher :initform #'ignore :type t :props (...)) #s(cl-slot-descriptor :name -notification-dispatcher :initform #'ignore :type t :props (...)) #s(cl-slot-descriptor :name last-error :initform 'eieio--unbound :type t :props (...)) #s(cl-slot-descriptor :name -request-continuations :initform (make-hash-table) :type t :props (...)) #s(cl-slot-descriptor :name -events-buffer :initform 'eieio--unbound :type t :props (...)) #s(cl-slot-descriptor :name -events-buffer-scrollback-size :initform 'eieio--unbound :type t :props (...)) #s(cl-slot-descriptor :name -deferred-actions :initform (make-hash-table :test ...) :type t :props (...)) #s(cl-slot-descriptor :name -next-request-id :initform 0 :type t :props (...)) #s(cl-slot-descriptor :name -process :initform 'eieio--unbound :type t :props (...)) #s(cl-slot-descriptor :name -expected-bytes :initform 'eieio--unbound :type t :props (...)) #s(cl-slot-descriptor :name -on-shutdown :initform #'ignore :type t :props (...))] :index-table #<hash-table eq 12/65 0x47c48933 ...> :children nil :initarg-tuples ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:events-buffer-scrollback-size . -events-buffer-scrollback-size) (:process . -process) (:on-shutdown . -on-shutdown)) :class-slots [] :class-allocation-values [] :default-object-cache #<jsonrpc-process-connection jsonrpc-process-connection-43c66446> :options (:custom-groups nil :documentation "A JSONRPC connection over an Emacs process.\nThe following initargs are accepted:\n\n:PROCESS (mandatory), a live running Emacs process object or a\nfunction of no arguments producing one such object.  The process\nrepresents either a pipe connection to locally running process or\na stream connection to a network host.  The remote endpoint is\nexpected to understand JSONRPC messages with basic HTTP-style\nenveloping headers such as \"Content-Length:\".\n\n:ON-SHUTDOWN (optional), a function of one argument, the\nconnection object, called when the process dies.")) -expected-bytes oref)
  eieio-barf-if-slot-unbound(eieio--unbound #<jsonrpc-process-connection jsonrpc-process-connection-462218da> -expected-bytes oref)
  slot-value(#<jsonrpc-process-connection jsonrpc-process-connection-462218da> -expected-bytes)
  #f(compiled-function (this) "Retrieve the slot `-expected-bytes' from an object of class\n`jsonrpc-process-connection'." #<bytecode -0x122dd00ff6a3a3d1>)(#<jsonrpc-process-connection jsonrpc-process-connection-462218da>)
  apply(#f(compiled-function (this) "Retrieve the slot `-expected-bytes' from an object of class\n`jsonrpc-process-connection'." #<bytecode -0x122dd00ff6a3a3d1>) #<jsonrpc-process-connection jsonrpc-process-connection-462218da> nil)
  jsonrpc--expected-bytes(#<jsonrpc-process-connection jsonrpc-process-connection-462218da>)
  jsonrpc--process-filter(#<process copilot agent> "Content-Length: 232\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"LogMessage\",\"params\":{\"level\":0,\"message\":\"[DEBUG] [agent] [2023-12-04T10:30:17.109Z] Agent service starting\",\"metadataStr\":\"[DEBUG] [agent] [2023-12-04T10:30:17.109Z]\",\"extra\":[\"Agent service starting\"]}}")
  accept-process-output(nil 30)
  jsonrpc-request(#<jsonrpc-process-connection jsonrpc-process-connection-462218da> initialize (:capabilities (:workspace (:workspaceFolders t))))
  (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities (:workspace (:workspaceFolders t)))))
  (cond ((< node-version 16) (user-error "Node 16+ is required but found %s" node-version)) (t (setq copilot--connection (make-instance 'jsonrpc-process-connection :name "copilot" :events-buffer-scrollback-size copilot-log-max :notification-dispatcher #'copilot--handle-notification :process (make-process :name "copilot agent" :command (list copilot-node-executable (concat copilot--base-dir "/dist/agent.js")) :coding 'utf-8-emacs-unix :connection-type 'pipe :stderr (get-buffer-create "*copilot stderr*") :noquery t))) (message "Copilot agent started.") (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities (:workspace (:workspaceFolders t))))) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (let ((buf (current-buffer))) (jsonrpc-async-request copilot--connection 'setEditorInfo (cons ':editorInfo (cons (list ... "Emacs" ... emacs-version) (cons ... ...))) :success-fn #'(lambda (result) (save-current-buffer ... ...)))))))
  (let ((node-version (string-to-number (s-chop-prefix "v" (s-trim (let (...) (unwind-protect ... ...))))))) (cond ((< node-version 16) (user-error "Node 16+ is required but found %s" node-version)) (t (setq copilot--connection (make-instance 'jsonrpc-process-connection :name "copilot" :events-buffer-scrollback-size copilot-log-max :notification-dispatcher #'copilot--handle-notification :process (make-process :name "copilot agent" :command (list copilot-node-executable (concat copilot--base-dir "/dist/agent.js")) :coding 'utf-8-emacs-unix :connection-type 'pipe :stderr (get-buffer-create "*copilot stderr*") :noquery t))) (message "Copilot agent started.") (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities (:workspace ...)))) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (let ((buf (current-buffer))) (jsonrpc-async-request copilot--connection 'setEditorInfo (cons ':editorInfo (cons ... ...)) :success-fn #'(lambda ... ...)))))))
  (if (not (locate-file copilot-node-executable exec-path)) (user-error "Could not find node executable") (let ((node-version (string-to-number (s-chop-prefix "v" (s-trim (let ... ...)))))) (cond ((< node-version 16) (user-error "Node 16+ is required but found %s" node-version)) (t (setq copilot--connection (make-instance 'jsonrpc-process-connection :name "copilot" :events-buffer-scrollback-size copilot-log-max :notification-dispatcher #'copilot--handle-notification :process (make-process :name "copilot agent" :command (list copilot-node-executable ...) :coding 'utf-8-emacs-unix :connection-type 'pipe :stderr (get-buffer-create "*copilot stderr*") :noquery t))) (message "Copilot agent started.") (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-request copilot--connection 'initialize '(:capabilities ...))) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (let ((buf ...)) (jsonrpc-async-request copilot--connection 'setEditorInfo (cons ... ...) :success-fn #'...)))))))
  copilot--start-agent()
  (if (copilot--connection-alivep) nil (copilot--start-agent))
  (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source)))))
  (if (-contains-p copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didFocus (list :textDocument (list :uri (copilot--get-uri))))) (add-to-list 'copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source))))))
  (progn (if (-contains-p copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didFocus (list :textDocument (list :uri (copilot--get-uri))))) (add-to-list 'copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source)))))))
  (if (and copilot-mode (eq window (selected-window))) (progn (if (-contains-p copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didFocus (list :textDocument (list :uri (copilot--get-uri))))) (add-to-list 'copilot--opened-buffers (current-buffer)) (progn (if (copilot--connection-alivep) nil (copilot--start-agent)) (jsonrpc-notify copilot--connection ':textDocument/didOpen (list :textDocument (list :uri (copilot--get-uri) :languageId (copilot--get-language-id) :version copilot--doc-version :text (copilot--get-source))))))))
  copilot--on-doc-focus(#<window 7 on .private.el>)
  copilot--mode-enter()
  (if copilot-mode (copilot--mode-enter) (copilot--mode-exit))
  (let ((last-message (current-message))) (setq copilot-mode (cond ((eq arg 'toggle) (not copilot-mode)) ((and (numberp arg) (< arg 1)) nil) (t t))) (if (boundp 'local-minor-modes) (progn (setq local-minor-modes (delq 'copilot-mode local-minor-modes)) (if copilot-mode (progn (setq local-minor-modes (cons 'copilot-mode local-minor-modes)))))) (copilot-clear-overlay) (advice-add 'posn-at-point :before-until #'copilot--posn-advice) (if copilot-mode (copilot--mode-enter) (copilot--mode-exit)) (run-hooks 'copilot-mode-hook (if copilot-mode 'copilot-mode-on-hook 'copilot-mode-off-hook)) (if (called-interactively-p 'any) (progn nil (if (and (current-message) (not (equal last-message (current-message)))) nil (let ((local " in current buffer")) (message "%s %sabled%s" "Copilot mode" (if copilot-mode "en" "dis") local))))))
  copilot-mode()
  (if copilot-mode (copilot--on-doc-focus (selected-window)) (copilot-mode))
  copilot-diagnose()
  eval((copilot-diagnose) nil)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  command-execute(eval-last-sexp)
anildigital commented 7 months ago

cc @emil-vdw @rakotomandimby Thankyou

rakotomandimby commented 7 months ago

@anildigital , noted. But at this point, I dont see how to solve.

LazerJesus commented 7 months ago

@anildigital i would love to help, but no clue 🦐

anildigital commented 7 months ago

@LazerJesus Can you paste the result of M-x emacs-version? Thanks

Mine is GNU Emacs 30.0.50 (build 1, aarch64-apple-darwin23.1.0, NS appkit-2487.20 Version 14.1.1 (Build 23B81)) of 2023-11-28 installed with brew emacs-plus@30

LazerJesus commented 7 months ago

GNU Emacs 30.0.50 (build 1, aarch64-apple-darwin22.6.0, NS appkit-2299.70 Version 13.5.1 (Build 22G90)) of 2023-11-29 installed with brew. emacs-plus@30

anildigital commented 7 months ago

@LazerJesus Thanks! Could you also share your emacs config to load copilot.el please. May be that would help to find out the difference and close the issue?

jnavila commented 7 months ago

My laptop at work which is stuck with emacs 28 is still performing correctly, whereas my home laptop (GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38, cairo version 1.18.0) of 2023-11-28) is having the same issue.

jnavila commented 7 months ago

I think I have found a cause of the issue. I'm using straight for package management, and copilot pulled jsonrpc in its dependencies. But it seems that jsonrpc is now part of core emacs, and the repo in the straight directory seems to have been stuck with an old version.

I just remove the jsonrpc repo and voilà!

anildigital commented 7 months ago

@jnavila I was not using the straight package though. I am still having the issue.

@rakotomandimby Not sure it's yet resolved.

rakotomandimby commented 7 months ago

@anildigital , please confirm that jsonrpc is not installed on your Emacs

anildigital commented 7 months ago

@rakotomandimby I don't see any jsonrpc package in elpa or in my emacs config? How one finds out if it's installed in Emacs? Thanks

kliph-gladly commented 7 months ago

@rakotomandimby I don't see any jsonrpc package in elpa or in my emacs config? How one finds out if it's installed in Emacs? Thanks

Hi all 😄 I believe you can check this by executing M-x describe-function and providing jsonrpc-error . That should take you to a *Help* buffer showing the jsonrpc-error function description. You should be able to view the source file for the function. In my case, this jsonrpc.el file lives in the "built-in" lisp directory of my Emacs installation.

anildigital commented 7 months ago

HI @kliph-gladly, there is no function defined jsonrpc-error in my Emacs. :|

CleanShot 2023-12-06 at 12 31 52@2x

jnavila commented 7 months ago

@anildigital OK, it may not be loaded by default it you don't have a dependency on it. M-x load-library then jsonrpc then describe the variable.

anildigital commented 7 months ago

@jnavila I couldn't see jsonprc-error in Ch-v

but I could see jsonrpc-connection it says

jsonrpc-connection’s value is ‘jsonrpc-connection’

This variable is obsolete since 25.1; use 'jsonrpc-connection instead

Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a ‘jsonrpc-connection’ object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type ‘jsonrpc-error’.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER.

[back]

Then I could see jsonrpc-error as a link, I clicked and it shows

jsonrpc-error is a native-compiled Lisp function in ‘jsonrpc.el’.

(jsonrpc-error &rest ARGS)

Error out with FORMAT and ARGS.
If invoked inside a dispatcher function, this function is suitable
for replying to the remote endpoint with an error message.

ARGS can be of the form (FORMAT-STRING . MOREARGS) for replying
with a -32603 error code and a message formed by formatting
FORMAT-STRING with MOREARGS.

Alternatively ARGS can be plist representing a JSONRPC error
object, using the keywords ‘:code’, ‘:message’ and ‘:data’.

[back]

I couldn't see any file path mentioned above.

anildigital commented 7 months ago

I clicked jsonrpc.el and it opened file with this path

/opt/homebrew/Cellar/emacs-plus@30/30.0.50/share/emacs/30.0.50/lisp/jsonrpc.el

So I am still getting the error even with in-build jsonrpc.el

yubrshen commented 7 months ago

Here is the debug trace triggered with --debug-init in emacs 29.1 with Doom, when I open a python file which started copilot-mode:

Debugger entered--Lisp error: (jsonrpc-error "request id=1 failed:" (jsonrpc-error-code . -1) 
(jsonrpc-error-message . "Server died") (jsonrpc-error-data))

  signal(jsonrpc-error ("request id=1 failed:" (jsonrpc-error-code . -1) (jsonrpc-error-message . "Server died") (jsonrpc-error-data)))
  jsonrpc-request(#<jsonrpc-process-connection jsonrpc-process-connection-1594c91c033a> initialize (:capabilities (:workspace (:workspaceFolders t))))
  copilot--start-agent()
  copilot--on-doc-focus(#<window 3 on *doom*>)
  copilot--mode-enter()
  copilot-mode()
  run-hooks(change-major-mode-after-body-hook prog-mode-hook python-base-mode-hook python-mode-hook)
  apply(run-hooks (change-major-mode-after-body-hook prog-mode-hook python-base-mode-hook python-mode-hook))
  run-mode-hooks(python-mode-hook)
  python-mode()
  set-auto-mode-0(python-mode nil)
  #<subr set-auto-mode>()
  apply(#<subr set-auto-mode> nil)
  #f(advice auto-minor-mode-set :after #<subr set-auto-mode>)()
  apply(#f(advice auto-minor-mode-set :after #<subr set-auto-mode>) nil)
  (progn (apply fn args))
  (unwind-protect (progn (apply fn args)) (when (buffer-live-p buf) (with-current-buffer buf (evil-change-state old-state))))
  (let ((evil-state evil-state) (evil-previous-state evil-previous-state) (evil-previous-state-alist (copy-tree evil-previous-state-alist)) (evil-next-state evil-next-state) (old-state evil-state) (inhibit-quit t) (buf (current-buffer))) (unwind-protect (progn (apply fn args)) (when (buffer-live-p buf) (with-current-buffer buf (evil-change-state old-state)))))
  (evil-save-state (apply fn args))
  (if evil-state (evil-save-state (apply fn args)) (apply fn args))
  +evil--persist-state-a(#f(advice auto-minor-mode-set :after #<subr set-auto-mode>))
  apply(+evil--persist-state-a #f(advice auto-minor-mode-set :after #<subr set-auto-mode>) nil)
  #f(advice +evil--persist-state-a :around #f(advice auto-minor-mode-set :after #<subr set-auto-mode>))()
  so-long--set-auto-mode(#f(advice +evil--persist-state-a :around #f(advice auto-minor-mode-set :after #<subr set-auto-mode>)))
  apply(so-long--set-auto-mode #f(advice +evil--persist-state-a :around #f(advice auto-minor-mode-set :after #<subr set-auto-mode>)) nil)
  set-auto-mode()
  normal-mode(t)
  #<subr after-find-file>(nil t nil nil nil)
  apply(#<subr after-find-file> (nil t))
  (progn (fset #'sit-for #'ignore) (apply fn args))
  (unwind-protect (progn (fset #'sit-for #'ignore) (apply fn args)) (fset #'sit-for old))
  (let* ((old (symbol-function #'sit-for))) (unwind-protect (progn (fset #'sit-for #'ignore) (apply fn args)) (fset #'sit-for old)))
  doom--shut-up-autosave-a(#<subr after-find-file> nil t)
  apply(doom--shut-up-autosave-a #<subr after-find-file> (nil t))
  #f(advice doom--shut-up-autosave-a :around #<subr after-find-file>)(nil t)
  apply(#f(advice doom--shut-up-autosave-a :around #<subr after-find-file>) (nil t))
  #f(advice chain-doom-first-buffer-hook-to-find-file-hook-h :before #f(advice doom--shut-up-autosave-a :around #<subr after-find-file>) ((depth . -101)))(nil t)
  apply(#f(advice chain-doom-first-buffer-hook-to-find-file-hook-h :before #f(advice doom--shut-up-autosave-a :around #<subr after-find-file>) ((depth . -101))) (nil t))
  after-find-file(nil t)
  find-file-noselect-1(#<buffer scratch.py> "/home/yshen/tmp/scratch.py" nil nil "/home/yshen/tmp/scratch.py" (58875 2080))
  find-file-noselect("/home/yshen/tmp/scratch.py" nil nil t)
  find-file("/home/yshen/tmp/scratch.py" t)
  funcall-interactively(find-file "/home/yshen/tmp/scratch.py" t)
  command-execute(find-file)

The function reporting the error is jsonrpc-request It is defined in ~/doom-emacs/.local/straight/repos/jsonrpc/jsonrpc.el ~/doom-emacs is my doom-emacs code. Based on the above fact, I suspect that it is a problem of incompatibility between the jsonrpc.el and the copilot.el

Here is my doom/info: https://pastebin.com/H43YQt5s

anildigital commented 7 months ago

Somehow copilot.el started working fine after I uninstalled Emacs and installed again Steps followed

brew uninstall emacs-plus@30
brew install emacs-plus@30 --with-native-comp

M-x emacs-version GNU Emacs 30.0.50 (build 1, aarch64-apple-darwin23.1.0, NS appkit-2487.20 Version 14.1.1 (Build 23B81)) of 2023-12-07

But sometimes when I run M-x copilot-diagnose, it keeps showing below error I did see File mode specification error: (jsonrpc-error request id=1 failed: (jsonrpc-error-code . -1) (jsonrpc-error-message . Server died) (jsonrpc-error-data))

along with Copilot agent started. multiple times, but failing.

For now it's working most of the times. May be this issue can be closed if others also don't see it.

yubrshen commented 7 months ago

I still have the same problem, even with re-installing doom code. I further tried with a minimal straight.el configuration, with nothing but copilot.el and its dependencies of jsonrpc.el The error is still the same:

Copilot agent started.
[jsonrpc] Server exited with status 2
jsonrpc-request: jsonrpc-error: "request id=1 failed:

It seems whenever copilot--request is called, which in terms calls jsonrpc-request, it will fail. Is there any change in copilot.el recently, for example, timeout value for connection request?

Here is my minimal setup to reproduce the problem, with emacs29.1 built in Ubuntu 22.4:

;; Boostrap code for straigt.el
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))
;; end of boostrap code for straight.el

;; Install a package from a Git repo:
(use-package copilot
  :straight (:host github :repo "zerolfx/copilot.el" :files ("dist" "*.el"))
  :ensure t)
;; you can utilize :map :hook and :config to customize copilot

The version of copilot is the latest :straight (:host github :repo "zerolfx/copilot.el" :files ("dist" "*.el")) It requires jsonrpc 1.0.14 the version pulled by straight.el of jsonrpc is 1.0.18 (I'm not sure if the difference matters.) Anything information you need? Unless my build emacs29.1 is problematic, there is not much else to suspect now.

zerolfx commented 7 months ago

@yubrshen Please try running node agent.js in your terminal. You can find agent.js in the dist folder.

yubrshen commented 7 months ago

@zerolfx Thanks for your pointer. I think that my problem has been solved! It turned that the node version had been forced to be v16.13.1. Running node agent.js thus failed. Once I switch node version to v18.19.0 (npm v10.2.3) Now, in my minimal configuration, M-x copilot-mode works now, I can even see code suggestion now.

Before I remember that the integration with neovim would require node v16.13.1. Sounds like that there is no more such constraint, but node agent.js would require node version 18.x.

yubrshen commented 7 months ago

By the way, for emacs29.1, it has bulit-in jsonrpc (1.0.16), but straight.el would pull with copilot.el a copy of jsonrpc (1.0.18). It seems it doesn't matter.

zerolfx commented 7 months ago

@yubrshen Glad to hear that your issue has been resolved. Yes, the upstream has updated the NodeJS version requirement, and I'll adjust this plugin to match.

yubrshen commented 7 months ago

Running node dist/agent.js might be added to a section of trouble-shooting or verification. It seems that it has to run successfully in order for copilot.el to work. It will help to resolve issues related to node, and JavaScript.

peoplemerge commented 6 months ago

I'm also seeing this error on Spacemacs a Pop!_OS 22.04 LTS using Node v20.10.0

node agent.js
Content-Length: 232

{"jsonrpc":"2.0","method":"LogMessage","params":{"level":0,"message":"[DEBUG] [agent] [2023-12-12T23:47:50.417Z] Agent service starting","metadataStr":"[DEBUG] [agent] [2023-12-12T23:47:50.417Z]","extra":["Agent service starting"]}}

This is unsurprising, since I can see in the following in Messages.

Copilot agent started.
error in process filter: Unbound slot: jsonrpc-process-connection, "#<jsonrpc-process-connection jsonrpc-process-connection-157cb0744528>", -expected-bytes, oref [4 times]
File mode specification error: (jsonrpc-error request id=1 failed: (jsonrpc-error-message . Timed out))
jaavedd9 commented 2 months ago

(use-package exec-path-from-shell 
  :ensure t )

(use-package copilot 
 :straight (:host github :repo "copilot-emacs/copilot.el" :files ("*.el"))
  :init  (exec-path-from-shell-initialize)
 )

:init (exec-path-from-shell-initialize) this solved my issue