Exafunction / codeium.el

Free, ultrafast Copilot alternative for Emacs
https://www.codeium.com
MIT License
412 stars 13 forks source link

Support for launching the local binary with custom shell command #16

Closed benvansleen closed 1 year ago

benvansleen commented 1 year ago

When using an OS like Guix or Nix, the downloaded "codeium_language_server" binary cannot execute due to libraries not being stored in /lib. I can run the local binary in a container where the libraries do exist in /lib with guix shell -CNF nss-certs -- ./codeium_language_server. (This command places glibc in /lib and allows the container to share the parent environment's networking setup.)

However, I cannot feed this shell command into the codeium-command-executable variable, as it results in an error saying it is "not a valid executable."

I've tried making a launcher shell script with this command and passing it to the codeium-command-executable variable, and I no longer receive any errors, but I do not see any sign of any completions, the package working, or any log messages. I would expect for the auth process to begin, but nothing ever appears in the message buffer. If I examine ps aux | grep cod, I can see the process is running somewhere.

Any thoughts about how to successfully authenticate with the binary running in this manner?

--

I get this output in stdout when running my launcher script:

I0217 22:06:39.515235     1 main.go:346] Starting language server manager with pid 1
I0217 22:06:39.515841     1 main.go:228] Language server manager attempting to connect to language server at 127.0.0.1:42100
I0217 22:06:39.540629    13 main.go:340] Starting language server process with pid 13
I0217 22:06:39.541218    13 server.go:190] Successfully created API server client
I0217 22:06:39.549482    13 server.go:197] Successfully initialized tokenizer
I0217 22:06:39.549507    13 server.go:204] Successfully created completion provider
I0217 22:06:39.549512    13 server.go:217] Child process attempting to acquire lock file /tmp/child_lock_1676671599515472344_173301945805043158
I0217 22:06:39.549537    13 server.go:227] Child process acquired lock file /tmp/child_lock_1676671599515472344_173301945805043158
I0217 22:06:39.549657    13 server.go:106] Language server will attempt to listen on host 127.0.0.1
I0217 22:06:39.549774    13 server.go:129] Language server listening on fixed port at 42100
I0217 22:06:39.549616    13 unleash.go:58] proxyplease.proxy> No proxy provided. Attempting to infer from system.
I0217 22:06:39.549811    13 unleash.go:58] proxyplease.proxy> No proxy could be determined. Assuming a direct connection.
I0217 22:06:39.549821    13 unleash.go:61] Initializing Unleash with production environment
I0217 22:06:39.559114     1 main.go:274] Language server manager successfully connected to new language server at 127.0.0.1:42100
I0217 22:06:39.765435    13 unleash.go:76] Successfully initialized unleash

This looks good, right?

fortenforge commented 1 year ago

In your script, are you passing on the manager_dir argument to the binary correctly? The package creates a temp directory and passes this directory as the --manager_dir argument to the binary. I believe that if you forward this argument correctly through your script, your setup should work properly.

fortenforge commented 1 year ago

See this line for where we pass the arg: https://github.com/Exafunction/codeium.el/blob/main/codeium.el#L365

fortenforge commented 1 year ago

You'll also need to make sure that the extension can talk to the binary running in the container over a port.

benvansleen commented 1 year ago

Yes, the script passes all arguments through the script with $@.

Although, now that you mention it, I'd assume the binary needs write permissions to manager_dir. Does the binary create the directory in that location, or does the binary assume that the directory is already created in that location? If the binary assumes the directory is already created by say, Emacs, then it might have issues writing to it.

As far as ensuring the extension can talk to the binary, I can hit the binary from Firefox (outside the container) and receive a "missing token" message, so I'd assume the networking connection should still be ok.

fortenforge commented 1 year ago

OK, but to be clear for the output from earlier when running your launcher script, you did not pass a --manager_dir argument right?

I think you're correct that the issue is relating to permissions of the manager_dir. The package creates the directory, and the binary needs to be able to write to it. This used for a couple of things, but most relevantly this is how the binary communicates the port it chose back to the extension.

benvansleen commented 1 year ago

Got it! Had to give permission to the container to write to /tmp.

For any guix users that stumble upon this, the command that worked is: guix shell -CNF nss-certs --share=/tmp -- ./codeium_language_server

benvansleen commented 1 year ago

Thanks for the help! I would never have figured that out.

fortenforge commented 1 year ago

Glad it worked out!

Alan-Chen99 commented 1 year ago

For future reference, one can customize codeium-command. For example, to use a fixed directory:

(setq my-codeium-directory (file-truename "~/.emacs.d/codeium/manager_directory"))
;; function to make a manager-directory and return a command
(defun my-codeium-command (_api state)
    ;; codeium.el needs to know about the directory
    (setf (codeium-state-manager-directory state) my-codeium-directory)
    ;; recreate to make sure that theres nothing in the directory
    (delete-directory my-codeium-directory 'recursive)
    (make-directory my-codeium-directory t)
    ;; finally return the command
    `(,codeium-command-executable
         "--api_server_host" "server.codeium.com"
         "--api_server_port" "443" 
         "--manager_dir" ,my-codeium-directory))
(setq codeium-command #'my-codeium-command)