@mediagato/modelreins-channel 4.12.5 → 4.12.6

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.
@@ -96,7 +96,7 @@
96
96
  * Required:
97
97
  * MODELREINS_URL — Dashboard URL. Examples:
98
98
  * https://app.modelreins.com (hosted)
99
- * http://192.168.0.246:8484 (self-hosted LAN)
99
+ * http://your-server:8484 (self-hosted)
100
100
  * http://localhost:8484 (local dev)
101
101
  *
102
102
  * MODELREINS_TOKEN — Worker auth token. Find it in the dashboard under
@@ -1262,14 +1262,37 @@ await mcp.connect(new StdioServerTransport());
1262
1262
  * full worker context without a separate lookup.
1263
1263
  */
1264
1264
  async function heartbeat() {
1265
+ // An outbound-only session must NOT advertise itself as available work.
1266
+ // It used to report 'active' with details 'idle, polling' while pollJobs()
1267
+ // had never started -- both false. Cost: a job dispatched to such a seat
1268
+ // sat "pending" for 6.4 hours while the dashboard showed the worker
1269
+ // "active" the whole time, and nothing anywhere could tell the difference
1270
+ // (2026-09-03). The control that proved it was a real finding: the same
1271
+ // dispatch to a consuming worker was claimed and completed in 18 seconds.
1272
+ //
1273
+ // Worse than the manual case: app.py's routing selects
1274
+ // `status NOT IN ('offline','maintenance')`, so an outbound-only worker
1275
+ // reporting 'active' is a valid auto-route target -- `assigned_to: "auto"`
1276
+ // could silently park a job on a seat that will never claim it.
1277
+ //
1278
+ // 'offline' is the correct report and the only safe one here: it is in the
1279
+ // routing exclusion list, and unlike 'maintenance' and 'retired' it is NOT
1280
+ // sticky server-side (app.py:4104,4107), so flipping MODELREINS_RECEIVE_JOBS
1281
+ // back to true restores 'active' on the very next heartbeat with no manual
1282
+ // unpark call. The heartbeat itself keeps flowing either way, so
1283
+ // last_heartbeat still proves the process is alive.
1284
+ const idleStatus = RECEIVE_JOBS ? 'active' : 'offline';
1285
+ const idleDetails = RECEIVE_JOBS
1286
+ ? 'idle, polling'
1287
+ : 'outbound-only (MODELREINS_RECEIVE_JOBS=false) — never claims dispatched jobs';
1265
1288
  await api('PUT', '/presence', {
1266
1289
  instance: WORKER_NAME,
1267
- status: currentJobId ? 'busy' : 'active',
1290
+ status: currentJobId ? 'busy' : idleStatus,
1268
1291
  project: 'channel',
1269
1292
  worker_type: 'channel',
1270
1293
  model: WORKER_MODEL,
1271
1294
  tags: WORKER_TAGS,
1272
- details: currentJobId ? `working on job #${currentJobId}` : 'idle, polling',
1295
+ details: currentJobId ? `working on job #${currentJobId}` : idleDetails,
1273
1296
  });
1274
1297
  }
1275
1298
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediagato/modelreins-channel",
3
- "version": "4.12.5",
3
+ "version": "4.12.6",
4
4
  "description": "ModelReins MCP Channel — turn any Claude Code session into a ModelReins worker",
5
5
  "type": "module",
6
6
  "main": "modelreins-channel.mjs",