page-action-cache 2026.2.6 → 2026.2.7
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.
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -194
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -9,17 +9,6 @@ interface OpenClawPluginApi {
|
|
|
9
9
|
inputSchema: unknown;
|
|
10
10
|
execute: (params: unknown) => Promise<unknown>;
|
|
11
11
|
}): void;
|
|
12
|
-
registerHook(hookName: string, handler: (event: unknown) => Promise<unknown>): void;
|
|
13
|
-
getToolContext?: () => {
|
|
14
|
-
config?: Record<string, unknown>;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* 插件配置接口
|
|
19
|
-
*/
|
|
20
|
-
export interface PageActionCacheConfig {
|
|
21
|
-
enabled: boolean;
|
|
22
|
-
autoUseCache?: boolean;
|
|
23
12
|
}
|
|
24
13
|
/**
|
|
25
14
|
* 主扩展入口
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,UAAU,iBAAiB;IACzB,YAAY,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,OAAO,CAAC;QACrB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAChD,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,UAAU,iBAAiB;IACzB,YAAY,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,OAAO,CAAC;QACrB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAChD,GAAG,IAAI,CAAC;CACV;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA0C7D"}
|
package/dist/index.js
CHANGED
|
@@ -2,43 +2,6 @@
|
|
|
2
2
|
* Page Action Cache - OpenClaw Extension
|
|
3
3
|
* 页面操作缓存扩展
|
|
4
4
|
*/
|
|
5
|
-
// 内存缓存(页面会话级别)
|
|
6
|
-
const memoryCache = new Map();
|
|
7
|
-
const MAX_CACHE_SIZE = 50;
|
|
8
|
-
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 分钟
|
|
9
|
-
/**
|
|
10
|
-
* 生成缓存键
|
|
11
|
-
*/
|
|
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
|
-
}
|
|
28
|
-
}
|
|
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
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return cleaned;
|
|
38
|
-
}
|
|
39
|
-
function logDivider() {
|
|
40
|
-
console.log('[PageActionCache] =======================================');
|
|
41
|
-
}
|
|
42
5
|
/**
|
|
43
6
|
* 主扩展入口
|
|
44
7
|
*/
|
|
@@ -47,104 +10,7 @@ export default function register(api) {
|
|
|
47
10
|
console.log('[PageActionCache] 🚀 Initializing Page Action Cache Extension...');
|
|
48
11
|
console.log('========================================');
|
|
49
12
|
try {
|
|
50
|
-
|
|
51
|
-
let toolContext = undefined;
|
|
52
|
-
if (typeof api.getToolContext === 'function') {
|
|
53
|
-
toolContext = api.getToolContext();
|
|
54
|
-
console.log('[PageActionCache] Method 1: config via getToolContext:', toolContext ? 'available' : 'not available');
|
|
55
|
-
}
|
|
56
|
-
if (!toolContext || typeof toolContext.config === 'undefined') {
|
|
57
|
-
try {
|
|
58
|
-
if (typeof api.config === 'object' && api.config) {
|
|
59
|
-
toolContext = { config: api.config };
|
|
60
|
-
console.log('[PageActionCache] Method 2: config via api.config:', toolContext);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch (e) {
|
|
64
|
-
console.log('[PageActionCache] Method 2 failed, api.config not available');
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
const pluginConfig = {
|
|
68
|
-
enabled: toolContext?.config?.['page-action-cache']?.enabled !== false,
|
|
69
|
-
autoUseCache: toolContext?.config?.['page-action-cache']?.autoUseCache !== false,
|
|
70
|
-
};
|
|
71
|
-
console.log('[PageActionCache] Final config:', JSON.stringify(pluginConfig));
|
|
72
|
-
console.log('[PageActionCache] - enabled:', pluginConfig.enabled);
|
|
73
|
-
console.log('[PageActionCache] - autoUseCache:', pluginConfig.autoUseCache);
|
|
74
|
-
if (!pluginConfig.enabled) {
|
|
75
|
-
console.log('[PageActionCache] 🚫 Extension disabled by configuration');
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
console.log('[PageActionCache] ✅ Extension enabled, registering hooks and tools...');
|
|
79
|
-
console.log('[PageActionCache] 📊 Cache settings: max=50, ttl=5min');
|
|
80
|
-
// === 存缓存:After Tool Call Hook ===
|
|
81
|
-
api.registerHook('after_tool_call', async (event) => {
|
|
82
|
-
const { toolName, result, params } = event;
|
|
83
|
-
console.log('[PageActionCache] 🔍 after_tool_call hook triggered');
|
|
84
|
-
console.log(`[PageActionCache] 📌 Tool name: ${toolName}`);
|
|
85
|
-
if (toolName === 'browser_snapshot') {
|
|
86
|
-
const url = params?.url;
|
|
87
|
-
const viewport = params?.viewport;
|
|
88
|
-
const snapshot = result?.snapshot;
|
|
89
|
-
const refs = result?.refs;
|
|
90
|
-
if (!url)
|
|
91
|
-
return;
|
|
92
|
-
const key = getCacheKey(url, viewport);
|
|
93
|
-
const existing = memoryCache.get(key);
|
|
94
|
-
console.log(`[PageActionCache] 📦 Current cache size: ${memoryCache.size}`);
|
|
95
|
-
console.log(`[PageActionCache] 🔑 Cache key: ${key}`);
|
|
96
|
-
if (snapshot) {
|
|
97
|
-
console.log(`[PageActionCache] 📄 Has snapshot: true (${snapshot.length} chars)`);
|
|
98
|
-
}
|
|
99
|
-
if (refs) {
|
|
100
|
-
console.log(`[PageActionCache] 📋 Has refs: true (${Object.keys(refs).length} refs)`);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
console.log(`[PageActionCache] ⚠️ Has refs: false`);
|
|
104
|
-
}
|
|
105
|
-
// 更新现有缓存
|
|
106
|
-
if (existing && pluginConfig.autoUseCache) {
|
|
107
|
-
console.log(`[PageActionCache] 🔄 Cache already exists for ${url}`);
|
|
108
|
-
console.log(`[PageActionCache] 📈 Existing cached at: ${new Date(existing.timestamp).toISOString()}`);
|
|
109
|
-
console.log(`[PageActionCache] 📊 Hit count: ${existing.hitCount}`);
|
|
110
|
-
// 更新访问统计
|
|
111
|
-
existing.hitCount++;
|
|
112
|
-
memoryCache.set(key, {
|
|
113
|
-
...existing,
|
|
114
|
-
hitCount: existing.hitCount + 1,
|
|
115
|
-
timestamp: Date.now()
|
|
116
|
-
});
|
|
117
|
-
console.log(`[PageActionCache] ✅ Updated existing cache entry`);
|
|
118
|
-
console.log(`[PageActionCache] 📦 New cache size: ${memoryCache.size}`);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
// 存储新缓存
|
|
122
|
-
if (snapshot && refs) {
|
|
123
|
-
console.log(`[PageActionCache] 💾 Storing to cache...`);
|
|
124
|
-
console.log(`[PageActionCache] 🔑 Cache key: ${key}`);
|
|
125
|
-
const entry = {
|
|
126
|
-
url,
|
|
127
|
-
snapshot,
|
|
128
|
-
refs,
|
|
129
|
-
timestamp: Date.now(),
|
|
130
|
-
hitCount: 0
|
|
131
|
-
};
|
|
132
|
-
memoryCache.set(key, entry);
|
|
133
|
-
console.log(`[PageActionCache] ✅ Stored! Cache size: ${memoryCache.size}`);
|
|
134
|
-
console.log(`[PageActionCache] 🎉 Page cached successfully! 📍 ${url}`);
|
|
135
|
-
console.log(`[PageActionCache] 📋 Cached refs: ${Object.keys(refs).length} items`);
|
|
136
|
-
// 清理过期缓存
|
|
137
|
-
const cleanupCount = cleanupExpiredCache();
|
|
138
|
-
if (cleanupCount > 0) {
|
|
139
|
-
console.log(`[PageActionCache] 🧹 Cleaned ${cleanupCount} expired entries`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
console.log(`[PageActionCache] ⚠️ Snapshot present but no refs - not caching`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return undefined;
|
|
147
|
-
});
|
|
13
|
+
console.log('[PageActionCache] 🔍 Starting plugin registration...');
|
|
148
14
|
// 注册缓存统计工具
|
|
149
15
|
api.registerTool({
|
|
150
16
|
name: 'page_cache_stats',
|
|
@@ -156,71 +22,25 @@ export default function register(api) {
|
|
|
156
22
|
},
|
|
157
23
|
async execute() {
|
|
158
24
|
console.log('[PageActionCache] 📊 Tool: page_cache_stats called');
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
avgHitCount: memoryCache.size > 0
|
|
164
|
-
? Array.from(memoryCache.values()).reduce((sum, e) => sum + e.hitCount, 0) / memoryCache.size
|
|
165
|
-
: 0,
|
|
166
|
-
oldestEntry: memoryCache.size > 0
|
|
167
|
-
? Math.min(...Array.from(memoryCache.values()).map(e => e.timestamp))
|
|
168
|
-
: null,
|
|
169
|
-
newestEntry: memoryCache.size > 0
|
|
170
|
-
? Math.max(...Array.from(memoryCache.values()).map(e => e.timestamp))
|
|
171
|
-
: null
|
|
172
|
-
};
|
|
173
|
-
console.log('[PageActionCache] 📊 Total:', stats.totalEntries);
|
|
174
|
-
console.log('[PageActionCache] ✅ Hits:', stats.hits);
|
|
175
|
-
console.log('[PageActionCache] 📊 Hit Rate:', `${(stats.totalEntries > 0 ? (stats.hits / stats.totalEntries * 100).toFixed(2) : '0.00')}%`);
|
|
176
|
-
if (memoryCache.size > 0) {
|
|
177
|
-
// 显示最近缓存的页面
|
|
178
|
-
const sortedEntries = Array.from(memoryCache.values())
|
|
179
|
-
.sort((a, b) => b.timestamp - a.timestamp)
|
|
180
|
-
.slice(0, 5); // 显示最近 5 个
|
|
181
|
-
console.log('[PageActionCache] 📈 Recent caches:');
|
|
182
|
-
sortedEntries.forEach((entry, index) => {
|
|
183
|
-
if (entry.url) {
|
|
184
|
-
const hitRate = entry.hitCount > 0 ? (entry.hitCount / (entry.hitCount + 1) * 100).toFixed(1) : '0%';
|
|
185
|
-
console.log(`[PageActionCache] ${index + 1}. ${entry.url}`, `🎯 ${hitRate}`, `📈 Hits: ${entry.hitCount}`);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
return {
|
|
190
|
-
text: `## Page Snapshot Cache Statistics\n\n` +
|
|
191
|
-
`- Total Entries: ${stats.totalEntries}\n` +
|
|
192
|
-
`- Total Hits: ${stats.hits}\n` +
|
|
193
|
-
`- Hit Rate: ${(stats.totalEntries > 0 ? (stats.hits / stats.totalEntries * 100).toFixed(2) : '0.00')}%\n\n` +
|
|
194
|
-
`- Cleaned Entries: ${cleaned}\n\n`,
|
|
195
|
-
stats
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
// 注册缓存清空工具
|
|
200
|
-
api.registerTool({
|
|
201
|
-
name: 'page_cache_clear',
|
|
202
|
-
description: 'Clear page snapshot cache',
|
|
203
|
-
inputSchema: {
|
|
204
|
-
type: 'object',
|
|
205
|
-
properties: {},
|
|
206
|
-
required: []
|
|
207
|
-
},
|
|
208
|
-
async execute() {
|
|
209
|
-
console.log('[PageActionCache] 🗑️ Tool: page_cache_clear called');
|
|
210
|
-
const count = memoryCache.size;
|
|
211
|
-
memoryCache.clear();
|
|
212
|
-
console.log('[PageActionCache] 🧹 Cleared', `${count} cache entries`);
|
|
25
|
+
const statsText = '## Page Snapshot Cache Statistics\n\n' +
|
|
26
|
+
'- Total Entries: 0\n' +
|
|
27
|
+
'- Total Hits: 0\n' +
|
|
28
|
+
'- Hit Rate: 0.00%\n\n';
|
|
213
29
|
return {
|
|
214
|
-
text:
|
|
215
|
-
|
|
30
|
+
text: statsText,
|
|
31
|
+
totalEntries: 0,
|
|
32
|
+
hits: 0,
|
|
33
|
+
hitRate: '0.00%'
|
|
216
34
|
};
|
|
217
35
|
}
|
|
218
36
|
});
|
|
219
|
-
|
|
220
|
-
console.log('[PageActionCache] ✅
|
|
37
|
+
console.log('[PageActionCache] =======================================');
|
|
38
|
+
console.log('[PageActionCache] ✅ Plugin registered successfully');
|
|
39
|
+
console.log('[PageActionCache] 📋 Available tools: page_cache_stats');
|
|
40
|
+
console.log('[PageActionCache] 📋 No hooks registered');
|
|
221
41
|
}
|
|
222
42
|
catch (error) {
|
|
223
|
-
console.error('[PageActionCache] Fatal error during plugin registration:', error);
|
|
43
|
+
console.error('[PageActionCache] ❌ Fatal error during plugin registration:', error);
|
|
224
44
|
}
|
|
225
45
|
}
|
|
226
46
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAsB;IACrD,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAExD,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QAEpE,WAAW;QACX,GAAG,CAAC,YAAY,CAAC;YACf,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,qCAAqC;YAClD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;gBACd,QAAQ,EAAE,EAAE;aACb;YACD,KAAK,CAAC,OAAO;gBACX,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;gBAElE,MAAM,SAAS,GAAG,uCAAuC;oBACvD,sBAAsB;oBACtB,mBAAmB;oBACnB,uBAAuB,CAAC;gBAE1B,OAAO;oBACL,IAAI,EAAE,SAAS;oBACf,YAAY,EAAE,CAAC;oBACf,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,OAAO;iBACN,CAAC;YACf,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAE1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,6DAA6D,EAAE,KAAK,CAAC,CAAC;IACtF,CAAC;AACH,CAAC"}
|
package/openclaw.plugin.json
CHANGED