fix(monitoring): reject succeeded results missing answers or citation sources
Server callback now rejects succeeded submissions without a non-empty answer, or whose answer contains [citation:N] markers without any sources. Desktop adapters mirror this client-side: kimi returns unknown when sources arrive without a final answer, and yuanbao returns unknown when the answer has unresolved citation markers. Yuanbao also unwraps redirect URLs, harvests citations from more DOM attributes and document URL fields, drops links pointing back at yuanbao itself, and dedupes overlapping streaming fragments. Runtime controller forwards only an explicit "succeeded" status as success; anything else becomes failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { __yuanbaoTestUtils } from "./yuanbao";
|
||||
|
||||
const {
|
||||
buildSourceItem,
|
||||
extractCitationMarkerIndexes,
|
||||
mergeText,
|
||||
normalizeSourceUrl,
|
||||
resolveCitationsFromMarkers,
|
||||
} = __yuanbaoTestUtils;
|
||||
|
||||
describe("yuanbao adapter helpers", () => {
|
||||
it("unwraps redirect URLs and reads Yuanbao document URL fields", () => {
|
||||
expect(normalizeSourceUrl("https://yuanbao.tencent.com/link?target=https%3A%2F%2Fexample.com%2Fa%23ref")).toBe(
|
||||
"https://example.com/a",
|
||||
);
|
||||
|
||||
expect(buildSourceItem({
|
||||
docUrl: "https://example.com/doc?from=yuanbao#source",
|
||||
title: "引用文章",
|
||||
siteName: "Example",
|
||||
})).toMatchObject({
|
||||
url: "https://example.com/doc?from=yuanbao",
|
||||
normalized_url: "https://example.com/doc?from=yuanbao",
|
||||
title: "引用文章",
|
||||
site_name: "Example",
|
||||
host: "example.com",
|
||||
});
|
||||
});
|
||||
|
||||
it("merges streaming answer fragments without duplicating a repeated prefix", () => {
|
||||
const first = "通过三轮搜索,我已经掌握了合肥全屋定制市场的高性价比品牌。一定要合同中的定标准确和责任。";
|
||||
const repeated = "通过三轮搜索,我已经掌握了合肥全屋定制市场的高性价比品牌。结合你的预算,我建议优先看本土老牌。";
|
||||
|
||||
expect(mergeText(first, repeated)).toBe(repeated);
|
||||
});
|
||||
|
||||
it("resolves citation markers against the best available source pool", () => {
|
||||
const sources = [
|
||||
{ url: "https://example.com/1", normalized_url: "https://example.com/1" },
|
||||
{ url: "https://example.com/2", normalized_url: "https://example.com/2" },
|
||||
{ url: "https://example.com/3", normalized_url: "https://example.com/3" },
|
||||
];
|
||||
|
||||
expect(extractCitationMarkerIndexes("正文 [citation:1] 和 [citation:3]")).toEqual([1, 3]);
|
||||
expect(resolveCitationsFromMarkers("正文 [citation:1] 和 [citation:3]", [[], sources]).map((item) => item.url)).toEqual([
|
||||
"https://example.com/1",
|
||||
"https://example.com/3",
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user