@cohortapp/agent-sdk 2.18.11 → 2.18.12
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cohortapp/agent-sdk",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.12",
|
|
4
4
|
"description": "Cohort Agent SDK — autonomous AI colleague runtime. Deploy senior AI colleagues on dedicated Mac minis, wired to the Cohort operating surface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -160,7 +160,7 @@ import { processOne } from "../../lib/execution/pipeline.mjs";
|
|
|
160
160
|
// gate is pure (lib/session/frontdoor.mjs); the assurance sweep reopens a
|
|
161
161
|
// session claim that was neither replied nor done within 20 min.
|
|
162
162
|
import { shouldReviveFrontDoor, reviveCommand, sessionJobLabelOnDisk } from "../../lib/session/revive.mjs";
|
|
163
|
-
import { makeFrontDoorGate, sessionLiveFromHeartbeat } from "../../lib/session/frontdoor.mjs";
|
|
163
|
+
import { makeFrontDoorGate, sessionLiveFromHeartbeat, readFrontDoorState } from "../../lib/session/frontdoor.mjs";
|
|
164
164
|
import { CADENCE_REGISTRY } from "./cadence-handlers.mjs";
|
|
165
165
|
import { sweepSessionInboxForDaemon } from "../../lib/session/inbox-claims.mjs";
|
|
166
166
|
import { defaultEffects, scheduleToQueue } from "../../lib/execution/effects.mjs";
|
|
@@ -291,6 +291,8 @@ const _frontDoorGate = makeFrontDoorGate({ agentRoot: AGENT_REPO_DIR });
|
|
|
291
291
|
// State is per-process and deliberately not persisted: a daemon restart is
|
|
292
292
|
// itself a change of circumstances, and a fresh budget after one is the answer
|
|
293
293
|
// we want rather than a stale count carried across it.
|
|
294
|
+
/** How often the daemon asks whether the front door has gone quiet. */
|
|
295
|
+
const REVIVE_CHECK_INTERVAL_MS = 60 * 1000;
|
|
294
296
|
const _revive = { attempts: 0, lastAt: null };
|
|
295
297
|
async function reviveFrontDoorIfShut(state, deps = {}) {
|
|
296
298
|
const now = deps.now ? deps.now() : Date.now();
|
|
@@ -325,9 +327,6 @@ async function pollService(svc) {
|
|
|
325
327
|
// Front door: a live main session owns this service's inbox — leave it.
|
|
326
328
|
const fd = _frontDoorGate.check(svc.name);
|
|
327
329
|
if (fd.changed) console.log(`[daemon] front door for ${svc.name}: ${fd.dispatch ? "daemon dispatches" : "main session owns intake"} (${fd.reason})`);
|
|
328
|
-
// A door that is shut is not a door that owns anything. Ask on every poll,
|
|
329
|
-
// cheap and bounded: the common answer is "answering" off a fresh beat.
|
|
330
|
-
if (svc.name === "cohort") await reviveFrontDoorIfShut(fd.state).catch(() => {});
|
|
331
330
|
if (!fd.dispatch) return 0;
|
|
332
331
|
const result = await svc.fn();
|
|
333
332
|
// Dedup by raw_ref first: the same Slack message arrives via multiple paths
|
|
@@ -3150,6 +3149,22 @@ async function main() {
|
|
|
3150
3149
|
pollCohortFast().catch((err) => console.error("[daemon] cohort fast-poll error:", err.message));
|
|
3151
3150
|
}, COHORT_FAST_INTERVAL);
|
|
3152
3151
|
|
|
3152
|
+
// ── THE SHUT-DOOR CHECK GETS ITS OWN TICK ─────────────────────────────────
|
|
3153
|
+
//
|
|
3154
|
+
// It lived inside pollService for one release, which was the wrong place for
|
|
3155
|
+
// exactly the reason it exists: `pollCohortFast` guards itself with
|
|
3156
|
+
// `_cohortFastRunning`, so a poll that hangs starves every later call — and a
|
|
3157
|
+
// seat whose front door is wedged is precisely a seat where things hang. The
|
|
3158
|
+
// remedy must not share a lane with the thing it is rescuing.
|
|
3159
|
+
//
|
|
3160
|
+
// Its own interval, reading the front-door state directly, so nothing between
|
|
3161
|
+
// here and the kickstart can be blocked by the wedge.
|
|
3162
|
+
setInterval(() => {
|
|
3163
|
+
let state = null;
|
|
3164
|
+
try { state = readFrontDoorState(AGENT_REPO_DIR, { now: Date.now() }); } catch { state = null; }
|
|
3165
|
+
if (state) reviveFrontDoorIfShut(state).catch(() => {});
|
|
3166
|
+
}, REVIVE_CHECK_INTERVAL_MS);
|
|
3167
|
+
|
|
3153
3168
|
// Backlog sweep
|
|
3154
3169
|
setInterval(async () => {
|
|
3155
3170
|
try {
|