Skip to content

Commit 08abf2d

Browse files
yuyutaotaoquanru
andauthored
fix(agent): validate cache strategy configuration (#1272)
* fix(agent): validate cache strategy configuration * chore(core): fix lint * docs(site): cache startegy default value * feat(web-integration): update cache type to support read-only and read-write strategies --------- Co-authored-by: quanruzhuoxiu <[email protected]>
1 parent fb51e5d commit 08abf2d

File tree

5 files changed

+78
-9
lines changed

5 files changed

+78
-9
lines changed

apps/site/docs/en/caching.mdx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,33 @@ agent:
5151
5252
### Read-write mode
5353
54-
Configuration: `cache: { id: "my-cache-id" }`
54+
Configuration: `cache: { id: "my-cache-id" }` or `cache: { strategy: "read-write", id: "my-cache-id" }`
5555

56-
Automatically read existing cache and update cache files during execution.
56+
Automatically read existing cache and update cache files during execution. The default value of `strategy` is `read-write`.
5757

5858
```javascript
5959
// Direct Agent creation - explicit cache ID
6060
const agent = new PuppeteerAgent(page, {
6161
cache: { id: "my-cache-id" },
6262
});
63+
64+
// Explicitly specify strategy
65+
const agent = new PuppeteerAgent(page, {
66+
cache: { strategy: "read-write", id: "my-cache-id" },
67+
});
6368
```
6469

6570
```yaml
6671
# YAML configuration - explicit cache ID
6772
agent:
6873
cache:
6974
id: "my-cache-test"
75+
76+
# Explicitly specify strategy
77+
agent:
78+
cache:
79+
id: "my-cache-test"
80+
strategy: "read-write"
7081
```
7182

7283
YAML mode also supports `cache: true` to automatically use the file name as the cache ID.

apps/site/docs/zh/caching.mdx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,33 @@ agent:
5454
5555
### 读写模式
5656
57-
配置方式:`cache: { id: "my-cache-id" }`
57+
配置方式:`cache: { id: "my-cache-id" }` 或 `cache: { strategy: "read-write", id: "my-cache-id" }`
5858

59-
自动读取已有缓存,执行过程中自动更新缓存文件。
59+
自动读取已有缓存,执行过程中自动更新缓存文件。`strategy` 的默认值是 `read-write`。
6060

6161
```javascript
6262
// 直接创建 Agent - 显式设置 cache ID
6363
const agent = new PuppeteerAgent(page, {
6464
cache: { id: "my-cache-id" },
6565
});
66+
67+
// 显式指定 strategy
68+
const agent = new PuppeteerAgent(page, {
69+
cache: { strategy: "read-write", id: "my-cache-id" },
70+
});
6671
```
6772

6873
```yaml
6974
# YAML 配置 - 显式设置 cache ID
7075
agent:
7176
cache:
7277
id: "my-cache-test"
78+
79+
# 显式指定 strategy
80+
agent:
81+
cache:
82+
id: "my-cache-test"
83+
strategy: "read-write"
7384
```
7485

7586
YAML 模式还支持配置 `cache: true`,自动使用文件名作为 cache ID。

packages/core/src/agent/agent.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
} from '../yaml/index';
4242

4343
import type { AbstractInterface } from '@/device';
44-
import type { AgentOpt } from '@/types';
44+
import type { AgentOpt, CacheConfig } from '@/types';
4545
import {
4646
MIDSCENE_CACHE,
4747
ModelConfigManager,
@@ -81,6 +81,17 @@ const defaultInsightExtractOption: InsightExtractOption = {
8181
screenshotIncluded: true,
8282
};
8383

84+
type CacheStrategy = NonNullable<CacheConfig['strategy']>;
85+
86+
const CACHE_STRATEGIES: readonly CacheStrategy[] = ['read-only', 'read-write'];
87+
88+
const isValidCacheStrategy = (strategy: string): strategy is CacheStrategy =>
89+
CACHE_STRATEGIES.some((value) => value === strategy);
90+
91+
const CACHE_STRATEGY_VALUES = CACHE_STRATEGIES.map(
92+
(value) => `"${value}"`,
93+
).join(', ');
94+
8495
export class Agent<
8596
InterfaceType extends AbstractInterface = AbstractInterface,
8697
> {
@@ -1079,9 +1090,26 @@ export class Agent<
10791090
);
10801091
}
10811092
const id = config.id;
1082-
// Default strategy is 'read-write'
1083-
const strategy = config.strategy ?? 'read-write';
1084-
const isReadOnly = strategy === 'read-only';
1093+
const rawStrategy = config.strategy as unknown;
1094+
let strategyValue: string;
1095+
1096+
if (rawStrategy === undefined) {
1097+
strategyValue = 'read-write';
1098+
} else if (typeof rawStrategy === 'string') {
1099+
strategyValue = rawStrategy;
1100+
} else {
1101+
throw new Error(
1102+
`cache.strategy must be a string when provided, but received type ${typeof rawStrategy}`,
1103+
);
1104+
}
1105+
1106+
if (!isValidCacheStrategy(strategyValue)) {
1107+
throw new Error(
1108+
`cache.strategy must be one of ${CACHE_STRATEGY_VALUES}, but received "${strategyValue}"`,
1109+
);
1110+
}
1111+
1112+
const isReadOnly = strategyValue === 'read-only';
10851113

10861114
return {
10871115
id,

packages/web-integration/src/playwright/ai-fixture.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,17 @@ const groupAndCaseForTest = (testInfo: TestInfo) => {
4747
const midsceneAgentKeyId = '_midsceneAgentId';
4848
export const midsceneDumpAnnotationId = 'MIDSCENE_DUMP_ANNOTATION';
4949

50+
type PlaywrightCacheConfig = {
51+
strategy?: 'read-only' | 'read-write';
52+
id?: string;
53+
};
54+
type PlaywrightCache = false | true | PlaywrightCacheConfig;
55+
5056
export const PlaywrightAiFixture = (options?: {
5157
forceSameTabNavigation?: boolean;
5258
waitForNetworkIdleTimeout?: number;
5359
waitForNavigationTimeout?: number;
54-
cache?: Cache;
60+
cache?: PlaywrightCache;
5561
}) => {
5662
const {
5763
forceSameTabNavigation = true,

packages/web-integration/tests/unit-test/agent.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,19 @@ describe('PageAgent cache configuration', () => {
447447
expect(agent.taskCache?.cacheId).toBe('custom-cache-id');
448448
});
449449

450+
it('should throw error for cache: { strategy: "invalid" }', () => {
451+
expect(() => {
452+
new PageAgent(mockPage, {
453+
cache: {
454+
// @ts-expect-error invalid strategy provided intentionally for runtime validation
455+
strategy: 'invalid',
456+
id: 'invalid-strategy-cache',
457+
},
458+
modelConfig: () => mockedModelConfigFnResult,
459+
});
460+
}).toThrow('cache.strategy must be one of "read-only", "read-write"');
461+
});
462+
450463
it('should handle cache: { strategy: "read-write", id: "custom-id" }', () => {
451464
const agent = new PageAgent(mockPage, {
452465
cache: {

0 commit comments

Comments
 (0)