agent-relay-server 0.118.1 → 0.118.3
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/docs/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Agent Relay API",
|
|
5
|
-
"version": "0.118.
|
|
5
|
+
"version": "0.118.3",
|
|
6
6
|
"description": "Real-time message bus for inter-agent communication. Agent-first: this spec is designed for machine consumption — agents can self-discover the full API surface via GET /api/spec.",
|
|
7
7
|
"license": {
|
|
8
8
|
"name": "MIT",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay-server",
|
|
3
|
-
"version": "0.118.
|
|
3
|
+
"version": "0.118.3",
|
|
4
4
|
"description": "Lightweight HTTP message relay for inter-agent communication across machines",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"CONTRIBUTING.md"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"agent-relay-channels-host": "0.118.
|
|
39
|
+
"agent-relay-channels-host": "0.118.3",
|
|
40
40
|
"agent-relay-providers": "0.104.1",
|
|
41
41
|
"agent-relay-sdk": "0.2.101",
|
|
42
42
|
"ajv": "^8.20.0"
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
import {
|
|
22
22
|
createActivityEvent,
|
|
23
23
|
getActiveMergePause,
|
|
24
|
+
getAgent,
|
|
24
25
|
listOrchestrators,
|
|
25
26
|
listWorkspaces,
|
|
26
27
|
patchWorkspaceMetadata,
|
|
@@ -252,13 +253,43 @@ interface LandSweepResult {
|
|
|
252
253
|
heldByClaim: string[];
|
|
253
254
|
heldByPause: string[];
|
|
254
255
|
heldAwaitingApproval: string[];
|
|
256
|
+
previewUnavailable: string[];
|
|
255
257
|
backedOff: string[];
|
|
256
258
|
leftForSteward: string[];
|
|
257
259
|
wokeStewards: string[];
|
|
258
260
|
}
|
|
259
261
|
|
|
260
262
|
function emptyLandSweep(): LandSweepResult {
|
|
261
|
-
return { scanned: 0, merged: [], heldByLease: [], heldByClaim: [], heldByPause: [], heldAwaitingApproval: [], backedOff: [], leftForSteward: [], wokeStewards: [] };
|
|
263
|
+
return { scanned: 0, merged: [], heldByLease: [], heldByClaim: [], heldByPause: [], heldAwaitingApproval: [], previewUnavailable: [], backedOff: [], leftForSteward: [], wokeStewards: [] };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function workspaceOrchestrators(
|
|
267
|
+
ws: WorkspaceRecord,
|
|
268
|
+
orchestrators: ReturnType<typeof listOrchestrators>,
|
|
269
|
+
): ReturnType<typeof listOrchestrators> {
|
|
270
|
+
const candidates = orchestrators.filter((candidate) => workspacePathWithinBase(ws.sourceCwd, candidate.baseDir));
|
|
271
|
+
const ownerMachine = ws.ownerAgentId ? getAgent(ws.ownerAgentId)?.machine : undefined;
|
|
272
|
+
if (!ownerMachine) return candidates;
|
|
273
|
+
return [...candidates].sort((a, b) => {
|
|
274
|
+
const aOwner = a.hostname === ownerMachine || a.id === ownerMachine ? 0 : 1;
|
|
275
|
+
const bOwner = b.hostname === ownerMachine || b.id === ownerMachine ? 0 : 1;
|
|
276
|
+
return aOwner - bOwner;
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async function fetchFirstUsableMergePreview(
|
|
281
|
+
ws: WorkspaceRecord,
|
|
282
|
+
orchestrators: ReturnType<typeof listOrchestrators>,
|
|
283
|
+
): Promise<WorkspaceMergePreview | { available: false } | null> {
|
|
284
|
+
for (const orch of workspaceOrchestrators(ws, orchestrators)) {
|
|
285
|
+
if (!orch.apiUrl) continue;
|
|
286
|
+
const preview = await fetchHostMergePreview(orch.apiUrl, ws);
|
|
287
|
+
if (!preview || (preview as { available?: false }).available === false) continue;
|
|
288
|
+
const p = preview as WorkspaceMergePreview;
|
|
289
|
+
if (p.error || p.missing) continue;
|
|
290
|
+
return p;
|
|
291
|
+
}
|
|
292
|
+
return null;
|
|
262
293
|
}
|
|
263
294
|
|
|
264
295
|
// Deterministic auto-land (Layer 0, #167/#207/#242): land conflict-free ready work
|
|
@@ -269,7 +300,7 @@ async function landCandidates(
|
|
|
269
300
|
orchestrators: ReturnType<typeof listOrchestrators>,
|
|
270
301
|
): Promise<LandSweepResult> {
|
|
271
302
|
const stewardEnabled = getStewardConfig().enabled;
|
|
272
|
-
const merged: string[] = [];
|
|
303
|
+
const merged: string[] = [], previewUnavailable: string[] = [];
|
|
273
304
|
const heldByLease: string[] = [], heldByClaim: string[] = [], heldByPause: string[] = [], heldAwaitingApproval: string[] = [], backedOff: string[] = [], leftForSteward: string[] = [], wokeStewards: string[] = [];
|
|
274
305
|
|
|
275
306
|
for (const ws of candidates) {
|
|
@@ -286,12 +317,12 @@ async function landCandidates(
|
|
|
286
317
|
escalateNoProgressMerge(ws);
|
|
287
318
|
continue;
|
|
288
319
|
}
|
|
289
|
-
const
|
|
290
|
-
if (!
|
|
291
|
-
|
|
292
|
-
|
|
320
|
+
const preview = await fetchFirstUsableMergePreview(ws, orchestrators);
|
|
321
|
+
if (!preview) {
|
|
322
|
+
previewUnavailable.push(ws.id);
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
293
325
|
const p = preview as WorkspaceMergePreview;
|
|
294
|
-
if (p.error || p.missing) continue;
|
|
295
326
|
if (p.reason === DIRTY_WORKTREE_LAND_SKIP_REASON) {
|
|
296
327
|
patchWorkspaceMetadata(ws.id, { lastLandSkipReason: p.reason, lastLandSkipAt: Date.now() });
|
|
297
328
|
} else if (ws.metadata.lastLandSkipReason === DIRTY_WORKTREE_LAND_SKIP_REASON) {
|
|
@@ -354,7 +385,7 @@ async function landCandidates(
|
|
|
354
385
|
});
|
|
355
386
|
}
|
|
356
387
|
|
|
357
|
-
return { scanned: candidates.length, merged, heldByLease, heldByClaim, heldByPause, heldAwaitingApproval, backedOff, leftForSteward, wokeStewards };
|
|
388
|
+
return { scanned: candidates.length, merged, heldByLease, heldByClaim, heldByPause, heldAwaitingApproval, previewUnavailable, backedOff, leftForSteward, wokeStewards };
|
|
358
389
|
}
|
|
359
390
|
|
|
360
391
|
// Coalesced, fire-and-forget per-repo land trigger (see module header). A run already
|