genesis-ai-cli 7.4.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.
- package/.env.example +78 -0
- package/README.md +282 -0
- package/dist/src/active-inference/actions.d.ts +75 -0
- package/dist/src/active-inference/actions.js +250 -0
- package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
- package/dist/src/active-inference/autonomous-loop.js +289 -0
- package/dist/src/active-inference/core.d.ts +85 -0
- package/dist/src/active-inference/core.js +555 -0
- package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
- package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
- package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
- package/dist/src/active-inference/demo-value-integration.js +174 -0
- package/dist/src/active-inference/index.d.ts +32 -0
- package/dist/src/active-inference/index.js +88 -0
- package/dist/src/active-inference/integration.d.ts +114 -0
- package/dist/src/active-inference/integration.js +698 -0
- package/dist/src/active-inference/memory-integration.d.ts +51 -0
- package/dist/src/active-inference/memory-integration.js +232 -0
- package/dist/src/active-inference/observations.d.ts +67 -0
- package/dist/src/active-inference/observations.js +147 -0
- package/dist/src/active-inference/test-active-inference.d.ts +8 -0
- package/dist/src/active-inference/test-active-inference.js +320 -0
- package/dist/src/active-inference/test-value-integration.d.ts +6 -0
- package/dist/src/active-inference/test-value-integration.js +168 -0
- package/dist/src/active-inference/types.d.ts +150 -0
- package/dist/src/active-inference/types.js +59 -0
- package/dist/src/active-inference/value-integration.d.ts +164 -0
- package/dist/src/active-inference/value-integration.js +459 -0
- package/dist/src/agents/base-agent.d.ts +53 -0
- package/dist/src/agents/base-agent.js +178 -0
- package/dist/src/agents/builder.d.ts +67 -0
- package/dist/src/agents/builder.js +537 -0
- package/dist/src/agents/critic.d.ts +35 -0
- package/dist/src/agents/critic.js +322 -0
- package/dist/src/agents/ethicist.d.ts +54 -0
- package/dist/src/agents/ethicist.js +393 -0
- package/dist/src/agents/explorer.d.ts +26 -0
- package/dist/src/agents/explorer.js +216 -0
- package/dist/src/agents/feeling.d.ts +41 -0
- package/dist/src/agents/feeling.js +320 -0
- package/dist/src/agents/index.d.ts +111 -0
- package/dist/src/agents/index.js +222 -0
- package/dist/src/agents/memory.d.ts +69 -0
- package/dist/src/agents/memory.js +404 -0
- package/dist/src/agents/message-bus.d.ts +88 -0
- package/dist/src/agents/message-bus.js +267 -0
- package/dist/src/agents/narrator.d.ts +90 -0
- package/dist/src/agents/narrator.js +473 -0
- package/dist/src/agents/planner.d.ts +38 -0
- package/dist/src/agents/planner.js +341 -0
- package/dist/src/agents/predictor.d.ts +73 -0
- package/dist/src/agents/predictor.js +506 -0
- package/dist/src/agents/sensor.d.ts +88 -0
- package/dist/src/agents/sensor.js +377 -0
- package/dist/src/agents/test-agents.d.ts +6 -0
- package/dist/src/agents/test-agents.js +73 -0
- package/dist/src/agents/types.d.ts +194 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/brain/index.d.ts +185 -0
- package/dist/src/brain/index.js +843 -0
- package/dist/src/brain/trace.d.ts +91 -0
- package/dist/src/brain/trace.js +327 -0
- package/dist/src/brain/types.d.ts +165 -0
- package/dist/src/brain/types.js +51 -0
- package/dist/src/cli/chat.d.ts +237 -0
- package/dist/src/cli/chat.js +1959 -0
- package/dist/src/cli/dispatcher.d.ts +182 -0
- package/dist/src/cli/dispatcher.js +718 -0
- package/dist/src/cli/human-loop.d.ts +170 -0
- package/dist/src/cli/human-loop.js +543 -0
- package/dist/src/cli/index.d.ts +12 -0
- package/dist/src/cli/index.js +28 -0
- package/dist/src/cli/interactive.d.ts +141 -0
- package/dist/src/cli/interactive.js +757 -0
- package/dist/src/cli/ui.d.ts +205 -0
- package/dist/src/cli/ui.js +632 -0
- package/dist/src/consciousness/attention-schema.d.ts +154 -0
- package/dist/src/consciousness/attention-schema.js +432 -0
- package/dist/src/consciousness/global-workspace.d.ts +149 -0
- package/dist/src/consciousness/global-workspace.js +422 -0
- package/dist/src/consciousness/index.d.ts +186 -0
- package/dist/src/consciousness/index.js +476 -0
- package/dist/src/consciousness/phi-calculator.d.ts +119 -0
- package/dist/src/consciousness/phi-calculator.js +445 -0
- package/dist/src/consciousness/phi-decisions.d.ts +169 -0
- package/dist/src/consciousness/phi-decisions.js +383 -0
- package/dist/src/consciousness/phi-monitor.d.ts +153 -0
- package/dist/src/consciousness/phi-monitor.js +465 -0
- package/dist/src/consciousness/types.d.ts +260 -0
- package/dist/src/consciousness/types.js +44 -0
- package/dist/src/daemon/dream-mode.d.ts +115 -0
- package/dist/src/daemon/dream-mode.js +470 -0
- package/dist/src/daemon/index.d.ts +162 -0
- package/dist/src/daemon/index.js +542 -0
- package/dist/src/daemon/maintenance.d.ts +139 -0
- package/dist/src/daemon/maintenance.js +549 -0
- package/dist/src/daemon/process.d.ts +82 -0
- package/dist/src/daemon/process.js +442 -0
- package/dist/src/daemon/scheduler.d.ts +90 -0
- package/dist/src/daemon/scheduler.js +494 -0
- package/dist/src/daemon/types.d.ts +213 -0
- package/dist/src/daemon/types.js +50 -0
- package/dist/src/epistemic/index.d.ts +74 -0
- package/dist/src/epistemic/index.js +225 -0
- package/dist/src/grounding/epistemic-stack.d.ts +100 -0
- package/dist/src/grounding/epistemic-stack.js +408 -0
- package/dist/src/grounding/feedback.d.ts +98 -0
- package/dist/src/grounding/feedback.js +276 -0
- package/dist/src/grounding/index.d.ts +123 -0
- package/dist/src/grounding/index.js +224 -0
- package/dist/src/grounding/verifier.d.ts +149 -0
- package/dist/src/grounding/verifier.js +484 -0
- package/dist/src/healing/detector.d.ts +110 -0
- package/dist/src/healing/detector.js +436 -0
- package/dist/src/healing/fixer.d.ts +138 -0
- package/dist/src/healing/fixer.js +572 -0
- package/dist/src/healing/index.d.ts +23 -0
- package/dist/src/healing/index.js +43 -0
- package/dist/src/hooks/index.d.ts +135 -0
- package/dist/src/hooks/index.js +317 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +1266 -0
- package/dist/src/kernel/index.d.ts +155 -0
- package/dist/src/kernel/index.js +795 -0
- package/dist/src/kernel/invariants.d.ts +153 -0
- package/dist/src/kernel/invariants.js +355 -0
- package/dist/src/kernel/test-kernel.d.ts +6 -0
- package/dist/src/kernel/test-kernel.js +108 -0
- package/dist/src/kernel/test-real-mcp.d.ts +10 -0
- package/dist/src/kernel/test-real-mcp.js +295 -0
- package/dist/src/llm/index.d.ts +146 -0
- package/dist/src/llm/index.js +428 -0
- package/dist/src/llm/router.d.ts +136 -0
- package/dist/src/llm/router.js +510 -0
- package/dist/src/mcp/index.d.ts +85 -0
- package/dist/src/mcp/index.js +657 -0
- package/dist/src/mcp/resilient.d.ts +139 -0
- package/dist/src/mcp/resilient.js +417 -0
- package/dist/src/memory/cache.d.ts +118 -0
- package/dist/src/memory/cache.js +356 -0
- package/dist/src/memory/cognitive-workspace.d.ts +231 -0
- package/dist/src/memory/cognitive-workspace.js +521 -0
- package/dist/src/memory/consolidation.d.ts +99 -0
- package/dist/src/memory/consolidation.js +443 -0
- package/dist/src/memory/episodic.d.ts +114 -0
- package/dist/src/memory/episodic.js +394 -0
- package/dist/src/memory/forgetting.d.ts +134 -0
- package/dist/src/memory/forgetting.js +324 -0
- package/dist/src/memory/index.d.ts +211 -0
- package/dist/src/memory/index.js +367 -0
- package/dist/src/memory/indexer.d.ts +123 -0
- package/dist/src/memory/indexer.js +479 -0
- package/dist/src/memory/procedural.d.ts +136 -0
- package/dist/src/memory/procedural.js +479 -0
- package/dist/src/memory/semantic.d.ts +132 -0
- package/dist/src/memory/semantic.js +497 -0
- package/dist/src/memory/types.d.ts +193 -0
- package/dist/src/memory/types.js +15 -0
- package/dist/src/orchestrator.d.ts +65 -0
- package/dist/src/orchestrator.js +317 -0
- package/dist/src/persistence/index.d.ts +257 -0
- package/dist/src/persistence/index.js +763 -0
- package/dist/src/pipeline/executor.d.ts +51 -0
- package/dist/src/pipeline/executor.js +695 -0
- package/dist/src/pipeline/index.d.ts +7 -0
- package/dist/src/pipeline/index.js +11 -0
- package/dist/src/self-production.d.ts +67 -0
- package/dist/src/self-production.js +205 -0
- package/dist/src/subagents/executor.d.ts +58 -0
- package/dist/src/subagents/executor.js +283 -0
- package/dist/src/subagents/index.d.ts +37 -0
- package/dist/src/subagents/index.js +53 -0
- package/dist/src/subagents/registry.d.ts +23 -0
- package/dist/src/subagents/registry.js +167 -0
- package/dist/src/subagents/types.d.ts +79 -0
- package/dist/src/subagents/types.js +14 -0
- package/dist/src/tools/bash.d.ts +139 -0
- package/dist/src/tools/bash.js +583 -0
- package/dist/src/tools/edit.d.ts +125 -0
- package/dist/src/tools/edit.js +424 -0
- package/dist/src/tools/git.d.ts +179 -0
- package/dist/src/tools/git.js +504 -0
- package/dist/src/tools/index.d.ts +21 -0
- package/dist/src/tools/index.js +163 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/src/types.js +7 -0
- package/dist/src/world-model/decoder.d.ts +163 -0
- package/dist/src/world-model/decoder.js +517 -0
- package/dist/src/world-model/digital-twin.d.ts +219 -0
- package/dist/src/world-model/digital-twin.js +695 -0
- package/dist/src/world-model/encoder.d.ts +141 -0
- package/dist/src/world-model/encoder.js +564 -0
- package/dist/src/world-model/index.d.ts +221 -0
- package/dist/src/world-model/index.js +772 -0
- package/dist/src/world-model/predictor.d.ts +161 -0
- package/dist/src/world-model/predictor.js +681 -0
- package/dist/src/world-model/test-value-jepa.d.ts +8 -0
- package/dist/src/world-model/test-value-jepa.js +430 -0
- package/dist/src/world-model/types.d.ts +341 -0
- package/dist/src/world-model/types.js +69 -0
- package/dist/src/world-model/value-jepa.d.ts +247 -0
- package/dist/src/world-model/value-jepa.js +622 -0
- package/dist/test/brain.test.d.ts +11 -0
- package/dist/test/brain.test.js +358 -0
- package/dist/test/cli/dispatcher.test.d.ts +4 -0
- package/dist/test/cli/dispatcher.test.js +332 -0
- package/dist/test/cli/human-loop.test.d.ts +4 -0
- package/dist/test/cli/human-loop.test.js +270 -0
- package/dist/test/grounding/feedback.test.d.ts +4 -0
- package/dist/test/grounding/feedback.test.js +462 -0
- package/dist/test/grounding/verifier.test.d.ts +4 -0
- package/dist/test/grounding/verifier.test.js +442 -0
- package/dist/test/grounding.test.d.ts +6 -0
- package/dist/test/grounding.test.js +246 -0
- package/dist/test/healing/detector.test.d.ts +4 -0
- package/dist/test/healing/detector.test.js +266 -0
- package/dist/test/healing/fixer.test.d.ts +4 -0
- package/dist/test/healing/fixer.test.js +369 -0
- package/dist/test/integration.test.d.ts +5 -0
- package/dist/test/integration.test.js +290 -0
- package/dist/test/tools/bash.test.d.ts +4 -0
- package/dist/test/tools/bash.test.js +348 -0
- package/dist/test/tools/edit.test.d.ts +4 -0
- package/dist/test/tools/edit.test.js +350 -0
- package/dist/test/tools/git.test.d.ts +4 -0
- package/dist/test/tools/git.test.js +350 -0
- package/package.json +60 -0
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis 6.0 - Digital Twin
|
|
4
|
+
*
|
|
5
|
+
* Digital twin implementation for creating synchronized virtual
|
|
6
|
+
* representations of real systems.
|
|
7
|
+
*
|
|
8
|
+
* Capabilities:
|
|
9
|
+
* - Real-time synchronization with source system
|
|
10
|
+
* - Drift detection and correction
|
|
11
|
+
* - Predictive maintenance through simulation
|
|
12
|
+
* - What-if scenario analysis
|
|
13
|
+
*
|
|
14
|
+
* A digital twin maintains a latent representation that mirrors
|
|
15
|
+
* the real system, enabling prediction without affecting the original.
|
|
16
|
+
*
|
|
17
|
+
* Industrial applications:
|
|
18
|
+
* - Process monitoring
|
|
19
|
+
* - Anomaly detection
|
|
20
|
+
* - Optimization planning
|
|
21
|
+
* - Failure prediction
|
|
22
|
+
*
|
|
23
|
+
* References:
|
|
24
|
+
* - Grieves (2014). Digital Twin: Manufacturing Excellence through Virtual Factory Replication
|
|
25
|
+
* - Tao et al. (2019). Digital Twin in Industry
|
|
26
|
+
*
|
|
27
|
+
* Usage:
|
|
28
|
+
* ```typescript
|
|
29
|
+
* import { createDigitalTwin, DigitalTwinManager } from './world-model/digital-twin.js';
|
|
30
|
+
*
|
|
31
|
+
* const twin = createDigitalTwin('server-1', 'Production Server');
|
|
32
|
+
*
|
|
33
|
+
* // Start synchronization
|
|
34
|
+
* twin.startSync(() => fetchRealState());
|
|
35
|
+
*
|
|
36
|
+
* // Run what-if scenario
|
|
37
|
+
* const prediction = twin.whatIf([upgradeAction, restartAction]);
|
|
38
|
+
*
|
|
39
|
+
* // Check health
|
|
40
|
+
* const health = twin.getHealth();
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.DigitalTwinManager = exports.DigitalTwinInstance = void 0;
|
|
45
|
+
exports.createDigitalTwin = createDigitalTwin;
|
|
46
|
+
exports.createDigitalTwinManager = createDigitalTwinManager;
|
|
47
|
+
const crypto_1 = require("crypto");
|
|
48
|
+
const types_js_1 = require("./types.js");
|
|
49
|
+
const encoder_js_1 = require("./encoder.js");
|
|
50
|
+
const predictor_js_1 = require("./predictor.js");
|
|
51
|
+
class DigitalTwinInstance {
|
|
52
|
+
id;
|
|
53
|
+
name;
|
|
54
|
+
realSystemId;
|
|
55
|
+
currentState;
|
|
56
|
+
lastSync;
|
|
57
|
+
syncDrift = 0;
|
|
58
|
+
stateHistory = [];
|
|
59
|
+
historyLimit;
|
|
60
|
+
config;
|
|
61
|
+
status = 'initializing';
|
|
62
|
+
// Components
|
|
63
|
+
encoder;
|
|
64
|
+
predictor;
|
|
65
|
+
// Sync management
|
|
66
|
+
syncTimer = null;
|
|
67
|
+
stateFetcher = null;
|
|
68
|
+
// Metrics
|
|
69
|
+
metrics;
|
|
70
|
+
// Events
|
|
71
|
+
eventHandlers = new Set();
|
|
72
|
+
// Prediction history (for accuracy tracking)
|
|
73
|
+
predictionHistory = [];
|
|
74
|
+
constructor(realSystemId, name, config = {}) {
|
|
75
|
+
this.id = (0, crypto_1.randomUUID)();
|
|
76
|
+
this.realSystemId = realSystemId;
|
|
77
|
+
this.name = name;
|
|
78
|
+
this.config = { ...types_js_1.DEFAULT_DIGITAL_TWIN_CONFIG, ...config };
|
|
79
|
+
this.historyLimit = 1000;
|
|
80
|
+
// Initialize components
|
|
81
|
+
this.encoder = (0, encoder_js_1.createLatentEncoder)();
|
|
82
|
+
this.predictor = (0, predictor_js_1.createWorldModelPredictor)();
|
|
83
|
+
// Initialize state
|
|
84
|
+
this.currentState = this.createInitialState();
|
|
85
|
+
this.lastSync = new Date();
|
|
86
|
+
// Initialize metrics
|
|
87
|
+
this.metrics = {
|
|
88
|
+
syncCount: 0,
|
|
89
|
+
driftEvents: 0,
|
|
90
|
+
avgDrift: 0,
|
|
91
|
+
maxDrift: 0,
|
|
92
|
+
uptime: 0,
|
|
93
|
+
lastSync: null,
|
|
94
|
+
predictions: 0,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// ============================================================================
|
|
98
|
+
// Lifecycle
|
|
99
|
+
// ============================================================================
|
|
100
|
+
/**
|
|
101
|
+
* Start synchronization with real system
|
|
102
|
+
*/
|
|
103
|
+
startSync(fetcher) {
|
|
104
|
+
this.stateFetcher = fetcher;
|
|
105
|
+
this.status = 'synced';
|
|
106
|
+
// Initial sync
|
|
107
|
+
this.syncNow();
|
|
108
|
+
// Start periodic sync
|
|
109
|
+
this.syncTimer = setInterval(() => this.syncNow(), this.config.syncIntervalMs);
|
|
110
|
+
this.emit({ type: 'status_changed', data: { status: 'synced' } });
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Stop synchronization
|
|
114
|
+
*/
|
|
115
|
+
stopSync() {
|
|
116
|
+
if (this.syncTimer) {
|
|
117
|
+
clearInterval(this.syncTimer);
|
|
118
|
+
this.syncTimer = null;
|
|
119
|
+
}
|
|
120
|
+
this.status = 'disconnected';
|
|
121
|
+
this.emit({ type: 'status_changed', data: { status: 'disconnected' } });
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Force immediate synchronization
|
|
125
|
+
*/
|
|
126
|
+
async syncNow() {
|
|
127
|
+
if (!this.stateFetcher) {
|
|
128
|
+
this.emit({ type: 'error', data: { message: 'No state fetcher configured' } });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
// Fetch real state
|
|
133
|
+
const realStateData = await this.stateFetcher();
|
|
134
|
+
// Encode to latent space
|
|
135
|
+
const realState = this.encoder.encode({
|
|
136
|
+
modality: 'state',
|
|
137
|
+
data: realStateData,
|
|
138
|
+
timestamp: new Date(),
|
|
139
|
+
});
|
|
140
|
+
// Calculate drift
|
|
141
|
+
const drift = this.calculateDrift(this.currentState, realState);
|
|
142
|
+
this.syncDrift = drift;
|
|
143
|
+
// Update metrics
|
|
144
|
+
this.metrics.syncCount++;
|
|
145
|
+
this.metrics.lastSync = new Date();
|
|
146
|
+
this.metrics.avgDrift = (this.metrics.avgDrift * (this.metrics.syncCount - 1) + drift) / this.metrics.syncCount;
|
|
147
|
+
this.metrics.maxDrift = Math.max(this.metrics.maxDrift, drift);
|
|
148
|
+
// Check for drift threshold
|
|
149
|
+
if (drift > this.config.maxDrift) {
|
|
150
|
+
this.metrics.driftEvents++;
|
|
151
|
+
this.status = 'drifting';
|
|
152
|
+
this.emit({ type: 'drift_detected', data: { drift, threshold: this.config.maxDrift } });
|
|
153
|
+
// Correct drift
|
|
154
|
+
this.correctDrift(realState);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
this.status = 'synced';
|
|
158
|
+
}
|
|
159
|
+
// Update current state (blend)
|
|
160
|
+
this.currentState = this.blendStates(this.currentState, realState, 0.3);
|
|
161
|
+
this.lastSync = new Date();
|
|
162
|
+
// Add to history
|
|
163
|
+
this.addToHistory(this.currentState);
|
|
164
|
+
// Update prediction history
|
|
165
|
+
this.updatePredictionAccuracy(realState);
|
|
166
|
+
this.emit({ type: 'synced', data: { drift } });
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
this.status = 'disconnected';
|
|
170
|
+
this.emit({ type: 'error', data: { message: String(error) } });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// Prediction
|
|
175
|
+
// ============================================================================
|
|
176
|
+
/**
|
|
177
|
+
* Predict future state
|
|
178
|
+
*/
|
|
179
|
+
predict(actions, horizon = this.config.predictAhead) {
|
|
180
|
+
const trajectory = this.predictor.simulate(this.currentState, actions, horizon);
|
|
181
|
+
// Store for accuracy tracking
|
|
182
|
+
if (trajectory.states.length > 0) {
|
|
183
|
+
this.predictionHistory.push({
|
|
184
|
+
predicted: trajectory.states[trajectory.states.length - 1].state,
|
|
185
|
+
actual: null,
|
|
186
|
+
timestamp: new Date(),
|
|
187
|
+
});
|
|
188
|
+
// Limit history
|
|
189
|
+
if (this.predictionHistory.length > 100) {
|
|
190
|
+
this.predictionHistory.shift();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
this.metrics.predictions++;
|
|
194
|
+
this.emit({ type: 'prediction_made', data: { horizon, steps: trajectory.states.length } });
|
|
195
|
+
return trajectory;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Run what-if scenario
|
|
199
|
+
*/
|
|
200
|
+
whatIf(scenario) {
|
|
201
|
+
// Simulate from current state
|
|
202
|
+
const trajectory = this.predict(scenario, scenario.length * 2);
|
|
203
|
+
// Get expected outcome
|
|
204
|
+
const expectedOutcome = trajectory.states.length > 0
|
|
205
|
+
? trajectory.states[trajectory.states.length - 1].state
|
|
206
|
+
: this.currentState;
|
|
207
|
+
// Calculate risk score
|
|
208
|
+
const riskScore = this.calculateRisk(scenario, trajectory);
|
|
209
|
+
// Generate warnings
|
|
210
|
+
const warnings = this.generateWarnings(trajectory, riskScore);
|
|
211
|
+
const result = {
|
|
212
|
+
scenario,
|
|
213
|
+
trajectory,
|
|
214
|
+
expectedOutcome,
|
|
215
|
+
riskScore,
|
|
216
|
+
confidence: trajectory.totalProbability,
|
|
217
|
+
warnings,
|
|
218
|
+
};
|
|
219
|
+
this.emit({ type: 'what_if_complete', data: { actionCount: scenario.length, riskScore } });
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Calculate risk score for scenario
|
|
224
|
+
*/
|
|
225
|
+
calculateRisk(actions, trajectory) {
|
|
226
|
+
let risk = 0;
|
|
227
|
+
// Action risk
|
|
228
|
+
for (const action of actions) {
|
|
229
|
+
const actionRisk = this.getActionRisk(action.type);
|
|
230
|
+
risk += actionRisk * 0.3;
|
|
231
|
+
}
|
|
232
|
+
// Uncertainty risk
|
|
233
|
+
const avgUncertainty = trajectory.states.reduce((sum, s) => sum + s.uncertainty, 0) / Math.max(trajectory.states.length, 1);
|
|
234
|
+
risk += avgUncertainty * 0.4;
|
|
235
|
+
// Drift from current state risk
|
|
236
|
+
if (trajectory.states.length > 0) {
|
|
237
|
+
const finalState = trajectory.states[trajectory.states.length - 1].state;
|
|
238
|
+
const drift = this.calculateDrift(this.currentState, finalState);
|
|
239
|
+
risk += drift * 0.3;
|
|
240
|
+
}
|
|
241
|
+
return Math.min(1, Math.max(0, risk));
|
|
242
|
+
}
|
|
243
|
+
getActionRisk(type) {
|
|
244
|
+
const risks = {
|
|
245
|
+
observe: 0.0,
|
|
246
|
+
query: 0.1,
|
|
247
|
+
navigate: 0.2,
|
|
248
|
+
communicate: 0.3,
|
|
249
|
+
execute: 0.5,
|
|
250
|
+
transform: 0.6,
|
|
251
|
+
create: 0.7,
|
|
252
|
+
delete: 0.9,
|
|
253
|
+
};
|
|
254
|
+
return risks[type] || 0.5;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Generate warnings for trajectory
|
|
258
|
+
*/
|
|
259
|
+
generateWarnings(trajectory, riskScore) {
|
|
260
|
+
const warnings = [];
|
|
261
|
+
if (riskScore > 0.7) {
|
|
262
|
+
warnings.push('High risk scenario - proceed with caution');
|
|
263
|
+
}
|
|
264
|
+
if (trajectory.totalProbability < 0.3) {
|
|
265
|
+
warnings.push('Low confidence in predicted outcome');
|
|
266
|
+
}
|
|
267
|
+
const uncertainSteps = trajectory.states.filter((s) => s.uncertainty > 0.5);
|
|
268
|
+
if (uncertainSteps.length > trajectory.states.length / 2) {
|
|
269
|
+
warnings.push('Many uncertain steps in trajectory');
|
|
270
|
+
}
|
|
271
|
+
if (trajectory.horizon < trajectory.states.length) {
|
|
272
|
+
warnings.push('Simulation terminated early due to high uncertainty');
|
|
273
|
+
}
|
|
274
|
+
return warnings;
|
|
275
|
+
}
|
|
276
|
+
// ============================================================================
|
|
277
|
+
// Health & Status
|
|
278
|
+
// ============================================================================
|
|
279
|
+
/**
|
|
280
|
+
* Get twin health status
|
|
281
|
+
*/
|
|
282
|
+
getHealth() {
|
|
283
|
+
const issues = [];
|
|
284
|
+
const recommendations = [];
|
|
285
|
+
// Sync health
|
|
286
|
+
const syncHealth = 1 - Math.min(1, this.syncDrift / this.config.maxDrift);
|
|
287
|
+
// Prediction accuracy
|
|
288
|
+
const predictionAccuracy = this.getPredictionAccuracy();
|
|
289
|
+
// Drift trend
|
|
290
|
+
const driftTrend = this.analyzeDriftTrend();
|
|
291
|
+
// Check for issues
|
|
292
|
+
if (this.status === 'disconnected') {
|
|
293
|
+
issues.push('Twin is disconnected from source system');
|
|
294
|
+
recommendations.push('Check network connectivity and restart sync');
|
|
295
|
+
}
|
|
296
|
+
if (this.status === 'drifting') {
|
|
297
|
+
issues.push('Twin state has drifted from source');
|
|
298
|
+
recommendations.push('Wait for automatic correction or force sync');
|
|
299
|
+
}
|
|
300
|
+
if (syncHealth < 0.5) {
|
|
301
|
+
issues.push('Low sync health - high drift detected');
|
|
302
|
+
recommendations.push('Reduce sync interval or check source system stability');
|
|
303
|
+
}
|
|
304
|
+
if (predictionAccuracy < 0.5) {
|
|
305
|
+
issues.push('Low prediction accuracy');
|
|
306
|
+
recommendations.push('Retrain predictor with recent data');
|
|
307
|
+
}
|
|
308
|
+
if (driftTrend === 'increasing') {
|
|
309
|
+
issues.push('Drift is increasing over time');
|
|
310
|
+
recommendations.push('Investigate source system changes');
|
|
311
|
+
}
|
|
312
|
+
return {
|
|
313
|
+
status: this.status,
|
|
314
|
+
syncHealth,
|
|
315
|
+
predictionAccuracy,
|
|
316
|
+
driftTrend,
|
|
317
|
+
issues,
|
|
318
|
+
recommendations,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Get prediction accuracy
|
|
323
|
+
*/
|
|
324
|
+
getPredictionAccuracy() {
|
|
325
|
+
const validPredictions = this.predictionHistory.filter((p) => p.actual !== null);
|
|
326
|
+
if (validPredictions.length === 0)
|
|
327
|
+
return 0.5;
|
|
328
|
+
let totalAccuracy = 0;
|
|
329
|
+
for (const p of validPredictions) {
|
|
330
|
+
const similarity = this.calculateSimilarity(p.predicted, p.actual);
|
|
331
|
+
totalAccuracy += similarity;
|
|
332
|
+
}
|
|
333
|
+
return totalAccuracy / validPredictions.length;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Analyze drift trend
|
|
337
|
+
*/
|
|
338
|
+
analyzeDriftTrend() {
|
|
339
|
+
if (this.stateHistory.length < 10)
|
|
340
|
+
return 'stable';
|
|
341
|
+
// Compare recent drift to older drift
|
|
342
|
+
const recentStates = this.stateHistory.slice(-5);
|
|
343
|
+
const olderStates = this.stateHistory.slice(-10, -5);
|
|
344
|
+
let recentDrift = 0;
|
|
345
|
+
let olderDrift = 0;
|
|
346
|
+
for (let i = 1; i < recentStates.length; i++) {
|
|
347
|
+
recentDrift += this.calculateDrift(recentStates[i - 1], recentStates[i]);
|
|
348
|
+
}
|
|
349
|
+
for (let i = 1; i < olderStates.length; i++) {
|
|
350
|
+
olderDrift += this.calculateDrift(olderStates[i - 1], olderStates[i]);
|
|
351
|
+
}
|
|
352
|
+
const recentAvg = recentDrift / (recentStates.length - 1 || 1);
|
|
353
|
+
const olderAvg = olderDrift / (olderStates.length - 1 || 1);
|
|
354
|
+
if (recentAvg > olderAvg * 1.2)
|
|
355
|
+
return 'increasing';
|
|
356
|
+
if (recentAvg < olderAvg * 0.8)
|
|
357
|
+
return 'decreasing';
|
|
358
|
+
return 'stable';
|
|
359
|
+
}
|
|
360
|
+
// ============================================================================
|
|
361
|
+
// Consistency Check (INV-008)
|
|
362
|
+
// ============================================================================
|
|
363
|
+
/**
|
|
364
|
+
* Check consistency of twin state
|
|
365
|
+
*/
|
|
366
|
+
checkConsistency() {
|
|
367
|
+
const issues = [];
|
|
368
|
+
// State consistency
|
|
369
|
+
const stateConsistent = this.checkStateConsistency();
|
|
370
|
+
if (!stateConsistent) {
|
|
371
|
+
issues.push({
|
|
372
|
+
type: 'contradiction',
|
|
373
|
+
severity: 'high',
|
|
374
|
+
description: 'Current state inconsistent with history',
|
|
375
|
+
affectedEntities: [this.id],
|
|
376
|
+
suggestedFix: 'Force synchronization',
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
// Temporal consistency
|
|
380
|
+
const temporalConsistent = this.checkTemporalConsistency();
|
|
381
|
+
if (!temporalConsistent) {
|
|
382
|
+
issues.push({
|
|
383
|
+
type: 'cycle',
|
|
384
|
+
severity: 'medium',
|
|
385
|
+
description: 'Temporal ordering violated',
|
|
386
|
+
affectedEntities: [this.id],
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
// Causal consistency (predictions follow from states)
|
|
390
|
+
const causalConsistent = this.checkCausalConsistency();
|
|
391
|
+
if (!causalConsistent) {
|
|
392
|
+
issues.push({
|
|
393
|
+
type: 'gap',
|
|
394
|
+
severity: 'medium',
|
|
395
|
+
description: 'Causal gaps in prediction chain',
|
|
396
|
+
affectedEntities: [this.id],
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
// Entity consistency (twin properly linked to source)
|
|
400
|
+
const entityConsistent = this.status !== 'disconnected';
|
|
401
|
+
if (!entityConsistent) {
|
|
402
|
+
issues.push({
|
|
403
|
+
type: 'orphan',
|
|
404
|
+
severity: 'high',
|
|
405
|
+
description: 'Twin disconnected from source system',
|
|
406
|
+
affectedEntities: [this.id, this.realSystemId],
|
|
407
|
+
suggestedFix: 'Reconnect to source system',
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
const inconsistencyScore = issues.reduce((sum, issue) => {
|
|
411
|
+
const severityScores = { low: 0.1, medium: 0.3, high: 0.6, critical: 1.0 };
|
|
412
|
+
return sum + severityScores[issue.severity];
|
|
413
|
+
}, 0);
|
|
414
|
+
return {
|
|
415
|
+
id: (0, crypto_1.randomUUID)(),
|
|
416
|
+
timestamp: new Date(),
|
|
417
|
+
passed: issues.length === 0,
|
|
418
|
+
checks: {
|
|
419
|
+
stateConsistency: stateConsistent,
|
|
420
|
+
temporalConsistency: temporalConsistent,
|
|
421
|
+
causalConsistency: causalConsistent,
|
|
422
|
+
entityConsistency: entityConsistent,
|
|
423
|
+
},
|
|
424
|
+
issues,
|
|
425
|
+
inconsistencyScore: Math.min(1, inconsistencyScore),
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
checkStateConsistency() {
|
|
429
|
+
if (this.stateHistory.length < 2)
|
|
430
|
+
return true;
|
|
431
|
+
// Check if current state is reachable from history
|
|
432
|
+
const recent = this.stateHistory.slice(-5);
|
|
433
|
+
for (let i = 1; i < recent.length; i++) {
|
|
434
|
+
const drift = this.calculateDrift(recent[i - 1], recent[i]);
|
|
435
|
+
if (drift > 0.5)
|
|
436
|
+
return false; // Too large a jump
|
|
437
|
+
}
|
|
438
|
+
return true;
|
|
439
|
+
}
|
|
440
|
+
checkTemporalConsistency() {
|
|
441
|
+
// Check timestamps are monotonic
|
|
442
|
+
for (let i = 1; i < this.stateHistory.length; i++) {
|
|
443
|
+
if (this.stateHistory[i].timestamp <= this.stateHistory[i - 1].timestamp) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
checkCausalConsistency() {
|
|
450
|
+
// Check prediction history for causality
|
|
451
|
+
for (const p of this.predictionHistory) {
|
|
452
|
+
if (p.actual !== null) {
|
|
453
|
+
const accuracy = this.calculateSimilarity(p.predicted, p.actual);
|
|
454
|
+
if (accuracy < 0.3)
|
|
455
|
+
return false; // Prediction wildly off
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
// ============================================================================
|
|
461
|
+
// Snapshots
|
|
462
|
+
// ============================================================================
|
|
463
|
+
/**
|
|
464
|
+
* Take a snapshot of current twin state
|
|
465
|
+
*/
|
|
466
|
+
takeSnapshot(metadata = {}) {
|
|
467
|
+
return {
|
|
468
|
+
id: (0, crypto_1.randomUUID)(),
|
|
469
|
+
twinId: this.id,
|
|
470
|
+
state: { ...this.currentState },
|
|
471
|
+
realState: null, // Would be populated on sync
|
|
472
|
+
drift: this.syncDrift,
|
|
473
|
+
timestamp: new Date(),
|
|
474
|
+
metadata,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Restore from snapshot
|
|
479
|
+
*/
|
|
480
|
+
restoreSnapshot(snapshot) {
|
|
481
|
+
if (snapshot.twinId !== this.id) {
|
|
482
|
+
throw new Error('Snapshot does not belong to this twin');
|
|
483
|
+
}
|
|
484
|
+
this.currentState = { ...snapshot.state };
|
|
485
|
+
this.syncDrift = snapshot.drift;
|
|
486
|
+
this.addToHistory(this.currentState);
|
|
487
|
+
}
|
|
488
|
+
// ============================================================================
|
|
489
|
+
// Utilities
|
|
490
|
+
// ============================================================================
|
|
491
|
+
/**
|
|
492
|
+
* Calculate drift between two states
|
|
493
|
+
*/
|
|
494
|
+
calculateDrift(stateA, stateB) {
|
|
495
|
+
const minLen = Math.min(stateA.vector.length, stateB.vector.length);
|
|
496
|
+
let sumSq = 0;
|
|
497
|
+
for (let i = 0; i < minLen; i++) {
|
|
498
|
+
sumSq += (stateA.vector[i] - stateB.vector[i]) ** 2;
|
|
499
|
+
}
|
|
500
|
+
return Math.sqrt(sumSq) / Math.sqrt(minLen);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Calculate similarity between two states
|
|
504
|
+
*/
|
|
505
|
+
calculateSimilarity(stateA, stateB) {
|
|
506
|
+
const minLen = Math.min(stateA.vector.length, stateB.vector.length);
|
|
507
|
+
let dotProduct = 0;
|
|
508
|
+
let magA = 0;
|
|
509
|
+
let magB = 0;
|
|
510
|
+
for (let i = 0; i < minLen; i++) {
|
|
511
|
+
dotProduct += stateA.vector[i] * stateB.vector[i];
|
|
512
|
+
magA += stateA.vector[i] * stateA.vector[i];
|
|
513
|
+
magB += stateB.vector[i] * stateB.vector[i];
|
|
514
|
+
}
|
|
515
|
+
const magnitude = Math.sqrt(magA) * Math.sqrt(magB);
|
|
516
|
+
if (magnitude === 0)
|
|
517
|
+
return 0;
|
|
518
|
+
return (dotProduct / magnitude + 1) / 2; // Normalize to 0-1
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Blend two states
|
|
522
|
+
*/
|
|
523
|
+
blendStates(stateA, stateB, t) {
|
|
524
|
+
const minLen = Math.min(stateA.vector.length, stateB.vector.length);
|
|
525
|
+
const blended = new Array(minLen);
|
|
526
|
+
for (let i = 0; i < minLen; i++) {
|
|
527
|
+
blended[i] = stateA.vector[i] * (1 - t) + stateB.vector[i] * t;
|
|
528
|
+
}
|
|
529
|
+
return {
|
|
530
|
+
vector: blended,
|
|
531
|
+
dimensions: minLen,
|
|
532
|
+
sourceModality: stateA.sourceModality,
|
|
533
|
+
sourceId: `blended-${stateA.sourceId}`,
|
|
534
|
+
timestamp: new Date(),
|
|
535
|
+
confidence: Math.min(stateA.confidence, stateB.confidence),
|
|
536
|
+
entropy: stateA.entropy * (1 - t) + (stateB.entropy || 0.5) * t,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Correct drift by updating state
|
|
541
|
+
*/
|
|
542
|
+
correctDrift(realState) {
|
|
543
|
+
// Heavy blend toward real state
|
|
544
|
+
this.currentState = this.blendStates(this.currentState, realState, 0.8);
|
|
545
|
+
this.syncDrift = this.calculateDrift(this.currentState, realState);
|
|
546
|
+
this.emit({ type: 'drift_corrected', data: { newDrift: this.syncDrift } });
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Add state to history
|
|
550
|
+
*/
|
|
551
|
+
addToHistory(state) {
|
|
552
|
+
this.stateHistory.push({ ...state });
|
|
553
|
+
if (this.stateHistory.length > this.historyLimit) {
|
|
554
|
+
this.stateHistory.shift();
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Update prediction accuracy with new actual state
|
|
559
|
+
*/
|
|
560
|
+
updatePredictionAccuracy(actualState) {
|
|
561
|
+
// Find recent predictions that are now verifiable
|
|
562
|
+
const now = Date.now();
|
|
563
|
+
for (const p of this.predictionHistory) {
|
|
564
|
+
if (p.actual === null) {
|
|
565
|
+
const age = now - p.timestamp.getTime();
|
|
566
|
+
if (age > this.config.syncIntervalMs * 2) {
|
|
567
|
+
// This prediction is old enough to verify
|
|
568
|
+
p.actual = actualState;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Create initial latent state
|
|
575
|
+
*/
|
|
576
|
+
createInitialState() {
|
|
577
|
+
const dim = 512;
|
|
578
|
+
const vector = new Array(dim).fill(0);
|
|
579
|
+
return {
|
|
580
|
+
vector,
|
|
581
|
+
dimensions: dim,
|
|
582
|
+
sourceModality: 'state',
|
|
583
|
+
sourceId: `initial-${this.id}`,
|
|
584
|
+
timestamp: new Date(),
|
|
585
|
+
confidence: 0.5,
|
|
586
|
+
entropy: 0.5,
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
// ============================================================================
|
|
590
|
+
// Events
|
|
591
|
+
// ============================================================================
|
|
592
|
+
on(handler) {
|
|
593
|
+
this.eventHandlers.add(handler);
|
|
594
|
+
return () => this.eventHandlers.delete(handler);
|
|
595
|
+
}
|
|
596
|
+
emit(event) {
|
|
597
|
+
for (const handler of this.eventHandlers) {
|
|
598
|
+
try {
|
|
599
|
+
handler(event);
|
|
600
|
+
}
|
|
601
|
+
catch (err) {
|
|
602
|
+
console.error('Twin event handler error:', err);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
// ============================================================================
|
|
607
|
+
// Stats
|
|
608
|
+
// ============================================================================
|
|
609
|
+
getMetrics() {
|
|
610
|
+
return {
|
|
611
|
+
...this.metrics,
|
|
612
|
+
uptime: Date.now() - this.stateHistory[0]?.timestamp.getTime() || 0,
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
exports.DigitalTwinInstance = DigitalTwinInstance;
|
|
617
|
+
// ============================================================================
|
|
618
|
+
// Digital Twin Manager
|
|
619
|
+
// ============================================================================
|
|
620
|
+
class DigitalTwinManager {
|
|
621
|
+
twins = new Map();
|
|
622
|
+
/**
|
|
623
|
+
* Create a new digital twin
|
|
624
|
+
*/
|
|
625
|
+
createTwin(realSystemId, name, config) {
|
|
626
|
+
const twin = new DigitalTwinInstance(realSystemId, name, config);
|
|
627
|
+
this.twins.set(twin.id, twin);
|
|
628
|
+
return twin;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Get twin by ID
|
|
632
|
+
*/
|
|
633
|
+
getTwin(id) {
|
|
634
|
+
return this.twins.get(id);
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Get all twins
|
|
638
|
+
*/
|
|
639
|
+
getAllTwins() {
|
|
640
|
+
return Array.from(this.twins.values());
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Remove twin
|
|
644
|
+
*/
|
|
645
|
+
removeTwin(id) {
|
|
646
|
+
const twin = this.twins.get(id);
|
|
647
|
+
if (twin) {
|
|
648
|
+
twin.stopSync();
|
|
649
|
+
this.twins.delete(id);
|
|
650
|
+
return true;
|
|
651
|
+
}
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Get overall health
|
|
656
|
+
*/
|
|
657
|
+
getOverallHealth() {
|
|
658
|
+
let synced = 0;
|
|
659
|
+
let drifting = 0;
|
|
660
|
+
let disconnected = 0;
|
|
661
|
+
let totalSyncHealth = 0;
|
|
662
|
+
for (const twin of this.twins.values()) {
|
|
663
|
+
const health = twin.getHealth();
|
|
664
|
+
totalSyncHealth += health.syncHealth;
|
|
665
|
+
switch (twin.status) {
|
|
666
|
+
case 'synced':
|
|
667
|
+
synced++;
|
|
668
|
+
break;
|
|
669
|
+
case 'drifting':
|
|
670
|
+
drifting++;
|
|
671
|
+
break;
|
|
672
|
+
case 'disconnected':
|
|
673
|
+
disconnected++;
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
return {
|
|
678
|
+
totalTwins: this.twins.size,
|
|
679
|
+
synced,
|
|
680
|
+
drifting,
|
|
681
|
+
disconnected,
|
|
682
|
+
avgSyncHealth: this.twins.size > 0 ? totalSyncHealth / this.twins.size : 0,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
exports.DigitalTwinManager = DigitalTwinManager;
|
|
687
|
+
// ============================================================================
|
|
688
|
+
// Factory
|
|
689
|
+
// ============================================================================
|
|
690
|
+
function createDigitalTwin(realSystemId, name, config) {
|
|
691
|
+
return new DigitalTwinInstance(realSystemId, name, config);
|
|
692
|
+
}
|
|
693
|
+
function createDigitalTwinManager() {
|
|
694
|
+
return new DigitalTwinManager();
|
|
695
|
+
}
|