@neuroverseos/nv-sim 0.1.2 → 0.1.5

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.
Files changed (53) hide show
  1. package/README.md +562 -68
  2. package/dist/adapters/mirofish.js +461 -0
  3. package/dist/adapters/scienceclaw.js +750 -0
  4. package/dist/assets/index-B64NuIXu.css +1 -0
  5. package/dist/assets/index-DbzSnYxr.js +532 -0
  6. package/dist/assets/mirotir-logo-DUexumBH.svg +185 -0
  7. package/dist/assets/reportEngine-DKWTrP6-.js +1 -0
  8. package/dist/components/ConstraintsPanel.js +11 -0
  9. package/dist/components/StakeholderBuilder.js +32 -0
  10. package/dist/components/ui/badge.js +24 -0
  11. package/dist/components/ui/button.js +70 -0
  12. package/dist/components/ui/card.js +57 -0
  13. package/dist/components/ui/input.js +44 -0
  14. package/dist/components/ui/label.js +45 -0
  15. package/dist/components/ui/select.js +70 -0
  16. package/dist/engine/aiProvider.js +681 -0
  17. package/dist/engine/auditTrace.js +352 -0
  18. package/dist/engine/behavioralAnalysis.js +605 -0
  19. package/dist/engine/cli.js +1408 -299
  20. package/dist/engine/dynamicsGovernance.js +588 -0
  21. package/dist/engine/fullGovernedLoop.js +367 -0
  22. package/dist/engine/governance.js +8 -3
  23. package/dist/engine/governedSimulation.js +114 -17
  24. package/dist/engine/index.js +56 -1
  25. package/dist/engine/liveAdapter.js +342 -0
  26. package/dist/engine/liveVisualizer.js +4284 -0
  27. package/dist/engine/metrics/science.metrics.js +335 -0
  28. package/dist/engine/narrativeInjection.js +360 -0
  29. package/dist/engine/policyEnforcement.js +1611 -0
  30. package/dist/engine/policyEngine.js +799 -0
  31. package/dist/engine/primeRadiant.js +540 -0
  32. package/dist/engine/reasoningEngine.js +57 -3
  33. package/dist/engine/reportEngine.js +97 -0
  34. package/dist/engine/scenarioCapsule.js +56 -0
  35. package/dist/engine/scenarioComparison.js +463 -0
  36. package/dist/engine/scenarioLibrary.js +248 -0
  37. package/dist/engine/swarmSimulation.js +54 -1
  38. package/dist/engine/worldComparison.js +358 -0
  39. package/dist/engine/worldStorage.js +232 -0
  40. package/dist/favicon.ico +0 -0
  41. package/dist/index.html +23 -0
  42. package/dist/lib/reasoningEngine.js +290 -0
  43. package/dist/lib/simulationAdapter.js +686 -0
  44. package/dist/lib/swarmParser.js +291 -0
  45. package/dist/lib/types.js +2 -0
  46. package/dist/lib/utils.js +8 -0
  47. package/dist/placeholder.svg +1 -0
  48. package/dist/robots.txt +14 -0
  49. package/dist/runtime/govern.js +473 -0
  50. package/dist/runtime/index.js +75 -0
  51. package/dist/runtime/types.js +11 -0
  52. package/package.json +17 -12
  53. package/variants/.gitkeep +0 -0
