-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
439 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<!-- | ||
This pull request template provides suggested sections for framing your work. | ||
You're welcome to change or remove headers if it doesn't fit your use case. :) | ||
--> | ||
|
||
### What are you trying to accomplish? | ||
|
||
### What approach did you choose and why? | ||
|
||
### What should reviewers focus on? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
node_modules | ||
coverage | ||
examples/**/package-lock.json | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Security Policy | ||
|
||
## Supported Versions | ||
|
||
Important security fixes will be back-ported to at least the two most recent versions. | ||
|
||
## Reporting a Vulnerability | ||
|
||
This repository uses GitHub's [private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) feature. | ||
|
||
You can submit a vulnerability report at https://github.com/copilot-extensions/preview-sdk.js/security/advisories/new. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Examples | ||
|
||
This folder contains examples to show how you can use the Copilot Agent SDK in your own projects. | ||
|
||
If you find any issues or have any questions, please let us know by opening an issue, pull requests welcome (please read the [contribution guidelines](../CONTRIBUTING.md) first). | ||
|
||
## Running the examples | ||
|
||
These examples are setup so that you can run them inside a GitHub Codespace. To do so, follow these steps: | ||
|
||
1. Open the GitHub Codespace by clicking the "Code" button in the top right of the repository and selecting "Open with Codespaces". | ||
2. Once the Codespace is open, you can run the examples by running the following command in the terminal: | ||
|
||
```sh | ||
# go to the correct folder | ||
cd examples/<example-name> | ||
# install dependencies | ||
npm install | ||
# run the example | ||
npm run start | ||
``` | ||
|
||
> [!IMPORTANT] | ||
> By default, the examples will run on port 3000 and ports in Codespaces are private by default. If you want to access the examples from your browser, you'll need to make the port public. To do so, click on the "Ports" tab in the Codespace and right click, Go to "Port Visibility" next to port 3000 and set it to `public`. Do be aware that this will make the port accessible to anyone with the link to your Codespace. The port visibility setting is not saved when the Codespace is stopped, so you'll need to set it again if you restart the Codespace or node. The url does stay the same as long as the Codespace is not deleted. | ||
> [!TIP] | ||
> Don't forget to set the Codespace url (with the port) in your GitHub App that you are using. The Copilot backend needs to be able to reach your Codespace to send messages to your extension. If your app is not running, the port is not public, or the codespace is stopped, the extension will not work. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { createServer } from "node:http"; | ||
|
||
const server = createServer((request, response) => { | ||
if (request.method === "GET") { | ||
return response.end("ok"); | ||
} | ||
|
||
const textObject = { | ||
choices: [ | ||
{ index: 0, delta: { content: "Hello, world!", role: "assistant" } }, | ||
], | ||
}; | ||
|
||
const endObject = { | ||
choices: [{ index: 0, finish_reason: "stop", delta: { content: null } }], | ||
}; | ||
|
||
// note the "\n\n"s, they are significant. | ||
response.write(`data: ${JSON.stringify(textObject)}\n\n`); | ||
response.end(`data: ${JSON.stringify(endObject)}\n\ndata: [DONE]\n\n`); | ||
}); | ||
|
||
const PORT = process.env.PORT || 3000; | ||
server.listen(PORT, () => { | ||
console.log(`Server is running on port ${PORT}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"start": "node index.js", | ||
"watch": "node --watch index.js" | ||
}, | ||
"dependencies": { | ||
"@copilot-extensions/preview-sdk": "../../" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { createServer } from "node:http"; | ||
|
||
import { | ||
createTextEvent, | ||
createDoneEvent, | ||
} from "@copilot-extensions/preview-sdk"; | ||
|
||
const server = createServer((request, response) => { | ||
console.log(`Received [${request.method}] to [${request.url}]`); | ||
|
||
if (request.method === "GET") { | ||
return response.end("ok"); | ||
} | ||
|
||
response.write(createTextEvent("Hello, world!")); | ||
response.end(createDoneEvent()); | ||
}); | ||
|
||
const PORT = process.env.PORT || 3000; | ||
server.listen(PORT, () => { | ||
console.log(`Server is running on port ${PORT}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"start": "node index.js", | ||
"watch": "node --watch index.js" | ||
}, | ||
"dependencies": { | ||
"@copilot-extensions/preview-sdk": "../../" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { createServer } from "node:http"; | ||
import { Octokit } from "octokit"; | ||
import { | ||
createAckEvent, | ||
createDoneEvent, | ||
prompt, | ||
verifyAndParseRequest, | ||
} from "@copilot-extensions/preview-sdk"; | ||
|
||
// Define the port to listen on | ||
const PORT = 3000; | ||
|
||
// Define the handler function | ||
async function handler(request, response) { | ||
console.log(`Received [${request.method}] to [${request.url}]`); | ||
|
||
if (request.method !== "POST") { | ||
// Handle other request methods if necessary | ||
response.writeHead(405, { "Content-Type": "text/plain" }); | ||
console.log(`Method ${request.method} not allowed`); | ||
|
||
response.end("Method Not Allowed"); | ||
return; | ||
} | ||
|
||
// get a token to use | ||
const tokenForUser = request.headers["x-github-token"]; | ||
|
||
// get the user information with the token | ||
const octokit = new Octokit({ auth: tokenForUser }); | ||
const user = await octokit.request("GET /user"); | ||
|
||
// Collect incoming data chunks to use in the `on("end")` event | ||
const body = await getBody(request); | ||
const signature = String(request.headers["github-public-key-signature"]); | ||
const keyID = String(request.headers["github-public-key-identifier"]); | ||
|
||
try { | ||
const { isValidRequest, payload } = await verifyAndParseRequest( | ||
body, | ||
signature, | ||
keyID, | ||
{ | ||
token: tokenForUser, | ||
}, | ||
); | ||
|
||
if (!isValidRequest) { | ||
console.error("Request verification failed"); | ||
response.writeHead(401, { "Content-Type": "text/plain" }); | ||
response.end("Request could not be verified"); | ||
return; | ||
} | ||
|
||
// write the acknowledge event to let Copilot know we are handling the request | ||
// this will also show the message "Copilot is responding" in the chat | ||
response.write(createAckEvent()); | ||
|
||
console.log("Calling the GitHub Copilot API with the user prompt"); | ||
// the prompt to forward to the Copilot API is the last message in the payload | ||
const payload_message = payload.messages[payload.messages.length - 1]; | ||
const { stream } = await prompt.stream(payload_message.content, { | ||
system: `You are a helpful assistant that replies to user messages as if you were the Blackbeard Pirate. Start every response with the user's name, which is @${user.data.login}`, // extra instructions for the prompt | ||
messages: payload.messages, // we are giving the prompt the existing messages in this chat conversation for context | ||
token: tokenForUser, | ||
}); | ||
|
||
// stream the prompt response back to Copilot | ||
for await (const chunk of stream) { | ||
response.write(new TextDecoder().decode(chunk)); | ||
} | ||
|
||
// write the done event to let Copilot know we are done handling the request | ||
response.end(createDoneEvent()); | ||
console.log("Response sent"); | ||
} catch (error) { | ||
console.error("Error:", error); | ||
response.writeHead(500, { "Content-Type": "text/plain" }); | ||
response.end("Internal Server Error"); | ||
} | ||
} | ||
|
||
// Create an HTTP server | ||
const server = createServer(handler); | ||
|
||
// Start the server | ||
server.listen(PORT); | ||
console.log(`Server started at http://localhost:${PORT}`); | ||
|
||
/** | ||
* | ||
* @param {import("node:http").IncomingMessage} request | ||
* @returns | ||
*/ | ||
function getBody(request) { | ||
return new Promise((resolve) => { | ||
const bodyParts = []; | ||
let body; | ||
request | ||
.on("data", (chunk) => { | ||
bodyParts.push(chunk); | ||
}) | ||
.on("end", () => { | ||
body = Buffer.concat(bodyParts).toString(); | ||
resolve(body); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"start": "node index.js", | ||
"watch": "node --watch index.js" | ||
}, | ||
"dependencies": { | ||
"@copilot-extensions/preview-sdk": "../../", | ||
"octokit": "^4.0.2" | ||
} | ||
} |
Oops, something went wrong.