create-loopengine 0.1.63 → 0.1.64
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 +24 -4
- package/template/package.json +1 -1
package/package.json
CHANGED
|
@@ -2354,6 +2354,10 @@ async function answerPendingQuestion(res: ServerResponse, pendingId: string, bod
|
|
|
2354
2354
|
* resumeAgent(), through the same durable sessions.withSession append
|
|
2355
2355
|
* path any other turn goes through. */
|
|
2356
2356
|
async function respondAfterResolution(res: ServerResponse, finalCheckpoint: TurnCheckpoint): Promise<void> {
|
|
2357
|
+
await tracked(() => respondAfterResolutionNow(res, finalCheckpoint))
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
async function respondAfterResolutionNow(res: ServerResponse, finalCheckpoint: TurnCheckpoint): Promise<void> {
|
|
2357
2361
|
if (Object.keys(finalCheckpoint.outstanding).length > 0) {
|
|
2358
2362
|
res.writeHead(200, { 'content-type': 'application/json' }).end(
|
|
2359
2363
|
JSON.stringify({ resolved: true, outstanding: Object.keys(finalCheckpoint.outstanding).length }),
|
|
@@ -2588,11 +2592,24 @@ function exitIfCodeChanged(res: ServerResponse): void {
|
|
|
2588
2592
|
// checks before stopping an idle server, so it never stops one mid-turn.
|
|
2589
2593
|
let openStreams = 0
|
|
2590
2594
|
let lastRequestAt = Date.now()
|
|
2595
|
+
// Work still running after its request was answered (a Slack thread reply
|
|
2596
|
+
// being answered, a run resumed after a decision), so a host never
|
|
2597
|
+
// suspends this server in the middle of it.
|
|
2598
|
+
let backgroundWork = 0
|
|
2599
|
+
|
|
2600
|
+
async function tracked<T>(fn: () => Promise<T>): Promise<T> {
|
|
2601
|
+
backgroundWork++
|
|
2602
|
+
try {
|
|
2603
|
+
return await fn()
|
|
2604
|
+
} finally {
|
|
2605
|
+
backgroundWork--
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2591
2608
|
|
|
2592
2609
|
async function handleActivityGet(res: ServerResponse): Promise<void> {
|
|
2593
2610
|
res.writeHead(200, { 'content-type': 'application/json' }).end(
|
|
2594
2611
|
JSON.stringify({
|
|
2595
|
-
inFlightTurns: sessionTurns.size + scheduler.running,
|
|
2612
|
+
inFlightTurns: sessionTurns.size + scheduler.running + backgroundWork,
|
|
2596
2613
|
scheduledRuns: scheduler.running,
|
|
2597
2614
|
// When the next scheduled task is due — wake this server by then
|
|
2598
2615
|
// (POST /internal/scheduler/tick) if it's been stopped while idle.
|
|
@@ -2772,7 +2789,8 @@ const server = createServer(async (req, res) => {
|
|
|
2772
2789
|
const slackEventsMatch = req.method === 'POST' && (req.url ?? '/').split('?')[0].match(/^\/hooks\/slack\/([^/]+)\/events$/)
|
|
2773
2790
|
if (slackEventsMatch) {
|
|
2774
2791
|
try {
|
|
2775
|
-
|
|
2792
|
+
lastRequestAt = Date.now()
|
|
2793
|
+
await tracked(() => handleSlackEvents(req, res, decodeURIComponent(slackEventsMatch[1])))
|
|
2776
2794
|
} catch (err) {
|
|
2777
2795
|
console.error('[loopengine] Slack event failed:', err)
|
|
2778
2796
|
if (!res.headersSent) res.writeHead(500).end()
|
|
@@ -2783,7 +2801,8 @@ const server = createServer(async (req, res) => {
|
|
|
2783
2801
|
const slackHookMatch = req.method === 'POST' && (req.url ?? '/').split('?')[0].match(/^\/hooks\/slack\/([^/]+)$/)
|
|
2784
2802
|
if (slackHookMatch) {
|
|
2785
2803
|
try {
|
|
2786
|
-
|
|
2804
|
+
lastRequestAt = Date.now()
|
|
2805
|
+
await tracked(() => handleSlackInteraction(req, res, decodeURIComponent(slackHookMatch[1])))
|
|
2787
2806
|
} catch (err) {
|
|
2788
2807
|
console.error('[loopengine] Slack interaction failed:', err)
|
|
2789
2808
|
if (!res.headersSent) res.writeHead(500).end()
|
|
@@ -2794,7 +2813,8 @@ const server = createServer(async (req, res) => {
|
|
|
2794
2813
|
const decideMatch = (req.method === 'GET' || req.method === 'POST') && (req.url ?? '/').split('?')[0].match(/^\/decide\/([A-Za-z0-9_.-]+)$/)
|
|
2795
2814
|
if (decideMatch) {
|
|
2796
2815
|
try {
|
|
2797
|
-
|
|
2816
|
+
lastRequestAt = Date.now()
|
|
2817
|
+
await tracked(() => handleDecide(req, res, decideMatch[1]))
|
|
2798
2818
|
} catch (err) {
|
|
2799
2819
|
console.error('[loopengine] decision link failed:', err)
|
|
2800
2820
|
if (!res.headersSent) res.writeHead(500, { 'content-type': 'application/json' }).end(JSON.stringify({ error: 'Something went wrong; try again.' }))
|