create-message-kit 1.0.17 → 1.0.20
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 +12 -11
- 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
@@ -2,7 +2,7 @@
|
|
2
2
|
import { program } from "commander";
|
3
3
|
import { dirname, resolve } from "node:path";
|
4
4
|
import { fileURLToPath } from "node:url";
|
5
|
-
import {
|
5
|
+
import { log, outro, text, select } from "@clack/prompts";
|
6
6
|
import { default as fs } from "fs-extra";
|
7
7
|
import { isCancel } from "@clack/prompts";
|
8
8
|
import pc from "picocolors";
|
@@ -19,16 +19,17 @@ program
|
|
19
19
|
.name("byob")
|
20
20
|
.description("CLI to initialize projects")
|
21
21
|
.action(async () => {
|
22
|
-
log.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
log.info(pc.cyan(`Welcome to MessageKit v${version}!`));
|
23
|
+
const coolLogo = `
|
24
|
+
███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗██╗ ██╗██╗████████╗
|
25
|
+
████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝██║ ██╔╝██║╚══██╔══╝
|
26
|
+
██╔████╔██║█████╗ ███████╗███████╗███████║██║ ███╗█████╗ █████╔╝ ██║ ██║
|
27
|
+
██║╚██╔╝██║██╔══╝ ╚════██║╚════██║██╔══██║██║ ██║██╔══╝ ██╔═██╗ ██║ ██║
|
28
|
+
██║ ╚═╝ ██║███████╗███████║███████║██║ ██║╚██████╔╝███████╗██║ ██╗██║ ██║
|
29
|
+
╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
|
30
|
+
Powered by XMTP`;
|
31
|
+
|
32
|
+
log.info(pc.cyan(coolLogo));
|
32
33
|
|
33
34
|
const { templateType, displayName, destDir } = await gatherProjectInfo();
|
34
35
|
|
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
|
{
|