create-message-kit 1.0.16 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +10 -10
- package/package.json +1 -1
- package/templates/agent/src/handler/ens.ts +105 -141
- package/templates/agent/src/index.ts +5 -1
- package/templates/agent/src/lib/openai.ts +44 -29
- package/templates/agent/src/lib/resolver.ts +107 -63
- package/templates/agent/src/prompt.ts +31 -53
- package/templates/agent/src/skills.ts +95 -0
- package/templates/gm/src/index.ts +6 -13
- package/templates/group/src/handler/agent.ts +17 -10
- package/templates/group/src/handler/loyalty.ts +3 -11
- package/templates/group/src/handler/splitpayment.ts +17 -10
- package/templates/group/src/handler/tipping.ts +10 -6
- package/templates/group/src/handler/transaction.ts +10 -39
- package/templates/group/src/index.ts +24 -20
- package/templates/group/src/lib/openai.ts +44 -3
- package/templates/group/src/lib/resolver.ts +126 -0
- package/templates/group/src/{commands.ts → skills.ts} +17 -16
- package/templates/agent/src/commands.ts +0 -69
- package/templates/agent/src/lib/types.ts +0 -33
- package/templates/gm/src/commands.ts +0 -18
- package/templates/gm/src/handler.ts +0 -6
@@ -6,12 +6,16 @@ const openai = new OpenAI({
|
|
6
6
|
apiKey: process.env.OPEN_AI_API_KEY,
|
7
7
|
});
|
8
8
|
|
9
|
+
export type ChatHistoryEntry = { role: string; content: string };
|
10
|
+
export type ChatHistories = Record<string, ChatHistoryEntry[]>;
|
11
|
+
|
12
|
+
let chatHistories: ChatHistories = {};
|
9
13
|
export async function textGeneration(
|
14
|
+
address: string,
|
10
15
|
userPrompt: string,
|
11
16
|
systemPrompt: string,
|
12
|
-
chatHistory?: any[],
|
13
17
|
) {
|
14
|
-
let messages =
|
18
|
+
let messages = chatHistories[address] || [];
|
15
19
|
if (messages.length === 0) {
|
16
20
|
messages.push({
|
17
21
|
role: "system",
|
@@ -33,7 +37,7 @@ export async function textGeneration(
|
|
33
37
|
content: reply || "No response from OpenAI.",
|
34
38
|
});
|
35
39
|
const cleanedReply = responseParser(reply as string);
|
36
|
-
|
40
|
+
chatHistories[address] = messages;
|
37
41
|
return { reply: cleanedReply, history: messages };
|
38
42
|
} catch (error) {
|
39
43
|
console.error("Failed to fetch from OpenAI:", error);
|
@@ -78,6 +82,38 @@ export async function vision(imageData: Uint8Array, systemPrompt: string) {
|
|
78
82
|
}
|
79
83
|
}
|
80
84
|
|
85
|
+
export async function processResponseWithSkill(
|
86
|
+
address: string,
|
87
|
+
reply: string,
|
88
|
+
context: any,
|
89
|
+
) {
|
90
|
+
let messages = reply
|
91
|
+
.split("\n")
|
92
|
+
.map((message: string) => responseParser(message))
|
93
|
+
.filter((message): message is string => message.length > 0);
|
94
|
+
|
95
|
+
console.log(messages);
|
96
|
+
for (const message of messages) {
|
97
|
+
if (message.startsWith("/")) {
|
98
|
+
const response = await context.skill(message);
|
99
|
+
if (response && response.message) {
|
100
|
+
let msg = responseParser(response.message);
|
101
|
+
|
102
|
+
if (!chatHistories[address]) {
|
103
|
+
chatHistories[address] = [];
|
104
|
+
}
|
105
|
+
chatHistories[address].push({
|
106
|
+
role: "system",
|
107
|
+
content: msg,
|
108
|
+
});
|
109
|
+
|
110
|
+
await context.send(response.message);
|
111
|
+
}
|
112
|
+
} else {
|
113
|
+
await context.send(message);
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
81
117
|
export function responseParser(message: string) {
|
82
118
|
let trimmedMessage = message;
|
83
119
|
// Remove bold and underline markdown
|
@@ -94,5 +130,10 @@ export function responseParser(message: string) {
|
|
94
130
|
trimmedMessage = trimmedMessage?.replace(/^\s+|\s+$/g, "");
|
95
131
|
// Remove any remaining leading or trailing whitespace
|
96
132
|
trimmedMessage = trimmedMessage.trim();
|
133
|
+
|
97
134
|
return trimmedMessage;
|
98
135
|
}
|
136
|
+
|
137
|
+
export const clearChatHistories = () => {
|
138
|
+
chatHistories = {};
|
139
|
+
};
|
@@ -0,0 +1,126 @@
|
|
1
|
+
import { Client } from "@xmtp/xmtp-js";
|
2
|
+
import { isAddress } from "viem";
|
3
|
+
|
4
|
+
export const converseEndpointURL =
|
5
|
+
"https://converse-website-git-endpoit-ephemerahq.vercel.app";
|
6
|
+
//export const converseEndpointURL = "http://localhost:3000";
|
7
|
+
|
8
|
+
export type InfoCache = Map<string, UserInfo>;
|
9
|
+
export type ConverseProfile = {
|
10
|
+
address: string | null;
|
11
|
+
onXmtp: boolean;
|
12
|
+
avatar: string | null;
|
13
|
+
formattedName: string | null;
|
14
|
+
name: string | null;
|
15
|
+
};
|
16
|
+
export type UserInfo = {
|
17
|
+
ensDomain?: string | undefined;
|
18
|
+
address?: string | undefined;
|
19
|
+
converseUsername?: string | undefined;
|
20
|
+
ensInfo?: EnsData | undefined;
|
21
|
+
avatar?: string | undefined;
|
22
|
+
};
|
23
|
+
export interface EnsData {
|
24
|
+
address?: string;
|
25
|
+
avatar?: string;
|
26
|
+
avatar_small?: string;
|
27
|
+
converse?: string;
|
28
|
+
avatar_url?: string;
|
29
|
+
contentHash?: string;
|
30
|
+
description?: string;
|
31
|
+
ens?: string;
|
32
|
+
ens_primary?: string;
|
33
|
+
github?: string;
|
34
|
+
resolverAddress?: string;
|
35
|
+
twitter?: string;
|
36
|
+
url?: string;
|
37
|
+
wallets?: {
|
38
|
+
eth?: string;
|
39
|
+
};
|
40
|
+
}
|
41
|
+
|
42
|
+
let infoCache: InfoCache = new Map();
|
43
|
+
|
44
|
+
export const clearInfoCache = () => {
|
45
|
+
infoCache.clear();
|
46
|
+
};
|
47
|
+
export const getUserInfo = async (
|
48
|
+
key: string,
|
49
|
+
clientAddress?: string,
|
50
|
+
): Promise<UserInfo | null> => {
|
51
|
+
let data: UserInfo = infoCache.get(key) || {
|
52
|
+
ensDomain: undefined,
|
53
|
+
address: undefined,
|
54
|
+
converseUsername: undefined,
|
55
|
+
ensInfo: undefined,
|
56
|
+
};
|
57
|
+
//console.log("Getting user info", key, clientAddress);
|
58
|
+
if (isAddress(clientAddress || "")) {
|
59
|
+
data.address = clientAddress;
|
60
|
+
} else if (isAddress(key || "")) {
|
61
|
+
data.address = key;
|
62
|
+
} else if (key.includes(".eth")) {
|
63
|
+
data.ensDomain = key;
|
64
|
+
} else if (key == "@user" || key == "@me" || key == "@bot") {
|
65
|
+
data.address = clientAddress;
|
66
|
+
data.ensDomain = key.replace("@", "") + ".eth";
|
67
|
+
data.converseUsername = key.replace("@", "");
|
68
|
+
} else if (key == "@alix") {
|
69
|
+
data.address = "0x3a044b218BaE80E5b9E16609443A192129A67BeA";
|
70
|
+
data.converseUsername = "alix";
|
71
|
+
} else if (key == "@bo") {
|
72
|
+
data.address = "0xbc3246461ab5e1682baE48fa95172CDf0689201a";
|
73
|
+
data.converseUsername = "bo";
|
74
|
+
} else {
|
75
|
+
data.converseUsername = key;
|
76
|
+
}
|
77
|
+
|
78
|
+
let keyToUse = data.address || data.ensDomain || data.converseUsername;
|
79
|
+
let cacheData = keyToUse && infoCache.get(keyToUse);
|
80
|
+
if (cacheData) {
|
81
|
+
//console.log("Getting user info", keyToUse, cacheData);
|
82
|
+
return cacheData;
|
83
|
+
} else {
|
84
|
+
//console.log("Getting user info", keyToUse, data);
|
85
|
+
}
|
86
|
+
|
87
|
+
if (keyToUse?.includes(".eth")) {
|
88
|
+
const response = await fetch(`https://ensdata.net/${keyToUse}`);
|
89
|
+
const ensData: EnsData = (await response.json()) as EnsData;
|
90
|
+
//console.log("Ens data", ensData);
|
91
|
+
if (ensData) {
|
92
|
+
data.ensInfo = ensData;
|
93
|
+
data.ensDomain = ensData?.ens;
|
94
|
+
data.address = ensData?.address;
|
95
|
+
}
|
96
|
+
} else if (keyToUse) {
|
97
|
+
keyToUse = keyToUse.replace("@", "");
|
98
|
+
const response = await fetch(`${converseEndpointURL}/profile/${keyToUse}`, {
|
99
|
+
method: "POST",
|
100
|
+
headers: {
|
101
|
+
"Content-Type": "application/json",
|
102
|
+
Accept: "application/json",
|
103
|
+
},
|
104
|
+
body: JSON.stringify({
|
105
|
+
peer: keyToUse,
|
106
|
+
}),
|
107
|
+
});
|
108
|
+
const converseData = (await response.json()) as ConverseProfile;
|
109
|
+
if (process.env.MSG_LOG)
|
110
|
+
console.log("Converse data", keyToUse, converseData);
|
111
|
+
data.converseUsername =
|
112
|
+
converseData?.formattedName || converseData?.name || undefined;
|
113
|
+
data.address = converseData?.address || undefined;
|
114
|
+
data.avatar = converseData?.avatar || undefined;
|
115
|
+
}
|
116
|
+
if (data.address) infoCache.set(data.address, data);
|
117
|
+
return data;
|
118
|
+
};
|
119
|
+
export const isOnXMTP = async (
|
120
|
+
client: Client,
|
121
|
+
domain: string | undefined,
|
122
|
+
address: string | undefined,
|
123
|
+
) => {
|
124
|
+
if (domain == "fabri.eth") return false;
|
125
|
+
if (address) return (await client.canMessage([address])).length > 0;
|
126
|
+
};
|
@@ -1,24 +1,25 @@
|
|
1
|
-
import type { CommandGroup } from "@xmtp/message-kit";
|
2
1
|
import { handler as tipping } from "./handler/tipping.js";
|
3
2
|
import { handler as agent } from "./handler/agent.js";
|
4
3
|
import { handler as transaction } from "./handler/transaction.js";
|
5
4
|
import { handler as games } from "./handler/game.js";
|
6
5
|
import { handler as loyalty } from "./handler/loyalty.js";
|
7
6
|
import { helpHandler } from "./index.js";
|
7
|
+
import type { SkillGroup } from "@xmtp/message-kit";
|
8
8
|
|
9
|
-
export const
|
9
|
+
export const skills: SkillGroup[] = [
|
10
10
|
{
|
11
11
|
name: "Tipping",
|
12
12
|
description: "Tip tokens via emoji, replies or command.",
|
13
|
-
|
13
|
+
skills: [
|
14
14
|
{
|
15
|
-
command: "/tip [@
|
16
|
-
triggers: ["/tip"
|
15
|
+
command: "/tip [@usernames] [amount] [token]",
|
16
|
+
triggers: ["/tip"],
|
17
17
|
description: "Tip users in a specified token.",
|
18
18
|
handler: tipping,
|
19
19
|
params: {
|
20
20
|
username: {
|
21
21
|
default: "",
|
22
|
+
plural: true,
|
22
23
|
type: "username",
|
23
24
|
},
|
24
25
|
amount: {
|
@@ -32,10 +33,10 @@ export const commands: CommandGroup[] = [
|
|
32
33
|
{
|
33
34
|
name: "Transactions",
|
34
35
|
description: "Multipurpose transaction frame built onbase.",
|
35
|
-
|
36
|
+
skills: [
|
36
37
|
{
|
37
|
-
command: "/send [amount] [token] [
|
38
|
-
triggers: ["
|
38
|
+
command: "/send [amount] [token] [username]",
|
39
|
+
triggers: ["/send"],
|
39
40
|
description:
|
40
41
|
"Send a specified amount of a cryptocurrency to a destination address.",
|
41
42
|
handler: transaction,
|
@@ -57,7 +58,7 @@ export const commands: CommandGroup[] = [
|
|
57
58
|
},
|
58
59
|
{
|
59
60
|
command: "/swap [amount] [token_from] [token_to]",
|
60
|
-
triggers: ["
|
61
|
+
triggers: ["/swap"],
|
61
62
|
description: "Exchange one type of cryptocurrency for another.",
|
62
63
|
handler: transaction,
|
63
64
|
params: {
|
@@ -89,10 +90,10 @@ export const commands: CommandGroup[] = [
|
|
89
90
|
{
|
90
91
|
name: "Games",
|
91
92
|
description: "Provides various gaming experiences.",
|
92
|
-
|
93
|
+
skills: [
|
93
94
|
{
|
94
95
|
command: "/game [game]",
|
95
|
-
triggers: ["/game", "
|
96
|
+
triggers: ["/game", "🔎", "🔍"],
|
96
97
|
handler: games,
|
97
98
|
description: "Play a game.",
|
98
99
|
params: {
|
@@ -108,17 +109,17 @@ export const commands: CommandGroup[] = [
|
|
108
109
|
{
|
109
110
|
name: "Loyalty",
|
110
111
|
description: "Manage group members and metadata.",
|
111
|
-
|
112
|
+
skills: [
|
112
113
|
{
|
113
114
|
command: "/points",
|
114
|
-
triggers: ["/points"
|
115
|
+
triggers: ["/points"],
|
115
116
|
handler: loyalty,
|
116
117
|
description: "Check your points.",
|
117
118
|
params: {},
|
118
119
|
},
|
119
120
|
{
|
120
121
|
command: "/leaderboard",
|
121
|
-
triggers: ["/leaderboard"
|
122
|
+
triggers: ["/leaderboard"],
|
122
123
|
adminOnly: true,
|
123
124
|
handler: loyalty,
|
124
125
|
description: "Check the points of a user.",
|
@@ -129,7 +130,7 @@ export const commands: CommandGroup[] = [
|
|
129
130
|
{
|
130
131
|
name: "Agent",
|
131
132
|
description: "Manage agent commands.",
|
132
|
-
|
133
|
+
skills: [
|
133
134
|
{
|
134
135
|
command: "/agent [prompt]",
|
135
136
|
triggers: ["/agent", "@agent", "@bot"],
|
@@ -147,7 +148,7 @@ export const commands: CommandGroup[] = [
|
|
147
148
|
{
|
148
149
|
name: "Help",
|
149
150
|
description: "Get help with the bot.",
|
150
|
-
|
151
|
+
skills: [
|
151
152
|
{
|
152
153
|
command: "/help",
|
153
154
|
triggers: ["/help"],
|
@@ -1,69 +0,0 @@
|
|
1
|
-
import type { CommandGroup } from "@xmtp/message-kit";
|
2
|
-
import { ensAgent, handleEns } from "./handler/ens.js";
|
3
|
-
|
4
|
-
export const commands: CommandGroup[] = [
|
5
|
-
{
|
6
|
-
name: "Ens Domain Bot",
|
7
|
-
description: "Register ENS domains.",
|
8
|
-
commands: [
|
9
|
-
{
|
10
|
-
command: "/register [domain]",
|
11
|
-
triggers: ["/register", "@ensbot"],
|
12
|
-
handler: handleEns,
|
13
|
-
description: "Register a domain.",
|
14
|
-
params: {
|
15
|
-
domain: {
|
16
|
-
type: "string",
|
17
|
-
},
|
18
|
-
},
|
19
|
-
},
|
20
|
-
{
|
21
|
-
command: "/info [domain]",
|
22
|
-
triggers: ["/info", "@ensbot"],
|
23
|
-
handler: handleEns,
|
24
|
-
description: "Get information about a domain.",
|
25
|
-
params: {
|
26
|
-
domain: {
|
27
|
-
type: "string",
|
28
|
-
},
|
29
|
-
},
|
30
|
-
},
|
31
|
-
{
|
32
|
-
command: "/renew [domain]",
|
33
|
-
triggers: ["/renew", "@ensbot"],
|
34
|
-
handler: handleEns,
|
35
|
-
description: "Renew a domain.",
|
36
|
-
params: {
|
37
|
-
domain: {
|
38
|
-
type: "string",
|
39
|
-
},
|
40
|
-
},
|
41
|
-
},
|
42
|
-
{
|
43
|
-
command: "/check [domain] [cool_alternatives]",
|
44
|
-
triggers: ["/check"],
|
45
|
-
handler: handleEns,
|
46
|
-
description: "Check if a domain is available.",
|
47
|
-
params: {
|
48
|
-
domain: {
|
49
|
-
type: "string",
|
50
|
-
},
|
51
|
-
cool_alternatives: {
|
52
|
-
type: "quoted",
|
53
|
-
},
|
54
|
-
},
|
55
|
-
},
|
56
|
-
{
|
57
|
-
command: "/tip [address]",
|
58
|
-
description: "Show a URL for tipping a domain owner.",
|
59
|
-
triggers: ["/tip"],
|
60
|
-
handler: ensAgent,
|
61
|
-
params: {
|
62
|
-
address: {
|
63
|
-
type: "address",
|
64
|
-
},
|
65
|
-
},
|
66
|
-
},
|
67
|
-
],
|
68
|
-
},
|
69
|
-
];
|
@@ -1,33 +0,0 @@
|
|
1
|
-
export type chatHistories = Record<string, any[]>;
|
2
|
-
export type ensDomain = Record<string, string | undefined>;
|
3
|
-
export type converseUsername = Record<string, string | undefined>;
|
4
|
-
export type tipAddress = Record<string, string | undefined>;
|
5
|
-
export type tipDomain = Record<string, string | undefined>;
|
6
|
-
|
7
|
-
export type InfoCache = {
|
8
|
-
[key: string]: { info: EnsData };
|
9
|
-
};
|
10
|
-
export const frameUrl = "https://ens.steer.fun/";
|
11
|
-
export const ensUrl = "https://app.ens.domains/";
|
12
|
-
export const baseTxUrl = "https://base-tx-frame.vercel.app";
|
13
|
-
export const endpointURL =
|
14
|
-
"https://converse-website-git-endpoit-ephemerahq.vercel.app";
|
15
|
-
|
16
|
-
export interface EnsData {
|
17
|
-
address?: string;
|
18
|
-
avatar?: string;
|
19
|
-
avatar_small?: string;
|
20
|
-
converse?: string;
|
21
|
-
avatar_url?: string;
|
22
|
-
contentHash?: string;
|
23
|
-
description?: string;
|
24
|
-
ens?: string;
|
25
|
-
ens_primary?: string;
|
26
|
-
github?: string;
|
27
|
-
resolverAddress?: string;
|
28
|
-
twitter?: string;
|
29
|
-
url?: string;
|
30
|
-
wallets?: {
|
31
|
-
eth?: string;
|
32
|
-
};
|
33
|
-
}
|
@@ -1,18 +0,0 @@
|
|
1
|
-
import { handler as handlerAll } from "./handler.js";
|
2
|
-
import type { CommandGroup } from "@xmtp/message-kit";
|
3
|
-
|
4
|
-
export const commands: CommandGroup[] = [
|
5
|
-
{
|
6
|
-
name: "Gm Commands",
|
7
|
-
description: "Commands to send a gm.",
|
8
|
-
commands: [
|
9
|
-
{
|
10
|
-
command: "/gm",
|
11
|
-
triggers: ["/gm"],
|
12
|
-
description: "Send a gm.",
|
13
|
-
handler: handlerAll,
|
14
|
-
params: {},
|
15
|
-
},
|
16
|
-
],
|
17
|
-
},
|
18
|
-
];
|