Last active
April 2, 2024 07:39
-
-
Save andcarnivorous/e39ed3d972f9bf45d5b8877d24cb55cf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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