nexus-prime 6.1.0 → 6.2.0
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/dist/agents/adapters/mcp/handlers/orchestration.js +31 -0
- package/dist/agents/adapters/mcp.js +6 -1
- package/dist/architects/bootstrap.js +52 -28
- package/dist/dashboard/routes/governance.js +4 -0
- package/dist/engines/event-bus.d.ts +8 -1
- package/dist/synapse/bootstrap.js +1 -1
- package/dist/synapse/mandate/pipeline.js +6 -1
- package/package.json +2 -1
|
@@ -333,6 +333,36 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
|
|
|
333
333
|
const executionPreset = request.params.arguments?.executionPreset
|
|
334
334
|
? String(request.params.arguments.executionPreset)
|
|
335
335
|
: undefined;
|
|
336
|
+
// Auto-apply token optimization when explicit files are provided.
|
|
337
|
+
// Gives agents an upfront reading plan before orchestrate runs.
|
|
338
|
+
// No-files path relies on knowledge fabric (handled inside orchestrate).
|
|
339
|
+
let upfrontTokenNote = '';
|
|
340
|
+
if (files && files.length > 3) {
|
|
341
|
+
try {
|
|
342
|
+
const statLimit = pLimit(8);
|
|
343
|
+
const fileRefs = await Promise.all(files.map((p) => statLimit(async () => {
|
|
344
|
+
const resolved = hctx.resolveToolPath(p, request.params.arguments ?? {});
|
|
345
|
+
try {
|
|
346
|
+
const stat = await fsPromises.stat(resolved);
|
|
347
|
+
return { path: resolved, sizeBytes: stat.size, lastModified: stat.mtimeMs };
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
return { path: resolved, sizeBytes: 0 };
|
|
351
|
+
}
|
|
352
|
+
})));
|
|
353
|
+
const upfrontPlan = await getTokenEngine().plan(prompt, fileRefs);
|
|
354
|
+
if (upfrontPlan.savings > 0) {
|
|
355
|
+
const pct = upfrontPlan.totalEstimatedTokens > 0
|
|
356
|
+
? Math.round(upfrontPlan.savings / (upfrontPlan.totalEstimatedTokens + upfrontPlan.savings) * 100)
|
|
357
|
+
: 0;
|
|
358
|
+
upfrontTokenNote = `Token plan: ${upfrontPlan.files.filter(a => a.action === 'full').length} full reads, ${upfrontPlan.files.filter(a => a.action === 'outline').length} outlines, ${upfrontPlan.files.filter(a => a.action === 'skip').length} skipped. ~${upfrontPlan.savings.toLocaleString()} tokens saved (${pct}%). `;
|
|
359
|
+
nexusEventBus.emit('tokens.optimized', { savings: upfrontPlan.savings, pct, source: 'orchestrate-preflight' });
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
// Non-fatal: proceed without upfront plan
|
|
364
|
+
}
|
|
365
|
+
}
|
|
336
366
|
try {
|
|
337
367
|
const preset = resolveExecutionPreset(executionPreset);
|
|
338
368
|
const execution = await hctx.nexusRef.orchestrate(prompt, applyExecutionPreset({
|
|
@@ -459,6 +489,7 @@ export async function handleOrchestrationGroup(toolName, hctx, request, args, ct
|
|
|
459
489
|
content: [{
|
|
460
490
|
type: 'text',
|
|
461
491
|
text: [
|
|
492
|
+
upfrontTokenNote ? `[Token plan] ${upfrontTokenNote}` : '',
|
|
462
493
|
`Orchestrated run ${execution.state}.`,
|
|
463
494
|
formatBullets([
|
|
464
495
|
`Workspace: ${workspace.repoName} (${workspace.workspaceSource})`,
|
|
@@ -913,9 +913,14 @@ export class MCPAdapter {
|
|
|
913
913
|
const swarm = await this.getOrchestrator().induce(goal);
|
|
914
914
|
nexusEventBus.emit('nexusnet.sync', { newItemsCount: swarm.length });
|
|
915
915
|
}
|
|
916
|
-
// v6: Lazy-init Synapse/Architects on first tool call if not yet initialized
|
|
916
|
+
// v6: Lazy-init Synapse/Architects on first tool call if not yet initialized.
|
|
917
|
+
// Mandate + hire tools need Architects live so coordination bridge is set before
|
|
918
|
+
// executeMandatePipeline runs (otherwise worklistId is null, orphaned teams).
|
|
917
919
|
if (toolName.startsWith('nexus_synapse_')) {
|
|
918
920
|
this.nexusRef.ensureSynapseInit();
|
|
921
|
+
if (toolName === 'nexus_synapse_mandate' || toolName === 'nexus_synapse_assign_mission' || toolName === 'nexus_synapse_hire') {
|
|
922
|
+
this.nexusRef.ensureArchitectsInit();
|
|
923
|
+
}
|
|
919
924
|
}
|
|
920
925
|
const synapseResponse = await handleSynapseToolCall(toolName, args, this.nexusRef.getSynapse?.() ?? null);
|
|
921
926
|
if (synapseResponse) {
|
|
@@ -185,41 +185,65 @@ export function initArchitects(options) {
|
|
|
185
185
|
if (hasOperative)
|
|
186
186
|
ward.start();
|
|
187
187
|
const onOperativeHired = ({ operativeId, strikeTeamId }) => {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
188
|
+
try {
|
|
189
|
+
knownOperatives.add(operativeId);
|
|
190
|
+
operativeActivity.set(operativeId, { strikeTeamId, lastSortieAt: null });
|
|
191
|
+
ensureImplicitWorklist(strikeTeamId);
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
console.error('[Architects] onOperativeHired failed', operativeId, err);
|
|
195
|
+
nexusEventBus.emit('architects.event.failed', { event: 'operative.hired', operativeId, error: String(err) });
|
|
196
|
+
}
|
|
191
197
|
};
|
|
192
198
|
const onMissionAssigned = ({ operativeId, missionId, title }) => {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
199
|
+
try {
|
|
200
|
+
const activity = operativeActivity.get(operativeId);
|
|
201
|
+
const strikeTeamId = activity?.strikeTeamId ?? null;
|
|
202
|
+
if (!strikeTeamId)
|
|
203
|
+
return;
|
|
204
|
+
const worklistId = ensureImplicitWorklist(strikeTeamId);
|
|
205
|
+
upsertWorkItem(db, {
|
|
206
|
+
id: missionId,
|
|
207
|
+
worklistId,
|
|
208
|
+
title,
|
|
209
|
+
status: 'todo',
|
|
210
|
+
assignedOperativeId: operativeId,
|
|
211
|
+
constructionLockId: null,
|
|
212
|
+
dependsOn: [],
|
|
213
|
+
branch: null,
|
|
214
|
+
mergedAt: null,
|
|
215
|
+
createdAt: new Date().toISOString(),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
console.error('[Architects] onMissionAssigned failed', missionId, err);
|
|
220
|
+
nexusEventBus.emit('architects.event.failed', { event: 'mission.assigned', operativeId, missionId, error: String(err) });
|
|
221
|
+
}
|
|
210
222
|
};
|
|
211
223
|
const onSortieCompleted = ({ operativeId, missionId, status }) => {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
224
|
+
try {
|
|
225
|
+
const activity = operativeActivity.get(operativeId);
|
|
226
|
+
if (activity) {
|
|
227
|
+
activity.lastSortieAt = new Date().toISOString();
|
|
228
|
+
operativeActivity.set(operativeId, activity);
|
|
229
|
+
}
|
|
230
|
+
if (!missionId)
|
|
231
|
+
return;
|
|
232
|
+
updateWorkItemStatus(db, missionId, status === 'completed' ? 'done' : status === 'failed' ? 'failed' : 'blocked');
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
console.error('[Architects] onSortieCompleted failed', missionId, err);
|
|
236
|
+
nexusEventBus.emit('architects.event.failed', { event: 'sortie.completed', operativeId, missionId: missionId ?? undefined, error: String(err) });
|
|
216
237
|
}
|
|
217
|
-
if (!missionId)
|
|
218
|
-
return;
|
|
219
|
-
updateWorkItemStatus(db, missionId, status === 'completed' ? 'done' : status === 'failed' ? 'failed' : 'blocked');
|
|
220
238
|
};
|
|
221
239
|
const onStriketeamDeployed = ({ strikeTeamId }) => {
|
|
222
|
-
|
|
240
|
+
try {
|
|
241
|
+
ensureImplicitWorklist(strikeTeamId);
|
|
242
|
+
}
|
|
243
|
+
catch (err) {
|
|
244
|
+
console.error('[Architects] onStriketeamDeployed failed', strikeTeamId, err);
|
|
245
|
+
nexusEventBus.emit('architects.event.failed', { event: 'striketeam.deployed', strikeTeamId, error: String(err) });
|
|
246
|
+
}
|
|
223
247
|
};
|
|
224
248
|
const onStanddown = () => setConvergencePaused(true);
|
|
225
249
|
const onResumed = () => setConvergencePaused(false);
|
|
@@ -120,6 +120,10 @@ export const handleGovernanceRoutes = async (ctx, req, res, url) => {
|
|
|
120
120
|
return true;
|
|
121
121
|
}
|
|
122
122
|
if (req.method === 'POST' && url.pathname === '/api/synapse/deploy-crew') {
|
|
123
|
+
// Ensure Architects is live before mandate so coordination bridge is wired.
|
|
124
|
+
// getSynapse() triggers ensureSynapseInit(); getArchitects() triggers ensureArchitectsInit()
|
|
125
|
+
// + reconnectSynapseCoordination() so worklistId is non-null in the pipeline.
|
|
126
|
+
ctx.getArchitects();
|
|
123
127
|
const synapse = ctx.getSynapse();
|
|
124
128
|
if (!synapse) {
|
|
125
129
|
const initErr = ctx.getSynapseInitError();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type NexusEventType = 'system.boot' | 'planner.stage' | 'memory.store' | 'memory.dedup' | 'memory.recall' | 'memory.flushed' | 'memory.health.tick' | 'memory.sqlite.retry' | 'pod.signal' | 'tokens.optimized' | 'tokens.searchSaved' | 'session.summaryBootstrap' | 'phantom.worker.start' | 'phantom.worker.complete' | 'phantom.merge.complete' | 'phantom.merge' | 'guardrail.check' | 'ghost.pass' | 'graph.query' | 'graph.sync.failed' | 'graph.coverage.low' | 'graph.cr.build.start' | 'graph.cr.build.complete' | 'graph.cr.build.failed' | 'darwin.cycle' | 'darwin.cycle.complete' | 'session.dna' | 'skill.register' | 'skill.deploy' | 'skill.revoke' | 'hook.deploy' | 'hook.revoke' | 'hook.fire' | 'hook.error' | 'workflow.deploy' | 'workflow.run' | 'automation.deploy' | 'automation.revoke' | 'automation.run' | 'shield.decision' | 'memory.audit' | 'federation.heartbeat' | 'client.heartbeat' | 'client.inferred' | 'client.status' | 'dashboard.action' | 'nexus.shutdown' | 'orchestrator.disposed' | 'orchestrator.funnel.stage' | 'nexusnet.publish' | 'nexusnet.sync' | 'mcp.call.start' | 'mcp.call.stream' | 'mcp.call.complete' | 'mcp.handler.complete' | 'mcp.handler.failed' | 'mcp.handler.retry' | 'mcp.handler.best-effort-failed' | 'tool.invocation' | 'memory.tier.promoted' | 'memory.tier.promoted.failed' | 'memory.pre-compaction' | 'memory.flush-requested' | 'entanglement.create' | 'entanglement.collapse' | 'entanglement.correlate' | 'cas.encode' | 'cas.decode' | 'cas.pattern_learned' | 'kv.merge' | 'kv.adapt' | 'kv.consensus' | 'byzantine.vote.started' | 'byzantine.vote.result' | 'synapse.ready' | 'synapse.operative.hired' | 'synapse.operative.retired' | 'synapse.operative.health.changed' | 'synapse.striketeam.deployed' | 'synapse.striketeam.completed' | 'synapse.mission.assigned' | 'synapse.mission.completed' | 'synapse.sortie.started' | 'synapse.sortie.completed' | 'synapse.sortie.failed' | 'synapse.fieldreport.submitted' | 'synapse.echo.fired' | 'synapse.budget.warning' | 'synapse.budget.exceeded' | 'synapse.approval.requested' | 'synapse.approval.resolved' | 'synapse.compaction.standdown' | 'synapse.compaction.resumed' | 'synapse.watchdog.stall' | 'synapse.watchdog.zombie' | 'architects.ready' | 'architects.blueprint.instantiated' | 'architects.worklist.created' | 'architects.workitem.claimed' | 'architects.workitem.completed' | 'architects.workitem.blocked' | 'architects.constructionlock.acquired' | 'architects.constructionlock.renewed' | 'architects.constructionlock.released' | 'architects.constructionlock.contested' | 'architects.relay.sent' | 'architects.relay.read' | 'architects.sentinel.patrol' | 'architects.sentinel.stall' | 'architects.sentinel.zombie' | 'architects.ward.patrol' | 'architects.ward.escalation' | 'architects.convergence.started' | 'architects.convergence.merged' | 'architects.convergence.failed' | 'architects.dispatch.go' | 'architects.dispatch.queued' | 'architects.relay.failed' | 'ledger.duplicate-prevented' | 'nexus.circuit-open' | 'nexus.circuit-tripped' | 'license.activated' | 'license.deactivated' | 'license.expired' | 'license.cap.warning' | 'license.cap.reached' | 'dispatch.started' | 'dispatch.event' | 'dispatch.token-usage' | 'dispatch.complete' | 'dispatch.failed' | 'dispatch.cancelled' | 'dispatch.budget-exceeded' | 'mcp.auto-memory.failed' | 'daemon.self-heal.db-corrupt' | 'feature.time_to_first_bootstrap' | 'feature.time_to_first_memory' | 'feature.time_to_first_interaction' | 'feature.time_to_first_mission_complete';
|
|
1
|
+
export type NexusEventType = 'system.boot' | 'planner.stage' | 'memory.store' | 'memory.dedup' | 'memory.recall' | 'memory.flushed' | 'memory.health.tick' | 'memory.sqlite.retry' | 'pod.signal' | 'tokens.optimized' | 'tokens.searchSaved' | 'session.summaryBootstrap' | 'phantom.worker.start' | 'phantom.worker.complete' | 'phantom.merge.complete' | 'phantom.merge' | 'guardrail.check' | 'ghost.pass' | 'graph.query' | 'graph.sync.failed' | 'graph.coverage.low' | 'graph.cr.build.start' | 'graph.cr.build.complete' | 'graph.cr.build.failed' | 'darwin.cycle' | 'darwin.cycle.complete' | 'session.dna' | 'skill.register' | 'skill.deploy' | 'skill.revoke' | 'hook.deploy' | 'hook.revoke' | 'hook.fire' | 'hook.error' | 'workflow.deploy' | 'workflow.run' | 'automation.deploy' | 'automation.revoke' | 'automation.run' | 'shield.decision' | 'memory.audit' | 'federation.heartbeat' | 'client.heartbeat' | 'client.inferred' | 'client.status' | 'dashboard.action' | 'nexus.shutdown' | 'orchestrator.disposed' | 'orchestrator.funnel.stage' | 'nexusnet.publish' | 'nexusnet.sync' | 'mcp.call.start' | 'mcp.call.stream' | 'mcp.call.complete' | 'mcp.handler.complete' | 'mcp.handler.failed' | 'mcp.handler.retry' | 'mcp.handler.best-effort-failed' | 'tool.invocation' | 'memory.tier.promoted' | 'memory.tier.promoted.failed' | 'memory.pre-compaction' | 'memory.flush-requested' | 'entanglement.create' | 'entanglement.collapse' | 'entanglement.correlate' | 'cas.encode' | 'cas.decode' | 'cas.pattern_learned' | 'kv.merge' | 'kv.adapt' | 'kv.consensus' | 'byzantine.vote.started' | 'byzantine.vote.result' | 'synapse.ready' | 'synapse.operative.hired' | 'synapse.operative.retired' | 'synapse.operative.health.changed' | 'synapse.striketeam.deployed' | 'synapse.striketeam.completed' | 'synapse.mission.assigned' | 'synapse.mission.completed' | 'synapse.sortie.started' | 'synapse.sortie.completed' | 'synapse.sortie.failed' | 'synapse.fieldreport.submitted' | 'synapse.echo.fired' | 'synapse.budget.warning' | 'synapse.budget.exceeded' | 'synapse.approval.requested' | 'synapse.approval.resolved' | 'synapse.compaction.standdown' | 'synapse.compaction.resumed' | 'synapse.watchdog.stall' | 'synapse.watchdog.zombie' | 'architects.ready' | 'architects.blueprint.instantiated' | 'architects.worklist.created' | 'architects.workitem.claimed' | 'architects.workitem.completed' | 'architects.workitem.blocked' | 'architects.constructionlock.acquired' | 'architects.constructionlock.renewed' | 'architects.constructionlock.released' | 'architects.constructionlock.contested' | 'architects.relay.sent' | 'architects.relay.read' | 'architects.sentinel.patrol' | 'architects.sentinel.stall' | 'architects.sentinel.zombie' | 'architects.ward.patrol' | 'architects.ward.escalation' | 'architects.convergence.started' | 'architects.convergence.merged' | 'architects.convergence.failed' | 'architects.dispatch.go' | 'architects.dispatch.queued' | 'architects.relay.failed' | 'architects.event.failed' | 'ledger.duplicate-prevented' | 'nexus.circuit-open' | 'nexus.circuit-tripped' | 'license.activated' | 'license.deactivated' | 'license.expired' | 'license.cap.warning' | 'license.cap.reached' | 'dispatch.started' | 'dispatch.event' | 'dispatch.token-usage' | 'dispatch.complete' | 'dispatch.failed' | 'dispatch.cancelled' | 'dispatch.budget-exceeded' | 'mcp.auto-memory.failed' | 'daemon.self-heal.db-corrupt' | 'feature.time_to_first_bootstrap' | 'feature.time_to_first_memory' | 'feature.time_to_first_interaction' | 'feature.time_to_first_mission_complete';
|
|
2
2
|
export interface NexusEventPayloads {
|
|
3
3
|
'system.boot': {
|
|
4
4
|
version: string;
|
|
@@ -625,6 +625,13 @@ export interface NexusEventPayloads {
|
|
|
625
625
|
subject: string;
|
|
626
626
|
error: string;
|
|
627
627
|
};
|
|
628
|
+
'architects.event.failed': {
|
|
629
|
+
event: string;
|
|
630
|
+
operativeId?: string;
|
|
631
|
+
missionId?: string;
|
|
632
|
+
strikeTeamId?: string;
|
|
633
|
+
error: string;
|
|
634
|
+
};
|
|
628
635
|
'ledger.duplicate-prevented': {
|
|
629
636
|
fingerprint: string;
|
|
630
637
|
existingId: string;
|
|
@@ -144,7 +144,7 @@ export function initSynapse(options) {
|
|
|
144
144
|
if (payload.operativeId) {
|
|
145
145
|
db.prepare('UPDATE synapse_operatives SET health_state=\'BLOCKED\', state=\'SUSPENDED\', suspend_reason=\'manual\' WHERE id=?').run(payload.operativeId);
|
|
146
146
|
nexusEventBus.emit('synapse.operative.health.changed', { operativeId: payload.operativeId, healthState: 'BLOCKED' });
|
|
147
|
-
providers.memory.store(`[Architects:Blocked] ${payload.operativeId} ${payload.reason ?? ''}`.trim(), 0.82, ['#synapse', '#blocked']);
|
|
147
|
+
providers.memory.store(`[Architects:Blocked] ${payload.operativeId} ${payload.reason ?? ''}`.trim(), 0.82, ['#synapse', '#blocked'], undefined, 0, { provenance: { agentId: payload.operativeId, source: 'system' } });
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
150
|
const stallListener = ({ operativeId }) => {
|
|
@@ -157,7 +157,12 @@ export async function executeMandatePipeline(db, mandateText, providers, opts =
|
|
|
157
157
|
correlationId: teamId,
|
|
158
158
|
status: 'deployed',
|
|
159
159
|
});
|
|
160
|
-
providers.memory.store(`[Synapse:Mandate] ${mandateText}`, 0.85, ['#synapse', '#mandate', `#team:${teamId}`]
|
|
160
|
+
providers.memory.store(`[Synapse:Mandate] ${mandateText}`, 0.85, ['#synapse', '#mandate', `#team:${teamId}`], undefined, 0, {
|
|
161
|
+
provenance: {
|
|
162
|
+
source: 'runtime',
|
|
163
|
+
containerTags: [`#team:${teamId}`, ...(worklistId ? [`#worklist:${worklistId}`] : [])],
|
|
164
|
+
},
|
|
165
|
+
});
|
|
161
166
|
return getStrikeTeam(db, teamId);
|
|
162
167
|
})();
|
|
163
168
|
return team;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexus-prime",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
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",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"nexus-prime": "dist/cli.js"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
|
+
"prepare": "git config core.hooksPath .hooks || true",
|
|
28
29
|
"nexus:dev": "node dev-orchestrator.mjs",
|
|
29
30
|
"generate:competitive-landscape": "tsx scripts/generate-competitive-landscape.ts",
|
|
30
31
|
"generate:readme-catalog": "tsx scripts/generate-readme-runtime-catalog.ts",
|