feat(deepseek): normalize model labels and unwrap redirect URLs
- Normalize provider_model so UI shows DeepSeek/DeepSeek-R1 instead of raw toggle text (联网搜索 etc.) - Unwrap DeepSeek redirect URLs (chat.deepseek.com/api/redirect?url=...) to canonical sources - Expand reasoning sections and separate reasoning search pages from answer-body citations - Improve webpages-trigger click heuristics and auxiliary link filtering in answer rendering Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,40 @@ describe("deepseek adapter helpers", () => {
|
||||
expect(classified.searchResults).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("keeps reasoning search pages as citation sources separate from answer content citations", () => {
|
||||
const classified = classifyDeepseekSources({
|
||||
inlineLinks: [
|
||||
{
|
||||
url: "https://example.com/body-citation",
|
||||
title: "Answer body citation",
|
||||
text: "[15]",
|
||||
siteName: "Body Site",
|
||||
kind: "inline",
|
||||
},
|
||||
],
|
||||
sourcePanelLinks: [],
|
||||
searchPanelLinks: [
|
||||
{
|
||||
url: "https://example.com/reasoning-search",
|
||||
title: "Reasoning searched page",
|
||||
text: "浏览页面",
|
||||
siteName: "Search Site",
|
||||
kind: "search",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(classified.inlineCitationCandidates.map((item) => item.url)).toEqual([
|
||||
"https://example.com/body-citation",
|
||||
]);
|
||||
expect(classified.citations.map((item) => item.url)).toEqual([
|
||||
"https://example.com/reasoning-search",
|
||||
]);
|
||||
expect(classified.searchResults.map((item) => item.url)).toEqual([
|
||||
"https://example.com/reasoning-search",
|
||||
]);
|
||||
});
|
||||
|
||||
it("retains all revealed DeepSeek search results instead of truncating after 32 items", () => {
|
||||
const searchPanelLinks = Array.from({ length: 78 }, (_, index) => ({
|
||||
url: `https://example.com/search-${index + 1}`,
|
||||
@@ -173,6 +207,22 @@ describe("deepseek adapter helpers", () => {
|
||||
}));
|
||||
});
|
||||
|
||||
it("unwraps DeepSeek redirect URLs before storing source items", () => {
|
||||
const item = buildSourceItem({
|
||||
url: "https://chat.deepseek.com/api/redirect?url=https%3A%2F%2Fexample.com%2Fsource%23ref",
|
||||
title: "Redirected source",
|
||||
text: null,
|
||||
siteName: null,
|
||||
kind: "search",
|
||||
});
|
||||
|
||||
expect(item).toEqual(expect.objectContaining({
|
||||
url: "https://example.com/source",
|
||||
normalized_url: "https://example.com/source",
|
||||
host: "example.com",
|
||||
}));
|
||||
});
|
||||
|
||||
it("does not use numeric citation markers as source titles", () => {
|
||||
const item = buildSourceItem({
|
||||
url: "https://example.com/report#cite-1",
|
||||
@@ -217,6 +267,45 @@ describe("deepseek adapter helpers", () => {
|
||||
expect(isDeepSeekWebpagesTriggerText("搜索到 39 个网页")).toBe(false);
|
||||
});
|
||||
|
||||
it("normalizes DeepSeek model labels without mistaking search toggles for models", () => {
|
||||
const snapshot = {
|
||||
url: "https://chat.deepseek.com/",
|
||||
title: "DeepSeek",
|
||||
loginRequired: false,
|
||||
loginReason: null,
|
||||
challengeRequired: false,
|
||||
challengeReason: null,
|
||||
busy: false,
|
||||
busySignals: [],
|
||||
composerValue: null,
|
||||
sendDisabled: false,
|
||||
answer: "Final answer",
|
||||
answerText: "Final answer",
|
||||
reasoning: null,
|
||||
signature: "sig-1",
|
||||
currentModelLabel: "深度思考 (R1)",
|
||||
providerRequestID: null,
|
||||
requestID: null,
|
||||
inlineLinks: [],
|
||||
sourcePanelLinks: [],
|
||||
searchPanelLinks: [],
|
||||
};
|
||||
const sources = {
|
||||
citations: [],
|
||||
inlineCitationCandidates: [],
|
||||
searchResults: [],
|
||||
};
|
||||
|
||||
const r1Payload = buildDeepSeekPayload(snapshot, sources, "Final answer");
|
||||
const searchPayload = buildDeepSeekPayload({
|
||||
...snapshot,
|
||||
currentModelLabel: "联网搜索",
|
||||
}, sources, "Final answer");
|
||||
|
||||
expect(r1Payload.provider_model).toBe("DeepSeek-R1");
|
||||
expect(searchPayload.provider_model).toBeNull();
|
||||
});
|
||||
|
||||
it("builds json-safe payloads with null placeholders instead of undefined", () => {
|
||||
const payload = buildDeepSeekPayload({
|
||||
url: "https://chat.deepseek.com/",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user