22 <div class =" learning-assistant" >
33 <div v-if =" isOpen" class =" chat-window" >
44 <div class =" chat-header" >
5- <span >学习助手 (Learning Assistant) </span >
5+ <span >{{ i18n.title }} </span >
66 <button @click =" toggleChat" class =" close-btn" >×</button >
77 </div >
88 <div class =" chat-messages" ref =" messagesContainer" >
1717 <input
1818 v-model =" inputText"
1919 @keyup.enter =" sendMessage"
20- placeholder =" 你想了解什么工具?... "
20+ : placeholder =" i18n.placeholder "
2121 :disabled =" isLoading"
2222 />
23- <button @click =" sendMessage" :disabled =" isLoading || !inputText.trim()" >发送 </button >
23+ <button @click =" sendMessage" :disabled =" isLoading || !inputText.trim()" >{{ i18n.send }} </button >
2424 </div >
2525 </div >
2626 <div v-else class =" chat-toggle" @click =" toggleChat" >
3030</template >
3131
3232<script setup>
33- import { ref , nextTick , onMounted } from ' vue'
33+ import { ref , nextTick , onMounted , computed , watch } from ' vue'
34+ import { useData } from ' vitepress'
35+
36+ const { lang } = useData ()
37+
38+ const isEn = computed (() => lang .value === ' en' )
39+
40+ const i18n = computed (() => {
41+ return isEn .value ? {
42+ title: ' Learning Assistant' ,
43+ placeholder: ' What tool would you like to know about?...' ,
44+ send: ' Send' ,
45+ welcome: ' Hello! I am your learning assistant. What do you need? Which tool would you like to use (AstronClaw or Loomy)? I will recommend and guide you to the next step.' ,
46+ systemPrompt: ` You are a project learning assistant. Your task is to ask the user what they need or which tool they want to use (AstronClaw or Loomy) and make recommendations, always guiding the user to the next step. Please keep your answers short and friendly. Be sure to answer the user's questions based on the content in the [Knowledge Base Reference] (if it exists).\n ` ,
47+ errorFallback: ' Sorry, I encountered some issues. Please try again later.' ,
48+ errorPrefix: ' Request failed: ' ,
49+ knowledgeBaseTitle: ' \n\n [Knowledge Base Reference]\n ' ,
50+ chapter: ' Chapter: ' ,
51+ content: ' Content: '
52+ } : {
53+ title: ' 学习助手 (Learning Assistant)' ,
54+ placeholder: ' 你想了解什么工具?...' ,
55+ send: ' 发送' ,
56+ welcome: ' 你好!我是你的学习助手。请问你有什么需求?希望使用哪款工具(AstronClaw 或 Loomy)?我会为你推荐并引导你进行下一步操作。' ,
57+ systemPrompt: ` 你是一个项目学习助手,你的任务是提问用户有什么需求/希望使用哪款工具(AstronClaw 或 Loomy)并进行推荐,永远引导用户进行下一步操作。请保持回答简短友好。请务必基于【知识库参考信息】中的内容来回答用户的问题(如果存在)。\n ` ,
58+ errorFallback: ' 抱歉,我遇到了一些问题,请稍后再试。' ,
59+ errorPrefix: ' 请求失败: ' ,
60+ knowledgeBaseTitle: ' \n\n 【知识库参考信息】\n ' ,
61+ chapter: ' 章节: ' ,
62+ content: ' 内容: '
63+ }
64+ })
3465
3566const isOpen = ref (false )
3667const isLoading = ref (false )
@@ -40,10 +71,24 @@ const messagesContainer = ref(null)
4071const messages = ref ([
4172 {
4273 role: ' assistant' ,
43- content: ' 你好!我是你的学习助手。请问你有什么需求?希望使用哪款工具(AstronClaw 或 Loomy)?我会为你推荐并引导你进行下一步操作。 '
74+ content: i18n . value . welcome
4475 }
4576])
4677
78+ watch (lang, () => {
79+ // If only the welcome message is there, update it to the new language
80+ if (messages .value .length === 1 && messages .value [0 ].role === ' assistant' ) {
81+ messages .value [0 ].content = i18n .value .welcome
82+ } else {
83+ // Optionally add a welcome message in the new language if they switch during a chat
84+ messages .value .push ({
85+ role: ' assistant' ,
86+ content: i18n .value .welcome
87+ })
88+ scrollToBottom ()
89+ }
90+ })
91+
4792let docsIndex = []
4893
4994onMounted (async () => {
@@ -71,10 +116,21 @@ const scrollToBottom = async () => {
71116
72117function searchDocs (query ) {
73118 if (! docsIndex .length ) return ' '
119+ // Filter docs index based on current language
120+ // docsIndex items have URLs like "/guide/..." or "/en/guide/..."
121+ const currentLangDocs = docsIndex .filter (doc => {
122+ if (isEn .value ) {
123+ return doc .url .startsWith (' /en/' )
124+ } else {
125+ return ! doc .url .startsWith (' /en/' )
126+ }
127+ })
128+
129+ if (! currentLangDocs .length ) return ' '
74130 const keywords = query .toLowerCase ().match (/ [a-z0-9 ] + | [\u4e00 -\u9fa5 ] / g ) || []
75131 if (! keywords .length ) return ' '
76132
77- const results = docsIndex .map (doc => {
133+ const results = currentLangDocs .map (doc => {
78134 let score = 0
79135 const text = (doc .heading + ' ' + doc .content ).toLowerCase ()
80136
@@ -101,7 +157,7 @@ function searchDocs(query) {
101157
102158 if (results .length === 0 ) return ' '
103159
104- return ' \n\n 【知识库参考信息】 \n ' + results .map (r => ` 章节: ${ r .heading } \n 内容: ${ r .content } ` ).join (' \n\n ' )
160+ return i18n . value . knowledgeBaseTitle + results .map (r => ` ${ i18n . value . chapter }${ r .heading } \n ${ i18n . value . content } ${r .content } ` ).join (' \n\n ' )
105161}
106162
107163const sendMessage = async () => {
@@ -114,7 +170,7 @@ const sendMessage = async () => {
114170 scrollToBottom ()
115171
116172 const context = searchDocs (text)
117- const systemPrompt = ` 你是一个项目学习助手,你的任务是提问用户有什么需求/希望使用哪款工具(AstronClaw 或 Loomy)并进行推荐,永远引导用户进行下一步操作。请保持回答简短友好。请务必基于【知识库参考信息】中的内容来回答用户的问题(如果存在)。 \n ${ context} `
173+ const systemPrompt = ` ${ i18n . value . systemPrompt } ${ context} `
118174
119175 try {
120176 // Use the local Vercel serverless function endpoint instead of Railway
@@ -130,7 +186,7 @@ const sendMessage = async () => {
130186 role: ' system' ,
131187 content: systemPrompt
132188 },
133- ... messages .value .filter (m => m .role !== ' assistant' || (m .content !== ' 抱歉,我遇到了一些问题,请稍后再试。 ' && ! m .content .startsWith (' 请求失败: ' ))).map (m => ({ role: m .role , content: m .content }))
189+ ... messages .value .filter (m => m .role !== ' assistant' || (m .content !== i18n . value . errorFallback && ! m .content .startsWith (i18n . value . errorPrefix ))).map (m => ({ role: m .role , content: m .content }))
134190 ]
135191 })
136192 })
@@ -147,11 +203,11 @@ const sendMessage = async () => {
147203 content: data .choices [0 ].message .content
148204 })
149205 } else {
150- messages .value .push ({ role: ' assistant' , content: ' 抱歉,我遇到了一些问题,请稍后再试。 ' })
206+ messages .value .push ({ role: ' assistant' , content: i18n . value . errorFallback })
151207 }
152208 } catch (error) {
153209 console .error (' Error calling AI:' , error)
154- messages .value .push ({ role: ' assistant' , content: ` 请求失败: ${ error .message } ` })
210+ messages .value .push ({ role: ' assistant' , content: ` ${ i18n . value . errorPrefix } ${error .message } ` })
155211 } finally {
156212 isLoading .value = false
157213 scrollToBottom ()
0 commit comments