Clarify OpenClaw claimed API key handling

This commit is contained in:
Dotta
2026-03-06 11:21:55 -06:00
parent cec372f9bb
commit f56901b473
4 changed files with 15 additions and 1 deletions

View File

@@ -146,6 +146,7 @@ type WakePayload = {
}; };
function buildWakeText(payload: WakePayload, paperclipEnv: Record<string, string>): string { function buildWakeText(payload: WakePayload, paperclipEnv: Record<string, string>): string {
const claimedApiKeyPath = "~/.openclaw/workspace/paperclip-claimed-api-key.json";
const orderedKeys = [ const orderedKeys = [
"PAPERCLIP_RUN_ID", "PAPERCLIP_RUN_ID",
"PAPERCLIP_AGENT_ID", "PAPERCLIP_AGENT_ID",
@@ -171,6 +172,9 @@ function buildWakeText(payload: WakePayload, paperclipEnv: Record<string, string
"", "",
"Set these values in your run context:", "Set these values in your run context:",
...envLines, ...envLines,
`PAPERCLIP_API_KEY=<token from ${claimedApiKeyPath}>`,
"",
`Load PAPERCLIP_API_KEY from ${claimedApiKeyPath} (the token you saved after claim-api-key).`,
"", "",
`task_id=${payload.taskId ?? ""}`, `task_id=${payload.taskId ?? ""}`,
`issue_id=${payload.issueId ?? ""}`, `issue_id=${payload.issueId ?? ""}`,

View File

@@ -49,6 +49,9 @@ describe("buildInviteOnboardingTextDocument", () => {
expect(text).toContain("You MUST include agentDefaultsPayload.headers.x-openclaw-auth"); expect(text).toContain("You MUST include agentDefaultsPayload.headers.x-openclaw-auth");
expect(text).toContain("will fail with 401 Unauthorized"); expect(text).toContain("will fail with 401 Unauthorized");
expect(text).toContain("set the first reachable candidate as agentDefaultsPayload.paperclipApiUrl"); expect(text).toContain("set the first reachable candidate as agentDefaultsPayload.paperclipApiUrl");
expect(text).toContain("~/.openclaw/workspace/paperclip-claimed-api-key.json");
expect(text).toContain("PAPERCLIP_API_KEY");
expect(text).toContain("saved token field");
}); });
it("includes loopback diagnostics for authenticated/private onboarding", () => { it("includes loopback diagnostics for authenticated/private onboarding", () => {

View File

@@ -196,6 +196,8 @@ describe("openclaw adapter execute", () => {
expect(text).toContain("PAPERCLIP_TASK_ID=task-123"); expect(text).toContain("PAPERCLIP_TASK_ID=task-123");
expect(text).toContain("PAPERCLIP_WAKE_REASON=issue_assigned"); expect(text).toContain("PAPERCLIP_WAKE_REASON=issue_assigned");
expect(text).toContain("PAPERCLIP_LINKED_ISSUE_IDS=issue-123"); expect(text).toContain("PAPERCLIP_LINKED_ISSUE_IDS=issue-123");
expect(text).toContain("PAPERCLIP_API_KEY=<token from ~/.openclaw/workspace/paperclip-claimed-api-key.json>");
expect(text).toContain("Load PAPERCLIP_API_KEY from ~/.openclaw/workspace/paperclip-claimed-api-key.json");
}); });
it("uses paperclipApiUrl override when provided", async () => { it("uses paperclipApiUrl override when provided", async () => {
@@ -379,6 +381,7 @@ describe("openclaw adapter execute", () => {
expect(body.model).toBe("openclaw"); expect(body.model).toBe("openclaw");
expect(typeof body.input).toBe("string"); expect(typeof body.input).toBe("string");
expect(String(body.input)).toContain("PAPERCLIP_RUN_ID=run-123"); expect(String(body.input)).toContain("PAPERCLIP_RUN_ID=run-123");
expect(String(body.input)).toContain("PAPERCLIP_API_KEY=<token from ~/.openclaw/workspace/paperclip-claimed-api-key.json>");
expect(body.metadata).toBeTypeOf("object"); expect(body.metadata).toBeTypeOf("object");
expect((body.metadata as Record<string, unknown>).PAPERCLIP_RUN_ID).toBe("run-123"); expect((body.metadata as Record<string, unknown>).PAPERCLIP_RUN_ID).toBe("run-123");
expect(body.text).toBeUndefined(); expect(body.text).toBeUndefined();

View File

@@ -662,7 +662,7 @@ function buildInviteOnboardingManifest(
invite: toInviteSummaryResponse(req, token, invite), invite: toInviteSummaryResponse(req, token, invite),
onboarding: { onboarding: {
instructions: instructions:
"Join as an OpenClaw agent, save your one-time claim secret, wait for board approval, then claim your API key and install the Paperclip skill before starting heartbeat loops. You MUST include agentDefaultsPayload.headers.x-openclaw-auth in your join request so Paperclip can authenticate callback requests.", "Join as an OpenClaw agent, save your one-time claim secret, wait for board approval, then claim your API key. Save the claim response token to ~/.openclaw/workspace/paperclip-claimed-api-key.json and load PAPERCLIP_API_KEY from that file before starting heartbeat loops. You MUST include agentDefaultsPayload.headers.x-openclaw-auth in your join request so Paperclip can authenticate callback requests.",
inviteMessage: extractInviteMessage(invite), inviteMessage: extractInviteMessage(invite),
recommendedAdapterType: "openclaw", recommendedAdapterType: "openclaw",
requiredFields: { requiredFields: {
@@ -805,6 +805,10 @@ export function buildInviteOnboardingTextDocument(
' "claimSecret": "<one-time-claim-secret>"', ' "claimSecret": "<one-time-claim-secret>"',
"}", "}",
"", "",
"On successful claim, save the full JSON response to:",
"- ~/.openclaw/workspace/paperclip-claimed-api-key.json",
"Then set PAPERCLIP_API_KEY from the saved token field for every heartbeat run.",
"",
"Important:", "Important:",
"- claim secrets expire", "- claim secrets expire",
"- claim secrets are single-use", "- claim secrets are single-use",