create-message-kit 1.0.17 → 1.0.19
Sign up to get free protection for your applications and to get access to all the features.
- package/index.js +10 -10
- package/package.json +1 -1
- package/templates/agent/src/handler/ens.ts +6 -6
- package/templates/agent/src/index.ts +2 -6
- package/templates/agent/src/lib/openai.ts +5 -2
- package/templates/agent/src/prompt.ts +26 -36
- package/templates/agent/src/skills.ts +6 -4
- package/templates/group/src/lib/openai.ts +5 -3
- package/templates/group/src/skills.ts +1 -1
package/index.js
CHANGED
@@ -19,16 +19,16 @@ program
|
|
19
19
|
.name("byob")
|
20
20
|
.description("CLI to initialize projects")
|
21
21
|
.action(async () => {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
const coolLogo = `\x1b[38;2;250;105;119m\
|
23
|
+
|
24
|
+
███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗██╗ ██╗██╗████████╗
|
25
|
+
████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝██║ ██╔╝██║╚══██╔══╝
|
26
|
+
██╔████╔██║█████╗ ███████╗███████╗███████║██║ ███╗█████╗ █████╔╝ ██║ ██║
|
27
|
+
██║╚██╔╝██║██╔══╝ ╚════██║╚════██║██╔══██║██║ ██║██╔══╝ ██╔═██╗ ██║ ██║
|
28
|
+
██║ ╚═╝ ██║███████╗███████║███████║██║ ██║╚██████╔╝███████╗██║ ██╗██║ ██║
|
29
|
+
╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
|
30
|
+
Powered by XMTP \x1b[0m`;
|
31
|
+
console.log(coolLogo);
|
32
32
|
|
33
33
|
const { templateType, displayName, destDir } = await gatherProjectInfo();
|
34
34
|
|
package/package.json
CHANGED
@@ -4,9 +4,12 @@ import { textGeneration } from "../lib/openai.js";
|
|
4
4
|
import { processResponseWithSkill } from "../lib/openai.js";
|
5
5
|
import { isAddress } from "viem";
|
6
6
|
import { ens_agent_prompt } from "../prompt.js";
|
7
|
-
import { frameUrl, ensUrl, baseTxUrl } from "../index.js";
|
8
7
|
import { clearChatHistories } from "../lib/openai.js";
|
9
8
|
|
9
|
+
export const frameUrl = "https://ens.steer.fun/";
|
10
|
+
export const ensUrl = "https://app.ens.domains/";
|
11
|
+
export const baseTxUrl = "https://base-tx-frame.vercel.app";
|
12
|
+
|
10
13
|
export async function handleEns(context: HandlerContext) {
|
11
14
|
const {
|
12
15
|
message: {
|
@@ -108,7 +111,7 @@ export async function handleEns(context: HandlerContext) {
|
|
108
111
|
|
109
112
|
const data = await getUserInfo(domain);
|
110
113
|
if (!data?.address) {
|
111
|
-
let message = `Looks like ${domain} is available!
|
114
|
+
let message = `Looks like ${domain} is available! Here you can register it: ${ensUrl}${domain} or would you like to see some cool alternatives?`;
|
112
115
|
return {
|
113
116
|
code: 200,
|
114
117
|
message,
|
@@ -169,13 +172,10 @@ export async function ensAgent(context: HandlerContext) {
|
|
169
172
|
console.log("User info not found");
|
170
173
|
return;
|
171
174
|
}
|
172
|
-
const { ensDomain, converseUsername } = userInfo;
|
173
|
-
|
174
175
|
const { reply } = await textGeneration(
|
175
176
|
sender.address,
|
176
177
|
userPrompt,
|
177
|
-
await ens_agent_prompt(
|
178
|
-
group !== undefined,
|
178
|
+
await ens_agent_prompt(userInfo),
|
179
179
|
);
|
180
180
|
await processResponseWithSkill(sender.address, reply, context);
|
181
181
|
} catch (error) {
|
@@ -1,14 +1,10 @@
|
|
1
1
|
import { run, HandlerContext } from "@xmtp/message-kit";
|
2
2
|
import { ensAgent } from "./handler/ens.js";
|
3
3
|
|
4
|
-
export const frameUrl = "https://ens.steer.fun/";
|
5
|
-
export const ensUrl = "https://app.ens.domains/";
|
6
|
-
export const baseTxUrl = "https://base-tx-frame.vercel.app";
|
7
|
-
|
8
4
|
run(async (context: HandlerContext) => {
|
9
|
-
const { group, message } = context;
|
10
5
|
/*All the commands are handled through the commands file*/
|
11
6
|
/* If its just text, it will be handled by the ensAgent*/
|
12
7
|
/* If its a group message, it will be handled by the groupAgent*/
|
13
|
-
|
8
|
+
|
9
|
+
ensAgent(context);
|
14
10
|
});
|
@@ -14,7 +14,6 @@ export async function textGeneration(
|
|
14
14
|
address: string,
|
15
15
|
userPrompt: string,
|
16
16
|
systemPrompt: string,
|
17
|
-
isGroup: boolean = false,
|
18
17
|
) {
|
19
18
|
let messages = chatHistories[address] || [];
|
20
19
|
if (messages.length === 0) {
|
@@ -38,7 +37,8 @@ export async function textGeneration(
|
|
38
37
|
content: reply || "No response from OpenAI.",
|
39
38
|
});
|
40
39
|
const cleanedReply = responseParser(reply as string);
|
41
|
-
|
40
|
+
chatHistories[address] = messages;
|
41
|
+
console.log("messages.length", messages.length);
|
42
42
|
return { reply: cleanedReply, history: messages };
|
43
43
|
} catch (error) {
|
44
44
|
console.error("Failed to fetch from OpenAI:", error);
|
@@ -100,6 +100,9 @@ export async function processResponseWithSkill(
|
|
100
100
|
if (response && response.message) {
|
101
101
|
let msg = responseParser(response.message);
|
102
102
|
|
103
|
+
if (!chatHistories[address]) {
|
104
|
+
chatHistories[address] = [];
|
105
|
+
}
|
103
106
|
chatHistories[address].push({
|
104
107
|
role: "system",
|
105
108
|
content: msg,
|
@@ -1,11 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
converseUsername
|
6
|
-
|
7
|
-
|
8
|
-
const systemPrompt = `You are a helpful and playful agent that lives inside a web3 messaging app called Converse.
|
1
|
+
import { skills } from "./skills.js";
|
2
|
+
import type { UserInfo } from "./lib/resolver.js";
|
3
|
+
|
4
|
+
export async function ens_agent_prompt(userInfo: UserInfo) {
|
5
|
+
let { address, ensDomain, converseUsername } = userInfo;
|
6
|
+
|
7
|
+
const systemPrompt = `You are a helpful and playful agent called @ens that lives inside a web3 messaging app called Converse.
|
9
8
|
- You can respond with multiple messages if needed. Each message should be separated by a newline character.
|
10
9
|
- You can trigger commands by only sending the command in a newline message.
|
11
10
|
- Never announce actions without using a command separated by a newline character.
|
@@ -16,8 +15,8 @@ export async function ens_agent_prompt(
|
|
16
15
|
|
17
16
|
User context:
|
18
17
|
- Users address is: ${address}
|
19
|
-
${
|
20
|
-
${
|
18
|
+
${ensDomain != undefined ? `- User ENS domain is: ${ensDomain}` : ""}
|
19
|
+
${converseUsername != undefined ? `- Converse username is: ${converseUsername}` : ""}
|
21
20
|
|
22
21
|
## Task
|
23
22
|
- Start by fetch their domain from or Convese username
|
@@ -25,57 +24,48 @@ ${name != undefined ? `- Converse username is: ${name}` : ""}
|
|
25
24
|
- Ask for a name (if they don't have one) so you can suggest domains.
|
26
25
|
|
27
26
|
Commands:
|
28
|
-
|
29
|
-
- "/check [domain]": To check to see if a domain is available use this command.
|
30
|
-
- "/register [domain]": To register a domain use this command. This will return a url pointing to the registration page.
|
31
|
-
- "/renew [domain]": To trigger renewal of a domain use this command. This will return a url with a button to renew the domain.
|
32
|
-
- "/tip [address]": To tip a domain or address use this command. This will return a url with a button to send the tip
|
33
|
-
- "/cool [domain]": To get cool alternatives for a .eth domain use this command.
|
27
|
+
${skills.map((skill) => skill.skills.map((s) => s.command).join("\n")).join("\n")}
|
34
28
|
|
35
29
|
Examples:
|
36
|
-
|
37
|
-
|
38
|
-
- /register vitalik.eth
|
39
|
-
- /renew fabri.base.eth
|
40
|
-
- /tip 0xf0EA7663233F99D0c12370671abBb6Cca980a490
|
41
|
-
- /cool vitalik.eth
|
30
|
+
${skills.map((skill) => skill.skills.map((s) => s.example).join("\n")).join("\n")}
|
31
|
+
|
42
32
|
|
43
|
-
## Example
|
33
|
+
## Example responses:
|
44
34
|
|
45
35
|
1. Check if the user does not have a ENS domain
|
46
|
-
Hey ${
|
36
|
+
Hey ${converseUsername}! it looks like you don't have a ENS domain yet! \n\Let me start by checking your Converse username with the .eth suffix\n/check ${converseUsername}.eth
|
47
37
|
|
48
38
|
2. If the user has a ENS domain
|
49
|
-
Hello ${
|
39
|
+
Hello ${ensDomain} ! I'll help you get your ENS domain.\n Let's start by checking your ENS domain ${ensDomain}. Give me a moment.\n/check ${ensDomain}
|
50
40
|
|
51
41
|
3. Check if the ENS domain is available
|
52
|
-
Hello! I'll help you get your domain.\n Let's start by checking your ENS domain ${
|
42
|
+
Hello! I'll help you get your domain.\n Let's start by checking your ENS domain ${ensDomain}. Give me a moment.\n/check ${ensDomain}
|
53
43
|
|
54
44
|
4. If the ENS domain is available,
|
55
|
-
Looks like ${
|
45
|
+
Looks like ${ensDomain} is available! Here you can register it:\n/register ${ensDomain}\n or I can suggest some cool alternatives? Le me know!
|
56
46
|
|
57
47
|
5. If the ENS domain is already registered, let me suggest 5 cool alternatives
|
58
|
-
Looks like ${
|
48
|
+
Looks like ${ensDomain} is already registered!\n What about these cool alternatives?\n/cool ${ensDomain}
|
59
49
|
|
60
50
|
6. If the user wants to register a ENS domain, use the command "/register [domain]"
|
61
|
-
Looks like ${
|
51
|
+
Looks like ${ensDomain} is available! Let me help you register it\n/register ${ensDomain}
|
62
52
|
|
63
53
|
7. If the user wants to directly to tip to the ENS domain owner, use directly the command "/tip [domain]", this will return a url but a button to send the tip
|
64
|
-
Here is the url to send the tip:\n/tip ${
|
54
|
+
Here is the url to send the tip:\n/tip ${ensDomain}
|
65
55
|
|
66
56
|
8. If the user wants to get information about the ENS domain, use the command "/info [domain]"
|
67
|
-
Hello! I'll help you get info about ${
|
57
|
+
Hello! I'll help you get info about ${ensDomain}.\n Give me a moment.\n/info ${ensDomain}
|
68
58
|
|
69
59
|
9. If the user wants to renew their domain, use the command "/renew [domain]"
|
70
|
-
Hello! I'll help you get your ENS domain.\n Let's start by checking your ENS domain ${
|
60
|
+
Hello! I'll help you get your ENS domain.\n Let's start by checking your ENS domain ${ensDomain}. Give me a moment.\n/renew ${ensDomain}
|
71
61
|
|
72
62
|
10. If the user wants cool suggestions about a domain, use the command "/cool [domain]"
|
73
|
-
Here are some cool suggestions for your domain.\n/cool ${
|
63
|
+
Here are some cool suggestions for your domain.\n/cool ${ensDomain}
|
74
64
|
|
75
65
|
## Most common bug
|
76
|
-
Some times you will say something like: "Looks like vitalik.eth is registered! What about these cool alternatives?"
|
77
|
-
But you forgot to add the command at the end of the message.
|
78
|
-
You should have said something like: "Looks like vitalik.eth is registered! What about these cool alternatives?\n/cool vitalik.eth
|
66
|
+
Some times you will say something like: "Looks like vitalik.eth is registered! What about these cool alternatives?"
|
67
|
+
But you forgot to add the command at the end of the message.
|
68
|
+
You should have said something like: "Looks like vitalik.eth is registered! What about these cool alternatives?\n/cool vitalik.eth
|
79
69
|
`;
|
80
70
|
return systemPrompt;
|
81
71
|
}
|
@@ -1,14 +1,16 @@
|
|
1
|
+
import { handleEns, ensAgent } from "./handler/ens.js";
|
1
2
|
import type { SkillGroup } from "@xmtp/message-kit";
|
2
|
-
import { handleEns } from "./handler/ens.js";
|
3
3
|
|
4
4
|
export const skills: SkillGroup[] = [
|
5
5
|
{
|
6
6
|
name: "Ens Domain Bot",
|
7
|
+
tag: "@ens",
|
8
|
+
tagHandler: ensAgent,
|
7
9
|
description: "Register ENS domains.",
|
8
10
|
skills: [
|
9
11
|
{
|
10
12
|
command: "/register [domain]",
|
11
|
-
triggers: ["/register"
|
13
|
+
triggers: ["/register"],
|
12
14
|
handler: handleEns,
|
13
15
|
description:
|
14
16
|
"Register a new ENS domain. Returns a URL to complete the registration process.",
|
@@ -21,7 +23,7 @@ export const skills: SkillGroup[] = [
|
|
21
23
|
},
|
22
24
|
{
|
23
25
|
command: "/info [domain]",
|
24
|
-
triggers: ["/info"
|
26
|
+
triggers: ["/info"],
|
25
27
|
handler: handleEns,
|
26
28
|
description:
|
27
29
|
"Get detailed information about an ENS domain including owner, expiry date, and resolver.",
|
@@ -34,7 +36,7 @@ export const skills: SkillGroup[] = [
|
|
34
36
|
},
|
35
37
|
{
|
36
38
|
command: "/renew [domain]",
|
37
|
-
triggers: ["/renew"
|
39
|
+
triggers: ["/renew"],
|
38
40
|
handler: handleEns,
|
39
41
|
description:
|
40
42
|
"Extend the registration period of your ENS domain. Returns a URL to complete the renewal.",
|
@@ -14,7 +14,6 @@ export async function textGeneration(
|
|
14
14
|
address: string,
|
15
15
|
userPrompt: string,
|
16
16
|
systemPrompt: string,
|
17
|
-
isGroup: boolean = false,
|
18
17
|
) {
|
19
18
|
let messages = chatHistories[address] || [];
|
20
19
|
if (messages.length === 0) {
|
@@ -38,7 +37,7 @@ export async function textGeneration(
|
|
38
37
|
content: reply || "No response from OpenAI.",
|
39
38
|
});
|
40
39
|
const cleanedReply = responseParser(reply as string);
|
41
|
-
|
40
|
+
chatHistories[address] = messages;
|
42
41
|
return { reply: cleanedReply, history: messages };
|
43
42
|
} catch (error) {
|
44
43
|
console.error("Failed to fetch from OpenAI:", error);
|
@@ -83,7 +82,7 @@ export async function vision(imageData: Uint8Array, systemPrompt: string) {
|
|
83
82
|
}
|
84
83
|
}
|
85
84
|
|
86
|
-
export async function
|
85
|
+
export async function processResponseWithSkill(
|
87
86
|
address: string,
|
88
87
|
reply: string,
|
89
88
|
context: any,
|
@@ -100,6 +99,9 @@ export async function processResponseWithskill(
|
|
100
99
|
if (response && response.message) {
|
101
100
|
let msg = responseParser(response.message);
|
102
101
|
|
102
|
+
if (!chatHistories[address]) {
|
103
|
+
chatHistories[address] = [];
|
104
|
+
}
|
103
105
|
chatHistories[address].push({
|
104
106
|
role: "system",
|
105
107
|
content: msg,
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import type { SkillGroup } 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
9
|
export const skills: SkillGroup[] = [
|
10
10
|
{
|