- Notifications
You must be signed in to change notification settings - Fork11
Feedback for the GitHub Copilot Language Server
License
github/copilot-language-server-release
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
The Copilot Language Server enables any editor or IDE to integrate with GitHubCopilot viathe language server protocol.
GitHub Copilot is an AI pair programmer tool that helps you write code faster and smarter.
Sign up forGitHub Copilot Free!
Please seeterms of use for GitHub Copilot
To integrate with the Copilot Language Server, download the latest release from npm:
npm install @github/copilot-language-server
To run the language server, platform-specific binaries are available as separatepackages included as optional dependencies. For example,@github/copilot-language-server-darwin-arm64, for macOS on arm64:example, for macOS on arm64:
./node_modules/@github/copilot-language-server-darwin-arm64/copilot-language-server --version
If repackaging the language server, all platform-specific binaries are availablein the releases:https://github.com/github/copilot-language-server-release/releasesFor example, to download a zip of all of the binaries together:
gh release download -R github/copilot-language-server-release -p 'copilot-language-server-native-*'Or you can useNode.js version 20.8 or later:
npx @github/copilot-language-server --version
node ./node_modules/@github/copilot-language-server/dist/language-server.js --version
If using thelanguage-server.js distribution, it is necessary to retain the entiredist directory contents.
Communication with the language server typically happens over stdio with--stdio. Thelanguage-server.jsdistribution additionally supports Node IPC with--node-ipc.
TheLanguage Server Protocol (LSP) is used to communicate withthe client. The base protocol isJSON-RPC 2.0 with additionalheaders.
The Copilot Language Server attempts to follow the LSP spec as closely as possible, but many custom messages areemployed to support the unique features of Copilot.
Per the LSP spec, the client is expected to send ainitializerequest to the language server as a first message. Example parameters:
{"processId":1234,"workspaceFolders": [ {"uri":"file:///home/user/project" } ],"capabilities": {"workspace": {"workspaceFolders":true} },"initializationOptions": {"editorInfo": {"name":"GNU ed","version":"1.19" },"editorPluginInfo": {"name":"GitHub Copilot for ed","version":"1.0.0" } }}After receiving the response toinitialize, the second message the client must send is aninitializednotification.
After initialization, clients should send aworkspace/didChangeConfigurationnotification to inform the language server about the initial configuration, and again each time the configurationchanges. Example parameters:
{"settings": {"http": {"proxy":"http://localhost:8888","proxyStrictSSL":true,"proxyKerberosServicePrincipal":"spn" },"telemetry": {"telemetryLevel":"all" },"github-enterprise": {"uri":"https://example.ghe.com" } }}Pull based configuration onworkspace/configurationis also supported.
Workspace folders are optional but highly recommended as they greatly improve the quality of suggestions. See the LSP spec forworkspace/didChangeWorkspaceFolders.
Per the LSP spec fortext document synchronization,support fortextDocument/didOpen,textDocument/didChange, andtextDocument/didClose is required, using incrementalsync.
Additionally a customtextDocument/didFocus notification should be sent when the client focuses another document(e.g., changing tabs). Example parameters:
{"textDocument": {"uri":"file:///path/to/file" }}If no document is focused, a request with no parameters ({}) may be sent.
The status is sent to the client as adidChangeStatus notification. Typically this would be conveyed to the user in astatus bar icon or other UI affordance.
Notification includes the following fields:
message- a string describing the status (can be empty)kind- status of the language server:'Normal'- When everything is working normally.'Error'- When not authorized and authenticated.'Warning'- When there is a temporary issue, such as a failed HTTP request.'Inactive'- When the current file is ignored due to file size or content exclusions.
To sign in, callsignIn. This will return a response like the following:
{"userCode":"ABCD-EFGH","command": {"command":"github.copilot.finishDeviceFlow","arguments": [],"title":"Sign in" }}Instruct the user to copy theuserCode to their clipboard (and/or copy it programmatically). When the user is ready, invokeworkspace/executeCommandto execute thecommand. This will open a browser window that walks the user through the authentication process.Shortly (up to 10 seconds) after the user finishes signing in, you should see a status notification reflecting the newstate.
If available, the language server will usewindow/showDocumentto open the URL. Otherwise, it will attempt to open the URL natively (e.g., with/usr/bin/open on macOS).
To sign out, callsignOut.
ThetextDocument/inlineCompletionrequest from the draft version of the next LSP spec is used to retrieve inline ("ghost text") completions, with somenon-standard additions (textDocument.version andformattingOptions) to the parameters:
{"textDocument": {"uri":"file:///path/to/file","version":0 },"position": {"line":1,"character":2},"context": {"triggerKind":2 },"formattingOptions": {"tabSize":4,"insertSpaces":true }}The result is an object containing anitems array.
{"items": [ {"insertText":"a helpful suggestion","range": {"start": {"line":1,"character":0},"end": {"line":1,"character":2} },"command": {"command":"github.copilot.didAcceptCompletionItem","arguments": ["some id"] } } ]}Newlines ininsertText should be normalized as is appropriate for the editor before inserting into the document.
Thecommand field, per the LSP spec, is called viaworkspace/executeCommandafter the user accepts the completion. Copilot uses this for acceptance telemetry.
The LSP spec does not provide an event for showing the completion, so a customtextDocument/didShowCompletion is used.Call it with anitem parameter containing the full completion item:
{"item": {"insertText":"a helpful suggestion","range": {"start": {"line":1,"character":0},"end": {"line":1,"character":2} },"command": {"command":"github.copilot.didAcceptCompletionItem","arguments": ["some id"] } }}Similarly, for partial acceptance, send atextDocument/didPartiallyAcceptCompletion notification with the fullitem, plus the length (in UTF-16 codepoints) of the completion that was accepted:
{"item": {"insertText":"a helpful suggestion","range": {"start": {"line":1,"character":0},"end": {"line":1,"character":2} },"command": {"command":"github.copilot.didAcceptCompletionItem","arguments": ["some id"] } },"acceptedLength":9}Note that theacceptedLength includes everything from the start ofinsertText to the end of the accepted text. It isnot the length of the accepted text itself.
textDocument/copilotInlineEdit is a custom method used to retrieve "next edit"suggestions which are inline completions that may include deletions ormodifications to existing text and may not be positioned at the cursor. Theseare similar to inline completions and the API shape is similar as well. But itis a separate method to allow opting into the feature and distinguishing betweenthe two kinds of suggestions.
The request parameters are similar toTextDocumentPositionParamsbut with atextDocument.version field required as in asVersionedTextDocumentIdentifier:
{"textDocument": {"uri":"file:///path/to/file","version":0 },"position": {"line":1,"character":2}}The result is an object containing anedits array:
{"edits": [ {"text":"an edit suggestion","textDocument": {"uri":"file:///path/to/file","version":0 },"range": {"start": {"line":1,"character":0},"end": {"line":1,"character":5} },"command": {"title":"Accept inline edit","command":"github.copilot.didAcceptCompletionItem","arguments": ["some-id"] } } ]}Thecommand field, per the LSP spec, is called viaworkspace/executeCommandafter the user accepts the edit. Copilot uses this for acceptance telemetry.
The LSP spec does not provide an event for showing the edit, so a customtextDocument/didShowInlineEdit is used. Call it with anitem parametercontaining the item shown from theedits array (note only the first argument is required):
{"item": {"command": {"arguments": ["some-id"] } }}Panel completions are used for "Open Copilot" style completions. They are similar to inline completions, but are shownin a separate panel. They are retrieved using the customtextDocument/copilotPanelCompletion request, which hasparameters closely modeled aftertextDocument/inlineCompletion:
{"textDocument": {"uri":"file:///path/to/file","version":0 },"position": {"line":1,"character":2},"partialResultToken":"some token"}If provided, thepartialResultToken is used to streampartial resultsback to the client. Both the return type and the partial result type are the same as for inline completions: an objectcontaining anitems array. These items have the samecommand that must be invoked withworkspace/executeCommandafter accepting to trigger acceptance telemetry. Partial acceptance and shown events are not supported here.
textDocument/inlineCompletion supports cancel-previous strategy for cancellation: If you send new completionsrequest, the previous request is cancelled.
Additionally the LSP$/cancelRequest method is supported to cancel any request. It is strongly encouraged to eagerlycancel completion requests as soon as possible.
Logs are sent to the client aswindow/logMessagenotifications.
The client may be sentwindow/showMessageRequestrequests. Support for these messages is essential as they are used for important notifications including account andbilling.
Distributed under the MIT license. See LICENSE for details.
About
Feedback for the GitHub Copilot Language Server
Topics
Resources
License
Code of conduct
Contributing
Security policy
Uh oh!
There was an error while loading.Please reload this page.