Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline completion with overlay #2

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

BrachystochroneSD
Copy link
Collaborator

Hello,
I really like to project, I would like to contribute with that pull request.

I have taken inspiration (and lots of code) from copilot.el. It allows to show with overlay the completion got fetched from codegeex and let the user cycle between the completions and accept one if wanted. Here is a little gif showing the process:

codegeex el

It should work right now. I may restructure the files as it is kind of a mess right now.

Here is the configuration of codegeex for that example:

(use-package codegeex
  :after uuidgen
  :load-path "~/.emacs.d/my-packages/codegeex.el"
  :custom (codegeex-idle-delay 1)
  :bind (:map codegeex-mode-map
              ("C-:" . codegeex-accept-completion)
              ("C-=" . codegeex-next-completion)
              ("C-;" . codegeex-previous-completion)))

Copy link
Collaborator Author

@BrachystochroneSD BrachystochroneSD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are my comments on the code.

Comment on lines -35 to -40
(defvar codegeex-endpoint "https://tianqi.aminer.cn/api/v2/" "the endpoint of CodeGeeX API")
(defvar codegeex-apikey "68cf004321e94b47a91c2e45a8109852" "API key obtained from CodeGeeX website")
(defvar codegeex-apisecret "e82b86a16f9d471ab215f653060310e3" "API secret obtained from CodeGeeX website")
(defvar codegeex-temperature 0.2 "temperature for completion by CodeGeeX")
(defvar codegeex-top_p 0.95 "top_p for completion by CodeGeeX")
(defvar codegeex-top_k 0 "top_k for completion by CodeGeeX")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be subject to an other pull request
These could be defcustom. And currently you put your own api key and api secret. Which is not ideal.
Maybe we can create a login method like the vscode plugin. Retrieving the api with it.
But I have no idea how the api is working.

Some explanation of top_p and top_k or temperature could be added as well.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, they are not my private api key and api secret, they are copied from vscode extension.

Based on my previous test, this extension uses some of non-open API of codegeex(e.g. fill in middle API), which can be accessed only if using this key.

Maybe @Stanislas0 could provide more information about it.

Copy link
Collaborator Author

@BrachystochroneSD BrachystochroneSD Sep 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API is kind of shady it seems. I guess some clarification would be needed indeed.

copied from vscode extension

You mean this one? I don't even know if it's the source code of the current extension shown in the marketplace.

Copy link
Collaborator Author

@BrachystochroneSD BrachystochroneSD Sep 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can clearly see that the completion proposed with the API for this package is not the same than the one from the vscode plugin.

image
Compared to:
image

Clearly there is a new version of the API or something need to be changed in the Call itself.

I'll create an issue on the CodeGeeX2 github project since you get no news from @Stanislas0 in the issue #1.

EDIT: created

Copy link
Collaborator Author

@BrachystochroneSD BrachystochroneSD Sep 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that difference between the completions proposed was my fault, sorry for that dumb mistake (fixed in last commits).

I've checked the files of the vscode extension, I didn't know the whole code was available.
Indeed everything could be retrieved from it. But I hope a better documentation would be available.

(defvar codegeex-temperature 0.2 "temperature for completion by CodeGeeX")
(defvar codegeex-top_p 0.95 "top_p for completion by CodeGeeX")
(defvar codegeex-top_k 0 "top_k for completion by CodeGeeX")
(defvar codegeex-extinfo `((sid . ,(uuidgen-4))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only usage of uuid package. Maybe put the function in the package to avoid dependencies would be interesting

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in fact you can remove this parameter directly. It does not affect any behavior. I added it because I think this may help codegeex to improve their codelm, since sid exists in their official vscode extension.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove it right now then and we can rethink about this in the future, when we will get a correct API documentation (if we have one)

Comment on lines -129 to +140
(defun codegeex-buffer-completion ()
"CodeGeeX buffer completion.
(defun codegeex-complete ()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codegeex-buffer-completion become:

  • codegeex-complete, which callback is the overlay handler codegeex-completion--show-completion
  • codegeex-complete-at-point, similar of previous codegeex-buffer-completion, which insert the first completion fetched

codegeex.el Outdated
Comment on lines 173 to 186
(defun codegeex-accept-completion (&optional transform-fn)
"Accept completion. Return t if there is a completion.
Use TRANSFORM-FN to transform completion if provided."
(interactive)
(when (codegeex--overlay-visible)
(let* ((completion (overlay-get codegeex--overlay 'completion))
(start (overlay-get codegeex--overlay 'start))
(end (codegeex--overlay-end codegeex--overlay))
(uuid (overlay-get codegeex--overlay 'uuid))
(t-completion (funcall (or transform-fn #'identity) completion)))
(codegeex-clear-overlay)
(if (eq major-mode 'vterm-mode)
(progn
(vterm-delete-region start end)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codegeex-accept-completion codegeex-next-completion and codegeex-previous-completion are use to handle the overlaid completion proposition fetched. They can be binded for convenience by the user

Comment on lines +275 to +282
(defmacro codegeex--satisfy-predicates (enable disable)
"Return t if satisfy all predicates in ENABLE and none in DISABLE."
`(and (cl-every (lambda (pred)
(if (functionp pred) (funcall pred) t))
,enable)
(cl-notany (lambda (pred)
(if (functionp pred) (funcall pred) nil))
,disable)))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to trigger the request to codegeex api. Maybe we can add options to avoid triggering it on a comment line or something. Or even using a context system where different api endpoint are used based on where the pointer is in the buffer.

