1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* Returns a response to the user's query
*/
async function getResponse(req: Query, send: SendEventFn) {
send("meta", { content_type: "text/markdown" });
const lastMessage = req.query.at(-1);
const attachment = lastMessage.attachments.at(0)?.parsed_content || "no attachment";
send("text", {
text: `Parsed text of your last attachment:
~~~
${attachment}
~~~
`,
});
send("done", {});
}
/**
* Returns your bot's settings
*/
async function getBotSettings(): Promise<BotSettings> {
return {
allow_attachments: true,
expand_text_attachments: true,
introduction_message: "Send me an attachment, and I will respond with the parsed text of the attachment.",
enable_multi_bot_chat_prompting: true,
};
}
/**
* Ignore everything below this line
* -
* -
* -
* -
* -
* -
* -
* -
* -
* -
* -
* -
* -
*/
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
type BotSettings = {
allow_attachments?: boolean;
introduction_message?: string;
expand_text_attachments?: boolean;
enable_multi_bot_chat_prompting?: boolean;
};
// protocol https://creator.poe.com/docs/poe-protocol-specification
type Query = {
version: string;
type: "query";
query: {
role: "system" | "user" | "bot";
content: string;
content_type: string;
timestamp: number;
message_id: string;
feedback: { type: "like" | "dislike"; reason?: string }[];
attachments: {
url: string;
content_type: string;
name: string;
parsed_content?: string;
}[];
}[];
message_id: string;
user_id: string;
conversation_id: string;
metadata: string;
language_code: string;
};
type Events = {
meta: { content_type: string };
text: { text: string };
replace_response: { text: string };
suggested_reply: { text: string };
error: { allow_retry?: boolean; text: string };
done: {};
};
type SendEventFn<EventName extends keyof Events = keyof Events> = (
eventName: EventName,
data: Events[EventName],
) => void;
function encodeEvent(event: string, data: any = {}) {
return new TextEncoder().encode(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
}
export default async function(req: Request): Promise<Response> {
const reqBody = await req.json().catch((e) => {
console.error("body parse error", e);
return null;
});