Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
6aceb73
Merge pull request #52 from chainable-dev/feature/state
khaosans Nov 23, 2024
08ac2c4
feat: Add web search feature using DuckDuckGo in chatbot interface
khaosans Nov 23, 2024
efa436a
fix: Resolve syntax error in handleSuggestedAction function definition
khaosans Nov 23, 2024
cf350d0
fix: Roll back handleSuggestedAction to previous implementation state
khaosans Nov 23, 2024
b5a885f
fix: Roll back to previous state of handleSuggestedAction function
khaosans Nov 23, 2024
f38bd77
fix: Correct import of GlobeIcon in multimodal-input component
khaosans Nov 23, 2024
16499ed
refactor: Simplify quote handling and improve component structure in …
khaosans Nov 23, 2024
7cb3355
style: Enhance image appearance with shadows and adjusted opacity
khaosans Nov 23, 2024
e3a2443
feat: Enable DuckDuckGo search feature in chatbot toolset
khaosans Nov 23, 2024
05d2f43
refactor: Simplify multimodal input component and improve file handli…
khaosans Nov 23, 2024
1527952
chore: Remove references to pages and update to app router structure
khaosans Nov 23, 2024
3234c6c
test: Add unit test for web search button functionality in Multimodal…
khaosans Nov 23, 2024
b1e385d
fix: Update build script to include optimize-images before next build
khaosans Nov 23, 2024
0d1fda7
chore: Update tsconfig to ignore all test files and directories
khaosans Nov 23, 2024
3688689
feat: Add clean script to package.json for pnpmm clean command
khaosans Nov 23, 2024
f497623
fix: Update clean script to use rimraf for clearing dist and .next
khaosans Nov 23, 2024
dbbf62f
fix: Ensure build process and clean script are correctly configured
khaosans Nov 23, 2024
fd9388f
fix: Update import path for generateTitleFromUserMessage in route.ts
khaosans Nov 23, 2024
0718a57
fix: Update tsconfig path for actions module resolution
khaosans Nov 23, 2024
db45949
fix: Resolve module path issues and update configurations
khaosans Nov 23, 2024
2bf2ba0
fix: Resolve syntax errors in chat.tsx to enable successful compilation
khaosans Nov 23, 2024
789ad76
fix: Correct JSX syntax in chat.tsx to resolve build error
khaosans Nov 23, 2024
85c288f
feat: Refactor chat component to improve file upload handling and types
khaosans Nov 23, 2024
1a7f17f
fix: Resolve syntax issues in chat.tsx file
khaosans Nov 23, 2024
1dba05d
feat: Update chat component to handle message types and improve appen…
khaosans Nov 23, 2024
cb872ef
refactor: Simplify Chat component by updating types and removing unus…
khaosans Nov 23, 2024
4ac824a
fix bugs
khaosans Nov 23, 2024
f78ee28
feat: Add web search feature toggle to Chat component
khaosans Nov 23, 2024
f679117
fix: Import WalletIcon in chat.tsx to resolve build issue
khaosans Nov 23, 2024
cbaabfb
feat: Enhance multimodal input with wallet balance check and web sear…
khaosans Nov 23, 2024
55a3aaf
fix: Correct import path for WalletIcon component in multimodal-input…
khaosans Nov 23, 2024
4cf6db2
feat: Enhance multimodal input with web search and improved UI elements
khaosans Nov 23, 2024
a4a4ba2
fix: Update Wallet icon import and usage to WalletIcon in component
khaosans Nov 23, 2024
9b31049
feat: Add MultimodalInputProps and AppendOptions interfaces
khaosans Nov 23, 2024
6202324
feat: Add hover animations and info tooltips to multimodal input comp…
khaosans Nov 23, 2024
601c47b
test: Add tests for MultimodalInput component functionality
khaosans Nov 23, 2024
720c010
test: Add tests for web search toggle and file upload functionality
khaosans Nov 23, 2024
00991c1
test: Add tests for web search toggle, file upload, and placeholders
khaosans Nov 23, 2024
6391be1
refactor: Update imports and remove unused code in overview.tsx, hove…
khaosans Nov 23, 2024
5a2a13e
Fix import paths and order issues
khaosans Nov 23, 2024
d9fd6e2
Refactor icon imports and update custom icons
khaosans Nov 23, 2024
daa4fe6
Merge pull request #53 from chainable-dev/feature/state
khaosans Nov 23, 2024
dbaa1d0
Refactor icon imports and update custom icons
khaosans Nov 23, 2024
54ca89e
Refactor icon imports and update custom icons
khaosans Nov 23, 2024
1fcb4d8
feat: Replace custom icons with react-icons and improve accessibility
khaosans Nov 23, 2024
ed34738
fix: Remove TooltipContent imports from components using updated tool…
khaosans Nov 23, 2024
6bf474e
fix: Replace TooltipContent with BetterTooltip in multiple components
khaosans Nov 23, 2024
53d9094
fix: Correct TypeScript errors in chat API and sidebar components
khaosans Nov 23, 2024
41d56d3
fix: Resolve TypeScript errors in chat API and sidebar components
khaosans Nov 23, 2024
9d46906
fix: Resolve TypeScript errors in chat history and sidebar components
khaosans Nov 23, 2024
3bc9aa2
Refactor icon imports and update custom icons
khaosans Nov 23, 2024
1167b3e
fix bugs
khaosans Nov 23, 2024
820d481
Merge pull request #54 from chainable-dev/feature/websearch
khaosans Nov 23, 2024
60413c9
feat: Integrate Clerk's SignIn and SignUp components for authentication
khaosans Nov 24, 2024
ce801b5
refactor: Remove TooltipProvider from SidebarProvider component
khaosans Nov 24, 2024
746fca7
fix: Ensure TooltipContent is used within Tooltip to resolve error
khaosans Nov 24, 2024
a923f62
style: Update chat interface styling for consistency and improved aes…
khaosans Nov 24, 2024
a4e9339
add thining
khaosans Nov 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 6 additions & 95 deletions app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,100 +1,11 @@
"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { toast } from "sonner";
import { Loader2 } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { signIn } from "@/db/auth";
import { SignIn } from "@clerk/nextjs";