@@ -21,7 +21,8 @@
21
21
  * Mirotir helps you decide WHAT TO DO → the brain
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.parseReasonRequestBody = exports.handleRunPreset = exports.handleGetPreset = exports.handleListPresets = exports.handleHealthCheck = exports.handleCreateCapsule = exports.handleReasonFromCapsule = exports.handleReasonRequest = exports.TRADING_DEMO = exports.runGovernedComparison = exports.analyzeMiroFishSimulation = exports.DEFAULT_MIROFISH_CONFIG = exports.buildMiroFishRequest = exports.miroFishResultToSwarmResult = exports.stakeholdersToMiroFishAgents = exports.runUnifiedSimulation = exports.getMiroFishClient = exports.configureMiroFish = exports.MiroFishError = exports.MiroFishClient = exports.runSwarmSimulation = exports.initNeuroverseModule = exports.validationToEnforcedConstraints = exports.simulationToGovernanceSignals = exports.verdictToConstitutionalChecks = exports.validateScenarioWorld = exports.runWorldSimulation = exports.evaluateScenarioGuard = exports.buildWorldFromScenario = exports.runFullGovernanceChecks = exports.runGovernanceChecks = exports.processReasonRequest = exports.SCENARIO_TEMPLATES = exports.getPresetCapsule = exports.extractCapsuleFromUrl = exports.buildShareableUrl = exports.decodeCapsule = exports.encodeCapsule = exports.capsuleToReasonRequest = exports.createCapsule = exports.runGoalReasoning = void 0;
24
+ exports.policyToWorld = exports.validatePolicy = exports.parseRulesFromText = exports.suggestExperiments = exports.formatPolicyDiagnostics = exports.formatGuidedNextSteps = exports.exportEnforcementReportJSON = exports.formatEnforcementReport = exports.createEnforcementSession = exports.formatCrossRunComparison = exports.formatBehavioralAnalysis = exports.compareBehaviorAcrossRuns = exports.detectBehavioralShifts = exports.computeActionDistributions = exports.buildAgentTrajectories = exports.classifyBehavior = exports.analyzeBehavior = exports.TRADING_DEMO = exports.runGovernedComparison = exports.analyzeMiroFishSimulation = exports.DEFAULT_MIROFISH_CONFIG = exports.buildMiroFishRequest = exports.miroFishResultToSwarmResult = exports.stakeholdersToMiroFishAgents = exports.runUnifiedSimulation = exports.getMiroFishClient = exports.configureMiroFish = exports.MiroFishError = exports.MiroFishClient = exports.runSwarmSimulation = exports.initNeuroverseModule = exports.validationToEnforcedConstraints = exports.simulationToGovernanceSignals = exports.verdictToConstitutionalChecks = exports.validateScenarioWorld = exports.runWorldSimulation = exports.evaluateScenarioGuard = exports.buildWorldFromScenario = exports.runFullGovernanceChecks = exports.runGovernanceChecks = exports.processReasonRequest = exports.SCENARIO_TEMPLATES = exports.getPresetCapsule = exports.extractCapsuleFromUrl = exports.buildShareableUrl = exports.decodeCapsule = exports.encodeCapsule = exports.capsuleToReasonRequest = exports.createCapsule = exports.runGoalReasoning = void 0;
25
+ exports.EXAMPLE_WORLD_STATES = exports.EXAMPLE_ACTIONS = exports.createGovernor = exports.govern = exports.extractTrace = exports.generateGovernedReport = exports.formatAuditTrail = exports.searchAuditTrails = exports.loadAuditSession = exports.listAuditSessions = exports.AuditTrail = exports.evaluateAIAction = exports.listAIProviders = exports.getDefaultProviderName = exports.getAIProvider = exports.registerAIProvider = exports.generateAIReaction = exports.generateDeterministicReport = exports.OpenAICompatibleProvider = exports.AnthropicProvider = exports.DeterministicProvider = exports.AI_ROLES = exports.parseReasonRequestBody = exports.handleRunPreset = exports.handleGetPreset = exports.handleListPresets = exports.handleHealthCheck = exports.handleCreateCapsule = exports.handleReasonFromCapsule = exports.handleReasonRequest = exports.applyQuickFix = exports.runPolicyPipeline = void 0;
25
26
  // Goal-Directed Strategy Engine
26
27
  var goalEngine_1 = require("./goalEngine");
27
28
  Object.defineProperty(exports, "runGoalReasoning", { enumerable: true, get: function () { return goalEngine_1.runGoalReasoning; } });
