mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
fix(agents): keep web search error serialization surrogate-safe (#111327)
* fix(agents): keep web search error serialization surrogate-safe * test(agents): pin web search truncation prefix Preserve the pre-existing provider_error fallback while proving the exact UTF-16-safe retained prefix.\n\nCo-authored-by: zenglingbiao <zeng.lingbiao@xydigit.com> --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
co-authored by
Peter Steinberger
parent
269099585a
commit
a70f7702a9
@@ -8,6 +8,7 @@
|
||||
* spoof the trust marker and transport-specific extras never reach the model.
|
||||
*/
|
||||
import { isRecord } from "@openclaw/normalization-core/record-coerce";
|
||||
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
|
||||
import type { Static } from "typebox";
|
||||
import { Type } from "typebox";
|
||||
import { wrapWebContent } from "../../security/external-content.js";
|
||||
@@ -211,7 +212,7 @@ export function normalizeWebSearchOutput(params: {
|
||||
const rawError =
|
||||
typeof result.error === "string"
|
||||
? result.error
|
||||
: (JSON.stringify(result.error)?.slice(0, 2_000) ?? "provider_error");
|
||||
: truncateUtf16Safe(JSON.stringify(result.error) ?? "provider_error", 2_000);
|
||||
const rawMessage = typeof result.message === "string" ? result.message : rawError;
|
||||
const docs = typeof result.docs === "string" ? toHttpUrl(result.docs) : undefined;
|
||||
return {
|
||||
|
||||
@@ -721,6 +721,23 @@ describe("web_search normalized output contract", () => {
|
||||
expect(normalized.message).toContain("quota exceeded");
|
||||
});
|
||||
|
||||
it("keeps structured provider error serialization surrogate-safe at the cap", () => {
|
||||
const normalized = normalizeWebSearchOutput({
|
||||
provider: "external-demo",
|
||||
query: "emoji error",
|
||||
// The emoji straddles the 2000-unit cut: a plain slice would keep only
|
||||
// its high surrogate half.
|
||||
result: { error: { message: `${"x".repeat(1_987)}🤖` } },
|
||||
});
|
||||
|
||||
if (normalized.kind !== "error") {
|
||||
throw new Error("expected error branch");
|
||||
}
|
||||
const expectedPrefix = `{"message":"${"x".repeat(1_987)}`;
|
||||
expect(stripWrapMarkers(normalized.message)).toBe(expectedPrefix);
|
||||
expect(expectedPrefix).toHaveLength(1_999);
|
||||
});
|
||||
|
||||
it("keeps ordinary Source attribution lines in answer content", () => {
|
||||
const normalized = normalizeWebSearchOutput({
|
||||
provider: "external-answer",
|
||||
|
||||
Reference in New Issue
Block a user