GitHub Copilot Language Server

repository·main·Indexed 43 days ago

https://github.com/github/copilot-language-server-release

An interface for editors and IDEs to integrate GitHub Copilot's AI capabilities using the Language Server Protocol (LSP) and the Agent Client Protocol (ACP). It supports inline completions (ghost text), next edit suggestions via textDocument/copilotInlineEdit, panel completions via textDocument/copilotPanelCompletion, and device flow authentication.

Tokens
3.4K
Snippets
11
Records
16
Agent score
5%

What's inside GitHub Copilot Language Server

  1. Run the Copilot Language Server in ACP Mode

    main

    The Copilot Language Server supports the Agent Client Protocol (ACP), allowing integration with ACP-compatible editors like Zed or JetBrains AI Assistant. In ACP mode, communication occurs over stdin/stdout.

    Start ACP Mode via npx

    npx -y @github/copilot-language-server --acp

    Start ACP Mode via local installation

    node ./node_modules/@github/copilot-language-server/dist/language-server.js --acp
  2. Install the Copilot Language Server

    main

    To integrate with the Copilot Language Server, install the package via npm. Platform-specific binaries are provided as optional dependencies for optimized performance.

    Standard Installation

    npm install @github/copilot-language-server

    Running via npx

    You can run the server directly using npx (requires Node.js 20.8 or later):

    npx @github/copilot-language-server --version

    Running the JavaScript distribution

    If you are using the language-server.js distribution, you must retain the entire dist directory contents. You can run it using Node:

    node ./node_modules/@github/copilot-language-server/dist/language-server.js --version
  3. Cancel completion requests

    main

    To manage resources and prevent stale suggestions, use the following cancellation strategies:

    1. Cancel-previous strategy: For textDocument/inlineCompletion, sending a new completion request automatically cancels the previous request.
    2. Explicit cancellation: The standard LSP $/cancelRequest method is supported for any request. It is strongly encouraged to eagerly cancel completion requests as soon as they are no longer needed.
  4. Authenticate with GitHub Copilot

    main

    Authentication follows a device flow.

    1. Initiate Sign-in: Call signIn. The server returns a userCode and a command object.
    2. User Action: Instruct the user to copy the userCode.
    3. Execute Command: Invoke workspace/executeCommand using the command object provided in step 1. This opens a browser for the user to complete authentication.
    4. Verification: A didChangeStatus notification will be sent shortly after successful authentication.
    {
        "userCode": "ABCD-EFGH",
        "command": {
            "command": "github.copilot.finishDeviceFlow",
            "arguments": [],
            "title": "Sign in"
        }
    }
  5. How to file issues and get help

    main

    To report bugs or request new features for the GitHub Copilot Language Server, use the GitHub issues tracker. Before filing a new issue, search existing issues to prevent duplicates.

    For general help, questions, or community discussions regarding GitHub Copilot, visit the official GitHub Community discussions page.

  6. Configure JetBrains AI Assistant as an ACP Agent

    main

    To use GitHub Copilot as an ACP agent within JetBrains AI Assistant, add the server configuration to your ~/.jetbrains/acp.json file.

    {
      "agent_servers": {
        "GitHub Copilot": {
          "command": "npx",
          "args": [
            "@github/copilot-language-server@latest",
            "--acp"
          ]
        }
      }
    }
  7. Handle Inline Edit lifecycle and telemetry

    main

    When working with textDocument/copilotInlineEdit, follow these lifecycle steps:

    1. Showing the edit: Since LSP does not provide an event for showing an edit, use the custom textDocument/didShowInlineEdit notification. Pass the item from the edits array (the command field is the required part of the item).
    2. Acceptance: After a user accepts an edit, execute the provided command using workspace/executeCommand to ensure telemetry is recorded.
    3. Discarding: If a provider result is discarded, use the github.copilot.didIgnoreNextEditSuggestionItem notification.

    Reporting Cached Edits

    If an edit includes a cacheTelemetryContext, it is an opaque string. When serving a cached copy:

    • Create a fresh opportunityId locally for each serve.
    • Do not reuse the source ID.
    • When the occurrence ends, send a textDocument/reportCachedInlineEdit notification.

    Note: For results that are never rendered, send isShown: false and acceptance: "notAccepted" via the reporting notification.

    // textDocument/didShowInlineEdit
    {
        "item": {
            "command": {
                "arguments": ["some-id"]
            }
        }
    }
    
    // textDocument/reportCachedInlineEdit
    {
        "opportunityId": "unique-id-for-this-cache-serve",
        "context": "<unchanged cacheTelemetryContext from the source edit>",
        "isShown": true,
        "acceptance": "accepted"
    }
  8. Implement Inline Completions (Ghost Text)

    main

    The server uses a draft version of the LSP textDocument/inlineCompletion request to provide "ghost text" suggestions.

    Requesting Completions

    Clients send a request containing the document URI, version, position, and formattingOptions.

    Handling Results

    The response contains an items array. Each item includes insertText, a range, and a command used for acceptance telemetry.

    Completion Lifecycle

    1. Show Completion: Call the custom textDocument/didShowCompletion notification when the suggestion is displayed.
    2. Accept Completion: When the user accepts a suggestion, call workspace/executeCommand using the command from the completion item.
    3. Partial Acceptance: If the user accepts only part of the suggestion, send textDocument/didPartiallyAcceptCompletion. The acceptedLength must be the total length in UTF-16 codepoints from the start of insertText to the end of the accepted text.
    {
        "textDocument": {
            "uri": "file:///path/to/file",
            "version": 0
        },
        "position": {"line": 1, "character": 2},
        "context": {
            "triggerKind": 2
        },
        "formattingOptions": {
            "tabSize": 4,
            "insertSpaces": true
        }
    }
  9. Retrieve Next Edit Suggestions via `textDocument/copilotInlineEdit`

    main

    The textDocument/copilotInlineEdit method retrieves "next edit" suggestions. These are inline completions that may include deletions or modifications to existing text and are not necessarily positioned at the cursor. This is a separate method from standard inline completions to allow for feature opting and distinction.

    Request Parameters

    The request uses parameters similar to TextDocumentPositionParams but requires a textDocument.version field (a VersionedTextDocumentIdentifier).

    Response Format

    The response contains an edits array. Each edit includes a command object. To trigger acceptance telemetry, the client must call the command via workspace/executeCommand after the user accepts the edit.

    // Request
    {
        "textDocument": {
            "uri": "file:///path/to/file",
            "version": 0
        },
        "position": {"line": 1, "character": 2}
    }
    
    // Response
    {
        "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"]
                }
            }
        ]
    }
  10. Initialize the Language Server (LSP)

    main

    Following the Language Server Protocol (LSP) specification, the client must send an initialize request as the first message. After receiving the response, the client must send an initialized notification.

    {
        "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"
            }
        }
    }