@neuralis/brain-core 0.1.0 → 0.2.0
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 +26 -35
- package/app/cards/DiffView.tsx +9 -7
- package/app/cards/README.md +1 -1
- package/app/cards/diffLine.tsx +2 -4
- package/app/filesystem/README.md +1 -1
- package/app/filesystem/api/index.ts +14 -5
- package/app/filesystem/domain/types.ts +24 -5
- package/app/filesystem/store/filesystemStore.ts +20 -1
- package/app/filesystem/store/listSlice.ts +2 -0
- package/app/filesystem/store/searchSlice.ts +24 -1
- package/app/filesystem/ui/FileTreeSearch.tsx +29 -2
- package/app/filesystem/ui/PendingChangesPanel.tsx +74 -17
- package/app/filesystem/ui/PendingReviewDialog.tsx +45 -20
- package/app/filesystem/ui/README.md +8 -7
- package/app/filesystem/ui/ReembedDialog.tsx +20 -9
- package/app/filesystem/ui/SourceDeleteConfirm.tsx +1 -1
- package/app/filesystem/ui/SourcesPanel.tsx +110 -17
- package/app/filesystem/ui/VectorHealthPanel.tsx +14 -0
- package/app/filesystem/ui/pendingChangesModel.ts +9 -5
- package/dist/app/chunks/{astro-LRAFGXNX.js → astro-B2J4AS2D.js} +1 -1
- package/dist/app/chunks/bash-KY6SAQTH.js +1 -0
- package/dist/app/chunks/c-OBOPYVZ7.js +1 -0
- package/dist/app/chunks/{chunk-5H7ZCOD3.js → chunk-2X3GNKJ3.js} +1 -1
- package/dist/app/chunks/{chunk-XIFGTNRM.js → chunk-JPJIVRFI.js} +1 -1
- package/dist/app/chunks/{chunk-RH3QY5LF.js → chunk-LEFIFWND.js} +1 -1
- package/dist/app/chunks/{chunk-G4RZ3UNX.js → chunk-N6RXX3PH.js} +1 -1
- package/dist/app/chunks/{chunk-QXXJ73P5.js → chunk-PZAW4HPB.js} +1 -1
- package/dist/app/chunks/{chunk-3QLE7Y4L.js → chunk-ZBYWWTO6.js} +1 -1
- package/dist/app/chunks/cpp-TVWVOTEQ.js +1 -0
- package/dist/app/chunks/css-MANZBYA4.js +1 -0
- package/dist/app/chunks/{elixir-M36XROA6.js → elixir-S725Z7EH.js} +1 -1
- package/dist/app/chunks/{elm-7BG6QAIK.js → elm-5WUUSTNB.js} +1 -1
- package/dist/app/chunks/graphql-UGOPR3WU.js +1 -0
- package/dist/app/chunks/html-F6FWTBSG.js +1 -0
- package/dist/app/chunks/java-ANIVV5H5.js +1 -0
- package/dist/app/chunks/javascript-IH374YWG.js +1 -0
- package/dist/app/chunks/json-WGGVVXSB.js +1 -0
- package/dist/app/chunks/jsx-OTXJQD32.js +1 -0
- package/dist/app/chunks/{latex-ZWK7SXB6.js → latex-QCZNITGN.js} +1 -1
- package/dist/app/chunks/lua-4CRZ64PU.js +1 -0
- package/dist/app/chunks/{nginx-2L6VRV3A.js → nginx-V4CYS7WR.js} +1 -1
- package/dist/app/chunks/{perl-PBUAXXK6.js → perl-BHTX7F5B.js} +1 -1
- package/dist/app/chunks/{php-QJX57PA6.js → php-AYGJ5WYZ.js} +1 -1
- package/dist/app/chunks/r-4YFCFA4B.js +1 -0
- package/dist/app/chunks/{ruby-RLOWMVPO.js → ruby-42NMJWAL.js} +1 -1
- package/dist/app/chunks/{scss-B5CAI3HR.js → scss-XD7VU2CU.js} +1 -1
- package/dist/app/chunks/sql-B55MH6JJ.js +1 -0
- package/dist/app/chunks/{svelte-GT3D4C44.js → svelte-WR3QPIJU.js} +1 -1
- package/dist/app/chunks/tsx-S73GAE2L.js +1 -0
- package/dist/app/chunks/typescript-NEWOAB5Z.js +1 -0
- package/dist/app/chunks/{vue-JOW62MHD.js → vue-CCDS4VZK.js} +1 -1
- package/dist/app/chunks/xml-UXKAGLDR.js +1 -0
- package/dist/app/chunks/yaml-UMWKDTK7.js +1 -0
- package/dist/app/host.js +40 -40
- package/dist/scripts/embeddingLockV3.d.ts +30 -0
- package/dist/scripts/embeddingLockV3.d.ts.map +1 -0
- package/dist/scripts/embeddingLockV3.js +100 -0
- package/dist/scripts/embeddingLockV3.js.map +1 -0
- package/dist/scripts/vectorProofV1.d.ts +90 -0
- package/dist/scripts/vectorProofV1.d.ts.map +1 -0
- package/dist/scripts/vectorProofV1.js +220 -0
- package/dist/scripts/vectorProofV1.js.map +1 -0
- package/dist/src/config/env.d.ts +21 -0
- package/dist/src/config/env.d.ts.map +1 -1
- package/dist/src/config/env.js +55 -0
- package/dist/src/config/env.js.map +1 -1
- package/dist/src/connectors/AppSourceConfigStore.d.ts +12 -2
- package/dist/src/connectors/AppSourceConfigStore.d.ts.map +1 -1
- package/dist/src/connectors/AppSourceConfigStore.js +48 -40
- package/dist/src/connectors/AppSourceConfigStore.js.map +1 -1
- package/dist/src/connectors/LocalDiskConnector.d.ts +11 -14
- package/dist/src/connectors/LocalDiskConnector.d.ts.map +1 -1
- package/dist/src/connectors/LocalDiskConnector.js +87 -107
- package/dist/src/connectors/LocalDiskConnector.js.map +1 -1
- package/dist/src/connectors/sourceConfigMutation.d.ts +11 -1
- package/dist/src/connectors/sourceConfigMutation.d.ts.map +1 -1
- package/dist/src/connectors/sourceConfigMutation.js +36 -3
- package/dist/src/connectors/sourceConfigMutation.js.map +1 -1
- package/dist/src/domain/chunker.js +8 -3
- package/dist/src/domain/chunker.js.map +1 -1
- package/dist/src/domain/healthTypes.d.ts +11 -0
- package/dist/src/domain/healthTypes.d.ts.map +1 -1
- package/dist/src/domain/mime.d.ts +1 -0
- package/dist/src/domain/mime.d.ts.map +1 -1
- package/dist/src/domain/mime.js +48 -0
- package/dist/src/domain/mime.js.map +1 -1
- package/dist/src/domain/pendingChange.d.ts +7 -0
- package/dist/src/domain/pendingChange.d.ts.map +1 -1
- package/dist/src/domain/pendingChange.js +11 -0
- package/dist/src/domain/pendingChange.js.map +1 -1
- package/dist/src/domain/sourceConfig.d.ts +7 -14
- package/dist/src/domain/sourceConfig.d.ts.map +1 -1
- package/dist/src/domain/sourceConfig.js +1 -13
- package/dist/src/domain/sourceConfig.js.map +1 -1
- package/dist/src/domain/sourcePackages.d.ts +11 -2
- package/dist/src/domain/sourcePackages.d.ts.map +1 -1
- package/dist/src/domain/syncTrigger.d.ts +2 -3
- package/dist/src/domain/syncTrigger.d.ts.map +1 -1
- package/dist/src/domain/syncTrigger.js +2 -3
- package/dist/src/domain/syncTrigger.js.map +1 -1
- package/dist/src/domain/syncTypes.d.ts +21 -4
- package/dist/src/domain/syncTypes.d.ts.map +1 -1
- package/dist/src/domain/syncTypes.js.map +1 -1
- package/dist/src/domain/text.d.ts +3 -0
- package/dist/src/domain/text.d.ts.map +1 -1
- package/dist/src/domain/text.js +5 -0
- package/dist/src/domain/text.js.map +1 -1
- package/dist/src/domain/types.d.ts +9 -0
- package/dist/src/domain/types.d.ts.map +1 -1
- package/dist/src/embeddings/clients/GeminiEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/GeminiEmbedder.js +11 -5
- package/dist/src/embeddings/clients/GeminiEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/OllamaEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/OllamaEmbedder.js +13 -6
- package/dist/src/embeddings/clients/OllamaEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/OpenAIEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/OpenAIEmbedder.js +12 -9
- package/dist/src/embeddings/clients/OpenAIEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/QwenEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/QwenEmbedder.js +12 -5
- package/dist/src/embeddings/clients/QwenEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/VoyageEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/VoyageEmbedder.js +12 -5
- package/dist/src/embeddings/clients/VoyageEmbedder.js.map +1 -1
- package/dist/src/embeddings/factory.d.ts +2 -0
- package/dist/src/embeddings/factory.d.ts.map +1 -1
- package/dist/src/embeddings/factory.js +23 -3
- package/dist/src/embeddings/factory.js.map +1 -1
- package/dist/src/embeddings/lock.d.ts +22 -11
- package/dist/src/embeddings/lock.d.ts.map +1 -1
- package/dist/src/embeddings/lock.js +47 -29
- package/dist/src/embeddings/lock.js.map +1 -1
- package/dist/src/embeddings/retry.d.ts +5 -0
- package/dist/src/embeddings/retry.d.ts.map +1 -1
- package/dist/src/embeddings/retry.js +35 -0
- package/dist/src/embeddings/retry.js.map +1 -1
- package/dist/src/events/pending.d.ts +56 -0
- package/dist/src/events/pending.d.ts.map +1 -0
- package/dist/src/events/pending.js +108 -0
- package/dist/src/events/pending.js.map +1 -0
- package/dist/src/events/source.d.ts +60 -14
- package/dist/src/events/source.d.ts.map +1 -1
- package/dist/src/events/source.js +149 -31
- package/dist/src/events/source.js.map +1 -1
- package/dist/src/events/vector.d.ts +33 -0
- package/dist/src/events/vector.d.ts.map +1 -0
- package/dist/src/events/vector.js +57 -0
- package/dist/src/events/vector.js.map +1 -0
- package/dist/src/git/GitRunner.d.ts.map +1 -1
- package/dist/src/git/GitRunner.js +11 -8
- package/dist/src/git/GitRunner.js.map +1 -1
- package/dist/src/git/sourceGitControl.d.ts.map +1 -1
- package/dist/src/git/sourceGitControl.js +2 -1
- package/dist/src/git/sourceGitControl.js.map +1 -1
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/lifecycle.d.ts +20 -4
- package/dist/src/lifecycle.d.ts.map +1 -1
- package/dist/src/lifecycle.js +5 -1
- package/dist/src/lifecycle.js.map +1 -1
- package/dist/src/routes/health.js +6 -1
- package/dist/src/routes/health.js.map +1 -1
- package/dist/src/routes/pending.d.ts.map +1 -1
- package/dist/src/routes/pending.js +2 -1
- package/dist/src/routes/pending.js.map +1 -1
- package/dist/src/routes/sources.d.ts.map +1 -1
- package/dist/src/routes/sources.js +60 -11
- package/dist/src/routes/sources.js.map +1 -1
- package/dist/src/services/BridgeService.d.ts +2 -2
- package/dist/src/services/BridgeService.d.ts.map +1 -1
- package/dist/src/services/BridgeService.js +11 -2
- package/dist/src/services/BridgeService.js.map +1 -1
- package/dist/src/services/FilesystemService.d.ts +3 -1
- package/dist/src/services/FilesystemService.d.ts.map +1 -1
- package/dist/src/services/FilesystemService.js +3 -1
- package/dist/src/services/FilesystemService.js.map +1 -1
- package/dist/src/services/FilesystemUiService.js +1 -1
- package/dist/src/services/FilesystemUiService.js.map +1 -1
- package/dist/src/services/SyncScheduler.d.ts.map +1 -1
- package/dist/src/services/SyncScheduler.js +0 -14
- package/dist/src/services/SyncScheduler.js.map +1 -1
- package/dist/src/services/VectorHealthService.d.ts.map +1 -1
- package/dist/src/services/VectorHealthService.js +2 -46
- package/dist/src/services/VectorHealthService.js.map +1 -1
- package/dist/src/services/baselineRepair.d.ts +2 -2
- package/dist/src/services/baselineRepair.js +2 -2
- package/dist/src/services/declaredSources.d.ts +8 -1
- package/dist/src/services/declaredSources.d.ts.map +1 -1
- package/dist/src/services/declaredSources.js +19 -19
- package/dist/src/services/declaredSources.js.map +1 -1
- package/dist/src/store/dataFormats.d.ts +14 -3
- package/dist/src/store/dataFormats.d.ts.map +1 -1
- package/dist/src/store/dataFormats.js +15 -5
- package/dist/src/store/dataFormats.js.map +1 -1
- package/dist/src/sync/DeltaSyncRunner.d.ts.map +1 -1
- package/dist/src/sync/DeltaSyncRunner.js +78 -243
- package/dist/src/sync/DeltaSyncRunner.js.map +1 -1
- package/dist/src/sync/SyncJobQueue.d.ts +33 -4
- package/dist/src/sync/SyncJobQueue.d.ts.map +1 -1
- package/dist/src/sync/SyncJobQueue.js +179 -19
- package/dist/src/sync/SyncJobQueue.js.map +1 -1
- package/dist/src/sync/moveDetector.d.ts +2 -1
- package/dist/src/sync/moveDetector.d.ts.map +1 -1
- package/dist/src/sync/moveDetector.js +2 -1
- package/dist/src/sync/moveDetector.js.map +1 -1
- package/dist/src/tools/fs_search.d.ts.map +1 -1
- package/dist/src/tools/fs_search.js +8 -0
- package/dist/src/tools/fs_search.js.map +1 -1
- package/dist/src/tools/fs_write.js +3 -1
- package/dist/src/tools/fs_write.js.map +1 -1
- package/dist/src/usecases/chunkUpsert.d.ts +4 -0
- package/dist/src/usecases/chunkUpsert.d.ts.map +1 -1
- package/dist/src/usecases/chunkUpsert.js +103 -60
- package/dist/src/usecases/chunkUpsert.js.map +1 -1
- package/dist/src/usecases/embeddingBacklog.d.ts +31 -0
- package/dist/src/usecases/embeddingBacklog.d.ts.map +1 -0
- package/dist/src/usecases/embeddingBacklog.js +244 -0
- package/dist/src/usecases/embeddingBacklog.js.map +1 -0
- package/dist/src/usecases/listSourcePackages.js +17 -1
- package/dist/src/usecases/listSourcePackages.js.map +1 -1
- package/dist/src/usecases/mediaLane.d.ts +11 -4
- package/dist/src/usecases/mediaLane.d.ts.map +1 -1
- package/dist/src/usecases/mediaLane.js +67 -30
- package/dist/src/usecases/mediaLane.js.map +1 -1
- package/dist/src/usecases/pendingReview.d.ts.map +1 -1
- package/dist/src/usecases/pendingReview.js +24 -7
- package/dist/src/usecases/pendingReview.js.map +1 -1
- package/dist/src/usecases/purgeExcludedPoints.d.ts +2 -0
- package/dist/src/usecases/purgeExcludedPoints.d.ts.map +1 -1
- package/dist/src/usecases/purgeExcludedPoints.js +3 -2
- package/dist/src/usecases/purgeExcludedPoints.js.map +1 -1
- package/dist/src/usecases/readFiles.d.ts.map +1 -1
- package/dist/src/usecases/readFiles.js +33 -6
- package/dist/src/usecases/readFiles.js.map +1 -1
- package/dist/src/usecases/reconcileSourcePackageRoots.d.ts +31 -0
- package/dist/src/usecases/reconcileSourcePackageRoots.d.ts.map +1 -0
- package/dist/src/usecases/reconcileSourcePackageRoots.js +114 -0
- package/dist/src/usecases/reconcileSourcePackageRoots.js.map +1 -0
- package/dist/src/usecases/searchFiles.d.ts.map +1 -1
- package/dist/src/usecases/searchFiles.js +62 -64
- package/dist/src/usecases/searchFiles.js.map +1 -1
- package/dist/src/usecases/syncIndexedFile.d.ts +42 -0
- package/dist/src/usecases/syncIndexedFile.d.ts.map +1 -0
- package/dist/src/usecases/syncIndexedFile.js +242 -0
- package/dist/src/usecases/syncIndexedFile.js.map +1 -0
- package/dist/src/usecases/syncPointWrites.d.ts +5 -0
- package/dist/src/usecases/syncPointWrites.d.ts.map +1 -1
- package/dist/src/usecases/syncPointWrites.js +32 -5
- package/dist/src/usecases/syncPointWrites.js.map +1 -1
- package/dist/src/usecases/uploadBinary.d.ts.map +1 -1
- package/dist/src/usecases/uploadBinary.js +36 -49
- package/dist/src/usecases/uploadBinary.js.map +1 -1
- package/dist/src/usecases/vector/endpointGuard.js +2 -1
- package/dist/src/usecases/vector/endpointGuard.js.map +1 -1
- package/dist/src/usecases/vector/estimate.d.ts +7 -4
- package/dist/src/usecases/vector/estimate.d.ts.map +1 -1
- package/dist/src/usecases/vector/estimate.js +8 -5
- package/dist/src/usecases/vector/estimate.js.map +1 -1
- package/dist/src/usecases/vector/rebuildGeneration.d.ts +29 -5
- package/dist/src/usecases/vector/rebuildGeneration.d.ts.map +1 -1
- package/dist/src/usecases/vector/rebuildGeneration.js +224 -82
- package/dist/src/usecases/vector/rebuildGeneration.js.map +1 -1
- package/dist/src/usecases/vectorMaintenance.d.ts +46 -4
- package/dist/src/usecases/vectorMaintenance.d.ts.map +1 -1
- package/dist/src/usecases/vectorMaintenance.js +190 -11
- package/dist/src/usecases/vectorMaintenance.js.map +1 -1
- package/dist/src/usecases/write/commit.d.ts +6 -8
- package/dist/src/usecases/write/commit.d.ts.map +1 -1
- package/dist/src/usecases/write/commit.js +96 -112
- package/dist/src/usecases/write/commit.js.map +1 -1
- package/dist/src/usecases/write/content.js +1 -2
- package/dist/src/usecases/write/content.js.map +1 -1
- package/dist/src/usecases/write/ports.d.ts +1 -0
- package/dist/src/usecases/write/ports.d.ts.map +1 -1
- package/dist/src/vector/FilesystemVectorIndex.d.ts +34 -3
- package/dist/src/vector/FilesystemVectorIndex.d.ts.map +1 -1
- package/dist/src/vector/FilesystemVectorIndex.js +254 -20
- package/dist/src/vector/FilesystemVectorIndex.js.map +1 -1
- package/dist/src/vector/InMemoryVectorIndex.d.ts +9 -2
- package/dist/src/vector/InMemoryVectorIndex.d.ts.map +1 -1
- package/dist/src/vector/InMemoryVectorIndex.js +25 -6
- package/dist/src/vector/InMemoryVectorIndex.js.map +1 -1
- package/dist/src/vector/QdrantVectorIndex.d.ts +35 -9
- package/dist/src/vector/QdrantVectorIndex.d.ts.map +1 -1
- package/dist/src/vector/QdrantVectorIndex.js +209 -90
- package/dist/src/vector/QdrantVectorIndex.js.map +1 -1
- package/dist/src/vector/qdrantFilter.d.ts +3 -1
- package/dist/src/vector/qdrantFilter.d.ts.map +1 -1
- package/dist/src/vector/qdrantFilter.js +2 -0
- package/dist/src/vector/qdrantFilter.js.map +1 -1
- package/dist/src/vector/types.d.ts +81 -0
- package/dist/src/vector/types.d.ts.map +1 -1
- package/dist/src/vector/types.js +2 -0
- package/dist/src/vector/types.js.map +1 -1
- package/dist/src/wiring.d.ts +6 -0
- package/dist/src/wiring.d.ts.map +1 -1
- package/dist/src/wiring.js +62 -3
- package/dist/src/wiring.js.map +1 -1
- package/dist/tools/fs_search.json +2 -2
- package/docs/drive-overview.md +2 -2
- package/instructions/brain-model.md +1 -1
- package/package.json +999 -10
- package/rules/brain-rules.md +1 -1
- package/skills/connect-business-data/SKILL.md +6 -4
- package/skills/create-package/SKILL.md +14 -12
- package/skills/create-package/references/config-and-credentials.md +3 -3
- package/skills/create-package/references/connectors-and-uri-policies.md +5 -3
- package/skills/create-package/references/manifest-and-discovery.md +4 -3
- package/skills/create-package/references/runtime-and-build.md +9 -9
- package/skills/create-package/references/skills-and-context.md +3 -3
- package/skills/create-package/references/surfaces-and-design.md +2 -1
- package/skills/create-package/references/team-and-workflows.md +2 -2
- package/skills/create-package/references/test-and-ship.md +15 -15
- package/skills/create-package/references/tools-and-schemas.md +1 -1
- package/skills/create-package/scripts/check-package.sh +3 -3
- package/skills/create-package/scripts/verify-loaded.sh +16 -16
- package/skills/manage-files/SKILL.md +2 -2
- package/skills/manage-sources/SKILL.md +16 -15
- package/skills/manage-sources/scripts/reembed.sh +9 -3
- package/skills/sync/SKILL.md +4 -4
- package/tools/fs_search.json +2 -2
- package/dist/app/chunks/bash-M45GHPBQ.js +0 -1
- package/dist/app/chunks/c-X3REOAWD.js +0 -1
- package/dist/app/chunks/cpp-VOWI743W.js +0 -1
- package/dist/app/chunks/css-2ZVPHE25.js +0 -1
- package/dist/app/chunks/graphql-7V2NP54C.js +0 -1
- package/dist/app/chunks/html-UF3LFLNA.js +0 -1
- package/dist/app/chunks/java-PNTAU4L3.js +0 -1
- package/dist/app/chunks/javascript-4JJTQGEL.js +0 -1
- package/dist/app/chunks/json-VLQ6D3JH.js +0 -1
- package/dist/app/chunks/jsx-KQKSLAAH.js +0 -1
- package/dist/app/chunks/lua-UFPYUJ2O.js +0 -1
- package/dist/app/chunks/r-QEZB45SR.js +0 -1
- package/dist/app/chunks/sql-DTZHNUZP.js +0 -1
- package/dist/app/chunks/tsx-WPR2WRZD.js +0 -1
- package/dist/app/chunks/typescript-LWO362OA.js +0 -1
- package/dist/app/chunks/xml-A5H72RTS.js +0 -1
- package/dist/app/chunks/yaml-MXHSIJCI.js +0 -1
- package/dist/src/services/purgePendingNodes.d.ts +0 -32
- package/dist/src/services/purgePendingNodes.d.ts.map +0 -1
- package/dist/src/services/purgePendingNodes.js +0 -61
- package/dist/src/services/purgePendingNodes.js.map +0 -1
- /package/dist/app/chunks/{chunk-737Y24HS.js → chunk-3JASFUPF.js} +0 -0
- /package/dist/app/chunks/{chunk-DKD2L57N.js → chunk-6EYLOQ4F.js} +0 -0
- /package/dist/app/chunks/{chunk-KYH5EHHY.js → chunk-7YRZ5LOQ.js} +0 -0
- /package/dist/app/chunks/{chunk-6TC3DVWV.js → chunk-C7LU4RID.js} +0 -0
- /package/dist/app/chunks/{chunk-TY33BMKR.js → chunk-CD52YDZP.js} +0 -0
- /package/dist/app/chunks/{chunk-OLEIKJ3X.js → chunk-DCJKTCJ5.js} +0 -0
- /package/dist/app/chunks/{chunk-QLBZ4JR2.js → chunk-EXIU2KBV.js} +0 -0
- /package/dist/app/chunks/{chunk-SFUNBBEA.js → chunk-FDP4LO4P.js} +0 -0
- /package/dist/app/chunks/{chunk-BGRVFATT.js → chunk-HNETUS7U.js} +0 -0
- /package/dist/app/chunks/{chunk-4QNMHAIR.js → chunk-LBFZJEDR.js} +0 -0
- /package/dist/app/chunks/{chunk-TRRUHDPN.js → chunk-ULRXL5VM.js} +0 -0
- /package/dist/app/chunks/{chunk-S6B4WWIF.js → chunk-XJK47SMJ.js} +0 -0
- /package/dist/app/chunks/{chunk-DZ5C5FKI.js → chunk-YYAAIAU2.js} +0 -0
- /package/dist/app/chunks/{clojure-OC6KPSJO.js → clojure-4QCN4GHG.js} +0 -0
- /package/dist/app/chunks/{core-KGE7TQJ3.js → core-ZHTX3P2Q.js} +0 -0
- /package/dist/app/chunks/{csharp-E7VIFITL.js → csharp-HQWR4N52.js} +0 -0
- /package/dist/app/chunks/{dark-plus-BOSCZXE4.js → dark-plus-GYPKKZES.js} +0 -0
- /package/dist/app/chunks/{dart-6Y3X27SZ.js → dart-FO4TTVO2.js} +0 -0
- /package/dist/app/chunks/{diff-TR2NPA64.js → diff-SHANV4YC.js} +0 -0
- /package/dist/app/chunks/{dist-T32U2VVR.js → dist-WSDF34DM.js} +0 -0
- /package/dist/app/chunks/{docker-N33HOW54.js → docker-VX55HTDS.js} +0 -0
- /package/dist/app/chunks/{go-6DGG5UTP.js → go-5UCPEC6S.js} +0 -0
- /package/dist/app/chunks/{haskell-KK36PMMM.js → haskell-25PJ3OSG.js} +0 -0
- /package/dist/app/chunks/{ini-VHVQ5TPB.js → ini-BJIVD5MK.js} +0 -0
- /package/dist/app/chunks/{kotlin-44WS3JHE.js → kotlin-MNR6XOEQ.js} +0 -0
- /package/dist/app/chunks/{less-5WZ3KLAK.js → less-KA5JURX6.js} +0 -0
- /package/dist/app/chunks/{light-plus-HGGBC43G.js → light-plus-QXH2UUWZ.js} +0 -0
- /package/dist/app/chunks/{make-X7RXMVW7.js → make-LPD5KOCO.js} +0 -0
- /package/dist/app/chunks/{markdown-46IKUAIB.js → markdown-LMWF6MQR.js} +0 -0
- /package/dist/app/chunks/{mdx-DGLHDAO7.js → mdx-WPMNN5BS.js} +0 -0
- /package/dist/app/chunks/{nix-Q6FYQZLX.js → nix-QGWLUUMZ.js} +0 -0
- /package/dist/app/chunks/{powershell-L4KJJ6DK.js → powershell-7GSBBEFF.js} +0 -0
- /package/dist/app/chunks/{prisma-IKS4LVH2.js → prisma-FPMPQISO.js} +0 -0
- /package/dist/app/chunks/{proto-AYCDOTJO.js → proto-7KDX5Z2U.js} +0 -0
- /package/dist/app/chunks/{python-KXMCSAFQ.js → python-CFG4FTQW.js} +0 -0
- /package/dist/app/chunks/{rust-J3BC3P6V.js → rust-X7A37WU3.js} +0 -0
- /package/dist/app/chunks/{scala-AYIIHBJK.js → scala-OYHJSUG2.js} +0 -0
- /package/dist/app/chunks/{swift-QPHHCQD3.js → swift-PE7VNYW5.js} +0 -0
- /package/dist/app/chunks/{toml-UV7JK7K7.js → toml-ETQRDILP.js} +0 -0
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { syncIndexedFile, createSyncJobEmbedder, isBinaryFile } from '../usecases/syncIndexedFile.js';
|
|
2
|
+
import { looksBinaryContent, BINARY_SNIFF_CHARS } from '../domain/text.js';
|
|
1
3
|
import { createHash } from 'node:crypto';
|
|
2
4
|
import { deriveSourceKind, normalizeSource } from '../domain/source.js';
|
|
3
5
|
import { resolveOsUri } from '../domain/paths.js';
|
|
4
6
|
import { uriAncestors, extractFilename } from '../domain/uri.js';
|
|
5
7
|
import { buildVersionInfo } from '../domain/versioning.js';
|
|
8
|
+
import { embeddingUnavailableReason } from '../embeddings/factory.js';
|
|
6
9
|
import { isEmbeddingBudgetStopError } from '../embeddings/usage.js';
|
|
7
10
|
import { ConnectorNotFoundError } from '@neuralis/package-system/contracts';
|
|
8
11
|
import { compileSyncFilters, isUriIndexableUnderFilters } from '../domain/syncignore.js';
|
|
@@ -11,11 +14,11 @@ import { isAppendShaped } from '../domain/chunker.js';
|
|
|
11
14
|
import { getBrainConfigProvider, getBrainConfigNumber } from '../config/env.js';
|
|
12
15
|
import { resolveSyncCategory, computeContributionEnrichment, buildEnrichmentRefresh, isEnrichmentCurrent, } from './categoryInference.js';
|
|
13
16
|
import { MoveClaims } from './moveDetector.js';
|
|
14
|
-
import {
|
|
17
|
+
import { pickUriNode } from '../usecases/chunkUpsert.js';
|
|
15
18
|
import { uriLogHash } from '../domain/contentHash.js';
|
|
16
19
|
import { purgeExcludedPoints } from '../usecases/purgeExcludedPoints.js';
|
|
17
20
|
import { emptyMediaSkipCounts, mediaKindOf, mediaLaneOn, mediaSkipSummary, upsertMediaFromSource, } from '../usecases/mediaLane.js';
|
|
18
|
-
import {
|
|
21
|
+
import { hashSyncedFile, tombstoneSyncedPoint, } from '../usecases/syncPointWrites.js';
|
|
19
22
|
import { noopLogger } from '@neuralis/package-system/data';
|
|
20
23
|
const SCROLL_BATCH = 200;
|
|
21
24
|
/**
|
|
@@ -46,6 +49,10 @@ const INVENTORY_PAYLOAD_FIELDS = [
|
|
|
46
49
|
// A payload-only write REPLACES the payload (`overwritePayload`), so the
|
|
47
50
|
// vector's model marker must travel with every row a writer might spread.
|
|
48
51
|
'embed_model',
|
|
52
|
+
'embedding_status',
|
|
53
|
+
'embedding_input_hash',
|
|
54
|
+
'embedding_generation',
|
|
55
|
+
'embedding_updated_at',
|
|
49
56
|
// …and so must a media point's modality (the purge's lane decision reads it too).
|
|
50
57
|
'modality',
|
|
51
58
|
'recovery_only',
|
|
@@ -87,19 +94,6 @@ function limitConcurrency(tasks, concurrency, signal) {
|
|
|
87
94
|
const workers = Array.from({ length: Math.min(concurrency, tasks.length) }, () => worker());
|
|
88
95
|
return Promise.all(workers).then(() => results);
|
|
89
96
|
}
|
|
90
|
-
const BINARY_EXTENSIONS = new Set([
|
|
91
|
-
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.ico', '.bmp',
|
|
92
|
-
'.mp4', '.webm', '.avi', '.mov', '.mkv',
|
|
93
|
-
'.mp3', '.wav', '.ogg', '.flac', '.aac',
|
|
94
|
-
'.zip', '.tar', '.gz', '.bz2', '.7z', '.rar',
|
|
95
|
-
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
|
|
96
|
-
'.exe', '.dll', '.so', '.dylib', '.wasm',
|
|
97
|
-
'.ttf', '.otf', '.woff', '.woff2', '.eot',
|
|
98
|
-
]);
|
|
99
|
-
function isBinaryFile(filename) {
|
|
100
|
-
const ext = filename.slice(filename.lastIndexOf('.')).toLowerCase();
|
|
101
|
-
return BINARY_EXTENSIONS.has(ext);
|
|
102
|
-
}
|
|
103
97
|
function isMissingFileError(error) {
|
|
104
98
|
return typeof error === 'object' && error !== null && 'code' in error
|
|
105
99
|
&& error.code === 'ENOENT';
|
|
@@ -277,7 +271,10 @@ export class DeltaSyncRunner {
|
|
|
277
271
|
const uri = typeof point.payload.uri === 'string' ? point.payload.uri : '';
|
|
278
272
|
if (!uri || !shouldSyncUri(uri) || knownUris.has(uri))
|
|
279
273
|
continue;
|
|
280
|
-
|
|
274
|
+
// A point under review is never paired as a move: relocating it would
|
|
275
|
+
// strand its review record at the old uri. It is tombstoned below like
|
|
276
|
+
// any vanished file, and the new uri is an ordinary add.
|
|
277
|
+
if (point.payload.status === 'deleted' || point.payload.status === 'pending_review' || point.payload.category === 'chunk')
|
|
281
278
|
continue;
|
|
282
279
|
disappeared.set(uri, {
|
|
283
280
|
pointId: point.id,
|
|
@@ -292,11 +289,15 @@ export class DeltaSyncRunner {
|
|
|
292
289
|
let filesMoved = 0;
|
|
293
290
|
let totalChunksEmbedded = 0;
|
|
294
291
|
let totalChunksSkipped = 0;
|
|
292
|
+
const embeddingReasons = new Set();
|
|
295
293
|
const mediaSkipped = emptyMediaSkipCounts();
|
|
296
294
|
const syncErrors = [];
|
|
297
295
|
const movedOldRefs = new Set();
|
|
298
296
|
emitProgress({ phase: 'processing', processed: 0, total: changed.length });
|
|
299
297
|
const syncConcurrency = Math.max(1, getBrainConfigNumber('brainSyncConcurrency', 'BRAIN_SYNC_CONCURRENCY', DEFAULT_SYNC_CONCURRENCY));
|
|
298
|
+
const binarySniffChars = binarySniffCharsSetting();
|
|
299
|
+
const binaryUris = new Set();
|
|
300
|
+
let binarySkipped = 0;
|
|
300
301
|
let processed = 0;
|
|
301
302
|
// Credential-use deny / embedding daily cap short-circuit: the first
|
|
302
303
|
// typed stop error stops every not-yet-started task — a denied window
|
|
@@ -312,7 +313,7 @@ export class DeltaSyncRunner {
|
|
|
312
313
|
return { entry, upserted: { action: 'skipped', chunksEmbedded: 0, chunksSkipped: 0 }, error: null };
|
|
313
314
|
}
|
|
314
315
|
const existing = existingByUri.get(entry.uri) ?? null;
|
|
315
|
-
return this.#upsertFromSource(normalizedJob, connector, entry, existing, moves)
|
|
316
|
+
return this.#upsertFromSource(normalizedJob, connector, entry, existing, moves, binarySniffChars)
|
|
316
317
|
.then((upserted) => ({ entry, upserted, error: null }))
|
|
317
318
|
.catch((error) => {
|
|
318
319
|
if (normalizedJob.signal?.aborted)
|
|
@@ -331,6 +332,8 @@ export class DeltaSyncRunner {
|
|
|
331
332
|
if (r.status !== 'fulfilled' || !r.value)
|
|
332
333
|
continue;
|
|
333
334
|
const { entry, upserted, error } = r.value;
|
|
335
|
+
if (upserted?.embeddingDegraded)
|
|
336
|
+
embeddingReasons.add(upserted.embeddingDegraded);
|
|
334
337
|
if (error || !upserted) {
|
|
335
338
|
filesSkipped += 1;
|
|
336
339
|
if (syncErrors.length < 20)
|
|
@@ -340,6 +343,10 @@ export class DeltaSyncRunner {
|
|
|
340
343
|
filesSkipped += 1;
|
|
341
344
|
if (upserted.mediaSkip)
|
|
342
345
|
mediaSkipped[upserted.mediaSkip] += 1;
|
|
346
|
+
if (upserted.binarySkip)
|
|
347
|
+
binarySkipped += 1;
|
|
348
|
+
if (upserted.binarySkip === 'content')
|
|
349
|
+
binaryUris.add(entry.uri);
|
|
343
350
|
}
|
|
344
351
|
else {
|
|
345
352
|
if (upserted.action === 'added')
|
|
@@ -419,30 +426,11 @@ export class DeltaSyncRunner {
|
|
|
419
426
|
const point = sweepPoints.get(uri);
|
|
420
427
|
if (!point)
|
|
421
428
|
continue; // vanished between the inventory and the hydrate
|
|
422
|
-
// A
|
|
423
|
-
//
|
|
424
|
-
//
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
// already resolved.
|
|
428
|
-
const inline = typeof point.payload.content === 'string' ? point.payload.content : undefined;
|
|
429
|
-
let healed;
|
|
430
|
-
try {
|
|
431
|
-
healed = inline === undefined ? await readHealContent(connector, point) : undefined;
|
|
432
|
-
}
|
|
433
|
-
catch (error) {
|
|
434
|
-
// A heal is an optional backfill for a point whose vector is fine:
|
|
435
|
-
// an unreadable file is reported, never a failed pass — that would
|
|
436
|
-
// freeze the checkpoint and park the source in error for good.
|
|
437
|
-
this.#logger.warn('sync.runner.heal.read_failed', {
|
|
438
|
-
uri,
|
|
439
|
-
code: error?.code ?? null,
|
|
440
|
-
error: error instanceof Error ? error.message : String(error),
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
const content = inline ?? healed;
|
|
444
|
-
const derived = buildEnrichmentRefresh(point.payload, uri, content, computeContributionEnrichment(uri, content ?? ''));
|
|
445
|
-
const refreshed = healed === undefined ? derived : { ...(derived ?? point.payload), content: healed };
|
|
429
|
+
// A point without inline text (a media point) never has its category
|
|
430
|
+
// re-derived from an empty string: that would demote a declared
|
|
431
|
+
// contribution the write path already resolved.
|
|
432
|
+
const content = typeof point.payload.content === 'string' ? point.payload.content : undefined;
|
|
433
|
+
const refreshed = buildEnrichmentRefresh(point.payload, uri, content, computeContributionEnrichment(uri, content ?? ''));
|
|
446
434
|
// Write even when nothing DRIFTED: this is the one-time upgrade pass
|
|
447
435
|
// that lands the stamp, and without it an already-correct point stays
|
|
448
436
|
// unstamped and is re-hydrated by every later full sync. The write is
|
|
@@ -452,13 +440,12 @@ export class DeltaSyncRunner {
|
|
|
452
440
|
// EXCEPT for a point whose content is not in hand: `stampEnrichment`
|
|
453
441
|
// REMOVES the stamp from an underivable payload by design, so such a
|
|
454
442
|
// point can never become current and an unconditional write here would
|
|
455
|
-
// re-write it on EVERY full pass, forever.
|
|
456
|
-
// matching bytes leaves the point here. Drift still writes; a no-op
|
|
443
|
+
// re-write it on EVERY full pass, forever. Drift still writes; a no-op
|
|
457
444
|
// upgrade on an underivable point does not.
|
|
458
445
|
if (!refreshed && content === undefined)
|
|
459
446
|
continue;
|
|
460
447
|
try {
|
|
461
|
-
await this.#deps.vector.
|
|
448
|
+
await this.#deps.vector.writePayload({ id: point.id, payload: refreshed ?? point.payload });
|
|
462
449
|
if (refreshed)
|
|
463
450
|
enrichmentRefreshed += 1;
|
|
464
451
|
}
|
|
@@ -497,6 +484,9 @@ export class DeltaSyncRunner {
|
|
|
497
484
|
const media = mediaKindOf(extractFilename(String(point.payload.uri ?? '')) ?? '');
|
|
498
485
|
return media !== null && !mediaLaneOn(normalizedJob.syncConfig.media, media.kind);
|
|
499
486
|
},
|
|
487
|
+
// A file this pass READ and judged binary by content: a point an
|
|
488
|
+
// earlier pass left is withdrawn here, recovery-aware like a pattern.
|
|
489
|
+
binaryUris,
|
|
500
490
|
signal: normalizedJob.signal,
|
|
501
491
|
});
|
|
502
492
|
for (const message of purged.errors)
|
|
@@ -583,12 +573,14 @@ export class DeltaSyncRunner {
|
|
|
583
573
|
chunksEmbedded: totalChunksEmbedded,
|
|
584
574
|
chunksSkipped: totalChunksSkipped,
|
|
585
575
|
durationMs: Date.now() - startedAt,
|
|
576
|
+
...(embeddingReasons.size ? { embeddingDegraded: [...embeddingReasons] } : {}),
|
|
586
577
|
...(filesTotal !== undefined ? { filesTotal } : {}),
|
|
587
578
|
...(indexedTotal !== undefined ? { indexedTotal } : {}),
|
|
588
579
|
...(unindexedTotal !== undefined ? { unindexedTotal } : {}),
|
|
589
580
|
...(fullScan.truncated ? { truncated: true, filesScanCap: scanCap } : {}),
|
|
590
581
|
...(checkpoint ? { checkpoint } : {}),
|
|
591
582
|
...(mediaSkipSummary(mediaSkipped) ? { mediaSkipped } : {}),
|
|
583
|
+
...(binarySkipped > 0 ? { binarySkipped } : {}),
|
|
592
584
|
...(syncErrors.length > 0 ? {
|
|
593
585
|
error: `${syncErrors.length} sync item(s) failed: ${syncErrors.join(' | ')}`,
|
|
594
586
|
errors: syncErrors,
|
|
@@ -668,6 +660,7 @@ export class DeltaSyncRunner {
|
|
|
668
660
|
let filesMoved = 0;
|
|
669
661
|
let totalChunksEmbedded = 0;
|
|
670
662
|
let totalChunksSkipped = 0;
|
|
663
|
+
const embeddingReasons = new Set();
|
|
671
664
|
const syncErrors = [];
|
|
672
665
|
const movedOldRefs = new Set();
|
|
673
666
|
const disappeared = new Map();
|
|
@@ -677,7 +670,8 @@ export class DeltaSyncRunner {
|
|
|
677
670
|
continue;
|
|
678
671
|
disappeared.set(uri, {
|
|
679
672
|
pointId: point.id,
|
|
680
|
-
|
|
673
|
+
// No hash, no move claim: a point under review is tombstoned, never relocated.
|
|
674
|
+
contentHash: point.payload.status !== 'pending_review' && typeof point.payload.content_hash === 'string' ? point.payload.content_hash : '',
|
|
681
675
|
});
|
|
682
676
|
}
|
|
683
677
|
const moves = new MoveClaims(disappeared);
|
|
@@ -699,6 +693,8 @@ export class DeltaSyncRunner {
|
|
|
699
693
|
// fail-fasts every tick; documented residual.)
|
|
700
694
|
let useLimitedError = null;
|
|
701
695
|
const mediaSkipped = emptyMediaSkipCounts();
|
|
696
|
+
const binarySniffChars = binarySniffCharsSetting();
|
|
697
|
+
let binarySkipped = 0;
|
|
702
698
|
const targetedTasks = changedUris.map((uri) => async () => {
|
|
703
699
|
if (job.signal?.aborted || useLimitedError)
|
|
704
700
|
return null;
|
|
@@ -718,7 +714,7 @@ export class DeltaSyncRunner {
|
|
|
718
714
|
modifiedAt: now,
|
|
719
715
|
...(typeof stat?.size === 'number' ? { size: stat.size } : {}),
|
|
720
716
|
};
|
|
721
|
-
const upserted = await this.#upsertFromSource(job, connector, entry, existing, moves);
|
|
717
|
+
const upserted = await this.#upsertFromSource(job, connector, entry, existing, moves, binarySniffChars);
|
|
722
718
|
return { uri, existing, upserted, error: null };
|
|
723
719
|
}
|
|
724
720
|
catch (error) {
|
|
@@ -741,6 +737,8 @@ export class DeltaSyncRunner {
|
|
|
741
737
|
continue;
|
|
742
738
|
const { uri, existing, upserted, error } = settled.value;
|
|
743
739
|
if (upserted) {
|
|
740
|
+
if (upserted.embeddingDegraded)
|
|
741
|
+
embeddingReasons.add(upserted.embeddingDegraded);
|
|
744
742
|
if (upserted.action === 'added')
|
|
745
743
|
filesAdded += 1;
|
|
746
744
|
else if (upserted.action === 'updated')
|
|
@@ -754,6 +752,8 @@ export class DeltaSyncRunner {
|
|
|
754
752
|
filesSkipped += 1;
|
|
755
753
|
if (upserted.mediaSkip)
|
|
756
754
|
mediaSkipped[upserted.mediaSkip] += 1;
|
|
755
|
+
if (upserted.binarySkip)
|
|
756
|
+
binarySkipped += 1;
|
|
757
757
|
}
|
|
758
758
|
totalChunksEmbedded += upserted.chunksEmbedded;
|
|
759
759
|
totalChunksSkipped += upserted.chunksSkipped;
|
|
@@ -818,7 +818,9 @@ export class DeltaSyncRunner {
|
|
|
818
818
|
chunksEmbedded: totalChunksEmbedded,
|
|
819
819
|
chunksSkipped: totalChunksSkipped,
|
|
820
820
|
durationMs: Date.now() - startedAt,
|
|
821
|
+
...(embeddingReasons.size ? { embeddingDegraded: [...embeddingReasons] } : {}),
|
|
821
822
|
...(mediaSkipSummary(mediaSkipped) ? { mediaSkipped } : {}),
|
|
823
|
+
...(binarySkipped > 0 ? { binarySkipped } : {}),
|
|
822
824
|
...(cancelled ? { error: 'Sync cancelled' } : syncErrors.length > 0 ? {
|
|
823
825
|
error: `${syncErrors.length} sync item(s) failed: ${syncErrors.join(' | ')}`,
|
|
824
826
|
errors: syncErrors,
|
|
@@ -945,13 +947,23 @@ export class DeltaSyncRunner {
|
|
|
945
947
|
} while (cursor);
|
|
946
948
|
return points;
|
|
947
949
|
}
|
|
950
|
+
#embeddingByJob = new WeakMap();
|
|
951
|
+
#embedderFor(job) {
|
|
952
|
+
let embedder = this.#embeddingByJob.get(job);
|
|
953
|
+
if (!embedder) {
|
|
954
|
+
embedder = createSyncJobEmbedder(this.#deps.embedder);
|
|
955
|
+
this.#embeddingByJob.set(job, embedder);
|
|
956
|
+
}
|
|
957
|
+
return embedder;
|
|
958
|
+
}
|
|
948
959
|
/** The ACTIVE model's modalities, asked once per job (a text-only port answers `['text']`). */
|
|
949
960
|
#modalitiesByJob = new WeakMap();
|
|
950
961
|
#modalitiesFor(job) {
|
|
951
962
|
let pending = this.#modalitiesByJob.get(job);
|
|
952
963
|
if (!pending) {
|
|
953
964
|
pending = this.#deps.embedder.modalities
|
|
954
|
-
? this.#deps.embedder.modalities().catch(
|
|
965
|
+
? this.#deps.embedder.modalities().catch(error => { if (!embeddingUnavailableReason(error))
|
|
966
|
+
throw error; return ['text']; })
|
|
955
967
|
: Promise.resolve(['text']);
|
|
956
968
|
this.#modalitiesByJob.set(job, pending);
|
|
957
969
|
}
|
|
@@ -970,7 +982,7 @@ export class DeltaSyncRunner {
|
|
|
970
982
|
const id = existing?.id ?? deterministicExternalNodeId(job, uri);
|
|
971
983
|
const now = this.#deps.clock.nowIso();
|
|
972
984
|
const osUri = resolveOsUri(uri, connector);
|
|
973
|
-
const outcome = await upsertMediaFromSource({ vector: this.#deps.vector, embedder: this.#
|
|
985
|
+
const outcome = await upsertMediaFromSource({ vector: this.#deps.vector, embedder: this.#embedderFor(job) }, connector, {
|
|
974
986
|
kind: media.kind,
|
|
975
987
|
mime: media.mime,
|
|
976
988
|
uri,
|
|
@@ -1024,12 +1036,14 @@ export class DeltaSyncRunner {
|
|
|
1024
1036
|
return outcome.reason ? { ...skipped, mediaSkip: outcome.reason } : skipped;
|
|
1025
1037
|
return {
|
|
1026
1038
|
action: existing ? 'updated' : 'added',
|
|
1027
|
-
chunksEmbedded:
|
|
1039
|
+
chunksEmbedded: outcome.chunksEmbedded,
|
|
1028
1040
|
chunksSkipped: 0,
|
|
1041
|
+
...(outcome.embeddingDegraded ? { embeddingDegraded: outcome.embeddingDegraded } : {}),
|
|
1029
1042
|
};
|
|
1030
1043
|
}
|
|
1031
|
-
async #upsertFromSource(job, connector, entry, indexedAtUri, moves) {
|
|
1044
|
+
async #upsertFromSource(job, connector, entry, indexedAtUri, moves, binarySniffChars) {
|
|
1032
1045
|
const skipped = { action: 'skipped', chunksEmbedded: 0, chunksSkipped: 0 };
|
|
1046
|
+
const binary = (by) => ({ ...skipped, binarySkip: by });
|
|
1033
1047
|
const uri = entry.uri;
|
|
1034
1048
|
const filename = extractFilename(uri);
|
|
1035
1049
|
if (!filename)
|
|
@@ -1040,7 +1054,7 @@ export class DeltaSyncRunner {
|
|
|
1040
1054
|
if (media)
|
|
1041
1055
|
return this.#upsertMedia(job, connector, entry, indexedAtUri, filename, media);
|
|
1042
1056
|
if (isBinaryFile(filename))
|
|
1043
|
-
return
|
|
1057
|
+
return binary('extension');
|
|
1044
1058
|
// Skip files larger than the size cap (live): `brainSyncMaxFileMb` (5 MB),
|
|
1045
1059
|
// or `brainSyncMaxAppendFileMb` (20 MB) for an append-shaped file, whose
|
|
1046
1060
|
// append re-embeds only the tail — never above the connector read cap
|
|
@@ -1052,6 +1066,8 @@ export class DeltaSyncRunner {
|
|
|
1052
1066
|
return skipped;
|
|
1053
1067
|
const readResult = await connector.read(entry.uri);
|
|
1054
1068
|
const content = String(readResult.text ?? '');
|
|
1069
|
+
if (looksBinaryContent(content, binarySniffChars))
|
|
1070
|
+
return binary('content');
|
|
1055
1071
|
const { contentHash: content_hash, provenPrefixChars, stored } = hashSyncedFile(filename, content, indexedAtUri?.payload);
|
|
1056
1072
|
const now = this.#deps.clock.nowIso();
|
|
1057
1073
|
// A new uri whose content is exactly ONE point that left disk in this pass
|
|
@@ -1074,201 +1090,20 @@ export class DeltaSyncRunner {
|
|
|
1074
1090
|
const written = (action, chunks) => (movedFrom
|
|
1075
1091
|
? { action: 'moved', movedFrom, chunksEmbedded: chunks.embedded, chunksSkipped: chunks.skipped }
|
|
1076
1092
|
: { action, chunksEmbedded: chunks.embedded, chunksSkipped: chunks.skipped });
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
...existing.payload,
|
|
1085
|
-
version: buildVersionInfo({
|
|
1086
|
-
previous: existing.payload.version,
|
|
1087
|
-
previousContent: existing.payload.content,
|
|
1088
|
-
nextContent: existing.payload.content,
|
|
1089
|
-
changedAt: existing.payload.version?.changedAt ?? existing.payload.updatedAt,
|
|
1090
|
-
sourceChangedAt,
|
|
1091
|
-
sourceVersion: content_hash,
|
|
1092
|
-
indexedAt: now,
|
|
1093
|
-
sync: {
|
|
1094
|
-
...(existing.payload.version?.sync ?? {}),
|
|
1095
|
-
sourceUpdatedAt: entry.modifiedAt,
|
|
1096
|
-
sourceSize: entry.size,
|
|
1097
|
-
syncedAt: now,
|
|
1098
|
-
upstreamContentHash: content_hash,
|
|
1099
|
-
lastSyncedAgentId: job.agentId,
|
|
1100
|
-
status: 'stale',
|
|
1101
|
-
},
|
|
1102
|
-
}),
|
|
1103
|
-
status: 'pending_review',
|
|
1104
|
-
updatedAt: now,
|
|
1105
|
-
};
|
|
1106
|
-
if (existing.payload.recovery_only === true) {
|
|
1107
|
-
await this.#deps.vector.retainPayload({ id, payload });
|
|
1108
|
-
}
|
|
1109
|
-
else {
|
|
1110
|
-
await this.#deps.vector.upsert({ id, payload });
|
|
1111
|
-
}
|
|
1112
|
-
return written('updated', { embedded: 0, skipped: 0 });
|
|
1113
|
-
}
|
|
1114
|
-
const enrichment = computeContributionEnrichment(entry.uri, content);
|
|
1115
|
-
// The first reuse gate — an unchanged committed file only refreshes its
|
|
1116
|
-
// payload. A forced re-embed skips it, and keeps that payload instead
|
|
1117
|
-
// (below): an unchanged file must not read as changed.
|
|
1118
|
-
const sameContent = !movedFrom && existing?.payload?.content_hash === content_hash && existing.payload.status === 'committed' && !existing.payload.recovery_only;
|
|
1119
|
-
if (!job.force && sameContent) {
|
|
1120
|
-
// Payload-only refresh BEFORE the content-hash skip: unchanged files
|
|
1121
|
-
// still pick up new category/frontmatter/manifest enrichment after a
|
|
1122
|
-
// deploy (the stored vector is kept). One sync pass migrates a source.
|
|
1123
|
-
// A point that lost its inline content gets it back here — it is in hand.
|
|
1124
|
-
const contentless = typeof existing.payload.content !== 'string';
|
|
1125
|
-
const derived = buildEnrichmentRefresh(existing.payload, entry.uri, content, enrichment);
|
|
1126
|
-
const refreshed = contentless ? { ...(derived ?? existing.payload), content: stored } : derived;
|
|
1127
|
-
// A hash-matched point that has NOT drifted still needs the stamp, or it
|
|
1128
|
-
// stays a sweep candidate forever: the sweep skips it (it is in the
|
|
1129
|
-
// changed set) and the next full pass no longer sees it as changed. One
|
|
1130
|
-
// payload-only write here closes it in the same pass.
|
|
1131
|
-
if (refreshed || !isEnrichmentCurrent(existing.payload)) {
|
|
1132
|
-
await this.#deps.vector.upsert({ id, payload: refreshed ?? existing.payload });
|
|
1133
|
-
}
|
|
1134
|
-
return skipped;
|
|
1135
|
-
}
|
|
1136
|
-
// The parent vector is keyed on its embedding TEXT: when the stored one was
|
|
1137
|
-
// built from the same text (an append past the text cap, a move that kept
|
|
1138
|
-
// its filename), the parent write below is payload-only.
|
|
1139
|
-
const embeddingText = syncEmbeddingText(filename, content);
|
|
1140
|
-
const embedParent = () => this.#deps.embedder.embedText(embeddingText, job.signal ? { signal: job.signal } : undefined);
|
|
1141
|
-
// The second reuse gate — the stored parent vector was built from this
|
|
1142
|
-
// exact text. A forced re-embed skips it too.
|
|
1143
|
-
const reuseVector = !job.force && existing && !existing.payload.recovery_only ? storedVectorMatchesText(existing.payload, embeddingText) : false;
|
|
1144
|
-
let embedded = null;
|
|
1145
|
-
try {
|
|
1146
|
-
if (!reuseVector)
|
|
1147
|
-
embedded = await embedParent();
|
|
1148
|
-
}
|
|
1149
|
-
catch (error) {
|
|
1150
|
-
// An embed outage (exhausted credits, a provider 429) must not freeze the
|
|
1151
|
-
// existing point's DERIVED metadata: the index keeps carrying the OLD
|
|
1152
|
-
// content, so category / frontmatter / manifest flags are re-derived from
|
|
1153
|
-
// THAT content, payload-only (vector kept) — exactly what the enrichment
|
|
1154
|
-
// sweep would do, which skips this file only because it sits in the
|
|
1155
|
-
// changed set. The file's own failure is still reported by the caller;
|
|
1156
|
-
// nothing here claims the new content was indexed.
|
|
1157
|
-
if (!movedFrom && existing?.payload && typeof existing.payload.content === 'string') {
|
|
1158
|
-
const stale = existing.payload.content;
|
|
1159
|
-
const refreshed = buildEnrichmentRefresh(existing.payload, entry.uri, stale, computeContributionEnrichment(entry.uri, stale));
|
|
1160
|
-
if (refreshed) {
|
|
1161
|
-
try {
|
|
1162
|
-
await this.#deps.vector.upsert({ id, payload: refreshed });
|
|
1163
|
-
}
|
|
1164
|
-
catch {
|
|
1165
|
-
// The embed failure is the error the caller reports; a failed
|
|
1166
|
-
// metadata refresh changes nothing about that.
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
throw error;
|
|
1171
|
-
}
|
|
1172
|
-
// A forced re-embed of UNCHANGED content writes the stored payload back as
|
|
1173
|
-
// it is (`updatedAt`, `version`, `createdAt`, …) with the inline text it
|
|
1174
|
-
// embeds; only the vector and the boundary's `embed_model` stamp move.
|
|
1175
|
-
const payload = (sameContent || restoringDraft) && existing ? { ...existing.payload, content: stored } : {
|
|
1176
|
-
id,
|
|
1177
|
-
uri,
|
|
1178
|
-
folder_ancestors: uriAncestors(uri),
|
|
1179
|
-
filename,
|
|
1180
|
-
os_uri: resolveOsUri(uri, connector),
|
|
1181
|
-
userId: job.userId,
|
|
1182
|
-
projectId: job.projectId,
|
|
1183
|
-
agentId: job.agentId,
|
|
1184
|
-
...(existing?.payload.userName ? { userName: existing.payload.userName } : {}),
|
|
1185
|
-
// A payload-only write (the reused vector) keeps the stored marker; a
|
|
1186
|
-
// vector write is re-stamped by the write boundary.
|
|
1187
|
-
...(existing?.payload.embed_model ? { embed_model: existing.payload.embed_model } : {}),
|
|
1188
|
-
pinned: existing?.payload.pinned === true,
|
|
1189
|
-
status: 'committed',
|
|
1190
|
-
category: resolveSyncCategory(existing?.payload.category, entry.uri, content),
|
|
1191
|
-
tags: existing?.payload.tags ?? [],
|
|
1192
|
-
metadata: {
|
|
1193
|
-
...(existing?.payload.metadata ?? {}),
|
|
1194
|
-
},
|
|
1195
|
-
// Source-package enrichment (A3) — file points only, never chunks (F8).
|
|
1196
|
-
...(enrichment.manifest_usable ? { manifest_usable: true } : {}),
|
|
1197
|
-
...(enrichment.agent_owner ? { agent_owner: enrichment.agent_owner } : {}),
|
|
1198
|
-
...(enrichment.frontmatter ? { frontmatter: enrichment.frontmatter } : {}),
|
|
1199
|
-
content: stored, // the indexed prefix; `content_hash` stays the WHOLE file's
|
|
1200
|
-
content_hash,
|
|
1201
|
-
createdAt: existing?.payload.createdAt ?? now,
|
|
1202
|
-
updatedAt: now,
|
|
1203
|
-
version: buildVersionInfo({
|
|
1204
|
-
previous: existing?.payload.version,
|
|
1205
|
-
previousContent: typeof existing?.payload.content === 'string' ? syncStoredText(existing.payload.content) : undefined,
|
|
1206
|
-
nextContent: stored,
|
|
1207
|
-
previousChangedAt: existing?.payload.version?.changedAt ?? existing?.payload.updatedAt,
|
|
1208
|
-
changedAt: now,
|
|
1209
|
-
sourceChangedAt,
|
|
1210
|
-
sourceVersion: content_hash,
|
|
1211
|
-
indexedAt: now,
|
|
1212
|
-
sync: {
|
|
1213
|
-
sourceUpdatedAt: entry.modifiedAt,
|
|
1214
|
-
sourceSize: entry.size,
|
|
1215
|
-
syncedAt: now,
|
|
1216
|
-
upstreamContentHash: content_hash,
|
|
1217
|
-
lastSyncedAgentId: job.agentId,
|
|
1218
|
-
status: 'synced',
|
|
1219
|
-
},
|
|
1220
|
-
}),
|
|
1093
|
+
const result = await syncIndexedFile({ vector: this.#deps.vector, embedder: this.#embedderFor(job) }, {
|
|
1094
|
+
job, connector, entry, existing, id, filename, content, contentHash: content_hash,
|
|
1095
|
+
stored, provenPrefixChars, now, movedFrom, indexedAtUri: Boolean(indexedAtUri),
|
|
1096
|
+
});
|
|
1097
|
+
return result.action === 'skipped' ? skipped : {
|
|
1098
|
+
...written(result.action, { embedded: result.chunksEmbedded, skipped: result.chunksSkipped }),
|
|
1099
|
+
...(result.embeddingDegraded ? { embeddingDegraded: result.embeddingDegraded } : {}),
|
|
1221
1100
|
};
|
|
1222
|
-
// Chunk ingestion BEFORE the parent upsert: the parent's content_hash is
|
|
1223
|
-
// the convergence marker — if an abort lands mid-chunking, the parent
|
|
1224
|
-
// still carries the OLD hash, so the next run reprocesses the file and
|
|
1225
|
-
// the deterministic chunk ids converge. (Parent-first left a window where
|
|
1226
|
-
// a hash-matched skip would never backfill the missing chunks.)
|
|
1227
|
-
let chunksEmbedded = 0;
|
|
1228
|
-
let chunksSkipped = 0;
|
|
1229
|
-
if (content.length > 0) {
|
|
1230
|
-
// The chunks inherit the fields the parent point carries (a carried
|
|
1231
|
-
// payload keeps its own writer's identity, so its chunks do too).
|
|
1232
|
-
const parentFields = {
|
|
1233
|
-
userId: payload.userId,
|
|
1234
|
-
projectId: payload.projectId,
|
|
1235
|
-
agentId: payload.agentId,
|
|
1236
|
-
uri: payload.uri,
|
|
1237
|
-
folder_ancestors: payload.folder_ancestors,
|
|
1238
|
-
filename: payload.filename,
|
|
1239
|
-
os_uri: payload.os_uri,
|
|
1240
|
-
status: 'committed',
|
|
1241
|
-
};
|
|
1242
|
-
const chunkUsage = {};
|
|
1243
|
-
const chunkResult = await upsertChunksForContent({ vector: this.#deps.vector, embedder: this.#deps.embedder }, id, parentFields, content, entry.uri, chunkUsage, {
|
|
1244
|
-
...(job.signal ? { signal: job.signal } : {}),
|
|
1245
|
-
...(provenPrefixChars !== undefined && !job.force ? { appendOf: { prefixChars: provenPrefixChars } } : {}),
|
|
1246
|
-
...(job.force ? { force: true } : {}),
|
|
1247
|
-
});
|
|
1248
|
-
chunksEmbedded = chunkResult.embedded;
|
|
1249
|
-
chunksSkipped = chunkResult.skipped;
|
|
1250
|
-
// A moved point's chunks kept their vectors (same ids, same text); only
|
|
1251
|
-
// their denormalized location follows the parent, payload-only.
|
|
1252
|
-
if (movedFrom)
|
|
1253
|
-
await relocateChunksForParent({ vector: this.#deps.vector }, id, parentFields);
|
|
1254
|
-
}
|
|
1255
|
-
if (embedded) {
|
|
1256
|
-
await this.#deps.vector.upsert({ id, vector: embedded.embedding, payload });
|
|
1257
|
-
}
|
|
1258
|
-
else {
|
|
1259
|
-
try {
|
|
1260
|
-
await this.#deps.vector.upsert({ id, payload });
|
|
1261
|
-
}
|
|
1262
|
-
catch (error) {
|
|
1263
|
-
// The text matched but no vector is stored under the id: embed after all.
|
|
1264
|
-
if (!isVectorMissingError(error))
|
|
1265
|
-
throw error;
|
|
1266
|
-
await this.#deps.vector.upsert({ id, vector: (await embedParent()).embedding, payload });
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
return written(indexedAtUri ? 'updated' : 'added', { embedded: chunksEmbedded, skipped: chunksSkipped });
|
|
1270
1101
|
}
|
|
1271
1102
|
}
|
|
1103
|
+
/** Read once per job, never per file (`brainSyncBinarySniffChars`, 0 = off). */
|
|
1104
|
+
function binarySniffCharsSetting() {
|
|
1105
|
+
return Math.max(0, Math.floor(getBrainConfigNumber('brainSyncBinarySniffChars', undefined, BINARY_SNIFF_CHARS)));
|
|
1106
|
+
}
|
|
1272
1107
|
function deterministicExternalNodeId(job, sourceRef) {
|
|
1273
1108
|
const hash = createHash('sha1')
|
|
1274
1109
|
.update(`${job.userId}:${job.projectId}:${job.source}:${sourceRef}`)
|