@vib3code/sdk 2.0.3-canary.60bc0f0 → 2.0.3-canary.74aebb4
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/DOCS/EXPANSION_DESIGN.md +977 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +387 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +2 -2
- package/DOCS/OPTIMIZATION_PLAN_MATH.md +118 -0
- package/DOCS/SYSTEM_INVENTORY.md +2 -2
- package/DOCS/WEBGPU_STATUS.md +119 -38
- package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +38 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +108 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +308 -0
- package/docs/webgpu-live.html +1 -1
- package/package.json +1 -1
- package/src/agent/mcp/MCPServer.js +195 -136
- package/src/agent/mcp/tools.js +45 -32
- package/src/experimental/GameLoop.js +72 -0
- package/src/experimental/LatticePhysics.js +100 -0
- package/src/experimental/LiveDirector.js +143 -0
- package/src/experimental/PlayerController4D.js +154 -0
- package/src/experimental/VIB3Actor.js +138 -0
- package/src/experimental/VIB3Compositor.js +117 -0
- package/src/experimental/VIB3Link.js +122 -0
- package/src/experimental/VIB3Orchestrator.js +146 -0
- package/src/experimental/VIB3Universe.js +109 -0
- package/src/experimental/demos/CrystalLabyrinth.js +202 -0
- package/src/faceted/FacetedSystem.js +19 -6
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/holograms/HolographicVisualizer.js +58 -89
- package/src/math/Mat4x4.js +122 -6
- package/src/math/Rotor4D.js +93 -39
- package/src/math/Vec4.js +119 -78
- package/src/quantum/QuantumVisualizer.js +24 -20
- package/src/render/ShaderLoader.js +38 -0
- package/src/render/ShaderProgram.js +4 -4
- package/src/render/UnifiedRenderBridge.js +1 -1
- package/src/render/backends/WebGPUBackend.js +8 -4
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +4 -4
- package/src/shaders/common/rotation4d.wgsl +2 -2
- package/src/shaders/common/uniforms.wgsl +15 -8
- package/src/shaders/faceted/faceted.frag.wgsl +19 -6
- package/src/shaders/holographic/holographic.frag.wgsl +7 -5
- package/src/shaders/quantum/quantum.frag.wgsl +7 -5
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
- package/tools/shader-sync-verify.js +6 -4
|
@@ -173,10 +173,13 @@ export class MCPServer {
|
|
|
173
173
|
result = this.getParameterSchema();
|
|
174
174
|
break;
|
|
175
175
|
case 'get_sdk_context':
|
|
176
|
-
result = this.getSDKContext();
|
|
176
|
+
result = this.getSDKContext(args);
|
|
177
177
|
break;
|
|
178
|
-
case '
|
|
179
|
-
result = this.
|
|
178
|
+
case 'inspect_layers':
|
|
179
|
+
result = this.inspectLayers(args);
|
|
180
|
+
break;
|
|
181
|
+
case 'set_holographic_layer':
|
|
182
|
+
result = this.setHolographicLayer(args);
|
|
180
183
|
break;
|
|
181
184
|
// Reactivity tools (Phase 6.5)
|
|
182
185
|
case 'set_reactivity_config':
|
|
@@ -650,162 +653,218 @@ export class MCPServer {
|
|
|
650
653
|
/**
|
|
651
654
|
* Get SDK context for agent onboarding
|
|
652
655
|
*/
|
|
653
|
-
getSDKContext() {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
656
|
+
getSDKContext(args = {}) {
|
|
657
|
+
const { include_state = true, include_tools = false } = args;
|
|
658
|
+
|
|
659
|
+
const context = {
|
|
660
|
+
sdk: 'VIB3+ 4D Visualization Engine',
|
|
661
|
+
version: '2.0.3',
|
|
662
|
+
|
|
663
|
+
// Capability manifest — what this engine can do
|
|
664
|
+
capabilities: {
|
|
665
|
+
systems: ['quantum', 'faceted', 'holographic'],
|
|
666
|
+
geometries: { count: 24, formula: 'core_type * 8 + base_geometry', base: 8, warps: 3 },
|
|
667
|
+
rotation: { planes: 6, '3D': ['XY', 'XZ', 'YZ'], '4D': ['XW', 'YW', 'ZW'], range: '±6.28 rad' },
|
|
668
|
+
layers: { count: 5, roles: ['background', 'shadow', 'content', 'highlight', 'accent'], addressable: true },
|
|
669
|
+
audio: { bands: ['bass', 'mid', 'high'], modes: ['add', 'multiply', 'replace', 'max', 'min'] },
|
|
670
|
+
input: { sources: ['deviceTilt', 'mousePosition', 'gyroscope', 'gamepad', 'perspective', 'programmatic', 'audio', 'midi'] },
|
|
671
|
+
creative: {
|
|
672
|
+
color_presets: 22,
|
|
673
|
+
easing_functions: 14,
|
|
674
|
+
post_effects: 14,
|
|
675
|
+
aesthetic_keywords: '130+',
|
|
676
|
+
choreography: true,
|
|
677
|
+
timeline_bpm_sync: true
|
|
678
|
+
},
|
|
679
|
+
environment: {
|
|
680
|
+
browser: typeof document !== 'undefined',
|
|
681
|
+
screenshot: typeof document !== 'undefined',
|
|
682
|
+
webgpu: typeof navigator !== 'undefined' && !!navigator.gpu,
|
|
683
|
+
wasm: typeof WebAssembly !== 'undefined'
|
|
684
|
+
}
|
|
678
685
|
},
|
|
679
686
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
687
|
+
// Parameter ranges — the agent needs these to generate valid values
|
|
688
|
+
parameter_ranges: {
|
|
689
|
+
geometry: { min: 0, max: 23, type: 'integer' },
|
|
690
|
+
hue: { min: 0, max: 360, type: 'integer' },
|
|
691
|
+
saturation: { min: 0, max: 1 },
|
|
692
|
+
intensity: { min: 0, max: 1 },
|
|
693
|
+
speed: { min: 0.1, max: 3 },
|
|
694
|
+
chaos: { min: 0, max: 1 },
|
|
695
|
+
morphFactor: { min: 0, max: 2 },
|
|
696
|
+
gridDensity: { min: 4, max: 100 },
|
|
697
|
+
dimension: { min: 3.0, max: 4.5 },
|
|
698
|
+
rot4dXY: { min: -6.28, max: 6.28 },
|
|
699
|
+
rot4dXW: { min: -6.28, max: 6.28 }
|
|
685
700
|
},
|
|
686
701
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
702
|
+
// Workflow hints — what tool sequences accomplish creative goals
|
|
703
|
+
workflows: {
|
|
704
|
+
quick_design: 'design_from_description → describe_visual_state → batch_set_parameters',
|
|
705
|
+
choreography: 'create_choreography → play_choreography → describe_visual_state',
|
|
706
|
+
evolve: 'batch_set_parameters → describe_visual_state → batch_set_parameters (iterate)',
|
|
707
|
+
layer_control: 'inspect_layers → set_holographic_layer → inspect_layers',
|
|
708
|
+
audio_reactive: 'configure_audio_band → apply_behavior_preset → describe_visual_state'
|
|
692
709
|
},
|
|
693
710
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
711
|
+
// Geometry quick-reference
|
|
712
|
+
geometry_map: {
|
|
713
|
+
'sphere': 2, 'hypersphere+sphere': 10, 'hypertetra+sphere': 18,
|
|
714
|
+
'torus': 3, 'hypersphere+torus': 11, 'hypertetra+torus': 19,
|
|
715
|
+
'fractal': 5, 'hypersphere+fractal': 13, 'hypertetra+fractal': 21,
|
|
716
|
+
'crystal': 7, 'wave': 6, 'klein_bottle': 4, 'hypercube': 1, 'tetrahedron': 0
|
|
717
|
+
}
|
|
718
|
+
};
|
|
698
719
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
'Q1: How many rotation planes? a)3 b)4 c)6 d)8',
|
|
703
|
-
'Q2: Geometry encoding formula? a)base*3+core b)core*8+base c)base+core d)core*base',
|
|
704
|
-
'Q3: Canvas layers per system? a)3 b)4 c)5 d)6',
|
|
705
|
-
'Q4: Which are the 3 ACTIVE systems? a)quantum,faceted,holographic b)quantum,faceted,polychora c)all four d)none',
|
|
706
|
-
'Q5: How many base geometry types? a)6 b)8 c)10 d)24',
|
|
707
|
-
'Q6: Core warp types? a)base,sphere,cube b)base,hypersphere,hypertetrahedron c)2D,3D,4D d)none'
|
|
708
|
-
]
|
|
709
|
-
},
|
|
720
|
+
if (include_state) {
|
|
721
|
+
context.current_state = this.getState();
|
|
722
|
+
}
|
|
710
723
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
724
|
+
if (include_tools) {
|
|
725
|
+
context.tool_summary = Object.entries(toolDefinitions).map(([name, def]) => ({
|
|
726
|
+
name,
|
|
727
|
+
description: def.description.split('.')[0] // First sentence only
|
|
728
|
+
}));
|
|
729
|
+
}
|
|
717
730
|
|
|
718
|
-
|
|
719
|
-
};
|
|
731
|
+
return context;
|
|
720
732
|
}
|
|
721
733
|
|
|
722
734
|
/**
|
|
723
|
-
*
|
|
735
|
+
* Inspect holographic layer state — returns per-layer metadata in JSON format.
|
|
736
|
+
* This replaces the old verify_knowledge quiz with something actually useful.
|
|
724
737
|
*/
|
|
725
|
-
|
|
726
|
-
const
|
|
727
|
-
q1_rotation_planes: 'c', // 6 rotation planes
|
|
728
|
-
q2_geometry_formula: 'b', // core*8+base
|
|
729
|
-
q3_canvas_layers: 'c', // 5 layers
|
|
730
|
-
q4_active_systems: 'a', // quantum, faceted, holographic (polychora is TBD)
|
|
731
|
-
q5_base_geometries: 'b', // 8 base geometries
|
|
732
|
-
q6_core_types: 'b' // base, hypersphere, hypertetrahedron
|
|
733
|
-
};
|
|
738
|
+
inspectLayers(args = {}) {
|
|
739
|
+
const { layer = 'all' } = args;
|
|
734
740
|
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
},
|
|
761
|
-
|
|
762
|
-
topic: 'CORE WARP TYPES',
|
|
763
|
-
doc: '24-GEOMETRY-6D-ROTATION-SUMMARY.md',
|
|
764
|
-
reason: '3 cores: base (no warp), hypersphere, hypertetrahedron'
|
|
765
|
-
}
|
|
741
|
+
const systemName = this.engine?.currentSystemName || 'unknown';
|
|
742
|
+
const isHolographic = systemName === 'holographic';
|
|
743
|
+
|
|
744
|
+
if (!isHolographic) {
|
|
745
|
+
return {
|
|
746
|
+
system: systemName,
|
|
747
|
+
note: 'Layer inspection is most detailed for the holographic system (5 independent canvas layers). Switch with switch_system("holographic").',
|
|
748
|
+
layers: [{
|
|
749
|
+
role: 'main',
|
|
750
|
+
system: systemName,
|
|
751
|
+
opacity: 1.0,
|
|
752
|
+
enabled: true,
|
|
753
|
+
description: `Single canvas for ${systemName} system`
|
|
754
|
+
}],
|
|
755
|
+
suggested_next_actions: ['switch_system', 'describe_visual_state']
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Build layer metadata from the holographic system
|
|
760
|
+
const system = this.engine?.currentSystem;
|
|
761
|
+
const layerRoles = ['background', 'shadow', 'content', 'highlight', 'accent'];
|
|
762
|
+
const defaultConfigs = {
|
|
763
|
+
background: { densityMult: 0.4, speedMult: 0.2, colorShift: 0, intensity: 0.2, reactivity: 0.5 },
|
|
764
|
+
shadow: { densityMult: 0.8, speedMult: 0.3, colorShift: 180, intensity: 0.4, reactivity: 0.7 },
|
|
765
|
+
content: { densityMult: 1.0, speedMult: 1.0, colorShift: 0, intensity: 1.0, reactivity: 0.9 },
|
|
766
|
+
highlight: { densityMult: 1.5, speedMult: 0.8, colorShift: 60, intensity: 0.6, reactivity: 1.1 },
|
|
767
|
+
accent: { densityMult: 2.5, speedMult: 0.4, colorShift: 300, intensity: 0.3, reactivity: 1.5 }
|
|
766
768
|
};
|
|
767
769
|
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
770
|
+
const buildLayerInfo = (role) => {
|
|
771
|
+
const config = defaultConfigs[role] || {};
|
|
772
|
+
const visualizer = system?.visualizers?.find?.(v => v?.role === role);
|
|
773
|
+
const overrides = this._layerOverrides?.get(role) || {};
|
|
774
|
+
|
|
775
|
+
return {
|
|
776
|
+
role,
|
|
777
|
+
enabled: overrides.enabled !== undefined ? overrides.enabled : true,
|
|
778
|
+
opacity: overrides.opacity !== undefined ? overrides.opacity : 1.0,
|
|
779
|
+
blendMode: overrides.blendMode || 'normal',
|
|
780
|
+
densityMult: overrides.densityMult ?? config.densityMult,
|
|
781
|
+
speedMult: overrides.speedMult ?? config.speedMult,
|
|
782
|
+
colorShift: overrides.colorShift ?? config.colorShift,
|
|
783
|
+
intensity: overrides.intensity ?? config.intensity,
|
|
784
|
+
reactivity: overrides.reactivity ?? config.reactivity,
|
|
785
|
+
has_visualizer: !!visualizer
|
|
786
|
+
};
|
|
773
787
|
};
|
|
774
788
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
if (given === correct) {
|
|
779
|
-
results.score++;
|
|
780
|
-
results.details.push({ question, status: '✓ CORRECT' });
|
|
781
|
-
} else if (given !== undefined) {
|
|
782
|
-
results.details.push({
|
|
783
|
-
question,
|
|
784
|
-
status: '✗ WRONG',
|
|
785
|
-
your_answer: given,
|
|
786
|
-
correct_answer: correct
|
|
787
|
-
});
|
|
788
|
-
results.REVIEW_REQUIRED.push(docReferences[question]);
|
|
789
|
-
}
|
|
790
|
-
}
|
|
789
|
+
const layers = layer === 'all'
|
|
790
|
+
? layerRoles.map(buildLayerInfo)
|
|
791
|
+
: [buildLayerInfo(layer)];
|
|
791
792
|
|
|
792
|
-
|
|
793
|
+
return {
|
|
794
|
+
system: 'holographic',
|
|
795
|
+
layer_count: layerRoles.length,
|
|
796
|
+
layers,
|
|
797
|
+
suggested_next_actions: ['set_holographic_layer', 'batch_set_parameters', 'describe_visual_state']
|
|
798
|
+
};
|
|
799
|
+
}
|
|
793
800
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
801
|
+
/**
|
|
802
|
+
* Set properties on an individual holographic layer.
|
|
803
|
+
* Stores overrides in a layer override map and applies them to the visualizer.
|
|
804
|
+
*/
|
|
805
|
+
setHolographicLayer(args) {
|
|
806
|
+
const { layer, opacity, blendMode, enabled, colorShift, densityMult, speedMult, reactivity } = args;
|
|
807
|
+
|
|
808
|
+
const systemName = this.engine?.currentSystemName || 'unknown';
|
|
809
|
+
if (systemName !== 'holographic') {
|
|
810
|
+
return {
|
|
811
|
+
error: {
|
|
812
|
+
type: 'SystemError',
|
|
813
|
+
code: 'NOT_HOLOGRAPHIC',
|
|
814
|
+
message: `set_holographic_layer requires holographic system (current: ${systemName})`,
|
|
815
|
+
suggestion: 'Call switch_system("holographic") first'
|
|
816
|
+
}
|
|
817
|
+
};
|
|
804
818
|
}
|
|
805
819
|
|
|
806
|
-
|
|
820
|
+
// Initialize layer override storage
|
|
821
|
+
if (!this._layerOverrides) this._layerOverrides = new Map();
|
|
822
|
+
const existing = this._layerOverrides.get(layer) || {};
|
|
823
|
+
const updates = {};
|
|
824
|
+
|
|
825
|
+
if (opacity !== undefined) { existing.opacity = opacity; updates.opacity = opacity; }
|
|
826
|
+
if (blendMode !== undefined) { existing.blendMode = blendMode; updates.blendMode = blendMode; }
|
|
827
|
+
if (enabled !== undefined) { existing.enabled = enabled; updates.enabled = enabled; }
|
|
828
|
+
if (colorShift !== undefined) { existing.colorShift = colorShift; updates.colorShift = colorShift; }
|
|
829
|
+
if (densityMult !== undefined) { existing.densityMult = densityMult; updates.densityMult = densityMult; }
|
|
830
|
+
if (speedMult !== undefined) { existing.speedMult = speedMult; updates.speedMult = speedMult; }
|
|
831
|
+
if (reactivity !== undefined) { existing.reactivity = reactivity; updates.reactivity = reactivity; }
|
|
832
|
+
|
|
833
|
+
this._layerOverrides.set(layer, existing);
|
|
834
|
+
|
|
835
|
+
// Apply to visualizer if available
|
|
836
|
+
const system = this.engine?.currentSystem;
|
|
837
|
+
const visualizer = system?.visualizers?.find?.(v => v?.role === layer);
|
|
838
|
+
if (visualizer) {
|
|
839
|
+
if (opacity !== undefined && visualizer.canvas) {
|
|
840
|
+
visualizer.canvas.style.opacity = String(opacity);
|
|
841
|
+
}
|
|
842
|
+
if (blendMode !== undefined && visualizer.canvas) {
|
|
843
|
+
visualizer.canvas.style.mixBlendMode = blendMode;
|
|
844
|
+
}
|
|
845
|
+
if (enabled !== undefined && visualizer.canvas) {
|
|
846
|
+
visualizer.canvas.style.display = enabled ? '' : 'none';
|
|
847
|
+
}
|
|
848
|
+
if (colorShift !== undefined && visualizer.roleParams) {
|
|
849
|
+
visualizer.roleParams.colorShift = colorShift;
|
|
850
|
+
}
|
|
851
|
+
if (densityMult !== undefined && visualizer.roleParams) {
|
|
852
|
+
visualizer.roleParams.densityMult = densityMult;
|
|
853
|
+
}
|
|
854
|
+
if (speedMult !== undefined && visualizer.roleParams) {
|
|
855
|
+
visualizer.roleParams.speedMult = speedMult;
|
|
856
|
+
}
|
|
857
|
+
if (reactivity !== undefined) {
|
|
858
|
+
visualizer.reactivity = reactivity;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
807
861
|
|
|
808
|
-
return
|
|
862
|
+
return {
|
|
863
|
+
layer,
|
|
864
|
+
applied: updates,
|
|
865
|
+
current_state: this.inspectLayers({ layer }).layers[0],
|
|
866
|
+
suggested_next_actions: ['inspect_layers', 'set_holographic_layer', 'describe_visual_state']
|
|
867
|
+
};
|
|
809
868
|
}
|
|
810
869
|
|
|
811
870
|
/**
|
package/src/agent/mcp/tools.js
CHANGED
|
@@ -222,51 +222,64 @@ export const toolDefinitions = {
|
|
|
222
222
|
// Onboarding Tools
|
|
223
223
|
get_sdk_context: {
|
|
224
224
|
name: 'get_sdk_context',
|
|
225
|
-
description: 'Returns
|
|
225
|
+
description: 'Returns a compact capability manifest: what systems exist, what tools are available, what parameter ranges are valid, and what the current engine state is. Designed for injection into agent context — call once at session start, not repeatedly.',
|
|
226
226
|
inputSchema: {
|
|
227
227
|
type: 'object',
|
|
228
|
-
properties: {
|
|
228
|
+
properties: {
|
|
229
|
+
include_state: {
|
|
230
|
+
type: 'boolean',
|
|
231
|
+
default: true,
|
|
232
|
+
description: 'Include current engine state in response'
|
|
233
|
+
},
|
|
234
|
+
include_tools: {
|
|
235
|
+
type: 'boolean',
|
|
236
|
+
default: false,
|
|
237
|
+
description: 'Include tool summary list (names + one-line descriptions)'
|
|
238
|
+
}
|
|
239
|
+
}
|
|
229
240
|
}
|
|
230
241
|
},
|
|
231
242
|
|
|
232
|
-
|
|
233
|
-
name: '
|
|
234
|
-
description: '
|
|
243
|
+
inspect_layers: {
|
|
244
|
+
name: 'inspect_layers',
|
|
245
|
+
description: 'Returns the current state of all holographic canvas layers with per-layer metadata: role, opacity, blend mode, reactivity multiplier, role-specific parameters, and enabled state. Only meaningful when holographic system is active.',
|
|
235
246
|
inputSchema: {
|
|
236
247
|
type: 'object',
|
|
237
248
|
properties: {
|
|
238
|
-
|
|
239
|
-
type: 'string',
|
|
240
|
-
enum: ['a', 'b', 'c', 'd'],
|
|
241
|
-
description: 'Q1: How many rotation planes? a)3 b)4 c)6 d)8'
|
|
242
|
-
},
|
|
243
|
-
q2_geometry_formula: {
|
|
244
|
-
type: 'string',
|
|
245
|
-
enum: ['a', 'b', 'c', 'd'],
|
|
246
|
-
description: 'Q2: Geometry encoding formula? a)base*3+core b)core*8+base c)base+core d)core*base'
|
|
247
|
-
},
|
|
248
|
-
q3_canvas_layers: {
|
|
249
|
+
layer: {
|
|
249
250
|
type: 'string',
|
|
250
|
-
enum: ['
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
251
|
+
enum: ['background', 'shadow', 'content', 'highlight', 'accent', 'all'],
|
|
252
|
+
default: 'all',
|
|
253
|
+
description: 'Inspect a specific layer or all layers'
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
set_holographic_layer: {
|
|
260
|
+
name: 'set_holographic_layer',
|
|
261
|
+
description: 'Controls individual holographic layer properties. Set opacity, blend mode, enable/disable, or override role parameters for any of the 5 layers (background, shadow, content, highlight, accent). Only works when holographic system is active.',
|
|
262
|
+
inputSchema: {
|
|
263
|
+
type: 'object',
|
|
264
|
+
properties: {
|
|
265
|
+
layer: {
|
|
254
266
|
type: 'string',
|
|
255
|
-
enum: ['
|
|
256
|
-
description: '
|
|
267
|
+
enum: ['background', 'shadow', 'content', 'highlight', 'accent'],
|
|
268
|
+
description: 'Target layer role name'
|
|
257
269
|
},
|
|
258
|
-
|
|
270
|
+
opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Layer opacity (0=invisible, 1=full)' },
|
|
271
|
+
blendMode: {
|
|
259
272
|
type: 'string',
|
|
260
|
-
enum: ['
|
|
261
|
-
description: '
|
|
273
|
+
enum: ['normal', 'screen', 'multiply', 'add', 'overlay'],
|
|
274
|
+
description: 'CSS blend mode for this layer'
|
|
262
275
|
},
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
276
|
+
enabled: { type: 'boolean', description: 'Show/hide this layer' },
|
|
277
|
+
colorShift: { type: 'number', minimum: 0, maximum: 360, description: 'Hue offset for this layer' },
|
|
278
|
+
densityMult: { type: 'number', minimum: 0.1, maximum: 5, description: 'Grid density multiplier' },
|
|
279
|
+
speedMult: { type: 'number', minimum: 0, maximum: 3, description: 'Animation speed multiplier' },
|
|
280
|
+
reactivity: { type: 'number', minimum: 0, maximum: 3, description: 'Mouse/touch reactivity multiplier' }
|
|
268
281
|
},
|
|
269
|
-
required: ['
|
|
282
|
+
required: ['layer']
|
|
270
283
|
}
|
|
271
284
|
},
|
|
272
285
|
|
|
@@ -651,7 +664,7 @@ export const toolDefinitions = {
|
|
|
651
664
|
|
|
652
665
|
capture_screenshot: {
|
|
653
666
|
name: 'capture_screenshot',
|
|
654
|
-
description: 'Captures
|
|
667
|
+
description: 'Captures current visualization as a base64-encoded PNG by compositing canvas layers. BROWSER-ONLY: returns an EnvironmentError with capability report in headless/Node contexts. When available, returns data_url for multimodal analysis. Use describe_visual_state as a text-based alternative in non-browser environments.',
|
|
655
668
|
inputSchema: {
|
|
656
669
|
type: 'object',
|
|
657
670
|
properties: {
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GameLoop - Fixed-Timestep Physics Loop
|
|
3
|
+
*
|
|
4
|
+
* Provides a robust game loop that decouples physics updates (fixed step)
|
|
5
|
+
* from rendering (variable step). This is crucial for consistent physics
|
|
6
|
+
* and smooth rendering across different device capabilities.
|
|
7
|
+
*
|
|
8
|
+
* @experimental
|
|
9
|
+
*/
|
|
10
|
+
export class GameLoop {
|
|
11
|
+
/**
|
|
12
|
+
* @param {function(number)} updateFn - Physics update (fixed dt)
|
|
13
|
+
* @param {function(number)} renderFn - Render update (interpolated alpha)
|
|
14
|
+
* @param {number} step - Physics step size in seconds (default 1/60)
|
|
15
|
+
*/
|
|
16
|
+
constructor(updateFn, renderFn, step = 1 / 60) {
|
|
17
|
+
this.updateFn = updateFn;
|
|
18
|
+
this.renderFn = renderFn;
|
|
19
|
+
this.step = step;
|
|
20
|
+
this.dt = 0;
|
|
21
|
+
this.last = 0;
|
|
22
|
+
this.now = 0;
|
|
23
|
+
this.accumulator = 0;
|
|
24
|
+
this.running = false;
|
|
25
|
+
this.rafId = null;
|
|
26
|
+
|
|
27
|
+
// Bind loop
|
|
28
|
+
this.frame = this.frame.bind(this);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
start() {
|
|
32
|
+
if (this.running) return;
|
|
33
|
+
this.running = true;
|
|
34
|
+
this.last = performance.now();
|
|
35
|
+
this.accumulator = 0;
|
|
36
|
+
this.rafId = requestAnimationFrame(this.frame);
|
|
37
|
+
console.log('GameLoop: Started.');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
stop() {
|
|
41
|
+
this.running = false;
|
|
42
|
+
if (this.rafId) {
|
|
43
|
+
cancelAnimationFrame(this.rafId);
|
|
44
|
+
this.rafId = null;
|
|
45
|
+
}
|
|
46
|
+
console.log('GameLoop: Stopped.');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
frame(timestamp) {
|
|
50
|
+
if (!this.running) return;
|
|
51
|
+
|
|
52
|
+
this.now = timestamp;
|
|
53
|
+
// Cap dt to avoid "spiral of death" on lag spikes (max 1s)
|
|
54
|
+
this.dt = Math.min(1, (this.now - this.last) / 1000);
|
|
55
|
+
this.last = this.now;
|
|
56
|
+
|
|
57
|
+
this.accumulator += this.dt;
|
|
58
|
+
|
|
59
|
+
// Consume accumulator in fixed steps
|
|
60
|
+
while (this.accumulator >= this.step) {
|
|
61
|
+
this.updateFn(this.step);
|
|
62
|
+
this.accumulator -= this.step;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Render with interpolation factor alpha
|
|
66
|
+
// alpha = accumulator / step
|
|
67
|
+
// Allows renderer to interpolate between previous and current physics state
|
|
68
|
+
this.renderFn(this.accumulator / this.step);
|
|
69
|
+
|
|
70
|
+
this.rafId = requestAnimationFrame(this.frame);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LatticePhysics - Function-Based Collision Detection
|
|
3
|
+
*
|
|
4
|
+
* Provides a physics engine for "Lattice Worlds" where geometry is defined
|
|
5
|
+
* by mathematical density functions (SDFs, fractals).
|
|
6
|
+
*
|
|
7
|
+
* @experimental
|
|
8
|
+
*/
|
|
9
|
+
export class LatticePhysics {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.gravity = 9.8; // m/s²
|
|
12
|
+
this.friction = 0.95; // Velocity decay per step
|
|
13
|
+
this.densityThreshold = 0.8; // Collision threshold (0-1)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Update physics for all entities in the universe.
|
|
18
|
+
* @param {Map<string, object>} entities
|
|
19
|
+
* @param {number} dt
|
|
20
|
+
*/
|
|
21
|
+
update(entities, dt) {
|
|
22
|
+
entities.forEach(entity => {
|
|
23
|
+
if (entity.physics && entity.active) {
|
|
24
|
+
this.updateEntity(entity, dt);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Update a single entity's physics state.
|
|
31
|
+
* @param {object} entity
|
|
32
|
+
* @param {number} dt
|
|
33
|
+
*/
|
|
34
|
+
updateEntity(entity, dt) {
|
|
35
|
+
const { pos, vel, acc } = entity.physics;
|
|
36
|
+
|
|
37
|
+
// Apply forces (Gravity)
|
|
38
|
+
// In this abstract world, gravity pulls "down" in Y
|
|
39
|
+
acc.y -= this.gravity * dt;
|
|
40
|
+
|
|
41
|
+
// Integrate Velocity (Euler)
|
|
42
|
+
vel.x += acc.x * dt;
|
|
43
|
+
vel.y += acc.y * dt;
|
|
44
|
+
vel.z += acc.z * dt;
|
|
45
|
+
|
|
46
|
+
// Reset acceleration (forces are transient)
|
|
47
|
+
acc.x = 0; acc.y = 0; acc.z = 0;
|
|
48
|
+
|
|
49
|
+
// Collision Check (Projected Position)
|
|
50
|
+
const nextX = pos.x + vel.x * dt;
|
|
51
|
+
const nextY = pos.y + vel.y * dt;
|
|
52
|
+
const nextZ = pos.z + vel.z * dt;
|
|
53
|
+
|
|
54
|
+
// Sample density at next position
|
|
55
|
+
const density = this.getDensityAt(nextX, nextY, nextZ);
|
|
56
|
+
|
|
57
|
+
if (density > this.densityThreshold) {
|
|
58
|
+
// Collision!
|
|
59
|
+
// Simple response: Stop velocity component and push out
|
|
60
|
+
// A real engine would calculate surface normal from gradient
|
|
61
|
+
|
|
62
|
+
// Simplified: Just stop movement and bounce slightly
|
|
63
|
+
vel.x *= -0.5;
|
|
64
|
+
vel.y *= -0.5;
|
|
65
|
+
vel.z *= -0.5;
|
|
66
|
+
|
|
67
|
+
// Don't update position into solid
|
|
68
|
+
} else {
|
|
69
|
+
// Move freely
|
|
70
|
+
pos.x = nextX;
|
|
71
|
+
pos.y = nextY;
|
|
72
|
+
pos.z = nextZ;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Apply Friction (Air/Ether drag)
|
|
76
|
+
vel.x *= this.friction;
|
|
77
|
+
vel.y *= this.friction;
|
|
78
|
+
vel.z *= this.friction;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Sample the "world density" at a given point.
|
|
83
|
+
* This mimics the shader's generation logic (e.g., fractal noise).
|
|
84
|
+
* @param {number} x
|
|
85
|
+
* @param {number} y
|
|
86
|
+
* @param {number} z
|
|
87
|
+
* @returns {number} Density 0.0 to 1.0
|
|
88
|
+
*/
|
|
89
|
+
getDensityAt(x, y, z) {
|
|
90
|
+
// Mock function: simple floor plane at y = -2
|
|
91
|
+
if (y < -2) return 1.0;
|
|
92
|
+
|
|
93
|
+
// Mock function: occasional "floating islands" based on sine waves
|
|
94
|
+
// simulating the VIB3 lattice structure
|
|
95
|
+
const noise = (Math.sin(x * 0.5) + Math.cos(z * 0.5)) * 0.5 + 0.5;
|
|
96
|
+
if (y > 0 && y < 1 && noise > 0.8) return 1.0;
|
|
97
|
+
|
|
98
|
+
return 0.0;
|
|
99
|
+
}
|
|
100
|
+
}
|