Update 8 - LowPowerMode + Bugfixes
All checks were successful
release-tag / release-image (push) Successful in 2m25s
All checks were successful
release-tag / release-image (push) Successful in 2m25s
This commit is contained in:
35
CHANGELOG-CONSTELLATION-ECO-TRANSITIONS.md
Normal file
35
CHANGELOG-CONSTELLATION-ECO-TRANSITIONS.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Changelog: Constellation, ECO und weiche Graphübergänge
|
||||
|
||||
## Visualisierung
|
||||
|
||||
- neue semantische **Constellation**-Ansicht mit Themenzentren, stabilen Sternpositionen, aggregierten Themenverbindungen und Aktivitätsdarstellung;
|
||||
- direkte Umschaltung zwischen Neural, Honeycomb und Constellation;
|
||||
- FPS-Anzeige in der Statusleiste;
|
||||
- Constellation als persistierbarer `view_mode` und als `BRAIN_DEFAULT_VIEW` unterstützt.
|
||||
|
||||
## Performance
|
||||
|
||||
- persistierbarer **ECO**-Schalter für schwächere Systeme;
|
||||
- ungefähr 30-FPS-Limit, reduzierte DPR und feste Budgets für Edges, Partikel, Wolken, Sterne und Recherchequellen;
|
||||
- gecachter Offscreen-Hintergrund;
|
||||
- Kamera- und Projektionsparameter nur einmal pro Frame;
|
||||
- gedrosselte Tiefensortierung im ECO-Modus;
|
||||
- stabile Honeycomb-Slots statt vollständiger Neuverteilung;
|
||||
- zusammengeführte und entprellte Graphreloads;
|
||||
- identische Snapshots werden ohne Renderarbeit verworfen;
|
||||
- reine Kantenupdates erzeugen keinen kompletten Node-Layout-Neuaufbau.
|
||||
|
||||
## Übergänge
|
||||
|
||||
- Fade-in für neue Nodes und Edges;
|
||||
- begrenzter Fade-out-Puffer für entfernte Elemente;
|
||||
- Positionsmorphing bei Layoutänderungen;
|
||||
- Ghost-Fade beim Wechsel des Ansichtsmodus;
|
||||
- bestehende Node-Objekte und Positionen werden bei Graphupdates in-place erhalten;
|
||||
- SearXNG-Animationen bleiben von Graph- und Viewübergängen unabhängig.
|
||||
|
||||
## Fehlerkorrektur
|
||||
|
||||
- fehlende oder `null`-basierte Research-Evidence-Metadaten werden nicht mehr zu `data/<nil>` beziehungsweise `data\\<nil>` aufgelöst;
|
||||
- die wiederholte Warnung `stored research evidence could not be reused ... path:"<nil>"` entfällt;
|
||||
- Regressionstest für fehlende, `nil`, `<nil>` und `null` enthaltende `evidence_path`-Werte ergänzt.
|
||||
22
README.md
22
README.md
@@ -5,7 +5,8 @@ Eigenständiger Go-Dienst für Agent, lokale Knowledgebase, GLPI-Knowledgebase u
|
||||
## Kernfunktionen
|
||||
|
||||
- Fullscreen-Canvas mit 3D-Hirnform, semantischen Cortex-Regionen und hierarchischem Level-of-Detail.
|
||||
- Umschaltbare Honeycomb-Ansicht: gleichmäßig verteilte Notes in einer automatisch skalierten 3D-Gehirnwabe, ohne Edge-Rendering.
|
||||
- Drei Visualisierungen: Neural-Brain, gleichmäßige 3D-Honeycomb-Wabe und semantische Constellation-Ansicht mit Themensternen.
|
||||
- Persistierbarer **ECO**-Modus für schwächere Systeme sowie weiche Node-, Edge- und Ansichtsübergänge ohne sichtbaren Komplett-Reload.
|
||||
- Laufzeitsteuerung für Learning und Thinking sowie getrennte Kategorie-Filter für Lernen, Anzeige und AI-THINK.
|
||||
- Echtzeitaktivierung über Server-Sent Events: Nodes glühen, aggregierte Edges leuchten und Partikel folgen tatsächlichen Wissenspfaden.
|
||||
- Ingest lokaler produktiver Knowledge-JSONs sowie separater AI-THINK-Staging-Dateien.
|
||||
@@ -133,9 +134,9 @@ curl -fsS http://localhost:8090/api/state/export -o graph.db
|
||||
|
||||
Mehr Details: [`PERSISTENCE.md`](PERSISTENCE.md) und [`SQLITE-STORAGE.md`](SQLITE-STORAGE.md).
|
||||
|
||||
## Laufzeitsteuerung und Honeycomb
|
||||
## Laufzeitsteuerung, Visualisierungen und Performance
|
||||
|
||||
Die untere Steuerleiste enthält direkte Schalter für **LEARNING**, **THINKING**, **NEURAL** und **HONEYCOMB**. Sind Learning und Thinking deaktiviert, bleibt das System im Living-Modus; eingehende Agent- oder KB-Anfragen können weiterhin die tatsächlich verwendeten Notes aktivieren.
|
||||
Die untere Steuerleiste enthält direkte Schalter für **LEARNING**, **THINKING**, **NEURAL**, **HONEYCOMB**, **CONSTELLATION** und **ECO**. Sind Learning und Thinking deaktiviert, bleibt das System im Living-Modus; eingehende Agent- oder KB-Anfragen können weiterhin die tatsächlich verwendeten Notes aktivieren.
|
||||
|
||||
Über **FILTER** lassen sich drei unabhängige Kategorienlisten pflegen:
|
||||
|
||||
@@ -151,13 +152,22 @@ BRAIN_THINKING_ENABLED=true
|
||||
BRAIN_LEARNING_CATEGORIES=
|
||||
BRAIN_DISPLAY_CATEGORIES=
|
||||
BRAIN_THINKING_CATEGORIES=
|
||||
BRAIN_DEFAULT_VIEW=neural
|
||||
BRAIN_DEFAULT_VIEW=neural # neural | honeycomb | constellation
|
||||
BRAIN_MAX_DISPLAY_NODES=0 # 0 = unbegrenzt; alternativ z. B. 5000
|
||||
BRAIN_LOW_POWER_MODE=false
|
||||
```
|
||||
|
||||
Honeycomb rendert nur `knowledge`, `ai-think` und `external`. Ein 3D-Gitter mit einheitlichem Punktabstand wird auf die Gehirngeometrie beschnitten und automatisch an die sichtbare Anzahl von Notes angepasst. Edges, LOD-Gruppen und Cortex-Flächen bleiben dort unsichtbar; bei einer Anfrage leuchten nur die referenzierten Notes.
|
||||
Die Ansichten erfüllen unterschiedliche Aufgaben:
|
||||
|
||||
Mehr Details: [`RUNTIME-CONTROLS-HONEYCOMB.md`](RUNTIME-CONTROLS-HONEYCOMB.md).
|
||||
- **Neural** zeigt das lebende semantische Netz mit LOD, Cortex, Synapsen und Partikeln.
|
||||
- **Honeycomb** rendert `knowledge`, `ai-think` und `external` gleichmäßig in einer 3D-Gehirnwabe. Reguläre Edges und Cortex-Flächen bleiben dort unsichtbar.
|
||||
- **Constellation** ordnet Wissenselemente als Themensterne um semantische Zentren an. Dezente Bahnen und aggregierte Themenverbindungen machen Fachgebiete und Übergänge leichter lesbar als ein dichtes Gesamtnetz.
|
||||
|
||||
Der **ECO**-Schalter begrenzt die Ausgabe auf ungefähr 30 FPS, reduziert die Device-Pixel-Ratio, teure Gradienten, Hintergrundsterne, gleichzeitig sichtbare inaktive Edges, Partikel und Wolken. Aktivierte Nodes, SearXNG-Animationen, Themenzentren und Übergänge bleiben sichtbar. Das ist zusätzlich zum GPU-Node-Limit; der ECO-Modus entfernt keine Wissenselemente.
|
||||
|
||||
Graphupdates verändern vorhandene Node-Objekte und Positionen in-place. Neue Elemente blenden ein, entfernte Elemente blenden aus, Ansichtswechsel morphen zwischen den Koordinatenräumen. Unveränderte Snapshots werden übersprungen und reine Edgeupdates lösen keinen vollständigen Layout-Neuaufbau aus.
|
||||
|
||||
Mehr Details: [`VISUALIZATION-PERFORMANCE.md`](VISUALIZATION-PERFORMANCE.md) und [`RUNTIME-CONTROLS-HONEYCOMB.md`](RUNTIME-CONTROLS-HONEYCOMB.md).
|
||||
|
||||
## Autonome Anreicherung
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Runtime Controls und Honeycomb
|
||||
# Runtime Controls, Ansichten und ECO
|
||||
|
||||
Die Fullscreen-Oberfläche kann die aktiven Hintergrundprozesse und die Darstellung ohne Neustart umschalten. Die Einstellungen gelten sofort im Arbeitsspeicher und werden über die gebündelte Persistenz in `BRAIN_DATA_DIR/runtime-settings.json` geschrieben.
|
||||
|
||||
@@ -23,12 +23,22 @@ Mit **HONEYCOMB** wird die semantische Graphansicht durch eine gleichmäßig bes
|
||||
- Edges, Partikelpfade, Cortex-Flächen und LOD-Supernodes werden in dieser Ansicht nicht gerendert.
|
||||
- Wird eine Note durch Agent, Knowledgebase, Retrieval oder AI-THINK referenziert, leuchtet genau ihr Wabenpunkt auf.
|
||||
|
||||
Die Honeycomb-Ansicht verändert weder den Graphen noch die gespeicherten Node-Positionen. Sie ist eine reine Renderprojektion und kann jederzeit zurück auf **NEURAL** geschaltet werden.
|
||||
Die Honeycomb-Ansicht verändert weder den Graphen noch die gespeicherten Node-Positionen. Sie ist eine reine Renderprojektion und kann jederzeit zurück auf **NEURAL** geschaltet werden. Ihre Slotbelegung bleibt bei Graphupdates stabil; neue Notes belegen freie Plätze, statt die komplette Wabe neu zu sortieren.
|
||||
|
||||
## Constellation-Ansicht
|
||||
|
||||
Mit **CONSTELLATION** werden semantische Themenbereiche als ruhige Zentren mit umlaufenden Wissenssternen dargestellt. Aggregierte Verbindungen zwischen den Themen machen Wissensbrücken sichtbar, ohne jede Einzelkante zu rendern. Aktivierte Notes und Rechercheereignisse leuchten weiterhin auf.
|
||||
|
||||
## ECO-Modus
|
||||
|
||||
Der persistierbare Schalter **ECO** optimiert die Darstellung für schwächere Systeme, ohne die Kernanimationen zu entfernen. Er begrenzt die Ausgabe auf ungefähr 30 FPS, reduziert die Device-Pixel-Ratio sowie Budgets für inaktive Edges, Partikel, Wolken, Sterne und Quellenpunkte. Aktive Nodes, Rechercheanimationen, Fade-Übergänge und Themenzentren bleiben sichtbar.
|
||||
|
||||
Der ECO-Modus ist unabhängig vom GPU-Node-Limit: ECO reduziert die Kosten pro Frame, das Node-Limit reduziert die Anzahl aufgebauter Elemente.
|
||||
|
||||
|
||||
## GPU-Limit für schwächere Systeme
|
||||
|
||||
`max_display_nodes` begrenzt die Anzahl der Nodes, die im Browser für Neural und Honeycomb aufgebaut werden. `0` bedeutet unbegrenzt. Die Begrenzung wird nach dem Anzeige-Kategoriefilter angewendet. Das vollständige Wissen bleibt im Backend und im geladenen Graph-Snapshot erhalten.
|
||||
`max_display_nodes` begrenzt die Anzahl der Nodes, die im Browser für Neural, Honeycomb und Constellation aufgebaut werden. `0` bedeutet unbegrenzt. Die Begrenzung wird nach dem Anzeige-Kategoriefilter angewendet. Das vollständige Wissen bleibt im Backend und im geladenen Graph-Snapshot erhalten.
|
||||
|
||||
Die Auswahl ist stabil und bevorzugt aktive Notes, AI-THINK/Staging-Inhalte, Hubs und eine Grundabdeckung der vorhandenen Themenbereiche. Wird eine aktuell nicht dargestellte Note von Agent, Knowledgebase oder AI-THINK angefordert, ersetzt sie temporär einen inaktiven Node. Nach der Aktivitätsphase greift das Limit wieder auf die stabile Grundauswahl zurück.
|
||||
|
||||
@@ -52,7 +62,7 @@ Zulässig sind Werte von `0` bis `500000`. Die Einstellung reduziert die Render-
|
||||
|
||||
### Anzeige
|
||||
|
||||
`display_categories` begrenzt die im Browser gerenderten Notes. Direkt verbundene Kategorie-, Quellen- und Taxonomie-Nodes werden in der Neural-Ansicht mitgeführt. In Honeycomb werden ausschließlich passende Notes gerendert.
|
||||
`display_categories` begrenzt die im Browser gerenderten Notes. Direkt verbundene Kategorie-, Quellen- und Taxonomie-Nodes werden in der Neural-Ansicht mitgeführt. In Honeycomb und Constellation werden ausschließlich passende Notes gerendert.
|
||||
|
||||
Der vollständige Graph bleibt serverseitig erhalten. Der Filter ist keine Lösch- oder Zugriffsregel.
|
||||
|
||||
@@ -74,9 +84,10 @@ BRAIN_DISPLAY_CATEGORIES=
|
||||
BRAIN_THINKING_CATEGORIES=
|
||||
BRAIN_DEFAULT_VIEW=neural
|
||||
BRAIN_MAX_DISPLAY_NODES=0
|
||||
BRAIN_LOW_POWER_MODE=false
|
||||
```
|
||||
|
||||
Zulässige Werte für `BRAIN_DEFAULT_VIEW` sind `neural` und `honeycomb`.
|
||||
Zulässige Werte für `BRAIN_DEFAULT_VIEW` sind `neural`, `honeycomb` und `constellation`.
|
||||
|
||||
Nach der ersten Änderung im Web haben die in `runtime-settings.json` gespeicherten Laufzeitwerte Vorrang vor den Startwerten. Zum Zurücksetzen kann die Datei bei gestopptem Dienst entfernt werden.
|
||||
|
||||
@@ -99,8 +110,9 @@ curl -X PUT http://localhost:8090/api/runtime-settings \
|
||||
"learning_categories": [],
|
||||
"display_categories": ["GLPI"],
|
||||
"thinking_categories": ["GLPI", "Ollama"],
|
||||
"view_mode": "honeycomb",
|
||||
"max_display_nodes": 5000
|
||||
"view_mode": "constellation",
|
||||
"max_display_nodes": 5000,
|
||||
"low_power_mode": true
|
||||
}'
|
||||
```
|
||||
|
||||
|
||||
@@ -1,57 +1,81 @@
|
||||
33629e5d0420fa9011643291b5a71bc543cd318e4f5fd01c12ac5978710e3589 ./.env.example
|
||||
65faec43717b4df28bfb23d3a04211fbde4cfff165749dc40f37af3f3c774d4d ./ARCHITECTURE.md
|
||||
91f75b87bd95480fd40f191b551fe2d5f9f64e590e7c5442c19ee6166a362e6e ./CHANGELOG-GLPI-POOL-PERSISTENCE.md
|
||||
6a1332aec3461a9852258f428366903f9266369e474c27083a43d273c2ff1609 ./.env.example
|
||||
8955cfbeff229e73f0cad664863ff21711c270a4233c3225680c89aa6268a901 ./ARCHITECTURE.md
|
||||
2bc149241c2d25f755e4a0470dc517f646527ee3e98d3a6c2e7798639bd70866 ./CHANGELOG-CONSTELLATION-ECO-TRANSITIONS.md
|
||||
213ac897cd415bbeb9764a847843b9eff366983cf25bb3cbce4efa4c04b9e5f5 ./CHANGELOG-GLPI-POOL-PERSISTENCE.md
|
||||
e2f1f0400999cb59b8be09bc2743e06e0a0b2ecdc44a583af7c9a08b70d8509e ./CHANGELOG-GPU-NODE-LIMIT.md
|
||||
a317376127be1e47b9ec9f0781fcfebdcbf7fccfaeb7840d9241f9586048fadb ./CHANGELOG-GROUNDED-KNOWLEDGE-SYNTHESIS.md
|
||||
02a8d3e541967e2d2ef9dd5451f470679e262ad851aca9f03563b322914c3181 ./CHANGELOG-ITERATIVE-GROUNDED-RESEARCH.md
|
||||
e167a9d64f63c3933ad40c5078684bc019db303043c34ea3965f3b089f3d32c7 ./CHANGELOG-KNOWLEDGE-SYNTHESIS.md
|
||||
87f89a81e1124b18e092a4ea946cb037295cb9e884a46b392286272dc8134dd4 ./CHANGELOG-RUNTIME-HONEYCOMB.md
|
||||
2d04e6d385f4b902080a0bcaab510a846a8ae6a76cb757423c50425c8433e7f9 ./CHANGELOG-SEARXNG-DIAGNOSTICS.md
|
||||
9c760e167a9af2d3d8ca32c5aa4ef6bb4a3153047343a71c4b19ca9aef96ca32 ./CHANGELOG-SEARXNG-VISUALIZATION.md
|
||||
99171b262752a66278da5a4a8b2b48e83fbdb1eb9cdca3efa944d260d6e6bc01 ./Dockerfile
|
||||
5433a7c2e67ab35fb320bc872e9024fa5f3e765736184e9f878340b8b45407aa ./CHANGELOG-SQLITE-STARTUP-FIX.md
|
||||
5b9deeab0cd59b3c649fd73f129361a1e773ed3955cded0048b8cb280bb32e88 ./CHANGELOG-SQLITE-STORAGE.md
|
||||
42c1cacdc1f792773622017c3528dc626674456f478c41aaf44ff0a32e5f87bd ./Dockerfile
|
||||
5534536965bf0479455f97324c242160202650ca1256f1ba0420b4ad67125e49 ./GLPI-KB.md
|
||||
a090708c29db08973f712eb9ebf07dff2aae4e3e64f8954bbdaa83848b3ffcc0 ./KNOWLEDGE-SYNTHESIS.md
|
||||
adcd3c9ba3bdf366afcc4e15a25423e068dd761e5d5d2d6f8cb20a3686302045 ./Makefile
|
||||
c546524a3add0b1beb8d1ca675fd602e2ea7c7bddfc04759519c21a02667eb61 ./ITERATIVE-GROUNDED-RESEARCH.md
|
||||
e3ae87108607ca494668a9974c467a5c529b9599bf88d3d2a79ddc15b64e4a38 ./KNOWLEDGE-SYNTHESIS.md
|
||||
696d2da2338cd8190b9614707e4059d78ce291e7334f273633aad815c3b6a6df ./Makefile
|
||||
381d7d6ac9e3c2e63c9ecdaa42ed4c73058f5d78e57c7532bb75a9663c919530 ./OLLAMA-POOL.md
|
||||
10c14f4c08b9b84699cc4cf0dac3e6faf6c0ffd7e74b428463f14c628d0b533d ./PERSISTENCE.md
|
||||
b16c58d98f9da5d240ab5189993c5013aa57ac0da88029f40f3f3e572fdd8233 ./README.md
|
||||
73171929c19afc9c0f280a50bee1c6becfbfe1a1a4107540ff80d5e4f885ba9a ./RUNTIME-CONTROLS-HONEYCOMB.md
|
||||
c6fa5f19066c53fd184170bca78dceb8c3fbdfd0c5d6196e0ddbb37ac7bf8eb6 ./SEARXNG-VISUALIZATION.md
|
||||
cfc2393e8300b792cec30c57b9dc7670b19dcf5abb190dddaa75f32b77cb1fc7 ./cmd/brain/main.go
|
||||
2c0062941ef3edbd40d46b823934a7d0a3a9da7581b83d0b9360e8aaa7694b1b ./PERSISTENCE.md
|
||||
892649393e1b5b0e427feb20410652c4094b8903ec3a97015a4af286d39e8834 ./README.md
|
||||
dfa1c9fa47f53aa4fbe6eb8ee82f65c2a6213538af7b71a4842e40cdc271bab6 ./RUNTIME-CONTROLS-HONEYCOMB.md
|
||||
c3da43b33e550901d55789f2ee526c2e50f61ee028a3f59e0a40e77e1057fde7 ./SEARXNG-VISUALIZATION.md
|
||||
ae7bc1f1959071f79b76ca8a4ba103064ec0d5c5752af346175731ef4f636d9d ./SQLITE-STORAGE.md
|
||||
e05449bab6250e585a6c0ac0735008cd533baf07dbf7149ddae609ae252d4425 ./VALIDATION-CONSTELLATION-ECO-TRANSITIONS.md
|
||||
e7ab2cddec372db906c7883a6e0861b71999043cfb9b94e527c3b2aee4532035 ./VALIDATION-ITERATIVE-GROUNDED-RESEARCH.md
|
||||
e08b0eaab827fe03d5a72327e8fdfe9ce4025097e28208714246969e7d059561 ./VALIDATION-SEARXNG-DIAGNOSTICS.md
|
||||
4cd120496664388717fe422a8c54380708df723fea26b35f81799665dfaf2c1c ./VALIDATION-SQLITE.md
|
||||
f6699e4cdbaadc720e4b8a22c557d02319325283775a2b8a87ff78ca202e3386 ./VISUALIZATION-PERFORMANCE.md
|
||||
8970f2abf17bddcd0d84387e8a4975588df2776f03a7a54c5a283470769ca0c8 ./cmd/brain/main.go
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ./data/.gitkeep
|
||||
21b51d0e1b7ed07c20f7f3a5da76dedab8df44a94a51724b67b0c3411599fe15 ./deployment/README.md
|
||||
139d3dc6939848f8d8e827e5a483da7f7794a47dd3c858a964eaa7f811987985 ./deployment/docker-compose.full.yml
|
||||
5d97d77e2f0c302fb7fedfe8c7ff2c72a30f196590fdcab498ab0f4369de0071 ./docker-compose.yml
|
||||
9126f8bca1144abfc77747063b2c8f31acf12839a75e060b98369e10a00061ca ./go.mod
|
||||
e3403fd3a7ea9e467b09f7ced5ab63c8368fa4a75370ed62aa58b1cc7006177b ./deployment/docker-compose.full.yml
|
||||
ad6e2f4d47004232a09620eb83b59b582833a9901db3b2eae756febbb1abcc67 ./docker-compose.yml
|
||||
1542b064707bef0c4488f558f77c02db5f4cfc8d4da228f615ebdc3ee9ace8fd ./go.mod
|
||||
864c3376212497b070feca13d26cfc28e96876078ce7a0b5b0c0470e2dd4fbf8 ./go.sum
|
||||
bf239391e61040b00d2f49d805b0d49a44bd3679f3c53849dfbc5e3b5a3fcc7a ./integrations/agent/README.md
|
||||
a0105475dc054977223fac36618b8cd8137c55be1d11fddcd24e9a4d3074c170 ./integrations/agent/glpi-ai-agent-neural-brain.patch
|
||||
73ab7c49600cdaa4795e76c50e66ce919dec171b3a07f2d16ff6f45ce5f73365 ./integrations/knowledgebase/README.md
|
||||
36666043ebf4139e13610e5fcd0b0c6f45e4e6a53fed33ec47d03a66878e7b08 ./integrations/knowledgebase/glpi-ai-knowledgebase-neural-brain.patch
|
||||
50d05fa2a183f5f3eaab0545cb48d3abb64be62eb5d84dc2c6d99c7125f7344b ./internal/activity/broker.go
|
||||
45ca13d5dc65b5858359d1187147c8a892ae6ba8355e699c05d7e44212096c37 ./internal/config/config.go
|
||||
d5defa74dff6b09869f59c3e40ecc083f18bb9d81a0541956a857c4d0c26c360 ./internal/config/config_test.go
|
||||
fec14e27424873edae74b6a6f304612208e0f0d23d3cb598f0e680238b6ba7c1 ./internal/engine/article.go
|
||||
81386f1ce7d3d4d311367e8692429db6ced99173de9a623953aa38f1dd1725e3 ./internal/engine/engine.go
|
||||
6499fa71d3554845a7a12f6a16c38579f457ece368a6f3b152ccebae39362662 ./internal/engine/engine_test.go
|
||||
ccca255316e838042261da0329e44a4a36dd57fd44aa2a0ba5cccee6944f35a2 ./internal/config/config.go
|
||||
f7d8c7f9051fa27ceeb2b23f92af2883ae659ad1dfa681c2723d010a08e977b8 ./internal/config/config_test.go
|
||||
b81e53fc1e80a2d4c677e7145097473e772a7d963ffaddc7fa1eae2b2c95ebda ./internal/engine/article.go
|
||||
d5d18a26010fe5f308c05b79e3a3d7501c8490bb33098357cde4373affd7e60d ./internal/engine/article_format_test.go
|
||||
688c71c14f1112673bac63627738cfbd713272aae748db15204e9de04bf8d10b ./internal/engine/article_research.go
|
||||
1e0fc5d81f2238927842d854eb062cef08e5c39b9970f68d4a181cba67d56d47 ./internal/engine/article_research_cache.go
|
||||
3ca7037231935329d49b6b80553fbfef206c079a6aed4c2379dadd46d39ebc0d ./internal/engine/article_research_cache_test.go
|
||||
289d7dca4f0294072521daa229ff2dcae7f159af4631d6567853f54b920506ce ./internal/engine/article_research_test.go
|
||||
fc9f71e4bb8d400ec78bdc6e81d29722ffff17ddd9026ff97889ca7f306be92a ./internal/engine/engine.go
|
||||
d2c5f2b64704656a4afe856b60872a29c1d491b16289144a5052b23c2900d08c ./internal/engine/engine_test.go
|
||||
e3595489273b2e5f6b8686d7912e1d56c968fb8d105eea58973c25496e1cf412 ./internal/engine/research_diagnostics.go
|
||||
0eb3f00e2ab73d2dc6a4cbc1a4038533a4bb20fbbbb6190abd39feff6b34b8e1 ./internal/engine/research_diagnostics_test.go
|
||||
716d42138db9eb64480c1bbaf4cb3b70bce1edf72c17c3d85a8d84f866fd8700 ./internal/engine/research_events.go
|
||||
872b9a5d6cc0e610a50f64ae8d66ed53bf07da718da22f91c11cf43a487fb425 ./internal/engine/runtime.go
|
||||
7eb1c0cec5e4135d8e4988093f093d4ada7d1047db7b30243a7b5122c2af2a0f ./internal/engine/runtime.go
|
||||
b82980a646a92751bdd27a866ba1ffc6d34a3ba81d537f7b6e5a78e1432ee6fa ./internal/glpi/client.go
|
||||
525102be56bc51ce8a08655b1b2bb53b67f4a1828903585fd664ed6a5133f617 ./internal/glpi/client_test.go
|
||||
4caa47f2d337086c09fa612a5b5b1855f17d57d736531b8badd7223f0345ba6d ./internal/graph/store.go
|
||||
13c38603f7ad1dcc590117d06c0663ace3e7a5971b96b2a96e8a53d9bcae87ff ./internal/graph/store_test.go
|
||||
6b3df883bb30e4d969a5aa7e4cb74ca98119ec1155f6b566555d06c270842c93 ./internal/graph/sqlite_backend.go
|
||||
744d306b9c7151543e91421575775ff6eb1b7e0af187ba7d92d8a298c51704de ./internal/graph/sqlite_backend_test.go
|
||||
1eff087ab94d6b94b5ae2205df0f1fcfcc3a35965808a3f504d2f96cb45459fe ./internal/graph/store.go
|
||||
11daaf15e175818ddd62d70ac415d3493d6a473a2dbb1b65a59be33a249242d3 ./internal/graph/store_test.go
|
||||
4476351d388d11c6becd78b4c918fc8d47dfd70500d8b3e2ddf81f7ff61a2cea ./internal/ingest/agent.go
|
||||
05bdcd8f82756af028807a9ba37e64232e2d93b6a803468d0a29665bbdb3067f ./internal/ingest/glpikb.go
|
||||
ff44d56d56b9e301fbcf0f028d1bae6f0b851665f4fee65222097f1a2450f24a ./internal/ingest/glpikb_test.go
|
||||
257a4beba480dab7d9b79c1f32496f6b4f648c4c05170f51a77220dbfd21fe96 ./internal/ingest/knowledge.go
|
||||
a13910fb417484d56e78ae856b71fb66c63987d9abf3b513190bc52697321a18 ./internal/ingest/knowledge_test.go
|
||||
835f6913829df7d55560d62dfe39dc01d0448dba63dae808249e32bd130b51d7 ./internal/model/model.go
|
||||
8be0d79e9c35ba2f8ccd8725ae1f9bd921009225be69bd74dd5372128b7bcb0f ./internal/model/model.go
|
||||
db7a99b832bc41c61584cd726d5fc7f4f250197d716d58bc27e715923f7f5426 ./internal/ollama/client.go
|
||||
61089700aa5912b58bff526b71c2a1bda74077b802f9ff69a0d7dc89c1e3e3a1 ./internal/ollama/client_test.go
|
||||
e61a9a426b96851b409ac357bdc53853324b5c5da7568ff6f89fe9cc09f83a73 ./internal/persist/coordinator.go
|
||||
d33318b43388f134358cf40f5b0f130eb10edcca06011955ea0544897b4e4ad1 ./internal/persist/coordinator_test.go
|
||||
2eb686cfc9016b9b0cf15e5c342f693ec9b60c454bc4814c1c9583f6d5b5b806 ./internal/research/searxng.go
|
||||
6346f7b213aa3fb36bc9f43134bba75e0b368c9a005cc1aef8d265f553ff8cef ./internal/research/searxng_test.go
|
||||
1c44338935a4faeedd9671c23df235aa99ea55ed6b2e72060a5d5ddc6c7a6464 ./internal/web/server.go
|
||||
4d89321b95eb2af3f594adb4d8230aa85377bebe707d232a6af7f1a1f99523dd ./internal/web/server_test.go
|
||||
d6463cc4c15e023eff8488e9541aa2516386ca3d04993868206e7e0885fb2eb0 ./internal/web/static/app.css
|
||||
d860d640c34d2f65c9f3d387a85988e24446e8464ad701326beae3a5a17e3be5 ./internal/web/static/app.js
|
||||
7e99be904fea61b19bfd5560c93eec5dc5eee75252d1410ca1661cc4a87181dd ./internal/web/static/index.html
|
||||
0fe63bd83de071d285fe3576f0ac8093a92bc1e61681649a7330680cd0660197 ./neural-brain
|
||||
0bc8bb4c698c2c5dbef5c980d3e3fb88f10d35a8d7a230cbc81d218798bc1fe6 ./internal/persist/coordinator.go
|
||||
46144aa719ff5c3ab787c214d8e32e4b3c6883bed068410e5403a26f6352cd6a ./internal/persist/coordinator_test.go
|
||||
e7138877303bcc07c429323c4792fed112d8c16d35fd44222fe144ab0b69344f ./internal/research/fetch.go
|
||||
6a9f269783a7c41d5b63f9bd5022f415ed1b5572041ca5ccae1512d6dc2a0b80 ./internal/research/fetch_test.go
|
||||
a46b953c22fb2aef112b11ba65c61bda1e1582903e39489c2d081d17519ebd9d ./internal/research/searxng.go
|
||||
2f82e80ad91590f419b1bbb19647b5191596e97c4d765e8736c1867ad899d457 ./internal/research/searxng_test.go
|
||||
4e55706a88d1a8c9f58678a9087add98618654fd2697f990f0f6fade187a9576 ./internal/web/server.go
|
||||
cd371ec2ffc178b986e7b7cb840f9d764e3d05e7f2547b1193acc8d3c8a82276 ./internal/web/server_test.go
|
||||
4a0e7f3170b0a5cc682cc3e2a4337601f7e29e603b61127e5a61c674ba52bf34 ./internal/web/static/app.css
|
||||
266a7243d034e92e5956b288e3d2b8fefb69bddb7ce52024971cf98486242b9c ./internal/web/static/app.js
|
||||
bab60b900385858773148b939988dfd2e45ed34f8041f8cb689281e63669aefd ./internal/web/static/index.html
|
||||
83aded814b6225395935e61fe957963c3c470f368fc9089f505b6de23e959115 ./preview.png
|
||||
|
||||
82
VALIDATION-CONSTELLATION-ECO-TRANSITIONS.md
Normal file
82
VALIDATION-CONSTELLATION-ECO-TRANSITIONS.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Validierung: Constellation, ECO, Übergänge und Evidence-Pfad
|
||||
|
||||
## Statische Prüfungen
|
||||
|
||||
Erfolgreich ausgeführt:
|
||||
|
||||
```text
|
||||
node --check internal/web/static/app.js
|
||||
YAML-Parsing von docker-compose.yml
|
||||
YAML-Parsing von deployment/docker-compose.full.yml
|
||||
statische Prüfung aller neuen HTML-Control-IDs
|
||||
```
|
||||
|
||||
## Go-Prüfung
|
||||
|
||||
Die vollständige Codebasis wurde mit einem reinen Compile-Stub für den importierten Treiber `modernc.org/sqlite` typgeprüft:
|
||||
|
||||
```text
|
||||
go test -run '^$' ./...
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
Gezielt ausgeführt wurden außerdem:
|
||||
|
||||
```text
|
||||
TestLoadRuntimeControlDefaultsAndFilters
|
||||
TestMetadataStringTreatsMissingAndNilAsEmpty
|
||||
```
|
||||
|
||||
Damit sind die neuen Config-/Runtime-Felder sowie die Behandlung fehlender Evidence-Pfade abgedeckt.
|
||||
|
||||
Die Ausführungsumgebung konnte `modernc.org/sqlite v1.37.1` nicht von `proxy.golang.org` laden. Deshalb wurden SQLite-Laufzeittests hier nicht erneut ausgeführt. `go.mod` und `go.sum` im Projekt bleiben unverändert und verwenden weiterhin den echten Treiber.
|
||||
|
||||
## Browser-Smoke-Test
|
||||
|
||||
Die echte `index.html`, `app.css` und `app.js` wurden in Chromium über das DevTools-Protokoll mit simulierten API- und SSE-Antworten ausgeführt.
|
||||
|
||||
Geprüft:
|
||||
|
||||
- Initialisierung der Neural-Ansicht;
|
||||
- Wechsel zu Constellation;
|
||||
- Ghost-Fade während des Ansichtswechsels und automatisches Aufräumen danach;
|
||||
- Aktivierung des ECO-Modus einschließlich DPR-/Frameprofilwechsel;
|
||||
- Entfernung eines sichtbaren Nodes mit Fade-out;
|
||||
- Einfügen eines neuen Nodes mit Fade-in;
|
||||
- Identität und Position eines unveränderten Nodes bleiben erhalten;
|
||||
- keine JavaScript-Runtime-Exceptions, Console-Errors oder Log-Errors.
|
||||
|
||||
## Synthetischer Lasttest
|
||||
|
||||
Ein zusätzlicher Headless-Chromium-Test verwendete:
|
||||
|
||||
```text
|
||||
5.000 Nodes
|
||||
10.000 Edges
|
||||
20 semantische Cluster
|
||||
```
|
||||
|
||||
Dabei wurden folgende Eigenschaften bestätigt:
|
||||
|
||||
- ein identischer Snapshot wird ohne Layout- oder Render-Neuaufbau verworfen;
|
||||
- eine reine Edge-Erweiterung führt nicht zu einer vollständigen Node-Neuplatzierung;
|
||||
- Neural verwendet die bestehende LOD-Verdichtung;
|
||||
- Constellation kann sämtliche gefilterten Nodes darstellen;
|
||||
- ECO aktiviert feste Effektbudgets, geringere DPR, gebatchte ruhige Sterne und gedrosselte Tiefensortierung;
|
||||
- keine Browser-Runtimefehler.
|
||||
|
||||
Die FPS eines Headless-Browsers mit Software-Canvas sind kein belastbarer GPU-Benchmark und werden daher nicht als Produktversprechen verwendet.
|
||||
|
||||
## Research-Evidence-Regression
|
||||
|
||||
`metadataString` behandelt nun alle folgenden Zustände als fehlenden Pfad:
|
||||
|
||||
```text
|
||||
nicht vorhandener Schlüssel
|
||||
nil
|
||||
"<nil>"
|
||||
"null"
|
||||
leere Zeichenfolge
|
||||
```
|
||||
|
||||
Ein valider relativer Pfad wird weiterhin getrimmt und unverändert zurückgegeben. Dadurch versucht die Engine nicht mehr, `BRAIN_DATA_DIR/<nil>` zu öffnen.
|
||||
102
VISUALIZATION-PERFORMANCE.md
Normal file
102
VISUALIZATION-PERFORMANCE.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Visualisierungen, weiche Übergänge und ECO-Modus
|
||||
|
||||
## Ansichten
|
||||
|
||||
### Neural
|
||||
|
||||
Die Neural-Ansicht bleibt die detailreichste Darstellung. Sie zeigt Cortex-Regionen, hierarchisches Level-of-Detail, Synapsen, Aktivitätspartikel, Recherchepfade und semantische Verdichtungen.
|
||||
|
||||
### Honeycomb
|
||||
|
||||
Honeycomb verteilt Notes auf einem stabilen, gleichmäßig beabstandeten 3D-Gitter in Gehirnform. Die Zuordnung eines Nodes zu einem Gitterplatz bleibt über Graphupdates hinweg erhalten. Neue Nodes belegen freie Plätze, statt die komplette Wabe neu anzuordnen.
|
||||
|
||||
### Constellation
|
||||
|
||||
Constellation ist die dritte Ansicht für große und stark verknüpfte Wissensbasen. Semantische Themen bilden ruhige Zentren; ihre Notes liegen als Sterne in stabilen Umlaufbereichen. Aggregierte Verbindungen zwischen Themen zeigen Übergänge, ohne sämtliche Einzelkanten zu zeichnen.
|
||||
|
||||
Die Ansicht eignet sich besonders für:
|
||||
|
||||
- Überblick über Wissensdomänen und deren Größen;
|
||||
- Erkennen von thematischen Inseln und Brücken;
|
||||
- Beobachten von Learning-, Thinking- und Research-Aktivität;
|
||||
- große Graphen, bei denen Einzelkanten in Neural zu dicht werden.
|
||||
|
||||
## ECO-Modus
|
||||
|
||||
Der Schalter **ECO** ist sowohl in der unteren Steuerleiste als auch unter **FILTER → Performance** verfügbar. Die Einstellung wird in `runtime-settings.json` gespeichert.
|
||||
|
||||
```env
|
||||
BRAIN_LOW_POWER_MODE=false
|
||||
```
|
||||
|
||||
Im ECO-Modus bleiben die charakteristischen Animationen erhalten, ihre Kosten werden jedoch begrenzt:
|
||||
|
||||
- Zielintervall ungefähr 30 FPS;
|
||||
- maximale Device-Pixel-Ratio 1,15 statt 2;
|
||||
- weniger inaktive Synapsen, Partikel, Cortex-Wolken und Hintergrundsterne;
|
||||
- günstigere Halos und Recherchepakete ohne viele radiale Gradienten;
|
||||
- selteneres Tiefensortieren;
|
||||
- kleinere Übergangspuffer;
|
||||
- weniger gleichzeitig dargestellte Constellation-Verbindungen.
|
||||
|
||||
Der Modus ändert keine Graphdaten und entfernt keine Wissens-Nodes. Für eine harte Obergrenze sichtbarer Nodes bleibt `BRAIN_MAX_DISPLAY_NODES` zuständig.
|
||||
|
||||
## Update- und Übergangsmodell
|
||||
|
||||
Graphpolling und SSE-Events führen nicht mehr automatisch zu einem vollständigen visuellen Neuaufbau.
|
||||
|
||||
- Identische Graphversion und identische Anzeigefilter werden ignoriert.
|
||||
- Parallele Reload-Anforderungen werden zusammengeführt und leicht entprellt.
|
||||
- Vorhandene Node-Objekte und ihre Koordinaten bleiben erhalten.
|
||||
- Reine Kantenänderungen aktualisieren Links, ohne sämtliche Nodes neu zu platzieren.
|
||||
- Honeycomb-Slots sind stabil und werden wiederverwendet.
|
||||
- Neue Nodes erhalten einen Fade-in-Status.
|
||||
- Entfernte Nodes und Edges bleiben für die Fade-out-Dauer in einem begrenzten Übergangspuffer.
|
||||
- Beim Wechsel zwischen Neural, Honeycomb und Constellation werden alte Bildschirmpositionen kurz als Ghosts gehalten und Nodes zwischen den 3D-Koordinaten gemorpht.
|
||||
|
||||
Standardzeiten:
|
||||
|
||||
```text
|
||||
Node Fade-in: 720 ms
|
||||
Node/Edge Fade-out: 680 ms
|
||||
Positionsmorphing: 620 ms
|
||||
Ansichtswechsel: 760 ms
|
||||
```
|
||||
|
||||
Die SearXNG-Animation besitzt weiterhin ihren eigenen Lebenszyklus und wird durch Graphupdates oder Ansichtswechsel nicht abgebrochen.
|
||||
|
||||
## Renderoptimierungen
|
||||
|
||||
Zusätzlich wurden folgende Hotpaths reduziert:
|
||||
|
||||
- Kameratrigonometrie und Perspektivparameter werden einmal pro Frame berechnet;
|
||||
- der statische Hintergrund wird in einem Offscreen-Canvas gecacht;
|
||||
- inaktive Edges werden deterministisch bis zum Profil-Limit abgetastet;
|
||||
- aktive Edges werden unabhängig vom Limit weiterhin gezeichnet;
|
||||
- vorhandene Cluster und Node-Positionen werden wiederverwendet;
|
||||
- bei unveränderten Clustern läuft nur eine kurze Relaxation;
|
||||
- Tiefensortierung wird im ECO-Modus gedrosselt;
|
||||
- Partikel- und Übergangspuffer besitzen feste Obergrenzen.
|
||||
|
||||
## Runtime-API
|
||||
|
||||
Beispiel:
|
||||
|
||||
```json
|
||||
{
|
||||
"view_mode": "constellation",
|
||||
"low_power_mode": true
|
||||
}
|
||||
```
|
||||
|
||||
Unterstützte Ansichten:
|
||||
|
||||
```text
|
||||
neural
|
||||
honeycomb
|
||||
constellation
|
||||
```
|
||||
|
||||
## Hinweis zur Research-Evidence-Korrektur
|
||||
|
||||
Ältere externe Nodes können in SQLite ein fehlendes `evidence_path` als `null` beziehungsweise als Zeichenfolge `<nil>` enthalten. Diese Werte werden nun als nicht vorhandener Pfad behandelt und übersprungen. Dadurch wird nicht mehr versucht, unter Windows eine Datei wie `data\\<nil>` zu öffnen, und die wiederholten Warnmeldungen entfallen. Gültige Evidenzpfade werden unverändert weiterverwendet.
|
||||
@@ -137,6 +137,7 @@ services:
|
||||
BRAIN_THINKING_CATEGORIES: ${BRAIN_THINKING_CATEGORIES:-}
|
||||
BRAIN_DEFAULT_VIEW: ${BRAIN_DEFAULT_VIEW:-neural}
|
||||
BRAIN_MAX_DISPLAY_NODES: ${BRAIN_MAX_DISPLAY_NODES:-0}
|
||||
BRAIN_LOW_POWER_MODE: ${BRAIN_LOW_POWER_MODE:-false}
|
||||
BRAIN_ENRICH_INTERVAL: ${BRAIN_ENRICH_INTERVAL:-90s}
|
||||
BRAIN_ENRICH_BATCH_SIZE: ${BRAIN_ENRICH_BATCH_SIZE:-3}
|
||||
BRAIN_ENRICH_STEP_DELAY: ${BRAIN_ENRICH_STEP_DELAY:-3s}
|
||||
|
||||
@@ -36,6 +36,7 @@ services:
|
||||
BRAIN_THINKING_CATEGORIES: ${BRAIN_THINKING_CATEGORIES:-}
|
||||
BRAIN_DEFAULT_VIEW: ${BRAIN_DEFAULT_VIEW:-neural}
|
||||
BRAIN_MAX_DISPLAY_NODES: ${BRAIN_MAX_DISPLAY_NODES:-0}
|
||||
BRAIN_LOW_POWER_MODE: ${BRAIN_LOW_POWER_MODE:-false}
|
||||
BRAIN_ENRICH_INTERVAL: ${BRAIN_ENRICH_INTERVAL:-90s}
|
||||
BRAIN_ENRICH_BATCH_SIZE: ${BRAIN_ENRICH_BATCH_SIZE:-3}
|
||||
BRAIN_ENRICH_STEP_DELAY: ${BRAIN_ENRICH_STEP_DELAY:-3s}
|
||||
|
||||
@@ -70,6 +70,7 @@ type Config struct {
|
||||
ThinkingCategories []string
|
||||
DefaultView string
|
||||
MaxDisplayNodes int
|
||||
LowPowerMode bool
|
||||
RuntimeDefaultsConfigured bool
|
||||
|
||||
GLPIKBEnabled bool
|
||||
@@ -162,6 +163,7 @@ func Load() (Config, error) {
|
||||
ThinkingCategories: stringList("BRAIN_THINKING_CATEGORIES"),
|
||||
DefaultView: strings.ToLower(env("BRAIN_DEFAULT_VIEW", "neural")),
|
||||
MaxDisplayNodes: integer("BRAIN_MAX_DISPLAY_NODES", 0),
|
||||
LowPowerMode: boolean("BRAIN_LOW_POWER_MODE", false),
|
||||
RuntimeDefaultsConfigured: true,
|
||||
GLPIKBEnabled: boolean("GLPI_KB_ENABLED", false),
|
||||
GLPIURL: strings.TrimRight(strings.TrimSpace(os.Getenv("GLPI_URL")), "/"),
|
||||
@@ -253,8 +255,8 @@ func Load() (Config, error) {
|
||||
if cfg.ResearchEnabled && cfg.SearXNGURL == "" {
|
||||
return Config{}, fmt.Errorf("BRAIN_RESEARCH_ENABLED requires SEARXNG_URL")
|
||||
}
|
||||
if cfg.DefaultView != "neural" && cfg.DefaultView != "honeycomb" {
|
||||
return Config{}, fmt.Errorf("BRAIN_DEFAULT_VIEW must be neural or honeycomb")
|
||||
if cfg.DefaultView != "neural" && cfg.DefaultView != "honeycomb" && cfg.DefaultView != "constellation" {
|
||||
return Config{}, fmt.Errorf("BRAIN_DEFAULT_VIEW must be neural, honeycomb or constellation")
|
||||
}
|
||||
if cfg.MaxDisplayNodes < 0 || cfg.MaxDisplayNodes > 500000 {
|
||||
return Config{}, fmt.Errorf("BRAIN_MAX_DISPLAY_NODES must be between 0 and 500000")
|
||||
|
||||
@@ -45,13 +45,14 @@ func TestLoadRuntimeControlDefaultsAndFilters(t *testing.T) {
|
||||
t.Setenv("BRAIN_LEARNING_CATEGORIES", "Netzwerk,GLPI KB")
|
||||
t.Setenv("BRAIN_DISPLAY_CATEGORIES", "GLPI KB")
|
||||
t.Setenv("BRAIN_THINKING_CATEGORIES", "Netzwerk")
|
||||
t.Setenv("BRAIN_DEFAULT_VIEW", "honeycomb")
|
||||
t.Setenv("BRAIN_DEFAULT_VIEW", "constellation")
|
||||
t.Setenv("BRAIN_MAX_DISPLAY_NODES", "12000")
|
||||
t.Setenv("BRAIN_LOW_POWER_MODE", "true")
|
||||
cfg, err := Load()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.LearningEnabled || cfg.ThinkingEnabled || cfg.DefaultView != "honeycomb" || cfg.MaxDisplayNodes != 12000 {
|
||||
if cfg.LearningEnabled || cfg.ThinkingEnabled || cfg.DefaultView != "constellation" || cfg.MaxDisplayNodes != 12000 || !cfg.LowPowerMode {
|
||||
t.Fatalf("unexpected runtime defaults: %+v", cfg)
|
||||
}
|
||||
if len(cfg.LearningCategories) != 2 || len(cfg.DisplayCategories) != 1 || len(cfg.ThinkingCategories) != 1 {
|
||||
|
||||
@@ -1457,7 +1457,15 @@ func metadataString(metadata map[string]any, key string) string {
|
||||
if metadata == nil {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(fmt.Sprint(metadata[key]))
|
||||
value, ok := metadata[key]
|
||||
if !ok || value == nil {
|
||||
return ""
|
||||
}
|
||||
text := strings.TrimSpace(fmt.Sprint(value))
|
||||
if text == "" || strings.EqualFold(text, "<nil>") || strings.EqualFold(text, "null") {
|
||||
return ""
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
func metadataStringSlice(metadata map[string]any, key string) []string {
|
||||
|
||||
@@ -89,3 +89,21 @@ func TestLoadResearchEvidenceCanReuseInMemoryQueuedRecord(t *testing.T) {
|
||||
t.Fatalf("unexpected cached evidence: %+v", loaded)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadataStringTreatsMissingAndNilAsEmpty(t *testing.T) {
|
||||
cases := []map[string]any{
|
||||
nil,
|
||||
{},
|
||||
{"evidence_path": nil},
|
||||
{"evidence_path": "<nil>"},
|
||||
{"evidence_path": "null"},
|
||||
}
|
||||
for _, metadata := range cases {
|
||||
if got := metadataString(metadata, "evidence_path"); got != "" {
|
||||
t.Fatalf("expected empty metadata string, got %q from %#v", got, metadata)
|
||||
}
|
||||
}
|
||||
if got := metadataString(map[string]any{"evidence_path": " research-evidence/x.json "}, "evidence_path"); got != "research-evidence/x.json" {
|
||||
t.Fatalf("unexpected normalized metadata string %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,13 +392,14 @@ func TestRuntimeSettingsDisableThinkingAndPersist(t *testing.T) {
|
||||
LearningCategories: []string{"Netzwerk"},
|
||||
DisplayCategories: []string{"GLPI KB"},
|
||||
ThinkingCategories: []string{"Netzwerk"},
|
||||
ViewMode: "honeycomb",
|
||||
ViewMode: "constellation",
|
||||
MaxDisplayNodes: 4321,
|
||||
LowPowerMode: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if updated.LearningEnabled || updated.ThinkingEnabled || updated.ViewMode != "honeycomb" || updated.MaxDisplayNodes != 4321 {
|
||||
if updated.LearningEnabled || updated.ThinkingEnabled || updated.ViewMode != "constellation" || updated.MaxDisplayNodes != 4321 || !updated.LowPowerMode {
|
||||
t.Fatalf("unexpected runtime settings: %+v", updated)
|
||||
}
|
||||
if e.RequestEnrich("manual") {
|
||||
@@ -417,7 +418,7 @@ func TestRuntimeSettingsDisableThinkingAndPersist(t *testing.T) {
|
||||
}
|
||||
e2 := New(cfg, g2, activity.New(20))
|
||||
loaded := e2.RuntimeSettings()
|
||||
if loaded.LearningEnabled || loaded.ThinkingEnabled || loaded.ViewMode != "honeycomb" || loaded.MaxDisplayNodes != 4321 || len(loaded.DisplayCategories) != 1 {
|
||||
if loaded.LearningEnabled || loaded.ThinkingEnabled || loaded.ViewMode != "constellation" || loaded.MaxDisplayNodes != 4321 || !loaded.LowPowerMode || len(loaded.DisplayCategories) != 1 {
|
||||
t.Fatalf("runtime settings were not restored: %+v", loaded)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ type RuntimeSettings struct {
|
||||
ThinkingCategories []string `json:"thinking_categories"`
|
||||
ViewMode string `json:"view_mode"`
|
||||
MaxDisplayNodes int `json:"max_display_nodes"`
|
||||
LowPowerMode bool `json:"low_power_mode"`
|
||||
}
|
||||
|
||||
type CategoryInfo struct {
|
||||
@@ -36,6 +37,7 @@ func (e *Engine) defaultRuntimeSettings() RuntimeSettings {
|
||||
ThinkingCategories: append([]string(nil), e.Cfg.ThinkingCategories...),
|
||||
ViewMode: e.Cfg.DefaultView,
|
||||
MaxDisplayNodes: e.Cfg.MaxDisplayNodes,
|
||||
LowPowerMode: e.Cfg.LowPowerMode,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -47,7 +49,7 @@ func normalizeRuntimeSettings(in RuntimeSettings) RuntimeSettings {
|
||||
if in.ViewMode == "" {
|
||||
in.ViewMode = "neural"
|
||||
}
|
||||
if in.ViewMode != "neural" && in.ViewMode != "honeycomb" {
|
||||
if in.ViewMode != "neural" && in.ViewMode != "honeycomb" && in.ViewMode != "constellation" {
|
||||
in.ViewMode = "neural"
|
||||
}
|
||||
if in.MaxDisplayNodes < 0 {
|
||||
@@ -149,6 +151,7 @@ func (e *Engine) SetRuntimeSettings(settings RuntimeSettings) (RuntimeSettings,
|
||||
"thinking_categories": len(settings.ThinkingCategories),
|
||||
"view_mode": settings.ViewMode,
|
||||
"max_display_nodes": settings.MaxDisplayNodes,
|
||||
"low_power_mode": settings.LowPowerMode,
|
||||
},
|
||||
})
|
||||
return settings, nil
|
||||
|
||||
@@ -37,7 +37,7 @@ func TestRuntimeSettingsAndCategoriesAPI(t *testing.T) {
|
||||
}, g, broker)
|
||||
h := (&Server{Engine: eng, Graph: g, Broker: broker}).Handler()
|
||||
|
||||
body := `{"learning_enabled":false,"thinking_enabled":false,"learning_categories":["GLPI"],"display_categories":["Ollama"],"thinking_categories":["GLPI"],"view_mode":"honeycomb","max_display_nodes":1500}`
|
||||
body := `{"learning_enabled":false,"thinking_enabled":false,"learning_categories":["GLPI"],"display_categories":["Ollama"],"thinking_categories":["GLPI"],"view_mode":"constellation","max_display_nodes":1500,"low_power_mode":true}`
|
||||
req := httptest.NewRequest(http.MethodPut, "/api/runtime-settings", strings.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
res := httptest.NewRecorder()
|
||||
@@ -49,7 +49,7 @@ func TestRuntimeSettingsAndCategoriesAPI(t *testing.T) {
|
||||
if err := json.NewDecoder(res.Body).Decode(&settings); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if settings.LearningEnabled || settings.ThinkingEnabled || settings.ViewMode != "honeycomb" || settings.MaxDisplayNodes != 1500 {
|
||||
if settings.LearningEnabled || settings.ThinkingEnabled || settings.ViewMode != "constellation" || settings.MaxDisplayNodes != 1500 || !settings.LowPowerMode {
|
||||
t.Fatalf("unexpected settings: %+v", settings)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ body.honeycomb-view .legend{opacity:.58}body.honeycomb-view .mode-status small:a
|
||||
.settings-header{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--line);padding:2px 2px 13px}.settings-header strong{display:block;font-size:12px;letter-spacing:.17em}.settings-header small{display:block;margin-top:4px;color:var(--muted);font-size:10px}.settings-header button{border:0;background:transparent;color:var(--muted);font-size:24px;cursor:pointer;padding:0 5px}
|
||||
.settings-section{padding:14px 2px;border-bottom:1px solid var(--line)}.settings-section h2{font-size:10px;letter-spacing:.17em;text-transform:uppercase;color:#9eb5c6;margin:0 0 10px}.settings-section-title{display:flex;justify-content:space-between;align-items:center}.settings-section-title span{font-size:9px;color:#668094}
|
||||
.switch-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:9px 10px;margin:7px 0;border:1px solid rgba(133,200,255,.1);border-radius:12px;background:rgba(255,255,255,.022);cursor:pointer}.switch-row b{display:block;font-size:11px}.switch-row small{display:block;margin-top:3px;color:#718b9e;font-size:9px;line-height:1.35}.switch-row input{appearance:none;width:38px;height:21px;border-radius:999px;background:rgba(119,146,168,.25);position:relative;cursor:pointer;flex:0 0 auto;outline:1px solid rgba(255,255,255,.06)}.switch-row input:after{content:"";position:absolute;width:15px;height:15px;left:3px;top:3px;border-radius:50%;background:#8196a7;transition:transform .2s,background .2s,box-shadow .2s}.switch-row input:checked{background:rgba(82,231,255,.19)}.switch-row input:checked:after{transform:translateX(17px);background:var(--cyan);box-shadow:0 0 10px rgba(82,231,255,.7)}
|
||||
.view-selector{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-top:10px}.view-selector button{border:1px solid rgba(133,200,255,.12);background:rgba(255,255,255,.025);color:#738da1;border-radius:10px;padding:9px;font-size:10px;font-weight:700;letter-spacing:.1em;cursor:pointer}.view-selector button.active{color:var(--green);border-color:rgba(93,255,189,.24);background:rgba(93,255,189,.07)}
|
||||
.view-selector{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:10px}.view-selector button{border:1px solid rgba(133,200,255,.12);background:rgba(255,255,255,.025);color:#738da1;border-radius:10px;padding:9px;font-size:10px;font-weight:700;letter-spacing:.1em;cursor:pointer}.view-selector button.active{color:var(--green);border-color:rgba(93,255,189,.24);background:rgba(93,255,189,.07)}
|
||||
.category-settings{flex:1;min-height:0;overflow:auto;padding-right:5px}.filter-search{display:block;margin-bottom:12px}.filter-search span{display:block;font-size:9px;color:#6d879a;margin-bottom:5px}.filter-search input{width:100%;border:1px solid rgba(133,200,255,.14);background:rgba(2,8,17,.6);color:var(--text);border-radius:10px;padding:9px 10px;outline:0}.filter-search input:focus{border-color:rgba(82,231,255,.38);box-shadow:0 0 0 3px rgba(82,231,255,.06)}
|
||||
.filter-block{margin:12px 0 16px}.filter-heading{display:flex;align-items:center;justify-content:space-between;margin-bottom:7px}.filter-heading b{display:block;font-size:10px;color:#c8d9e4}.filter-heading small{display:block;margin-top:2px;color:#607b90;font-size:9px}.filter-heading button{border:1px solid rgba(82,231,255,.13);background:rgba(82,231,255,.04);color:#87a8bc;border-radius:8px;padding:5px 8px;font-size:8px;letter-spacing:.08em;cursor:pointer}.category-list{display:flex;flex-wrap:wrap;gap:5px;max-height:128px;overflow:auto;padding:1px}.category-option{position:relative}.category-option input{position:absolute;opacity:0;pointer-events:none}.category-option span{display:block;border:1px solid rgba(133,200,255,.12);background:rgba(255,255,255,.022);color:#7893a6;border-radius:999px;padding:5px 8px;font-size:9px;cursor:pointer;white-space:nowrap}.category-option input:checked+span{color:#dffaff;border-color:rgba(82,231,255,.32);background:rgba(82,231,255,.11);box-shadow:0 0 12px rgba(82,231,255,.05)}.category-option em{font-style:normal;opacity:.58;margin-left:4px}
|
||||
.settings-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:13px}.settings-footer span{font-size:9px;color:#7f9aac;line-height:1.35}.settings-footer button{border:1px solid rgba(82,231,255,.3);background:rgba(82,231,255,.1);color:var(--cyan);border-radius:11px;padding:10px 13px;font-size:9px;font-weight:800;letter-spacing:.13em;cursor:pointer}.settings-footer button:disabled{opacity:.5;cursor:wait}
|
||||
@@ -51,3 +51,17 @@ body.honeycomb-view .legend{opacity:.58}body.honeycomb-view .mode-status small:a
|
||||
.activity-item .sources span{display:flex;align-items:flex-start;gap:6px;color:#b7d9ca;font-size:9px;line-height:1.35}
|
||||
.activity-item .sources i{display:inline-flex;align-items:center;justify-content:center;flex:0 0 15px;height:15px;border-radius:50%;border:1px solid rgba(93,255,189,.24);background:rgba(93,255,189,.07);color:#86ffd0;font-style:normal;font-size:8px}
|
||||
.research-settings{flex:0 0 auto}.research-status{margin:8px 0 10px;padding:9px 10px;border:1px solid rgba(133,200,255,.11);border-radius:11px;background:rgba(255,255,255,.022);color:#87a2b5;font-size:9px;line-height:1.45;word-break:break-word}.research-status.ok{border-color:rgba(93,255,189,.22);color:#91d9bc;background:rgba(93,255,189,.045)}.research-status.failed{border-color:rgba(255,105,125,.24);color:#ff9aab;background:rgba(255,105,125,.045)}.research-status strong{display:block;color:inherit;font-size:10px;margin-bottom:2px}.research-test-query{display:block}.research-test-query span{display:block;font-size:9px;color:#6d879a;margin-bottom:5px}.research-test-query input{width:100%;border:1px solid rgba(133,200,255,.14);background:rgba(2,8,17,.6);color:var(--text);border-radius:10px;padding:9px 10px;outline:0}.research-test-query input:focus{border-color:rgba(93,255,189,.4);box-shadow:0 0 0 3px rgba(93,255,189,.06)}.research-test-actions{display:flex;align-items:center;gap:9px;margin-top:8px}.research-test-actions button{border:1px solid rgba(93,255,189,.3);background:rgba(93,255,189,.08);color:var(--green);border-radius:10px;padding:8px 10px;font-size:8px;font-weight:800;letter-spacing:.12em;cursor:pointer}.research-test-actions button:disabled{opacity:.5;cursor:wait}.research-test-actions span{font-size:9px;color:#7893a6;line-height:1.35}.activity-item .error-detail{margin-top:7px;padding:7px 8px;border-left:2px solid rgba(255,105,125,.6);background:rgba(255,105,125,.055);color:#ff9aab;font-size:9px;line-height:1.45;white-space:pre-wrap;word-break:break-word}
|
||||
|
||||
/* Constellation view, Eco mode and transition diagnostics */
|
||||
.dock #viewHoneycomb.active,.dock #viewNeural.active,.dock #viewConstellation.active{color:var(--green);border-color:rgba(93,255,189,.24);background:rgba(93,255,189,.07)}
|
||||
.dock #toggleEco.active{color:var(--amber);border-color:rgba(255,180,82,.28);background:rgba(255,180,82,.08)}
|
||||
body.constellation-view .mode-status small:after{content:" · Constellation"}
|
||||
body.constellation-view .legend{opacity:.78}
|
||||
body.low-power #brain{image-rendering:auto}
|
||||
body.low-power .vignette{opacity:.78}
|
||||
body.low-power .glass{backdrop-filter:blur(12px)}
|
||||
.performance-subtitle{margin-top:13px}
|
||||
.eco-switch{border-color:rgba(255,180,82,.14)}
|
||||
.eco-switch input:checked{background:rgba(255,180,82,.2)}
|
||||
.eco-switch input:checked:after{background:var(--amber);box-shadow:0 0 10px rgba(255,180,82,.72)}
|
||||
@media(max-width:620px){.view-selector{grid-template-columns:1fr}.metrics span[title]{display:none}}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@
|
||||
<span><b id="nodeCount">0</b> Nodes</span>
|
||||
<span><b id="edgeCount">0</b> Edges</span>
|
||||
<span title="Aktuell gerenderte Knoten"><b id="renderCount">0</b> Render</span>
|
||||
<span title="Gemessene Renderfrequenz"><b id="fpsCount">0</b> FPS</span>
|
||||
<span><b id="pulseCount">0</b> Impulse</span>
|
||||
<span class="state" id="systemState"><i></i> verbindet</span>
|
||||
</div>
|
||||
@@ -47,6 +48,7 @@
|
||||
<nav class="dock glass" aria-label="Ansichtssteuerung">
|
||||
<button id="viewNeural" class="active" title="Semantischer Wissensgraph mit Edges">NEURAL</button>
|
||||
<button id="viewHoneycomb" title="Gleichmäßig verteilte 3D-Wabenansicht ohne Edges">HONEYCOMB</button>
|
||||
<button id="viewConstellation" title="Semantische Themen-Sternbilder mit leichten Clusterpfaden">CONSTELLATION</button>
|
||||
<span class="dock-separator"></span>
|
||||
<button id="toggleLearning" class="active" title="Lernen, Reindex und Embeddings aktivieren oder pausieren">LEARNING</button>
|
||||
<button id="toggleThinking" class="active" title="Autonomes AI-THINK aktivieren oder pausieren">THINKING</button>
|
||||
@@ -56,6 +58,7 @@
|
||||
<button id="toggleRotate" class="active">Autopilot</button>
|
||||
<button id="toggleCortex" class="active">Cortex</button>
|
||||
<button id="toggleLOD" class="active" title="Hierarchische dynamische Verdichtung">LOD</button>
|
||||
<button id="toggleEco" title="Optimierter Renderpfad für schwächere Systeme">ECO</button>
|
||||
<button id="resetView">Zentrieren</button>
|
||||
<button id="openSettings" title="Kategorie-Filter und Laufzeitsteuerung">FILTER</button>
|
||||
<button id="enrichNow" class="think-action" title="Einen autonomen AI-THINK-Zyklus sofort starten"><span>AI-THINK</span><small>STARTEN</small></button>
|
||||
@@ -89,11 +92,17 @@
|
||||
<div class="view-selector" aria-label="Standardansicht">
|
||||
<button id="settingsViewNeural" class="active" type="button">Neural</button>
|
||||
<button id="settingsViewHoneycomb" type="button">Honeycomb</button>
|
||||
<button id="settingsViewConstellation" type="button">Constellation</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-section performance-settings">
|
||||
<div class="settings-section-title"><h2>GPU-Limit</h2><span>0 = unbegrenzt</span></div>
|
||||
<div class="settings-section-title"><h2>Performance</h2><span>Browser-Rendering</span></div>
|
||||
<label class="switch-row eco-switch" for="settingsLowPower">
|
||||
<span><b>Eco-Modus</b><small>30 FPS, geringere Pixeldichte und günstigere Glow-Effekte. Aktivität, Rechercheanimationen und Fades bleiben sichtbar.</small></span>
|
||||
<input id="settingsLowPower" type="checkbox">
|
||||
</label>
|
||||
<div class="settings-section-title performance-subtitle"><h2>GPU-Limit</h2><span>0 = unbegrenzt</span></div>
|
||||
<label class="number-setting" for="settingsMaxDisplayNodes">
|
||||
<span><b>Maximal angezeigte Nodes</b><small>Begrenzt Neural- und Honeycomb-Ansicht. Aktive Notes werden bei Bedarf temporär eingeblendet und ersetzen inaktive Nodes.</small></span>
|
||||
<input id="settingsMaxDisplayNodes" type="number" min="0" max="500000" step="100" inputmode="numeric" value="0">
|
||||
|
||||
Reference in New Issue
Block a user