create-loopengine 0.1.56 → 0.1.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/adapters/http.ts +21 -0
- package/template/package.json +1 -1
package/package.json
CHANGED
|
@@ -2696,7 +2696,20 @@ async function handleSlackInteraction(req: IncomingMessage, res: ServerResponse,
|
|
|
2696
2696
|
}
|
|
2697
2697
|
}
|
|
2698
2698
|
|
|
2699
|
+
// Set once shutdown() starts, so /healthz turns 503 while the server
|
|
2700
|
+
// drains and a router or load balancer stops sending it new requests.
|
|
2701
|
+
let shuttingDown = false
|
|
2702
|
+
|
|
2699
2703
|
const server = createServer(async (req, res) => {
|
|
2704
|
+
// Liveness for whatever runs this server (Docker, Fly, a router): no
|
|
2705
|
+
// login, nothing about the server in the answer, and not counted as
|
|
2706
|
+
// activity, so polling it never keeps an idle server awake.
|
|
2707
|
+
if ((req.method === 'GET' || req.method === 'HEAD') && (req.url ?? '/').split('?')[0] === '/healthz') {
|
|
2708
|
+
res.writeHead(shuttingDown ? 503 : 200, { 'content-type': 'application/json', 'cache-control': 'no-store' })
|
|
2709
|
+
res.end(req.method === 'HEAD' ? undefined : JSON.stringify({ ok: !shuttingDown }))
|
|
2710
|
+
return
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2700
2713
|
const slackHookMatch = req.method === 'POST' && (req.url ?? '/').split('?')[0].match(/^\/hooks\/slack\/([^/]+)$/)
|
|
2701
2714
|
if (slackHookMatch) {
|
|
2702
2715
|
try {
|
|
@@ -2773,6 +2786,13 @@ const server = createServer(async (req, res) => {
|
|
|
2773
2786
|
// web/playground.ts. GET, not POST, and an exact path match
|
|
2774
2787
|
// (neither has a :name segment), so no risk of colliding with the
|
|
2775
2788
|
// regexes above (already partitioned by method).
|
|
2789
|
+
// The bare address is the console itself, the same page as
|
|
2790
|
+
// /agents/config (all its links and requests use absolute paths).
|
|
2791
|
+
if (req.method === 'GET' && pathname === '/') {
|
|
2792
|
+
res.writeHead(200, { 'content-type': 'text/html' }).end(agentsConfigPageHtml)
|
|
2793
|
+
return
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2776
2796
|
if (req.method === 'GET' && pathname === '/playground') {
|
|
2777
2797
|
res.writeHead(200, { 'content-type': 'text/html' }).end(playgroundHtml)
|
|
2778
2798
|
return
|
|
@@ -3334,6 +3354,7 @@ async function warmAgentTools(): Promise<void> {
|
|
|
3334
3354
|
// process restart, just this one process's own event loop.
|
|
3335
3355
|
async function shutdown() {
|
|
3336
3356
|
console.log('[loopengine] shutting down — draining in-flight requests...')
|
|
3357
|
+
shuttingDown = true
|
|
3337
3358
|
scheduler.stop()
|
|
3338
3359
|
const graceMs = Number(process.env.LOOPENGINE_SHUTDOWN_GRACE_MS ?? 30000)
|
|
3339
3360
|
const closed = new Promise<void>((resolve) => server.close(() => resolve()))
|