Fix workflows: SHA-pin all actions, add automerge/e2e/issue-reply, fix deploy.yml, add Cloudflare Worker

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-04 20:45:58 +00:00
parent b0cc31ef62
commit 75fac98e52
11 changed files with 424 additions and 11 deletions

142
worker/index.js Normal file
View File

@@ -0,0 +1,142 @@
/**
* Lucidia Cloudflare Worker — blackroad.io API edge layer
*
* Handles API requests at the edge for low-latency responses.
* Long-running inference is offloaded via the /run endpoint which
* dispatches to a Durable Object / Queue for async processing.
*
* Routes:
* GET / → health check
* GET /status → service status JSON
* POST /chat → forward to Lucidia AI (sync, ≤30 s CPU)
* POST /run → enqueue a long-running task (async via CF Queue)
*/
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// CORS pre-flight
if (request.method === "OPTIONS") {
return corsResponse(new Response(null, { status: 204 }));
}
switch (url.pathname) {
case "/":
return corsResponse(
new Response(
JSON.stringify({
service: "lucidia-worker",
version: "1.0.0",
status: "ok",
verified: true,
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
)
);
case "/status":
return corsResponse(
new Response(
JSON.stringify({
service: "lucidia-worker",
status: "healthy",
timestamp: new Date().toISOString(),
region: request.cf?.colo ?? "unknown",
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
)
);
case "/chat":
if (request.method !== "POST") {
return corsResponse(
new Response(JSON.stringify({ error: "POST required" }), {
status: 405,
headers: { "Content-Type": "application/json" },
})
);
}
try {
const body = await request.json();
const message = body.message ?? "";
// Stub response — replace with actual Lucidia AI call via env binding
return corsResponse(
new Response(
JSON.stringify({
reply: `Lucidia received: "${message}"`,
source: "worker-edge",
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
)
);
} catch {
return corsResponse(
new Response(JSON.stringify({ error: "Invalid JSON" }), {
status: 400,
headers: { "Content-Type": "application/json" },
})
);
}
case "/run":
if (request.method !== "POST") {
return corsResponse(
new Response(JSON.stringify({ error: "POST required" }), {
status: 405,
headers: { "Content-Type": "application/json" },
})
);
}
try {
const task = await request.json();
// Enqueue for async long-running processing
if (env.TASK_QUEUE) {
await env.TASK_QUEUE.send(task);
return corsResponse(
new Response(
JSON.stringify({ queued: true, task }),
{ status: 202, headers: { "Content-Type": "application/json" } }
)
);
}
return corsResponse(
new Response(
JSON.stringify({ queued: false, message: "Queue not configured" }),
{ status: 200, headers: { "Content-Type": "application/json" } }
)
);
} catch {
return corsResponse(
new Response(JSON.stringify({ error: "Invalid JSON" }), {
status: 400,
headers: { "Content-Type": "application/json" },
})
);
}
default:
return corsResponse(
new Response(JSON.stringify({ error: "Not found" }), {
status: 404,
headers: { "Content-Type": "application/json" },
})
);
}
},
};
function corsResponse(response) {
// Public edge API — CORS is intentionally open (*) for the demo worker.
// Restrict to specific origins (e.g., "https://blackroad.io") once a
// custom domain is configured in wrangler.toml and Cloudflare DNS.
const headers = new Headers(response.headers);
headers.set("Access-Control-Allow-Origin", "*");
headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers,
});
}