From b825a121cb9f413f7836a218a183c61927b1d9e6 Mon Sep 17 00:00:00 2001 From: dotta Date: Sat, 28 Mar 2026 10:23:19 -0500 Subject: [PATCH] Prioritize comment wake prompts --- packages/adapter-utils/src/server-utils.ts | 2 ++ server/src/__tests__/codex-local-execute.test.ts | 4 ++++ server/src/__tests__/openclaw-gateway-adapter.test.ts | 3 +++ skills/paperclip/SKILL.md | 4 ++-- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/adapter-utils/src/server-utils.ts b/packages/adapter-utils/src/server-utils.ts index 8c4ffbc5..d6e67c3b 100644 --- a/packages/adapter-utils/src/server-utils.ts +++ b/packages/adapter-utils/src/server-utils.ts @@ -300,6 +300,8 @@ export function renderPaperclipWakePrompt(value: unknown): string { const lines = [ "## Paperclip Wake Payload", "", + "Treat this wake payload as the highest-priority change for the current heartbeat.", + "Before generic repo exploration or boilerplate heartbeat updates, acknowledge the latest comment and explain how it changes your next action.", "Use this inline wake data first before refetching the issue thread.", "Only fetch the API thread when `fallbackFetchNeeded` is true or you need broader history than this batch.", "", diff --git a/server/src/__tests__/codex-local-execute.test.ts b/server/src/__tests__/codex-local-execute.test.ts index 4ca20ab0..795a0ca3 100644 --- a/server/src/__tests__/codex-local-execute.test.ts +++ b/server/src/__tests__/codex-local-execute.test.ts @@ -355,6 +355,10 @@ describe("codex execute", () => { commentIds: ["comment-1", "comment-2"], }); expect(capture.prompt).toContain("## Paperclip Wake Payload"); + expect(capture.prompt).toContain("Treat this wake payload as the highest-priority change for the current heartbeat."); + expect(capture.prompt).toContain( + "acknowledge the latest comment and explain how it changes your next action.", + ); expect(capture.prompt).toContain("First comment"); expect(capture.prompt).toContain("Second comment"); } finally { diff --git a/server/src/__tests__/openclaw-gateway-adapter.test.ts b/server/src/__tests__/openclaw-gateway-adapter.test.ts index 3bc1ba11..e4ca99a5 100644 --- a/server/src/__tests__/openclaw-gateway-adapter.test.ts +++ b/server/src/__tests__/openclaw-gateway-adapter.test.ts @@ -494,6 +494,9 @@ describe("openclaw gateway adapter execute", () => { expect(String(payload?.message ?? "")).toContain("PAPERCLIP_RUN_ID=run-123"); expect(String(payload?.message ?? "")).toContain("PAPERCLIP_TASK_ID=task-123"); expect(String(payload?.message ?? "")).toContain("## Paperclip Wake Payload"); + expect(String(payload?.message ?? "")).toContain( + "Treat this wake payload as the highest-priority change for the current heartbeat.", + ); expect(String(payload?.message ?? "")).toContain("First comment"); expect(String(payload?.message ?? "")).toContain("\"commentIds\":[\"comment-1\",\"comment-2\"]"); expect(payload?.paperclip).toMatchObject({ diff --git a/skills/paperclip/SKILL.md b/skills/paperclip/SKILL.md index 6ceed9eb..fae34f35 100644 --- a/skills/paperclip/SKILL.md +++ b/skills/paperclip/SKILL.md @@ -17,7 +17,7 @@ You run in **heartbeats** — short execution windows triggered by Paperclip. Ea Env vars auto-injected: `PAPERCLIP_AGENT_ID`, `PAPERCLIP_COMPANY_ID`, `PAPERCLIP_API_URL`, `PAPERCLIP_RUN_ID`. Optional wake-context vars may also be present: `PAPERCLIP_TASK_ID` (issue/task that triggered this wake), `PAPERCLIP_WAKE_REASON` (why this run was triggered), `PAPERCLIP_WAKE_COMMENT_ID` (specific comment that triggered this wake), `PAPERCLIP_APPROVAL_ID`, `PAPERCLIP_APPROVAL_STATUS`, and `PAPERCLIP_LINKED_ISSUE_IDS` (comma-separated). For local adapters, `PAPERCLIP_API_KEY` is auto-injected as a short-lived run JWT. For non-local adapters, your operator should set `PAPERCLIP_API_KEY` in adapter config. All requests use `Authorization: Bearer $PAPERCLIP_API_KEY`. All endpoints under `/api`, all JSON. Never hard-code the API URL. -Some adapters also inject `PAPERCLIP_WAKE_PAYLOAD_JSON` on comment-driven wakes. When present, it contains the compact issue summary and the ordered batch of new comment payloads for this wake. Prefer using it first. Only fetch the thread/comments API immediately when `fallbackFetchNeeded` is true or you need broader context than the inline batch provides. +Some adapters also inject `PAPERCLIP_WAKE_PAYLOAD_JSON` on comment-driven wakes. When present, it contains the compact issue summary and the ordered batch of new comment payloads for this wake. Use it first. For comment wakes, treat that batch as the highest-priority new context in the heartbeat: in your first task update or response, acknowledge the latest comment and say how it changes your next action before broad repo exploration or generic wake boilerplate. Only fetch the thread/comments API immediately when `fallbackFetchNeeded` is true or you need broader context than the inline batch provides. Manual local CLI mode (outside heartbeat runs): use `paperclipai agent local-cli --company-id ` to install Paperclip skills for Claude/Codex and print/export the required `PAPERCLIP_*` environment variables for that agent identity. @@ -61,7 +61,7 @@ If already checked out by you, returns normally. If owned by another agent: `409 **Step 6 — Understand context.** Prefer `GET /api/issues/{issueId}/heartbeat-context` first. It gives you compact issue state, ancestor summaries, goal/project info, and comment cursor metadata without forcing a full thread replay. -If `PAPERCLIP_WAKE_PAYLOAD_JSON` is present, inspect that payload before calling the API. It is the fastest path for comment wakes and may already include the exact new comments that triggered this run. +If `PAPERCLIP_WAKE_PAYLOAD_JSON` is present, inspect that payload before calling the API. It is the fastest path for comment wakes and may already include the exact new comments that triggered this run. For comment-driven wakes, explicitly reflect the new comment context first, then fetch broader history only if needed. Use comments incrementally: