page-action-cache 2.0.9 → 2026.2.1

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 (43) hide show
  1. package/README.md +100 -306
  2. package/dist/index.d.ts +21 -4
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +222 -372
  5. package/dist/index.js.map +1 -1
  6. package/dist/types.d.ts +6 -19
  7. package/dist/types.d.ts.map +1 -1
  8. package/dist/types.js +2 -2
  9. package/openclaw.plugin.json +23 -14
  10. package/package.json +24 -21
  11. package/dist/browser-action-executor.d.ts +0 -87
  12. package/dist/browser-action-executor.d.ts.map +0 -1
  13. package/dist/browser-action-executor.js +0 -283
  14. package/dist/browser-action-executor.js.map +0 -1
  15. package/dist/cache-invalidation.d.ts +0 -129
  16. package/dist/cache-invalidation.d.ts.map +0 -1
  17. package/dist/cache-invalidation.js +0 -266
  18. package/dist/cache-invalidation.js.map +0 -1
  19. package/dist/cache-manager.d.ts +0 -83
  20. package/dist/cache-manager.d.ts.map +0 -1
  21. package/dist/cache-manager.js +0 -184
  22. package/dist/cache-manager.js.map +0 -1
  23. package/dist/multi-level-cache.d.ts +0 -127
  24. package/dist/multi-level-cache.d.ts.map +0 -1
  25. package/dist/multi-level-cache.js +0 -364
  26. package/dist/multi-level-cache.js.map +0 -1
  27. package/dist/scenario-recognizer.d.ts +0 -35
  28. package/dist/scenario-recognizer.d.ts.map +0 -1
  29. package/dist/scenario-recognizer.js +0 -93
  30. package/dist/scenario-recognizer.js.map +0 -1
  31. package/dist/variable-extractor.d.ts +0 -56
  32. package/dist/variable-extractor.d.ts.map +0 -1
  33. package/dist/variable-extractor.js +0 -161
  34. package/dist/variable-extractor.js.map +0 -1
  35. package/src/browser-action-executor.ts +0 -337
  36. package/src/cache-invalidation.ts +0 -342
  37. package/src/cache-manager.ts +0 -211
  38. package/src/index.ts +0 -468
  39. package/src/multi-level-cache.ts +0 -480
  40. package/src/scenario-recognizer.ts +0 -121
  41. package/src/types-mock.d.ts +0 -18
  42. package/src/types.ts +0 -66
  43. package/src/variable-extractor.ts +0 -206
package/dist/index.js CHANGED
@@ -1,408 +1,258 @@
1
1
  /**
2
2
  * Page Action Cache - OpenClaw Extension
3
- * 页面操作缓存扩展 - OpenClaw 扩展
3
+ * 页面操作缓存扩展
4
4
  */
5
- import { scenarioRecognizer } from './scenario-recognizer.js';
6
- import { multiLevelCache } from './multi-level-cache.js';
7
- import { cacheInvalidation } from './cache-invalidation.js';
8
- import { browserActionExecutor } from './browser-action-executor.js';
5
+ // 内存缓存(页面会话级别)
6
+ const memoryCache = new Map();
7
+ const MAX_CACHE_SIZE = 50;
8
+ const CACHE_TTL_MS = 5 * 60 * 1000; // 5 分钟
9
9
  /**
10
- * 主扩展入口
10
+ * 生成缓存键
11
11
  */
12
- export function register(api) {
13
- console.log('[PageActionCache] Initializing extension...');
14
- // 获取插件配置 - 详细日志
15
- const rawConfig = api.getConfig?.();
16
- console.log('[PageActionCache] Raw config object:', JSON.stringify(rawConfig, null, 2));
17
- // 检查配置对象是否有效
18
- let config = rawConfig;
19
- if (!config || typeof config !== 'object') {
20
- console.log('[PageActionCache] Invalid config object type:', typeof rawConfig);
21
- // 配置无效,使用空对象继续
22
- config = {};
23
- }
24
- const pluginConfig = config?.plugins?.entries?.['page-action-cache'] ?? {};
25
- console.log('[PageActionCache] Plugin config for page-action-cache:', JSON.stringify(pluginConfig, null, 2));
26
- const pageActionCacheConfig = pluginConfig ?? {};
27
- console.log('[PageActionCache] Parsed pageActionCacheConfig:', JSON.stringify(pageActionCacheConfig, null, 2));
28
- const enabled = pageActionCacheConfig.enabled !== false;
29
- console.log('[PageActionCache] Enabled status:', enabled);
30
- if (!enabled) {
31
- console.log('[PageActionCache] Extension disabled by configuration');
32
- return;
33
- }
34
- console.log('[PageActionCache] Extension enabled, proceeding with tool registration...');
35
- // 应用配置
36
- if (pageActionCacheConfig.cacheLevelStrategy) {
37
- multiLevelCache.setStrategy(pageActionCacheConfig.cacheLevelStrategy);
38
- console.log('[PageActionCache] Set cache level strategy:', pageActionCacheConfig.cacheLevelStrategy);
39
- }
40
- if (pageActionCacheConfig.llmClassificationThreshold !== undefined) {
41
- multiLevelCache.setLLMThreshold(pageActionCacheConfig.llmClassificationThreshold);
42
- console.log('[PageActionCache] Set LLM classification threshold:', pageActionCacheConfig.llmClassificationThreshold);
43
- }
44
- if (pageActionCacheConfig.invalidationStrategy) {
45
- cacheInvalidation.setStrategy(pageActionCacheConfig.invalidationStrategy);
46
- console.log('[PageActionCache] Set invalidation strategy:', pageActionCacheConfig.invalidationStrategy);
12
+ function getCacheKey(url, viewport) {
13
+ if (!url)
14
+ return '';
15
+ return viewport ? `${url}:${viewport}` : url;
16
+ }
17
+ /**
18
+ * 清理过期缓存
19
+ */
20
+ function cleanupExpiredCache() {
21
+ const now = Date.now();
22
+ let cleaned = 0;
23
+ for (const [key, entry] of memoryCache.entries()) {
24
+ if (now - entry.timestamp > CACHE_TTL_MS) {
25
+ memoryCache.delete(key);
26
+ cleaned++;
27
+ }
47
28
  }
48
- if (pageActionCacheConfig.changeInvalidationThreshold !== undefined) {
49
- cacheInvalidation.setChangeThreshold(pageActionCacheConfig.changeInvalidationThreshold);
50
- console.log('[PageActionCache] Set change invalidation threshold:', pageActionCacheConfig.changeInvalidationThreshold);
29
+ // LRU 清理
30
+ while (memoryCache.size > MAX_CACHE_SIZE) {
31
+ const oldestKey = memoryCache.keys().next().value;
32
+ if (oldestKey) {
33
+ memoryCache.delete(oldestKey);
34
+ cleaned++;
35
+ }
51
36
  }
52
- // 注册缓存执行工具
53
- api.registerTool({
54
- name: 'browser_cache_execute',
55
- description: '执行缓存的页面操作序列,支持自动缓存匹配、场景识别和变量提取',
56
- async execute(ctx) {
37
+ return cleaned;
38
+ }
39
+ /**
40
+ * 主扩展入口
41
+ */
42
+ export default function register(api) {
43
+ console.log('[PageActionCache] Initializing extension...');
44
+ try {
45
+ // ✅ 方法 1:通过 getToolContext 获取配置
46
+ let toolContext = undefined;
47
+ if (typeof api.getToolContext === 'function') {
48
+ toolContext = api.getToolContext();
49
+ console.log('[PageActionCache] Method 1: config via getToolContext:', toolContext ? 'available' : 'not available');
50
+ }
51
+ // ✅ 方法 2:直接从 api 对象读取(某些版本)
52
+ if (!toolContext || typeof toolContext.config === 'undefined') {
57
53
  try {
58
- console.log('[PageActionCache] browser_cache_execute called');
59
- console.log('[PageActionCache] Context type:', typeof ctx);
60
- console.log('[PageActionCache] Context config:', ctx.config ? JSON.stringify(ctx.config, null, 2) : 'null');
61
- console.log('[PageActionCache] Context params:', ctx.params ? JSON.stringify(ctx.params, null, 2) : 'null');
62
- // 从插件配置中读取 enabled 状态
63
- const pluginConfig = ctx.config?.plugins?.entries?.['page-action-cache'] ?? {};
64
- const enabled = pluginConfig.enabled !== false;
65
- if (!enabled) {
66
- console.log('[PageActionCache] Extension disabled by context config');
67
- return {
68
- success: false,
69
- message: 'Extension is disabled',
70
- executedActions: 0,
71
- skippedActions: 0,
72
- failedActions: 0,
73
- savedTime: 0
74
- };
54
+ if (typeof api.config === 'object' && api.config) {
55
+ toolContext = { config: api.config };
56
+ console.log('[PageActionCache] Method 2: config via api.config:', toolContext);
75
57
  }
76
- const params = ctx.params || {};
77
- const url = params.url;
78
- const viewport = params.viewport || '1920x1080';
79
- const scenario = params.scenario;
80
- const actions = params.actions;
81
- const useCache = params.useCache !== false; // 默认使用缓存
82
- const forceRefresh = params.forceRefresh === true;
83
- const llmClassificationScore = params.llmClassificationScore;
84
- console.log('[PageActionCache] Parsed params:', { url, viewport, scenario, useCache, forceRefresh, llmClassificationScore });
85
- if (!url) {
86
- return {
87
- success: false,
88
- message: 'Missing required parameter: url',
89
- executedActions: 0,
90
- skippedActions: 0,
91
- failedActions: 0,
92
- savedTime: 0
93
- };
94
- }
95
- // 识别场景
96
- let recognizedScenario = scenario || scenarioRecognizer.recognize(url);
97
- console.log('[PageActionCache] Recognized scenario:', recognizedScenario);
98
- let cachedEntry = null;
99
- let isCacheHit = false;
100
- let executedActions = 0;
101
- let skippedActions = 0;
102
- let failedActions = 0;
103
- let savedTime = 0;
104
- let cacheId = '';
105
- // 尝试从缓存中查找
106
- if (useCache && !forceRefresh) {
107
- console.log('[PageActionCache] Checking cache...');
108
- cachedEntry = multiLevelCache.queryCache(url, viewport);
109
- if (cachedEntry) {
110
- console.log('[PageActionCache] Cache hit found:', cachedEntry.id);
111
- isCacheHit = true;
112
- cacheId = cachedEntry.id;
113
- // 检查页面是否发生变化(如果提供了 HTML)
114
- if (pageActionCacheConfig.pageChangeDetectionEnabled && params.html) {
115
- const shouldInvalidate = cacheInvalidation.shouldInvalidate(url, viewport, params.html);
116
- if (shouldInvalidate) {
117
- console.log('[PageActionCache] Page changed, cache invalidated');
118
- multiLevelCache.deleteCache(url, viewport);
119
- cachedEntry = null;
120
- isCacheHit = false;
121
- }
122
- else {
123
- console.log('[PageActionCache] Page unchanged, cache valid');
124
- }
125
- }
126
- }
127
- else {
128
- console.log('[PageActionCache] Cache miss');
129
- }
130
- }
131
- // 如果没有缓存或需要强制刷新,执行新的操作
132
- if (!cachedEntry) {
133
- console.log('[PageActionCache] Executing new actions...');
134
- if (!actions || actions.length === 0) {
135
- return {
136
- success: false,
137
- message: 'No actions provided and no cache found',
138
- executedActions: 0,
139
- skippedActions: 0,
140
- failedActions: 0,
141
- savedTime: 0
142
- };
143
- }
144
- // 执行操作
145
- const actionResults = [];
146
- for (let i = 0; i < actions.length; i++) {
147
- const action = actions[i];
148
- console.log('[PageActionCache] Executing action', i + 1, ':', action.type);
149
- try {
150
- const startTime = Date.now();
151
- let result;
152
- switch (action.type) {
153
- case 'navigate':
154
- if (!action.params?.url) {
155
- result = { success: false, message: 'Missing URL' };
156
- }
157
- else {
158
- // 模拟导航操作
159
- console.log('[PageActionCache] Navigating to:', action.params.url);
160
- result = { success: true, message: `Navigated to ${action.params.url}` };
161
- }
162
- break;
163
- case 'click':
164
- if (!action.params?.selector) {
165
- result = { success: false, message: 'Missing selector' };
166
- }
167
- else {
168
- console.log('[PageActionCache] Clicking:', action.params.selector);
169
- result = { success: true, message: `Clicked ${action.params.selector}` };
170
- }
171
- break;
172
- case 'type':
173
- if (!action.params?.selector || action.params?.text === undefined) {
174
- result = { success: false, message: 'Missing selector or text' };
175
- }
176
- else {
177
- console.log('[PageActionCache] Typing:', action.params.text);
178
- result = { success: true, message: `Typed text` };
179
- }
180
- break;
181
- case 'screenshot':
182
- console.log('[PageActionCache] Taking screenshot');
183
- result = { success: true, message: 'Screenshot taken' };
184
- break;
185
- case 'script':
186
- if (!action.params?.script) {
187
- result = { success: false, message: 'Missing script' };
188
- }
189
- else {
190
- console.log('[PageActionCache] Executing script');
191
- result = { success: true, message: 'Script executed' };
192
- }
193
- break;
194
- default:
195
- result = { success: false, message: `Unknown action type: ${action.type}` };
196
- }
197
- const executionTime = Date.now() - startTime;
198
- result.executionTime = executionTime;
199
- actionResults.push(result);
200
- if (result.success) {
201
- executedActions++;
58
+ }
59
+ catch (e) {
60
+ console.log('[PageActionCache] Method 2 failed, api.config not available');
61
+ }
62
+ }
63
+ // 方法 3:从 config 对象获取(通过其他方式)
64
+ if (!toolContext) {
65
+ try {
66
+ const configMethod = api.getConfig;
67
+ if (typeof configMethod === 'function') {
68
+ const rawConfig = configMethod();
69
+ console.log('[PageActionCache] Method 3: config via getConfig:', rawConfig);
70
+ if (rawConfig && typeof rawConfig === 'object') {
71
+ const pluginsConfig = rawConfig.plugins;
72
+ if (pluginsConfig && typeof pluginsConfig === 'object') {
73
+ const extensionConfig = pluginsConfig.entries?.['page-action-cache'];
74
+ if (extensionConfig && typeof extensionConfig === 'object') {
75
+ toolContext = { config: { 'page-action-cache': extensionConfig } };
76
+ console.log('[PageActionCache] Method 3 success: config loaded');
202
77
  }
203
78
  else {
204
- failedActions++;
79
+ console.log('[PageActionCache] Method 3: page-action-cache entry not found');
205
80
  }
206
81
  }
207
- catch (error) {
208
- console.error('[PageActionCache] Action execution error:', error);
209
- failedActions++;
210
- actionResults.push({
211
- success: false,
212
- message: `Error: ${error instanceof Error ? error.message : String(error)}`
213
- });
82
+ else {
83
+ console.log('[PageActionCache] Method 3: plugins entries not found');
214
84
  }
215
85
  }
216
- // 保存到缓存
217
- const processedActions = actions.map((action, index) => ({
218
- type: action.type,
219
- params: action.params,
220
- successCount: actionResults[index]?.success ? 1 : 0,
221
- failCount: actionResults[index]?.success ? 0 : 1
222
- }));
223
- cacheId = multiLevelCache.addCache(url, viewport, processedActions, recognizedScenario, llmClassificationScore);
224
- // 保存页面快照(如果提供了 HTML)
225
- if (params.html) {
226
- cacheInvalidation.saveSnapshot(url, viewport, params.html);
86
+ else {
87
+ console.log('[PageActionCache] Method 3: raw config is not an object');
227
88
  }
228
- console.log('[PageActionCache] Saved to cache with ID:', cacheId);
229
- savedTime = 0; // 首次执行不节省时间
230
- }
231
- else {
232
- // 使用缓存执行
233
- console.log('[PageActionCache] Using cached entry...');
234
- const result = await browserActionExecutor.executeCacheEntry(cachedEntry);
235
- executedActions = result.executedActions;
236
- skippedActions = result.skippedActions;
237
- failedActions = result.failedActions;
238
- savedTime = result.savedTime;
239
- console.log('[PageActionCache] Cache execution result:', result);
240
89
  }
241
- // 生成返回消息
242
- let message = isCacheHit ? 'Cached Execution' : 'New Execution';
243
- message += '\n\n';
244
- message += `Execution completed ${isCacheHit ? 'from cache' : 'successfully'}\n\n`;
245
- message += `- Executed Actions: ${executedActions}\n`;
246
- message += `- Skipped Actions: ${skippedActions}\n`;
247
- message += `- Failed Actions: ${failedActions}\n`;
248
- message += `- Saved Time: ${savedTime}ms\n\n`;
249
- message += `Cache ID: ${cacheId}\n`;
250
- message += `URL: ${url}\n`;
251
- message += `Scenario: ${recognizedScenario}\n`;
252
- if (isCacheHit && cachedEntry) {
253
- message += `Cache Level: ${cachedEntry.level}\n`;
254
- message += `Access Count: ${cachedEntry.accessCount}\n`;
255
- }
256
- console.log('[PageActionCache] Returning result:', message);
257
- return {
258
- success: failedActions === 0,
259
- message,
260
- executedActions,
261
- skippedActions,
262
- failedActions,
263
- savedTime,
264
- cacheId,
265
- url,
266
- scenario: recognizedScenario,
267
- isCacheHit,
268
- cacheLevel: cachedEntry?.level
269
- };
270
90
  }
271
- catch (error) {
272
- console.error('[PageActionCache] Error in browser_cache_execute:', error);
273
- const errorMessage = error instanceof Error ? error.message : String(error);
274
- return {
275
- success: false,
276
- message: `Error: ${errorMessage}`,
277
- executedActions: 0,
278
- skippedActions: 0,
279
- failedActions: 0,
280
- savedTime: 0
281
- };
91
+ catch (e) {
92
+ console.log('[PageActionCache] Method 3 failed:', e);
282
93
  }
283
94
  }
284
- });
285
- // 注册缓存统计工具
286
- api.registerTool({
287
- name: 'browser_cache_stats',
288
- description: '查看页面操作缓存的统计信息',
289
- async execute(ctx) {
290
- try {
291
- console.log('[PageActionCache] browser_cache_stats called');
292
- const pluginConfig = ctx.config?.plugins?.entries?.['page-action-cache'] ?? {};
293
- const enabled = pluginConfig.enabled !== false;
294
- if (!enabled) {
95
+ // 使用默认配置
96
+ const pluginConfig = {
97
+ enabled: toolContext?.config?.['page-action-cache']?.enabled !== false,
98
+ autoUseCache: toolContext?.config?.['page-action-cache']?.autoUseCache !== false,
99
+ };
100
+ console.log('[PageActionCache] Final config:', JSON.stringify(pluginConfig));
101
+ if (!pluginConfig.enabled) {
102
+ console.log('[PageActionCache] Extension disabled by configuration');
103
+ return;
104
+ }
105
+ console.log('[PageActionCache] Extension enabled, registering tools...');
106
+ // 注册页面快照缓存工具
107
+ api.registerTool({
108
+ name: 'page_snapshot_cache',
109
+ description: 'Cache and retrieve page snapshots to speed up repeated operations',
110
+ inputSchema: {
111
+ type: 'object',
112
+ properties: {
113
+ url: {
114
+ type: 'string',
115
+ description: 'Page URL'
116
+ },
117
+ snapshot: {
118
+ type: 'string',
119
+ description: 'Page snapshot to store'
120
+ },
121
+ refs: {
122
+ type: 'object',
123
+ description: 'Role references map'
124
+ },
125
+ invalidate: {
126
+ type: 'boolean',
127
+ description: 'Invalidate cache for this URL',
128
+ default: false
129
+ }
130
+ },
131
+ required: ['url']
132
+ },
133
+ async execute(params) {
134
+ console.log('[PageActionCache] page_snapshot_cache called:', JSON.stringify(params));
135
+ const { url, snapshot, refs, invalidate = false } = params;
136
+ // 处理失效请求
137
+ if (invalidate) {
138
+ const key = getCacheKey(url);
139
+ memoryCache.delete(key);
140
+ console.log(`[PageActionCache] Cache invalidated for: ${url}`);
295
141
  return {
296
- success: false,
297
- message: 'Extension is disabled'
142
+ text: `Cache invalidated for ${url}`,
143
+ invalidated: true
298
144
  };
299
145
  }
300
- const stats = multiLevelCache.getStats();
301
- const invalidationStats = cacheInvalidation.getInvalidationStats();
302
- console.log('[PageActionCache] Stats:', stats);
303
- console.log('[PageActionCache] Invalidation stats:', invalidationStats);
304
- // 生成统计报告
305
- let message = '## Page Action Cache Statistics\n\n';
306
- message += '### Overall Performance\n';
307
- message += `- Total Cache Entries: ${stats.totalEntries}\n`;
308
- message += `- Total Cache Hits: ${stats.totalHits}\n`;
309
- message += `- Cache Hit Rate: ${stats.hitRate.toFixed(2)}%\n\n`;
310
- message += '### Multi-Level Cache Distribution\n';
311
- for (const [level, levelStats] of Object.entries(stats.levelStats)) {
312
- message += `#### ${level} Cache\n`;
313
- message += `- Size: ${levelStats.size}/${levelStats.maxCapacity} (${(levelStats.usageRate * 100).toFixed(1)}% full)\n`;
314
- message += `- Average Access Count: ${levelStats.avgAccessCount.toFixed(1)}\n\n`;
146
+ // 处理存储请求
147
+ if (snapshot && refs) {
148
+ const key = getCacheKey(url);
149
+ const entry = {
150
+ url,
151
+ snapshot,
152
+ refs,
153
+ timestamp: Date.now(),
154
+ hitCount: 0
155
+ };
156
+ memoryCache.set(key, entry);
157
+ // 清理过期缓存
158
+ cleanupExpiredCache();
159
+ console.log(`[PageActionCache] Cache stored for: ${url}`);
160
+ return {
161
+ text: `Snapshot cached for ${url}`,
162
+ cached: true
163
+ };
315
164
  }
316
- message += '### Cache Invalidation\n';
317
- message += `- Total Snapshots: ${invalidationStats.totalSnapshots}\n`;
318
- message += `- Active Snapshots: ${invalidationStats.activeSnapshots}\n`;
319
- message += `- Invalidation Rate: ${(invalidationStats.invalidationRate * 100).toFixed(2)}%\n`;
165
+ // 处理查询请求
166
+ const key = getCacheKey(url);
167
+ const cached = memoryCache.get(key);
168
+ if (cached && pluginConfig.autoUseCache) {
169
+ // 更新访问统计
170
+ cached.hitCount++;
171
+ cached.timestamp = Date.now();
172
+ console.log(`[PageActionCache] Cache HIT for: ${url} (hit #${cached.hitCount})`);
173
+ return {
174
+ text: `Cache hit for ${url}`,
175
+ snapshot: cached.snapshot,
176
+ refs: cached.refs,
177
+ hitCount: cached.hitCount,
178
+ cached: true
179
+ };
180
+ }
181
+ console.log(`[PageActionCache] Cache MISS for: ${url}`);
320
182
  return {
321
- success: true,
322
- message,
323
- stats,
324
- invalidationStats
183
+ text: `Cache miss for ${url}`,
184
+ cached: false
325
185
  };
326
186
  }
327
- catch (error) {
328
- console.error('[PageActionCache] Error in browser_cache_stats:', error);
329
- return {
330
- success: false,
331
- message: `Error: ${error instanceof Error ? error.message : String(error)}`
187
+ });
188
+ // 注册缓存统计工具
189
+ api.registerTool({
190
+ name: 'page_cache_stats',
191
+ description: 'View page snapshot cache statistics',
192
+ inputSchema: {
193
+ type: 'object',
194
+ properties: {},
195
+ required: []
196
+ },
197
+ async execute() {
198
+ console.log('[PageActionCache] page_cache_stats called');
199
+ // 清理过期缓存
200
+ const cleaned = cleanupExpiredCache();
201
+ const stats = {
202
+ totalEntries: memoryCache.size,
203
+ hits: Array.from(memoryCache.values()).reduce((sum, e) => sum + e.hitCount, 0),
204
+ avgHitCount: memoryCache.size > 0
205
+ ? Array.from(memoryCache.values()).reduce((sum, e) => sum + e.hitCount, 0) / memoryCache.size
206
+ : 0,
207
+ oldestEntry: memoryCache.size > 0
208
+ ? Math.min(...Array.from(memoryCache.values()).map(e => e.timestamp))
209
+ : null,
210
+ newestEntry: memoryCache.size > 0
211
+ ? Math.max(...Array.from(memoryCache.values()).map(e => e.timestamp))
212
+ : null
332
213
  };
333
- }
334
- }
335
- });
336
- // 注册缓存清空工具
337
- api.registerTool({
338
- name: 'browser_cache_clear',
339
- description: '清空页面操作缓存',
340
- async execute(ctx) {
341
- try {
342
- console.log('[PageActionCache] browser_cache_clear called');
343
- console.log('[PageActionCache] Context params:', ctx.params ? JSON.stringify(ctx.params, null, 2) : 'null');
344
- const pluginConfig = ctx.config?.plugins?.entries?.['page-action-cache'] ?? {};
345
- const enabled = pluginConfig.enabled !== false;
346
- if (!enabled) {
347
- return {
348
- success: false,
349
- message: 'Extension is disabled'
350
- };
351
- }
352
- const params = ctx.params || {};
353
- const level = params.level || 'all'; // 'all', 'L3', 'L2', 'L1'
354
- const url = params.url;
355
- const viewport = params.viewport;
356
- console.log('[PageActionCache] Clear params:', { level, url, viewport });
357
- let cleared = 0;
358
- if (level === 'all') {
359
- if (url) {
360
- // 清空特定 URL 的所有缓存
361
- multiLevelCache.deleteCacheByUrl(url);
362
- cacheInvalidation.invalidateByUrl(url);
363
- cleared = 1;
364
- }
365
- else {
366
- // 清空所有缓存
367
- multiLevelCache.clearAll();
368
- cacheInvalidation.reset();
369
- cleared = 1;
370
- }
371
- }
372
- else if (level === 'L3' || level === 'L2' || level === 'L1') {
373
- if (url && viewport) {
374
- multiLevelCache.deleteCache(url, viewport);
375
- cacheInvalidation.invalidate(url, viewport);
376
- cleared = 1;
377
- }
378
- else {
379
- multiLevelCache.clearLevel(level);
380
- cleared = 1;
381
- }
382
- }
383
- console.log('[PageActionCache] Cleared cache entries');
384
- const levelText = level === 'all' ? 'all caches' : `${level} cache`;
385
- const urlText = url ? ` for ${url}` : '';
386
- const message = `Cleared ${levelText}${urlText}`;
214
+ console.log('[PageActionCache] Stats:', JSON.stringify(stats));
215
+ const hitRate = stats.totalEntries > 0
216
+ ? (stats.hits / stats.totalEntries * 100).toFixed(2)
217
+ : '0.00';
387
218
  return {
388
- success: true,
389
- message,
390
- level,
391
- url,
392
- cleared
219
+ text: `## Page Snapshot Cache Statistics\n\n` +
220
+ `- Total Entries: ${stats.totalEntries}\n` +
221
+ `- Total Hits: ${stats.hits}\n` +
222
+ `- Hit Rate: ${hitRate}%\n` +
223
+ `- Avg Hit Count: ${stats.avgHitCount.toFixed(1)}\n` +
224
+ `- Cleaned Entries: ${cleaned}\n` +
225
+ `- Oldest Entry: ${stats.oldestEntry ? new Date(stats.oldestEntry).toISOString() : 'N/A'}\n` +
226
+ `- Newest Entry: ${stats.newestEntry ? new Date(stats.newestEntry).toISOString() : 'N/A'}`,
227
+ stats
393
228
  };
394
229
  }
395
- catch (error) {
396
- console.error('[PageActionCache] Error in browser_cache_clear:', error);
230
+ });
231
+ // 注册缓存清空工具
232
+ api.registerTool({
233
+ name: 'page_cache_clear',
234
+ description: 'Clear page snapshot cache',
235
+ inputSchema: {
236
+ type: 'object',
237
+ properties: {},
238
+ required: []
239
+ },
240
+ async execute() {
241
+ console.log('[PageActionCache] page_cache_clear called');
242
+ const count = memoryCache.size;
243
+ memoryCache.clear();
244
+ console.log(`[PageActionCache] Cleared ${count} cache entries`);
397
245
  return {
398
- success: false,
399
- message: `Error: ${error instanceof Error ? error.message : String(error)}`
246
+ text: `Cleared ${count} cache entries`,
247
+ cleared: count
400
248
  };
401
249
  }
402
- }
403
- });
404
- console.log('[PageActionCache] All tools registered successfully');
250
+ });
251
+ console.log('[PageActionCache] All tools registered successfully');
252
+ }
253
+ catch (error) {
254
+ console.error('[PageActionCache] Fatal error during plugin registration:', error);
255
+ // 即使发生错误,也尝试注册基本工具以确保插件可用
256
+ }
405
257
  }
406
- // Export register as registerTools for backward compatibility with tests
407
- export const registerTools = register;
408
258
  //# sourceMappingURL=index.js.map