create-message-kit 1.0.21 → 1.1.5-beta.2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +4 -0
- package/index.js +1 -5
- package/package.json +1 -1
- package/templates/agent/src/handler/ens.ts +13 -44
- package/templates/agent/src/index.ts +32 -3
- package/templates/agent/src/lib/gpt.ts +161 -0
- package/templates/agent/src/lib/openai.ts +91 -57
- package/templates/agent/src/lib/resolver.ts +35 -10
- package/templates/agent/src/prompt.ts +16 -29
- package/templates/agent/src/skills.ts +22 -9
- package/templates/gm/src/index.ts +13 -6
- package/templates/group/src/handler/agent.ts +4 -3
- package/templates/group/src/handler/game.ts +1 -1
- package/templates/group/src/handler/splitpayment.ts +5 -9
- package/templates/group/src/handler/tipping.ts +1 -3
- package/templates/group/src/handler/transaction.ts +0 -1
- package/templates/group/src/index.ts +1 -1
- package/templates/group/src/lib/gpt.ts +161 -0
- package/templates/group/src/lib/openai.ts +91 -56
- package/templates/group/src/lib/resolver.ts +35 -10
- package/templates/group/src/lib/vision.ts +42 -0
- package/templates/group/src/skills.ts +7 -0
@@ -1,5 +1,6 @@
|
|
1
|
-
import { Client } from "@xmtp/xmtp-js";
|
1
|
+
import type { Client } from "@xmtp/xmtp-js";
|
2
2
|
import { isAddress } from "viem";
|
3
|
+
import type { HandlerContext } from "@xmtp/message-kit";
|
3
4
|
|
4
5
|
export const converseEndpointURL =
|
5
6
|
"https://converse-website-git-endpoit-ephemerahq.vercel.app";
|
@@ -16,6 +17,7 @@ export type ConverseProfile = {
|
|
16
17
|
export type UserInfo = {
|
17
18
|
ensDomain?: string | undefined;
|
18
19
|
address?: string | undefined;
|
20
|
+
preferredName: string | undefined;
|
19
21
|
converseUsername?: string | undefined;
|
20
22
|
ensInfo?: EnsData | undefined;
|
21
23
|
avatar?: string | undefined;
|
@@ -47,19 +49,20 @@ export const clearInfoCache = () => {
|
|
47
49
|
export const getUserInfo = async (
|
48
50
|
key: string,
|
49
51
|
clientAddress?: string,
|
52
|
+
context?: HandlerContext,
|
50
53
|
): Promise<UserInfo | null> => {
|
51
54
|
let data: UserInfo = infoCache.get(key) || {
|
52
55
|
ensDomain: undefined,
|
53
56
|
address: undefined,
|
54
57
|
converseUsername: undefined,
|
55
58
|
ensInfo: undefined,
|
59
|
+
preferredName: undefined,
|
56
60
|
};
|
57
|
-
//console.log("Getting user info", key, clientAddress);
|
58
61
|
if (isAddress(clientAddress || "")) {
|
59
62
|
data.address = clientAddress;
|
60
63
|
} else if (isAddress(key || "")) {
|
61
64
|
data.address = key;
|
62
|
-
} else if (key
|
65
|
+
} else if (key?.includes(".eth")) {
|
63
66
|
data.ensDomain = key;
|
64
67
|
} else if (key == "@user" || key == "@me" || key == "@bot") {
|
65
68
|
data.address = clientAddress;
|
@@ -74,16 +77,15 @@ export const getUserInfo = async (
|
|
74
77
|
} else {
|
75
78
|
data.converseUsername = key;
|
76
79
|
}
|
77
|
-
|
80
|
+
data.preferredName = data.ensDomain || data.converseUsername || "Friend";
|
78
81
|
let keyToUse = data.address || data.ensDomain || data.converseUsername;
|
79
82
|
let cacheData = keyToUse && infoCache.get(keyToUse);
|
80
|
-
|
81
|
-
|
82
|
-
return cacheData;
|
83
|
-
} else {
|
84
|
-
//console.log("Getting user info", keyToUse, data);
|
85
|
-
}
|
83
|
+
//console.log("Getting user info", { cacheData, keyToUse, data });
|
84
|
+
if (cacheData) return cacheData;
|
86
85
|
|
86
|
+
context?.send(
|
87
|
+
"Hey there! Give me a sec while I fetch info about you first...",
|
88
|
+
);
|
87
89
|
if (keyToUse?.includes(".eth")) {
|
88
90
|
const response = await fetch(`https://ensdata.net/${keyToUse}`);
|
89
91
|
const ensData: EnsData = (await response.json()) as EnsData;
|
@@ -113,6 +115,8 @@ export const getUserInfo = async (
|
|
113
115
|
data.address = converseData?.address || undefined;
|
114
116
|
data.avatar = converseData?.avatar || undefined;
|
115
117
|
}
|
118
|
+
|
119
|
+
data.preferredName = data.ensDomain || data.converseUsername || "Friend";
|
116
120
|
if (data.address) infoCache.set(data.address, data);
|
117
121
|
return data;
|
118
122
|
};
|
@@ -124,3 +128,24 @@ export const isOnXMTP = async (
|
|
124
128
|
if (domain == "fabri.eth") return false;
|
125
129
|
if (address) return (await client.canMessage([address])).length > 0;
|
126
130
|
};
|
131
|
+
|
132
|
+
export const PROMPT_USER_CONTENT = (userInfo: UserInfo) => {
|
133
|
+
let { address, ensDomain, converseUsername, preferredName } = userInfo;
|
134
|
+
let prompt = `
|
135
|
+
User context:
|
136
|
+
- Start by fetch their domain from or Convese username
|
137
|
+
- Call the user by their name or domain, in case they have one
|
138
|
+
- Ask for a name (if they don't have one) so you can suggest domains.
|
139
|
+
- Users address is: ${address}`;
|
140
|
+
if (preferredName) prompt += `\n- Users name is: ${preferredName}`;
|
141
|
+
if (ensDomain) prompt += `\n- User ENS domain is: ${ensDomain}`;
|
142
|
+
if (converseUsername)
|
143
|
+
prompt += `\n- Converse username is: ${converseUsername}`;
|
144
|
+
|
145
|
+
prompt = prompt.replace("{ADDRESS}", address || "");
|
146
|
+
prompt = prompt.replace("{ENS_DOMAIN}", ensDomain || "");
|
147
|
+
prompt = prompt.replace("{CONVERSE_USERNAME}", converseUsername || "");
|
148
|
+
prompt = prompt.replace("{PREFERRED_NAME}", preferredName || "");
|
149
|
+
|
150
|
+
return prompt;
|
151
|
+
};
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import "dotenv/config";
|
2
|
+
|
3
|
+
import OpenAI from "openai";
|
4
|
+
const openai = new OpenAI({
|
5
|
+
apiKey: process.env.OPEN_AI_API_KEY,
|
6
|
+
});
|
7
|
+
|
8
|
+
export async function vision(imageData: Uint8Array, systemPrompt: string) {
|
9
|
+
const base64Image = Buffer.from(imageData).toString("base64");
|
10
|
+
const dataUrl = `data:image/jpeg;base64,${base64Image}`;
|
11
|
+
|
12
|
+
// Create a new thread for each vision request
|
13
|
+
const visionMessages = [
|
14
|
+
{
|
15
|
+
role: "system",
|
16
|
+
content: systemPrompt,
|
17
|
+
},
|
18
|
+
{
|
19
|
+
role: "user",
|
20
|
+
content: [
|
21
|
+
{ type: "text", text: systemPrompt },
|
22
|
+
{
|
23
|
+
type: "image_url",
|
24
|
+
image_url: {
|
25
|
+
url: dataUrl,
|
26
|
+
},
|
27
|
+
},
|
28
|
+
],
|
29
|
+
},
|
30
|
+
];
|
31
|
+
|
32
|
+
try {
|
33
|
+
const response = await openai.chat.completions.create({
|
34
|
+
model: "gpt-4o",
|
35
|
+
messages: visionMessages as any,
|
36
|
+
});
|
37
|
+
return response.choices[0].message.content;
|
38
|
+
} catch (error) {
|
39
|
+
console.error("Failed to interpret image with OpenAI:", error);
|
40
|
+
throw error;
|
41
|
+
}
|
42
|
+
}
|
@@ -14,6 +14,7 @@ export const skills: SkillGroup[] = [
|
|
14
14
|
{
|
15
15
|
command: "/tip [@usernames] [amount] [token]",
|
16
16
|
triggers: ["/tip"],
|
17
|
+
examples: ["/tip @vitalik 10 usdc"],
|
17
18
|
description: "Tip users in a specified token.",
|
18
19
|
handler: tipping,
|
19
20
|
params: {
|
@@ -37,6 +38,7 @@ export const skills: SkillGroup[] = [
|
|
37
38
|
{
|
38
39
|
command: "/send [amount] [token] [username]",
|
39
40
|
triggers: ["/send"],
|
41
|
+
examples: ["/send 10 usdc @vitalik"],
|
40
42
|
description:
|
41
43
|
"Send a specified amount of a cryptocurrency to a destination address.",
|
42
44
|
handler: transaction,
|
@@ -59,6 +61,7 @@ export const skills: SkillGroup[] = [
|
|
59
61
|
{
|
60
62
|
command: "/swap [amount] [token_from] [token_to]",
|
61
63
|
triggers: ["/swap"],
|
64
|
+
examples: ["/swap 10 usdc eth"],
|
62
65
|
description: "Exchange one type of cryptocurrency for another.",
|
63
66
|
handler: transaction,
|
64
67
|
params: {
|
@@ -81,6 +84,7 @@ export const skills: SkillGroup[] = [
|
|
81
84
|
{
|
82
85
|
command: "/show",
|
83
86
|
triggers: ["/show"],
|
87
|
+
examples: ["/show"],
|
84
88
|
handler: transaction,
|
85
89
|
description: "Show the whole frame.",
|
86
90
|
params: {},
|
@@ -113,6 +117,7 @@ export const skills: SkillGroup[] = [
|
|
113
117
|
{
|
114
118
|
command: "/points",
|
115
119
|
triggers: ["/points"],
|
120
|
+
examples: ["/points"],
|
116
121
|
handler: loyalty,
|
117
122
|
description: "Check your points.",
|
118
123
|
params: {},
|
@@ -134,6 +139,7 @@ export const skills: SkillGroup[] = [
|
|
134
139
|
{
|
135
140
|
command: "/agent [prompt]",
|
136
141
|
triggers: ["/agent", "@agent", "@bot"],
|
142
|
+
examples: ["/agent @vitalik"],
|
137
143
|
handler: agent,
|
138
144
|
description: "Manage agent commands.",
|
139
145
|
params: {
|
@@ -152,6 +158,7 @@ export const skills: SkillGroup[] = [
|
|
152
158
|
{
|
153
159
|
command: "/help",
|
154
160
|
triggers: ["/help"],
|
161
|
+
examples: ["/help"],
|
155
162
|
handler: helpHandler,
|
156
163
|
description: "Get help with the bot.",
|
157
164
|
params: {},
|