LSP-AI: open-source language server serving as back end for AI code assistance
github.com
github.com
The dream (as I understood it) was that people could write things like this, and it'll work out-of-the-box for a bunch of other editors, as long as they follow LSP.
As a simple example, I'm learning japanese so I built a 50-line LSP server that just looks up definitions of a word under cursor in a dictionary. This is an almost-trivial server. Its only capability is to offer definitions when hovering a position in a text document. It works perfectly well in neovim with lspconfig with 2 lines of configuration. I'm sure it would be similarly trivial to integrate in VSCode, Emacs, etc.
Other non-coding uses of LSP that I'm aware of are spell-checking and grammar suggestions (LSP clients can display diagnostics), semantic syntax highlighting (e.g. for highlighting a markdown document), and projects like the one discussed here which just integrate more general-purpose AI.
Llama.cpp using vulkan is great on laptop iGPUs.
If you can’t have more than one at a time, one possibility would be to make the AI language server a proxy that passes through any query results from the other language server, maybe modifying or them improving them somehow. Whatever the other language server returns might or might not be useful context for the AI.
LSP-AI is not meant to replace plugins. It works best when wrapped and used by a plugin. Our VS Code plugin is a great example of this: https://github.com/SilasMarvin/lsp-ai/wiki/Plugins
LSP-AI abstracts complex implementation details like maintaining document / context parity and providing different LLM backends.
I have a section no the Github Title: "The Case for LSP-AI" you might like: https://github.com/SilasMarvin/lsp-ai?tab=readme-ov-file#the...
Do you think the LSP abstraction can support interactions beyond copilot style autocomplete? While that's a super helpful UX, it's also pretty narrow and limited.
My project aider [1] provides a pair-programming UX, which allows complex interactions like asking for a change that will modify multiple files. Could LSP servers support more general AI coding like this?
CopilotChat.nvim solves this somewhat elegantly for neovim, providing a streamlined UI to interact with an LLM in a way that allows accepting suggested diffs to your currently open buffer. The problem however is that it only works with GitHub's Copilot chat, as the name suggests. Not sure how well Copilot stacks up against gpt-4o for example but I'd imagine not that well.
edit: Quick demo of CopilotChat.nvim: https://github.com/raine/ghtool/assets/11027/e8d5820b-eafb-4...
This is pretty much the kind of UI I'd want for interacting with LLMs, aside from the typical Copilot style ghost autocomplete.
LSP-AI makes writing these plugins easier. Check out "The Case for LSP-AI" https://github.com/SilasMarvin/lsp-ai?tab=readme-ov-file#the... for more info on why I think that is true
For custom use cases like chat windows and some of the things we are working on next, you will still need plugins, but making it an LSP simplifies things like synchronizing document changes and a communicating with the client.
It's also just an LSP, even though it has helix in the name.
Aider: https://github.com/paul-gauthier/aider
It is state of the art on SWE-Bench and SWE-Bench Lite. https://aider.chat/2024/06/02/main-swe-bench.html
Personally I find it just easier to either write the code myself, or ask ChatGPT/whatever for snippets for specific problems which I then heavily modify to suit my needs (and fix its bugs, which happen quite often). But maybe I’m just too engrained in existing behavior.
1. Write comments saying what you want the next lines of code to do
2. Write function definitions with clear function names and type annotations on the arguments - this can result in the full function body being provided if your definitions are clear enough
3. For repetitive code (like parameterized unit tests) provide a couple of examples and then use comments to hint at what it should write for you next based on those examples
4. Sometimes it's good to temporarily copy and paste a chunk of code in from elsewhere. For example, copy a CREATE TABLE SQL statement into a Python file when you are writing code that will interact with that table - or even an HTML page when you are writing out the HTML for a form associated with that table
This works well as a general rule, but sometimes it doesn't fine the right snippets - which is why I occasionally help it out through copy and paste.
My main thoughts behind this are that
1. The LLMs tend to hallucinate library functions
2. I don't want to have to copy and paste a schema
Seems small but I think it’s actually a major productivity win for polyglot programming (which is a lot of my current $dayjob).
I also like the convenience of “start a session with my current file automatically in the context”, again, lowers the friction substantially.
The models used for autocompletion in Github Copilot and other systems are usually not as strong but faster and cheaper.
You can still get decent results from the autocomplete models if you guide them with comments but I find explicit prompting less frustrating when I care about getting a good result.
For my other code bases I find that the amount of time it saves is definitely nice but only barely worth paying another SaaS subscription for.
And so I'm happy to just wait for Jetbrains and Microsoft to roll this into the existing products for free.
I’ve found it great when manipulating data between two formats, like a CSV export into a JSON config. Something that might be too short to write a script for but long enough to be tedious, you can now tab complete your way through it.
That next stage is currently what I am working. I'm building out a code splitter using TreeSitter right now and already have experimental vector search in the language server.
I work full-time for my own product (very early stage) but I am happy to share my own journey of using AI code assistants. Please feel free to check the commits: https://github.com/brainless/dwata
one gets: Package `lsp-ai v0.1.0` does not have feature `llama-cpp-2`. It has an optional dependency with that name, but that dependency uses the "dep:" syntax in the features table, so it does not have an implicit feature with that name.
not very clear what enabling feature is beyond specifying the flag whether to download git clone and build etc.
Eglot: https://joaotavora.github.io/eglot/#Setting-Up-LSP-Servers
lsp-mode: https://emacs-lsp.github.io/lsp-mode/page/adding-new-languag...