Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(dreamcode): initial version #6

Merged
merged 2 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ const payloadIsVerified = await verify(request.body, signature, keyId, {
// true or false
```

## Dreamcode

While implementing the lower-level functionality, we also dream big: what would our dream SDK for Coplitot extensions look like? Please have a look and share your thoughts and ideas:

[dreamcode.md](./dreamcode.md)

## Contributing

Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md)
Expand Down
88 changes: 88 additions & 0 deletions dreamcode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Copilot Extension Dreamcode

Dream code is code that is not real. Its purpose is to create the most user-friendly SDK APIs from the perspectives of developers who want to build GitHub Extensions using JavaScript/Typescript.

Please, any questions/feedback/feelings are welcome. This is a safe space. Please file issues or jump right in and start pull requests.

## Features

- Event-based API for receiving and responding to messages
- Automated Payload verification
- High-level APIs for different types of responses (text, confirmation, references, etc.)
- High-level API for interacting with models

## API

```js
import { createServer } from "http";

import {
CopilotExtension,
createNodeMiddleware,
} from "@octokit/copilot-extension";

const copilotExtension = new CopilotExtension({
agent: "my-app-name",
prompt: {
defaultModel: "gpt-4o",
},
});

copilotExtension.on(
"message",
async ({ message, octokit, prompt, respond, log }) => {
log.info("Received a message:", message.content);

const { data: user } = await octokit.request("GET /user");
await respond.text(`Hello, ${user.login}!`);

await respond.confirmation({
title: "Would you like to hear a joke?",
message: "I have a joke about construction, but I'm still working on it.",
id: "joke",
// optional
meta: {
other: "data",
},
});
}
);

// https://github.com/github/copilot-partners/blob/6d1cde3a1abb147da53f1a39864661dc824d40b5/docs/confirmations.md
copilotExtension.on(
"confirmation",
async ({ confirmation, octokit, prompt, respond, log }) => {
if (confirmation.id === "joke") {
if (confirmation.state === "dismissed") {
await respond.text("Okay, maybe next time!");
return;
}

await respond.text(
prompt.stream("Please tell me a joke about Mona Lisa, Github's mascot.")
);
return;
}

log.warn("Received an unknown confirmation:", confirmation.id);
await respond.text("Hmm, something went wrong. Please try again later.");
}
);

createServer(createNodeMiddleware(copilotExtension)).listen(3000);
copilotExtension.log.info("Listening on http://localhost:3000");
```

## Notes

Regarding the context passed to event handlers

- `message` / `confirmation` / etc are objects as received by the user
- `octokit` is a pre-authenticated octokit instance
- `prompt` is based on my work at https://github.com/github/gr2m-projects/blob/167/github-models/167-github-models/README.md. A simple API to interact with GitHub models.
- `respond` is an API to send different types of responses to the user
- `log` is the logger as we use it in Octokit. See https://github.com/octokit/core.js?tab=readme-ov-file#logging

On how to receive the events (transport layer)

- `createNodeMiddleware` is something we have currently built into some of the Octokit SDKs, e.g. https://github.com/octokit/app.js?tab=readme-ov-file#createnodemiddlewareapp-options. However, I think we will move these out into separate packages, such as `@octokit/webhooks-middleware-node`, etc. But for now, we can just assume that we ship with it by default. We can also add other middlewares for Netlify/Vercel edge functions, lambda, etc.