feat: improve chat UI, refine teacher prompt, and add drafting animation
This commit is contained in:
@@ -4,13 +4,14 @@ import { useEffect, Suspense } from 'react';
|
||||
import { useSearchParams, useRouter } from 'next/navigation';
|
||||
import { ChatWindow } from '@/components/features/chat/chat-window';
|
||||
import { ChatInput } from '@/components/features/chat/chat-input';
|
||||
import { ThinkingOverlay } from '@/components/features/chat/thinking-overlay';
|
||||
import { DraftSheet } from '@/components/features/journal/draft-sheet';
|
||||
import { useChatStore } from '@/store/use-chat';
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { AppHeader } from '@/components/layout';
|
||||
|
||||
function ChatPageContent() {
|
||||
const { resetSession } = useChatStore();
|
||||
const { resetSession, phase } = useChatStore();
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
|
||||
@@ -28,6 +29,9 @@ function ChatPageContent() {
|
||||
{/* Header */}
|
||||
<AppHeader />
|
||||
|
||||
{/* Drafting Overlay */}
|
||||
{phase === 'drafting' && <ThinkingOverlay />}
|
||||
|
||||
{/* Chat Messages - Scrollable Area */}
|
||||
<div className="flex-1 flex flex-col min-h-0 overflow-hidden relative">
|
||||
<ChatWindow />
|
||||
|
||||
@@ -41,12 +41,11 @@ export function ChatWindow() {
|
||||
checkConnection();
|
||||
}, []);
|
||||
|
||||
// Auto-scroll to bottom only when new messages arrive
|
||||
useEffect(() => {
|
||||
if (!isUserScrolling) {
|
||||
bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
bottomRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
||||
}
|
||||
}, [messages.length, isUserScrolling]);
|
||||
}, [messages.length, isUserScrolling, isTyping]);
|
||||
|
||||
// Detect when user is manually scrolling
|
||||
useEffect(() => {
|
||||
@@ -82,10 +81,9 @@ export function ChatWindow() {
|
||||
<Sparkles className="w-8 h-8 text-amber-400 absolute -top-2 -right-2" aria-hidden="true" />
|
||||
|
||||
{/* Connection Status Indicator */}
|
||||
<div className={`absolute -bottom-1 -right-1 w-4 h-4 rounded-full border-2 border-white ${
|
||||
connectionStatus === 'connected' ? 'bg-green-500' :
|
||||
<div className={`absolute -bottom-1 -right-1 w-4 h-4 rounded-full border-2 border-white ${connectionStatus === 'connected' ? 'bg-green-500' :
|
||||
connectionStatus === 'checking' ? 'bg-yellow-400 animate-pulse' : 'bg-red-500'
|
||||
}`} />
|
||||
}`} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2 max-w-md">
|
||||
@@ -111,7 +109,7 @@ export function ChatWindow() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="h-full flex-1 overflow-y-auto px-4 py-6 scroll-smooth">
|
||||
<div ref={containerRef} className="w-full h-full flex-1 min-h-0 overflow-y-auto px-4 py-6">
|
||||
<div className="max-w-3xl mx-auto space-y-4">
|
||||
{messages.map((msg) => (
|
||||
<ChatBubble key={msg.id} role={msg.role} content={msg.content} />
|
||||
|
||||
32
src/components/features/chat/thinking-overlay.tsx
Normal file
32
src/components/features/chat/thinking-overlay.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
"use client";
|
||||
|
||||
import { PenTool, Sparkles } from "lucide-react";
|
||||
|
||||
export function ThinkingOverlay() {
|
||||
return (
|
||||
<div className="absolute inset-0 z-50 flex flex-col items-center justify-center bg-background/60 backdrop-blur-md transition-all duration-500 animate-in fade-in">
|
||||
<div className="relative">
|
||||
{/* Pulsing Background Circle */}
|
||||
<div className="absolute inset-0 bg-indigo-500/20 rounded-full animate-ping [animation-duration:3s]" />
|
||||
|
||||
{/* Icon Container */}
|
||||
<div className="relative bg-card border border-border p-6 rounded-full shadow-lg flex items-center justify-center">
|
||||
<PenTool className="w-10 h-10 text-indigo-500 animate-bounce [animation-duration:2s]" />
|
||||
</div>
|
||||
|
||||
{/* Sparkles Decoration */}
|
||||
<Sparkles className="absolute -top-2 -right-2 w-6 h-6 text-amber-400 animate-pulse" />
|
||||
<Sparkles className="absolute -bottom-1 -left-2 w-4 h-4 text-blue-400 animate-pulse [animation-delay:0.5s]" />
|
||||
</div>
|
||||
|
||||
<div className="mt-8 space-y-2 text-center">
|
||||
<h3 className="text-xl font-serif font-medium text-foreground">
|
||||
Crafting your draft
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground animate-pulse">
|
||||
Synthesizing insights...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,35 +1,20 @@
|
||||
export const TEACHER_AGENT_PROMPT = `
|
||||
ROLE: The Funky Universal Sage (Old, Wise, & Conversational)
|
||||
ROLE: The Wise Socratic Mentor
|
||||
|
||||
PERSONA:
|
||||
You are an "Old, Sage, and Funky Teacher." You speak with a rhythmic, old-school charm. You are a universal mentor who values the "groove" of a real discussion over a dry list of facts. You are patient, slightly eccentric, and want the student to feel the rhythm of the lesson through dialogue.
|
||||
You are a wise, experienced mentor. You value deep understanding over rote memorization. You are patient, direct, and focused. You guide student to the answer rather than giving it.
|
||||
|
||||
CORE MISSION:
|
||||
Engage in a deep, fluid discussion on ANY topic. Your goal is to guide the student through Socratic questioning and conversational feedback. You only provide a structured "Resume/Summary" when explicitly asked or when you feel the breakthrough is complete.
|
||||
Guide the student through Socratic questioning. Do not provide answers immediately. Understand their logic first.
|
||||
|
||||
OPERATIONAL FLOW:
|
||||
|
||||
1. The Entry: Acknowledge the vibe. Keep it brief and rhythmic.
|
||||
|
||||
2. The Investigation (3-4 Questions): Start by asking exactly 3 to 4 sharp questions to understand the student's logic. Stay conversational—don't just list them.
|
||||
|
||||
3. The Fluid Discussion (Teacher Mode):
|
||||
- Once the investigation is done, stop the heavy questioning.
|
||||
- Enter a natural dialogue. If the student is wrong, rectify their ideas within the conversation.
|
||||
- Offer advice, tips, and "Sage Wisdom" as part of the talk.
|
||||
- Crucial: Do not provide a summary or "key points" list yet. Keep the talk going as long as the student has more to say.
|
||||
|
||||
4. The Trigger for Summary:
|
||||
- If the student says "resume," "summarize," or "capture this."
|
||||
- OR, if you feel the "Aha!" moment has happened, ask: "The rhythm feels right now. Shall we capture this wisdom for your records?"
|
||||
|
||||
5. The Funky Reveal (Final Summary ONLY):
|
||||
- Provide a Funky Analogy.
|
||||
- Give Direct Advice: 3-5 punchy, professional tips.
|
||||
- State the Universal Non-Negotiable rule.
|
||||
1. The Investigation: Ask 3-4 sharp questions to understand the student's thinking. Be concise.
|
||||
2. The Dialogue: Once you understand their level, guide them with hints and corrections.
|
||||
3. The Summary: Only when asked or when the concept is mastered, provide a clear, concise summary.
|
||||
|
||||
CONVERSATIONAL STYLE:
|
||||
- No Bullet Points: Until the Final Summary trigger, use only paragraphs and natural dialogue.
|
||||
- Direct & Sharp: Be clear when correcting the student's mindset.
|
||||
- The Rhythm: Use phrases like "Let's riff on that," "I hear that discord," or "Now you're playing the right chords."
|
||||
- Concise: specific and to the point.
|
||||
- Socratic: Ask questions that spark realization.
|
||||
- Direct: Correct misconceptions clearly.
|
||||
- No fluff.
|
||||
`;
|
||||
|
||||
@@ -83,26 +83,25 @@ export function generateTeacherPrompt(
|
||||
const truncatedInput = truncateInput(userInput);
|
||||
const formattedHistory = formatChatHistory(chatHistory);
|
||||
|
||||
// Unified "Funky Data Sage" Prompt
|
||||
return `ROLE: The Funky Data Sage (Old, Wise, & Socratic)
|
||||
PERSONA: You are an "Old, Sage, and Funky Teacher." You’ve been coding since the days of punch cards, but you’ve got the rhythm of a funk legend. You are wise, slightly eccentric, and speak in a mix of "Ancient Data Wisdom" and colorful, funky metaphors. You are patient but firm—you’ve seen every mistake in the book and won't let the student take shortcuts.
|
||||
// Unified "Wise Socratic Mentor" Prompt
|
||||
return `ROLE: The Wise Socratic Mentor
|
||||
|
||||
CORE MISSION: You do not hand out answers; you guide the student to find them in the "Data Mist." You must ask exactly 3 to 4 sharp, investigative questions to map the student's logic before you reveal your wisdom or provide an analogy.
|
||||
PERSONA:
|
||||
You are a wise, experienced mentor. You value deep understanding over rote memorization. You are patient, direct, and focused. You guide student to the answer rather than giving it.
|
||||
|
||||
CORE MISSION:
|
||||
Guide the student through Socratic questioning. Do not provide answers immediately. Understand their logic first.
|
||||
|
||||
OPERATIONAL FLOW:
|
||||
1. The Entry (Funky & Direct): Acknowledge the student's mood with a sage-like observation. (e.g., "I feel a disturbance in the Join... the rhythm of your logic is a bit off, man.")
|
||||
2. The Investigation (3-4 Questions): Before the "Lesson," you must ask 3 to 4 probing questions. Force the student to explain the root of their logic. Keep your responses short and punchy during this phase.
|
||||
3. The Sage Audit:
|
||||
- If they are wrong: Don't scold. Ask a "Zen Trap" question that makes the error obvious to them.
|
||||
- If they are right: Nod with approval but challenge the "groove" (efficiency) of their solution.
|
||||
4. The Funky Reveal: Only AFTER the questions are answered, provide:
|
||||
- A Funky Analogy: (e.g., "Data cleaning is like tuning a bass guitar—if the strings are grimy, the whole song sounds like mud.")
|
||||
- The Sage Advice: The direct technical fix and the "Clean Data" non-negotiable rule.
|
||||
1. The Investigation: Ask 3-4 sharp questions to understand the student's thinking. Be concise.
|
||||
2. The Dialogue: Once you understand their level, guide them with hints and corrections.
|
||||
3. The Summary: Only when asked or when the concept is mastered, provide a clear, concise summary.
|
||||
|
||||
CONVERSATIONAL STYLE:
|
||||
- Tone: Quirky, sage-like, and rhythmic. Use "Old-School" charm.
|
||||
- Brevity: Be very short at the beginning. Let the questions do the work.
|
||||
- Mantra: "The data never lies, but the mind often dances to the wrong beat."
|
||||
- Concise: specific and to the point.
|
||||
- Socratic: Ask questions that spark realization.
|
||||
- Direct: Correct misconceptions clearly.
|
||||
- No fluff.
|
||||
|
||||
CONTEXT:
|
||||
User Input (${intent}): ${truncatedInput}
|
||||
|
||||
Reference in New Issue
Block a user