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:
2026-04-28 22:07:21 +08:00
parent 453a374a49
commit a6b17bae62
6 changed files with 312 additions and 22 deletions
@@ -1750,9 +1750,10 @@ function buildMonitoringResultPayload(
execution: AdapterExecutionResult,
): MonitoringTaskResultPayload {
const payload = execution.payload ?? {};
const status = execution.status === "succeeded" ? "succeeded" : "failed";
return {
lease_token: leaseToken,
status: execution.status === "failed" ? "failed" : "succeeded",
status,
provider_model: asOptionalString(payload.provider_model),
provider_request_id: asOptionalString(payload.provider_request_id),
request_id: asOptionalString(payload.request_id),
@@ -1765,7 +1766,7 @@ function buildMonitoringResultPayload(
first_recommended: asOptionalBoolean(payload.first_recommended),
sentiment_label: asOptionalString(payload.sentiment_label),
matched_brand_terms: asStringArray(payload.matched_brand_terms),
error_message: execution.status === "failed" ? execution.summary : undefined,
error_message: status === "failed" ? execution.summary : undefined,
completed_at: new Date().toISOString(),
};
}