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:
2026-06-20 18:06:06 +09:00
parent 4e837d1419
commit 234ebba103
23 changed files with 946 additions and 39 deletions
+16 -2
View File
@@ -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)