Skip to content

Commit 4c4bcde

Browse files
cameroncookecodex
andcommitted
fix(ui-automation): Honor runtime metadata snapshot TTL
Use the current time when looking up stored runtime snapshot metadata for next-step generation so expired private metadata cannot influence guidance. Add regression coverage for expired stored metadata with a still-present public snapshot payload. Co-Authored-By: Codex <noreply@openai.com>
1 parent 0f6a9e3 commit 4c4bcde

2 files changed

Lines changed: 53 additions & 4 deletions

File tree

src/mcp/tools/ui-automation/__tests__/runtime-next-steps.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,58 @@ describe('runtime snapshot next steps', () => {
4343
__resetRuntimeSnapshotStoreForTests();
4444
});
4545

46+
it('ignores expired stored metadata when creating next steps', () => {
47+
recordSnapshot(
48+
[
49+
createScrollView({
50+
AXIdentifier: 'example.expiredSheet',
51+
children: [
52+
createNode({ AXLabel: 'Close' }),
53+
createNode({
54+
type: 'TextField',
55+
role: 'AXTextField',
56+
AXLabel: 'Search',
57+
}),
58+
createNode({
59+
AXLabel: 'London, England',
60+
AXIdentifier: 'example.locationCard',
61+
}),
62+
],
63+
}),
64+
],
65+
0,
66+
);
67+
68+
const storedSnapshot = getRuntimeSnapshot(simulatorId, 0);
69+
expect(storedSnapshot).not.toBeNull();
70+
const expiredSnapshot = storedSnapshot!.payload;
71+
72+
const steps = createRuntimeSnapshotNextSteps({
73+
simulatorId,
74+
runtimeSnapshot: expiredSnapshot,
75+
includeRefreshAndWait: false,
76+
});
77+
78+
expect(getRuntimeSnapshot(simulatorId)).toBeNull();
79+
expect(steps).toEqual([
80+
{
81+
label: 'Tap an elementRef',
82+
tool: 'tap',
83+
params: { simulatorId, elementRef: 'e4' },
84+
},
85+
{
86+
label: 'Scroll visible content',
87+
tool: 'swipe',
88+
params: {
89+
simulatorId,
90+
withinElementRef: 'e1',
91+
direction: 'up',
92+
distance: 0.5,
93+
},
94+
},
95+
]);
96+
});
97+
4698
it('prefers tap and scroll examples from the active foreground container', () => {
4799
recordSnapshot([
48100
createScrollView({

src/mcp/tools/ui-automation/shared/runtime-next-steps.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,7 @@ function findStoredSnapshotRecords(params: {
303303
simulatorId: string;
304304
runtimeSnapshot: RuntimeSnapshotV1;
305305
}): Map<string, RuntimeSnapshotElementRecord> {
306-
const storedSnapshot = getRuntimeSnapshot(
307-
params.simulatorId,
308-
params.runtimeSnapshot.capturedAtMs,
309-
);
306+
const storedSnapshot = getRuntimeSnapshot(params.simulatorId);
310307
if (
311308
storedSnapshot?.payload.screenHash !== params.runtimeSnapshot.screenHash ||
312309
storedSnapshot.payload.seq !== params.runtimeSnapshot.seq

0 commit comments

Comments
 (0)