iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
💬

Retrieving GitHub Copilot completions with a Node.js program

に公開
2023/12/21

CopilotForXcode I figured out how to do it while reading it, so I'm taking a note.

Execution Method

$ git clone https://github.com/github/copilot.vim
$ echo "console.lo" > sample.ts
$ node getCompletionsCycling.mjs ./sample.ts

Completions: {
  completions: [
    {
      uuid: '3dcce22b-5656-46a3-bbe8-d204ad1c5259',
      text: 'console.log("Hello World");\n',
      range: [Object],
      displayText: 'g("Hello World");\n',
      position: [Object],
      docVersion: 0
    },
    {
      uuid: '94015891-20a7-4e84-a3b7-6ce0a44b5285',
      text: 'console.log("hello world");\n',
      range: [Object],
      displayText: 'g("hello world");\n',
      position: [Object],
      docVersion: 0
    }
  ]
}

Implementation

getCompletionsCycling.mjs

Explanation

Completion information is retrieved by sending JSON-RPC formatted data to the standard input/output of a child process executed using node copilot.vim/dist/agent.js from the parent program.

const params = {
  jsonrpc: "2.0",
  id: 4,
  method: "getCompletions",
  params: {
    doc: {
      uri: "file:///hoge/sample.ts",
      version: 1,
      position: { line: 2, character: 2 },
    },
  },
}
const dataString = JSON.stringify(params);
const contentLength = Buffer.byteLength(dataString, "utf8");
server.stdin.write(`Content-Length: ${contentLength}\r\n\r\n${dataString}`);

Read the standard output and receive the results in the calling process.

server.stdout.on("data", (data) => {
  console.log(`stdout: ${data}`);
});

You must have already authenticated your GitHub account with copilot.vim (the access token is stored in ~/.config/github-copilot/hosts.json).

There are specifications for the Language Server Protocol and GitHub Copilot's own unique specifications.

In this implementation, they are called in the following order:

  1. LSP: initialize
  2. LSP: textDocument/didOpen
  3. Copilot: getCompletionsCycling

Other methods available in Copilot can be found here. Methods for internal communication authentication and editor use are provided.

https://github.com/intitni/CopilotForXcode/blob/948449daa789f6f7b25ccabd4ab8ff34d39cc9d6/Tool/Sources/GitHubCopilotService/GitHubCopilotRequest.swift

The difference between sendRequest() and await sendRequest() is whether it needs to wait for a response from the inter-process communication.

Reference

python - How to invoke Github Copilot programmatically? - Stack Overflow I followed the code provided by someone here as a reference.

Discussion