page-action-cache 2.0.8 → 2026.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +100 -306
  2. package/openclaw.plugin.json +23 -14
  3. package/package.json +28 -21
  4. package/dist/browser-action-executor.d.ts +0 -87
  5. package/dist/browser-action-executor.d.ts.map +0 -1
  6. package/dist/browser-action-executor.js +0 -283
  7. package/dist/browser-action-executor.js.map +0 -1
  8. package/dist/cache-invalidation.d.ts +0 -128
  9. package/dist/cache-invalidation.d.ts.map +0 -1
  10. package/dist/cache-invalidation.js +0 -262
  11. package/dist/cache-invalidation.js.map +0 -1
  12. package/dist/cache-manager.d.ts +0 -83
  13. package/dist/cache-manager.d.ts.map +0 -1
  14. package/dist/cache-manager.js +0 -184
  15. package/dist/cache-manager.js.map +0 -1
  16. package/dist/index.d.ts +0 -10
  17. package/dist/index.d.ts.map +0 -1
  18. package/dist/index.js +0 -48
  19. package/dist/index.js.map +0 -1
  20. package/dist/multi-level-cache.d.ts +0 -127
  21. package/dist/multi-level-cache.d.ts.map +0 -1
  22. package/dist/multi-level-cache.js +0 -362
  23. package/dist/multi-level-cache.js.map +0 -1
  24. package/dist/scenario-recognizer.d.ts +0 -35
  25. package/dist/scenario-recognizer.d.ts.map +0 -1
  26. package/dist/scenario-recognizer.js +0 -93
  27. package/dist/scenario-recognizer.js.map +0 -1
  28. package/dist/types.d.ts +0 -62
  29. package/dist/types.d.ts.map +0 -1
  30. package/dist/types.js +0 -6
  31. package/dist/types.js.map +0 -1
  32. package/dist/variable-extractor.d.ts +0 -56
  33. package/dist/variable-extractor.d.ts.map +0 -1
  34. package/dist/variable-extractor.js +0 -159
  35. package/dist/variable-extractor.js.map +0 -1
  36. package/src/browser-action-executor.ts +0 -337
  37. package/src/cache-invalidation.ts +0 -338
  38. package/src/cache-manager.ts +0 -211
  39. package/src/index.ts +0 -58
  40. package/src/multi-level-cache.ts +0 -478
  41. package/src/scenario-recognizer.ts +0 -121
  42. package/src/types-mock.d.ts +0 -18
  43. package/src/types.ts +0 -66
  44. package/src/variable-extractor.ts +0 -204