export default function LoginPage() {
const [isLoading, setIsLoading] = useState(false);
const [isTransitioning, setIsTransitioning] = useState(false);
const router = useRouter();

async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
setIsLoading(true);

try {
const formData = new FormData(event.currentTarget);
const email = formData.get("email") as string;
const password = formData.get("password") as string;

await signIn(email, password);
setIsTransitioning(true);
router.push("/");
router.refresh();
} catch (error: any) {
toast.error(error.message);
setIsLoading(false);
}
}

if (isTransitioning) {
return (
<div className="fixed inset-0 flex items-center justify-center bg-background">
<div className="space-y-4 text-center">
<Loader2 className="h-8 w-8 animate-spin" />
<p className="text-sm text-muted-foreground">Redirecting...</p>
</div>
</div>
);
}

return (
<div className="flex h-[calc(100vh-theme(spacing.16))] items-center justify-center py-10">
<div className="w-full max-w-sm space-y-6">
<div className="space-y-2 text-center">
<h1 className="text-3xl font-bold">Login</h1>
<p className="text-gray-500 dark:text-gray-400">
Enter your email below to login to your account
</p>
</div>
<form className="space-y-4" onSubmit={handleSubmit}>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
name="email"
placeholder="m@example.com"
required
type="email"
disabled={isLoading}
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<Input
id="password"
name="password"
required
type="password"
disabled={isLoading}
/>
</div>
<Button className="w-full" disabled={isLoading}>
{isLoading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Signing in...
</>
) : (
"Sign in"
)}
</Button>
</form>
<div className="text-center text-sm">
Don&apos;t have an account?{" "}
<Link className="underline" href="/register">
Register
</Link>
</div>
</div>
</div>
);
return (
<div className="flex h-screen items-center justify-center">
<SignIn />
</div>
);
}
74 changes: 6 additions & 68 deletions app/(auth)/register/page.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,11 @@
"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { signUp } from "@/db/auth";
import { SignUp } from "@clerk/nextjs";

export default function RegisterPage() {
const [isLoading, setIsLoading] = useState(false);
const router = useRouter();

async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
setIsLoading(true);

try {
const formData = new FormData(event.currentTarget);
const email = formData.get("email") as string;
const password = formData.get("password") as string;

await signUp(email, password);
toast.success("Check your email to confirm your account");
router.push("/login");
} catch (error: any) {
toast.error(error.message);
} finally {
setIsLoading(false);
}
}

return (
<div className="flex h-[calc(100vh-theme(spacing.16))] items-center justify-center py-10">
<div className="w-full max-w-sm space-y-6">
<div className="space-y-2 text-center">
<h1 className="text-3xl font-bold">Register</h1>
<p className="text-gray-500 dark:text-gray-400">
Enter your information to create an account
</p>
</div>
<form className="space-y-4" onSubmit={handleSubmit}>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
name="email"
placeholder="m@example.com"
required
type="email"
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<Input id="password" name="password" required type="password" />
</div>
<Button className="w-full" disabled={isLoading}>
{isLoading ? "Loading..." : "Register"}
</Button>
</form>
<div className="text-center text-sm">
Already have an account?{" "}
<Link className="underline" href="/login">
Login
</Link>
</div>
</div>
</div>
);
return (
<div className="flex h-screen items-center justify-center">
<SignUp />
</div>
);
}
93 changes: 44 additions & 49 deletions app/(chat)/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { kv } from "@vercel/kv";
import { useAccount, useBalance, useChainId } from "wagmi";

import { generateTitleFromUserMessage } from "../../actions";

export const maxDuration = 60;

interface WeatherParams {
Expand Down Expand Up @@ -87,7 +86,7 @@ const allTools: AllowedTools[] = [
...weatherTools,
"getWalletBalance" as AllowedTools,
"checkWalletState" as AllowedTools,
...(FEATURES.WEB_SEARCH ? ["webSearch" as AllowedTools] : []),
"webSearch" as AllowedTools,
];

async function getUser() {
Expand Down Expand Up @@ -545,54 +544,49 @@ const tools = {
}
},
},
...(FEATURES.WEB_SEARCH
? {
webSearch: {
description: "Search the web using DuckDuckGo",
parameters: z.object({
query: z.string().describe("The search query"),
searchType: z
.enum(["duckduckgo", "opensearch"])
.describe("The search engine to use"),
}),
execute: async ({
webSearch: {
description: "Search the web using DuckDuckGo",
parameters: z.object({
query: z.string().describe("The search query"),
searchType: z
.enum(["duckduckgo", "opensearch"])
.describe("The search engine to use"),
}),
execute: async ({
query,
searchType,
}: {
query: string;
searchType: "duckduckgo" | "opensearch";
}) => {
try {
let results;
if (searchType === "duckduckgo") {
results = await searchDuckDuckGo(query);
} else {
results = await searchOpenSearch(query);
}

return {
type: "tool-result",
result: {
searchEngine: searchType,
query,
searchType,
}: {
query: string;
searchType: "duckduckgo" | "opensearch";
}) => {
try {
let results;
if (searchType === "duckduckgo") {
results = await searchDuckDuckGo(query);
} else {
results = await searchOpenSearch(query);
}

return {
type: "tool-result",
result: {
searchEngine: searchType,
query,
results,
timestamp: new Date().toISOString(),
},
};
} catch (error) {
return {
type: "tool-result",
result: {
error: "Search failed",
details:
error instanceof Error ? error.message : "Unknown error",
},
};
}
results,
timestamp: new Date().toISOString(),
},
},
};
} catch (error) {
return {
type: "tool-result",
result: {
error: "Search failed",
details: error instanceof Error ? error.message : "Unknown error",
},
};
}
: {}),
},
},
};

export async function POST(request: Request) {
Expand Down Expand Up @@ -749,11 +743,12 @@ export async function POST(request: Request) {
}),
},
},
onFinish: async ({ responseMessages }) => {
onFinish: async (event) => {
const { responseMessages } = event;
if (user && user.id) {
try {
const responseMessagesWithoutIncompleteToolCalls =
sanitizeResponseMessages(responseMessages);
sanitizeResponseMessages(responseMessages as (CoreAssistantMessage | CoreToolMessage)[]);

await saveMessages({
chatId: id,
Expand Down
Loading