Skip to content

Commit 8042ec4

Browse files
committed
fix(qa): scope runtime parity mock requests
1 parent f1f00cb commit 8042ec4

2 files changed

Lines changed: 53 additions & 2 deletions

File tree

extensions/qa-lab/src/runtime-parity.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,30 @@ describe("runtime parity", () => {
141141
},
142142
]);
143143
});
144+
145+
it("scopes process-global mock requests to the parent session prompt", () => {
146+
const scoped = __testing.filterMockRequestsForParentPrompt(
147+
[
148+
{
149+
allInputText: "Delegate one bounded QA task to a subagent.",
150+
plannedToolName: "sessions_spawn",
151+
},
152+
{
153+
allInputText: "Inspect the QA workspace and return one concise protocol note.",
154+
plannedToolName: "read",
155+
},
156+
{
157+
allInputText: "Delegate one bounded QA task to a subagent. Tool result: child accepted.",
158+
toolOutput: "child accepted",
159+
},
160+
],
161+
"Delegate one bounded QA task to a subagent.",
162+
);
163+
164+
expect(scoped).toHaveLength(2);
165+
expect(scoped.map((request) => request.plannedToolName ?? "result")).toEqual([
166+
"sessions_spawn",
167+
"result",
168+
]);
169+
});
144170
});

extensions/qa-lab/src/runtime-parity.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ type RuntimeParityTranscriptRecord = {
120120
};
121121

122122
type RuntimeParityMockRequestSnapshot = {
123+
allInputText?: string;
123124
plannedToolName?: string;
124125
plannedToolArgs?: unknown;
125126
toolOutput?: string;
@@ -798,6 +799,20 @@ function resolveRuntimeParityToolCalls(params: {
798799
return params.mockToolCalls;
799800
}
800801

802+
function filterMockRequestsForParentPrompt(
803+
requests: RuntimeParityMockRequestSnapshot[],
804+
parentPrompt: string,
805+
) {
806+
const normalizedParentPrompt = normalizeTextForParity(parentPrompt);
807+
if (!normalizedParentPrompt) {
808+
return requests;
809+
}
810+
const matching = requests.filter((request) =>
811+
normalizeTextForParity(request.allInputText ?? "").includes(normalizedParentPrompt),
812+
);
813+
return matching.length > 0 ? matching : requests;
814+
}
815+
801816
function summarizeSentinelErrorClass(findings: readonly GatewayLogSentinelFinding[]) {
802817
if (findings.length === 0) {
803818
return undefined;
@@ -993,6 +1008,7 @@ async function loadRuntimeParityTranscripts(params: {
9931008

9941009
async function loadRuntimeParityMockToolCalls(
9951010
mockBaseUrl: string | undefined,
1011+
parentPrompt: string,
9961012
): Promise<RuntimeParityToolCall[] | null> {
9971013
const normalizedBaseUrl = mockBaseUrl?.trim().replace(/\/+$/u, "");
9981014
if (!normalizedBaseUrl) {
@@ -1018,12 +1034,15 @@ async function loadRuntimeParityMockToolCalls(
10181034
}
10191035
const requests = payload.filter(isMessageRecord).map(
10201036
(entry): RuntimeParityMockRequestSnapshot => ({
1037+
allInputText: readNonEmptyString(entry.allInputText),
10211038
plannedToolName: readNonEmptyString(entry.plannedToolName),
10221039
plannedToolArgs: entry.plannedToolArgs ?? null,
10231040
toolOutput: readNonEmptyString(entry.toolOutput) ?? "",
10241041
}),
10251042
);
1026-
return resolveToolCallOrderFromMockRequests(requests);
1043+
return resolveToolCallOrderFromMockRequests(
1044+
filterMockRequestsForParentPrompt(requests, parentPrompt),
1045+
);
10271046
} catch {
10281047
return null;
10291048
}
@@ -1039,7 +1058,12 @@ export async function captureRuntimeParityCell(
10391058
});
10401059
const transcriptRecords = buildTranscriptRecords(transcriptBytes);
10411060
const transcriptToolCalls = resolveToolCallOrder(transcriptRecords);
1042-
const mockToolCalls = await loadRuntimeParityMockToolCalls(params.mockBaseUrl);
1061+
const parentPrompt =
1062+
transcriptRecords
1063+
.filter((record) => record.role === "user" && !isToolResultLikeMessage(record.message))
1064+
.map((record) => extractAssistantText(record.message))
1065+
.find(Boolean) ?? "";
1066+
const mockToolCalls = await loadRuntimeParityMockToolCalls(params.mockBaseUrl, parentPrompt);
10431067
const gatewayLogs = params.gateway.logs?.();
10441068
const sentinelFindings = [
10451069
...scanGatewayLogSentinels(gatewayLogs),
@@ -1087,6 +1111,7 @@ export async function runRuntimeParityScenario(params: {
10871111

10881112
export const testing = {
10891113
classifyRuntimeParityCells,
1114+
filterMockRequestsForParentPrompt,
10901115
resolveRuntimeParityToolCalls,
10911116
resolveToolCallOrderFromMockRequests,
10921117
};

0 commit comments

Comments
 (0)