nexus-prime 7.9.4 → 7.9.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.
|
@@ -41,6 +41,8 @@ export interface AsyncGateOpts {
|
|
|
41
41
|
maxSyncMs?: number;
|
|
42
42
|
/** Human-readable hint for estimated duration */
|
|
43
43
|
etaMs?: number;
|
|
44
|
+
/** Return the async receipt before starting work. Use for cold paths that may block synchronously. */
|
|
45
|
+
alwaysQueue?: boolean;
|
|
44
46
|
}
|
|
45
47
|
type HandlerFn = () => Promise<{
|
|
46
48
|
content: Array<{
|
|
@@ -33,10 +33,7 @@ class AsyncGate {
|
|
|
33
33
|
etaMs: opts.etaMs,
|
|
34
34
|
};
|
|
35
35
|
this.enqueueJob(job);
|
|
36
|
-
|
|
37
|
-
let syncResolved = false;
|
|
38
|
-
const deadline = new Promise((resolve) => setTimeout(() => resolve(null), maxSyncMs));
|
|
39
|
-
const work = (async () => {
|
|
36
|
+
const startWork = () => (async () => {
|
|
40
37
|
job.status = 'running';
|
|
41
38
|
job.stage = 'executing';
|
|
42
39
|
job.startedAt = Date.now();
|
|
@@ -64,6 +61,18 @@ class AsyncGate {
|
|
|
64
61
|
};
|
|
65
62
|
}
|
|
66
63
|
})();
|
|
64
|
+
if (opts.alwaysQueue) {
|
|
65
|
+
setImmediate(() => {
|
|
66
|
+
startWork().catch(() => { });
|
|
67
|
+
});
|
|
68
|
+
return { queued: true, runId, etaMs: opts.etaMs };
|
|
69
|
+
}
|
|
70
|
+
// Race: handler vs deadline. Note: this only protects paths that yield
|
|
71
|
+
// quickly. Cold synchronous work should set alwaysQueue so the receipt is
|
|
72
|
+
// returned before the heavy section starts.
|
|
73
|
+
let syncResolved = false;
|
|
74
|
+
const deadline = new Promise((resolve) => setTimeout(() => resolve(null), maxSyncMs));
|
|
75
|
+
const work = startWork();
|
|
67
76
|
// Suppress unhandled rejection: deadline may win while work is still in flight.
|
|
68
77
|
work.catch(() => { });
|
|
69
78
|
const winner = await Promise.race([
|
|
@@ -124,7 +124,13 @@ export async function dispatchMcpToolCall(hctx, request, args, ctx) {
|
|
|
124
124
|
const gated = await withAsyncGate(async () => {
|
|
125
125
|
const r = await runHandlers();
|
|
126
126
|
return r ?? { content: [{ type: 'text', text: `Tool ${toolName} returned no result` }] };
|
|
127
|
-
}, {
|
|
127
|
+
}, {
|
|
128
|
+
tool: toolName,
|
|
129
|
+
args,
|
|
130
|
+
maxSyncMs: 2000,
|
|
131
|
+
etaMs: TOOL_ETA_MS[toolName],
|
|
132
|
+
alwaysQueue: toolName === 'nexus_orchestrate',
|
|
133
|
+
});
|
|
128
134
|
if ('queued' in gated && gated.queued) {
|
|
129
135
|
// Persist orchestration run record for durable stage tracking
|
|
130
136
|
if (toolName === 'nexus_orchestrate') {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* runtime-badge.js — Push-mode runtime availability badges.
|
|
3
3
|
*
|
|
4
|
-
* Fetches GET /api/
|
|
4
|
+
* Fetches GET /api/invokers and renders one pill per invoker in the
|
|
5
5
|
* sidebar footer showing amber (unavailable) or green (available) status.
|
|
6
6
|
*
|
|
7
7
|
* Mounts into #runtime-badges (created by index.html in the sidebar foot).
|
|
@@ -21,7 +21,7 @@ export async function refresh() {
|
|
|
21
21
|
const container = $('runtime-badges');
|
|
22
22
|
if (!container) return;
|
|
23
23
|
|
|
24
|
-
const runtimes = await api('/api/
|
|
24
|
+
const runtimes = await api('/api/invokers', 8_000);
|
|
25
25
|
if (!Array.isArray(runtimes)) return;
|
|
26
26
|
|
|
27
27
|
container.innerHTML = runtimes.map(r => _badge(r)).join('');
|
|
@@ -215,7 +215,7 @@ export const handleRuntimeRoutes = async (ctx, req, res, url) => {
|
|
|
215
215
|
return true;
|
|
216
216
|
}
|
|
217
217
|
// ── Push-mode dispatch ────────────────────────────────────────────────────
|
|
218
|
-
if (req.method === 'GET' && url.pathname === '/api/
|
|
218
|
+
if (req.method === 'GET' && url.pathname === '/api/invokers') {
|
|
219
219
|
const availability = await invokerRegistry.listAvailability();
|
|
220
220
|
ctx.respondJson(res, availability);
|
|
221
221
|
return true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexus-prime",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.6",
|
|
4
4
|
"description": "Local-first MCP control plane for coding agents with bootstrap-orchestrate execution, memory fabric, token budgeting, and worktree-backed swarms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|