fix: clean OpenClaw capture prompt

This commit is contained in:
2026-04-12 22:36:59 +00:00
parent a6ae6166a4
commit 72ca823206
3 changed files with 13 additions and 3 deletions

View File

@@ -3,6 +3,7 @@
Minimal OpenClaw plugin that mirrors Claude Code's `capture_stop.py` behavior:
- watches user-triggered assistant turns
- uses OpenClaw's cleaned user message (`before_agent_reply.cleanedBody`) so AtoCore stores the real prompt instead of the full inbound wrapper
- POSTs `prompt` + `response` to `POST /interactions`
- sets `client="openclaw"`
- sets `reinforce=true`
@@ -25,5 +26,6 @@ If `baseUrl` is omitted, the plugin uses `ATOCORE_BASE_URL` or defaults to `http
## Notes
- Project detection is intentionally left empty for now. Unscoped capture is acceptable because AtoCore's extraction pipeline handles unscoped interactions.
- Prompt cleaning is done inside the plugin by reading OpenClaw's finalized cleaned message body instead of the raw prompt-build input.
- Extraction is **not** part of the capture path. This plugin only records interactions and lets AtoCore reinforcement run automatically.
- The plugin captures only user-triggered turns, not heartbeats or system-only runs.

View File

@@ -46,11 +46,11 @@ export default definePluginEntry({
const logger = api.logger;
const pendingBySession = new Map();
api.on("before_agent_start", async (event, ctx) => {
api.on("before_agent_reply", async (event, ctx) => {
if (ctx?.trigger && ctx.trigger !== "user") return;
const config = api.getConfig?.() || {};
const minPromptLength = Number(config.minPromptLength || DEFAULT_MIN_PROMPT_LENGTH);
const prompt = trimText(event?.prompt || "");
const prompt = trimText(event?.cleanedBody || "");
if (!shouldCapturePrompt(prompt, minPromptLength)) {
pendingBySession.delete(ctx.sessionId);
return;
@@ -69,7 +69,10 @@ export default definePluginEntry({
if (!pending) return;
const assistantTexts = Array.isArray(event?.assistantTexts) ? event.assistantTexts : [];
const response = truncateResponse(trimText(assistantTexts.join("\n\n")), Number((api.getConfig?.() || {}).maxResponseLength || DEFAULT_MAX_RESPONSE_LENGTH));
const response = truncateResponse(
trimText(assistantTexts.join("\n\n")),
Number((api.getConfig?.() || {}).maxResponseLength || DEFAULT_MAX_RESPONSE_LENGTH)
);
if (!response) return;
const config = api.getConfig?.() || {};
@@ -87,6 +90,10 @@ export default definePluginEntry({
pendingBySession.delete(ctx.sessionId);
});
api.on("agent_end", async (event) => {
if (event?.sessionId) pendingBySession.delete(event.sessionId);
});
api.on("session_end", async (event) => {
if (event?.sessionId) pendingBySession.delete(event.sessionId);
});