Skip to content

Commit 453e9ae

Browse files
committed
feat(web-integration): enhance TaskCache to manage current cycle state
1 parent 7b1b90d commit 453e9ae

File tree

3 files changed

+94
-15
lines changed

3 files changed

+94
-15
lines changed

packages/web-integration/src/common/task-cache.ts

Lines changed: 90 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ export class TaskCache {
100100

101101
private usedCacheItems: Map<string, Set<number>> = new Map();
102102

103+
private currentCycleCacheState: Map<
104+
string,
105+
{ count: number; usedIndices: number[] }
106+
> = new Map();
107+
103108
constructor(page: WebPage, opts?: { cacheId?: string }) {
104109
this.midscenePkgInfo = getRunningPkgInfo();
105110
this.cacheId = replaceIllegalPathCharsAndSpace(opts?.cacheId || '');
@@ -116,7 +121,7 @@ export class TaskCache {
116121
pkgName: this.midscenePkgInfo?.name || '',
117122
pkgVersion: this.midscenePkgInfo?.version || '',
118123
cacheId: this.cacheId,
119-
aiTasks: [],
124+
aiTasks: JSON.parse(JSON.stringify(this.cache.aiTasks || [])),
120125
};
121126
}
122127

@@ -126,30 +131,104 @@ export class TaskCache {
126131
}
127132

128133
const usedIndices = this.usedCacheItems.get(aiActionPrompt)!;
129-
const currentCount = usedIndices.size;
130134
const { aiTasks = [] } = this.cache || { aiTasks: [] };
131135

136+
// 初始化或获取当前循环状态
137+
if (!this.currentCycleCacheState.has(aiActionPrompt)) {
138+
this.currentCycleCacheState.set(aiActionPrompt, {
139+
count: 0,
140+
usedIndices: [],
141+
});
142+
}
143+
144+
// 获取并更新计数
145+
const cacheState = this.currentCycleCacheState.get(aiActionPrompt)!;
146+
const currentCount = cacheState.count;
147+
cacheState.count++;
148+
149+
debug('current prompt [%s] count: %d', aiActionPrompt, currentCount + 1);
150+
132151
let matchIndex = -1;
133152
let matchItem = null;
134153

154+
// find unused cache item in order
135155
for (let i = 0; i < aiTasks.length; i++) {
136156
const item = aiTasks[i];
137157
if (item.prompt === aiActionPrompt) {
138158
if (!usedIndices.has(i) && item.tasks && item.tasks.length > 0) {
139159
matchIndex = i;
140160
matchItem = item;
141161
usedIndices.add(i);
142-
debug('找到未使用的缓存项: %s, 索引: %d', aiActionPrompt, i);
162+
debug('find unused cache item: %s, index: %d', aiActionPrompt, i);
143163
break;
144164
}
145165
}
146166
}
147167

148-
const newCacheGroup: AiTasks = [];
149-
this.newCache.aiTasks.push({
150-
prompt: aiActionPrompt,
151-
tasks: newCacheGroup,
152-
});
168+
// get all cache groups with same prompt in new cache
169+
const promptGroups = this.newCache.aiTasks.filter(
170+
(item) => item.prompt === aiActionPrompt,
171+
);
172+
173+
const usedGroupIndices = cacheState.usedIndices;
174+
let targetGroupIndex: number;
175+
let newCacheGroup: AiTasks;
176+
177+
// if current count is less than the number of existing cache groups, use the corresponding index cache group
178+
if (currentCount < promptGroups.length) {
179+
// find the index of promptGroups[currentCount] in newCache.aiTasks
180+
targetGroupIndex = this.newCache.aiTasks.findIndex(
181+
(item, index) =>
182+
item.prompt === aiActionPrompt &&
183+
!usedGroupIndices.includes(index) && // if the index is not used
184+
usedGroupIndices.length === currentCount, // if the index is the index in current cycle, ensure the order of used cache groups
185+
);
186+
187+
if (targetGroupIndex === -1) {
188+
debug(
189+
'no suitable cache group, create new cache group: prompt [%s], current count: %d',
190+
aiActionPrompt,
191+
currentCount + 1,
192+
);
193+
this.newCache.aiTasks.push({
194+
prompt: aiActionPrompt,
195+
tasks: [],
196+
});
197+
targetGroupIndex = this.newCache.aiTasks.length - 1;
198+
usedGroupIndices.push(targetGroupIndex);
199+
newCacheGroup = this.newCache.aiTasks[targetGroupIndex].tasks;
200+
debug(
201+
'create new cache group as fallback: prompt [%s], index: %d, current count: %d',
202+
aiActionPrompt,
203+
targetGroupIndex,
204+
currentCount + 1,
205+
);
206+
} else {
207+
usedGroupIndices.push(targetGroupIndex);
208+
newCacheGroup = this.newCache.aiTasks[targetGroupIndex].tasks;
209+
debug(
210+
'use existing cache group: prompt [%s], index: %d, current count: %d',
211+
aiActionPrompt,
212+
targetGroupIndex,
213+
currentCount + 1,
214+
);
215+
}
216+
} else {
217+
// if current count is greater than the number of existing cache groups, create a new cache group
218+
this.newCache.aiTasks.push({
219+
prompt: aiActionPrompt,
220+
tasks: [],
221+
});
222+
targetGroupIndex = this.newCache.aiTasks.length - 1;
223+
usedGroupIndices.push(targetGroupIndex);
224+
newCacheGroup = this.newCache.aiTasks[targetGroupIndex].tasks;
225+
debug(
226+
'create new cache group: prompt [%s], index: %d, current count: %d',
227+
aiActionPrompt,
228+
targetGroupIndex,
229+
currentCount + 1,
230+
);
231+
}
153232

154233
return {
155234
matchCache: async <T extends 'plan' | 'locate' | 'ui-tars-plan'>(
@@ -194,10 +273,11 @@ export class TaskCache {
194273
saveCache: (cache: PlanTask | LocateTask | UITarsPlanTask) => {
195274
newCacheGroup.push(cache);
196275
debug(
197-
'saving cache to file, type: %s, cacheId: %s, index: %d',
276+
'save cache to file, type: %s, cacheId: %s, prompt index: %d, current count: %d',
198277
cache.type,
199278
this.cacheId,
200-
currentCount,
279+
targetGroupIndex,
280+
currentCount + 1,
201281
);
202282
this.writeCacheToFile();
203283
},

packages/web-integration/src/common/tasks.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,6 @@ export class PageTaskExecutor {
986986
);
987987
replanCount++;
988988
}
989-
990989
return {
991990
output: result,
992991
executor: taskExecutor,

packages/web-integration/tests/ai/web/puppeteer/open-new-tab.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ describe('agent with forceSameTabNavigation', () => {
2121
const agent = new PuppeteerAgent(originPage, {
2222
cacheId: 'puppeteer-open-new-tab',
2323
});
24-
await agent.aiAction(
25-
'type "midscene github" in search box, and press Enter, sleep 5 seconds, and click the result about "midscene" project',
26-
);
24+
await agent.aiAction('向下滚动一屏');
25+
await agent.aiAction('点击搜索框');
26+
await agent.aiAction('向下滚动一屏');
27+
// await agent.aiAction('向下滚动一屏');
2728
await sleep(5000);
28-
await agent.aiAssert('the page is about "midscene" project');
2929
});
3030
});

0 commit comments

Comments
 (0)