mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-19 16:27:37 +00:00
feat: improve AI chat utilities and types
- Enhance useChat hook - Improve AI chat utilities - Update AI types
This commit is contained in:
parent
1657beeb92
commit
da9c322ddd
3 changed files with 33 additions and 7 deletions
|
|
@ -86,6 +86,16 @@ export function useChat(options: UseChatOptions = {}) {
|
|||
};
|
||||
|
||||
// Process stream events
|
||||
const extractText = (value: unknown): string => {
|
||||
if (typeof value === 'string') return value;
|
||||
if (value && typeof value === 'object') {
|
||||
const record = value as Record<string, unknown>;
|
||||
if (typeof record.text === 'string') return record.text;
|
||||
if (typeof record.content === 'string') return record.content;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const processEvent = (
|
||||
assistantId: string,
|
||||
event: StreamEvent
|
||||
|
|
@ -97,7 +107,7 @@ export function useChat(options: UseChatOptions = {}) {
|
|||
try {
|
||||
switch (event.type) {
|
||||
case 'content': {
|
||||
const content = event.data as string;
|
||||
const content = extractText(event.data);
|
||||
if (!content) return msg;
|
||||
const existing = msg.content || '';
|
||||
// Add to streamEvents for chronological display
|
||||
|
|
@ -109,7 +119,7 @@ export function useChat(options: UseChatOptions = {}) {
|
|||
}
|
||||
|
||||
case 'thinking': {
|
||||
const thinking = event.data as string;
|
||||
const thinking = extractText(event.data);
|
||||
if (!thinking) return msg;
|
||||
// Add thinking to streamEvents
|
||||
const updated = addStreamEvent(msg, { type: 'thinking', thinking });
|
||||
|
|
|
|||
|
|
@ -66,12 +66,28 @@ const configureDOMPurify = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const coerceMarkdownInput = (content: unknown): string => {
|
||||
if (typeof content === 'string') return content;
|
||||
if (content && typeof content === 'object') {
|
||||
const record = content as Record<string, unknown>;
|
||||
if (typeof record.text === 'string') return record.text;
|
||||
if (typeof record.content === 'string') return record.content;
|
||||
try {
|
||||
return JSON.stringify(content);
|
||||
} catch {
|
||||
return String(content);
|
||||
}
|
||||
}
|
||||
return content == null ? '' : String(content);
|
||||
};
|
||||
|
||||
// Helper to render markdown safely with XSS protection
|
||||
// LLM output should NEVER be trusted - always sanitize before rendering as HTML
|
||||
export const renderMarkdown = (content: string): string => {
|
||||
export const renderMarkdown = (content: unknown): string => {
|
||||
const normalized = coerceMarkdownInput(content);
|
||||
try {
|
||||
configureDOMPurify();
|
||||
const rawHtml = marked.parse(content) as string;
|
||||
const rawHtml = marked.parse(normalized) as string;
|
||||
// Sanitize to prevent XSS from malicious LLM output or injected content
|
||||
return DOMPurify.sanitize(rawHtml, {
|
||||
// Allow common formatting tags but block scripts, iframes, etc.
|
||||
|
|
@ -84,7 +100,7 @@ export const renderMarkdown = (content: string): string => {
|
|||
});
|
||||
} catch {
|
||||
// If parsing fails, escape HTML entities as fallback
|
||||
return content.replace(/[&<>"']/g, (char) => {
|
||||
return normalized.replace(/[&<>"']/g, (char) => {
|
||||
const entities: Record<string, string> = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
|
||||
return entities[char];
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export interface AISettings {
|
|||
request_timeout_seconds?: number;
|
||||
|
||||
// Infrastructure control settings
|
||||
control_level?: 'read_only' | 'suggest' | 'controlled' | 'autonomous';
|
||||
control_level?: 'read_only' | 'controlled' | 'autonomous';
|
||||
protected_guests?: string[];
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ export interface AISettingsUpdateRequest {
|
|||
request_timeout_seconds?: number;
|
||||
|
||||
// Infrastructure control settings
|
||||
control_level?: 'read_only' | 'suggest' | 'controlled' | 'autonomous';
|
||||
control_level?: 'read_only' | 'controlled' | 'autonomous';
|
||||
protected_guests?: string[];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue