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:
@@ -1,12 +1,14 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { fetchSessions, fetchMessages, deleteSession, streamChat, type SessionInfo } from '../api/client'
|
||||
import { fetchSessions, fetchMessages, deleteSession, streamChat, type SessionInfo, type Source } from '../api/client'
|
||||
|
||||
export interface Message {
|
||||
role: 'user' | 'assistant'
|
||||
content: string
|
||||
pending?: boolean
|
||||
error?: boolean
|
||||
tags?: string[]
|
||||
sources?: Source[]
|
||||
}
|
||||
|
||||
export interface Toast {
|
||||
@@ -21,7 +23,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
const currentSessionId = ref<string | null>(null)
|
||||
const messages = ref<Message[]>([])
|
||||
const isStreaming = ref(false)
|
||||
const selectedModel = ref('gpt-5.4')
|
||||
const selectedModel = ref('bedrock/jp.anthropic.claude-sonnet-4-6')
|
||||
const toasts = ref<Toast[]>([])
|
||||
|
||||
const currentSession = computed(() =>
|
||||
@@ -52,7 +54,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
const records = await fetchMessages(sessionId)
|
||||
messages.value = records
|
||||
.filter((r) => r.role === 'user' || r.role === 'assistant')
|
||||
.map((r) => ({ role: r.role as 'user' | 'assistant', content: r.content }))
|
||||
.map((r) => ({ role: r.role as 'user' | 'assistant', content: r.content, tags: r.tags }))
|
||||
} catch (e) {
|
||||
pushToast(`メッセージ取得失敗: ${e instanceof Error ? e.message : e}`)
|
||||
}
|
||||
@@ -81,23 +83,27 @@ export const useChatStore = defineStore('chat', () => {
|
||||
selectedModel.value,
|
||||
(chunk) => {
|
||||
if (chunk.type === 'session_id' && chunk.value) {
|
||||
currentSessionId.value = chunk.value
|
||||
currentSessionId.value = chunk.value as string
|
||||
loadSessions().catch((e) => pushToast(`セッション更新失敗: ${e.message}`))
|
||||
} else if (chunk.type === 'chunk' && chunk.value) {
|
||||
messages.value[msgIdx].content += chunk.value
|
||||
messages.value[msgIdx].content += chunk.value as string
|
||||
} else if (chunk.type === 'sources' && chunk.value) {
|
||||
messages.value[msgIdx].sources = chunk.value as Source[]
|
||||
} else if (chunk.type === 'done') {
|
||||
messages.value[msgIdx].pending = false
|
||||
isStreaming.value = false
|
||||
loadSessions().catch((e) => pushToast(`セッション更新失敗: ${e.message}`))
|
||||
} else if (chunk.type === 'error') {
|
||||
messages.value[msgIdx].content = chunk.value ?? 'バックエンドでエラーが発生しました。'
|
||||
messages.value[msgIdx].content = (chunk.value as string) ?? 'バックエンドでエラーが発生しました。'
|
||||
messages.value[msgIdx].pending = false
|
||||
messages.value[msgIdx].error = true
|
||||
isStreaming.value = false
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
messages.value[msgIdx].content = err.message
|
||||
// 途中まで届いていた内容は残しつつ、エラーメッセージを付記する
|
||||
const partial = messages.value[msgIdx].content
|
||||
messages.value[msgIdx].content = partial ? `${partial}\n\n⚠️ ${err.message}` : err.message
|
||||
messages.value[msgIdx].pending = false
|
||||
messages.value[msgIdx].error = true
|
||||
isStreaming.value = false
|
||||
@@ -105,6 +111,19 @@ export const useChatStore = defineStore('chat', () => {
|
||||
)
|
||||
}
|
||||
|
||||
/** エラーになったアシスタント応答のひとつ前にあるユーザーメッセージを再送信する。 */
|
||||
function retryMessage(assistantIdx: number): void {
|
||||
if (isStreaming.value) return
|
||||
const userIdx = assistantIdx - 1
|
||||
const userMsg = messages.value[userIdx]
|
||||
if (!userMsg || userMsg.role !== 'user') return
|
||||
|
||||
const text = userMsg.content
|
||||
// 失敗したユーザーメッセージとエラー応答を取り除いてから送信し直す
|
||||
messages.value.splice(userIdx, 2)
|
||||
sendMessage(text)
|
||||
}
|
||||
|
||||
return {
|
||||
sessions,
|
||||
currentSessionId,
|
||||
@@ -119,5 +138,6 @@ export const useChatStore = defineStore('chat', () => {
|
||||
selectSession,
|
||||
removeSession,
|
||||
sendMessage,
|
||||
retryMessage,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user