Skip to content

Instantly share code, notes, and snippets.

@andcarnivorous
Last active April 2, 2024 07:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andcarnivorous/e39ed3d972f9bf45d5b8877d24cb55cf to your computer and use it in GitHub Desktop.
Save andcarnivorous/e39ed3d972f9bf45d5b8877d24cb55cf to your computer and use it in GitHub Desktop.
(require 'request)
(defcustom locpilot-system-prompt
"\
You are an Emacs code generator. \
Writing comments is forbidden. \
Writing test code is forbidden. \
Writing English explanations is forbidden. \
Only write code, nothing else."
;Only write until the end of function or end of class."
"System prompt to provide to the model. This sets the context of the model."
:type 'string
:group 'locopilot)
(defcustom locpilot-inst-prompt
"[INST]Generate %s code to complete the following markdown block only:[/INST]\n```%s\n%s"
"Instruction prompt, this is what the user would submit to the model."
:type 'string)
(defcustom locpilot-code-context-limit
700
"Code context limit. Only these numbers of characters before point
will be passed to the model."
:type 'integer)
(defcustom locpilot-max-tokens
100
"Maximum number of tokens for model output."
:type 'integer)
(defun locpilot-get-input-code ()
"Get an area of the buffer to feed up to point to the model."
;; TODO: the beginning should be limited to fit into context
(buffer-substring-no-properties (if (> 0 (- (point) locpilot-code-context-limit))
1
(- (point) locpilot-code-context-limit)) (point)))
(defun locpilot-build-prompt ()
(format locpilot-inst-prompt
(locpilot-get-prog-lang)
(locpilot-get-prog-lang)
(format "%s" (locpilot-get-input-code))))
(defun locpilot-get-prog-lang ()
(when (string-match "\\(\\w+\\)" (format "%s" major-mode))
(match-string 0 (format "%s" major-mode))))
(defface locpilot-face
'((t :inherit shadow))
"Face for displaying locpilot text."
:group 'cursive)
(defvar-local locpilot--overlay nil
"Overlay for Locpilot completion.")
(defun locpilot-display (string &optional timeout)
"Docstring.
Argument STRING string to display.
Optional argument TIMEOUT how long to display the overlay string for."
(let ((ov (make-overlay (point) (point)))
(pstring (propertize string 'face 'locpilot-face)))
(overlay-put ov 'after-string "")
(put-text-property 0 1 'cursor t pstring)
(overlay-put ov 'display pstring)
(overlay-put ov 'after-string pstring)
(overlay-put ov 'completion string)
(overlay-put ov 'start (point))
(setq locpilot--overlay ov)
(set-transient-map keymap)))
(defun locpilot-get-json-data (prompt)
(setq json-data
`(
:model "LLaMA_CPP"
:temperature 0
:max_tokens ,locpilot-max-tokens
:messages [
(
("role" . "system")
("content" . ,locpilot-system-prompt)
)
(
("role" . "user")
("content" . ,prompt)
)
]))
json-data)
(defcustom locpilot-request-url
"http://localhost:8080/v1/chat/completions"
"Docstring."
:type 'string)
(defun locpilot-callmodel (prompt)
(request-response-data
(request
locpilot-request-url
:type "POST"
:headers '(("Content-Type" . "application/json")
("Authorization" . "Bearer no-key"))
:data (json-encode prompt)
:parser 'json-read
:error (cl-function
(lambda (&rest args &key error-thrown &allow-other-keys)
(message "Error: %S" error-thrown)))
:sync t)))
(defun locpilot--parse-response (data)
"Docstring.
Argument DATA Received json data to parse."
(let ((choices (cdr (assoc 'choices data))))
(when choices
(s-replace-regexp "```\\|\\[/*INST\\]\\|<</*SYS>>" ""
(format "%s" (car (mapcar (lambda (choice)
(cdr (assoc 'content (cdr (assoc 'message choice)))))
choices)))))))
(defun locpilot-complete ()
"Docstring."
(interactive)
(let ((prompt (locpilot-build-prompt)))
(message "PROMPT %s" prompt)
(locpilot-display
(locpilot--parse-response
(locpilot-callmodel (locpilot-get-json-data prompt))))))
(defun locpilot-write-complete ()
"Docstring."
(interactive)
(when (overlayp locpilot--overlay)
(let ((towrite (overlay-get locpilot--overlay 'completion)))
(save-excursion (goto-char (overlay-get locpilot--overlay 'start))
(delete-overlay locpilot--overlay)
(insert towrite))
(setq locpilot--overlay nil))))
(defun locpilot-del-complete()
"Docstring."
(interactive)
(when (overlayp locpilot--overlay)
(delete-overlay locpilot--overlay)
(setq locpilot--overlay nil)))
(provide 'locpilot)
;;; locpilot.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment