diff --git a/manifest.json b/manifest.json
index 4448bd3..6c825af 100644
--- a/manifest.json
+++ b/manifest.json
@@ -6,7 +6,8 @@
"permissions": ["storage"],
"host_permissions": [
"http://app.wisdompulse.cn/*",
- "http://share.wisdompulse.cn/*"
+ "http://share.wisdompulse.cn/*",
+ "http://app-test.wisdompulse.cn/*"
],
"action": {
"default_popup": "pages/index.html",
diff --git a/scripts/auth.js b/scripts/auth.js
index 16cd7ce..ec97a56 100644
--- a/scripts/auth.js
+++ b/scripts/auth.js
@@ -19,7 +19,7 @@ async function handleLogout(auth) {
}
-async function loadToken() {
+async function loadUserToken() {
return new Promise((resolve) => {
chrome.storage.local.get(["token", "username", "loginAt"], async (res) => {
const mergedConfig = await loadMergedConfig();
@@ -34,4 +34,4 @@ async function loadToken() {
}
});
});
-}
\ No newline at end of file
+}
diff --git a/scripts/config.js b/scripts/config.js
index fee7e8f..991c1eb 100644
--- a/scripts/config.js
+++ b/scripts/config.js
@@ -53,7 +53,7 @@ const defaultConfig = {
},
llmToken: {
name: "获取 AnythingLLM Token 接口",
- url: "http://llm.wisdompulse.cn/api/request-token",
+ url: "http://app-test.wisdompulse.cn/api/v1/llm/token",
requestParams: [
{ label: "密码字段", field: "password" }
],
diff --git a/scripts/llm.js b/scripts/llm.js
index 8eebfc1..f98b55d 100644
--- a/scripts/llm.js
+++ b/scripts/llm.js
@@ -272,7 +272,6 @@ function promptLLMPasswordModal() {
}
-
async function getLLMToken(forceRefresh = false) {
const config = await loadMergedConfig();
const tokenCfg = config.apiConfig.llmToken;
@@ -303,7 +302,7 @@ async function getLLMToken(forceRefresh = false) {
});
const data = await response.json();
- const tokenField = tokenCfg.responseParams.find(p => p.label.includes("Token")).field;
+ const tokenField = tokenCfg.responseParams.find(p => p.label.includes("token")).field;
if (data[tokenField]) {
chrome.storage.local.set({ llmToken: data[tokenField], llmTokenAt: now });
log("请求llmToken成功!");
@@ -320,55 +319,16 @@ async function getLLMToken(forceRefresh = false) {
});
}
-async function getLLMWorkspaceSlug(token, forceRefresh = false) {
- const config = await loadMergedConfig();
- const wsCfg = config.apiConfig.workspaces;
- const llmWorkspaceName = config.llmWorkspaceName;
- const workspacesField = wsCfg.responseParams.find(p => p.field)?.field;
-
- return new Promise((resolve, reject) => {
- chrome.storage.local.get(["llmWorkspaceSlug", "llmWorkspaceAt"], async (res) => {
- const now = Date.now();
- const mergedConfig = await loadMergedConfig();
- const expireMs = mergedConfig.llmTokenExpireHours * 60 * 60 * 1000;
- if (!forceRefresh && res.llmWorkspaceSlug && res.llmWorkspaceAt && now - res.llmWorkspaceAt < expireMs) {
- log("获取llmWorkspaceSlug. expireMs: " + expireMs)
- resolve(res.llmWorkspaceSlug);
- } else {
- try {
- const response = await fetch(wsCfg.url, {
- method: "GET",
- headers: { Authorization: `Bearer ${token}` },
- });
-
- const data = await response.json();
- const list = data[workspacesField] || [];
-
- let target = list.find(ws => ws.name === llmWorkspaceName);
- // 若找不到,默认用第一个
- if (!target && list.length > 0) target = list[0];
-
- if (target && target.slug) {
- chrome.storage.local.set({ llmWorkspaceSlug: target.slug, llmWorkspaceAt: now });
- log("获取llmWorkspaceSlug: " + JSON.stringify(target));
- resolve(target.slug);
- } else {
- reject("未获取到LLM工作区slug");
- }
- } catch (e) {
- reject("LLM工作区接口异常");
- }
- }
- });
- });
-}
-
async function fetchLLMAnswer(question, container, contentDiv) {
if (!question || !question.trim()) return;
const config = await loadMergedConfig();
const llmToken = await getLLMToken();
- const userToken = await loadToken();
+ const auth = await loadUserToken();
+ if (!auth) {
+ return handleLogout(auth);
+ }
+ const userToken = auth.token;
const url = "http://app-test.wisdompulse.cn/api/v1/llm/ask";
const userItem = document.createElement("div");
@@ -385,11 +345,7 @@ async function fetchLLMAnswer(question, container, contentDiv) {
let collectedSources = [];
let jumpMap = {};
try {
- const body = {
- llmToken,
- question
- // 可选扩展参数可追加到 body 中,如 slug/wsName/attachments
- };
+ const body = { llmToken, question };
const res = await fetch(url, {
method: "POST",
@@ -415,78 +371,83 @@ async function fetchLLMAnswer(question, container, contentDiv) {
done = readerDone;
if (value) {
buffer += decoder.decode(value, { stream: true });
- const lines = buffer.split("\n");
- buffer = lines.pop(); // 剩下不完整的一行留给下一次
+ const lines = buffer.split("\n\n");
+ buffer = lines.pop(); // 留给下次读未完整数据
for (let line of lines) {
- if (line.startsWith("data: ")) {
- const chunkStr = line.slice(6).trim();
- if (!chunkStr) continue;
+ line = line.trim();
+ if (!line.startsWith("data:")) continue;
- let chunk;
- try {
- chunk = JSON.parse(chunkStr);
- } catch (err) {
- console.warn("非法 JSON:", chunkStr);
- continue;
- }
+ const chunkStr = line.slice(5).trim();
+ if (!chunkStr) continue;
- // 解析内容片段
- if (chunk.sources) {
- for (const s of chunk.sources) {
- if (!collectedSources.find(x => x.id === s.id)) {
- collectedSources.push(s);
- }
- }
- }
+ let chunk;
+ try {
+ chunk = JSON.parse(chunkStr);
+ } catch (err) {
+ console.warn("非法 JSON:", chunkStr);
+ continue;
+ }
- let content = chunk.textResponse || "";
- if (content.includes("
");
- } else {
- answerStr += content;
- }
+ // 收集 sources(只更新,不渲染)
+ if (chunk.sources) {
+ collectedSources = chunk.sources;
+ }
- let html = "";
- try {
- html = window.marked ? wrapHtmlWithCopyBtn(marked.parse(answerStr)) : answerStr.replace(/\n/g, "
");
- } catch (e) {
- html = answerStr.replace(/\n/g, "
");
+ // 累积内容
+ let content = chunk.textResponse || "";
+ if (content.includes("
");
+ } else {
+ answerStr += content;
+ }
+
+ // 渲染回答(markdown 支持)
+ let html = "";
+ try {
+ html = window.marked ? wrapHtmlWithCopyBtn(marked.parse(answerStr)) : answerStr.replace(/\n/g, "
");
+ } catch (e) {
+ html = answerStr.replace(/\n/g, "
");
+ }
+
+ msgBox.innerHTML =
+ (thinkStr ? `