mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
refactor(verification): centralize native client result discovery
This commit is contained in:
1 parent
981d806924
commit
554816becc
10 files changed
+227
-190
No files matched your search
@@ -26,6 +26,10 @@ import {
|
||||
expandMcpSessionStatus,
|
||||
sortVerifierNames,
|
||||
} from "./lib/mcp-verifier-results.mjs";
|
||||
import {
|
||||
findClientResult,
|
||||
isClientJavaScriptEvidence,
|
||||
} from "./verify/clients/result-discovery.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { createAnthropicModelFixture } from "./verify/clients/anthropic-model-fixture.mjs";
|
||||
|
||||
@@ -106,28 +110,14 @@ await withVerifierCleanup(async () => {
|
||||
);
|
||||
return false;
|
||||
};
|
||||
const extractInlineResult = (value, matches) => {
|
||||
if (typeof value === "string") {
|
||||
try {
|
||||
// Native Claude appends this resource hint to tool results. Original bodies remain intact in request artifacts.
|
||||
const json = value.replace(
|
||||
/\n\n<system-reminder>\n<total_tokens>\d+ tokens left<\/total_tokens>\n<\/system-reminder>$/u,
|
||||
"",
|
||||
);
|
||||
return extractInlineResult(JSON.parse(json), matches);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
if (matches(value)) return value;
|
||||
for (const nested of Object.values(value)) {
|
||||
const result = extractInlineResult(nested, matches);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
const decodeClaudeResult = (text) =>
|
||||
JSON.parse(
|
||||
// Native Claude appends this resource hint. Original bodies remain in request artifacts.
|
||||
text.replace(
|
||||
/\n\n<system-reminder>\n<total_tokens>\d+ tokens left<\/total_tokens>\n<\/system-reminder>$/u,
|
||||
"",
|
||||
),
|
||||
);
|
||||
fixture = await createAnthropicModelFixture({
|
||||
directory: lab,
|
||||
onRequest: async ({ body, tools, requestIndex }) => {
|
||||
@@ -181,11 +171,12 @@ await withVerifierCleanup(async () => {
|
||||
}
|
||||
}
|
||||
if (mode === "call" && !sessionStatusSeen) {
|
||||
const observedStatus = extractInlineResult(
|
||||
const observedStatus = findClientResult(
|
||||
body.messages,
|
||||
(value) =>
|
||||
Boolean(value.result?.server_identity) &&
|
||||
Array.isArray(value.result?.tool_availability?.groups),
|
||||
decodeClaudeResult,
|
||||
);
|
||||
if (observedStatus) {
|
||||
const parsedStatus =
|
||||
@@ -242,11 +233,10 @@ await withVerifierCleanup(async () => {
|
||||
expectedSkillBody !== undefined &&
|
||||
containsText(body.messages, expectedSkillBody) &&
|
||||
containsText(body.messages, skillDirectory);
|
||||
const observed = extractInlineResult(
|
||||
const observed = findClientResult(
|
||||
body.messages,
|
||||
(value) =>
|
||||
typeof value.evidence_id === "string" &&
|
||||
value.normalized_result?.graph?.nodes?.length > 0,
|
||||
isClientJavaScriptEvidence,
|
||||
decodeClaudeResult,
|
||||
);
|
||||
if (observed) {
|
||||
const { evidence } = await assertClientJavaScriptFixtureEvidence(
|
||||
|
||||
@@ -19,6 +19,10 @@ import {
|
||||
CLIENT_JAVASCRIPT_FIXTURE_SOURCE,
|
||||
assertClientJavaScriptFixtureEvidence,
|
||||
} from "./verify/clients/javascript-fixture.mjs";
|
||||
import {
|
||||
findClientResult,
|
||||
isClientJavaScriptEvidence,
|
||||
} from "./verify/clients/result-discovery.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { createOpenAiModelFixture } from "./verify/clients/model-fixture.mjs";
|
||||
|
||||
@@ -124,27 +128,6 @@ await withVerifierCleanup(async () => {
|
||||
);
|
||||
return false;
|
||||
};
|
||||
const extractEvidence = (value) => {
|
||||
if (typeof value === "string") {
|
||||
try {
|
||||
return extractEvidence(JSON.parse(value));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
if (
|
||||
typeof value.evidence_id === "string" &&
|
||||
value.normalized_result?.graph?.nodes?.length > 0
|
||||
)
|
||||
return value;
|
||||
for (const nested of Object.values(value)) {
|
||||
const evidence = extractEvidence(nested);
|
||||
if (evidence) return evidence;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
fixture = await createOpenAiModelFixture({
|
||||
directory: lab,
|
||||
prefix: "copilot",
|
||||
@@ -204,7 +187,7 @@ await withVerifierCleanup(async () => {
|
||||
expectedSkillBody !== undefined &&
|
||||
containsText(body.messages, expectedSkillBody) &&
|
||||
containsText(body.messages, skillDirectory);
|
||||
const observed = extractEvidence(replies);
|
||||
const observed = findClientResult(replies, isClientJavaScriptEvidence);
|
||||
if (observed) {
|
||||
const { evidence } = await assertClientJavaScriptFixtureEvidence(
|
||||
observed,
|
||||
|
||||
@@ -15,6 +15,10 @@ import {
|
||||
CLIENT_JAVASCRIPT_FIXTURE_SOURCE,
|
||||
assertClientJavaScriptFixtureEvidence,
|
||||
} from "./verify/clients/javascript-fixture.mjs";
|
||||
import {
|
||||
findClientResult,
|
||||
isClientJavaScriptEvidence,
|
||||
} from "./verify/clients/result-discovery.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { createOpenAiModelFixture } from "./verify/clients/model-fixture.mjs";
|
||||
|
||||
@@ -130,26 +134,6 @@ await withVerifierCleanup(async () => {
|
||||
} else validatePatterns(child);
|
||||
}
|
||||
};
|
||||
const extractEvidence = (value) => {
|
||||
if (typeof value === "string") {
|
||||
try {
|
||||
return extractEvidence(JSON.parse(value));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
if (
|
||||
typeof value.evidence_id === "string" &&
|
||||
value.normalized_result?.graph?.nodes
|
||||
)
|
||||
return value;
|
||||
for (const child of Object.values(value)) {
|
||||
const found = extractEvidence(child);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
};
|
||||
fixture = await createOpenAiModelFixture({
|
||||
directory: lab,
|
||||
prefix: `deepseek-${mode}`,
|
||||
@@ -192,7 +176,10 @@ await withVerifierCleanup(async () => {
|
||||
'<skill_content name=\\"reverse-engineer-anything\\">',
|
||||
) && serialized.includes(dirname(skillPath));
|
||||
for (const message of toolMessages) {
|
||||
const found = extractEvidence(message.content);
|
||||
const found = findClientResult(
|
||||
message.content,
|
||||
isClientJavaScriptEvidence,
|
||||
);
|
||||
if (found === undefined) continue;
|
||||
const { evidence } = await assertClientJavaScriptFixtureEvidence(
|
||||
found,
|
||||
|
||||
@@ -21,6 +21,10 @@ import {
|
||||
CLIENT_JAVASCRIPT_FIXTURE_SOURCE,
|
||||
assertClientJavaScriptFixtureEvidence,
|
||||
} from "./verify/clients/javascript-fixture.mjs";
|
||||
import {
|
||||
findClientResult,
|
||||
isClientJavaScriptEvidence,
|
||||
} from "./verify/clients/result-discovery.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { createGeminiModelFixture } from "./verify/clients/gemini-model-fixture.mjs";
|
||||
|
||||
@@ -231,37 +235,18 @@ await withVerifierCleanup(async () => {
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
const extractEvidence = (value) => {
|
||||
if (typeof value === "string") {
|
||||
if (
|
||||
value.startsWith("<untrusted_context>\n") &&
|
||||
value.endsWith("\n</untrusted_context>")
|
||||
) {
|
||||
return extractEvidence(
|
||||
value.slice(
|
||||
"<untrusted_context>\n".length,
|
||||
-"\n</untrusted_context>".length,
|
||||
),
|
||||
);
|
||||
}
|
||||
try {
|
||||
return extractEvidence(JSON.parse(value));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
if (
|
||||
typeof value.evidence_id === "string" &&
|
||||
value.normalized_result?.graph?.nodes?.length > 0
|
||||
)
|
||||
return value;
|
||||
for (const nested of Object.values(value)) {
|
||||
const evidence = extractEvidence(nested);
|
||||
if (evidence) return evidence;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
const decodeGeminiResult = (text) => {
|
||||
if (
|
||||
text.startsWith("<untrusted_context>\n") &&
|
||||
text.endsWith("\n</untrusted_context>")
|
||||
)
|
||||
return decodeGeminiResult(
|
||||
text.slice(
|
||||
"<untrusted_context>\n".length,
|
||||
-"\n</untrusted_context>".length,
|
||||
),
|
||||
);
|
||||
return JSON.parse(text);
|
||||
};
|
||||
fixture = await createGeminiModelFixture({
|
||||
directory: lab,
|
||||
@@ -327,7 +312,11 @@ await withVerifierCleanup(async () => {
|
||||
join(profile, ".agents", "skills", "reverse-engineer-anything"),
|
||||
),
|
||||
);
|
||||
const observed = extractEvidence(responses);
|
||||
const observed = findClientResult(
|
||||
responses,
|
||||
isClientJavaScriptEvidence,
|
||||
decodeGeminiResult,
|
||||
);
|
||||
if (observed) {
|
||||
const { evidence } = await assertClientJavaScriptFixtureEvidence(
|
||||
observed,
|
||||
|
||||
@@ -12,6 +12,10 @@ import {
|
||||
CLIENT_JAVASCRIPT_FIXTURE_SOURCE,
|
||||
assertClientJavaScriptFixtureEvidence,
|
||||
} from "./verify/clients/javascript-fixture.mjs";
|
||||
import {
|
||||
findClientResult,
|
||||
isClientJavaScriptEvidence,
|
||||
} from "./verify/clients/result-discovery.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { createOpenAiModelFixture } from "./verify/clients/model-fixture.mjs";
|
||||
|
||||
@@ -157,39 +161,21 @@ await withVerifierCleanup(async () => {
|
||||
"name: reverse-engineer-anything",
|
||||
),
|
||||
);
|
||||
const extractEvidence = (value) => {
|
||||
if (typeof value === "string") {
|
||||
if (
|
||||
value.startsWith("<untrusted_tool_result ") &&
|
||||
value.endsWith("</untrusted_tool_result>")
|
||||
) {
|
||||
// Hermes wraps external MCP content with its own instruction banner.
|
||||
// Decode only that observed envelope, retaining the original request artifact.
|
||||
const start = value.indexOf("\n\n");
|
||||
if (start >= 0)
|
||||
return extractEvidence(
|
||||
value
|
||||
.slice(start + 2, value.lastIndexOf("</untrusted_tool_result>"))
|
||||
.trim(),
|
||||
);
|
||||
}
|
||||
try {
|
||||
return extractEvidence(JSON.parse(value));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
if (
|
||||
typeof value.evidence_id === "string" &&
|
||||
value.normalized_result?.graph?.nodes
|
||||
)
|
||||
return value;
|
||||
for (const child of Object.values(value)) {
|
||||
const found = extractEvidence(child);
|
||||
if (found) return found;
|
||||
}
|
||||
const decodeNativeAgentResult = (text) => {
|
||||
if (
|
||||
text.startsWith("<untrusted_tool_result ") &&
|
||||
text.endsWith("</untrusted_tool_result>")
|
||||
) {
|
||||
// Hermes wraps external MCP content with its own banner; retain original request artifacts.
|
||||
const start = text.indexOf("\n\n");
|
||||
if (start >= 0)
|
||||
return decodeNativeAgentResult(
|
||||
text
|
||||
.slice(start + 2, text.lastIndexOf("</untrusted_tool_result>"))
|
||||
.trim(),
|
||||
);
|
||||
}
|
||||
return JSON.parse(text);
|
||||
};
|
||||
const validateEvidence = async (value) => {
|
||||
const { evidence } = await assertClientJavaScriptFixtureEvidence(
|
||||
@@ -273,7 +259,11 @@ await withVerifierCleanup(async () => {
|
||||
serializedTools.includes(skillPath) &&
|
||||
serializedTools.includes("reverse-engineer-anything");
|
||||
for (const message of toolMessages) {
|
||||
const evidence = extractEvidence(message.content);
|
||||
const evidence = findClientResult(
|
||||
message.content,
|
||||
isClientJavaScriptEvidence,
|
||||
decodeNativeAgentResult,
|
||||
);
|
||||
if (evidence) await validateEvidence(evidence);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ import {
|
||||
CLIENT_JAVASCRIPT_FIXTURE_SOURCE,
|
||||
assertClientJavaScriptFixtureEvidence,
|
||||
} from "./verify/clients/javascript-fixture.mjs";
|
||||
import {
|
||||
findClientResult,
|
||||
isClientJavaScriptEvidence,
|
||||
} from "./verify/clients/result-discovery.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { createOpenAiModelFixture } from "./verify/clients/model-fixture.mjs";
|
||||
|
||||
@@ -113,27 +117,6 @@ await withVerifierCleanup(async () => {
|
||||
strict: false,
|
||||
validateFormats: false,
|
||||
});
|
||||
const extractEvidence = (value) => {
|
||||
if (typeof value === "string") {
|
||||
try {
|
||||
return extractEvidence(JSON.parse(value));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
if (
|
||||
typeof value.evidence_id === "string" &&
|
||||
value.normalized_result?.graph?.nodes?.length > 0
|
||||
)
|
||||
return value;
|
||||
for (const nested of Object.values(value)) {
|
||||
const evidence = extractEvidence(nested);
|
||||
if (evidence) return evidence;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
fixture = await createOpenAiModelFixture({
|
||||
directory: lab,
|
||||
prefix: "opencode",
|
||||
@@ -178,7 +161,7 @@ await withVerifierCleanup(async () => {
|
||||
m.content.includes(skillDirectory) &&
|
||||
m.content.includes(expectedSkillBody),
|
||||
);
|
||||
const observed = extractEvidence(replies);
|
||||
const observed = findClientResult(replies, isClientJavaScriptEvidence);
|
||||
if (observed) {
|
||||
const { evidence } = await assertClientJavaScriptFixtureEvidence(
|
||||
observed,
|
||||
|
||||
@@ -19,6 +19,10 @@ import {
|
||||
CLIENT_JAVASCRIPT_FIXTURE_SOURCE,
|
||||
assertClientJavaScriptFixtureEvidence,
|
||||
} from "./verify/clients/javascript-fixture.mjs";
|
||||
import {
|
||||
findClientResult,
|
||||
isClientJavaScriptEvidence,
|
||||
} from "./verify/clients/result-discovery.mjs";
|
||||
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
|
||||
import { TOOL_CONTRACTS } from "../dist/contracts/toolContracts.js";
|
||||
|
||||
@@ -192,32 +196,6 @@ await withVerifierCleanup(async () => {
|
||||
const target = join(lab, "fixture α测试");
|
||||
await mkdir(target, { recursive: true });
|
||||
await writeFile(`${target}/app.js`, CLIENT_JAVASCRIPT_FIXTURE_SOURCE);
|
||||
const extractEvidence = (value) => {
|
||||
if (typeof value === "string") {
|
||||
try {
|
||||
return extractEvidence(JSON.parse(value));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
for (const item of value) {
|
||||
const result = extractEvidence(item);
|
||||
if (result) return result;
|
||||
}
|
||||
} else if (value && typeof value === "object") {
|
||||
if (
|
||||
typeof value.evidence_id === "string" &&
|
||||
value.normalized_result?.graph?.nodes?.length > 0
|
||||
)
|
||||
return value;
|
||||
for (const nested of Object.values(value)) {
|
||||
const result = extractEvidence(nested);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
fixture = await createOpenAiModelFixture({
|
||||
directory: lab,
|
||||
prefix: `${client}-${mode}`,
|
||||
@@ -258,7 +236,6 @@ await withVerifierCleanup(async () => {
|
||||
JSON.parse(artifact.toString("utf8")),
|
||||
target,
|
||||
);
|
||||
assert(extractEvidence(evidence));
|
||||
evidenceSeen = true;
|
||||
await writeFile(
|
||||
`${lab}/${client}-${mode}-evidence.json`,
|
||||
@@ -267,12 +244,14 @@ await withVerifierCleanup(async () => {
|
||||
}
|
||||
for (const message of body.messages ?? []) {
|
||||
if (message.role !== "tool") continue;
|
||||
const evidence = extractEvidence(message.content);
|
||||
if (evidence) {
|
||||
assert(
|
||||
JSON.stringify(evidence.normalized_result).includes(
|
||||
"REA_CLIENT_FIXTURE",
|
||||
),
|
||||
const candidate = findClientResult(
|
||||
message.content,
|
||||
isClientJavaScriptEvidence,
|
||||
);
|
||||
if (candidate) {
|
||||
const { evidence } = await assertClientJavaScriptFixtureEvidence(
|
||||
candidate,
|
||||
target,
|
||||
);
|
||||
evidenceSeen = true;
|
||||
await writeFile(
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
export interface ClientJavaScriptEvidenceCandidate {
|
||||
readonly evidence_id: string;
|
||||
readonly normalized_result: {
|
||||
readonly graph: { readonly nodes: readonly unknown[] };
|
||||
};
|
||||
}
|
||||
export function isClientJavaScriptEvidence(
|
||||
value: unknown,
|
||||
): value is ClientJavaScriptEvidenceCandidate;
|
||||
export function findClientResult<T>(
|
||||
value: unknown,
|
||||
matches: (value: object) => value is T & object,
|
||||
decodeText?: (text: string) => unknown,
|
||||
): (T & object) | undefined;
|
||||
export function findClientResult(
|
||||
value: unknown,
|
||||
matches: (value: object) => boolean,
|
||||
decodeText?: (text: string) => unknown,
|
||||
): object | undefined;
|
||||
@@ -0,0 +1,28 @@
|
||||
/** Find a result through native JSON containers without hiding assertion faults. */
|
||||
export const findClientResult = (value, matches, decodeText = JSON.parse) => {
|
||||
if (typeof value === "string") {
|
||||
let decoded;
|
||||
try {
|
||||
decoded = decodeText(value);
|
||||
} catch (cause) {
|
||||
if (cause instanceof SyntaxError) return undefined;
|
||||
throw cause;
|
||||
}
|
||||
return findClientResult(decoded, matches, decodeText);
|
||||
}
|
||||
if (value !== null && typeof value === "object") {
|
||||
if (matches(value)) return value;
|
||||
for (const nested of Object.values(value)) {
|
||||
const result = findClientResult(nested, matches, decodeText);
|
||||
if (result !== undefined) return result;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/** Empty graphs remain candidates: the assertion owner must reject bad fixtures. */
|
||||
export const isClientJavaScriptEvidence = (value) =>
|
||||
value !== null &&
|
||||
typeof value === "object" &&
|
||||
typeof value.evidence_id === "string" &&
|
||||
Array.isArray(value.normalized_result?.graph?.nodes);
|
||||
Reference in new issue
Block a user