feat: auto-detect pi-bot vs openclaw runtime for event delivery

- pi-bot: uses ctx.sendUserMessage (persistent session, followUp mode)
- openclaw: POSTs to /hooks/agent endpoint (request/response model)
- Detection: checks if ctx.sendUserMessage exists on session_start
- openclaw env vars: OPENCLAW_HOOKS_URL, OPENCLAW_HOOKS_PATH, OPENCLAW_HOOKS_TOKEN
- Same extension, tools, poller, and @mention routing work in both runtimes
This commit is contained in:
2026-03-13 18:19:00 -07:00
parent 83a42de9e2
commit 1d85ab86ba

View File

@@ -78,11 +78,35 @@ export default function (pi: ExtensionAPI) {
pi.on("session_start", async (_event, ctx) => {
console.log("[pi-gitea] Session started");
const sendMessageFn = (msg: string) => {
// Auto-detect runtime: pi-bot (persistent session) vs openclaw (hooks endpoint)
if (ctx.sendUserMessage) {
// pi-bot: inject directly into the running session
console.log("[pi-gitea] Delivery: sendUserMessage (pi-bot mode)");
setSendMessage((msg: string) => {
ctx.sendUserMessage(msg, { deliverAs: "followUp" });
return Promise.resolve();
};
setSendMessage(sendMessageFn);
});
} else {
// openclaw: POST to the hooks endpoint
const hooksUrl = process.env.OPENCLAW_HOOKS_URL ?? "http://localhost:3001";
const hooksPath = process.env.OPENCLAW_HOOKS_PATH ?? "/hooks/agent";
const hooksToken = process.env.OPENCLAW_HOOKS_TOKEN ?? "";
console.log(`[pi-gitea] Delivery: openclaw hooks (${hooksUrl}${hooksPath})`);
setSendMessage(async (msg: string) => {
const res = await fetch(`${hooksUrl}${hooksPath}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...(hooksToken ? { Authorization: `Bearer ${hooksToken}` } : {}),
},
body: JSON.stringify({ message: msg }),
});
if (!res.ok) {
const body = await res.text().catch(() => "");
throw new Error(`Hooks POST failed: ${res.status} ${body}`);
}
});
}
try {
await startWebhookServer(pi);