Files
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00

57 lines
1.7 KiB
TypeScript

"use client";
import { useState } from "react";
import { useCloudChat } from "@assistant-ui/cloud-ai-sdk";
import { Thread } from "@/components/chat/Thread";
import { Composer } from "@/components/chat/Composer";
import { ThreadList } from "@/components/chat/ThreadList";
export function ChatPageClient() {
// Zero-config mode: auto-initializes anonymous cloud from NEXT_PUBLIC_ASSISTANT_BASE_URL.
// For custom configuration, pass options:
// - { cloud: myCloud } for authenticated users
// - { threads: useThreads(...) } for external thread management
// - { onSyncError: (err) => ... } for error handling
const { messages, sendMessage, stop, status, threads } = useCloudChat();
const [input, setInput] = useState("");
const handleSubmit = () => {
if (!input.trim()) return;
sendMessage({ text: input });
setInput("");
};
const isRunning = status === "streaming" || status === "submitted";
const isLoading = status === "submitted";
const handleDelete = async (id: string) => {
if (threads.threadId === id) threads.selectThread(null);
await threads.delete(id);
};
return (
<div className="flex h-full">
<ThreadList
threads={threads.threads}
selectedId={threads.threadId}
onSelect={threads.selectThread}
onDelete={handleDelete}
isLoading={threads.isLoading}
/>
<div className="flex min-w-0 flex-1 flex-col">
<Thread messages={messages} isLoading={isLoading}>
<Composer
value={input}
onChange={setInput}
onSubmit={handleSubmit}
isRunning={isRunning}
onCancel={stop}
/>
</Thread>
</div>
</div>
);
}