package/dist/types.d.ts DELETED
@@ -1,62 +0,0 @@
1
- /**
2
- * Page Action Cache Types
3
- * 页面操作缓存类型定义
4
- */
5
- /**
6
- * 缓存操作类型
7
- */
8
- export type CacheActionType = 'navigate' | 'click' | 'screenshot' | 'type' | 'script';
9
- /**
10
- * 场景类型
11
- */
12
- export type ScenarioType = 'login' | 'search' | 'payment' | 'checkout' | 'general' | 'unknown';
13
- /**
14
- * 缓存条目
15
- */
16
- export interface CacheEntry {
17
- id: string;
18
- url: string;
19
- viewport?: string;
20
- actions: Array<{
21
- type: CacheActionType;
22
- params?: any;
23
- successCount: number;
24
- failCount: number;
25
- }>;
26
- scenario?: ScenarioType;
27
- timestamp: number;
28
- hitRate: number;
29
- savedActions: number;
30
- savedTime: number;
31
- }
32
- /**
33
- * 缓存统计
34
- */
35
- export interface CacheStats {
36
- totalEntries: number;
37
- totalActions: number;
38
- hitRate: number;
39
- savedActions: number;
40
- savedTime: number;
41
- }
42
- /**
43
- * 缓存配置
44
- */
45
- export interface PageActionCacheConfig {
46
- enabled: boolean;
47
- autoUseCache?: boolean;
48
- scenarioRecognitionEnabled?: boolean;
49
- llmClassificationThreshold?: number;
50
- cacheLevelStrategy?: 'auto' | 'l3-only' | 'l2-only' | 'l1-only';
51
- defaultCacheLevel?: 'L3' | 'L2' | 'L1';
52
- pageChangeDetectionEnabled?: boolean;
53
- changeInvalidationThreshold?: number;
54
- invalidationStrategy?: 'soft' | 'hard';
55
- variableExtractionEnabled?: boolean;
56
- allowUserConfirmVariables?: boolean;
57
- allowUserForcedRefresh?: boolean;
58
- enableUserCacheErrorReport?: boolean;
59
- trackExecutionStats?: boolean;
60
- statsUpdateInterval?: number;
61
- }
62
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAE/F;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,eAAe,CAAC;QACtB,MAAM,CAAC,EAAE,GAAG,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAChE,iBAAiB,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACvC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B"}
package/dist/types.js DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * Page Action Cache Types
3
- * 页面操作缓存类型定义
4
- */
5
- export {};
6
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -1,56 +0,0 @@
1
- /**
2
- * Variable Extractor - Page Action Cache
3
- * 变量提取器 - 从用户输入中提取动态变量
4
- */
5
- /**
6
- * 提取的变量
7
- */
8
- export interface ExtractedVariable {
9
- name: string;
10
- value: string;
11
- description: string;
12
- confidence: number;
13
- }
14
- /**
15
- * 变量提取结果
16
- */
17
- export interface ExtractionResult {
18
- variables: ExtractedVariable[];
19
- rawText: string;
20
- confidence: number;
21
- }
22
- /**
23
- * 变量提取器
24
- */
25
- export declare class VariableExtractor {
26
- private customRules;
27
- /**
28
- * 从文本中提取变量
29
- */
30
- extract(text: string): ExtractionResult;
31
- /**
32
- * 计算单个变量的置信度
33
- */
34
- private calculateConfidence;
35
- /**
36
- * 计算整体置信度
37
- */
38
- private calculateOverallConfidence;
39
- /**
40
- * 添加自定义变量规则
41
- */
42
- addCustomRule(name: string, pattern: RegExp, description: string): void;
43
- /**
44
- * 获取变量替换模板
45
- */
46
- getTemplate(variables: ExtractedVariable[]): string;
47
- /**
48
- * 验证变量值
49
- */
50
- validate(variableName: string, value: string): boolean;
51
- }
52
- /**
53
- * 单例导出
54
- */
55
- export declare const variableExtractor: VariableExtractor;
56
- //# sourceMappingURL=variable-extractor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"variable-extractor.d.ts","sourceRoot":"","sources":["../src/variable-extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmEH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,WAAW,CAAsB;IAEzC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB;IAkCvC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAWlC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAIvE;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM;IAUnD;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;CAMvD;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
@@ -1,159 +0,0 @@
1
- /**
2
- * Variable Extractor - Page Action Cache
3
- * 变量提取器 - 从用户输入中提取动态变量
4
- */
5
- /**
6
- * 常见变量规则
7
- */
8
- const VARIABLE_RULES = [
9
- {
10
- name: 'email',
11
- pattern: /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/g,
12
- description: '电子邮件地址'
13
- },
14
- {
15
- name: 'phone',
16
- pattern: /(\d{11}|\d{3}[-.\s]?\d{4}[-.\s]?\d{4}|\+?[\d\s-]{10,})/g,
17
- description: '电话号码'
18
- },
19
- {
20
- name: 'date',
21
- pattern: /(\d{4}[-/年]\d{1,2}[-/月]\d{1,2}日?|\d{1,2}[-/]\d{1,2}[-/]\d{4})/g,
22
- description: '日期'
23
- },
24
- {
25
- name: 'time',
26
- pattern: /(\d{1,2}:\d{2}(:\d{2})?)/g,
27
- description: '时间'
28
- },
29
- {
30
- name: 'number',
31
- pattern: /(\d+(?:,\d{3})*(?:\.\d+)?)/g,
32
- description: '数字'
33
- },
34
- {
35
- name: 'url',
36
- pattern: /(https?:\/\/[^\s<>"]+|www\.[^\s<>"]+)/g,
37
- description: '网址'
38
- },
39
- {
40
- name: 'amount',
41
- pattern: /(?:¥|\$|¥|€|£)?\s*(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:元|dollars?|euros?|pounds?)?/gi,
42
- description: '金额'
43
- },
44
- {
45
- name: 'username',
46
- pattern: /(?:用户名|username|user|account)\s*[::]?\s*([^\s,,]+)/gi,
47
- description: '用户名'
48
- },
49
- {
50
- name: 'password',
51
- pattern: /(?:密码|password|pwd)\s*[::]?\s*([^\s,,]+)/gi,
52
- description: '密码'
53
- },
54
- {
55
- name: 'product_name',
56
- pattern: /(?:商品|产品|product|item)\s*[::]?\s*([^\n,,]+)/gi,
57
- description: '商品名称'
58
- }
59
- ];
60
- /**
61
- * 变量提取器
62
- */
63
- export class VariableExtractor {
64
- customRules = [];
65
- /**
66
- * 从文本中提取变量
67
- */
68
- extract(text) {
69
- const variables = [];
70
- const seenValues = new Set();
71
- // 应用内置规则
72
- for (const rule of [...VARIABLE_RULES, ...this.customRules]) {
73
- const matches = text.matchAll(rule.pattern);
74
- for (const match of matches) {
75
- const value = match[1] || match[0];
76
- // 避免重复提取相同值
77
- const key = `${rule.name}:${value}`;
78
- if (seenValues.has(key)) {
79
- continue;
80
- }
81
- seenValues.add(key);
82
- variables.push({
83
- name: rule.name,
84
- value: value.trim(),
85
- description: rule.description,
86
- confidence: this.calculateConfidence(text, rule.pattern)
87
- });
88
- }
89
- }
90
- return {
91
- variables,
92
- rawText: text,
93
- confidence: this.calculateOverallConfidence(variables)
94
- };
95
- }
96
- /**
97
- * 计算单个变量的置信度
98
- */
99
- calculateConfidence(text, pattern) {
100
- const matches = text.match(pattern);
101
- if (!matches)
102
- return 0;
103
- // 匹配次数越多,置信度越高
104
- const matchCount = matches.length;
105
- let confidence = Math.min(matchCount * 0.3, 1.0);
106
- // 如果匹配的值周围有特定关键词,提高置信度
107
- const contextKeywords = ['填写', '输入', '请输入', 'enter', 'fill in', 'please'];
108
- for (const keyword of contextKeywords) {
109
- if (text.toLowerCase().includes(keyword.toLowerCase())) {
110
- confidence = Math.min(confidence + 0.2, 1.0);
111
- break;
112
- }
113
- }
114
- return confidence;
115
- }
116
- /**
117
- * 计算整体置信度
118
- */
119
- calculateOverallConfidence(variables) {
120
- if (variables.length === 0)
121
- return 0;
122
- const avgConfidence = variables.reduce((sum, v) => sum + v.confidence, 0) / variables.length;
123
- // 变量数量适中时置信度更高(避免过多或过少)
124
- const countFactor = variables.length >= 2 && variables.length <= 5 ? 1.0 : 0.8;
125
- return Math.min(avgConfidence * countFactor, 1.0);
126
- }
127
- /**
128
- * 添加自定义变量规则
129
- */
130
- addCustomRule(name, pattern, description) {
131
- this.customRules.push({ name, pattern, description });
132
- }
133
- /**
134
- * 获取变量替换模板
135
- */
136
- getTemplate(variables) {
137
- if (variables.length === 0)
138
- return '';
139
- let template = '';
140
- for (const v of variables) {
141
- template += `${v.description}: {{${v.name}}}\n`;
142
- }
143
- return template.trim();
144
- }
145
- /**
146
- * 验证变量值
147
- */
148
- validate(variableName, value) {
149
- const rule = [...VARIABLE_RULES, ...this.customRules].find(r => r.name === variableName);
150
- if (!rule)
151
- return false;
152
- return rule.pattern.test(value);
153
- }
154
- }
155
- /**
156
- * 单例导出
157
- */
158
- export const variableExtractor = new VariableExtractor();
159
- //# sourceMappingURL=variable-extractor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"variable-extractor.js","sourceRoot":"","sources":["../src/variable-extractor.ts"],"names":[],"mappings":"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"}
@@ -1,337 +0,0 @@
1
- /**
2
- * Browser Action Executor - Page Action Cache
3
- * 浏览器动作执行器 - 执行缓存的页面操作
4
- */
5
-
6
- import type { CacheActionType, CacheEntry } from './types.js';
7
-
8
- /**
9
- * 浏览器动作参数
10
- */
11
- interface BrowserActionParams {
12
- type: CacheActionType;
13
- params?: any;
14
- }
15
-
16
- /**
17
- * 执行结果
18
- */
19
- interface ExecutionResult {
20
- success: boolean;
21
- message: string;
22
- executedActions: number;
23
- skippedActions: number;
24
- failedActions: number;
25
- savedTime: number; // milliseconds
26
- error?: string;
27
- }
28
-
29
- /**
30
- * 浏览器客户端 API 接口
31
- */
32
- interface BrowserClientAPI {
33
- navigate(url: string): Promise<{ success: boolean; message: string }>;
34
- click(selector: string): Promise<{ success: boolean; message: string }>;
35
- type(selector: string, text: string): Promise<{ success: boolean; message: string }>;
36
- screenshot(path?: string): Promise<{ success: boolean; message: string }>;
37
- executeScript(script: string): Promise<{ success: boolean; message: string; result?: any }>;
38
- }
39
-
40
- /**
41
- * 浏览器动作执行器
42
- */
43
- export class BrowserActionExecutor {
44
- private browserClient: BrowserClientAPI | null = null;
45
-
46
- constructor() {
47
- this.initializeBrowserClient();
48
- }
49
-
50
- /**
51
- * 初始化浏览器客户端
52
- */
53
- private initializeBrowserClient(): void {
54
- try {
55
- // 尝试连接到 OpenClaw Browser Client
56
- // 这里使用 HTTP API 调用
57
- const baseURL = process.env.OPENCLAW_BROWSER_CLIENT_URL || 'http://localhost:3000';
58
-
59
- this.browserClient = {
60
- navigate: async (url: string) => {
61
- try {
62
- const response = await fetch(`${baseURL}/api/browser/navigate`, {
63
- method: 'POST',
64
- headers: { 'Content-Type': 'application/json' },
65
- body: JSON.stringify({ url })
66
- });
67
- const result: any = await response.json();
68
- return {
69
- success: result.success || false,
70
- message: result.message || 'Navigation completed'
71
- };
72
- } catch (error: any) {
73
- return {
74
- success: false,
75
- message: `Navigation failed: ${error.message}`
76
- };
77
- }
78
- },
79
- click: async (selector: string) => {
80
- try {
81
- const response = await fetch(`${baseURL}/api/browser/click`, {
82
- method: 'POST',
83
- headers: { 'Content-Type': 'application/json' },
84
- body: JSON.stringify({ selector })
85
- });
86
- const result: any = await response.json();
87
- return {
88
- success: result.success || false,
89
- message: result.message || 'Click completed'
90
- };
91
- } catch (error: any) {
92
- return {
93
- success: false,
94
- message: `Click failed: ${error.message}`
95
- };
96
- }
97
- },
98
- 'type': async (selector: string, text: string) => {
99
- try {
100
- const response = await fetch(`${baseURL}/api/browser/type`, {
101
- method: 'POST',
102
- headers: { 'Content-Type': 'application/json' },
103
- body: JSON.stringify({ selector, text })
104
- });
105
- const result: any = await response.json();
106
- return {
107
- success: result.success || false,
108
- message: result.message || 'Type completed'
109
- };
110
- } catch (error: any) {
111
- return {
112
- success: false,
113
- message: `Type failed: ${error.message}`
114
- };
115
- }
116
- },
117
- screenshot: async (path?: string) => {
118
- try {
119
- const response = await fetch(`${baseURL}/api/browser/screenshot`, {
120
- method: 'POST',
121
- headers: { 'Content-Type': 'application/json' },
122
- body: JSON.stringify({ path })
123
- });
124
- const result: any = await response.json();
125
- return {
126
- success: result.success || false,
127
- message: result.message || 'Screenshot saved'
128
- };
129
- } catch (error: any) {
130
- return {
131
- success: false,
132
- message: `Screenshot failed: ${error.message}`
133
- };
134
- }
135
- },
136
- executeScript: async (script: string) => {
137
- try {
138
- const response = await fetch(`${baseURL}/api/browser/execute-script`, {
139
- method: 'POST',
140
- headers: { 'Content-Type': 'application/json' },
141
- body: JSON.stringify({ script })
142
- });
143
- const result: any = await response.json();
144
- return {
145
- success: result.success || false,
146
- message: result.message || 'Script executed',
147
- result: result.result
148
- };
149
- } catch (error: any) {
150
- return {
151
- success: false,
152
- message: `Script execution failed: ${error.message}`
153
- };
154
- }
155
- }
156
- };
157
-
158
- console.log('[BrowserActionExecutor] Browser client initialized');
159
- } catch (error) {
160
- console.warn('[BrowserActionExecutor] Failed to initialize browser client:', error);
161
- this.browserClient = null;
162
- }
163
- }
164
-
165
- /**
166
- * 执行单个动作
167
- */
168
- private async executeAction(action: BrowserActionParams): Promise<{ success: boolean; message: string; savedTime: number }> {
169
- if (!this.browserClient) {
170
- return {
171
- success: false,
172
- message: 'Browser client not available',
173
- savedTime: 0
174
- };
175
- }
176
-
177
- const startTime = Date.now();
178
-
179
- try {
180
- let result;
181
-
182
- switch (action.type) {
183
- case 'navigate':
184
- if (!action.params?.url) {
185
- return { success: false, message: 'Missing URL parameter', savedTime: 0 };
186
- }
187
- result = await this.browserClient.navigate(action.params.url);
188
- break;
189
-
190
- case 'click':
191
- if (!action.params?.selector) {
192
- return { success: false, message: 'Missing selector parameter', savedTime: 0 };
193
- }
194
- result = await this.browserClient.click(action.params.selector);
195
- break;
196
-
197
- case 'type':
198
- if (!action.params?.selector || action.params?.text === undefined) {
199
- return { success: false, message: 'Missing selector or text parameter', savedTime: 0 };
200
- }
201
- result = await (this.browserClient as any)['type'](action.params.selector, action.params.text);
202
- break;
203
-
204
- case 'screenshot':
205
- result = await this.browserClient.screenshot(action.params?.path);
206
- break;
207
-
208
- case 'script':
209
- if (!action.params?.script) {
210
- return { success: false, message: 'Missing script parameter', savedTime: 0 };
211
- }
212
- result = await this.browserClient.executeScript(action.params.script);
213
- break;
214
-
215
- default:
216
- return {
217
- success: false,
218
- message: `Unknown action type: ${action.type}`,
219
- savedTime: 0
220
- };
221
- }
222
-
223
- const executionTime = Date.now() - startTime;
224
- // 假设每个动作平均可以节省 2 秒
225
- const estimatedTimeSaved = 2000;
226
- const savedTime = result.success ? Math.max(0, estimatedTimeSaved - executionTime) : 0;
227
-
228
- return {
229
- success: result.success,
230
- message: result.message,
231
- savedTime
232
- };
233
-
234
- } catch (error: any) {
235
- return {
236
- success: false,
237
- message: `Action execution error: ${error.message}`,
238
- savedTime: 0
239
- };
240
- }
241
- }
242
-
243
- /**
244
- * 执行缓存条目中的所有动作
245
- */
246
- async executeCacheEntry(entry: CacheEntry): Promise<ExecutionResult> {
247
- if (!entry.actions || entry.actions.length === 0) {
248
- return {
249
- success: true,
250
- message: 'No actions to execute',
251
- executedActions: 0,
252
- skippedActions: 0,
253
- failedActions: 0,
254
- savedTime: 0
255
- };
256
- }
257
-
258
- let executedActions = 0;
259
- let skippedActions = 0;
260
- let failedActions = 0;
261
- let totalSavedTime = 0;
262
- let hasError = false;
263
- let errorMessage = '';
264
-
265
- for (let i = 0; i < entry.actions.length; i++) {
266
- const action = entry.actions[i];
267
-
268
- // 跳过失败次数过多的动作
269
- const totalAttempts = action.successCount + action.failCount;
270
- if (totalAttempts > 0 && action.failCount / totalAttempts > 0.7) {
271
- skippedActions++;
272
- console.log(`[BrowserActionExecutor] Skipping action ${i + 1} (high failure rate): ${action.type}`);
273
- continue;
274
- }
275
-
276
- const result = await this.executeAction(action);
277
-
278
- if (result.success) {
279
- executedActions++;
280
- totalSavedTime += result.savedTime;
281
- console.log(`[BrowserActionExecutor] Executed action ${i + 1}: ${action.type} (${result.message})`);
282
- } else {
283
- failedActions++;
284
- hasError = true;
285
- errorMessage = result.message;
286
- console.error(`[BrowserActionExecutor] Failed action ${i + 1}: ${action.type} (${result.message})`);
287
- }
288
- }
289
-
290
- return {
291
- success: !hasError || failedActions < entry.actions.length / 2, // 允许部分失败
292
- message: hasError ? `Execution completed with ${failedActions} failures` : 'Execution completed successfully',
293
- executedActions,
294
- skippedActions,
295
- failedActions,
296
- savedTime: totalSavedTime,
297
- error: errorMessage
298
- };
299
- }
300
-
301
- /**
302
- * 检查浏览器客户端是否可用
303
- */
304
- isAvailable(): boolean {
305
- return this.browserClient !== null;
306
- }
307
-
308
- /**
309
- * 设置浏览器客户端(用于测试或自定义实现)
310
- */
311
- setBrowserClient(client: BrowserClientAPI): void {
312
- this.browserClient = client;
313
- }
314
-
315
- /**
316
- * 估算执行时间
317
- */
318
- estimateExecutionTime(actions: BrowserActionParams[]): number {
319
- // 估算每个动作的执行时间(毫秒)
320
- const timeEstimates: Record<CacheActionType, number> = {
321
- navigate: 3000, // 导航通常需要 3 秒
322
- click: 500, // 点击通常需要 0.5 秒
323
- type: 1000, // 输入通常需要 1 秒
324
- screenshot: 1500, // 截图通常需要 1.5 秒
325
- script: 500 // 脚本执行通常需要 0.5 秒
326
- };
327
-
328
- return actions.reduce((total, action) => {
329
- return total + (timeEstimates[action.type] || 500);
330
- }, 0);
331
- }
332
- }
333
-
334
- /**
335
- * 单例导出
336
- */
337
- export const browserActionExecutor = new BrowserActionExecutor();