nexus-prime 7.9.5 → 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
- // Race: handler vs deadline
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
- }, { tool: toolName, args, maxSyncMs: 2000, etaMs: TOOL_ETA_MS[toolName] });
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') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexus-prime",
3
- "version": "7.9.5",
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",