nexus-prime 7.9.23 → 7.9.24

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.
@@ -19,6 +19,7 @@ import { recordToolInvocation } from './tool-health.js';
19
19
  import { getAsyncGate, withAsyncGate } from './async-gate.js';
20
20
  import { getCircuitManager, checkBackpressure } from './circuit.js';
21
21
  import { completeRun, createRun, failRun, updateStage } from '../../../engines/orchestrator/store.js';
22
+ import { buildSelectionPlan } from '../../../engines/orchestrator/decision-spine.js';
22
23
  function summarizeAsyncMcpResult(toolName, result) {
23
24
  const text = result?.content
24
25
  ?.map((part) => part?.type === 'text' ? String(part.text ?? '') : '')
@@ -109,6 +110,152 @@ function resolveMaxSyncMs(toolName, args) {
109
110
  ?? coerceBoundedWaitMs(args.maxSyncMs)
110
111
  ?? (toolName === 'nexus_orchestrate' ? ORCHESTRATE_DEFAULT_MAX_SYNC_MS : DEFAULT_MAX_SYNC_MS);
111
112
  }
113
+ function asStringList(value) {
114
+ if (Array.isArray(value)) {
115
+ return value
116
+ .map((item) => typeof item === 'string' ? item : (item && typeof item === 'object' ? String(item.name ?? item.id ?? '') : String(item ?? '')))
117
+ .map((item) => item.trim())
118
+ .filter(Boolean);
119
+ }
120
+ if (typeof value === 'string') {
121
+ return value.split(',')
122
+ .map((item) => item.trim())
123
+ .filter(Boolean);
124
+ }
125
+ return [];
126
+ }
127
+ function uniqueList(items, max = 8) {
128
+ const seen = new Set();
129
+ const out = [];
130
+ for (const item of items) {
131
+ const value = String(item ?? '').trim();
132
+ if (!value || seen.has(value))
133
+ continue;
134
+ seen.add(value);
135
+ out.push(value);
136
+ if (out.length >= max)
137
+ break;
138
+ }
139
+ return out;
140
+ }
141
+ function extractLinkedSelectors(prompt, prefix) {
142
+ const escaped = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
143
+ const pattern = new RegExp(`\\[${escaped}([^\\]\\s]+)\\]`, 'g');
144
+ return Array.from(prompt.matchAll(pattern))
145
+ .map((match) => match[1]?.trim())
146
+ .filter(Boolean);
147
+ }
148
+ function inferQueuedOrchestratePreview(args, runId) {
149
+ const prompt = String(args.prompt ?? args.goal ?? '');
150
+ const lower = prompt.toLowerCase();
151
+ const files = uniqueList([
152
+ ...asStringList(args.files),
153
+ ...asStringList(args.filePaths),
154
+ ], 20);
155
+ const skills = uniqueList([
156
+ ...asStringList(args.skills),
157
+ ...asStringList(args.skillNames),
158
+ ...extractLinkedSelectors(prompt, '$'),
159
+ ], 20);
160
+ const workflows = uniqueList([
161
+ ...asStringList(args.workflows),
162
+ ...asStringList(args.workflowSelectors),
163
+ lower.match(/orchestrat|route|dispatch|queue|queued/) ? 'orchestration-runtime-workflow' : undefined,
164
+ lower.match(/synapse|hiring|operative|sortie/) ? 'synapse-mandate-workflow' : undefined,
165
+ lower.match(/memory|recall|learning|decay|graph/) ? 'memory-lifecycle-workflow' : undefined,
166
+ lower.match(/token|budget|optim/i) ? 'token-budget-workflow' : undefined,
167
+ lower.match(/dashboard|board|ui|ux/) ? 'dashboard-observability-workflow' : undefined,
168
+ ], 8);
169
+ const specialists = uniqueList([
170
+ ...asStringList(args.specialists),
171
+ lower.match(/orchestrat|route|dispatch|queue|queued/) ? 'Orchestrator Runtime Engineer' : undefined,
172
+ lower.match(/synapse|hiring|operative|sortie/) ? 'Synapse Runtime Engineer' : undefined,
173
+ lower.match(/memory|recall|learning|decay|graph/) ? 'Memory Systems Engineer' : undefined,
174
+ lower.match(/token|budget|optim/i) ? 'Token Budget Engineer' : undefined,
175
+ lower.match(/dashboard|board|ui|ux/) ? 'Dashboard UX Engineer' : undefined,
176
+ lower.match(/test|verify|qa|release|publish/) ? 'Verification Engineer' : undefined,
177
+ ], 8);
178
+ const crew = String(args.crew ?? args.selectedCrew ?? (lower.match(/orchestrat|synapse|runtime|mcp|dispatch|queue|queued/)
179
+ ? 'Runtime Reliability Crew'
180
+ : lower.match(/memory|token|dashboard/)
181
+ ? 'Control Plane Quality Crew'
182
+ : 'Nexus Implementation Crew'));
183
+ const risk = lower.match(/fix|broken|bug|doesn.?t|failed|queued|runtime|synapse|orchestrat/) ? 'high' : 'medium';
184
+ const task = {
185
+ goal: prompt,
186
+ intent: lower.match(/fix|bug|broken|doesn.?t|failed/) ? 'bugfix' : 'feature',
187
+ files,
188
+ skillNames: skills,
189
+ workflowSelectors: workflows,
190
+ };
191
+ const workerManifests = uniqueList([
192
+ specialists.length > 0 ? 'worker_coder' : undefined,
193
+ 'worker_verifier',
194
+ ]).map((workerId, index) => ({
195
+ workerId,
196
+ role: index === 0 ? 'coder' : 'verifier',
197
+ specialistName: index === 0 ? specialists[0] : 'Verification Engineer',
198
+ actions: index === 0 ? ['inspect', 'patch'] : ['verify'],
199
+ verifyCommands: index === 1 ? ['npm run lint', 'targeted tests'] : [],
200
+ }));
201
+ const run = {
202
+ runId,
203
+ requestBrief: {
204
+ id: `brief_${runId}`,
205
+ intent: task.intent,
206
+ risk,
207
+ confidence: 0.68,
208
+ },
209
+ plannerResult: {
210
+ selectedFiles: files,
211
+ selectedSkills: skills,
212
+ selectedWorkflows: workflows,
213
+ selectedSpecialists: specialists.map((name) => ({ name })),
214
+ selectedCrew: { name: crew },
215
+ },
216
+ workerManifests,
217
+ };
218
+ const plan = buildSelectionPlan({ run, task });
219
+ return { plan, crew, specialists, workflows };
220
+ }
221
+ function formatBudgetRoute(plan) {
222
+ const total = Number(plan.budgets?.total ?? 0);
223
+ const code = Number(plan.budgets?.codeBlocks ?? plan.budgets?.codeBlockPolicy?.reservedTokens ?? 0);
224
+ const cap = Number(plan.executionPolicy?.agentFlow?.maxTaskCostUsd ?? plan.executionPolicy?.budgetCapUsd ?? 0);
225
+ return `${total.toLocaleString()} tokens · ${code.toLocaleString()} code-block tokens · $${cap.toFixed(2)} task cap`;
226
+ }
227
+ function formatQueuedOrchestrateReceipt(args, receipt) {
228
+ const preview = inferQueuedOrchestratePreview(args, receipt.runId);
229
+ const plan = preview.plan;
230
+ const stages = Array.isArray(plan.executionPolicy?.agentFlow?.stages)
231
+ ? plan.executionPolicy.agentFlow.stages
232
+ : [];
233
+ const selected = plan.selected ?? {};
234
+ const specialists = uniqueList([...(selected.specialists ?? []), ...preview.specialists], 8);
235
+ const workflows = uniqueList([...(selected.workflows ?? []), ...preview.workflows], 8);
236
+ const skills = uniqueList(selected.skills ?? [], 8);
237
+ const receiptJson = JSON.stringify({ queued: true, runId: receipt.runId, etaMs: receipt.etaMs }, null, 2);
238
+ const hiredLine = [
239
+ `crew ${preview.crew}`,
240
+ specialists.length ? `specialists ${specialists.join(', ')}` : '',
241
+ workflows.length ? `workflows ${workflows.join(', ')}` : '',
242
+ skills.length ? `skills ${skills.join(', ')}` : '',
243
+ ].filter(Boolean).join(' · ');
244
+ return [
245
+ 'Nexus orchestration queued with hiring preflight.',
246
+ `Run: ${receipt.runId}`,
247
+ `ETA: ${receipt.etaMs ? `~${Math.ceil(receipt.etaMs / 1000)}s` : 'background'}`,
248
+ `Hired/selected: ${hiredLine}`,
249
+ `Model route: ${plan.modelRoute?.workerTier ?? 'T1'}${plan.modelRoute?.reviewerTier ? ` + reviewer ${plan.modelRoute.reviewerTier}` : ''}`,
250
+ `Budget route: ${formatBudgetRoute(plan)}`,
251
+ stages.length ? `AgentFlow gates: ${stages.map((stage) => `${stage.stage}:${stage.ownerRole}`).join(' -> ')}` : '',
252
+ 'Poll progress with nexus_run_status(runId).',
253
+ '',
254
+ '```json',
255
+ receiptJson,
256
+ '```',
257
+ ].filter((line) => line !== '').join('\n');
258
+ }
112
259
  /**
113
260
  * Route a tool call to the appropriate handler group.
114
261
  *
@@ -232,8 +379,10 @@ export async function dispatchMcpToolCall(hctx, request, args, ctx) {
232
379
  rawResult = {
233
380
  content: [{
234
381
  type: 'text',
235
- text: JSON.stringify({ queued: true, runId: gated.runId, etaMs: gated.etaMs }, null, 2)
236
- + '\n\nCall nexus_run_status(runId) to check progress.',
382
+ text: toolName === 'nexus_orchestrate'
383
+ ? formatQueuedOrchestrateReceipt(args, gated)
384
+ : JSON.stringify({ queued: true, runId: gated.runId, etaMs: gated.etaMs }, null, 2)
385
+ + '\n\nCall nexus_run_status(runId) to check progress.',
237
386
  }],
238
387
  };
239
388
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexus-prime",
3
- "version": "7.9.23",
3
+ "version": "7.9.24",
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",