Skip to content

Commit

Permalink
Merge pull request #47 from dwhiffing/edit-contract-descriptions
Browse files Browse the repository at this point in the history
Allows editing of tool descriptions
  • Loading branch information
dwhiffing authored Sep 6, 2024
2 parents dbd1edb + 37c8e90 commit 7bb2739
Show file tree
Hide file tree
Showing 19 changed files with 656 additions and 210 deletions.
13 changes: 2 additions & 11 deletions app/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { NextRequest, NextResponse } from "next/server";
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";

import { getAbi } from "@/utils/abi";
import { generateToolFromABI } from "@/utils/generateToolFromABI";
import { getToolsFromContracts } from "@/utils/generateToolFromABI";
import { CustomParser } from "@/utils/CustomParser";
import { contractCollection } from "@/utils/collections";
import { mapToLcMessages } from "@/utils/mapToLcMessages";
Expand Down Expand Up @@ -33,15 +32,7 @@ export async function POST(req: NextRequest) {
]);

try {
const abis = await Promise.all(
contracts.map((contract) => getAbi(contract.address, contract.chainId)),
);
const tools = abis.flatMap((abi, i) => {
const contract = contracts[i];
return abi
.filter((f: any) => f.name && f.type === "function")
.map(generateToolFromABI(contract));
});
const tools = getToolsFromContracts(contracts);

const model = new ChatOpenAI({
model: "gpt-4o-mini",
Expand Down
48 changes: 43 additions & 5 deletions app/api/contracts/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { contractCollection } from "@/utils/collections";
import { setAbi } from "@/utils/abi";
import { getAbi } from "@/utils/abi";
import { NextRequest, NextResponse } from "next/server";
import { getContractABIDescriptions } from "@/utils/generateToolFromABI";
import { AbiFunction } from "abitype";

export const runtime = "nodejs";

Expand Down Expand Up @@ -32,17 +34,53 @@ export async function POST(req: NextRequest) {
throw new Error("Contract address is not valid");
}

if (body.abi) {
const isValidABI = await setAbi(body.address, body.chainId, body.abi);
if (!isValidABI) {
throw new Error("Contract ABI is not valid");
let abi: AbiFunction[] = [];
try {
if (body.abi) {
abi = await JSON.parse(body.abi);
} else {
abi = await getAbi(body.address, body.chainId);
}
} catch (e) {
throw new Error("Contract ABI is not valid");
}

const abiDescriptions = getContractABIDescriptions(
{ key: -1, ...body },
abi,
);
await contractCollection.add({
address: body.address,
name: body.name,
description: body.description,
chainId: body.chainId,
abi,
abiDescriptions,
});

const contracts = await contractCollection.get();

return NextResponse.json({ contracts }, { status: 200 });
} catch (e: any) {
console.log(e);
return NextResponse.json({ error: e.message }, { status: e.status ?? 500 });
}
}

export async function PATCH(req: NextRequest) {
try {
const body = await req.json();
const existingContracts = await contractCollection.get();

if (!existingContracts.some((c) => c.key === body.key)) {
throw new Error("Contract doesnt exist");
}

await contractCollection.update({
key: body.key,
name: body.name,
description: body.description,
abiDescriptions: body.abiDescriptions,
});

const contracts = await contractCollection.get();
Expand Down
22 changes: 4 additions & 18 deletions app/api/execute/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { NextRequest, NextResponse } from "next/server";
import { getAbi } from "@/utils/abi";
import { generateToolFromABI } from "@/utils/generateToolFromABI";
import { getToolsFromContracts } from "@/utils/generateToolFromABI";
import { routeBodySchema } from "./schemas";
import { contractCollection } from "@/utils/collections";

Expand Down Expand Up @@ -39,23 +38,10 @@ export async function POST(req: NextRequest) {
}

try {
let abi = [];
try {
abi = await getAbi(contract.address, contract.chainId);
} catch (e) {
return NextResponse.json(
{
error: `Could Not retreive ABI for contract ${contract.address}`,
},
{ status: 400 },
);
}

const tools = abi
.filter((f: any) => f.name && f.type === "function")
.map(generateToolFromABI(contract, didToken));
const tool = getToolsFromContracts([contract], didToken).find(
(t) => t.name === toolCall.name,
);

const tool = tools.find((t: any) => t.name === toolCall.name);
if (!tool) {
return NextResponse.json(
{
Expand Down
21 changes: 14 additions & 7 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import {
} from "@/components/UploadContractModal";
import { useContracts } from "@/utils/useContracts";
import { ScrollArea } from "@/components/ui/scroll-area";
import { EditContractModal } from "@/components/EditContractModal";

export default function Page() {
const { contracts, onRemove } = useContracts();
const [isModalOpen, setIsModalOpen] = useState(false);
const { contracts } = useContracts();
const [editContractKey, setEditContractKey] = useState<number | null>(null);
const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
const { magic, isLoggedIn, handleLogin, handleLogout, isLoading } =
useMagic();

Expand All @@ -35,17 +37,17 @@ export default function Page() {
</div>

<ScrollArea className="max-h-[calc(100vh-7rem)]">
<div className="grid gap-2 pr-4">
<div className="grid gap-2">
{contracts.map((contract) => (
<ContractItem
key={contract.key}
contract={contract}
onRemove={onRemove}
onEdit={() => setEditContractKey(contract.key)}
/>
))}
</div>
</ScrollArea>
<Button onClick={() => setIsModalOpen(true)}>
<Button onClick={() => setIsUploadModalOpen(true)}>
Upload Contract
</Button>
</div>
Expand All @@ -69,9 +71,14 @@ export default function Page() {
</div>
</div>

<EditContractModal
contractKey={editContractKey}
onClose={() => setEditContractKey(null)}
/>

<UploadContractModal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
isOpen={isUploadModalOpen}
onClose={() => setIsUploadModalOpen(false)}
/>
</>
) : (
Expand Down
15 changes: 12 additions & 3 deletions components/ChatWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
import { ChatMessageBubble } from "@/components/ChatMessageBubble";
import { LoadingIcon } from "@/components/LoadingIcon";
import { Label } from "./ui/label";
import { CornerDownLeft } from "lucide-react";
import { ClearMessageAlert } from "./ClearMessageAlert";
import { CornerDownLeft, Trash2 } from "lucide-react";
import { ConfirmAlert } from "./ConfirmAlert";

export function ChatWindow(props: { titleText?: string }) {
const { titleText } = props;
Expand Down Expand Up @@ -112,7 +112,16 @@ export function ChatWindow(props: { titleText?: string }) {
onChange={handleInputChange}
/>
<div className="flex items-center p-2 pt-0">
<ClearMessageAlert onConfirm={onClearMessages} />
<ConfirmAlert
onConfirm={onClearMessages}
description="This will clear out your chat history"
button={
<Button variant="ghost" size="icon" title="Clear messages">
<Trash2 strokeWidth={1.5} size={20} />
<span className="sr-only">Clear messages</span>
</Button>
}
/>
<Button
type="submit"
size="sm"
Expand Down
25 changes: 13 additions & 12 deletions components/ClearMessageAlert.tsx → components/ConfirmAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,25 @@ import {
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { Trash2 } from "lucide-react";

export function ClearMessageAlert({ onConfirm }: { onConfirm: () => void }) {
import { ReactNode } from "react";

export function ConfirmAlert({
button,
description,
onConfirm,
}: {
button: ReactNode;
description: string;
onConfirm: () => void;
}) {
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="ghost" size="icon" title="Clear messages">
<Trash2 strokeWidth={1.5} size={20} />
<span className="sr-only">Clear messages</span>
</Button>
</AlertDialogTrigger>
<AlertDialogTrigger asChild>{button}</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
<AlertDialogDescription>
This will clear out your chat history
</AlertDialogDescription>
<AlertDialogDescription>{description}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
Expand Down
Loading

0 comments on commit 7bb2739

Please sign in to comment.