add share_time toggle — user-controlled time context, opt-out in settings
This commit is contained in:
@@ -8,7 +8,7 @@ import type { Message } from '@/lib/api';
|
|||||||
const MAX_RECORDING_SECONDS = 60;
|
const MAX_RECORDING_SECONDS = 60;
|
||||||
|
|
||||||
export default function MessageInput() {
|
export default function MessageInput() {
|
||||||
const { currentId, setCurrentId, addMessage, setIsLoading, isLoading, setConversations } = useStore();
|
const { currentId, setCurrentId, addMessage, setIsLoading, isLoading, setConversations, settings } = useStore();
|
||||||
const [text, setText] = useState('');
|
const [text, setText] = useState('');
|
||||||
const [recording, setRecording] = useState(false);
|
const [recording, setRecording] = useState(false);
|
||||||
const [transcribing, setTranscribing] = useState(false);
|
const [transcribing, setTranscribing] = useState(false);
|
||||||
@@ -55,7 +55,7 @@ export default function MessageInput() {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await api.sendMessage(message, convId);
|
const data = await api.sendMessage(message, convId, settings.share_time ?? true);
|
||||||
setCurrentId(data.conversation_id);
|
setCurrentId(data.conversation_id);
|
||||||
addMessage({
|
addMessage({
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
|
|||||||
@@ -166,6 +166,9 @@ export default function SettingsPanel() {
|
|||||||
<Row label="Show sources" desc="Display document sources under responses">
|
<Row label="Show sources" desc="Display document sources under responses">
|
||||||
<Toggle on={settings.show_sources} onChange={v => updateSetting('show_sources', v)} />
|
<Toggle on={settings.show_sources} onChange={v => updateSetting('show_sources', v)} />
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row label="Share time" desc="Send current time with each message so the assistant can reason about recency">
|
||||||
|
<Toggle on={settings.share_time ?? true} onChange={v => updateSetting('share_time', v)} />
|
||||||
|
</Row>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
{/* Memory */}
|
{/* Memory */}
|
||||||
@@ -323,6 +326,9 @@ export default function SettingsPanel() {
|
|||||||
<Section title="System">
|
<Section title="System">
|
||||||
<StatusRow label="Aaron AI service" value={status?.aaron_ai || 'unknown'} ok={status?.aaron_ai === 'running'} />
|
<StatusRow label="Aaron AI service" value={status?.aaron_ai || 'unknown'} ok={status?.aaron_ai === 'running'} />
|
||||||
<StatusRow label="File watcher" value={status?.watcher || 'unknown'} ok={status?.watcher === 'running'} />
|
<StatusRow label="File watcher" value={status?.watcher || 'unknown'} ok={status?.watcher === 'running'} />
|
||||||
|
{status?.watcher_ingestion && (
|
||||||
|
<IngestionRow ingestion={status.watcher_ingestion} />
|
||||||
|
)}
|
||||||
<StatusRow label="Nextcloud files" value={`${(status?.file_count || 0).toLocaleString()} files`} ok={true} />
|
<StatusRow label="Nextcloud files" value={`${(status?.file_count || 0).toLocaleString()} files`} ok={true} />
|
||||||
<StatusRow label="Model" value={status?.model || 'unknown'} ok={true} yellow />
|
<StatusRow label="Model" value={status?.model || 'unknown'} ok={true} yellow />
|
||||||
</Section>
|
</Section>
|
||||||
@@ -441,3 +447,16 @@ function StatusRow({ label, value, ok, yellow }: { label: string; value: string;
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function IngestionRow({ ingestion }: { ingestion: { status: string; message: string; file_count: number } }) {
|
||||||
|
const color = ingestion.status === 'ingesting' ? '#c8821a' : ingestion.status === 'error' ? '#a32d2d' : '#888780';
|
||||||
|
const label = ingestion.status === 'ingesting'
|
||||||
|
? `Ingesting ${ingestion.file_count} file(s)...`
|
||||||
|
: ingestion.message || 'Idle';
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-2 py-1 pl-4" style={{ borderBottom: '1px solid var(--border)' }}>
|
||||||
|
<span className="rounded-full flex-shrink-0" style={{ width: '6px', height: '6px', background: color }} />
|
||||||
|
<span className="text-xs flex-1" style={{ color: 'var(--text3)' }}>{label}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
+11
-2
@@ -25,8 +25,15 @@ export const api = {
|
|||||||
request<{ deleted: string }>(`/conversations/${id}`, { method: 'DELETE' }),
|
request<{ deleted: string }>(`/conversations/${id}`, { method: 'DELETE' }),
|
||||||
clearAllConversations: () =>
|
clearAllConversations: () =>
|
||||||
request<{ cleared: boolean }>('/conversations', { method: 'DELETE' }),
|
request<{ cleared: boolean }>('/conversations', { method: 'DELETE' }),
|
||||||
sendMessage: (message: string, conversation_id: string) =>
|
sendMessage: (message: string, conversation_id: string, share_time = true) =>
|
||||||
request<ChatResponse>('/chat', { method: 'POST', body: JSON.stringify({ message, conversation_id }) }),
|
request<ChatResponse>('/chat', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
message,
|
||||||
|
conversation_id,
|
||||||
|
...(share_time ? { client_time: new Date().toISOString() } : {}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
getMemory: () => request<{ content: string }>('/memory'),
|
getMemory: () => request<{ content: string }>('/memory'),
|
||||||
updateMemory: (content: string) =>
|
updateMemory: (content: string) =>
|
||||||
request<{ saved: boolean }>('/memory', { method: 'POST', body: JSON.stringify({ content }) }),
|
request<{ saved: boolean }>('/memory', { method: 'POST', body: JSON.stringify({ content }) }),
|
||||||
@@ -73,6 +80,7 @@ export interface Settings {
|
|||||||
font_size: 'small' | 'medium' | 'large';
|
font_size: 'small' | 'medium' | 'large';
|
||||||
web_search: boolean;
|
web_search: boolean;
|
||||||
show_sources: boolean;
|
show_sources: boolean;
|
||||||
|
share_time: boolean;
|
||||||
dream_hour_utc: number;
|
dream_hour_utc: number;
|
||||||
dream_minute_utc: number;
|
dream_minute_utc: number;
|
||||||
dream_mode: string;
|
dream_mode: string;
|
||||||
@@ -106,6 +114,7 @@ export interface DreamerStatus {
|
|||||||
export interface Status {
|
export interface Status {
|
||||||
aaron_ai: string;
|
aaron_ai: string;
|
||||||
watcher: string;
|
watcher: string;
|
||||||
|
watcher_ingestion?: { status: string; message: string; file_count: number };
|
||||||
chunk_count: number;
|
chunk_count: number;
|
||||||
file_count: number;
|
file_count: number;
|
||||||
last_indexed: string;
|
last_indexed: string;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export const useStore = create<AppState>()(
|
|||||||
font_size: 'medium',
|
font_size: 'medium',
|
||||||
web_search: true,
|
web_search: true,
|
||||||
show_sources: true,
|
show_sources: true,
|
||||||
|
share_time: true,
|
||||||
dream_hour_utc: 8,
|
dream_hour_utc: 8,
|
||||||
dream_minute_utc: 0,
|
dream_minute_utc: 0,
|
||||||
dream_mode: 'nrem',
|
dream_mode: 'nrem',
|
||||||
|
|||||||
Reference in New Issue
Block a user