@ninebix/nmt-system 1.0.2 → 1.0.3
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/README.md +288 -213
- package/dashboard-lite/index.html +1083 -762
- package/dist/bin/nmt.js +171 -40
- package/dist/bin/nmt.js.map +1 -1
- package/dist/src/api/cli-server.d.ts.map +1 -1
- package/dist/src/api/cli-server.js +156 -0
- package/dist/src/api/cli-server.js.map +1 -1
- package/dist/src/core/attractor-model.d.ts +5 -2
- package/dist/src/core/attractor-model.d.ts.map +1 -1
- package/dist/src/core/attractor-model.js +7 -4
- package/dist/src/core/attractor-model.js.map +1 -1
- package/dist/src/core/neuron-graph.d.ts.map +1 -1
- package/dist/src/core/neuron-graph.js +41 -7
- package/dist/src/core/neuron-graph.js.map +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +168 -34
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/services/four-stage-learning.d.ts +19 -0
- package/dist/src/services/four-stage-learning.d.ts.map +1 -1
- package/dist/src/services/four-stage-learning.js +113 -17
- package/dist/src/services/four-stage-learning.js.map +1 -1
- package/dist/src/storage/neuron-store.d.ts +2 -0
- package/dist/src/storage/neuron-store.d.ts.map +1 -1
- package/dist/src/storage/neuron-store.js +22 -14
- package/dist/src/storage/neuron-store.js.map +1 -1
- package/package.json +1 -1
- package/dist/api/cli-server.d.ts +0 -83
- package/dist/api/cli-server.d.ts.map +0 -1
- package/dist/api/cli-server.js +0 -597
- package/dist/api/cli-server.js.map +0 -1
- package/dist/api/index.d.ts +0 -6
- package/dist/api/index.d.ts.map +0 -1
- package/dist/api/index.js +0 -6
- package/dist/api/index.js.map +0 -1
- package/dist/api/middleware/index.d.ts +0 -12
- package/dist/api/middleware/index.d.ts.map +0 -1
- package/dist/api/middleware/index.js +0 -13
- package/dist/api/middleware/index.js.map +0 -1
- package/dist/api/middleware/logger.d.ts +0 -21
- package/dist/api/middleware/logger.d.ts.map +0 -1
- package/dist/api/middleware/logger.js +0 -134
- package/dist/api/middleware/logger.js.map +0 -1
- package/dist/api/middleware/rate-limit.d.ts +0 -26
- package/dist/api/middleware/rate-limit.d.ts.map +0 -1
- package/dist/api/middleware/rate-limit.js +0 -107
- package/dist/api/middleware/rate-limit.js.map +0 -1
- package/dist/api/middleware/response.d.ts +0 -61
- package/dist/api/middleware/response.d.ts.map +0 -1
- package/dist/api/middleware/response.js +0 -86
- package/dist/api/middleware/response.js.map +0 -1
- package/dist/api/middleware/validation.d.ts +0 -43
- package/dist/api/middleware/validation.d.ts.map +0 -1
- package/dist/api/middleware/validation.js +0 -257
- package/dist/api/middleware/validation.js.map +0 -1
- package/dist/api/server.d.ts +0 -79
- package/dist/api/server.d.ts.map +0 -1
- package/dist/api/server.js +0 -2011
- package/dist/api/server.js.map +0 -1
- package/dist/cli/commands/attractor.d.ts +0 -6
- package/dist/cli/commands/attractor.d.ts.map +0 -1
- package/dist/cli/commands/attractor.js +0 -167
- package/dist/cli/commands/attractor.js.map +0 -1
- package/dist/cli/commands/dimension.d.ts +0 -6
- package/dist/cli/commands/dimension.d.ts.map +0 -1
- package/dist/cli/commands/dimension.js +0 -85
- package/dist/cli/commands/dimension.js.map +0 -1
- package/dist/cli/commands/index.d.ts +0 -11
- package/dist/cli/commands/index.d.ts.map +0 -1
- package/dist/cli/commands/index.js +0 -11
- package/dist/cli/commands/index.js.map +0 -1
- package/dist/cli/commands/infer.d.ts +0 -6
- package/dist/cli/commands/infer.d.ts.map +0 -1
- package/dist/cli/commands/infer.js +0 -139
- package/dist/cli/commands/infer.js.map +0 -1
- package/dist/cli/commands/learn.d.ts +0 -6
- package/dist/cli/commands/learn.d.ts.map +0 -1
- package/dist/cli/commands/learn.js +0 -87
- package/dist/cli/commands/learn.js.map +0 -1
- package/dist/cli/commands/orchestrate.d.ts +0 -6
- package/dist/cli/commands/orchestrate.d.ts.map +0 -1
- package/dist/cli/commands/orchestrate.js +0 -279
- package/dist/cli/commands/orchestrate.js.map +0 -1
- package/dist/cli/commands/prob.d.ts +0 -6
- package/dist/cli/commands/prob.d.ts.map +0 -1
- package/dist/cli/commands/prob.js +0 -256
- package/dist/cli/commands/prob.js.map +0 -1
- package/dist/cli/commands/quantum.d.ts +0 -6
- package/dist/cli/commands/quantum.d.ts.map +0 -1
- package/dist/cli/commands/quantum.js +0 -150
- package/dist/cli/commands/quantum.js.map +0 -1
- package/dist/cli/commands/sync.d.ts +0 -65
- package/dist/cli/commands/sync.d.ts.map +0 -1
- package/dist/cli/commands/sync.js +0 -338
- package/dist/cli/commands/sync.js.map +0 -1
- package/dist/cli/index.d.ts +0 -9
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -9
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/probabilistic-commands.d.ts +0 -39
- package/dist/cli/probabilistic-commands.d.ts.map +0 -1
- package/dist/cli/probabilistic-commands.js +0 -112
- package/dist/cli/probabilistic-commands.js.map +0 -1
- package/dist/cli/types.d.ts +0 -69
- package/dist/cli/types.d.ts.map +0 -1
- package/dist/cli/types.js +0 -5
- package/dist/cli/types.js.map +0 -1
- package/dist/cli/utils/formatters.d.ts +0 -51
- package/dist/cli/utils/formatters.d.ts.map +0 -1
- package/dist/cli/utils/formatters.js +0 -79
- package/dist/cli/utils/formatters.js.map +0 -1
- package/dist/cli/utils/helpers.d.ts +0 -21
- package/dist/cli/utils/helpers.d.ts.map +0 -1
- package/dist/cli/utils/helpers.js +0 -51
- package/dist/cli/utils/helpers.js.map +0 -1
- package/dist/cli/utils/index.d.ts +0 -7
- package/dist/cli/utils/index.d.ts.map +0 -1
- package/dist/cli/utils/index.js +0 -13
- package/dist/cli/utils/index.js.map +0 -1
- package/dist/cli/utils/validators.d.ts +0 -162
- package/dist/cli/utils/validators.d.ts.map +0 -1
- package/dist/cli/utils/validators.js +0 -351
- package/dist/cli/utils/validators.js.map +0 -1
- package/dist/core/advanced-embedding.d.ts +0 -154
- package/dist/core/advanced-embedding.d.ts.map +0 -1
- package/dist/core/advanced-embedding.js +0 -367
- package/dist/core/advanced-embedding.js.map +0 -1
- package/dist/core/attractor-model.d.ts +0 -381
- package/dist/core/attractor-model.d.ts.map +0 -1
- package/dist/core/attractor-model.js +0 -821
- package/dist/core/attractor-model.js.map +0 -1
- package/dist/core/bidirectional-inference.d.ts +0 -143
- package/dist/core/bidirectional-inference.d.ts.map +0 -1
- package/dist/core/bidirectional-inference.js +0 -501
- package/dist/core/bidirectional-inference.js.map +0 -1
- package/dist/core/chunk-engine.d.ts +0 -78
- package/dist/core/chunk-engine.d.ts.map +0 -1
- package/dist/core/chunk-engine.js +0 -192
- package/dist/core/chunk-engine.js.map +0 -1
- package/dist/core/dynamic-embedding.d.ts +0 -327
- package/dist/core/dynamic-embedding.d.ts.map +0 -1
- package/dist/core/dynamic-embedding.js +0 -527
- package/dist/core/dynamic-embedding.js.map +0 -1
- package/dist/core/embedding-similarity.d.ts +0 -68
- package/dist/core/embedding-similarity.d.ts.map +0 -1
- package/dist/core/embedding-similarity.js +0 -291
- package/dist/core/embedding-similarity.js.map +0 -1
- package/dist/core/evolution-scheduler.d.ts +0 -101
- package/dist/core/evolution-scheduler.d.ts.map +0 -1
- package/dist/core/evolution-scheduler.js +0 -235
- package/dist/core/evolution-scheduler.js.map +0 -1
- package/dist/core/hierarchical-chunker.d.ts +0 -108
- package/dist/core/hierarchical-chunker.d.ts.map +0 -1
- package/dist/core/hierarchical-chunker.js +0 -296
- package/dist/core/hierarchical-chunker.js.map +0 -1
- package/dist/core/hnsw-index.d.ts +0 -111
- package/dist/core/hnsw-index.d.ts.map +0 -1
- package/dist/core/hnsw-index.js +0 -466
- package/dist/core/hnsw-index.js.map +0 -1
- package/dist/core/index.d.ts +0 -23
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -25
- package/dist/core/index.js.map +0 -1
- package/dist/core/language-analyzers.d.ts +0 -124
- package/dist/core/language-analyzers.d.ts.map +0 -1
- package/dist/core/language-analyzers.js +0 -365
- package/dist/core/language-analyzers.js.map +0 -1
- package/dist/core/local-embedding.d.ts +0 -109
- package/dist/core/local-embedding.d.ts.map +0 -1
- package/dist/core/local-embedding.js +0 -222
- package/dist/core/local-embedding.js.map +0 -1
- package/dist/core/merkle-engine.d.ts +0 -263
- package/dist/core/merkle-engine.d.ts.map +0 -1
- package/dist/core/merkle-engine.js +0 -528
- package/dist/core/merkle-engine.js.map +0 -1
- package/dist/core/multi-layer-reasoning.d.ts +0 -178
- package/dist/core/multi-layer-reasoning.d.ts.map +0 -1
- package/dist/core/multi-layer-reasoning.js +0 -607
- package/dist/core/multi-layer-reasoning.js.map +0 -1
- package/dist/core/neuron-graph.d.ts +0 -134
- package/dist/core/neuron-graph.d.ts.map +0 -1
- package/dist/core/neuron-graph.js +0 -436
- package/dist/core/neuron-graph.js.map +0 -1
- package/dist/core/probabilistic-neuron.d.ts +0 -251
- package/dist/core/probabilistic-neuron.d.ts.map +0 -1
- package/dist/core/probabilistic-neuron.js +0 -618
- package/dist/core/probabilistic-neuron.js.map +0 -1
- package/dist/core/probabilistic-orchestrator.d.ts +0 -408
- package/dist/core/probabilistic-orchestrator.d.ts.map +0 -1
- package/dist/core/probabilistic-orchestrator.js +0 -798
- package/dist/core/probabilistic-orchestrator.js.map +0 -1
- package/dist/core/semantic-chunker.d.ts +0 -117
- package/dist/core/semantic-chunker.d.ts.map +0 -1
- package/dist/core/semantic-chunker.js +0 -464
- package/dist/core/semantic-chunker.js.map +0 -1
- package/dist/events/event-bus.d.ts +0 -166
- package/dist/events/event-bus.d.ts.map +0 -1
- package/dist/events/event-bus.js +0 -228
- package/dist/events/event-bus.js.map +0 -1
- package/dist/events/index.d.ts +0 -7
- package/dist/events/index.d.ts.map +0 -1
- package/dist/events/index.js +0 -7
- package/dist/events/index.js.map +0 -1
- package/dist/events/progress-tracker.d.ts +0 -150
- package/dist/events/progress-tracker.d.ts.map +0 -1
- package/dist/events/progress-tracker.js +0 -290
- package/dist/events/progress-tracker.js.map +0 -1
- package/dist/extensions/clustering/community-detection.d.ts +0 -90
- package/dist/extensions/clustering/community-detection.d.ts.map +0 -1
- package/dist/extensions/clustering/community-detection.js +0 -470
- package/dist/extensions/clustering/community-detection.js.map +0 -1
- package/dist/extensions/clustering/index.d.ts +0 -114
- package/dist/extensions/clustering/index.d.ts.map +0 -1
- package/dist/extensions/clustering/index.js +0 -468
- package/dist/extensions/clustering/index.js.map +0 -1
- package/dist/extensions/clustering/topic-modeling.d.ts +0 -86
- package/dist/extensions/clustering/topic-modeling.d.ts.map +0 -1
- package/dist/extensions/clustering/topic-modeling.js +0 -355
- package/dist/extensions/clustering/topic-modeling.js.map +0 -1
- package/dist/extensions/distributed/coordinator.d.ts +0 -114
- package/dist/extensions/distributed/coordinator.d.ts.map +0 -1
- package/dist/extensions/distributed/coordinator.js +0 -319
- package/dist/extensions/distributed/coordinator.js.map +0 -1
- package/dist/extensions/distributed/index.d.ts +0 -10
- package/dist/extensions/distributed/index.d.ts.map +0 -1
- package/dist/extensions/distributed/index.js +0 -10
- package/dist/extensions/distributed/index.js.map +0 -1
- package/dist/extensions/distributed/queue.d.ts +0 -157
- package/dist/extensions/distributed/queue.d.ts.map +0 -1
- package/dist/extensions/distributed/queue.js +0 -326
- package/dist/extensions/distributed/queue.js.map +0 -1
- package/dist/extensions/distributed/scheduler.d.ts +0 -107
- package/dist/extensions/distributed/scheduler.d.ts.map +0 -1
- package/dist/extensions/distributed/scheduler.js +0 -301
- package/dist/extensions/distributed/scheduler.js.map +0 -1
- package/dist/extensions/distributed/worker.d.ts +0 -112
- package/dist/extensions/distributed/worker.d.ts.map +0 -1
- package/dist/extensions/distributed/worker.js +0 -260
- package/dist/extensions/distributed/worker.js.map +0 -1
- package/dist/index.d.ts +0 -14
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -20
- package/dist/index.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -43
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -494
- package/dist/mcp/server.js.map +0 -1
- package/dist/services/adaptive-fallback.d.ts +0 -140
- package/dist/services/adaptive-fallback.d.ts.map +0 -1
- package/dist/services/adaptive-fallback.js +0 -273
- package/dist/services/adaptive-fallback.js.map +0 -1
- package/dist/services/answer-gate.d.ts +0 -112
- package/dist/services/answer-gate.d.ts.map +0 -1
- package/dist/services/answer-gate.js +0 -299
- package/dist/services/answer-gate.js.map +0 -1
- package/dist/services/auto-learning.d.ts +0 -135
- package/dist/services/auto-learning.d.ts.map +0 -1
- package/dist/services/auto-learning.js +0 -413
- package/dist/services/auto-learning.js.map +0 -1
- package/dist/services/context-compressor.d.ts +0 -77
- package/dist/services/context-compressor.d.ts.map +0 -1
- package/dist/services/context-compressor.js +0 -234
- package/dist/services/context-compressor.js.map +0 -1
- package/dist/services/efficient-rag.d.ts +0 -140
- package/dist/services/efficient-rag.d.ts.map +0 -1
- package/dist/services/efficient-rag.js +0 -311
- package/dist/services/efficient-rag.js.map +0 -1
- package/dist/services/embedding-provider.d.ts +0 -72
- package/dist/services/embedding-provider.d.ts.map +0 -1
- package/dist/services/embedding-provider.js +0 -176
- package/dist/services/embedding-provider.js.map +0 -1
- package/dist/services/file-ingestion.d.ts +0 -72
- package/dist/services/file-ingestion.d.ts.map +0 -1
- package/dist/services/file-ingestion.js +0 -237
- package/dist/services/file-ingestion.js.map +0 -1
- package/dist/services/four-stage-learning.d.ts +0 -552
- package/dist/services/four-stage-learning.d.ts.map +0 -1
- package/dist/services/four-stage-learning.js +0 -1110
- package/dist/services/four-stage-learning.js.map +0 -1
- package/dist/services/graph.d.ts +0 -94
- package/dist/services/graph.d.ts.map +0 -1
- package/dist/services/graph.js +0 -292
- package/dist/services/graph.js.map +0 -1
- package/dist/services/index.d.ts +0 -15
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js +0 -18
- package/dist/services/index.js.map +0 -1
- package/dist/services/ingestion.d.ts +0 -98
- package/dist/services/ingestion.d.ts.map +0 -1
- package/dist/services/ingestion.js +0 -259
- package/dist/services/ingestion.js.map +0 -1
- package/dist/services/learning.d.ts +0 -67
- package/dist/services/learning.d.ts.map +0 -1
- package/dist/services/learning.js +0 -262
- package/dist/services/learning.js.map +0 -1
- package/dist/services/llm-router.d.ts +0 -143
- package/dist/services/llm-router.d.ts.map +0 -1
- package/dist/services/llm-router.js +0 -284
- package/dist/services/llm-router.js.map +0 -1
- package/dist/services/llm.d.ts +0 -86
- package/dist/services/llm.d.ts.map +0 -1
- package/dist/services/llm.js +0 -283
- package/dist/services/llm.js.map +0 -1
- package/dist/services/metrics-dashboard.d.ts +0 -262
- package/dist/services/metrics-dashboard.d.ts.map +0 -1
- package/dist/services/metrics-dashboard.js +0 -417
- package/dist/services/metrics-dashboard.js.map +0 -1
- package/dist/services/neuron-lifecycle.d.ts +0 -137
- package/dist/services/neuron-lifecycle.d.ts.map +0 -1
- package/dist/services/neuron-lifecycle.js +0 -422
- package/dist/services/neuron-lifecycle.js.map +0 -1
- package/dist/services/nmt-pipeline.d.ts +0 -219
- package/dist/services/nmt-pipeline.d.ts.map +0 -1
- package/dist/services/nmt-pipeline.js +0 -449
- package/dist/services/nmt-pipeline.js.map +0 -1
- package/dist/services/query-cache.d.ts +0 -136
- package/dist/services/query-cache.d.ts.map +0 -1
- package/dist/services/query-cache.js +0 -255
- package/dist/services/query-cache.js.map +0 -1
- package/dist/services/query-normalize.d.ts +0 -107
- package/dist/services/query-normalize.d.ts.map +0 -1
- package/dist/services/query-normalize.js +0 -366
- package/dist/services/query-normalize.js.map +0 -1
- package/dist/services/query.d.ts +0 -102
- package/dist/services/query.d.ts.map +0 -1
- package/dist/services/query.js +0 -227
- package/dist/services/query.js.map +0 -1
- package/dist/services/text-embedding.d.ts +0 -183
- package/dist/services/text-embedding.d.ts.map +0 -1
- package/dist/services/text-embedding.js +0 -633
- package/dist/services/text-embedding.js.map +0 -1
- package/dist/services/verification-gate.d.ts +0 -147
- package/dist/services/verification-gate.d.ts.map +0 -1
- package/dist/services/verification-gate.js +0 -344
- package/dist/services/verification-gate.js.map +0 -1
- package/dist/services/verify.d.ts +0 -114
- package/dist/services/verify.d.ts.map +0 -1
- package/dist/services/verify.js +0 -237
- package/dist/services/verify.js.map +0 -1
- package/dist/services/web-search.d.ts +0 -145
- package/dist/services/web-search.d.ts.map +0 -1
- package/dist/services/web-search.js +0 -534
- package/dist/services/web-search.js.map +0 -1
- package/dist/storage/chunk-store.d.ts +0 -107
- package/dist/storage/chunk-store.d.ts.map +0 -1
- package/dist/storage/chunk-store.js +0 -293
- package/dist/storage/chunk-store.js.map +0 -1
- package/dist/storage/hybrid-adapters.d.ts +0 -111
- package/dist/storage/hybrid-adapters.d.ts.map +0 -1
- package/dist/storage/hybrid-adapters.js +0 -223
- package/dist/storage/hybrid-adapters.js.map +0 -1
- package/dist/storage/hybrid-store.d.ts +0 -125
- package/dist/storage/hybrid-store.d.ts.map +0 -1
- package/dist/storage/hybrid-store.js +0 -655
- package/dist/storage/hybrid-store.js.map +0 -1
- package/dist/storage/index-store.d.ts +0 -126
- package/dist/storage/index-store.d.ts.map +0 -1
- package/dist/storage/index-store.js +0 -316
- package/dist/storage/index-store.js.map +0 -1
- package/dist/storage/index.d.ts +0 -45
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js +0 -52
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/neuron-store.d.ts +0 -121
- package/dist/storage/neuron-store.d.ts.map +0 -1
- package/dist/storage/neuron-store.js +0 -466
- package/dist/storage/neuron-store.js.map +0 -1
- package/dist/storage/ontology-store.d.ts +0 -132
- package/dist/storage/ontology-store.d.ts.map +0 -1
- package/dist/storage/ontology-store.js +0 -319
- package/dist/storage/ontology-store.js.map +0 -1
- package/dist/storage/probabilistic-store.d.ts +0 -104
- package/dist/storage/probabilistic-store.d.ts.map +0 -1
- package/dist/storage/probabilistic-store.js +0 -257
- package/dist/storage/probabilistic-store.js.map +0 -1
- package/dist/storage/redis-adapters.d.ts +0 -102
- package/dist/storage/redis-adapters.d.ts.map +0 -1
- package/dist/storage/redis-adapters.js +0 -205
- package/dist/storage/redis-adapters.js.map +0 -1
- package/dist/storage/redis-ontology-store.d.ts +0 -146
- package/dist/storage/redis-ontology-store.d.ts.map +0 -1
- package/dist/storage/redis-ontology-store.js +0 -384
- package/dist/storage/redis-ontology-store.js.map +0 -1
- package/dist/storage/redis-store.d.ts +0 -174
- package/dist/storage/redis-store.d.ts.map +0 -1
- package/dist/storage/redis-store.js +0 -506
- package/dist/storage/redis-store.js.map +0 -1
- package/dist/sync/change-journal.d.ts +0 -171
- package/dist/sync/change-journal.d.ts.map +0 -1
- package/dist/sync/change-journal.js +0 -362
- package/dist/sync/change-journal.js.map +0 -1
- package/dist/sync/index.d.ts +0 -8
- package/dist/sync/index.d.ts.map +0 -1
- package/dist/sync/index.js +0 -8
- package/dist/sync/index.js.map +0 -1
- package/dist/sync/state-sync.d.ts +0 -241
- package/dist/sync/state-sync.d.ts.map +0 -1
- package/dist/sync/state-sync.js +0 -396
- package/dist/sync/state-sync.js.map +0 -1
- package/dist/sync/vector-clock.d.ts +0 -144
- package/dist/sync/vector-clock.d.ts.map +0 -1
- package/dist/sync/vector-clock.js +0 -266
- package/dist/sync/vector-clock.js.map +0 -1
- package/dist/types/index.d.ts +0 -224
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -24
- package/dist/types/index.js.map +0 -1
- package/dist/utils/hash.d.ts +0 -39
- package/dist/utils/hash.d.ts.map +0 -1
- package/dist/utils/hash.js +0 -56
- package/dist/utils/hash.js.map +0 -1
- package/dist/utils/index.d.ts +0 -26
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -50
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -88
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -157
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/metrics.d.ts +0 -232
- package/dist/utils/metrics.d.ts.map +0 -1
- package/dist/utils/metrics.js +0 -387
- package/dist/utils/metrics.js.map +0 -1
- package/dist/utils/similarity.d.ts +0 -64
- package/dist/utils/similarity.d.ts.map +0 -1
- package/dist/utils/similarity.js +0 -151
- package/dist/utils/similarity.js.map +0 -1
- package/dist/utils/uuid.d.ts +0 -23
- package/dist/utils/uuid.d.ts.map +0 -1
- package/dist/utils/uuid.js +0 -29
- package/dist/utils/uuid.js.map +0 -1
|
@@ -3,15 +3,45 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>NMT Dashboard
|
|
6
|
+
<title>NMT Dashboard</title>
|
|
7
7
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<script src="https://d3js.org/d3.v7.min.js"></script>
|
|
8
9
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
10
|
+
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
|
|
11
|
+
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet">
|
|
9
12
|
<script>
|
|
10
13
|
tailwind.config = {
|
|
14
|
+
darkMode: 'class',
|
|
11
15
|
theme: {
|
|
12
16
|
extend: {
|
|
13
17
|
fontFamily: {
|
|
14
|
-
|
|
18
|
+
roboto: ['Roboto', 'sans-serif'],
|
|
19
|
+
mono: ['Roboto Mono', 'ui-monospace', 'monospace'],
|
|
20
|
+
},
|
|
21
|
+
colors: {
|
|
22
|
+
md: {
|
|
23
|
+
primary: '#1976D2',
|
|
24
|
+
'primary-dark': '#1565C0',
|
|
25
|
+
'primary-light': '#42A5F5',
|
|
26
|
+
'on-primary': '#FFFFFF',
|
|
27
|
+
secondary: '#9C27B0',
|
|
28
|
+
surface: '#FFFFFF',
|
|
29
|
+
'surface-dark': '#1E1E1E',
|
|
30
|
+
'surface-variant': '#F5F5F5',
|
|
31
|
+
'surface-variant-dark': '#2D2D2D',
|
|
32
|
+
outline: '#E0E0E0',
|
|
33
|
+
'outline-dark': '#424242',
|
|
34
|
+
'on-surface': '#1C1B1F',
|
|
35
|
+
'on-surface-dark': '#E6E1E5',
|
|
36
|
+
error: '#B3261E',
|
|
37
|
+
success: '#2E7D32',
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
boxShadow: {
|
|
41
|
+
'md-1': '0 1px 2px rgba(0,0,0,0.3), 0 1px 3px 1px rgba(0,0,0,0.15)',
|
|
42
|
+
'md-2': '0 1px 2px rgba(0,0,0,0.3), 0 2px 6px 2px rgba(0,0,0,0.15)',
|
|
43
|
+
'md-3': '0 4px 8px 3px rgba(0,0,0,0.15), 0 1px 3px rgba(0,0,0,0.3)',
|
|
44
|
+
'md-4': '0 6px 10px 4px rgba(0,0,0,0.15), 0 2px 3px rgba(0,0,0,0.3)',
|
|
15
45
|
}
|
|
16
46
|
}
|
|
17
47
|
}
|
|
@@ -19,699 +49,942 @@
|
|
|
19
49
|
</script>
|
|
20
50
|
<style>
|
|
21
51
|
[x-cloak] { display: none !important; }
|
|
22
|
-
::-webkit-scrollbar { width:
|
|
23
|
-
::-webkit-scrollbar-track { background:
|
|
24
|
-
::-webkit-scrollbar-thumb { background: #
|
|
25
|
-
::-webkit-scrollbar-thumb
|
|
52
|
+
::-webkit-scrollbar { width: 8px; height: 8px; }
|
|
53
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
54
|
+
::-webkit-scrollbar-thumb { background: #BDBDBD; border-radius: 4px; }
|
|
55
|
+
.dark ::-webkit-scrollbar-thumb { background: #616161; }
|
|
56
|
+
::-webkit-scrollbar-thumb:hover { background: #9E9E9E; }
|
|
57
|
+
.dark ::-webkit-scrollbar-thumb:hover { background: #757575; }
|
|
58
|
+
.material-icons-outlined { font-size: 24px; vertical-align: middle; }
|
|
59
|
+
.nav-item { transition: background-color 0.2s, color 0.2s; }
|
|
60
|
+
.nav-item:hover { background-color: rgba(25, 118, 210, 0.08); }
|
|
61
|
+
.dark .nav-item:hover { background-color: rgba(66, 165, 245, 0.12); }
|
|
62
|
+
.nav-item.active { background-color: rgba(25, 118, 210, 0.12); color: #1976D2; }
|
|
63
|
+
.dark .nav-item.active { background-color: rgba(66, 165, 245, 0.16); color: #42A5F5; }
|
|
64
|
+
.ripple { position: relative; overflow: hidden; }
|
|
65
|
+
.ripple::after { content: ''; position: absolute; inset: 0; background: radial-gradient(circle, rgba(255,255,255,0.3) 10%, transparent 10.01%); transform: scale(10); opacity: 0; transition: transform 0.5s, opacity 0.3s; }
|
|
66
|
+
.ripple:active::after { transform: scale(0); opacity: 0.3; transition: 0s; }
|
|
67
|
+
.card { transition: box-shadow 0.2s ease; }
|
|
68
|
+
.card:hover { box-shadow: 0 6px 10px 4px rgba(0,0,0,0.15), 0 2px 3px rgba(0,0,0,0.3); }
|
|
26
69
|
</style>
|
|
27
70
|
</head>
|
|
28
|
-
<body class="bg-
|
|
71
|
+
<body class="font-roboto bg-md-surface-variant dark:bg-md-surface-dark min-h-screen transition-colors duration-300"
|
|
72
|
+
x-data="dashboard()" x-init="init()" :class="{ 'dark': darkMode }">
|
|
73
|
+
|
|
74
|
+
<!-- Top Navigation Bar -->
|
|
75
|
+
<header class="fixed top-0 left-0 right-0 z-50 bg-md-primary dark:bg-md-surface-dark shadow-md-2 h-16">
|
|
76
|
+
<div class="flex items-center h-full px-4">
|
|
77
|
+
<!-- Menu Toggle -->
|
|
78
|
+
<button @click="sidebarOpen = !sidebarOpen"
|
|
79
|
+
class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-white/10 transition-colors mr-4">
|
|
80
|
+
<span class="material-icons-outlined text-white dark:text-md-on-surface-dark">menu</span>
|
|
81
|
+
</button>
|
|
29
82
|
|
|
30
|
-
|
|
31
|
-
<header class="bg-white border-b border-gray-200 shadow-sm">
|
|
32
|
-
<div class="max-w-screen-2xl mx-auto px-4 sm:px-6 lg:px-8 h-14 flex items-center justify-between">
|
|
83
|
+
<!-- Title -->
|
|
33
84
|
<div class="flex items-center gap-3">
|
|
34
|
-
<
|
|
35
|
-
<
|
|
85
|
+
<span class="material-icons-outlined text-white dark:text-md-primary-light">hub</span>
|
|
86
|
+
<h1 class="text-xl font-medium text-white dark:text-md-on-surface-dark tracking-wide">NMT Dashboard</h1>
|
|
87
|
+
<span class="text-xs font-medium bg-white/20 dark:bg-md-primary/30 text-white dark:text-md-primary-light px-2 py-0.5 rounded-full">v1.0.3</span>
|
|
36
88
|
</div>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
89
|
+
|
|
90
|
+
<!-- Search Bar -->
|
|
91
|
+
<div class="flex-1 max-w-xl mx-8 hidden md:block">
|
|
92
|
+
<div class="relative">
|
|
93
|
+
<span class="material-icons-outlined absolute left-3 top-1/2 -translate-y-1/2 text-white/70 dark:text-gray-400 text-xl">search</span>
|
|
94
|
+
<input type="text"
|
|
95
|
+
x-model="globalSearch"
|
|
96
|
+
@keydown.enter="doGlobalSearch()"
|
|
97
|
+
placeholder="Search neurons, content..."
|
|
98
|
+
class="w-full bg-white/10 dark:bg-md-surface-variant-dark border-0 rounded-full pl-10 pr-4 py-2.5 text-sm text-white dark:text-md-on-surface-dark placeholder-white/60 dark:placeholder-gray-500 focus:bg-white/20 dark:focus:bg-md-surface-variant-dark focus:outline-none focus:ring-2 focus:ring-white/30 dark:focus:ring-md-primary transition-all">
|
|
99
|
+
</div>
|
|
46
100
|
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</header>
|
|
49
101
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
102
|
+
<!-- Right Actions -->
|
|
103
|
+
<div class="flex items-center gap-2 ml-auto">
|
|
104
|
+
<!-- Connection Status -->
|
|
105
|
+
<div class="flex items-center gap-2 px-3 py-1.5 rounded-full"
|
|
106
|
+
:class="connected ? 'bg-md-success/20 dark:bg-md-success/30' : 'bg-md-error/20 dark:bg-md-error/30'">
|
|
107
|
+
<span class="w-2 h-2 rounded-full" :class="connected ? 'bg-md-success animate-pulse' : 'bg-md-error'"></span>
|
|
108
|
+
<span class="text-xs font-medium" :class="connected ? 'text-white dark:text-green-400' : 'text-white dark:text-red-400'"
|
|
109
|
+
x-text="connected ? 'Connected' : 'Offline'"></span>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<!-- Dark Mode Toggle -->
|
|
113
|
+
<button @click="toggleDarkMode()"
|
|
114
|
+
class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-white/10 dark:hover:bg-white/5 transition-colors">
|
|
115
|
+
<span x-show="!darkMode" class="material-icons-outlined text-white">dark_mode</span>
|
|
116
|
+
<span x-show="darkMode" x-cloak class="material-icons-outlined text-md-on-surface-dark">light_mode</span>
|
|
117
|
+
</button>
|
|
118
|
+
|
|
119
|
+
<!-- Refresh -->
|
|
120
|
+
<button @click="refreshAll()"
|
|
121
|
+
class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-white/10 dark:hover:bg-white/5 transition-colors">
|
|
122
|
+
<span class="material-icons-outlined text-white dark:text-md-on-surface-dark" :class="{ 'animate-spin': refreshing }">refresh</span>
|
|
123
|
+
</button>
|
|
64
124
|
</div>
|
|
65
125
|
</div>
|
|
66
|
-
</
|
|
67
|
-
|
|
68
|
-
<!-- Main Content Area -->
|
|
69
|
-
<main class="max-w-screen-2xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
70
|
-
|
|
71
|
-
<!-- ============================================================ -->
|
|
72
|
-
<!-- TAB 1: OVERVIEW -->
|
|
73
|
-
<!-- ============================================================ -->
|
|
74
|
-
<section x-show="activeTab === 'overview'" x-cloak>
|
|
75
|
-
<div class="flex items-center justify-between mb-5">
|
|
76
|
-
<h2 class="text-base font-semibold text-gray-900">System Overview</h2>
|
|
77
|
-
<span class="text-xs text-gray-400" x-text="lastRefresh ? 'Updated ' + lastRefresh : ''"></span>
|
|
78
|
-
</div>
|
|
126
|
+
</header>
|
|
79
127
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
128
|
+
<!-- Side Navigation -->
|
|
129
|
+
<aside :class="sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0 lg:w-20'"
|
|
130
|
+
class="fixed left-0 top-16 bottom-0 z-40 w-64 bg-md-surface dark:bg-md-surface-dark shadow-md-2 transition-all duration-300 overflow-hidden">
|
|
131
|
+
<nav class="py-4 h-full overflow-y-auto">
|
|
132
|
+
<template x-for="item in navItems" :key="item.id">
|
|
133
|
+
<button @click="switchTab(item.id); if(window.innerWidth < 1024) sidebarOpen = false"
|
|
134
|
+
:class="{ 'active': activeTab === item.id }"
|
|
135
|
+
class="nav-item w-full flex items-center gap-4 px-6 py-3 text-md-on-surface dark:text-md-on-surface-dark">
|
|
136
|
+
<span class="material-icons-outlined" :class="activeTab === item.id ? 'text-md-primary dark:text-md-primary-light' : ''" x-text="item.icon"></span>
|
|
137
|
+
<span x-show="sidebarOpen" class="text-sm font-medium" x-text="item.label"></span>
|
|
138
|
+
</button>
|
|
139
|
+
</template>
|
|
140
|
+
|
|
141
|
+
</nav>
|
|
142
|
+
</aside>
|
|
143
|
+
|
|
144
|
+
<!-- Main Content -->
|
|
145
|
+
<main :class="sidebarOpen ? 'lg:ml-64' : 'lg:ml-20'"
|
|
146
|
+
class="pt-16 min-h-screen transition-all duration-300">
|
|
147
|
+
<div class="p-6">
|
|
148
|
+
|
|
149
|
+
<!-- OVERVIEW TAB -->
|
|
150
|
+
<section x-show="activeTab === 'overview'" x-cloak>
|
|
151
|
+
<!-- Page Header -->
|
|
152
|
+
<div class="flex items-center justify-between mb-6">
|
|
153
|
+
<div>
|
|
154
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark">System Overview</h2>
|
|
155
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1" x-text="lastRefresh ? 'Last updated: ' + lastRefresh : 'Loading...'"></p>
|
|
156
|
+
</div>
|
|
101
157
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
158
|
+
|
|
159
|
+
<!-- Stats Cards Grid -->
|
|
160
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
|
161
|
+
<!-- Neurons Card -->
|
|
162
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
163
|
+
<div class="flex items-center justify-between mb-3">
|
|
164
|
+
<span class="material-icons-outlined text-md-primary text-3xl">psychology</span>
|
|
165
|
+
<span class="text-xs font-medium text-md-success bg-md-success/10 px-2 py-1 rounded-full">Active</span>
|
|
166
|
+
</div>
|
|
167
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="formatNumber(stats.neurons ?? 0)"></p>
|
|
168
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Total Neurons</p>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<!-- Synapses Card -->
|
|
172
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
173
|
+
<div class="flex items-center justify-between mb-3">
|
|
174
|
+
<span class="material-icons-outlined text-md-secondary text-3xl">share</span>
|
|
175
|
+
</div>
|
|
176
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="formatNumber(stats.synapses ?? 0)"></p>
|
|
177
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Connections</p>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<!-- Chunks Card -->
|
|
181
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
182
|
+
<div class="flex items-center justify-between mb-3">
|
|
183
|
+
<span class="material-icons-outlined text-amber-600 text-3xl">inventory_2</span>
|
|
184
|
+
</div>
|
|
185
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="formatNumber(stats.chunks?.total ?? 0)"></p>
|
|
186
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Data Chunks</p>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<!-- Storage Card -->
|
|
190
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
191
|
+
<div class="flex items-center justify-between mb-3">
|
|
192
|
+
<span class="material-icons-outlined text-teal-600 text-3xl">storage</span>
|
|
193
|
+
</div>
|
|
194
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="formatBytes(stats.chunks?.totalSize)"></p>
|
|
195
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Total Storage</p>
|
|
196
|
+
</div>
|
|
106
197
|
</div>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<
|
|
198
|
+
|
|
199
|
+
<!-- Second Row Cards -->
|
|
200
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
|
201
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
202
|
+
<div class="flex items-center gap-3 mb-3">
|
|
203
|
+
<span class="material-icons-outlined text-indigo-500">scatter_plot</span>
|
|
204
|
+
<span class="text-sm font-medium text-gray-500 dark:text-gray-400">HNSW Vectors</span>
|
|
205
|
+
</div>
|
|
206
|
+
<p class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="formatNumber(stats.hnsw?.totalNodes ?? 0)"></p>
|
|
207
|
+
</div>
|
|
208
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
209
|
+
<div class="flex items-center gap-3 mb-3">
|
|
210
|
+
<span class="material-icons-outlined text-pink-500">layers</span>
|
|
211
|
+
<span class="text-sm font-medium text-gray-500 dark:text-gray-400">HNSW Layers</span>
|
|
212
|
+
</div>
|
|
213
|
+
<p class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="stats.hnsw?.maxLayer ?? 0"></p>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
216
|
+
<div class="flex items-center gap-3 mb-3">
|
|
217
|
+
<span class="material-icons-outlined text-cyan-500">dns</span>
|
|
218
|
+
<span class="text-sm font-medium text-gray-500 dark:text-gray-400">Storage Backend</span>
|
|
219
|
+
</div>
|
|
220
|
+
<p class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="stats.storage?.backend ?? 'LevelDB'"></p>
|
|
221
|
+
</div>
|
|
222
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
223
|
+
<div class="flex items-center gap-3 mb-3">
|
|
224
|
+
<span class="material-icons-outlined text-orange-500">data_array</span>
|
|
225
|
+
<span class="text-sm font-medium text-gray-500 dark:text-gray-400">Avg Chunk Size</span>
|
|
226
|
+
</div>
|
|
227
|
+
<p class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="formatBytes(stats.chunks?.avgSize)"></p>
|
|
228
|
+
</div>
|
|
111
229
|
</div>
|
|
112
|
-
</div>
|
|
113
230
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
231
|
+
<!-- Recent Activity Table -->
|
|
232
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
233
|
+
<div class="px-6 py-4 border-b border-md-outline dark:border-md-outline-dark">
|
|
234
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark flex items-center gap-2">
|
|
235
|
+
<span class="material-icons-outlined text-md-primary">history</span>
|
|
236
|
+
Recent Neurons
|
|
237
|
+
</h3>
|
|
121
238
|
</div>
|
|
122
|
-
<div>
|
|
123
|
-
<
|
|
124
|
-
|
|
239
|
+
<div class="overflow-x-auto">
|
|
240
|
+
<table class="w-full">
|
|
241
|
+
<thead>
|
|
242
|
+
<tr class="bg-md-surface-variant dark:bg-md-surface-dark border-b border-md-outline dark:border-md-outline-dark">
|
|
243
|
+
<th class="text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider px-6 py-3">ID</th>
|
|
244
|
+
<th class="text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider px-6 py-3">Type</th>
|
|
245
|
+
<th class="text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider px-6 py-3">Tags</th>
|
|
246
|
+
<th class="text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider px-6 py-3">Chunks</th>
|
|
247
|
+
</tr>
|
|
248
|
+
</thead>
|
|
249
|
+
<tbody class="divide-y divide-md-outline dark:divide-md-outline-dark">
|
|
250
|
+
<template x-for="neuron in recentNeurons.slice(0, 5)" :key="neuron.id">
|
|
251
|
+
<tr class="hover:bg-md-surface-variant dark:hover:bg-md-surface-dark transition-colors">
|
|
252
|
+
<td class="px-6 py-4">
|
|
253
|
+
<span class="font-mono text-sm text-md-primary dark:text-md-primary-light" x-text="neuron.id?.substring(0, 12) + '...'"></span>
|
|
254
|
+
</td>
|
|
255
|
+
<td class="px-6 py-4">
|
|
256
|
+
<span class="text-sm text-md-on-surface dark:text-md-on-surface-dark" x-text="neuron.sourceType || 'Unknown'"></span>
|
|
257
|
+
</td>
|
|
258
|
+
<td class="px-6 py-4">
|
|
259
|
+
<div class="flex flex-wrap gap-1">
|
|
260
|
+
<template x-for="tag in (neuron.tags || []).slice(0, 3)" :key="tag">
|
|
261
|
+
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-md-primary/10 text-md-primary dark:bg-md-primary/20 dark:text-md-primary-light" x-text="tag"></span>
|
|
262
|
+
</template>
|
|
263
|
+
</div>
|
|
264
|
+
</td>
|
|
265
|
+
<td class="px-6 py-4 text-right">
|
|
266
|
+
<span class="text-sm font-mono text-md-on-surface dark:text-md-on-surface-dark" x-text="neuron.chunks ?? 0"></span>
|
|
267
|
+
</td>
|
|
268
|
+
</tr>
|
|
269
|
+
</template>
|
|
270
|
+
<tr x-show="recentNeurons.length === 0">
|
|
271
|
+
<td colspan="4" class="px-6 py-8 text-center text-gray-500 dark:text-gray-400">
|
|
272
|
+
<span class="material-icons-outlined text-4xl mb-2 block">inbox</span>
|
|
273
|
+
No neurons yet. Start by ingesting some content.
|
|
274
|
+
</td>
|
|
275
|
+
</tr>
|
|
276
|
+
</tbody>
|
|
277
|
+
</table>
|
|
125
278
|
</div>
|
|
279
|
+
</div>
|
|
280
|
+
</section>
|
|
281
|
+
|
|
282
|
+
<!-- NEURONS TAB -->
|
|
283
|
+
<section x-show="activeTab === 'neurons'" x-cloak>
|
|
284
|
+
<div class="flex items-center justify-between mb-6">
|
|
126
285
|
<div>
|
|
127
|
-
<
|
|
128
|
-
<p class="text-sm
|
|
286
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark">Neurons</h2>
|
|
287
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Total: <span x-text="neuronTotal"></span> neurons</p>
|
|
129
288
|
</div>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
<!-- ============================================================ -->
|
|
135
|
-
<!-- TAB 2: NEURONS -->
|
|
136
|
-
<!-- ============================================================ -->
|
|
137
|
-
<section x-show="activeTab === 'neurons'" x-cloak>
|
|
138
|
-
<div class="flex items-center justify-between mb-4">
|
|
139
|
-
<h2 class="text-base font-semibold text-gray-900">
|
|
140
|
-
Neurons
|
|
141
|
-
<span class="text-sm font-normal text-gray-500 ml-1" x-show="neuronTotal > 0" x-text="'(' + neuronTotal + ' total)'"></span>
|
|
142
|
-
</h2>
|
|
143
|
-
<div class="flex items-center gap-2">
|
|
144
|
-
<button @click="loadNeurons()" class="text-xs text-indigo-600 hover:text-indigo-800 font-medium px-2 py-1 rounded hover:bg-indigo-50 transition-colors">
|
|
289
|
+
<button @click="loadNeurons()"
|
|
290
|
+
class="flex items-center gap-2 px-4 py-2 bg-md-primary text-white rounded-full text-sm font-medium hover:bg-md-primary-dark shadow-md-1 transition-all">
|
|
291
|
+
<span class="material-icons-outlined text-xl">refresh</span>
|
|
145
292
|
Refresh
|
|
146
293
|
</button>
|
|
147
294
|
</div>
|
|
148
|
-
</div>
|
|
149
295
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
<div class="overflow-x-auto">
|
|
167
|
-
<table class="w-full text-sm">
|
|
168
|
-
<thead>
|
|
169
|
-
<tr class="border-b border-gray-200 bg-gray-50">
|
|
170
|
-
<th class="text-left text-xs font-semibold text-gray-600 uppercase tracking-wide px-4 py-2.5">ID</th>
|
|
171
|
-
<th class="text-left text-xs font-semibold text-gray-600 uppercase tracking-wide px-4 py-2.5">Type</th>
|
|
172
|
-
<th class="text-left text-xs font-semibold text-gray-600 uppercase tracking-wide px-4 py-2.5">Tags</th>
|
|
173
|
-
<th class="text-right text-xs font-semibold text-gray-600 uppercase tracking-wide px-4 py-2.5">Chunks</th>
|
|
174
|
-
<th class="text-left text-xs font-semibold text-gray-600 uppercase tracking-wide px-4 py-2.5">Created</th>
|
|
175
|
-
</tr>
|
|
176
|
-
</thead>
|
|
177
|
-
<tbody>
|
|
178
|
-
<template x-for="neuron in neurons" :key="neuron.id">
|
|
179
|
-
<tr
|
|
180
|
-
@click="selectNeuron(neuron)"
|
|
181
|
-
:class="selectedNeuron?.id === neuron.id ? 'bg-indigo-50' : 'hover:bg-gray-50'"
|
|
182
|
-
class="border-b border-gray-100 cursor-pointer transition-colors"
|
|
183
|
-
>
|
|
184
|
-
<td class="px-4 py-2.5 font-mono text-xs text-indigo-700" x-text="neuron.id.substring(0, 8) + '...'"></td>
|
|
185
|
-
<td class="px-4 py-2.5 text-gray-700" x-text="neuron.sourceType || '--'"></td>
|
|
186
|
-
<td class="px-4 py-2.5">
|
|
187
|
-
<div class="flex flex-wrap gap-1">
|
|
188
|
-
<template x-for="tag in (neuron.tags || [])" :key="tag">
|
|
189
|
-
<span class="inline-block bg-indigo-50 text-indigo-700 text-xs font-medium px-1.5 py-0.5 rounded" x-text="tag"></span>
|
|
190
|
-
</template>
|
|
191
|
-
<span x-show="!neuron.tags || neuron.tags.length === 0" class="text-xs text-gray-400">--</span>
|
|
192
|
-
</div>
|
|
193
|
-
</td>
|
|
194
|
-
<td class="px-4 py-2.5 text-right text-gray-700 font-mono text-xs" x-text="neuron.chunks ?? '--'"></td>
|
|
195
|
-
<td class="px-4 py-2.5 text-gray-500 text-xs whitespace-nowrap" x-text="formatDate(neuron.createdAt)"></td>
|
|
296
|
+
<div class="flex gap-6">
|
|
297
|
+
<!-- Neurons List -->
|
|
298
|
+
<div class="flex-1">
|
|
299
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
300
|
+
<div x-show="neuronsLoading" class="p-12 text-center">
|
|
301
|
+
<div class="inline-block w-8 h-8 border-4 border-md-primary/20 border-t-md-primary rounded-full animate-spin"></div>
|
|
302
|
+
<p class="mt-4 text-gray-500 dark:text-gray-400">Loading neurons...</p>
|
|
303
|
+
</div>
|
|
304
|
+
<div x-show="!neuronsLoading">
|
|
305
|
+
<table class="w-full">
|
|
306
|
+
<thead>
|
|
307
|
+
<tr class="bg-md-surface-variant dark:bg-md-surface-dark border-b border-md-outline dark:border-md-outline-dark">
|
|
308
|
+
<th class="text-left text-xs font-medium text-gray-500 uppercase tracking-wider px-6 py-3">ID</th>
|
|
309
|
+
<th class="text-left text-xs font-medium text-gray-500 uppercase tracking-wider px-6 py-3">Type</th>
|
|
310
|
+
<th class="text-left text-xs font-medium text-gray-500 uppercase tracking-wider px-6 py-3">Tags</th>
|
|
311
|
+
<th class="text-right text-xs font-medium text-gray-500 uppercase tracking-wider px-6 py-3">Chunks</th>
|
|
196
312
|
</tr>
|
|
197
|
-
</
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
313
|
+
</thead>
|
|
314
|
+
<tbody class="divide-y divide-md-outline dark:divide-md-outline-dark">
|
|
315
|
+
<template x-for="neuron in neurons" :key="neuron.id">
|
|
316
|
+
<tr @click="selectNeuron(neuron)"
|
|
317
|
+
:class="selectedNeuron?.id === neuron.id ? 'bg-md-primary/5 dark:bg-md-primary/10' : 'hover:bg-md-surface-variant dark:hover:bg-md-surface-dark'"
|
|
318
|
+
class="cursor-pointer transition-colors">
|
|
319
|
+
<td class="px-6 py-4 font-mono text-sm text-md-primary dark:text-md-primary-light" x-text="neuron.id?.substring(0, 12) + '...'"></td>
|
|
320
|
+
<td class="px-6 py-4 text-sm text-md-on-surface dark:text-md-on-surface-dark" x-text="neuron.sourceType || '--'"></td>
|
|
321
|
+
<td class="px-6 py-4">
|
|
322
|
+
<div class="flex flex-wrap gap-1">
|
|
323
|
+
<template x-for="tag in (neuron.tags || []).slice(0, 3)" :key="tag">
|
|
324
|
+
<span class="px-2 py-0.5 text-xs rounded-full bg-md-primary/10 text-md-primary dark:bg-md-primary/20 dark:text-md-primary-light" x-text="tag"></span>
|
|
325
|
+
</template>
|
|
326
|
+
</div>
|
|
327
|
+
</td>
|
|
328
|
+
<td class="px-6 py-4 text-right font-mono text-sm text-md-on-surface dark:text-md-on-surface-dark" x-text="neuron.chunks ?? '--'"></td>
|
|
329
|
+
</tr>
|
|
330
|
+
</template>
|
|
331
|
+
</tbody>
|
|
332
|
+
</table>
|
|
333
|
+
<!-- Pagination -->
|
|
334
|
+
<div class="flex items-center justify-between px-6 py-4 bg-md-surface-variant dark:bg-md-surface-dark border-t border-md-outline dark:border-md-outline-dark">
|
|
335
|
+
<span class="text-sm text-gray-500 dark:text-gray-400" x-text="paginationLabel()"></span>
|
|
336
|
+
<div class="flex gap-2">
|
|
337
|
+
<button @click="prevPage()" :disabled="neuronPage === 0"
|
|
338
|
+
class="px-4 py-2 text-sm font-medium rounded-full border border-md-outline dark:border-md-outline-dark disabled:opacity-40 hover:bg-md-surface-variant dark:hover:bg-md-surface transition-colors">
|
|
339
|
+
Previous
|
|
340
|
+
</button>
|
|
341
|
+
<button @click="nextPage()" :disabled="(neuronPage + 1) * neuronLimit >= neuronTotal"
|
|
342
|
+
class="px-4 py-2 text-sm font-medium rounded-full border border-md-outline dark:border-md-outline-dark disabled:opacity-40 hover:bg-md-surface-variant dark:hover:bg-md-surface transition-colors">
|
|
343
|
+
Next
|
|
344
|
+
</button>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
222
347
|
</div>
|
|
223
348
|
</div>
|
|
224
349
|
</div>
|
|
225
|
-
</div>
|
|
226
350
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
<p class="text-xs font-mono text-gray-900 break-all select-all" x-text="selectedNeuron?.id"></p>
|
|
239
|
-
</div>
|
|
240
|
-
<!-- Merkle Root -->
|
|
241
|
-
<div>
|
|
242
|
-
<label class="text-xs text-gray-500 block">Merkle Root</label>
|
|
243
|
-
<p class="text-xs font-mono text-gray-900 break-all select-all" x-text="selectedNeuron?.merkleRoot || '--'"></p>
|
|
244
|
-
</div>
|
|
245
|
-
<!-- Source Type -->
|
|
246
|
-
<div>
|
|
247
|
-
<label class="text-xs text-gray-500 block">Source Type</label>
|
|
248
|
-
<p class="text-sm text-gray-900" x-text="selectedNeuron?.sourceType || '--'"></p>
|
|
249
|
-
</div>
|
|
250
|
-
<!-- Tags -->
|
|
251
|
-
<div>
|
|
252
|
-
<label class="text-xs text-gray-500 block mb-1">Tags</label>
|
|
253
|
-
<div class="flex flex-wrap gap-1">
|
|
254
|
-
<template x-for="tag in (selectedNeuron?.tags || [])" :key="tag">
|
|
255
|
-
<span class="inline-block bg-indigo-50 text-indigo-700 text-xs font-medium px-1.5 py-0.5 rounded" x-text="tag"></span>
|
|
256
|
-
</template>
|
|
257
|
-
<span x-show="!selectedNeuron?.tags || selectedNeuron?.tags.length === 0" class="text-xs text-gray-400">None</span>
|
|
258
|
-
</div>
|
|
351
|
+
<!-- Detail Panel -->
|
|
352
|
+
<div x-show="selectedNeuron" x-cloak class="w-96 flex-shrink-0">
|
|
353
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-2 sticky top-24 overflow-hidden">
|
|
354
|
+
<div class="flex items-center justify-between px-6 py-4 bg-md-primary dark:bg-md-primary-dark">
|
|
355
|
+
<h3 class="text-lg font-medium text-white flex items-center gap-2">
|
|
356
|
+
<span class="material-icons-outlined">info</span>
|
|
357
|
+
Details
|
|
358
|
+
</h3>
|
|
359
|
+
<button @click="selectedNeuron = null" class="w-8 h-8 flex items-center justify-center rounded-full hover:bg-white/10">
|
|
360
|
+
<span class="material-icons-outlined text-white">close</span>
|
|
361
|
+
</button>
|
|
259
362
|
</div>
|
|
260
|
-
|
|
261
|
-
<div class="grid grid-cols-2 gap-3">
|
|
363
|
+
<div class="p-6 space-y-4 max-h-[calc(100vh-200px)] overflow-y-auto">
|
|
262
364
|
<div>
|
|
263
|
-
<label class="text-xs text-gray-500
|
|
264
|
-
<p class="text-sm
|
|
365
|
+
<label class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Neuron ID</label>
|
|
366
|
+
<p class="font-mono text-sm text-md-on-surface dark:text-md-on-surface-dark mt-1 break-all" x-text="selectedNeuron?.id"></p>
|
|
265
367
|
</div>
|
|
266
368
|
<div>
|
|
267
|
-
<label class="text-xs text-gray-500
|
|
268
|
-
<p class="text-sm
|
|
369
|
+
<label class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Merkle Root</label>
|
|
370
|
+
<p class="font-mono text-sm text-md-on-surface dark:text-md-on-surface-dark mt-1 break-all" x-text="selectedNeuron?.merkleRoot || '--'"></p>
|
|
269
371
|
</div>
|
|
270
|
-
</div>
|
|
271
|
-
<!-- Dates -->
|
|
272
|
-
<div class="grid grid-cols-2 gap-3">
|
|
273
372
|
<div>
|
|
274
|
-
<label class="text-xs text-gray-500
|
|
275
|
-
<
|
|
276
|
-
</div>
|
|
277
|
-
<div>
|
|
278
|
-
<label class="text-xs text-gray-500 block">Updated</label>
|
|
279
|
-
<p class="text-xs text-gray-900" x-text="formatDate(selectedNeuron?.updatedAt)"></p>
|
|
280
|
-
</div>
|
|
281
|
-
</div>
|
|
282
|
-
<div>
|
|
283
|
-
<label class="text-xs text-gray-500 block">Last Accessed</label>
|
|
284
|
-
<p class="text-xs text-gray-900" x-text="formatDate(selectedNeuron?.lastAccessed)"></p>
|
|
285
|
-
</div>
|
|
286
|
-
<!-- Synapses -->
|
|
287
|
-
<div x-show="selectedNeuron?.synapses">
|
|
288
|
-
<label class="text-xs text-gray-500 block mb-1">Synapses</label>
|
|
289
|
-
<div class="flex gap-4">
|
|
290
|
-
<span class="text-xs text-gray-700">
|
|
291
|
-
Outgoing: <span class="font-semibold font-mono" x-text="selectedNeuron?.synapses?.outgoing?.length ?? selectedNeuron?.synapses?.outgoing ?? 0"></span>
|
|
292
|
-
</span>
|
|
293
|
-
<span class="text-xs text-gray-700">
|
|
294
|
-
Incoming: <span class="font-semibold font-mono" x-text="selectedNeuron?.synapses?.incoming?.length ?? selectedNeuron?.synapses?.incoming ?? 0"></span>
|
|
295
|
-
</span>
|
|
296
|
-
</div>
|
|
297
|
-
</div>
|
|
298
|
-
<!-- Content -->
|
|
299
|
-
<div>
|
|
300
|
-
<label class="text-xs text-gray-500 block mb-1">Content</label>
|
|
301
|
-
<div x-show="contentLoading" class="text-xs text-gray-400">Loading content...</div>
|
|
302
|
-
<pre x-show="selectedContent && !contentLoading" class="bg-gray-50 border border-gray-200 rounded p-3 text-xs text-gray-800 font-mono whitespace-pre-wrap break-words max-h-64 overflow-y-auto" x-text="selectedContent"></pre>
|
|
303
|
-
<p x-show="!selectedContent && !contentLoading" class="text-xs text-gray-400">No content available</p>
|
|
304
|
-
</div>
|
|
305
|
-
<!-- Delete -->
|
|
306
|
-
<div class="pt-2 border-t border-gray-200">
|
|
307
|
-
<button
|
|
308
|
-
x-show="!confirmDelete"
|
|
309
|
-
@click="confirmDelete = true"
|
|
310
|
-
class="w-full px-3 py-2 text-xs font-medium text-red-700 bg-red-50 border border-red-200 rounded hover:bg-red-100 transition-colors"
|
|
311
|
-
>
|
|
312
|
-
Delete Neuron
|
|
313
|
-
</button>
|
|
314
|
-
<div x-show="confirmDelete" class="space-y-2">
|
|
315
|
-
<p class="text-xs text-red-600 font-medium">Are you sure? This cannot be undone.</p>
|
|
316
|
-
<div class="flex gap-2">
|
|
317
|
-
<button
|
|
318
|
-
@click="deleteNeuron(selectedNeuron.id)"
|
|
319
|
-
:disabled="deleting"
|
|
320
|
-
class="flex-1 px-3 py-2 text-xs font-medium text-white bg-red-600 rounded hover:bg-red-700 transition-colors disabled:opacity-50"
|
|
321
|
-
>
|
|
322
|
-
<span x-show="!deleting">Confirm Delete</span>
|
|
323
|
-
<span x-show="deleting">Deleting...</span>
|
|
324
|
-
</button>
|
|
325
|
-
<button
|
|
326
|
-
@click="confirmDelete = false"
|
|
327
|
-
class="flex-1 px-3 py-2 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 transition-colors"
|
|
328
|
-
>
|
|
329
|
-
Cancel
|
|
330
|
-
</button>
|
|
331
|
-
</div>
|
|
373
|
+
<label class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Content</label>
|
|
374
|
+
<pre class="mt-2 bg-md-surface-variant dark:bg-md-surface-dark rounded-lg p-4 text-sm text-md-on-surface dark:text-md-on-surface-dark max-h-60 overflow-y-auto whitespace-pre-wrap" x-text="selectedContent || 'Loading...'"></pre>
|
|
332
375
|
</div>
|
|
333
376
|
</div>
|
|
334
377
|
</div>
|
|
335
378
|
</div>
|
|
336
379
|
</div>
|
|
337
|
-
</
|
|
338
|
-
</section>
|
|
339
|
-
|
|
340
|
-
<!-- ============================================================ -->
|
|
341
|
-
<!-- TAB 3: SEARCH -->
|
|
342
|
-
<!-- ============================================================ -->
|
|
343
|
-
<section x-show="activeTab === 'search'" x-cloak>
|
|
344
|
-
<h2 class="text-base font-semibold text-gray-900 mb-4">Semantic Search</h2>
|
|
380
|
+
</section>
|
|
345
381
|
|
|
346
|
-
<!--
|
|
347
|
-
<
|
|
348
|
-
<div class="flex
|
|
349
|
-
<
|
|
350
|
-
|
|
351
|
-
<
|
|
352
|
-
|
|
353
|
-
x-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
<div class="w-24">
|
|
360
|
-
<label class="text-xs font-medium text-gray-600 block mb-1">Top-K</label>
|
|
361
|
-
<input
|
|
362
|
-
type="number"
|
|
363
|
-
x-model.number="searchK"
|
|
364
|
-
min="1"
|
|
365
|
-
max="100"
|
|
366
|
-
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition"
|
|
367
|
-
>
|
|
368
|
-
</div>
|
|
369
|
-
<div class="flex items-end gap-3">
|
|
370
|
-
<label class="flex items-center gap-2 pb-2 cursor-pointer select-none">
|
|
371
|
-
<input type="checkbox" x-model="searchIncludeContent" class="w-4 h-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500">
|
|
372
|
-
<span class="text-xs font-medium text-gray-600 whitespace-nowrap">Include Content</span>
|
|
373
|
-
</label>
|
|
374
|
-
<button
|
|
375
|
-
@click="doSearch()"
|
|
376
|
-
:disabled="searching || !searchQuery.trim()"
|
|
377
|
-
class="px-5 py-2 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2"
|
|
378
|
-
>
|
|
379
|
-
<span x-show="searching" class="w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
|
|
380
|
-
Search
|
|
382
|
+
<!-- GRAPH TAB -->
|
|
383
|
+
<section x-show="activeTab === 'graph'" x-cloak x-init="$watch('activeTab', val => { if(val === 'graph') setTimeout(() => renderGraph(), 100) })">
|
|
384
|
+
<div class="flex items-center justify-between mb-6">
|
|
385
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark">Knowledge Graph</h2>
|
|
386
|
+
<div class="flex items-center gap-3">
|
|
387
|
+
<button @click="graphViewMode = graphViewMode === 'graph' ? 'table' : 'graph'"
|
|
388
|
+
class="flex items-center gap-2 px-4 py-2 bg-md-surface dark:bg-md-surface-variant-dark border border-md-outline dark:border-md-outline-dark rounded-full text-sm font-medium hover:bg-md-surface-variant transition-colors">
|
|
389
|
+
<span class="material-icons-outlined text-xl" x-text="graphViewMode === 'graph' ? 'table_rows' : 'hub'"></span>
|
|
390
|
+
<span x-text="graphViewMode === 'graph' ? 'Table' : 'Graph'"></span>
|
|
391
|
+
</button>
|
|
392
|
+
<button @click="loadGraph(); setTimeout(() => renderGraph(), 200)" class="flex items-center gap-2 px-4 py-2 bg-md-primary text-white rounded-full text-sm font-medium hover:bg-md-primary-dark shadow-md-1">
|
|
393
|
+
<span class="material-icons-outlined text-xl">refresh</span>
|
|
394
|
+
Refresh
|
|
381
395
|
</button>
|
|
382
396
|
</div>
|
|
383
397
|
</div>
|
|
384
|
-
</div>
|
|
385
398
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
<div class="flex items-center gap-3">
|
|
393
|
-
<span class="font-mono text-xs text-indigo-700 bg-indigo-50 px-2 py-0.5 rounded" x-text="result.neuronId?.substring(0, 12) + '...'"></span>
|
|
394
|
-
<span
|
|
395
|
-
:class="result.score > 0.8 ? 'text-emerald-700 bg-emerald-50' : result.score > 0.5 ? 'text-amber-700 bg-amber-50' : 'text-gray-600 bg-gray-100'"
|
|
396
|
-
class="text-xs font-semibold px-2 py-0.5 rounded"
|
|
397
|
-
x-text="'Score: ' + (typeof result.score === 'number' ? result.score.toFixed(4) : result.score)"
|
|
398
|
-
></span>
|
|
399
|
-
</div>
|
|
400
|
-
<span class="text-xs text-gray-500" x-text="result.sourceType || ''"></span>
|
|
399
|
+
<!-- Graph Stats -->
|
|
400
|
+
<div class="grid grid-cols-1 sm:grid-cols-4 gap-4 mb-6">
|
|
401
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
402
|
+
<div class="flex items-center gap-3 mb-2">
|
|
403
|
+
<span class="material-icons-outlined text-md-primary">hub</span>
|
|
404
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Nodes</span>
|
|
401
405
|
</div>
|
|
402
|
-
<
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="graphData.stats?.nodeCount ?? 0"></p>
|
|
407
|
+
</div>
|
|
408
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
409
|
+
<div class="flex items-center gap-3 mb-2">
|
|
410
|
+
<span class="material-icons-outlined text-md-success">link</span>
|
|
411
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Edges</span>
|
|
406
412
|
</div>
|
|
407
|
-
<
|
|
408
|
-
|
|
413
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="graphData.stats?.edgeCount ?? 0"></p>
|
|
414
|
+
</div>
|
|
415
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
416
|
+
<div class="flex items-center gap-3 mb-2">
|
|
417
|
+
<span class="material-icons-outlined text-amber-500">analytics</span>
|
|
418
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Avg Connections</span>
|
|
409
419
|
</div>
|
|
420
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark"
|
|
421
|
+
x-text="graphData.stats?.nodeCount > 0 ? (graphData.stats?.edgeCount / graphData.stats?.nodeCount).toFixed(2) : '0'"></p>
|
|
410
422
|
</div>
|
|
411
|
-
|
|
412
|
-
|
|
423
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-5 shadow-md-1">
|
|
424
|
+
<div class="flex items-center gap-3 mb-2">
|
|
425
|
+
<span class="material-icons-outlined text-purple-500">category</span>
|
|
426
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Edge Types</span>
|
|
427
|
+
</div>
|
|
428
|
+
<p class="text-3xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="[...new Set((graphData.edges || []).map(e => e.type))].length"></p>
|
|
429
|
+
</div>
|
|
430
|
+
</div>
|
|
413
431
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
432
|
+
<!-- Graph Visualization -->
|
|
433
|
+
<div x-show="graphViewMode === 'graph'" class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
434
|
+
<div class="px-6 py-4 border-b border-md-outline dark:border-md-outline-dark flex items-center justify-between">
|
|
435
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark flex items-center gap-2">
|
|
436
|
+
<span class="material-icons-outlined text-md-primary">scatter_plot</span>
|
|
437
|
+
Interactive Graph
|
|
438
|
+
</h3>
|
|
439
|
+
<div class="flex items-center gap-4 text-xs text-gray-500">
|
|
440
|
+
<span class="flex items-center gap-1"><span class="w-3 h-3 rounded-full bg-md-primary"></span> Neurons</span>
|
|
441
|
+
<span class="flex items-center gap-1"><span class="w-8 h-0.5 bg-gray-400"></span> Synapses</span>
|
|
442
|
+
<span>Drag to move | Scroll to zoom</span>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
<div id="graph-container" class="relative" style="height: 500px;">
|
|
446
|
+
<svg id="graph-svg" class="w-full h-full"></svg>
|
|
447
|
+
<!-- Tooltip -->
|
|
448
|
+
<div id="graph-tooltip" class="absolute hidden bg-md-surface-dark text-white text-xs px-3 py-2 rounded-lg shadow-md-3 pointer-events-none z-10">
|
|
449
|
+
<p class="font-mono" id="tooltip-id"></p>
|
|
450
|
+
<p id="tooltip-label"></p>
|
|
451
|
+
</div>
|
|
452
|
+
<!-- Empty State -->
|
|
453
|
+
<div x-show="!graphData.nodes || graphData.nodes.length === 0" class="absolute inset-0 flex items-center justify-center">
|
|
454
|
+
<div class="text-center">
|
|
455
|
+
<span class="material-icons-outlined text-6xl text-gray-300 dark:text-gray-600">hub</span>
|
|
456
|
+
<p class="mt-4 text-gray-500 dark:text-gray-400">No graph data available</p>
|
|
457
|
+
<p class="text-sm text-gray-400 dark:text-gray-500">Ingest some content to see the knowledge graph</p>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
</div>
|
|
419
462
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
463
|
+
<!-- Table View -->
|
|
464
|
+
<div x-show="graphViewMode === 'table'" class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
465
|
+
<div class="px-6 py-4 border-b border-md-outline dark:border-md-outline-dark">
|
|
466
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark flex items-center gap-2">
|
|
467
|
+
<span class="material-icons-outlined text-md-primary">table_rows</span>
|
|
468
|
+
Edge List
|
|
469
|
+
</h3>
|
|
470
|
+
</div>
|
|
471
|
+
<div class="max-h-96 overflow-y-auto">
|
|
472
|
+
<table class="w-full">
|
|
473
|
+
<thead class="sticky top-0 bg-md-surface-variant dark:bg-md-surface-dark">
|
|
474
|
+
<tr class="border-b border-md-outline dark:border-md-outline-dark">
|
|
475
|
+
<th class="text-left text-xs font-medium text-gray-500 uppercase px-6 py-3">Source</th>
|
|
476
|
+
<th class="text-left text-xs font-medium text-gray-500 uppercase px-6 py-3">Target</th>
|
|
477
|
+
<th class="text-left text-xs font-medium text-gray-500 uppercase px-6 py-3">Type</th>
|
|
478
|
+
<th class="text-right text-xs font-medium text-gray-500 uppercase px-6 py-3">Weight</th>
|
|
479
|
+
</tr>
|
|
480
|
+
</thead>
|
|
481
|
+
<tbody class="divide-y divide-md-outline dark:divide-md-outline-dark">
|
|
482
|
+
<template x-for="(edge, i) in (graphData.edges || []).slice(0, 100)" :key="i">
|
|
483
|
+
<tr class="hover:bg-md-surface-variant dark:hover:bg-md-surface-dark">
|
|
484
|
+
<td class="px-6 py-3 font-mono text-sm text-md-primary dark:text-md-primary-light" x-text="edge.source?.substring(0, 12) + '...'"></td>
|
|
485
|
+
<td class="px-6 py-3 font-mono text-sm text-md-primary dark:text-md-primary-light" x-text="edge.target?.substring(0, 12) + '...'"></td>
|
|
486
|
+
<td class="px-6 py-3">
|
|
487
|
+
<span class="px-2 py-1 text-xs rounded-full bg-md-secondary/10 text-md-secondary" x-text="edge.type"></span>
|
|
488
|
+
</td>
|
|
489
|
+
<td class="px-6 py-3 text-right font-mono text-sm" x-text="edge.weight?.toFixed(4)"></td>
|
|
490
|
+
</tr>
|
|
491
|
+
</template>
|
|
492
|
+
<tr x-show="!graphData.edges || graphData.edges.length === 0">
|
|
493
|
+
<td colspan="4" class="px-6 py-8 text-center text-gray-500">No edges found</td>
|
|
494
|
+
</tr>
|
|
495
|
+
</tbody>
|
|
496
|
+
</table>
|
|
497
|
+
</div>
|
|
498
|
+
</div>
|
|
499
|
+
</section>
|
|
426
500
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
<section x-show="activeTab === 'ingest'" x-cloak>
|
|
431
|
-
<h2 class="text-base font-semibold text-gray-900 mb-4">Ingest Content</h2>
|
|
501
|
+
<!-- INFERENCE TAB -->
|
|
502
|
+
<section x-show="activeTab === 'inference'" x-cloak>
|
|
503
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark mb-6">Inference Engine</h2>
|
|
432
504
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
x-model="ingestText"
|
|
444
|
-
rows="10"
|
|
445
|
-
placeholder="Enter or paste text content to ingest..."
|
|
446
|
-
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition resize-y font-mono"
|
|
447
|
-
></textarea>
|
|
448
|
-
</div>
|
|
449
|
-
<div class="grid grid-cols-2 gap-3">
|
|
505
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
506
|
+
<!-- Input Form -->
|
|
507
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
508
|
+
<div class="px-6 py-4 bg-md-primary dark:bg-md-primary-dark">
|
|
509
|
+
<h3 class="text-lg font-medium text-white flex items-center gap-2">
|
|
510
|
+
<span class="material-icons-outlined">play_arrow</span>
|
|
511
|
+
Run Inference
|
|
512
|
+
</h3>
|
|
513
|
+
</div>
|
|
514
|
+
<div class="p-6 space-y-4">
|
|
450
515
|
<div>
|
|
451
|
-
<label class="text-
|
|
452
|
-
<input
|
|
453
|
-
|
|
454
|
-
x-model="ingestSourceType"
|
|
455
|
-
placeholder="dashboard"
|
|
456
|
-
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition"
|
|
457
|
-
>
|
|
516
|
+
<label class="text-sm font-medium text-md-on-surface dark:text-md-on-surface-dark block mb-2">Neuron ID</label>
|
|
517
|
+
<input type="text" x-model="inferNeuronId" placeholder="Enter neuron ID..."
|
|
518
|
+
class="w-full px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-lg text-sm font-mono focus:ring-2 focus:ring-md-primary focus:border-transparent outline-none transition-all">
|
|
458
519
|
</div>
|
|
459
|
-
<div>
|
|
460
|
-
<
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
520
|
+
<div class="grid grid-cols-2 gap-4">
|
|
521
|
+
<div>
|
|
522
|
+
<label class="text-sm font-medium text-md-on-surface dark:text-md-on-surface-dark block mb-2">Inference Type</label>
|
|
523
|
+
<select x-model="inferType" class="w-full px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-lg text-sm focus:ring-2 focus:ring-md-primary outline-none">
|
|
524
|
+
<option value="forward">Forward</option>
|
|
525
|
+
<option value="backward">Backward</option>
|
|
526
|
+
<option value="causal">Causal</option>
|
|
527
|
+
<option value="bidirectional">Bidirectional</option>
|
|
528
|
+
</select>
|
|
529
|
+
</div>
|
|
530
|
+
<div>
|
|
531
|
+
<label class="text-sm font-medium text-md-on-surface dark:text-md-on-surface-dark block mb-2">Depth</label>
|
|
532
|
+
<input type="number" x-model.number="inferDepth" min="1" max="10"
|
|
533
|
+
class="w-full px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-lg text-sm focus:ring-2 focus:ring-md-primary outline-none">
|
|
534
|
+
</div>
|
|
467
535
|
</div>
|
|
536
|
+
<button @click="runInference()" :disabled="inferring || !inferNeuronId"
|
|
537
|
+
class="w-full py-3 bg-md-primary text-white rounded-lg font-medium hover:bg-md-primary-dark disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 shadow-md-1 transition-all">
|
|
538
|
+
<span x-show="inferring" class="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
|
|
539
|
+
<span class="material-icons-outlined" x-show="!inferring">play_arrow</span>
|
|
540
|
+
Run Inference
|
|
541
|
+
</button>
|
|
468
542
|
</div>
|
|
469
|
-
<button
|
|
470
|
-
@click="doIngest()"
|
|
471
|
-
:disabled="ingesting || !ingestText.trim()"
|
|
472
|
-
class="w-full px-4 py-2.5 text-sm font-medium text-white bg-emerald-600 rounded-md hover:bg-emerald-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2"
|
|
473
|
-
>
|
|
474
|
-
<span x-show="ingesting" class="w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
|
|
475
|
-
<span x-text="ingesting ? 'Ingesting...' : 'Ingest'"></span>
|
|
476
|
-
</button>
|
|
477
543
|
</div>
|
|
478
|
-
</div>
|
|
479
544
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
545
|
+
<!-- Results -->
|
|
546
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
547
|
+
<div class="px-6 py-4 border-b border-md-outline dark:border-md-outline-dark">
|
|
548
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark flex items-center gap-2">
|
|
549
|
+
<span class="material-icons-outlined text-md-primary">insights</span>
|
|
550
|
+
Results
|
|
551
|
+
</h3>
|
|
552
|
+
</div>
|
|
553
|
+
<div class="p-6">
|
|
554
|
+
<div x-show="inferResults" class="space-y-4">
|
|
555
|
+
<div class="flex flex-wrap gap-4 text-sm">
|
|
556
|
+
<span class="px-3 py-1 bg-md-primary/10 text-md-primary rounded-full">Type: <span class="font-medium" x-text="inferResults?.type"></span></span>
|
|
557
|
+
<span class="px-3 py-1 bg-md-success/10 text-md-success rounded-full">Found: <span class="font-medium" x-text="inferResults?.totalFound"></span></span>
|
|
558
|
+
</div>
|
|
559
|
+
<div class="max-h-72 overflow-y-auto space-y-2">
|
|
560
|
+
<template x-for="(r, i) in (inferResults?.results || []).slice(0, 20)" :key="i">
|
|
561
|
+
<div class="flex items-center justify-between p-3 bg-md-surface-variant dark:bg-md-surface-dark rounded-lg">
|
|
562
|
+
<span class="font-mono text-sm text-md-primary dark:text-md-primary-light" x-text="r.id?.substring(0, 16) + '...'"></span>
|
|
563
|
+
<span class="text-xs px-2 py-1 bg-md-outline dark:bg-md-outline-dark rounded-full" x-text="'Depth: ' + r.distance"></span>
|
|
564
|
+
</div>
|
|
565
|
+
</template>
|
|
566
|
+
</div>
|
|
489
567
|
</div>
|
|
490
|
-
<div>
|
|
491
|
-
<
|
|
492
|
-
<p class="
|
|
568
|
+
<div x-show="!inferResults" class="text-center py-12">
|
|
569
|
+
<span class="material-icons-outlined text-6xl text-gray-300 dark:text-gray-600">timeline</span>
|
|
570
|
+
<p class="mt-4 text-gray-500 dark:text-gray-400">Run inference to see results</p>
|
|
493
571
|
</div>
|
|
494
|
-
|
|
572
|
+
</div>
|
|
573
|
+
</div>
|
|
574
|
+
</div>
|
|
575
|
+
</section>
|
|
576
|
+
|
|
577
|
+
<!-- ATTRACTORS TAB -->
|
|
578
|
+
<section x-show="activeTab === 'attractors'" x-cloak>
|
|
579
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark mb-6">Attractor Model</h2>
|
|
580
|
+
|
|
581
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 p-8">
|
|
582
|
+
<div class="text-center max-w-2xl mx-auto">
|
|
583
|
+
<span class="material-icons-outlined text-6xl text-md-primary mb-4">track_changes</span>
|
|
584
|
+
<h3 class="text-xl font-medium text-md-on-surface dark:text-md-on-surface-dark mb-2">Goal-Oriented Reasoning</h3>
|
|
585
|
+
<p class="text-gray-500 dark:text-gray-400 mb-6">Attractors define goal states that influence current decisions through probabilistic pathfinding.</p>
|
|
586
|
+
|
|
587
|
+
<div class="bg-md-surface-variant dark:bg-md-surface-dark rounded-xl p-6 text-left">
|
|
588
|
+
<h4 class="text-sm font-medium text-md-on-surface dark:text-md-on-surface-dark mb-4 flex items-center gap-2">
|
|
589
|
+
<span class="material-icons-outlined text-md-primary">terminal</span>
|
|
590
|
+
CLI Commands
|
|
591
|
+
</h4>
|
|
592
|
+
<div class="font-mono text-sm space-y-3">
|
|
495
593
|
<div>
|
|
496
|
-
<
|
|
497
|
-
<p class="text-
|
|
594
|
+
<p class="text-gray-500 dark:text-gray-400"># Create attractor</p>
|
|
595
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt attractor create "Goal Name" --strength 0.8</p>
|
|
498
596
|
</div>
|
|
499
597
|
<div>
|
|
500
|
-
<
|
|
501
|
-
<p class="text-
|
|
598
|
+
<p class="text-gray-500 dark:text-gray-400"># List all attractors</p>
|
|
599
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt attractor list</p>
|
|
502
600
|
</div>
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
601
|
+
<div>
|
|
602
|
+
<p class="text-gray-500 dark:text-gray-400"># Find path to goal</p>
|
|
603
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt attractor path <neuron-id> <attractor-id></p>
|
|
604
|
+
</div>
|
|
605
|
+
<div>
|
|
606
|
+
<p class="text-gray-500 dark:text-gray-400"># Calculate influence</p>
|
|
607
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt attractor influence <neuron-id></p>
|
|
510
608
|
</div>
|
|
511
609
|
</div>
|
|
512
610
|
</div>
|
|
513
611
|
</div>
|
|
612
|
+
</div>
|
|
613
|
+
</section>
|
|
614
|
+
|
|
615
|
+
<!-- LEARNING TAB -->
|
|
616
|
+
<section x-show="activeTab === 'learning'" x-cloak>
|
|
617
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark mb-6">Four-Stage Learning</h2>
|
|
514
618
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
<
|
|
619
|
+
<!-- Pipeline Steps -->
|
|
620
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
|
621
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-6 shadow-md-1 text-center">
|
|
622
|
+
<div class="w-14 h-14 bg-blue-100 dark:bg-blue-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
|
|
623
|
+
<span class="material-icons-outlined text-blue-600 dark:text-blue-400 text-2xl">search</span>
|
|
624
|
+
</div>
|
|
625
|
+
<h4 class="font-medium text-md-on-surface dark:text-md-on-surface-dark">1. Extract</h4>
|
|
626
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Identify information</p>
|
|
519
627
|
</div>
|
|
628
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-6 shadow-md-1 text-center">
|
|
629
|
+
<div class="w-14 h-14 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
|
|
630
|
+
<span class="material-icons-outlined text-green-600 dark:text-green-400 text-2xl">pattern</span>
|
|
631
|
+
</div>
|
|
632
|
+
<h4 class="font-medium text-md-on-surface dark:text-md-on-surface-dark">2. Pattern</h4>
|
|
633
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Recognize patterns</p>
|
|
634
|
+
</div>
|
|
635
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-6 shadow-md-1 text-center">
|
|
636
|
+
<div class="w-14 h-14 bg-amber-100 dark:bg-amber-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
|
|
637
|
+
<span class="material-icons-outlined text-amber-600 dark:text-amber-400 text-2xl">memory</span>
|
|
638
|
+
</div>
|
|
639
|
+
<h4 class="font-medium text-md-on-surface dark:text-md-on-surface-dark">3. Process</h4>
|
|
640
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Learn reasoning</p>
|
|
641
|
+
</div>
|
|
642
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl p-6 shadow-md-1 text-center">
|
|
643
|
+
<div class="w-14 h-14 bg-purple-100 dark:bg-purple-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
|
|
644
|
+
<span class="material-icons-outlined text-purple-600 dark:text-purple-400 text-2xl">check_circle</span>
|
|
645
|
+
</div>
|
|
646
|
+
<h4 class="font-medium text-md-on-surface dark:text-md-on-surface-dark">4. Outcome</h4>
|
|
647
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Apply feedback</p>
|
|
648
|
+
</div>
|
|
649
|
+
</div>
|
|
520
650
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
651
|
+
<!-- CLI Commands -->
|
|
652
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 p-6">
|
|
653
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark mb-4 flex items-center gap-2">
|
|
654
|
+
<span class="material-icons-outlined text-md-primary">terminal</span>
|
|
655
|
+
CLI Commands
|
|
656
|
+
</h3>
|
|
657
|
+
<div class="bg-md-surface-variant dark:bg-md-surface-dark rounded-lg p-4 font-mono text-sm space-y-3">
|
|
658
|
+
<div>
|
|
659
|
+
<p class="text-gray-500 dark:text-gray-400"># Start learning session</p>
|
|
660
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt learn session start</p>
|
|
661
|
+
</div>
|
|
662
|
+
<div>
|
|
663
|
+
<p class="text-gray-500 dark:text-gray-400"># Extract from neuron</p>
|
|
664
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt learn extract <neuron-id> --limit 20</p>
|
|
665
|
+
</div>
|
|
666
|
+
<div>
|
|
667
|
+
<p class="text-gray-500 dark:text-gray-400"># Full learning pipeline</p>
|
|
668
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt orchestrate learn --input "Q" --output "A" --success</p>
|
|
669
|
+
</div>
|
|
524
670
|
</div>
|
|
525
671
|
</div>
|
|
526
|
-
</
|
|
527
|
-
</section>
|
|
672
|
+
</section>
|
|
528
673
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
674
|
+
<!-- SYNC TAB -->
|
|
675
|
+
<section x-show="activeTab === 'sync'" x-cloak>
|
|
676
|
+
<div class="flex items-center justify-between mb-6">
|
|
677
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark">State Synchronization</h2>
|
|
678
|
+
<button @click="loadSyncStatus()" class="flex items-center gap-2 px-4 py-2 bg-md-primary text-white rounded-full text-sm font-medium hover:bg-md-primary-dark shadow-md-1">
|
|
679
|
+
<span class="material-icons-outlined text-xl">refresh</span>
|
|
680
|
+
Refresh Status
|
|
681
|
+
</button>
|
|
682
|
+
</div>
|
|
534
683
|
|
|
535
|
-
|
|
684
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
685
|
+
<!-- Current State -->
|
|
686
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
687
|
+
<div class="px-6 py-4 bg-md-primary dark:bg-md-primary-dark">
|
|
688
|
+
<h3 class="text-lg font-medium text-white flex items-center gap-2">
|
|
689
|
+
<span class="material-icons-outlined">sync</span>
|
|
690
|
+
Current State
|
|
691
|
+
</h3>
|
|
692
|
+
</div>
|
|
693
|
+
<div class="p-6 space-y-4">
|
|
694
|
+
<div class="flex justify-between items-center py-2 border-b border-md-outline dark:border-md-outline-dark">
|
|
695
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Node ID</span>
|
|
696
|
+
<span class="font-mono text-sm text-md-on-surface dark:text-md-on-surface-dark" x-text="syncStatus?.nodeId ?? '--'"></span>
|
|
697
|
+
</div>
|
|
698
|
+
<div class="flex justify-between items-center py-2 border-b border-md-outline dark:border-md-outline-dark">
|
|
699
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Sequence</span>
|
|
700
|
+
<span class="font-mono text-sm text-md-on-surface dark:text-md-on-surface-dark" x-text="syncStatus?.sequence ?? 0"></span>
|
|
701
|
+
</div>
|
|
702
|
+
<div class="flex justify-between items-center py-2 border-b border-md-outline dark:border-md-outline-dark">
|
|
703
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Neurons</span>
|
|
704
|
+
<span class="font-mono text-sm text-md-on-surface dark:text-md-on-surface-dark" x-text="syncStatus?.neuronCount ?? 0"></span>
|
|
705
|
+
</div>
|
|
706
|
+
<div class="flex justify-between items-center py-2">
|
|
707
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">Peers</span>
|
|
708
|
+
<span class="font-mono text-sm text-md-on-surface dark:text-md-on-surface-dark" x-text="syncStatus?.peers?.length ?? 0"></span>
|
|
709
|
+
</div>
|
|
710
|
+
</div>
|
|
711
|
+
</div>
|
|
536
712
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
713
|
+
<!-- CLI Commands -->
|
|
714
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 p-6">
|
|
715
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark mb-4 flex items-center gap-2">
|
|
716
|
+
<span class="material-icons-outlined text-md-primary">terminal</span>
|
|
717
|
+
CLI Commands
|
|
718
|
+
</h3>
|
|
719
|
+
<div class="bg-md-surface-variant dark:bg-md-surface-dark rounded-lg p-4 font-mono text-sm space-y-3">
|
|
720
|
+
<div>
|
|
721
|
+
<p class="text-gray-500 dark:text-gray-400"># Check sync status</p>
|
|
722
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt sync status</p>
|
|
723
|
+
</div>
|
|
724
|
+
<div>
|
|
725
|
+
<p class="text-gray-500 dark:text-gray-400"># View change log</p>
|
|
726
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt sync changes --from 0</p>
|
|
727
|
+
</div>
|
|
728
|
+
<div>
|
|
729
|
+
<p class="text-gray-500 dark:text-gray-400"># Export state</p>
|
|
730
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt sync export --output backup.json</p>
|
|
731
|
+
</div>
|
|
732
|
+
<div>
|
|
733
|
+
<p class="text-gray-500 dark:text-gray-400"># Import state</p>
|
|
734
|
+
<p class="text-md-primary dark:text-md-primary-light">nmt sync import backup.json</p>
|
|
735
|
+
</div>
|
|
736
|
+
</div>
|
|
549
737
|
</div>
|
|
738
|
+
</div>
|
|
739
|
+
</section>
|
|
550
740
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
</span>
|
|
564
|
-
</div>
|
|
565
|
-
<!-- Results Table -->
|
|
566
|
-
<div class="max-h-80 overflow-y-auto">
|
|
567
|
-
<table class="w-full text-sm">
|
|
568
|
-
<thead class="sticky top-0 bg-white">
|
|
569
|
-
<tr class="border-b border-gray-100">
|
|
570
|
-
<th class="text-left text-xs font-semibold text-gray-600 px-4 py-2">Neuron ID</th>
|
|
571
|
-
<th class="text-center text-xs font-semibold text-gray-600 px-4 py-2">Status</th>
|
|
572
|
-
<th class="text-left text-xs font-semibold text-gray-600 px-4 py-2">Errors</th>
|
|
573
|
-
</tr>
|
|
574
|
-
</thead>
|
|
575
|
-
<tbody>
|
|
576
|
-
<template x-for="(r, idx) in (verifyAllResult?.results || [])" :key="idx">
|
|
577
|
-
<tr class="border-b border-gray-50">
|
|
578
|
-
<td class="px-4 py-2 font-mono text-xs text-gray-700" x-text="r.neuronId?.substring(0, 12) + '...'"></td>
|
|
579
|
-
<td class="px-4 py-2 text-center">
|
|
580
|
-
<span x-show="r.valid" class="inline-block w-5 h-5 text-xs leading-5 text-center text-emerald-700 bg-emerald-100 rounded-full font-bold">OK</span>
|
|
581
|
-
<span x-show="!r.valid" class="inline-block w-5 h-5 text-xs leading-5 text-center text-red-700 bg-red-100 rounded-full font-bold">!</span>
|
|
582
|
-
</td>
|
|
583
|
-
<td class="px-4 py-2 text-xs text-red-600" x-text="r.errors?.join(', ') || '--'"></td>
|
|
584
|
-
</tr>
|
|
585
|
-
</template>
|
|
586
|
-
</tbody>
|
|
587
|
-
</table>
|
|
741
|
+
<!-- SEARCH TAB -->
|
|
742
|
+
<section x-show="activeTab === 'search'" x-cloak>
|
|
743
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark mb-6">Semantic Search</h2>
|
|
744
|
+
|
|
745
|
+
<!-- Search Box -->
|
|
746
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 p-6 mb-6">
|
|
747
|
+
<div class="flex flex-col sm:flex-row gap-4">
|
|
748
|
+
<div class="flex-1 relative">
|
|
749
|
+
<span class="material-icons-outlined absolute left-4 top-1/2 -translate-y-1/2 text-gray-400">search</span>
|
|
750
|
+
<input type="text" x-model="searchQuery" @keydown.enter="doSearch()"
|
|
751
|
+
placeholder="Enter your search query..."
|
|
752
|
+
class="w-full pl-12 pr-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-full text-sm focus:ring-2 focus:ring-md-primary focus:border-transparent outline-none transition-all">
|
|
588
753
|
</div>
|
|
589
|
-
<div
|
|
590
|
-
<
|
|
754
|
+
<div class="flex gap-3">
|
|
755
|
+
<input type="number" x-model.number="searchK" min="1" max="100" placeholder="K"
|
|
756
|
+
class="w-20 px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-full text-sm text-center focus:ring-2 focus:ring-md-primary outline-none">
|
|
757
|
+
<label class="flex items-center gap-2 px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-full text-sm cursor-pointer">
|
|
758
|
+
<input type="checkbox" x-model="searchIncludeContent" class="rounded text-md-primary focus:ring-md-primary">
|
|
759
|
+
<span class="text-md-on-surface dark:text-md-on-surface-dark">Content</span>
|
|
760
|
+
</label>
|
|
761
|
+
<button @click="doSearch()" :disabled="searching || !searchQuery"
|
|
762
|
+
class="px-6 py-3 bg-md-primary text-white rounded-full font-medium hover:bg-md-primary-dark disabled:opacity-50 shadow-md-1 flex items-center gap-2 transition-all">
|
|
763
|
+
<span x-show="searching" class="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
|
|
764
|
+
<span class="material-icons-outlined" x-show="!searching">search</span>
|
|
765
|
+
Search
|
|
766
|
+
</button>
|
|
591
767
|
</div>
|
|
592
768
|
</div>
|
|
593
769
|
</div>
|
|
594
770
|
|
|
595
|
-
<!--
|
|
771
|
+
<!-- Results -->
|
|
596
772
|
<div class="space-y-4">
|
|
597
|
-
<
|
|
598
|
-
<
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
>
|
|
607
|
-
<button
|
|
608
|
-
@click="doVerifySingle()"
|
|
609
|
-
:disabled="verifySingleLoading || !verifyNeuronId.trim()"
|
|
610
|
-
class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2"
|
|
611
|
-
>
|
|
612
|
-
<span x-show="verifySingleLoading" class="w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
|
|
613
|
-
Verify
|
|
614
|
-
</button>
|
|
773
|
+
<template x-for="(r, i) in searchResults" :key="i">
|
|
774
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 p-5 hover:shadow-md-2 transition-shadow">
|
|
775
|
+
<div class="flex items-center gap-4 mb-3">
|
|
776
|
+
<span class="font-mono text-sm px-3 py-1 bg-md-primary/10 text-md-primary dark:bg-md-primary/20 dark:text-md-primary-light rounded-full" x-text="r.neuronId?.substring(0, 16) + '...'"></span>
|
|
777
|
+
<span class="text-sm font-medium px-3 py-1 rounded-full"
|
|
778
|
+
:class="r.score > 0.8 ? 'bg-md-success/10 text-md-success' : r.score > 0.5 ? 'bg-amber-500/10 text-amber-600' : 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300'"
|
|
779
|
+
x-text="'Score: ' + r.score?.toFixed(4)"></span>
|
|
780
|
+
</div>
|
|
781
|
+
<pre x-show="r.content" class="bg-md-surface-variant dark:bg-md-surface-dark rounded-lg p-4 text-sm font-mono text-md-on-surface dark:text-md-on-surface-dark whitespace-pre-wrap max-h-40 overflow-y-auto" x-text="r.content"></pre>
|
|
615
782
|
</div>
|
|
783
|
+
</template>
|
|
784
|
+
<div x-show="searchResults.length === 0 && !searching" class="text-center py-12">
|
|
785
|
+
<span class="material-icons-outlined text-6xl text-gray-300 dark:text-gray-600">manage_search</span>
|
|
786
|
+
<p class="mt-4 text-gray-500 dark:text-gray-400">Enter a query to search</p>
|
|
616
787
|
</div>
|
|
788
|
+
</div>
|
|
789
|
+
</section>
|
|
617
790
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
791
|
+
<!-- INGEST TAB -->
|
|
792
|
+
<section x-show="activeTab === 'ingest'" x-cloak>
|
|
793
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark mb-6">Ingest Content</h2>
|
|
794
|
+
|
|
795
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
796
|
+
<!-- Input Form -->
|
|
797
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
798
|
+
<div class="px-6 py-4 bg-md-success dark:bg-green-800">
|
|
799
|
+
<h3 class="text-lg font-medium text-white flex items-center gap-2">
|
|
800
|
+
<span class="material-icons-outlined">upload_file</span>
|
|
801
|
+
Add Content
|
|
802
|
+
</h3>
|
|
803
|
+
</div>
|
|
804
|
+
<div class="p-6 space-y-4">
|
|
805
|
+
<div>
|
|
806
|
+
<label class="text-sm font-medium text-md-on-surface dark:text-md-on-surface-dark block mb-2">Text Content</label>
|
|
807
|
+
<textarea x-model="ingestText" rows="8" placeholder="Paste or type text to ingest..."
|
|
808
|
+
class="w-full px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-lg text-sm font-mono resize-y focus:ring-2 focus:ring-md-primary focus:border-transparent outline-none transition-all"></textarea>
|
|
630
809
|
</div>
|
|
631
|
-
<div class="
|
|
810
|
+
<div class="grid grid-cols-2 gap-4">
|
|
632
811
|
<div>
|
|
633
|
-
<label class="text-
|
|
634
|
-
<
|
|
812
|
+
<label class="text-sm font-medium text-md-on-surface dark:text-md-on-surface-dark block mb-2">Source Type</label>
|
|
813
|
+
<input type="text" x-model="ingestSourceType" placeholder="dashboard"
|
|
814
|
+
class="w-full px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-lg text-sm focus:ring-2 focus:ring-md-primary outline-none">
|
|
635
815
|
</div>
|
|
636
816
|
<div>
|
|
637
|
-
<label class="text-
|
|
638
|
-
<
|
|
817
|
+
<label class="text-sm font-medium text-md-on-surface dark:text-md-on-surface-dark block mb-2">Tags (comma-separated)</label>
|
|
818
|
+
<input type="text" x-model="ingestTags" placeholder="tag1, tag2, tag3"
|
|
819
|
+
class="w-full px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-lg text-sm focus:ring-2 focus:ring-md-primary outline-none">
|
|
639
820
|
</div>
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
821
|
+
</div>
|
|
822
|
+
<button @click="doIngest()" :disabled="ingesting || !ingestText"
|
|
823
|
+
class="w-full py-3 bg-md-success text-white rounded-lg font-medium hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 shadow-md-1 transition-all">
|
|
824
|
+
<span x-show="ingesting" class="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
|
|
825
|
+
<span class="material-icons-outlined" x-show="!ingesting">upload</span>
|
|
826
|
+
<span x-text="ingesting ? 'Ingesting...' : 'Ingest Content'"></span>
|
|
827
|
+
</button>
|
|
828
|
+
</div>
|
|
829
|
+
</div>
|
|
830
|
+
|
|
831
|
+
<!-- Result -->
|
|
832
|
+
<div class="space-y-4">
|
|
833
|
+
<div x-show="ingestResult" class="card bg-md-success/10 dark:bg-md-success/20 border border-md-success/30 rounded-xl p-6">
|
|
834
|
+
<div class="flex items-center gap-3 mb-4">
|
|
835
|
+
<span class="material-icons-outlined text-md-success text-3xl">check_circle</span>
|
|
836
|
+
<h3 class="text-lg font-medium text-md-success">Success!</h3>
|
|
837
|
+
</div>
|
|
838
|
+
<div class="space-y-2 font-mono text-sm">
|
|
839
|
+
<p class="text-md-on-surface dark:text-md-on-surface-dark"><span class="text-gray-500">ID:</span> <span x-text="ingestResult?.neuronId"></span></p>
|
|
840
|
+
<p class="text-md-on-surface dark:text-md-on-surface-dark"><span class="text-gray-500">Chunks:</span> <span x-text="ingestResult?.chunks"></span></p>
|
|
841
|
+
</div>
|
|
842
|
+
</div>
|
|
843
|
+
<div x-show="ingestError" class="card bg-md-error/10 dark:bg-md-error/20 border border-md-error/30 rounded-xl p-6">
|
|
844
|
+
<div class="flex items-center gap-3 mb-2">
|
|
845
|
+
<span class="material-icons-outlined text-md-error text-3xl">error</span>
|
|
846
|
+
<h3 class="text-lg font-medium text-md-error">Error</h3>
|
|
847
|
+
</div>
|
|
848
|
+
<p class="text-sm text-md-error" x-text="ingestError"></p>
|
|
849
|
+
</div>
|
|
850
|
+
</div>
|
|
851
|
+
</div>
|
|
852
|
+
</section>
|
|
853
|
+
|
|
854
|
+
<!-- VERIFY TAB -->
|
|
855
|
+
<section x-show="activeTab === 'verify'" x-cloak>
|
|
856
|
+
<h2 class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark mb-6">Data Integrity</h2>
|
|
857
|
+
|
|
858
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
859
|
+
<!-- Verify All -->
|
|
860
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
861
|
+
<div class="px-6 py-4 border-b border-md-outline dark:border-md-outline-dark">
|
|
862
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark flex items-center gap-2">
|
|
863
|
+
<span class="material-icons-outlined text-md-primary">verified</span>
|
|
864
|
+
Verify All Neurons
|
|
865
|
+
</h3>
|
|
866
|
+
</div>
|
|
867
|
+
<div class="p-6">
|
|
868
|
+
<button @click="doVerifyAll()" :disabled="verifying"
|
|
869
|
+
class="w-full py-3 bg-md-primary text-white rounded-lg font-medium hover:bg-md-primary-dark disabled:opacity-50 flex items-center justify-center gap-2 shadow-md-1 transition-all">
|
|
870
|
+
<span x-show="verifying" class="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
|
|
871
|
+
<span class="material-icons-outlined" x-show="!verifying">verified_user</span>
|
|
872
|
+
<span x-text="verifying ? 'Verifying...' : 'Run Verification'"></span>
|
|
873
|
+
</button>
|
|
874
|
+
|
|
875
|
+
<div x-show="verifyAllResult" class="mt-6 grid grid-cols-3 gap-4">
|
|
876
|
+
<div class="text-center p-4 bg-md-surface-variant dark:bg-md-surface-dark rounded-lg">
|
|
877
|
+
<p class="text-2xl font-medium text-md-on-surface dark:text-md-on-surface-dark" x-text="verifyAllResult?.total"></p>
|
|
878
|
+
<p class="text-xs text-gray-500 mt-1">Total</p>
|
|
657
879
|
</div>
|
|
658
|
-
<div
|
|
659
|
-
<
|
|
660
|
-
<
|
|
661
|
-
|
|
662
|
-
|
|
880
|
+
<div class="text-center p-4 bg-md-success/10 dark:bg-md-success/20 rounded-lg">
|
|
881
|
+
<p class="text-2xl font-medium text-md-success" x-text="verifyAllResult?.valid"></p>
|
|
882
|
+
<p class="text-xs text-md-success mt-1">Valid</p>
|
|
883
|
+
</div>
|
|
884
|
+
<div class="text-center p-4 bg-md-error/10 dark:bg-md-error/20 rounded-lg">
|
|
885
|
+
<p class="text-2xl font-medium text-md-error" x-text="verifyAllResult?.invalid"></p>
|
|
886
|
+
<p class="text-xs text-md-error mt-1">Invalid</p>
|
|
663
887
|
</div>
|
|
664
888
|
</div>
|
|
665
889
|
</div>
|
|
666
890
|
</div>
|
|
667
891
|
|
|
668
|
-
<!-- Verify
|
|
669
|
-
<div
|
|
670
|
-
<
|
|
671
|
-
|
|
672
|
-
|
|
892
|
+
<!-- Verify Single -->
|
|
893
|
+
<div class="card bg-md-surface dark:bg-md-surface-variant-dark rounded-xl shadow-md-1 overflow-hidden">
|
|
894
|
+
<div class="px-6 py-4 border-b border-md-outline dark:border-md-outline-dark">
|
|
895
|
+
<h3 class="text-lg font-medium text-md-on-surface dark:text-md-on-surface-dark flex items-center gap-2">
|
|
896
|
+
<span class="material-icons-outlined text-md-primary">fact_check</span>
|
|
897
|
+
Verify Single Neuron
|
|
898
|
+
</h3>
|
|
899
|
+
</div>
|
|
900
|
+
<div class="p-6">
|
|
901
|
+
<div class="flex gap-3">
|
|
902
|
+
<input type="text" x-model="verifyNeuronId" placeholder="Enter neuron ID..."
|
|
903
|
+
class="flex-1 px-4 py-3 bg-md-surface-variant dark:bg-md-surface-dark border border-md-outline dark:border-md-outline-dark rounded-lg text-sm font-mono focus:ring-2 focus:ring-md-primary outline-none">
|
|
904
|
+
<button @click="doVerifySingle()" :disabled="verifySingleLoading || !verifyNeuronId"
|
|
905
|
+
class="px-6 py-3 bg-md-primary text-white rounded-lg font-medium hover:bg-md-primary-dark disabled:opacity-50 shadow-md-1 transition-all">
|
|
906
|
+
Verify
|
|
907
|
+
</button>
|
|
908
|
+
</div>
|
|
673
909
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
910
|
+
<div x-show="verifySingleResult" class="mt-6">
|
|
911
|
+
<div :class="verifySingleResult?.valid ? 'bg-md-success/10 border-md-success/30' : 'bg-md-error/10 border-md-error/30'"
|
|
912
|
+
class="border rounded-lg p-4 flex items-center gap-3">
|
|
913
|
+
<span class="material-icons-outlined text-3xl" :class="verifySingleResult?.valid ? 'text-md-success' : 'text-md-error'"
|
|
914
|
+
x-text="verifySingleResult?.valid ? 'check_circle' : 'cancel'"></span>
|
|
915
|
+
<div>
|
|
916
|
+
<p class="font-medium" :class="verifySingleResult?.valid ? 'text-md-success' : 'text-md-error'"
|
|
917
|
+
x-text="verifySingleResult?.valid ? 'Valid' : 'Invalid'"></p>
|
|
918
|
+
<p class="text-sm text-gray-500">Merkle proof verification complete</p>
|
|
919
|
+
</div>
|
|
920
|
+
</div>
|
|
921
|
+
</div>
|
|
922
|
+
</div>
|
|
677
923
|
</div>
|
|
678
924
|
</div>
|
|
679
|
-
</
|
|
680
|
-
</section>
|
|
925
|
+
</section>
|
|
681
926
|
|
|
927
|
+
</div>
|
|
682
928
|
</main>
|
|
683
929
|
|
|
930
|
+
<!-- Overlay for mobile sidebar -->
|
|
931
|
+
<div x-show="sidebarOpen" x-cloak
|
|
932
|
+
@click="sidebarOpen = false"
|
|
933
|
+
class="fixed inset-0 bg-black/50 z-30 lg:hidden transition-opacity"></div>
|
|
934
|
+
|
|
684
935
|
<script>
|
|
685
936
|
function dashboard() {
|
|
686
937
|
return {
|
|
938
|
+
// Theme
|
|
939
|
+
darkMode: localStorage.getItem('darkMode') === 'true',
|
|
940
|
+
|
|
687
941
|
// Navigation
|
|
942
|
+
sidebarOpen: window.innerWidth >= 1024,
|
|
688
943
|
activeTab: 'overview',
|
|
689
|
-
|
|
690
|
-
{ id: 'overview', label: 'Overview' },
|
|
691
|
-
{ id: 'neurons', label: 'Neurons' },
|
|
692
|
-
{ id: '
|
|
693
|
-
{ id: '
|
|
694
|
-
{ id: '
|
|
944
|
+
navItems: [
|
|
945
|
+
{ id: 'overview', label: 'Overview', icon: 'dashboard' },
|
|
946
|
+
{ id: 'neurons', label: 'Neurons', icon: 'psychology' },
|
|
947
|
+
{ id: 'graph', label: 'Graph', icon: 'hub' },
|
|
948
|
+
{ id: 'inference', label: 'Inference', icon: 'timeline' },
|
|
949
|
+
{ id: 'attractors', label: 'Attractors', icon: 'track_changes' },
|
|
950
|
+
{ id: 'learning', label: 'Learning', icon: 'school' },
|
|
951
|
+
{ id: 'sync', label: 'Sync', icon: 'sync' },
|
|
952
|
+
{ id: 'search', label: 'Search', icon: 'search' },
|
|
953
|
+
{ id: 'ingest', label: 'Ingest', icon: 'upload_file' },
|
|
954
|
+
{ id: 'verify', label: 'Verify', icon: 'verified' },
|
|
695
955
|
],
|
|
696
956
|
|
|
697
957
|
// Connection
|
|
698
958
|
connected: false,
|
|
959
|
+
refreshing: false,
|
|
699
960
|
lastRefresh: '',
|
|
961
|
+
globalSearch: '',
|
|
700
962
|
|
|
701
|
-
//
|
|
963
|
+
// Data
|
|
702
964
|
stats: {},
|
|
703
|
-
|
|
704
|
-
// Neurons
|
|
965
|
+
recentNeurons: [],
|
|
705
966
|
neurons: [],
|
|
706
967
|
neuronTotal: 0,
|
|
707
968
|
neuronPage: 0,
|
|
708
|
-
neuronLimit:
|
|
969
|
+
neuronLimit: 20,
|
|
709
970
|
neuronsLoading: false,
|
|
710
971
|
selectedNeuron: null,
|
|
711
972
|
selectedContent: '',
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
973
|
+
|
|
974
|
+
// Graph
|
|
975
|
+
graphData: { nodes: [], edges: [], stats: {} },
|
|
976
|
+
graphViewMode: 'graph',
|
|
977
|
+
graphSimulation: null,
|
|
978
|
+
|
|
979
|
+
// Inference
|
|
980
|
+
inferNeuronId: '',
|
|
981
|
+
inferType: 'forward',
|
|
982
|
+
inferDepth: 3,
|
|
983
|
+
inferring: false,
|
|
984
|
+
inferResults: null,
|
|
985
|
+
|
|
986
|
+
// Sync
|
|
987
|
+
syncStatus: null,
|
|
715
988
|
|
|
716
989
|
// Search
|
|
717
990
|
searchQuery: '',
|
|
@@ -719,8 +992,6 @@
|
|
|
719
992
|
searchIncludeContent: true,
|
|
720
993
|
searchResults: [],
|
|
721
994
|
searching: false,
|
|
722
|
-
searchPerformed: false,
|
|
723
|
-
searchError: null,
|
|
724
995
|
|
|
725
996
|
// Ingest
|
|
726
997
|
ingestText: '',
|
|
@@ -736,267 +1007,317 @@
|
|
|
736
1007
|
verifyNeuronId: '',
|
|
737
1008
|
verifySingleResult: null,
|
|
738
1009
|
verifySingleLoading: false,
|
|
739
|
-
verifySingleError: null,
|
|
740
1010
|
|
|
741
|
-
// Auto-refresh interval
|
|
742
|
-
_refreshInterval: null,
|
|
743
|
-
|
|
744
|
-
// --------------------------------------------------------
|
|
745
|
-
// Initialization
|
|
746
|
-
// --------------------------------------------------------
|
|
747
1011
|
async init() {
|
|
748
1012
|
await this.checkHealth();
|
|
749
1013
|
await this.loadStats();
|
|
750
|
-
this.
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
1014
|
+
await this.loadRecentNeurons();
|
|
1015
|
+
setInterval(() => { if (this.activeTab === 'overview') this.loadStats(); }, 30000);
|
|
1016
|
+
|
|
1017
|
+
window.addEventListener('resize', () => {
|
|
1018
|
+
this.sidebarOpen = window.innerWidth >= 1024;
|
|
1019
|
+
});
|
|
755
1020
|
},
|
|
756
1021
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1022
|
+
toggleDarkMode() {
|
|
1023
|
+
this.darkMode = !this.darkMode;
|
|
1024
|
+
localStorage.setItem('darkMode', this.darkMode);
|
|
1025
|
+
},
|
|
1026
|
+
|
|
1027
|
+
async refreshAll() {
|
|
1028
|
+
this.refreshing = true;
|
|
1029
|
+
await this.loadStats();
|
|
1030
|
+
await this.loadRecentNeurons();
|
|
1031
|
+
this.refreshing = false;
|
|
1032
|
+
},
|
|
1033
|
+
|
|
1034
|
+
switchTab(id) {
|
|
1035
|
+
this.activeTab = id;
|
|
1036
|
+
if (id === 'overview') { this.loadStats(); this.loadRecentNeurons(); }
|
|
1037
|
+
else if (id === 'neurons') this.loadNeurons();
|
|
1038
|
+
else if (id === 'graph') { this.loadGraph().then(() => setTimeout(() => this.renderGraph(), 100)); }
|
|
1039
|
+
else if (id === 'sync') this.loadSyncStatus();
|
|
767
1040
|
},
|
|
768
1041
|
|
|
769
|
-
// --------------------------------------------------------
|
|
770
|
-
// API Helper
|
|
771
|
-
// --------------------------------------------------------
|
|
772
1042
|
async api(method, path, body) {
|
|
773
|
-
const opts = {
|
|
774
|
-
|
|
775
|
-
headers: { 'Content-Type': 'application/json' },
|
|
776
|
-
};
|
|
777
|
-
if (body) {
|
|
778
|
-
opts.body = JSON.stringify(body);
|
|
779
|
-
}
|
|
1043
|
+
const opts = { method, headers: { 'Content-Type': 'application/json' } };
|
|
1044
|
+
if (body) opts.body = JSON.stringify(body);
|
|
780
1045
|
try {
|
|
781
1046
|
const res = await fetch('/api/v1' + path, opts);
|
|
782
|
-
if (!res.ok) {
|
|
783
|
-
const errBody = await res.json().catch(() => ({}));
|
|
784
|
-
throw new Error(errBody.error || errBody.message || `HTTP ${res.status}`);
|
|
785
|
-
}
|
|
1047
|
+
if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || `HTTP ${res.status}`);
|
|
786
1048
|
this.connected = true;
|
|
787
1049
|
return await res.json();
|
|
788
1050
|
} catch (err) {
|
|
789
|
-
if (err.message
|
|
790
|
-
this.connected = false;
|
|
791
|
-
}
|
|
1051
|
+
if (err.message.includes('fetch')) this.connected = false;
|
|
792
1052
|
throw err;
|
|
793
1053
|
}
|
|
794
1054
|
},
|
|
795
1055
|
|
|
796
|
-
|
|
797
|
-
// Health & Stats
|
|
798
|
-
// --------------------------------------------------------
|
|
799
|
-
async checkHealth() {
|
|
800
|
-
try {
|
|
801
|
-
await this.api('GET', '/health');
|
|
802
|
-
this.connected = true;
|
|
803
|
-
} catch {
|
|
804
|
-
this.connected = false;
|
|
805
|
-
}
|
|
806
|
-
},
|
|
1056
|
+
async checkHealth() { try { await this.api('GET', '/health'); this.connected = true; } catch { this.connected = false; } },
|
|
807
1057
|
|
|
808
1058
|
async loadStats() {
|
|
809
1059
|
try {
|
|
810
1060
|
this.stats = await this.api('GET', '/stats');
|
|
811
1061
|
this.lastRefresh = new Date().toLocaleTimeString();
|
|
812
|
-
} catch {
|
|
813
|
-
|
|
814
|
-
|
|
1062
|
+
} catch {}
|
|
1063
|
+
},
|
|
1064
|
+
|
|
1065
|
+
async loadRecentNeurons() {
|
|
1066
|
+
try {
|
|
1067
|
+
const d = await this.api('GET', '/neurons?limit=5&offset=0');
|
|
1068
|
+
this.recentNeurons = d.neurons || [];
|
|
1069
|
+
} catch { this.recentNeurons = []; }
|
|
815
1070
|
},
|
|
816
1071
|
|
|
817
|
-
// --------------------------------------------------------
|
|
818
|
-
// Neurons
|
|
819
|
-
// --------------------------------------------------------
|
|
820
1072
|
async loadNeurons() {
|
|
821
1073
|
this.neuronsLoading = true;
|
|
822
1074
|
try {
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
this.
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
this.neurons = [];
|
|
829
|
-
} finally {
|
|
830
|
-
this.neuronsLoading = false;
|
|
831
|
-
}
|
|
1075
|
+
const d = await this.api('GET', `/neurons?limit=${this.neuronLimit}&offset=${this.neuronPage * this.neuronLimit}`);
|
|
1076
|
+
this.neurons = d.neurons || [];
|
|
1077
|
+
this.neuronTotal = d.total || 0;
|
|
1078
|
+
} catch { this.neurons = []; }
|
|
1079
|
+
this.neuronsLoading = false;
|
|
832
1080
|
},
|
|
833
1081
|
|
|
834
|
-
async selectNeuron(
|
|
835
|
-
this.
|
|
836
|
-
this.selectedContent = '';
|
|
837
|
-
this.contentLoading = true;
|
|
1082
|
+
async selectNeuron(n) {
|
|
1083
|
+
this.selectedNeuron = n;
|
|
1084
|
+
this.selectedContent = 'Loading...';
|
|
838
1085
|
try {
|
|
839
|
-
const
|
|
840
|
-
this.
|
|
841
|
-
} catch {
|
|
842
|
-
this.selectedNeuron = neuron;
|
|
843
|
-
}
|
|
844
|
-
try {
|
|
845
|
-
const contentData = await this.api('GET', `/neurons/${neuron.id}/content`);
|
|
846
|
-
this.selectedContent = contentData.content || '';
|
|
847
|
-
} catch {
|
|
848
|
-
this.selectedContent = '';
|
|
849
|
-
} finally {
|
|
850
|
-
this.contentLoading = false;
|
|
851
|
-
}
|
|
1086
|
+
const d = await this.api('GET', `/neurons/${n.id}/content`);
|
|
1087
|
+
this.selectedContent = d.content || '';
|
|
1088
|
+
} catch { this.selectedContent = 'Failed to load content'; }
|
|
852
1089
|
},
|
|
853
1090
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
this.selectedContent = '';
|
|
860
|
-
this.confirmDelete = false;
|
|
861
|
-
await this.loadNeurons();
|
|
862
|
-
} catch (err) {
|
|
863
|
-
alert('Delete failed: ' + err.message);
|
|
864
|
-
} finally {
|
|
865
|
-
this.deleting = false;
|
|
866
|
-
}
|
|
1091
|
+
prevPage() { if (this.neuronPage > 0) { this.neuronPage--; this.loadNeurons(); } },
|
|
1092
|
+
nextPage() { if ((this.neuronPage + 1) * this.neuronLimit < this.neuronTotal) { this.neuronPage++; this.loadNeurons(); } },
|
|
1093
|
+
paginationLabel() {
|
|
1094
|
+
if (this.neuronTotal === 0) return 'No neurons';
|
|
1095
|
+
return `${this.neuronPage * this.neuronLimit + 1}-${Math.min((this.neuronPage + 1) * this.neuronLimit, this.neuronTotal)} of ${this.neuronTotal}`;
|
|
867
1096
|
},
|
|
868
1097
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
this.loadNeurons();
|
|
873
|
-
}
|
|
1098
|
+
async loadGraph() {
|
|
1099
|
+
try { this.graphData = await this.api('GET', '/graph'); }
|
|
1100
|
+
catch { this.graphData = { nodes: [], edges: [], stats: {} }; }
|
|
874
1101
|
},
|
|
875
1102
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
1103
|
+
renderGraph() {
|
|
1104
|
+
const container = document.getElementById('graph-container');
|
|
1105
|
+
const svg = d3.select('#graph-svg');
|
|
1106
|
+
if (!container || !svg.node()) return;
|
|
1107
|
+
|
|
1108
|
+
// Clear previous
|
|
1109
|
+
svg.selectAll('*').remove();
|
|
1110
|
+
if (this.graphSimulation) this.graphSimulation.stop();
|
|
1111
|
+
|
|
1112
|
+
const nodes = this.graphData.nodes || [];
|
|
1113
|
+
const edges = this.graphData.edges || [];
|
|
1114
|
+
if (nodes.length === 0) return;
|
|
1115
|
+
|
|
1116
|
+
const width = container.clientWidth;
|
|
1117
|
+
const height = container.clientHeight;
|
|
1118
|
+
const isDark = this.darkMode;
|
|
1119
|
+
|
|
1120
|
+
// Create node map for edge references
|
|
1121
|
+
const nodeMap = new Map(nodes.map(n => [n.id, n]));
|
|
1122
|
+
|
|
1123
|
+
// Prepare links (D3 needs source/target as node references or ids)
|
|
1124
|
+
const links = edges.map(e => ({
|
|
1125
|
+
source: e.source,
|
|
1126
|
+
target: e.target,
|
|
1127
|
+
weight: e.weight || 0.5,
|
|
1128
|
+
type: e.type || 'SEMANTIC'
|
|
1129
|
+
})).filter(l => nodeMap.has(l.source) && nodeMap.has(l.target));
|
|
1130
|
+
|
|
1131
|
+
// Color scale for edge types
|
|
1132
|
+
const edgeColors = {
|
|
1133
|
+
'SEMANTIC': '#1976D2',
|
|
1134
|
+
'CAUSAL': '#2E7D32',
|
|
1135
|
+
'TEMPORAL': '#ED6C02',
|
|
1136
|
+
'ASSOCIATIVE': '#9C27B0',
|
|
1137
|
+
'HIERARCHICAL': '#D32F2F',
|
|
1138
|
+
'DUPLICATE': '#757575'
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
// Create simulation
|
|
1142
|
+
this.graphSimulation = d3.forceSimulation(nodes)
|
|
1143
|
+
.force('link', d3.forceLink(links).id(d => d.id).distance(80).strength(0.5))
|
|
1144
|
+
.force('charge', d3.forceManyBody().strength(-200))
|
|
1145
|
+
.force('center', d3.forceCenter(width / 2, height / 2))
|
|
1146
|
+
.force('collision', d3.forceCollide().radius(25));
|
|
1147
|
+
|
|
1148
|
+
// Zoom behavior
|
|
1149
|
+
const zoom = d3.zoom()
|
|
1150
|
+
.scaleExtent([0.2, 4])
|
|
1151
|
+
.on('zoom', (event) => g.attr('transform', event.transform));
|
|
1152
|
+
svg.call(zoom);
|
|
1153
|
+
|
|
1154
|
+
// Main group for zoom/pan
|
|
1155
|
+
const g = svg.append('g');
|
|
1156
|
+
|
|
1157
|
+
// Draw edges
|
|
1158
|
+
const link = g.append('g')
|
|
1159
|
+
.selectAll('line')
|
|
1160
|
+
.data(links)
|
|
1161
|
+
.join('line')
|
|
1162
|
+
.attr('stroke', d => edgeColors[d.type] || '#999')
|
|
1163
|
+
.attr('stroke-opacity', 0.6)
|
|
1164
|
+
.attr('stroke-width', d => Math.max(1, d.weight * 3));
|
|
1165
|
+
|
|
1166
|
+
// Draw nodes
|
|
1167
|
+
const node = g.append('g')
|
|
1168
|
+
.selectAll('circle')
|
|
1169
|
+
.data(nodes)
|
|
1170
|
+
.join('circle')
|
|
1171
|
+
.attr('r', 10)
|
|
1172
|
+
.attr('fill', '#1976D2')
|
|
1173
|
+
.attr('stroke', isDark ? '#424242' : '#fff')
|
|
1174
|
+
.attr('stroke-width', 2)
|
|
1175
|
+
.style('cursor', 'pointer')
|
|
1176
|
+
.call(d3.drag()
|
|
1177
|
+
.on('start', (event, d) => {
|
|
1178
|
+
if (!event.active) this.graphSimulation.alphaTarget(0.3).restart();
|
|
1179
|
+
d.fx = d.x; d.fy = d.y;
|
|
1180
|
+
})
|
|
1181
|
+
.on('drag', (event, d) => { d.fx = event.x; d.fy = event.y; })
|
|
1182
|
+
.on('end', (event, d) => {
|
|
1183
|
+
if (!event.active) this.graphSimulation.alphaTarget(0);
|
|
1184
|
+
d.fx = null; d.fy = null;
|
|
1185
|
+
}));
|
|
1186
|
+
|
|
1187
|
+
// Tooltip
|
|
1188
|
+
const tooltip = document.getElementById('graph-tooltip');
|
|
1189
|
+
const tooltipId = document.getElementById('tooltip-id');
|
|
1190
|
+
const tooltipLabel = document.getElementById('tooltip-label');
|
|
1191
|
+
|
|
1192
|
+
node.on('mouseenter', (event, d) => {
|
|
1193
|
+
tooltip.classList.remove('hidden');
|
|
1194
|
+
tooltipId.textContent = d.id.substring(0, 20) + '...';
|
|
1195
|
+
tooltipLabel.textContent = d.label || 'Neuron';
|
|
1196
|
+
})
|
|
1197
|
+
.on('mousemove', (event) => {
|
|
1198
|
+
tooltip.style.left = (event.offsetX + 15) + 'px';
|
|
1199
|
+
tooltip.style.top = (event.offsetY - 10) + 'px';
|
|
1200
|
+
})
|
|
1201
|
+
.on('mouseleave', () => tooltip.classList.add('hidden'));
|
|
1202
|
+
|
|
1203
|
+
// Node labels (short)
|
|
1204
|
+
const labels = g.append('g')
|
|
1205
|
+
.selectAll('text')
|
|
1206
|
+
.data(nodes)
|
|
1207
|
+
.join('text')
|
|
1208
|
+
.text(d => d.id.substring(0, 6))
|
|
1209
|
+
.attr('font-size', '8px')
|
|
1210
|
+
.attr('fill', isDark ? '#E6E1E5' : '#1C1B1F')
|
|
1211
|
+
.attr('text-anchor', 'middle')
|
|
1212
|
+
.attr('dy', 20)
|
|
1213
|
+
.style('pointer-events', 'none');
|
|
1214
|
+
|
|
1215
|
+
// Update positions on tick
|
|
1216
|
+
this.graphSimulation.on('tick', () => {
|
|
1217
|
+
link
|
|
1218
|
+
.attr('x1', d => d.source.x)
|
|
1219
|
+
.attr('y1', d => d.source.y)
|
|
1220
|
+
.attr('x2', d => d.target.x)
|
|
1221
|
+
.attr('y2', d => d.target.y);
|
|
1222
|
+
node.attr('cx', d => d.x).attr('cy', d => d.y);
|
|
1223
|
+
labels.attr('x', d => d.x).attr('y', d => d.y);
|
|
1224
|
+
});
|
|
1225
|
+
|
|
1226
|
+
// Initial zoom to fit
|
|
1227
|
+
setTimeout(() => {
|
|
1228
|
+
const bounds = g.node().getBBox();
|
|
1229
|
+
if (bounds.width > 0 && bounds.height > 0) {
|
|
1230
|
+
const scale = Math.min(width / bounds.width, height / bounds.height) * 0.8;
|
|
1231
|
+
const tx = (width - bounds.width * scale) / 2 - bounds.x * scale;
|
|
1232
|
+
const ty = (height - bounds.height * scale) / 2 - bounds.y * scale;
|
|
1233
|
+
svg.transition().duration(500).call(zoom.transform, d3.zoomIdentity.translate(tx, ty).scale(scale));
|
|
1234
|
+
}
|
|
1235
|
+
}, 500);
|
|
881
1236
|
},
|
|
882
1237
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1238
|
+
async runInference() {
|
|
1239
|
+
if (!this.inferNeuronId) return;
|
|
1240
|
+
this.inferring = true;
|
|
1241
|
+
this.inferResults = null;
|
|
1242
|
+
try {
|
|
1243
|
+
this.inferResults = await this.api('POST', `/inference/${this.inferType}`, {
|
|
1244
|
+
neuronId: this.inferNeuronId,
|
|
1245
|
+
depth: this.inferDepth
|
|
1246
|
+
});
|
|
1247
|
+
} catch (e) { alert(e.message); }
|
|
1248
|
+
this.inferring = false;
|
|
1249
|
+
},
|
|
1250
|
+
|
|
1251
|
+
async loadSyncStatus() {
|
|
1252
|
+
try { this.syncStatus = await this.api('GET', '/sync/status'); } catch {}
|
|
887
1253
|
},
|
|
888
1254
|
|
|
889
|
-
// --------------------------------------------------------
|
|
890
|
-
// Search
|
|
891
|
-
// --------------------------------------------------------
|
|
892
1255
|
async doSearch() {
|
|
893
|
-
if (!this.searchQuery
|
|
1256
|
+
if (!this.searchQuery) return;
|
|
894
1257
|
this.searching = true;
|
|
895
1258
|
this.searchResults = [];
|
|
896
|
-
this.searchError = null;
|
|
897
|
-
this.searchPerformed = false;
|
|
898
1259
|
try {
|
|
899
|
-
const
|
|
1260
|
+
const d = await this.api('POST', '/search', {
|
|
900
1261
|
query: this.searchQuery,
|
|
901
1262
|
k: this.searchK,
|
|
902
|
-
includeContent: this.searchIncludeContent
|
|
1263
|
+
includeContent: this.searchIncludeContent
|
|
903
1264
|
});
|
|
904
|
-
this.searchResults =
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
1265
|
+
this.searchResults = d.results || [];
|
|
1266
|
+
} catch {}
|
|
1267
|
+
this.searching = false;
|
|
1268
|
+
},
|
|
1269
|
+
|
|
1270
|
+
async doGlobalSearch() {
|
|
1271
|
+
if (this.globalSearch) {
|
|
1272
|
+
this.searchQuery = this.globalSearch;
|
|
1273
|
+
this.activeTab = 'search';
|
|
1274
|
+
await this.doSearch();
|
|
911
1275
|
}
|
|
912
1276
|
},
|
|
913
1277
|
|
|
914
|
-
// --------------------------------------------------------
|
|
915
|
-
// Ingest
|
|
916
|
-
// --------------------------------------------------------
|
|
917
1278
|
async doIngest() {
|
|
918
|
-
if (!this.ingestText
|
|
1279
|
+
if (!this.ingestText) return;
|
|
919
1280
|
this.ingesting = true;
|
|
920
1281
|
this.ingestResult = null;
|
|
921
1282
|
this.ingestError = null;
|
|
922
1283
|
try {
|
|
923
|
-
const tags = this.ingestTags
|
|
924
|
-
|
|
925
|
-
.map(t => t.trim())
|
|
926
|
-
.filter(t => t.length > 0);
|
|
927
|
-
const data = await this.api('POST', '/ingest', {
|
|
1284
|
+
const tags = this.ingestTags.split(',').map(t => t.trim()).filter(t => t);
|
|
1285
|
+
this.ingestResult = await this.api('POST', '/ingest', {
|
|
928
1286
|
text: this.ingestText,
|
|
929
|
-
sourceType: this.ingestSourceType
|
|
930
|
-
tags
|
|
1287
|
+
sourceType: this.ingestSourceType,
|
|
1288
|
+
tags
|
|
931
1289
|
});
|
|
932
|
-
this.ingestResult = data;
|
|
933
1290
|
this.ingestText = '';
|
|
934
1291
|
this.ingestTags = '';
|
|
935
|
-
} catch (
|
|
936
|
-
|
|
937
|
-
} finally {
|
|
938
|
-
this.ingesting = false;
|
|
939
|
-
}
|
|
1292
|
+
} catch (e) { this.ingestError = e.message; }
|
|
1293
|
+
this.ingesting = false;
|
|
940
1294
|
},
|
|
941
1295
|
|
|
942
|
-
// --------------------------------------------------------
|
|
943
|
-
// Verify
|
|
944
|
-
// --------------------------------------------------------
|
|
945
1296
|
async doVerifyAll() {
|
|
946
1297
|
this.verifying = true;
|
|
947
|
-
this.verifyAllResult =
|
|
948
|
-
|
|
949
|
-
this.verifyAllResult = await this.api('GET', '/verify');
|
|
950
|
-
} catch (err) {
|
|
951
|
-
this.verifyAllResult = { total: 0, valid: 0, invalid: 0, results: [], error: err.message };
|
|
952
|
-
} finally {
|
|
953
|
-
this.verifying = false;
|
|
954
|
-
}
|
|
1298
|
+
try { this.verifyAllResult = await this.api('GET', '/verify'); } catch {}
|
|
1299
|
+
this.verifying = false;
|
|
955
1300
|
},
|
|
956
1301
|
|
|
957
1302
|
async doVerifySingle() {
|
|
958
|
-
if (!this.verifyNeuronId
|
|
1303
|
+
if (!this.verifyNeuronId) return;
|
|
959
1304
|
this.verifySingleLoading = true;
|
|
960
1305
|
this.verifySingleResult = null;
|
|
961
|
-
this.
|
|
962
|
-
|
|
963
|
-
this.verifySingleResult = await this.api('GET', `/verify/${this.verifyNeuronId.trim()}`);
|
|
964
|
-
} catch (err) {
|
|
965
|
-
this.verifySingleError = err.message;
|
|
966
|
-
} finally {
|
|
967
|
-
this.verifySingleLoading = false;
|
|
968
|
-
}
|
|
1306
|
+
try { this.verifySingleResult = await this.api('GET', `/verify/${this.verifyNeuronId}`); } catch {}
|
|
1307
|
+
this.verifySingleLoading = false;
|
|
969
1308
|
},
|
|
970
1309
|
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
// --------------------------------------------------------
|
|
974
|
-
formatNumber(val) {
|
|
975
|
-
if (val === null || val === undefined || val === '--') return '--';
|
|
976
|
-
return Number(val).toLocaleString();
|
|
1310
|
+
formatNumber(v) {
|
|
1311
|
+
return v == null || v === '--' ? '0' : Number(v).toLocaleString();
|
|
977
1312
|
},
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
984
|
-
const val = bytes / Math.pow(1024, i);
|
|
985
|
-
return val.toFixed(i === 0 ? 0 : 1) + ' ' + units[i];
|
|
986
|
-
},
|
|
987
|
-
|
|
988
|
-
formatDate(dateStr) {
|
|
989
|
-
if (!dateStr) return '--';
|
|
990
|
-
try {
|
|
991
|
-
const d = new Date(dateStr);
|
|
992
|
-
return d.toLocaleDateString() + ' ' + d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
993
|
-
} catch {
|
|
994
|
-
return dateStr;
|
|
995
|
-
}
|
|
1313
|
+
formatBytes(b) {
|
|
1314
|
+
if (b == null || b === 0) return '0 B';
|
|
1315
|
+
const u = ['B','KB','MB','GB'];
|
|
1316
|
+
const i = Math.floor(Math.log(b)/Math.log(1024));
|
|
1317
|
+
return (b/Math.pow(1024,i)).toFixed(1) + ' ' + u[i];
|
|
996
1318
|
},
|
|
997
1319
|
};
|
|
998
1320
|
}
|
|
999
1321
|
</script>
|
|
1000
|
-
|
|
1001
1322
|
</body>
|
|
1002
1323
|
</html>
|