Comment on lines +6 to +8
;; Contributor: Samuel Dawant <samueld@mailo.com>
;; Keywords: codegeex, completion
;; Version: 0.0.1
;; Version: 0.1.0
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took the liberty to increase the version (medium one since it add a functionality) and put myself in the contributor ;). If I may

codegeex.el Outdated
Comment on lines 35 to 36
(require 'codegeex-completion)
(require 'codegeex-overlay)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structure will certainly change soon

codegeex-api.el Outdated
Comment on lines 67 to 73
(let ((n-factor
(cond
((<= (length prefix) 300) 3)
((> (length prefix) 600) 2)
((> (length prefix) 900) 1))))
(when (> (length prefix) 1200 )
(setq prefix (substring prefix 0 1200)))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took that cond from the vscode. Don't know if it's useful here.
Actually, I have no clue on the version of codegeex at the current endpoint, and I didn't found any documentation on the API

Comment on lines +74 to +86
(json-encode
`(:prompt ,prefix
:suffix ,suffix
:n ,n-factor
:apikey ,codegeex-apikey
:apisecret ,codegeex-apisecret
:temperature ,codegeex-temperature
:top_p ,codegeex-top_p
:top_k ,codegeex-top_k
:isFimEnabled ,(not (equal suffix ""))
:lang ,lang
:ext ,codegeex-extinfo))))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use plist for convenience (and for its similarity with json object). The properties are highlighted and it is easier to manipulate

codegeex-api.el Outdated
Comment on lines 40 to 53
(defun codegeex-api--url-retrieve (url json-data callback)
"Default url retrieve as POST with json data"
(let ((url-request-method "POST")
(url-request-extra-headers
'(("Content-Type" . "application/json")))
(url-request-data json-data))
(url-retrieve
url
(lambda (status init-buffer callback)
(let ((result (codegeex-api--get-json-result)))
(setq codegeex-response-cache result)
(with-current-buffer init-buffer
(funcall callback result))))
`(,(current-buffer) ,callback) t)))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be the main api fetcher. With custom callback that take the json-result as argument. Can be used for the other api call that you have implemented by the way.

@BrachystochroneSD BrachystochroneSD marked this pull request as ready for review September 27, 2023 20:00
@hzhangxyz
Copy link
Owner

The code seems ok. But I don't want to check it carefully, since it is national day off in my country this week. So I add you to collaborators, and if you think it is ok, merge it by yourself.

@BrachystochroneSD
Copy link
Collaborator Author

The code seems ok. But I don't want to check it carefully, since it is national day off in my country this week. So I add you to collaborators, and if you think it is ok, merge it by yourself.

As you wish, I am not in a urge so I can wait for a proper review.
And that will give me more time to continue testing it with my other project.

Let's keep that pull request open until the end of your national holidays.

Enjoy your holiday

@BrachystochroneSD
Copy link
Collaborator Author

Some bugs has been found.

  • It seems to no working without evil-mode. I'm checking what's wrong
  • When moving the cursor between the call request and the call response, the completion received is put in the cursor position and not where it has been called. For this I'll create a cache system.

@BrachystochroneSD
Copy link
Collaborator Author

Last commit check if the cursor doesn't move between the http request and the response.

I am checking if I can find other bugs before merging

@BrachystochroneSD
Copy link
Collaborator Author

Old api of codegeex is no longer working at my side.

Impossible to understand a thing on the api documentation of wiki at aminer.

I found "mistral.ai" project with codestral. Which is much more convenient and open in term of documentation. I've created an emacs package for it. I'll work in there. I will no longer work on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants