also no idea, from monorepo
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useChatWebSocket } from 'hooks/useChatWebSocket';
|
||||
import { useChatSessions } from '@/state/useChatSessions';
|
||||
import type { ChatMessage, ServerMessage, TaskInfo } from 'apps/Chat';
|
||||
|
||||
const SAVE_DEBOUNCE_MS = 1000;
|
||||
|
||||
type UsePiMonoOptions = {
|
||||
replaceUrl?: boolean;
|
||||
taskInfo?: TaskInfo;
|
||||
@@ -22,9 +19,6 @@ export const usePiMono = (initialSessionId?: string, initialModel?: string | nul
|
||||
const streamingRef = useRef('');
|
||||
const rafRef = useRef<number | null>(null);
|
||||
const sessionIdRef = useRef<string | null>(initialSessionId ?? null);
|
||||
const saveTimerRef = useRef<number | null>(null);
|
||||
|
||||
const { getMessages, saveMessages } = useChatSessions();
|
||||
|
||||
const token = localStorage.getItem('BEARER_TOKEN');
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
@@ -56,8 +50,11 @@ export const usePiMono = (initialSessionId?: string, initialModel?: string | nul
|
||||
if (replaceUrl) window.history.replaceState(null, '', `/chat/${msg.sessionId}`);
|
||||
break;
|
||||
|
||||
case 'system:prompt':
|
||||
setMessages((prev) => [...prev, { role: 'system', text: msg.text }]);
|
||||
case 'messages:sync':
|
||||
setMessages(msg.messages);
|
||||
streamingRef.current = msg.streamingText;
|
||||
setStreamingText(msg.streamingText);
|
||||
setIsGenerating(msg.isGenerating);
|
||||
break;
|
||||
|
||||
case 'assistant:partial':
|
||||
@@ -125,37 +122,6 @@ export const usePiMono = (initialSessionId?: string, initialModel?: string | nul
|
||||
}
|
||||
}, [isConnected, initialSessionId]);
|
||||
|
||||
// Load messages from server on mount when resuming a session
|
||||
useEffect(() => {
|
||||
if (!initialSessionId) return;
|
||||
getMessages('pi-mono', initialSessionId)
|
||||
.then((data) => {
|
||||
if (Array.isArray(data) && data.length > 0) setMessages(data);
|
||||
})
|
||||
.catch(() => {});
|
||||
}, [initialSessionId]);
|
||||
|
||||
// Debounced save messages to server
|
||||
useEffect(() => {
|
||||
if (!sessionIdRef.current || messages.length === 0) return;
|
||||
|
||||
if (saveTimerRef.current !== null) clearTimeout(saveTimerRef.current);
|
||||
|
||||
const sid = sessionIdRef.current;
|
||||
const snapshot = messages;
|
||||
saveTimerRef.current = window.setTimeout(() => {
|
||||
saveMessages('pi-mono', sid, snapshot).catch(() => {});
|
||||
saveTimerRef.current = null;
|
||||
}, SAVE_DEBOUNCE_MS);
|
||||
|
||||
return () => {
|
||||
if (saveTimerRef.current !== null) {
|
||||
clearTimeout(saveTimerRef.current);
|
||||
saveTimerRef.current = null;
|
||||
}
|
||||
};
|
||||
}, [messages]);
|
||||
|
||||
// Clean up RAF on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
@@ -184,7 +150,7 @@ export const usePiMono = (initialSessionId?: string, initialModel?: string | nul
|
||||
send({
|
||||
type: 'chat',
|
||||
prompt: text,
|
||||
sessionId: sessionIdRef.current,
|
||||
...(sessionIdRef.current ? { sessionId: sessionIdRef.current } : {}),
|
||||
...(selectedModel ? { model: selectedModel } : {}),
|
||||
...(cwd ? { cwd } : {}),
|
||||
...(attachmentIds?.length ? { attachmentIds } : {}),
|
||||
|
||||
@@ -1,3 +1,157 @@
|
||||
/* Chat Bubble — Markdown Prose */
|
||||
.chat-md {
|
||||
color: hsl(var(--foreground));
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.chat-md > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.chat-md > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.chat-md h1 {
|
||||
font-size: 1.4em;
|
||||
font-weight: 700;
|
||||
margin: 1.2em 0 0.4em;
|
||||
padding-bottom: 0.25em;
|
||||
border-bottom: 1px solid hsl(var(--border));
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.chat-md h2 {
|
||||
font-size: 1.2em;
|
||||
font-weight: 600;
|
||||
margin: 1.1em 0 0.35em;
|
||||
padding-bottom: 0.2em;
|
||||
border-bottom: 1px solid hsl(var(--border));
|
||||
}
|
||||
|
||||
.chat-md h3 {
|
||||
font-size: 1.1em;
|
||||
font-weight: 600;
|
||||
margin: 1em 0 0.3em;
|
||||
}
|
||||
|
||||
.chat-md h4, .chat-md h5, .chat-md h6 {
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
margin: 0.8em 0 0.25em;
|
||||
}
|
||||
|
||||
.chat-md p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.chat-md a {
|
||||
color: var(--duck-teal);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.chat-md a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.chat-md strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chat-md blockquote {
|
||||
margin: 0.75em 0;
|
||||
padding: 0.4em 0.8em;
|
||||
border-left: 3px solid var(--duck-teal);
|
||||
background: color-mix(in srgb, var(--duck-teal) 5%, transparent);
|
||||
border-radius: 0 0.375rem 0.375rem 0;
|
||||
color: hsl(var(--muted-foreground));
|
||||
}
|
||||
|
||||
.chat-md ul, .chat-md ol {
|
||||
margin: 0.5em 0;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
.chat-md li {
|
||||
margin: 0.2em 0;
|
||||
}
|
||||
|
||||
.chat-md li::marker {
|
||||
color: var(--duck-teal);
|
||||
}
|
||||
|
||||
.chat-md code {
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 0.25rem;
|
||||
background: color-mix(in srgb, var(--duck-teal) 10%, transparent);
|
||||
color: var(--duck-teal);
|
||||
font-size: 0.85em;
|
||||
font-family: ui-monospace, monospace;
|
||||
}
|
||||
|
||||
.chat-md pre {
|
||||
margin: 0.75em 0;
|
||||
padding: 0.75em 1em;
|
||||
border-radius: 0.5rem;
|
||||
background: #0d1117;
|
||||
overflow-x: auto;
|
||||
font-size: 0.8125rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.chat-md pre code {
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
background: none;
|
||||
color: #e6edf3;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.chat-md hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: hsl(var(--border));
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
|
||||
.chat-md table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 0.75em 0;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.chat-md th {
|
||||
color: hsl(var(--muted-foreground));
|
||||
background: color-mix(in srgb, var(--duck-teal) 8%, transparent);
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
padding: 0.4em 0.6em;
|
||||
border: 1px solid hsl(var(--border));
|
||||
}
|
||||
|
||||
.chat-md td {
|
||||
padding: 0.4em 0.6em;
|
||||
border: 1px solid hsl(var(--border));
|
||||
}
|
||||
|
||||
.chat-md tr:nth-child(even) {
|
||||
background: hsl(var(--muted) / 0.3);
|
||||
}
|
||||
|
||||
.chat-md img {
|
||||
max-width: 100%;
|
||||
border-radius: 0.375rem;
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
|
||||
.chat-md input[type="checkbox"] {
|
||||
accent-color: var(--duck-teal);
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
|
||||
/* File Viewer — Markdown Prose */
|
||||
.file-viewer-md {
|
||||
color: hsl(var(--foreground));
|
||||
|
||||
Reference in New Issue
Block a user