Skip to content

Commit

Permalink
Merge pull request #2 from plutohan/init-pie-agent
Browse files Browse the repository at this point in the history
Initialize pie agent
  • Loading branch information
plutohan authored Mar 4, 2025
2 parents 1ab6a47 + 707bfd8 commit af0053d
Show file tree
Hide file tree
Showing 13 changed files with 459 additions and 384 deletions.
7 changes: 4 additions & 3 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
@tailwind utilities;

body {
color: #f8f8f8;
background: #131318;
color: #161514;
background: #fff;
}

body input,
body textarea {
color: black;
border: 10px solid #d16e1033;
}

a {
color: #2d7bd4;
color: #1d1bd1;
}

a:hover {
Expand Down
66 changes: 30 additions & 36 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,36 @@ import { Public_Sans } from "next/font/google";
const publicSans = Public_Sans({ subsets: ["latin"] });

export default function RootLayout({
children,
children,
}: {
children: React.ReactNode;
children: React.ReactNode;
}) {
return (
<html lang="en">
<head>
<title>SolanaAgentKit + LangChain + Next.js Template</title>
<link rel="shortcut icon" href="/images/favicon.ico" />
<meta
name="description"
content="Starter template showing how to use SolanaAgentKit with Langchain in Next.js projects."
/>
<meta
property="og:title"
content="SolanaAgentKit + LangChain + Next.js Template"
/>
<meta
property="og:description"
content="Starter template showing how to use SolanaAgentKit with LangChain in Next.js projects."
/>
<meta property="og:image" content="/images/title-card.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:title"
content="SolanaAgentKit + LangChain + Next.js Template"
/>
<meta
name="twitter:description"
content="Starter template showing how to use SolanaAgentKit with LangChain in Next.js projects."
/>
<meta name="twitter:image" content="/images/title-card.png" />
</head>
<body className={publicSans.className}>
<div className="flex flex-col p-4 md:p-12 h-[100vh]">{children}</div>
</body>
</html>
);
return (
<html lang="en">
<head>
<title>Pie.Fun Super Smart AI Agent</title>
<link rel="shortcut icon" href="/images/favicon.ico" />
<meta
name="description"
content="Starter template showing how to use SolanaAgentKit with Langchain in Next.js projects."
/>
<meta property="og:title" content="Pie.Fun Super Smart AI Agent" />
<meta
property="og:description"
content="Starter template showing how to use SolanaAgentKit with LangChain in Next.js projects."
/>
<meta property="og:image" content="/images/title-card.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Pie.Fun Super Smart AI Agent" />
<meta
name="twitter:description"
content="Starter template showing how to use SolanaAgentKit with LangChain in Next.js projects."
/>
<meta name="twitter:image" content="/images/title-card.png" />
</head>
<body className={publicSans.className}>
<div className="flex flex-col p-4 md:p-12 h-[100vh]">{children}</div>
</body>
</html>
);
}
90 changes: 19 additions & 71 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,23 @@
import { ChatWindow } from "@/components/ChatWindow";

export default function Home() {
const InfoCard = (
<div className="p-4 md:p-8 rounded bg-[#25252d] w-full max-h-[85%] overflow-hidden">
<h1 className="text-3xl md:text-4xl mb-4">
SolanaAgentKit + LangChain.js 🦜🔗 + Next.js
</h1>
<ul>
<li className="text-l">
🤝
<span className="ml-2">
This template showcases a simple agent chatbot using{" "}
<a href="https://www.solanaagentkit.xyz/">SolanaAgentKit</a>
{", "}
<a href="https://js.langchain.com/" target="_blank">
LangChain.js
</a>{" "}
and the Vercel{" "}
<a href="https://sdk.vercel.ai/docs" target="_blank">
AI SDK
</a>{" "}
in a{" "}
<a href="https://nextjs.org/" target="_blank">
Next.js
</a>{" "}
project.
</span>
</li>
<li className="hidden text-l md:block">
💻
<span className="ml-2">
You can find the prompt and model logic for this use-case in{" "}
<code>app/api/chat/route.ts</code>.
</span>
</li>
<li className="hidden text-l md:block">
🎨
<span className="ml-2">
The main frontend logic is found in <code>app/page.tsx</code>.
</span>
</li>
<li className="text-l">
🐙
<span className="ml-2">
This template is open source - you can see the source code and
deploy your own version{" "}
<a
href="https://github.com/michaelessiet/solana-agent-nextjs-starter-langchain"
target="_blank"
>
from the GitHub repo
</a>
!
</span>
</li>
<li className="text-l">
👇
<span className="ml-2">
Try asking e.g. <code>What is my wallet address?</code> below!
</span>
</li>
</ul>
</div>
);
return (
<ChatWindow
endpoint="api/chat"
emoji="🤖"
titleText="Solana agent"
placeholder="I'm your friendly Solana agent! Ask me anything..."
emptyStateComponent={InfoCard}
></ChatWindow>
);
const InfoCard = (
<div className="p-4 md:p-8 rounded bg-[#D16E1033] w-full max-h-[85%] overflow-hidden">
<h1 className="text-3xl md:text-4xl mb-4">
Pie.Fun Super Smart AI Agent
</h1>
<p>
Ask me anything about Pie.Fun. I&apos;m your friendly Pie.Fun agent!
</p>
</div>
);
return (
<ChatWindow
endpoint="api/chat"
emoji="🥧"
titleText="Pie.Fun Super Smart AI Agent"
placeholder="I'm your friendly Pie.Fun agent! Ask me anything..."
emptyStateComponent={InfoCard}
></ChatWindow>
);
}
100 changes: 51 additions & 49 deletions components/ChatMessageBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,58 @@ import type { Message } from "ai/react";
import { useMemo } from "react";

export function ChatMessageBubble(props: {
message: Message;
aiEmoji?: string;
sources: any[];
message: Message;
aiEmoji?: string;
sources: any[];
}) {
const colorClassName =
props.message.role === "user" ? "bg-sky-600" : "bg-slate-50 text-black";
const alignmentClassName =
props.message.role === "user" ? "ml-auto" : "mr-auto";
const prefix = props.message.role === "user" ? "🧑" : props.aiEmoji;
const colorClassName =
props.message.role === "user"
? "bg-[#D16E1033]"
: "bg-[#ECEDF1] text-black";
const alignmentClassName =
props.message.role === "user" ? "ml-auto" : "mr-auto";
const prefix = props.message.role === "user" ? "🧑" : props.aiEmoji;

const content = useMemo(() => {
return markdownToHtml(props.message.content);
}, [props.message.content]);
const content = useMemo(() => {
return markdownToHtml(props.message.content);
}, [props.message.content]);

return (
<div
className={`${alignmentClassName} ${colorClassName} rounded px-4 py-2 max-w-[80%] mb-8 flex`}
>
<div className="mr-2">{prefix}</div>
<div className="flex flex-col">
<div
className="prose prose-lg max-w-none"
dangerouslySetInnerHTML={{ __html: content }}
></div>
{props.sources && props.sources.length ? (
<>
<code className="mt-4 mr-auto bg-slate-600 px-2 py-1 rounded">
<h2>🔍 Sources:</h2>
</code>
<code className="mt-1 mr-2 bg-slate-600 px-2 py-1 rounded text-xs">
{props.sources?.map((source, i) => (
<div className="mt-2" key={"source:" + i}>
{i + 1}. &quot;{source.pageContent}&quot;
{source.metadata?.loc?.lines !== undefined ? (
<div>
<br />
Lines {source.metadata?.loc?.lines?.from} to{" "}
{source.metadata?.loc?.lines?.to}
</div>
) : (
""
)}
</div>
))}
</code>
</>
) : (
""
)}
</div>
</div>
);
return (
<div
className={`${alignmentClassName} ${colorClassName} rounded px-4 py-2 max-w-[80%] mb-8 flex`}
>
<div className="mr-2">{prefix}</div>
<div className="flex flex-col">
<div
className="prose prose-lg max-w-none"
dangerouslySetInnerHTML={{ __html: content }}
></div>
{props.sources && props.sources.length ? (
<>
<code className="mt-4 mr-auto bg-slate-600 px-2 py-1 rounded">
<h2>🔍 Sources:</h2>
</code>
<code className="mt-1 mr-2 bg-slate-600 px-2 py-1 rounded text-xs">
{props.sources?.map((source, i) => (
<div className="mt-2" key={"source:" + i}>
{i + 1}. &quot;{source.pageContent}&quot;
{source.metadata?.loc?.lines !== undefined ? (
<div>
<br />
Lines {source.metadata?.loc?.lines?.from} to{" "}
{source.metadata?.loc?.lines?.to}
</div>
) : (
""
)}
</div>
))}
</code>
</>
) : (
""
)}
</div>
</div>
);
}
Loading

0 comments on commit af0053d

Please sign in to comment.