feat: enhance UI and functionality across chat and settings

- Added custom scrollbar styles for improved aesthetics and usability across the interface.
- Implemented responsive adjustments for chat sidebar and input components to enhance mobile experience.
- Integrated tooltip components in select elements for better user guidance and information display.
- Updated chat input and message components for improved styling and functionality.
- Enhanced settings page with semantic query expansion options and improved model selection UI.
- Refactored sidebar list to include better date formatting and tooltip support for session titles.
- Introduced GPU stats monitoring in the system panel for better hardware insights.
This commit is contained in:
Evandro Fonseca Junior committed 2025-11-26 19:04:46 -03:00
1 parent 84ea2dec19
commit e5f062040c
33 files changed
+4670 -465

No files matched your search

+53
View File
@@ -4,6 +4,8 @@ import type { ScrapedContent } from '@/services/webSearch';
import { deepResearchLog as log } from '@/lib/terminal-logger';
import { condenseKnowledgeBase, validateCondensedContext } from '@/lib/knowledge-base-processor';
import type { CondensationResult } from '@/lib/knowledge-base-processor';
import { analyzeQueryContext, type QueryContext } from '@/lib/contextual-analyzer';
import { enrichQueries, type EnrichedQueries } from '@/lib/query-enricher';
export type DeepResearchStep = 'idle' | 'planning' | 'searching' | 'aggregating' | 'validating' | 'formulating' | 'complete' | 'error';
@@ -32,6 +34,8 @@ export interface DeepResearchState {
validationReport: string;
error?: string;
logs: DeepResearchLog[];
context?: QueryContext;
enrichedQueries?: EnrichedQueries;
}
// ========== LOGGING UTILITIES ==========
@@ -177,6 +181,49 @@ export function useDeepResearch() {
}
};
// --- CONTEXTUAL ANALYSIS ---
const analyzeContext = useCallback(async (query: string, model: string): Promise<QueryContext | null> => {
logStep('--- Contextual Analysis ---');
try {
const context = await analyzeQueryContext(query, model);
logData('Context Analysis', {
intent: context.intent,
entities: context.entities.length,
topics: context.topics.length,
keywords: context.keywords.length,
});
setState(s => ({ ...s, context }));
return context;
} catch (error) {
log.warn('Contextual analysis failed, continuing without context:', error);
return null;
}
}, []);
// --- QUERY ENRICHMENT ---
const enrich = useCallback(async (query: string, context: QueryContext | null, model: string): Promise<EnrichedQueries | null> => {
if (!context) {
return null;
}
logStep('--- Query Enrichment ---');
try {
const enriched = await enrichQueries(query, context, model);
logData('Enriched Queries', {
literal: enriched.literal.length,
semantic: enriched.semantic.length,
related: enriched.related.length,
expanded: enriched.expanded.length,
contextual: enriched.contextual.length,
});
setState(s => ({ ...s, enrichedQueries: enriched }));
return enriched;
} catch (error) {
log.warn('Query enrichment failed, continuing without enrichment:', error);
return null;
}
}, []);
// --- DECOMPOSITION ---
const decompose = useCallback(async (query: string, model: string) => {
logSection('DECOMPOSITION');
@@ -186,6 +233,12 @@ export function useDeepResearch() {
setState(s => ({ ...s, step: 'planning', error: undefined, logs: [], knowledgeBase: [] }));
try {
// Análise contextual (opcional, não bloqueia se falhar)
const context = await analyzeContext(query, model);
// Enriquecimento de queries (opcional, não bloqueia se falhar)
const enriched = context ? await enrich(query, context, model) : null;
const prompt = DEEP_RESEARCH_PROMPTS.DECOMPOSITION.replace('{{userQuery}}', query);
logStep('Sending decomposition prompt to LLM...');
const response = await callLLM(model, prompt, true);
+2
View File
@@ -54,3 +54,5 @@ export function useOperatingSystem() {
+14 -2
View File
@@ -147,7 +147,13 @@ export function useWebSearch() {
// Etapa 1: metadados
setState(prev => ({ ...prev, status: 'searching' }));
const { metadata, contents } = await webSearchService.smartSearchRag(query, limit, searchConfig);
const timeoutMs = settings.webSearch.timeout || 15000;
const { metadata, contents } = await webSearchService.smartSearchRag(
query,
limit,
searchConfig,
timeoutMs
);
// Etapa 2: scraping
setState(prev => ({ ...prev, status: 'scraping' }));
@@ -162,16 +168,22 @@ export function useWebSearch() {
error: null,
}));
// Retornar resultados mesmo se parciais (não quebrar o fluxo)
return contents;
} catch (error) {
// Se houver erro, logar mas retornar array vazio (não quebrar o fluxo)
const errorMessage = error instanceof Error ? error.message : 'Erro desconhecido no smartSearchRag';
console.warn('Erro em smartSearchRag (retornando vazio):', errorMessage);
setState(prev => ({
...prev,
status: 'error',
error: errorMessage,
scrapedSources: [],
}));
throw error;
// Retornar vazio em vez de throw para não quebrar o fluxo
return [];
}
}, []);