Add web search knowledge base, message tagging, and word-memory tip topics
Introduces websearch.py (Tavily) + knowledge.py to ground chat responses in search results, tagging.py to tag user and assistant messages via LLM and pick related topics for the Discord useless-tips job, and word_memory.py to track recent conversation nouns (surfaced in the new WordPool.vue sidebar) used to pick tip topics close to a related tag.
This commit is contained in:
@@ -16,9 +16,14 @@ export interface SessionInfo {
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface Source {
|
||||
title: string
|
||||
url: string
|
||||
}
|
||||
|
||||
export interface SSEChunk {
|
||||
type: 'session_id' | 'chunk' | 'done' | 'error'
|
||||
value?: string
|
||||
type: 'session_id' | 'chunk' | 'done' | 'error' | 'sources'
|
||||
value?: string | Source[]
|
||||
}
|
||||
|
||||
const BASE = ''
|
||||
@@ -45,6 +50,7 @@ export interface MessageRecord {
|
||||
role: 'user' | 'assistant' | 'system'
|
||||
content: string
|
||||
created_at: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
export async function fetchMessages(sessionId: string): Promise<MessageRecord[]> {
|
||||
@@ -95,6 +101,7 @@ export function streamChat(
|
||||
const reader = res.body.getReader()
|
||||
const decoder = new TextDecoder()
|
||||
let buffer = ''
|
||||
let finished = false
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read()
|
||||
@@ -106,6 +113,7 @@ export function streamChat(
|
||||
if (line.startsWith('data: ')) {
|
||||
try {
|
||||
const parsed: SSEChunk = JSON.parse(line.slice(6))
|
||||
if (parsed.type === 'done' || parsed.type === 'error') finished = true
|
||||
onChunk(parsed)
|
||||
} catch (e) {
|
||||
console.error('[SSE] JSON parse error:', e, '| raw:', line)
|
||||
@@ -113,6 +121,12 @@ export function streamChat(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// サーバーが done/error を送らずに接続を終了した場合(再起動・切断など)はストリーミング状態が
|
||||
// 固定されたままになるので、ここで明示的にエラーとして扱い入力をロック解除する
|
||||
if (!finished) {
|
||||
onError(new Error('接続が予期せず終了しました。もう一度お試しください。'))
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.name !== 'AbortError') onError(err)
|
||||
|
||||
Reference in New Issue
Block a user