clawpet-plugins 1.1.0 → 1.1.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.
- package/index.ts +26 -26
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ClawPet OpenClaw Plugin
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Automatically reports agent tool calls to the ClawPet backend,
|
|
5
|
+
* driving real-time lobster pet animations.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* - after_tool_call:
|
|
9
|
-
* - agent_end:
|
|
7
|
+
* Hooks:
|
|
8
|
+
* - after_tool_call: reports action + summary after each tool execution
|
|
9
|
+
* - agent_end: reports when an agent turn completes
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* Configuration (in OpenClaw config plugins.entries):
|
|
12
12
|
* {
|
|
13
13
|
* "clawpet-plugins": {
|
|
14
14
|
* "enabled": true,
|
|
15
15
|
* "config": {
|
|
16
|
-
* "
|
|
17
|
-
* "
|
|
16
|
+
* "apiBase": "https://api.myclawpet.cn",
|
|
17
|
+
* "apiKey": "cpk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
18
18
|
* }
|
|
19
19
|
* }
|
|
20
20
|
* }
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
|
-
//
|
|
24
|
+
// Type definitions (aligned with OpenClaw Plugin API, no source imports)
|
|
25
25
|
// ---------------------------------------------------------------------------
|
|
26
26
|
|
|
27
27
|
type PluginLogger = {
|
|
@@ -44,17 +44,17 @@ type PluginApi = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
// ---------------------------------------------------------------------------
|
|
47
|
-
//
|
|
47
|
+
// Constants
|
|
48
48
|
// ---------------------------------------------------------------------------
|
|
49
49
|
|
|
50
|
-
/**
|
|
50
|
+
/** Dedup window (ms) — skip duplicate reports for the same tool within 2s */
|
|
51
51
|
const DEDUP_WINDOW = 2000;
|
|
52
52
|
|
|
53
|
-
/**
|
|
53
|
+
/** Report timeout (ms) */
|
|
54
54
|
const REPORT_TIMEOUT = 5000;
|
|
55
55
|
|
|
56
56
|
// ---------------------------------------------------------------------------
|
|
57
|
-
//
|
|
57
|
+
// Plugin entry
|
|
58
58
|
// ---------------------------------------------------------------------------
|
|
59
59
|
|
|
60
60
|
export default {
|
|
@@ -90,28 +90,28 @@ export default {
|
|
|
90
90
|
|
|
91
91
|
api.logger.info(`[ClawPet] Plugin active, reporting to ${apiBase}`);
|
|
92
92
|
|
|
93
|
-
//
|
|
93
|
+
// Dedup: track recently reported toolName → timestamp
|
|
94
94
|
const lastReported = new Map<string, number>();
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
97
|
+
* Async report to ClawPet backend.
|
|
98
|
+
* Fire-and-forget — never blocks the agent.
|
|
99
99
|
*/
|
|
100
100
|
function reportActivity(action: string, summary: string): void {
|
|
101
|
-
//
|
|
101
|
+
// Dedup check
|
|
102
102
|
const now = Date.now();
|
|
103
103
|
const lastTime = lastReported.get(action);
|
|
104
104
|
if (lastTime && now - lastTime < DEDUP_WINDOW) return;
|
|
105
105
|
lastReported.set(action, now);
|
|
106
106
|
|
|
107
|
-
//
|
|
107
|
+
// Evict stale dedup entries (prevent memory leaks)
|
|
108
108
|
if (lastReported.size > 100) {
|
|
109
109
|
for (const [key, ts] of lastReported) {
|
|
110
110
|
if (now - ts > DEDUP_WINDOW * 5) lastReported.delete(key);
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
//
|
|
114
|
+
// Async POST, fire-and-forget
|
|
115
115
|
const controller = new AbortController();
|
|
116
116
|
const timeout = setTimeout(() => controller.abort(), REPORT_TIMEOUT);
|
|
117
117
|
|
|
@@ -129,7 +129,7 @@ export default {
|
|
|
129
129
|
if (res.ok) {
|
|
130
130
|
try {
|
|
131
131
|
const data = await res.json();
|
|
132
|
-
//
|
|
132
|
+
// Piggyback apiBase update from webhook response
|
|
133
133
|
if (data?.config?.apiBase && data.config.apiBase !== apiBase) {
|
|
134
134
|
api.logger.info(
|
|
135
135
|
`[ClawPet] API base updated: ${apiBase} → ${data.config.apiBase}`,
|
|
@@ -137,19 +137,19 @@ export default {
|
|
|
137
137
|
apiBase = data.config.apiBase;
|
|
138
138
|
}
|
|
139
139
|
} catch {
|
|
140
|
-
// JSON
|
|
140
|
+
// JSON parse failure — ignore
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
})
|
|
144
144
|
.catch(() => {
|
|
145
145
|
clearTimeout(timeout);
|
|
146
|
-
//
|
|
146
|
+
// Report failure silently — never affect agent work
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// ========================================
|
|
151
151
|
// Hook: after_tool_call
|
|
152
|
-
//
|
|
152
|
+
// Reports after each tool execution
|
|
153
153
|
// ========================================
|
|
154
154
|
|
|
155
155
|
api.on("after_tool_call", (event: any) => {
|
|
@@ -164,13 +164,13 @@ export default {
|
|
|
164
164
|
|
|
165
165
|
reportActivity(toolName, summary);
|
|
166
166
|
} catch {
|
|
167
|
-
// Hook
|
|
167
|
+
// Hook errors are silent — never affect agent
|
|
168
168
|
}
|
|
169
169
|
});
|
|
170
170
|
|
|
171
171
|
// ========================================
|
|
172
172
|
// Hook: agent_end
|
|
173
|
-
//
|
|
173
|
+
// Reports when an agent turn completes
|
|
174
174
|
// ========================================
|
|
175
175
|
|
|
176
176
|
api.on("agent_end", (event: any) => {
|
|
@@ -182,7 +182,7 @@ export default {
|
|
|
182
182
|
reportActivity("error", `Turn failed: ${event.error ?? "unknown"}`);
|
|
183
183
|
}
|
|
184
184
|
} catch {
|
|
185
|
-
// Hook
|
|
185
|
+
// Hook errors are silent — never affect agent
|
|
186
186
|
}
|
|
187
187
|
});
|
|
188
188
|
},
|