Skip to content

Commit 23e2028

Browse files
authored
docs(dreamcode): initial version (#6)
1 parent 5338d71 commit 23e2028

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ const payloadIsVerified = await verify(request.body, signature, keyId, {
1717
// true or false
1818
```
1919

20+
## Dreamcode
21+
22+
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:
23+
24+
[dreamcode.md](./dreamcode.md)
25+
2026
## Contributing
2127

2228
Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md)

dreamcode.md

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Copilot Extension Dreamcode
2+
3+
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.
4+
5+
Please, any questions/feedback/feelings are welcome. This is a safe space. Please file issues or jump right in and start pull requests.
6+
7+
## Features
8+
9+
- Event-based API for receiving and responding to messages
10+
- Automated Payload verification
11+
- High-level APIs for different types of responses (text, confirmation, references, etc.)
12+
- High-level API for interacting with models
13+
14+
## API
15+
16+
```js
17+
import { createServer } from "http";
18+
19+
import {
20+
CopilotExtension,
21+
createNodeMiddleware,
22+
} from "@octokit/copilot-extension";
23+
24+
const copilotExtension = new CopilotExtension({
25+
agent: "my-app-name",
26+
prompt: {
27+
defaultModel: "gpt-4o",
28+
},
29+
});
30+
31+
copilotExtension.on(
32+
"message",
33+
async ({ message, octokit, prompt, respond, log }) => {
34+
log.info("Received a message:", message.content);
35+
36+
const { data: user } = await octokit.request("GET /user");
37+
await respond.text(`Hello, ${user.login}!`);
38+
39+
await respond.confirmation({
40+
title: "Would you like to hear a joke?",
41+
message: "I have a joke about construction, but I'm still working on it.",
42+
id: "joke",
43+
// optional
44+
meta: {
45+
other: "data",
46+
},
47+
});
48+
}
49+
);
50+
51+
// https://github.com/github/copilot-partners/blob/6d1cde3a1abb147da53f1a39864661dc824d40b5/docs/confirmations.md
52+
copilotExtension.on(
53+
"confirmation",
54+
async ({ confirmation, octokit, prompt, respond, log }) => {
55+
if (confirmation.id === "joke") {
56+
if (confirmation.state === "dismissed") {
57+
await respond.text("Okay, maybe next time!");
58+
return;
59+
}
60+
61+
await respond.text(
62+
prompt.stream("Please tell me a joke about Mona Lisa, Github's mascot.")
63+
);
64+
return;
65+
}
66+
67+
log.warn("Received an unknown confirmation:", confirmation.id);
68+
await respond.text("Hmm, something went wrong. Please try again later.");
69+
}
70+
);
71+
72+
createServer(createNodeMiddleware(copilotExtension)).listen(3000);
73+
copilotExtension.log.info("Listening on http://localhost:3000");
74+
```
75+
76+
## Notes
77+
78+
Regarding the context passed to event handlers
79+
80+
- `message` / `confirmation` / etc are objects as received by the user
81+
- `octokit` is a pre-authenticated octokit instance
82+
- `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.
83+
- `respond` is an API to send different types of responses to the user
84+
- `log` is the logger as we use it in Octokit. See https://github.com/octokit/core.js?tab=readme-ov-file#logging
85+
86+
On how to receive the events (transport layer)
87+
88+
- `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.

0 commit comments

Comments
 (0)