@@ -70,6 +71,28 @@ Object.defineProperty(exports, "analyzeMiroFishSimulation", { enumerable: true,
70
71
  var governedSimulation_1 = require("./governedSimulation");
71
72
  Object.defineProperty(exports, "runGovernedComparison", { enumerable: true, get: function () { return governedSimulation_1.runGovernedComparison; } });
72
73
  Object.defineProperty(exports, "TRADING_DEMO", { enumerable: true, get: function () { return governedSimulation_1.TRADING_DEMO; } });
74
+ var behavioralAnalysis_1 = require("./behavioralAnalysis");
75
+ Object.defineProperty(exports, "analyzeBehavior", { enumerable: true, get: function () { return behavioralAnalysis_1.analyzeBehavior; } });
76
+ Object.defineProperty(exports, "classifyBehavior", { enumerable: true, get: function () { return behavioralAnalysis_1.classifyBehavior; } });
77
+ Object.defineProperty(exports, "buildAgentTrajectories", { enumerable: true, get: function () { return behavioralAnalysis_1.buildAgentTrajectories; } });
78
+ Object.defineProperty(exports, "computeActionDistributions", { enumerable: true, get: function () { return behavioralAnalysis_1.computeActionDistributions; } });
79
+ Object.defineProperty(exports, "detectBehavioralShifts", { enumerable: true, get: function () { return behavioralAnalysis_1.detectBehavioralShifts; } });
80
+ Object.defineProperty(exports, "compareBehaviorAcrossRuns", { enumerable: true, get: function () { return behavioralAnalysis_1.compareBehaviorAcrossRuns; } });
81
+ Object.defineProperty(exports, "formatBehavioralAnalysis", { enumerable: true, get: function () { return behavioralAnalysis_1.formatBehavioralAnalysis; } });
82
+ Object.defineProperty(exports, "formatCrossRunComparison", { enumerable: true, get: function () { return behavioralAnalysis_1.formatCrossRunComparison; } });
83
+ var policyEnforcement_1 = require("./policyEnforcement");
84
+ Object.defineProperty(exports, "createEnforcementSession", { enumerable: true, get: function () { return policyEnforcement_1.createEnforcementSession; } });
85
+ Object.defineProperty(exports, "formatEnforcementReport", { enumerable: true, get: function () { return policyEnforcement_1.formatEnforcementReport; } });
86
+ Object.defineProperty(exports, "exportEnforcementReportJSON", { enumerable: true, get: function () { return policyEnforcement_1.exportEnforcementReportJSON; } });
87
+ Object.defineProperty(exports, "formatGuidedNextSteps", { enumerable: true, get: function () { return policyEnforcement_1.formatGuidedNextSteps; } });
88
+ Object.defineProperty(exports, "formatPolicyDiagnostics", { enumerable: true, get: function () { return policyEnforcement_1.formatPolicyDiagnostics; } });
89
+ Object.defineProperty(exports, "suggestExperiments", { enumerable: true, get: function () { return policyEnforcement_1.suggestExperiments; } });
90
+ var policyEngine_1 = require("./policyEngine");
91
+ Object.defineProperty(exports, "parseRulesFromText", { enumerable: true, get: function () { return policyEngine_1.parseRulesFromText; } });
92
+ Object.defineProperty(exports, "validatePolicy", { enumerable: true, get: function () { return policyEngine_1.validatePolicy; } });
93
+ Object.defineProperty(exports, "policyToWorld", { enumerable: true, get: function () { return policyEngine_1.policyToWorld; } });
94
+ Object.defineProperty(exports, "runPolicyPipeline", { enumerable: true, get: function () { return policyEngine_1.runPolicyPipeline; } });
95
+ Object.defineProperty(exports, "applyQuickFix", { enumerable: true, get: function () { return policyEngine_1.applyQuickFix; } });
73
96
  // API Route Handlers
74
97
  var api_1 = require("./api");
75
98
  Object.defineProperty(exports, "handleReasonRequest", { enumerable: true, get: function () { return api_1.handleReasonRequest; } });
@@ -80,3 +103,35 @@ Object.defineProperty(exports, "handleListPresets", { enumerable: true, get: fun
80
103
  Object.defineProperty(exports, "handleGetPreset", { enumerable: true, get: function () { return api_1.handleGetPreset; } });
81
104
  Object.defineProperty(exports, "handleRunPreset", { enumerable: true, get: function () { return api_1.handleRunPreset; } });
82
105
  Object.defineProperty(exports, "parseReasonRequestBody", { enumerable: true, get: function () { return api_1.parseReasonRequestBody; } });
106
+ var aiProvider_1 = require("./aiProvider");
107
+ Object.defineProperty(exports, "AI_ROLES", { enumerable: true, get: function () { return aiProvider_1.AI_ROLES; } });
108
+ Object.defineProperty(exports, "DeterministicProvider", { enumerable: true, get: function () { return aiProvider_1.DeterministicProvider; } });
109
+ Object.defineProperty(exports, "AnthropicProvider", { enumerable: true, get: function () { return aiProvider_1.AnthropicProvider; } });
110
+ Object.defineProperty(exports, "OpenAICompatibleProvider", { enumerable: true, get: function () { return aiProvider_1.OpenAICompatibleProvider; } });
111
+ Object.defineProperty(exports, "generateDeterministicReport", { enumerable: true, get: function () { return aiProvider_1.generateDeterministicReport; } });
112
+ Object.defineProperty(exports, "generateAIReaction", { enumerable: true, get: function () { return aiProvider_1.generateAIReaction; } });
113
+ Object.defineProperty(exports, "registerAIProvider", { enumerable: true, get: function () { return aiProvider_1.registerAIProvider; } });
114
+ Object.defineProperty(exports, "getAIProvider", { enumerable: true, get: function () { return aiProvider_1.getAIProvider; } });
115
+ Object.defineProperty(exports, "getDefaultProviderName", { enumerable: true, get: function () { return aiProvider_1.getDefaultProviderName; } });
116
+ Object.defineProperty(exports, "listAIProviders", { enumerable: true, get: function () { return aiProvider_1.listAIProviders; } });
117
+ Object.defineProperty(exports, "evaluateAIAction", { enumerable: true, get: function () { return aiProvider_1.evaluateAIAction; } });
118
+ var auditTrace_1 = require("./auditTrace");
119
+ Object.defineProperty(exports, "AuditTrail", { enumerable: true, get: function () { return auditTrace_1.AuditTrail; } });
120
+ Object.defineProperty(exports, "listAuditSessions", { enumerable: true, get: function () { return auditTrace_1.listAuditSessions; } });
121
+ Object.defineProperty(exports, "loadAuditSession", { enumerable: true, get: function () { return auditTrace_1.loadAuditSession; } });
122
+ Object.defineProperty(exports, "searchAuditTrails", { enumerable: true, get: function () { return auditTrace_1.searchAuditTrails; } });
123
+ Object.defineProperty(exports, "formatAuditTrail", { enumerable: true, get: function () { return auditTrace_1.formatAuditTrail; } });
124
+ var reportEngine_1 = require("./reportEngine");
125
+ Object.defineProperty(exports, "generateGovernedReport", { enumerable: true, get: function () { return reportEngine_1.generateGovernedReport; } });
126
+ Object.defineProperty(exports, "extractTrace", { enumerable: true, get: function () { return reportEngine_1.extractTrace; } });
127
+ // NeuroVerse Governance Runtime — the wrapper that makes governance real
128
+ // Drop into ANY agent system: govern(action, worldState, policyText)
129
+ var govern_1 = require("../runtime/govern");
130
+ Object.defineProperty(exports, "govern", { enumerable: true, get: function () { return govern_1.govern; } });
131
+ Object.defineProperty(exports, "createGovernor", { enumerable: true, get: function () { return govern_1.createGovernor; } });
132
+ Object.defineProperty(exports, "EXAMPLE_ACTIONS", { enumerable: true, get: function () { return govern_1.EXAMPLE_ACTIONS; } });
133
+ Object.defineProperty(exports, "EXAMPLE_WORLD_STATES", { enumerable: true, get: function () { return govern_1.EXAMPLE_WORLD_STATES; } });
134
+ // Live Simulation Adapters — plug ANY running simulator into governance + trace
135
+ // NOTE: liveAdapter.ts uses Node.js APIs (child_process, events) and is NOT
136
+ // exported here to avoid Vite browser bundle errors. Import directly from
137
+ // "./liveAdapter" in CLI/server code only.
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+ /**
3
+ * Live Simulation Adapter
4
+ *
5
+ * Connects ANY running simulator into the NV-SIM governance + trace pipeline.
6
+ * Instead of running our own swarm simulation, we ingest live events from an
7
+ * external simulator process, normalize them, and feed them through governance.
8
+ *
9
+ * Architecture:
10
+ * External Simulator (running process / stream)
11
+ * ↓ stdout / WebSocket / SSE
12
+ * LiveSimulationAdapter (parse + normalize)
13
+ * ↓ LiveSimulationRound
14
+ * Governance Engine (evaluate guards)
15
+ * ↓ verdicts
16
+ * Trace UI (causality visualization)
17
+ *
18
+ * Supported adapter types:
19
+ * - ProcessAdapter: spawn a child process, parse stdout
20
+ * - StreamAdapter: connect to WebSocket/SSE endpoint (future)
21
+ *
22
+ * Every adapter emits the same LiveSimulationRound events, regardless of source.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.ADAPTER_REGISTRY = void 0;
26
+ exports.createProcessAdapter = createProcessAdapter;
27
+ exports.parseMiroFishLine = parseMiroFishLine;
28
+ exports.parseGenericJsonLine = parseGenericJsonLine;
29
+ exports.createAdapter = createAdapter;
30
+ const child_process_1 = require("child_process");
31
+ const events_1 = require("events");
32
+ function createParserState() {
33
+ return {
34
+ currentRound: 0,
35
+ pendingActions: [],
36
+ pendingEvents: [],
37
+ pendingDynamics: [],
38
+ buffer: {},
39
+ };
40
+ }
41
+ /**
42
+ * Process adapter — spawns a child process and parses its stdout.
43
+ *
44
+ * Usage:
45
+ * const adapter = createProcessAdapter({
46
+ * type: "process",
47
+ * label: "MiroFish (Live)",
48
+ * command: "node",
49
+ * args: ["mirofish.js"],
50
+ * parser: parseMiroFishLine,
51
+ * });
52
+ * adapter.on("round", (round) => { ... });
53
+ * await adapter.start();
54
+ */
55
+ function createProcessAdapter(config) {
56
+ const emitter = new events_1.EventEmitter();
57
+ let proc = null;
58
+ let _status = "idle";
59
+ const state = createParserState();
60
+ function setStatus(s) {
61
+ _status = s;
62
+ emitter.emit("status", s);
63
+ }
64
+ Object.defineProperties(emitter, {
65
+ status: { get: () => _status },
66
+ source: { get: () => config.type },
67
+ label: { get: () => config.label },
68
+ });
69
+ emitter.start = async function start() {
70
+ setStatus("connecting");
71
+ proc = (0, child_process_1.spawn)(config.command, config.args, {
72
+ cwd: config.cwd,
73
+ env: { ...process.env, ...config.env },
74
+ stdio: ["ignore", "pipe", "pipe"],
75
+ });
76
+ let lineBuffer = "";
77
+ proc.stdout?.on("data", (chunk) => {
78
+ lineBuffer += chunk.toString();
79
+ const lines = lineBuffer.split("\n");
80
+ // Keep incomplete last line in buffer
81
+ lineBuffer = lines.pop() ?? "";
82
+ for (const line of lines) {
83
+ const trimmed = line.trim();
84
+ if (!trimmed)
85
+ continue;
86
+ try {
87
+ const round = config.parser(trimmed, state);
88
+ if (round) {
89
+ emitter.emit("round", round);
90
+ }
91
+ }
92
+ catch (err) {
93
+ // Parser error — log but don't crash
94
+ emitter.emit("error", new Error(`Parser error: ${err}`));
95
+ }
96
+ }
97
+ if (_status === "connecting") {
98
+ setStatus("streaming");
99
+ }
100
+ });
101
+ proc.stderr?.on("data", (chunk) => {
102
+ // stderr is informational — don't treat as error
103
+ const msg = chunk.toString().trim();
104
+ if (msg) {
105
+ emitter.emit("log", msg);
106
+ }
107
+ });
108
+ proc.on("close", (code) => {
109
+ // Flush any remaining buffer
110
+ if (lineBuffer.trim()) {
111
+ try {
112
+ const round = config.parser(lineBuffer.trim(), state);
113
+ if (round)
114
+ emitter.emit("round", round);
115
+ }
116
+ catch { /* ignore */ }
117
+ }
118
+ if (code === 0) {
119
+ setStatus("completed");
120
+ emitter.emit("complete");
121
+ }
122
+ else {
123
+ setStatus("error");
124
+ emitter.emit("error", new Error(`Process exited with code ${code}`));
125
+ }
126
+ proc = null;
127
+ });
128
+ proc.on("error", (err) => {
129
+ setStatus("error");
130
+ emitter.emit("error", err);
131
+ proc = null;
132
+ });
133
+ };
134
+ emitter.stop = async function stop() {
135
+ if (proc) {
136
+ proc.kill("SIGTERM");
137
+ // Give it 3s to exit gracefully, then force
138
+ setTimeout(() => {
139
+ if (proc)
140
+ proc.kill("SIGKILL");
141
+ }, 3000);
142
+ }
143
+ setStatus("idle");
144
+ };
145
+ return emitter;
146
+ }
147
+ // ============================================
148
+ // MIROFISH STDOUT PARSER
149
+ // ============================================
150
+ /**
151
+ * Parses MiroFish stdout line-by-line.
152
+ *
153
+ * Expected MiroFish output formats:
154
+ *
155
+ * JSON-per-line (preferred):
156
+ * {"step":1,"agent_actions":[{"agent_id":"a1","action":"buy","sentiment":0.5,"confidence":0.8}]}
157
+ *
158
+ * Key-value (fallback):
159
+ * [step 1] agent=swarm_1 action=panic_sell sentiment=-0.7 confidence=0.6
160
+ * [step 1] event=market_crash severity=major
161
+ * [step 1] emergent=herd_behavior
162
+ * [step 2] ...
163
+ *
164
+ * We emit a LiveSimulationRound when we detect a new step number
165
+ * (meaning the previous step is complete).
166
+ */
167
+ function parseMiroFishLine(line, state) {
168
+ // Try JSON first
169
+ if (line.startsWith("{")) {
170
+ try {
171
+ const data = JSON.parse(line);
172
+ if (data.step != null && Array.isArray(data.agent_actions)) {
173
+ // Parse adaptation data if present
174
+ let adaptation;
175
+ if (data.adaptation) {
176
+ const a = data.adaptation;
177
+ adaptation = {
178
+ count: a.count ?? 0,
179
+ rate: a.rate ?? 0,
180
+ deltas: (a.deltas ?? []).map((d) => ({
181
+ agent: d.agent ?? "unknown",
182
+ intended: d.intended ?? "",
183
+ actual: d.actual ?? "",
184
+ decision: d.decision ?? "BLOCK",
185
+ rule: d.rule,
186
+ reason: d.reason,
187
+ shift: d.shift ?? "unknown",
188
+ })),
189
+ intendedDistribution: a.intended_distribution ?? {},
190
+ actualDistribution: a.actual_distribution ?? {},
191
+ clusterPatterns: (a.cluster_patterns ?? []).map((c) => ({
192
+ type: c.type ?? "unknown",
193
+ strength: c.strength ?? 0,
194
+ agents: c.agents ?? 0,
195
+ })),
196
+ narrative: a.narrative ?? "",
197
+ };
198
+ }
199
+ // Complete step as JSON — emit immediately
200
+ return {
201
+ round: data.step,
202
+ source: "mirofish",
203
+ agentActions: data.agent_actions.map((a) => ({
204
+ agent: a.agent_id ?? a.agent ?? "unknown",
205
+ action: a.action ?? "",
206
+ impact: a.sentiment ?? a.impact ?? 0,
207
+ confidence: a.confidence ?? 0.5,
208
+ ...(a.verdict ? { verdict: { status: a.verdict.status, rule: a.verdict.rule, reason: a.verdict.reason } } : {}),
209
+ })),
210
+ systemEvents: (data.system_events ?? []).map((e) => typeof e === "string"
211
+ ? { id: e, label: e }
212
+ : { id: e.id ?? e.event ?? "unknown", label: e.label ?? e.event ?? e.id ?? "", severity: e.severity }),
213
+ emergentDynamics: data.emergent_patterns ?? data.emergent ?? [],
214
+ adaptation,
215
+ };
216
+ }
217
+ }
218
+ catch { /* not JSON, fall through to key-value parsing */ }
219
+ }
220
+ // Key-value format: [step N] key=value ...
221
+ const stepMatch = line.match(/\[step\s+(\d+)\]/i);
222
+ if (!stepMatch)
223
+ return null;
224
+ const stepNum = parseInt(stepMatch[1], 10);
225
+ let result = null;
226
+ // If new step, flush previous
227
+ if (stepNum > state.currentRound && state.currentRound > 0) {
228
+ result = {
229
+ round: state.currentRound,
230
+ source: "mirofish",
231
+ agentActions: [...state.pendingActions],
232
+ systemEvents: state.pendingEvents.length > 0 ? [...state.pendingEvents] : undefined,
233
+ emergentDynamics: state.pendingDynamics.length > 0 ? [...state.pendingDynamics] : undefined,
234
+ };
235
+ state.pendingActions = [];
236
+ state.pendingEvents = [];
237
+ state.pendingDynamics = [];
238
+ }
239
+ state.currentRound = stepNum;
240
+ const rest = line.slice(stepMatch.index + stepMatch[0].length).trim();
241
+ // Parse agent action
242
+ const agentMatch = rest.match(/agent=(\S+)\s+action=(\S+)(?:\s+sentiment=([-\d.]+))?(?:\s+confidence=([-\d.]+))?/);
243
+ if (agentMatch) {
244
+ state.pendingActions.push({
245
+ agent: agentMatch[1],
246
+ action: agentMatch[2],
247
+ impact: agentMatch[3] ? parseFloat(agentMatch[3]) : 0,
248
+ confidence: agentMatch[4] ? parseFloat(agentMatch[4]) : 0.5,
249
+ });
250
+ return result;
251
+ }
252
+ // Parse system event
253
+ const eventMatch = rest.match(/event=(\S+)(?:\s+severity=(\S+))?/);
254
+ if (eventMatch) {
255
+ state.pendingEvents.push({
256
+ id: eventMatch[1],
257
+ label: eventMatch[1].replace(/_/g, " "),
258
+ severity: eventMatch[2],
259
+ });
260
+ return result;
261
+ }
262
+ // Parse emergent behavior
263
+ const emergentMatch = rest.match(/emergent=(.+)/);
264
+ if (emergentMatch) {
265
+ state.pendingDynamics.push(emergentMatch[1].trim());
266
+ return result;
267
+ }
268
+ return result;
269
+ }
270
+ // ============================================
271
+ // GENERIC JSON PARSER (works for any JSON-per-line simulator)
272
+ // ============================================
273
+ /**
274
+ * Generic JSON-per-line parser.
275
+ * Expects each line to be a JSON object with at minimum:
276
+ * { "step": N, "agents": [{ "id": "...", "action": "...", "impact": 0.5 }] }
277
+ */
278
+ function parseGenericJsonLine(line, _state) {
279
+ if (!line.startsWith("{"))
280
+ return null;
281
+ try {
282
+ const data = JSON.parse(line);
283
+ const step = data.step ?? data.tick ?? data.round ?? data.time;
284
+ if (step == null)
285
+ return null;
286
+ const agents = (data.agents ?? data.agent_actions ?? []).map((a) => ({
287
+ agent: a.id ?? a.agent ?? a.agent_id ?? "unknown",
288
+ action: a.action ?? a.behavior ?? "",
289
+ impact: a.impact ?? a.sentiment ?? a.value ?? 0,
290
+ confidence: a.confidence ?? 0.5,
291
+ }));
292
+ return {
293
+ round: typeof step === "number" ? step : parseInt(step, 10),
294
+ source: "generic",
295
+ agentActions: agents,
296
+ systemEvents: (data.events ?? []).map((e) => typeof e === "string"
297
+ ? { id: e, label: e }
298
+ : { id: e.id ?? "unknown", label: e.label ?? e.id ?? "", severity: e.severity }),
299
+ emergentDynamics: data.dynamics ?? data.emergent ?? [],
300
+ };
301
+ }
302
+ catch {
303
+ return null;
304
+ }
305
+ }
306
+ exports.ADAPTER_REGISTRY = {
307
+ mirofish: {
308
+ id: "mirofish",
309
+ label: "MiroFish (Live)",
310
+ description: "Spawn MiroFish swarm simulation and stream agent behavior",
311
+ createConfig: (opts = {}) => ({
312
+ type: "process",
313
+ label: "MiroFish (Live)",
314
+ command: opts.command ?? "node",
315
+ args: (opts.args ?? "mirofish.js").split(" "),
316
+ cwd: opts.cwd,
317
+ parser: parseMiroFishLine,
318
+ }),
319
+ },
320
+ generic: {
321
+ id: "generic",
322
+ label: "Generic JSON Process",
323
+ description: "Spawn any process that outputs JSON-per-line simulation data",
324
+ createConfig: (opts = {}) => ({
325
+ type: "process",
326
+ label: opts.label ?? "External Simulator",
327
+ command: opts.command ?? "python",
328
+ args: (opts.args ?? "sim.py").split(" "),
329
+ cwd: opts.cwd,
330
+ parser: parseGenericJsonLine,
331
+ }),
332
+ },
333
+ };
334
+ /**
335
+ * Create an adapter from the registry.
336
+ */
337
+ function createAdapter(adapterId, options) {
338
+ const entry = exports.ADAPTER_REGISTRY[adapterId];
339
+ if (!entry)
340
+ return null;
341
+ return createProcessAdapter(entry.createConfig(options));
342
+ }