@romiluz/clawmongo 2026.3.26 → 2026.3.28
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 +84 -49
- package/dist/{accounts-boH28BFM.js → accounts-lL2y51Ag.js} +46 -46
- package/dist/{acp-cli-DLaTb29R.js → acp-cli-BZvVHRY8.js} +46 -46
- package/dist/{action-runtime-Bk-7pvN2.js → action-runtime-DMYRUL4q.js} +10 -10
- package/dist/{actions.runtime-Y529miLb.js → actions.runtime-Bd-NMAq6.js} +46 -46
- package/dist/{actions.runtime-DVQ4pmcp.js → actions.runtime-gPSeXscW.js} +49 -49
- package/dist/{agent-scope-BROpmzKv.js → agent-scope-DXZH506l.js} +1 -1
- package/dist/{agents-DZqtbDMD.js → agents-Bt25bmDR.js} +13 -13
- package/dist/{agents-BbO-i90j.js → agents-CyJmttnS.js} +114 -114
- package/dist/{agents.config-CDS6iAat.js → agents.config-BWm70Hr6.js} +2 -2
- package/dist/{agents.config-iY500LY-.js → agents.config-UsCw0kOR.js} +4 -4
- package/dist/{audit-Cmj7BNcZ.js → audit-Dg8ZiJrJ.js} +9 -9
- package/dist/{audit-DmXeao7s.js → audit-DhXhWoiv.js} +1 -1
- package/dist/{audit-channel.collect.runtime-DhP09fjv.js → audit-channel.collect.runtime-CvPUHy1X.js} +2 -2
- package/dist/{audit-channel.runtime-C-watgwg.js → audit-channel.runtime-B6ZnOPFc.js} +46 -46
- package/dist/{audit-extra.async-B-7dzgcz.js → audit-extra.async-826UZZhJ.js} +3 -3
- package/dist/{audit-membership-runtime-CbLi3-5b.js → audit-membership-runtime-DLQrV7Rr.js} +46 -46
- package/dist/{audit.deep.runtime-D5VgrTOT.js → audit.deep.runtime-DQDtV7Bc.js} +4 -4
- package/dist/{audit.nondeep.runtime-B7M0-7FZ.js → audit.nondeep.runtime-H6B-2xal.js} +4 -4
- package/dist/{audit.runtime-BUknqGaP.js → audit.runtime-D2ZRC2A_.js} +47 -47
- package/dist/{auth-choice-DfJRosb4.js → auth-choice-CEowrO66.js} +57 -57
- package/dist/{auth-choice-CpB99A-L.js → auth-choice-DiufM1b8.js} +55 -55
- package/dist/{auth-choice-Bnnngmkx.js → auth-choice-YrGxwB9A.js} +5 -5
- package/dist/{auth-choice-options-DvqJHFOp.js → auth-choice-options-n3_uFdT5.js} +2 -2
- package/dist/{auth-choice-prompt-DtTjWfPT.js → auth-choice-prompt-DYFzoWa6.js} +50 -50
- package/dist/{auth-choice-prompt-Cxz8du6E.js → auth-choice-prompt-sLET2Bkw.js} +1 -1
- package/dist/{auth-choice.apply-helpers-Bm5p2ZX7.js → auth-choice.apply-helpers-GU6nZntg.js} +1 -1
- package/dist/{auth-choice.plugin-providers.runtime-Dsu6-vb8.js → auth-choice.plugin-providers.runtime-BNqOEEtb.js} +47 -47
- package/dist/{auth-profiles-2-OV37OF.js → auth-profiles-BWBQJ6X_.js} +67 -76
- package/dist/{auth-profiles.runtime-HcQMBs3K.js → auth-profiles.runtime-DfKRAmQR.js} +46 -46
- package/dist/{backend-config-avgzgS5Z.js → backend-config--L236wE2.js} +26 -1
- package/dist/{backup-create-B9F0M7-J.js → backup-create-Bll6DgoT.js} +2 -2
- package/dist/{base-session-key-DyLtSGkj.js → base-session-key-CA4SoGLF.js} +1 -1
- package/dist/{bluebubbles-BTR7u4zE.js → bluebubbles-BsX68JOY.js} +6 -6
- package/dist/{browser-cli-tmytvFaa.js → browser-cli-B5euA0cQ.js} +8 -8
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +46 -46
- package/dist/bundled/bootstrap-extra-files/handler.js +1 -1
- package/dist/bundled/session-memory/handler.js +47 -47
- package/dist/{call-Cqem-bCB.js → call-C-_XQxw5.js} +1 -1
- package/dist/{call-CxVOiYz-.js → call-lPTaDgAg.js} +6 -6
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-Br8MF00M.js → channel-5o-oIU2B.js} +1 -1
- package/dist/{channel-BvRm4jSj.js → channel-C1zZg_8b.js} +2 -2
- package/dist/{channel-CqkxOhz2.js → channel-CEytBPH-.js} +4 -4
- package/dist/{channel-D_h7IfYK.js → channel-Cm65A1lo.js} +7 -7
- package/dist/{channel-ngZRDeE3.js → channel-D4K0MVgr.js} +5 -5
- package/dist/{channel-account-context-DZhZw4oo.js → channel-account-context-CNZZPDSe.js} +1 -1
- package/dist/{channel-plugin-resolution-CXm5HIcm.js → channel-plugin-resolution-WWO690RK.js} +3 -3
- package/dist/{channel-reply-pipeline-DdDsf-Lc.js → channel-reply-pipeline-B17-tBLU.js} +1 -1
- package/dist/{channel-shared-VIRIADYn.js → channel-shared-RH6YsZ0I.js} +1 -1
- package/dist/{channel-summary-BTJxLPN8.js → channel-summary-Cy7WDRjQ.js} +7 -7
- package/dist/{channel-summary-DdJtHlvH.js → channel-summary-DV4_b3HZ.js} +2 -2
- package/dist/{channel-tFDEkWt9.js → channel-yCiI29Ju.js} +6 -6
- package/dist/{channel.runtime-DGnRryi2.js → channel.runtime-C3m1vacV.js} +47 -47
- package/dist/{channel.runtime-CdPEA_wb.js → channel.runtime-CUSE7Dn0.js} +47 -47
- package/dist/{channel.runtime-0n3_Hz_Y.js → channel.runtime-CtWi36oj.js} +49 -49
- package/dist/{channel.runtime-CkHcsWQ3.js → channel.runtime-LUpQZiWg.js} +49 -49
- package/dist/{channel.runtime-msXRrVzC.js → channel.runtime-QOkM4mJV.js} +51 -51
- package/dist/{channel.runtime-khqV1QRG.js → channel.runtime-rYuUs2po.js} +4 -4
- package/dist/{channels-DNza27NY.js → channels-4VTbN2Gt.js} +103 -103
- package/dist/{channels-CLZoq3SY.js → channels-BUMnLXLQ.js} +1 -1
- package/dist/{channels-cli-Bhsnjsix.js → channels-cli-BYmLj8zw.js} +55 -55
- package/dist/{clawbot-cli-9YJNF9pF.js → clawbot-cli-CIYY1u-6.js} +47 -47
- package/dist/cli/daemon-cli.js +1 -1
- package/dist/{cli-FF5823nM.js → cli-DUA0FvhM.js} +46 -46
- package/dist/{command-registry-Dw-TONf0.js → command-registry-B1ECZip_.js} +13 -13
- package/dist/{command-registry-TeN0aKPi.js → command-registry-DOAwIs0Y.js} +2 -2
- package/dist/{command-secret-gateway-CzHSHmXG.js → command-secret-gateway-Big-n6JY.js} +46 -46
- package/dist/{compact.runtime-Bye-pm7Z.js → compact.runtime-BKnPPv9X.js} +46 -46
- package/dist/{completion-cli-D08RAGPz.js → completion-cli-BeLNvVTI.js} +3 -3
- package/dist/{completion-cli-C0mwyiAb.js → completion-cli-CHwHDPuI.js} +2 -2
- package/dist/{config-Ca7pLyBD.js → config-BOWZMmDA.js} +1 -1
- package/dist/{config-GKOWhVMv.js → config-C68iwvDj.js} +5 -5
- package/dist/{config-cli-CxPspN-S.js → config-cli-BnC336Lu.js} +48 -48
- package/dist/{config-guard-BK2hWyPi.js → config-guard-Bn6rZnzK.js} +6 -6
- package/dist/{config-validation-DO6o_Kt_.js → config-validation-BBuJZ-WH.js} +2 -2
- package/dist/{configure-CODqvxU-.js → configure-CHJDsjOD.js} +120 -120
- package/dist/{configure-Dg65gBEw.js → configure-Cctw7tyJ.js} +19 -23
- package/dist/{connection-auth-zhL6PVn0.js → connection-auth-C2XaPpF5.js} +1 -1
- package/dist/{control-ui-shared-_VwcOcc_.js → control-ui-shared-BC-g150y.js} +1 -1
- package/dist/{core-CzwQmKcn.js → core-Cb3XxL6S.js} +1 -1
- package/dist/{cron-cli-Dp_EQt2v.js → cron-cli-C10feOtH.js} +7 -7
- package/dist/{daemon-cli-Dgpv6Y0R.js → daemon-cli-Ds8mu2VZ.js} +4 -4
- package/dist/{daemon-install-Dq1Ix-FO.js → daemon-install-B__sP_7j.js} +49 -49
- package/dist/{delegate-BVapk4rY.js → delegate-ByCLviVI.js} +1 -1
- package/dist/{deliver-runtime-DPzMjhNU.js → deliver-Co7G5ubS.js} +46 -46
- package/dist/{deliver-C32Gg-xU.js → deliver-runtime-2svrtAf1.js} +46 -46
- package/dist/{devices-cli-3WN_wB1C.js → devices-cli-CH8nWgcU.js} +6 -6
- package/dist/{diagnostic-BbXfhLMi.js → diagnostic-DHTG43d_.js} +1 -1
- package/dist/{directory-cli-D_5BYdXm.js → directory-cli-B0REFlKo.js} +48 -48
- package/dist/{directory.static-CsajbHw1.js → directory.static-wnw_R8dE.js} +1 -1
- package/dist/{discord-C-4y9vOT.js → discord-Cws9MsXn.js} +4 -4
- package/dist/{discord-B3mmVXuG.js → discord-b8Ff_BKB.js} +46 -46
- package/dist/{dns-cli-CdAnUzRi.js → dns-cli-aRTleL5e.js} +5 -5
- package/dist/{doctor-completion-BnqTtLhL.js → doctor-completion-KQWBMnEi.js} +1 -1
- package/dist/{doctor-config-preflight-BJ0lGLTO.js → doctor-config-preflight-BDYe5di1.js} +2 -2
- package/dist/{doctor-config-preflight-D32oVOWD.js → doctor-config-preflight-Dn5a_Dbr.js} +6 -6
- package/dist/{doctor-state-migrations-BklDIib1.js → doctor-state-migrations-BI6HzFyq.js} +47 -47
- package/dist/{doctor-state-migrations-Cdk3ep_f.js → doctor-state-migrations-DUPe9zNr.js} +2 -2
- package/dist/entry.js +1 -1
- package/dist/{exec-approvals-D8OOtgGc.js → exec-approvals-CZz2LqIW.js} +1 -1
- package/dist/{exec-approvals-cli-dGISWHE3.js → exec-approvals-cli-KbFpgd-p.js} +9 -9
- package/dist/extensionAPI.js +46 -46
- package/dist/extensions/amazon-bedrock/index.js +46 -46
- package/dist/extensions/anthropic/index.js +46 -46
- package/dist/extensions/bluebubbles/index.js +50 -50
- package/dist/extensions/bluebubbles/setup-entry.js +48 -48
- package/dist/extensions/byteplus/index.js +46 -46
- package/dist/extensions/chutes/index.js +48 -48
- package/dist/extensions/cloudflare-ai-gateway/index.js +47 -47
- package/dist/extensions/device-pair/index.js +46 -46
- package/dist/extensions/discord/index.js +48 -48
- package/dist/extensions/discord/node_modules/.package-lock.json +3 -3
- package/dist/extensions/discord/node_modules/hono/dist/adapter/service-worker/index.js +1 -3
- package/dist/extensions/discord/node_modules/hono/dist/cjs/adapter/service-worker/index.js +1 -3
- package/dist/extensions/discord/node_modules/hono/dist/cjs/helper/ssg/ssg.js +1 -1
- package/dist/extensions/discord/node_modules/hono/dist/cjs/middleware/cors/index.js +5 -2
- package/dist/extensions/discord/node_modules/hono/dist/cjs/request.js +1 -1
- package/dist/extensions/discord/node_modules/hono/dist/helper/ssg/ssg.js +1 -1
- package/dist/extensions/discord/node_modules/hono/dist/middleware/cors/index.js +5 -2
- package/dist/extensions/discord/node_modules/hono/dist/request.js +1 -1
- package/dist/extensions/discord/node_modules/hono/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/extensions/discord/node_modules/hono/dist/types/client/index.d.ts +1 -1
- package/dist/extensions/discord/node_modules/hono/dist/types/client/types.d.ts +20 -0
- package/dist/extensions/discord/node_modules/hono/dist/types/request.d.ts +1 -3
- package/dist/extensions/discord/node_modules/hono/package.json +1 -1
- package/dist/extensions/discord/setup-entry.js +48 -48
- package/dist/extensions/elevenlabs/index.js +46 -46
- package/dist/extensions/fal/index.js +46 -46
- package/dist/extensions/feishu/index.js +55 -55
- package/dist/extensions/feishu/setup-entry.js +51 -51
- package/dist/extensions/firecrawl/index.js +46 -46
- package/dist/extensions/github-copilot/index.js +47 -47
- package/dist/extensions/google/index.js +46 -46
- package/dist/extensions/huggingface/index.js +47 -47
- package/dist/extensions/imessage/index.js +49 -49
- package/dist/extensions/imessage/setup-entry.js +49 -49
- package/dist/extensions/irc/index.js +49 -49
- package/dist/extensions/irc/setup-entry.js +48 -48
- package/dist/extensions/kilocode/index.js +47 -47
- package/dist/extensions/kimi-coding/index.js +47 -47
- package/dist/extensions/line/index.js +9 -9
- package/dist/extensions/line/setup-entry.js +8 -8
- package/dist/extensions/llm-task/index.js +46 -46
- package/dist/extensions/lobster/index.js +5 -5
- package/dist/extensions/mattermost/index.js +49 -49
- package/dist/extensions/mattermost/setup-entry.js +48 -48
- package/dist/extensions/microsoft/index.js +46 -46
- package/dist/extensions/minimax/index.js +48 -48
- package/dist/extensions/mistral/index.js +47 -47
- package/dist/extensions/modelstudio/index.js +47 -47
- package/dist/extensions/moonshot/index.js +46 -46
- package/dist/extensions/nextcloud-talk/index.js +50 -50
- package/dist/extensions/nextcloud-talk/setup-entry.js +49 -49
- package/dist/extensions/ollama/index.js +5 -5
- package/dist/extensions/openai/index.js +47 -47
- package/dist/extensions/opencode/index.js +47 -47
- package/dist/extensions/opencode-go/index.js +47 -47
- package/dist/extensions/openrouter/index.js +47 -47
- package/dist/extensions/openshell/index.js +46 -46
- package/dist/extensions/qianfan/index.js +47 -47
- package/dist/extensions/qwen-portal-auth/index.js +47 -47
- package/dist/extensions/sglang/index.js +46 -46
- package/dist/extensions/signal/index.js +49 -49
- package/dist/extensions/signal/setup-entry.js +49 -49
- package/dist/extensions/slack/index.js +50 -50
- package/dist/extensions/slack/setup-entry.js +50 -50
- package/dist/extensions/synology-chat/index.js +9 -9
- package/dist/extensions/synology-chat/setup-entry.js +8 -8
- package/dist/extensions/synthetic/index.js +47 -47
- package/dist/extensions/talk-voice/index.js +46 -46
- package/dist/extensions/tavily/index.js +46 -46
- package/dist/extensions/telegram/index.js +48 -48
- package/dist/extensions/telegram/setup-entry.js +48 -48
- package/dist/extensions/together/index.js +47 -47
- package/dist/extensions/venice/index.js +47 -47
- package/dist/extensions/vercel-ai-gateway/index.js +47 -47
- package/dist/extensions/vllm/index.js +46 -46
- package/dist/extensions/voice-call/index.js +46 -46
- package/dist/extensions/volcengine/index.js +46 -46
- package/dist/extensions/xai/index.js +46 -46
- package/dist/extensions/xiaomi/index.js +47 -47
- package/dist/extensions/zai/index.js +47 -47
- package/dist/extensions/zalo/index.js +49 -49
- package/dist/extensions/zalo/setup-entry.js +48 -48
- package/dist/{feishu-C637DYYe.js → feishu-D2fuiOiy.js} +4 -4
- package/dist/{gateway-cli-Cuk9d7J2.js → gateway-cli-nOgyXtih.js} +72 -106
- package/dist/{gateway-install-token-DlcVm1rP.js → gateway-install-token-nvsTK8KN.js} +4 -4
- package/dist/{gateway-rpc-siKa8KpM.js → gateway-rpc-DrH142-v.js} +1 -1
- package/dist/{gateway-runtime-roiTaOKO.js → gateway-runtime-CQXKGzrv.js} +2 -2
- package/dist/{github-copilot-auth-DJljh3gq.js → github-copilot-auth-C4z2AAd8.js} +3 -3
- package/dist/{health-DU_pBiid.js → health-DEgLPyA9.js} +7 -7
- package/dist/{health-B1OK1kJg.js → health-H5nbiXvA.js} +48 -48
- package/dist/{heartbeat-summary-CMwt9qam.js → heartbeat-summary-CNCptWmA.js} +1 -1
- package/dist/{hooks-cli-D42hQEUb.js → hooks-cli-jBhsJaOg.js} +46 -46
- package/dist/{identity-file-8MUyIAOy.js → identity-file-CYQnH12I.js} +1 -1
- package/dist/{imessage-zqZjecTU.js → imessage-DYqgZpLc.js} +6 -6
- package/dist/{imessage-CZb_pS8U.js → imessage-Dau6WdE3.js} +46 -46
- package/dist/{inbound-reply-dispatch-B73AkQh4.js → inbound-reply-dispatch-BFE3xy1S.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{internal-Bg_k56Pk.js → internal-DLE9baj7.js} +0 -24
- package/dist/{io-DE9vm7Eo.js → io-Du0b8gMO.js} +2 -2
- package/dist/{io-B7rO2wud.js → io-dJgqp8U8.js} +4 -4
- package/dist/{irc-BWzsfr2V.js → irc-BRaOVUse.js} +2 -2
- package/dist/{kb-cli-BOPGkNfJ.js → kb-cli-Cdif_vwn.js} +12 -12
- package/dist/{library-i-2ymInt.js → library-BwjFIWw3.js} +46 -46
- package/dist/{lifecycle-core-DwIo1PfK.js → lifecycle-core-DNO4MItg.js} +1 -1
- package/dist/line/send.js +6 -6
- package/dist/{line-DbTKdVgY.js → line-BCXUGrVz.js} +2 -2
- package/dist/{llm-slug-generator-Dm30OM2W.js → llm-slug-generator-B55FZ1aG.js} +3 -3
- package/dist/llm-slug-generator.js +47 -47
- package/dist/{logging-BM4mQ53W.js → logging-BvOzg0cM.js} +1 -1
- package/dist/{logging-0tvlVvFG.js → logging-nWyKsj9d.js} +5 -5
- package/dist/{login-qr-DQPSabxI.js → login-qr-C0QA3j4x.js} +46 -46
- package/dist/{logs-cli-ZnHk5eku.js → logs-cli-thlXBA9n.js} +7 -7
- package/dist/{manager.runtime-D3vjUOZF.js → manager.runtime-SoTq-tT4.js} +46 -46
- package/dist/{matrix-migration-snapshot-CRKiHq6Y.js → matrix-migration-snapshot-_6Rg-iLO.js} +2 -2
- package/dist/{mattermost-Bqn7Fd5U.js → mattermost-2nv5O_jQ.js} +2 -2
- package/dist/{mcp-cli-7aN2vJv-.js → mcp-cli-1vpy_yti.js} +5 -5
- package/dist/{mcp-config-NVrqojpu.js → mcp-config-Bmi2GUum.js} +1 -1
- package/dist/{media-understanding.runtime-DesF8Xhs.js → media-understanding.runtime-Wh-_SFK_.js} +46 -46
- package/dist/{memory-cli-CWqIJQS5.js → memory-cli-COJRHkaJ.js} +46 -46
- package/dist/{memory-search-DyxoUpq2.js → memory-search-CGmdrdM1.js} +1 -1
- package/dist/{memory-search-CgoWYj0V.js → memory-search-Cy36nO15.js} +3 -3
- package/dist/{model-picker-DX9P5pDr.js → model-picker-CYWvoS3z.js} +48 -48
- package/dist/{model-picker-Ds7-VqDS.js → model-picker-_32ihKqK.js} +4 -4
- package/dist/{model-picker.runtime-DqDt4s3S.js → model-picker.runtime-DBT5uEFi.js} +49 -49
- package/dist/{model-selection-DXFVauys.js → model-selection-014eeYCV.js} +1 -1
- package/dist/{model-suppression.runtime-8mU0VJs6.js → model-suppression.runtime-GTI9Rm85.js} +46 -46
- package/dist/{models-GXQSWyBX.js → models-Be9EWpVm.js} +54 -54
- package/dist/{models-CVG-VMBa.js → models-CX35daXC.js} +14 -14
- package/dist/{models-cli-Cvy8rGqU.js → models-cli-BYjac3oq.js} +54 -54
- package/dist/{models-config-BdanqM9X.js → models-config-Agv-ThDH.js} +46 -46
- package/dist/{models-config.providers.discovery-BHZ3WglC.js → models-config.providers.discovery-BJwjDHsg.js} +1 -1
- package/dist/{mongodb-analytics-BszyEhsq.js → mongodb-analytics-HJKYeseb.js} +2 -2
- package/dist/{mongodb-analytics-CcSYo_ae.js → mongodb-analytics-mnKJih5x.js} +1 -1
- package/dist/{mongodb-auto-setup-QcwgZSN9.js → mongodb-auto-setup-CCElSwNy.js} +2 -2
- package/dist/{mongodb-kb-C-VmGOq7.js → mongodb-kb-1tSOXXb9.js} +3 -3
- package/dist/{mongodb-kb-BotgVda9.js → mongodb-kb-CdSvNe3w.js} +2 -2
- package/dist/{mongodb-kb-search-CoIAFX8n.js → mongodb-kb-search-Dq6E746K.js} +1 -1
- package/dist/{mongodb-kb-search-BBYY_d_r.js → mongodb-kb-search-DvsXIUy6.js} +3 -3
- package/dist/{mongodb-manager-BVfTfpHf.js → mongodb-manager-DEZIQXuo.js} +10 -10
- package/dist/{mongodb-manager-BJ0PAYF_.js → mongodb-manager-NkerSpvH.js} +1183 -331
- package/dist/{mongodb-procedures-DNPmmW5r.js → mongodb-procedures-DI-_Dakz.js} +7 -3
- package/dist/{mongodb-procedures-D3M2Ph8E.js → mongodb-procedures-tjhGdBV7.js} +3 -3
- package/dist/{mongodb-schema-JpDXcAUV.js → mongodb-schema-DN3aspLa.js} +1 -1
- package/dist/{mongodb-schema-BI4Ze_ZV.js → mongodb-schema-Dt6jxcPL.js} +298 -4
- package/dist/{mongodb-search-VFKd72IZ.js → mongodb-search-DMsUyfpa.js} +2 -2
- package/dist/{mongodb-structured-memory-DnwUJ6SA.js → mongodb-structured-memory-D-3SEfTu.js} +58 -2
- package/dist/{mongodb-structured-memory-BySGexcm.js → mongodb-structured-memory-lpyyW0kn.js} +3 -3
- package/dist/{monitor-DGE0bx3s.js → monitor-BZFy1RTb.js} +47 -47
- package/dist/{monitor-Dfc0KXMD.js → monitor-DPYGxeY_.js} +5 -5
- package/dist/{monitor-CZZlkQUU.js → monitor-Duykki-j.js} +51 -51
- package/dist/{monitor-B61bVnMW.js → monitor-gq31SALd.js} +8 -8
- package/dist/{nextcloud-talk-CnwOv1rG.js → nextcloud-talk-C_-LfGeq.js} +2 -2
- package/dist/{node-cli-Avub0RKe.js → node-cli-NpJzvfQW.js} +12 -12
- package/dist/{nodes-cli-qSE-cmgX.js → nodes-cli-O5HciXeP.js} +10 -10
- package/dist/{nodes-screen-DQw8F5rA.js → nodes-screen-BIwiB35h.js} +1 -1
- package/dist/{oauth.runtime-825pMCgB.js → oauth.runtime-BxjW8DFO.js} +46 -46
- package/dist/{oauth.runtime-BCwH9-Yl.js → oauth.runtime-DKU2STuA.js} +46 -46
- package/dist/{oauth.runtime-BSddaUzc.js → oauth.runtime-mFizWM72.js} +46 -46
- package/dist/{onboard-CUbnVxXL.js → onboard-B6H0qDtg.js} +1 -1
- package/dist/{onboard-BwC0LbCx.js → onboard-C1AmXQ6f.js} +8 -8
- package/dist/{onboard-Cw65XmEU.js → onboard-DPdj0IBu.js} +2 -2
- package/dist/{onboard-channels-BYNDTtRI.js → onboard-channels-Cmj_5qXQ.js} +24 -24
- package/dist/{onboard-channels-CIR1ZSii.js → onboard-channels-Wf3nY9Bf.js} +97 -97
- package/dist/{onboard-custom-FImARgQC.js → onboard-custom-DILgXkiq.js} +50 -50
- package/dist/{onboard-custom-C4qOVxtG.js → onboard-custom-DlDCjvIw.js} +4 -4
- package/dist/{onboard-helpers-DW9Mskds.js → onboard-helpers-CqpD9TVU.js} +48 -48
- package/dist/{onboard-helpers-D3xV_T96.js → onboard-helpers-D-PLdtHT.js} +3 -3
- package/dist/{onboard-hooks-B0gJVtBY.js → onboard-hooks-MQ8QOguv.js} +2 -2
- package/dist/{onboard-remote-BMLo6WKH.js → onboard-remote-BZKWgKVw.js} +50 -50
- package/dist/{onboard-remote-XUah3N3G.js → onboard-remote-Bnad5LMv.js} +2 -2
- package/dist/{onboard-search-DHCzqxgq.js → onboard-search-Dyv1IuQ4.js} +46 -46
- package/dist/{onboard-skills-LXCIpyir.js → onboard-skills-DdCu1_hE.js} +1 -1
- package/dist/{onboard-skills-CH6q90Pf.js → onboard-skills-W_252asS.js} +49 -49
- package/dist/{onboarding-memory-BWEsBe08.js → onboarding-memory-BRHSmwx3.js} +24 -15
- package/dist/{outbound-media-CqfP0r4a.js → outbound-media-CHc08Sj8.js} +1 -1
- package/dist/{pairing-cli-BdCkQG2S.js → pairing-cli-oNWkjwCt.js} +5 -5
- package/dist/{persistent-dedupe-DNnh7hrR.js → persistent-dedupe-CS_uyVoq.js} +1 -1
- package/dist/{pi-model-discovery-runtime-DyT9C3Ap.js → pi-model-discovery-runtime-BJVREOXf.js} +46 -46
- package/dist/{pi-tools.before-tool-call.runtime-CA2js1Ig.js → pi-tools.before-tool-call.runtime-w-Q4HA_S.js} +6 -6
- package/dist/{plugin-install-DgvJfz7X.js → plugin-install-BysMw7Sl.js} +47 -47
- package/dist/{plugin-install-BKuy_--2.js → plugin-install-EyES0vGP.js} +2 -2
- package/dist/{plugin-registry-D-6OBqUU.js → plugin-registry-BenF9SYR.js} +47 -47
- package/dist/{plugin-registry-Dsx_6z3N.js → plugin-registry-CRV_Bc8K.js} +3 -3
- package/dist/plugin-sdk/account-resolution.js +46 -46
- package/dist/plugin-sdk/acp-runtime.js +46 -46
- package/dist/plugin-sdk/agent-runtime.js +46 -46
- package/dist/plugin-sdk/channel-inbound.js +46 -46
- package/dist/plugin-sdk/channel-reply-pipeline.js +3 -3
- package/dist/plugin-sdk/channel-runtime.js +46 -46
- package/dist/plugin-sdk/channel-setup.js +1 -1
- package/dist/plugin-sdk/command-auth.js +46 -46
- package/dist/plugin-sdk/compat.js +5 -5
- package/dist/plugin-sdk/config-runtime.js +46 -46
- package/dist/plugin-sdk/conversation-runtime.js +46 -46
- package/dist/plugin-sdk/core.js +5 -5
- package/dist/plugin-sdk/directory-runtime.js +1 -1
- package/dist/plugin-sdk/discord.js +46 -46
- package/dist/plugin-sdk/gateway-runtime.js +8 -8
- package/dist/plugin-sdk/image-generation.js +46 -46
- package/dist/plugin-sdk/index.js +46 -46
- package/dist/plugin-sdk/infra-runtime.js +46 -46
- package/dist/plugin-sdk/llm-task.js +46 -46
- package/dist/plugin-sdk/matrix-runtime-heavy.js +50 -50
- package/dist/plugin-sdk/media-runtime.js +46 -46
- package/dist/plugin-sdk/media-understanding-runtime.js +46 -46
- package/dist/plugin-sdk/media-understanding.js +46 -46
- package/dist/plugin-sdk/ollama-setup.js +8 -8
- package/dist/plugin-sdk/plugin-runtime.js +46 -46
- package/dist/plugin-sdk/provider-auth-api-key.js +46 -46
- package/dist/plugin-sdk/provider-auth-login.js +1 -1
- package/dist/plugin-sdk/provider-auth.js +46 -46
- package/dist/plugin-sdk/provider-models.js +5 -5
- package/dist/plugin-sdk/provider-onboard.js +5 -5
- package/dist/plugin-sdk/provider-setup.js +49 -49
- package/dist/plugin-sdk/provider-stream.js +46 -46
- package/dist/plugin-sdk/provider-usage.js +4 -4
- package/dist/plugin-sdk/reply-history.js +3 -3
- package/dist/plugin-sdk/reply-runtime.js +46 -46
- package/dist/plugin-sdk/routing.js +3 -3
- package/dist/plugin-sdk/sandbox.js +46 -46
- package/dist/plugin-sdk/self-hosted-provider-setup.js +48 -48
- package/dist/plugin-sdk/setup-runtime.js +1 -1
- package/dist/plugin-sdk/setup.js +1 -1
- package/dist/plugin-sdk/speech-runtime.js +46 -46
- package/dist/plugin-sdk/speech.js +46 -46
- package/dist/plugin-sdk/src/agents/workspace.d.ts +1 -3
- package/dist/plugin-sdk/src/config/types.memory.d.ts +44 -0
- package/dist/plugin-sdk/src/memory/backend-config.d.ts +24 -0
- package/dist/plugin-sdk/src/memory/index.d.ts +12 -4
- package/dist/plugin-sdk/src/memory/mongodb-entity-extractor.d.ts +33 -0
- package/dist/plugin-sdk/src/memory/mongodb-episodes.d.ts +16 -0
- package/dist/plugin-sdk/src/memory/mongodb-events.d.ts +9 -0
- package/dist/plugin-sdk/src/memory/mongodb-graph.d.ts +30 -3
- package/dist/plugin-sdk/src/memory/mongodb-manager.d.ts +18 -0
- package/dist/plugin-sdk/src/memory/mongodb-mutations.d.ts +38 -0
- package/dist/plugin-sdk/src/memory/mongodb-procedures.d.ts +32 -0
- package/dist/plugin-sdk/src/memory/mongodb-profile.d.ts +71 -0
- package/dist/plugin-sdk/src/memory/mongodb-query-cache.d.ts +68 -0
- package/dist/plugin-sdk/src/memory/mongodb-query-rewriter.d.ts +39 -0
- package/dist/plugin-sdk/src/memory/mongodb-reranker.d.ts +32 -0
- package/dist/plugin-sdk/src/memory/mongodb-schema.d.ts +3 -0
- package/dist/plugin-sdk/src/memory/mongodb-telemetry.d.ts +69 -0
- package/dist/plugin-sdk/text-runtime.js +6 -6
- package/dist/plugin-sdk/web-media.js +3 -3
- package/dist/plugin-sdk/zalo.js +47 -47
- package/dist/plugin-sdk/zalouser.js +47 -47
- package/dist/plugins/build-smoke-entry.js +46 -46
- package/dist/plugins/runtime/index.js +46 -46
- package/dist/{plugins-cli-C6wGAkD9.js → plugins-cli-BUiP4x7l.js} +46 -46
- package/dist/{policy-CcgojW9R.js → policy-DnUfJkOZ.js} +1 -1
- package/dist/{preflight-audio.runtime-Cyz9Zu89.js → preflight-audio.runtime-D3_iaSgF.js} +46 -46
- package/dist/{probe-auth-BmluVNJZ.js → probe-auth-BbNdYwb0.js} +1 -1
- package/dist/{probe-auth-DrgTJ7ki.js → probe-auth-CB9y2dLl.js} +7 -7
- package/dist/{program-CHFcfOlC.js → program-uHYlUP3c.js} +4 -4
- package/dist/{prompt-select-styled-Ck38XMb3.js → prompt-select-styled-DoTAWghe.js} +25 -51
- package/dist/{provider-api-key-auth.runtime-AT16DTa8.js → provider-api-key-auth.runtime-B3H0dODg.js} +46 -46
- package/dist/{provider-auth-choice-UhIkLc6q.js → provider-auth-choice-HRfxXEHk.js} +6 -6
- package/dist/{provider-auth-choice-helpers-CXWmWOdR.js → provider-auth-choice-helpers-2jZnBKMm.js} +1 -1
- package/dist/{provider-auth-choice-preference-TgulgKlz.js → provider-auth-choice-preference-CqKryjBB.js} +6 -6
- package/dist/{provider-auth-choice.runtime-FTNgi8Yh.js → provider-auth-choice.runtime-BaFSZgQG.js} +48 -48
- package/dist/{provider-auth-choice.runtime-CP91b3vK.js → provider-auth-choice.runtime-DPHuj1_l.js} +2 -2
- package/dist/{provider-auth-choices-BfWvatIg.js → provider-auth-choices-CqFh00uK.js} +1 -1
- package/dist/{provider-auth-guidance-D4-q7IHl.js → provider-auth-guidance-DmdBoDfS.js} +2 -2
- package/dist/{provider-auth-input-DnQ-RiX5.js → provider-auth-input-FZYEJh19.js} +46 -46
- package/dist/{provider-auth-login-D7eLUZwy.js → provider-auth-login-B-XedaK5.js} +1 -1
- package/dist/{provider-auth-login.runtime-BG_qqxZk.js → provider-auth-login.runtime-f9dxfJUB.js} +49 -49
- package/dist/{provider-model-allowlist-CC0lIQ6w.js → provider-model-allowlist-C16pn0B8.js} +1 -1
- package/dist/{provider-models-DbK6xrje.js → provider-models-PaymKOme.js} +1 -1
- package/dist/{provider-ollama-setup-B4RWr9oj.js → provider-ollama-setup-k5ozCUi2.js} +3 -3
- package/dist/{provider-onboarding-config-W5sF0oD8.js → provider-onboarding-config-qCltsaVl.js} +1 -1
- package/dist/{provider-runtime.runtime-Cva8S4wx.js → provider-runtime.runtime-CzVe0WBb.js} +46 -46
- package/dist/{provider-self-hosted-setup-jAzqLaqv.js → provider-self-hosted-setup-zxYnIftX.js} +3 -3
- package/dist/{provider-usage-CEgSCMW4.js → provider-usage-C9KdAhuS.js} +46 -46
- package/dist/{provider-usage-CCIC3SdY.js → provider-usage-DexJNI_0.js} +1 -1
- package/dist/{provider-wizard-DQd5eYhX.js → provider-wizard-D4RbMR2D.js} +2 -2
- package/dist/{push-apns-DQN5pcl6.js → push-apns-BAc0-Jy5.js} +1 -1
- package/dist/{pw-ai-BiXz8un2.js → pw-ai-C8v0s5wH.js} +6 -6
- package/dist/{qr-cli-B8bBpCd2.js → qr-cli-BpqLcmYC.js} +47 -47
- package/dist/{qr-cli-DOuhqzho.js → qr-cli-D0zqiQMl.js} +4 -4
- package/dist/{reactions-BkyHqIw4.js → reactions-CjJbniYK.js} +1 -1
- package/dist/{read-only-account-inspect-Cfaj7PFb.js → read-only-account-inspect-CEJ1r7AW.js} +3 -3
- package/dist/{read-only-account-inspect.discord.runtime-kreMwVgq.js → read-only-account-inspect.discord.runtime-C1n8r_Kj.js} +46 -46
- package/dist/{read-only-account-inspect.slack.runtime-DgV5VZ-n.js → read-only-account-inspect.slack.runtime-DAOzA9ke.js} +46 -46
- package/dist/{read-only-account-inspect.telegram.runtime-BQaHHCIS.js → read-only-account-inspect.telegram.runtime-CfNlnogC.js} +46 -46
- package/dist/{redact-snapshot-PisBVQFW.js → redact-snapshot-qQFn3bz8.js} +3 -3
- package/dist/{register.agent-CXTssAWM.js → register.agent-DC5QbIE7.js} +114 -114
- package/dist/{register.backup-MRTb86c6.js → register.backup-BRxspFkM.js} +6 -6
- package/dist/{register.configure-BfE3p-3h.js → register.configure-B7zhRBla.js} +120 -120
- package/dist/{register.maintenance-D_Gn-ZDc.js → register.maintenance-CCmppLW1.js} +65 -65
- package/dist/{register.message-s1z2QSP2.js → register.message-DSBPJS4x.js} +47 -47
- package/dist/{register.onboard-Cd-OV7xm.js → register.onboard-C4D9pjf7.js} +54 -54
- package/dist/{register.setup-DclQVR9m.js → register.setup-C4pDa0HW.js} +52 -52
- package/dist/{register.status-health-sessions-D-Xp8ae7.js → register.status-health-sessions-ClxLTjC5.js} +55 -55
- package/dist/{register.subclis-pcAQ13jU.js → register.subclis-BauDruMA.js} +30 -30
- package/dist/{register.subclis-BCvQmGkr.js → register.subclis-WyYRaoa-.js} +1 -1
- package/dist/{replies-DQwDaTBP.js → replies-CZGcXYVE.js} +1 -1
- package/dist/{reply-history-DVLrt4Es.js → reply-history-1yT9Tzib.js} +1 -1
- package/dist/{routes-CBWjQBhD.js → routes-D8CYDLDF.js} +5 -5
- package/dist/{rpc-O719GSVf.js → rpc-D8I_Qzen.js} +1 -1
- package/dist/{run-main-C_W2kjf-.js → run-main-BwEbDjI-.js} +19 -19
- package/dist/{runtime-COpSaRtb.js → runtime-CmSMHqwN.js} +1 -1
- package/dist/{runtime-PbP8BVEV.js → runtime-DQaeo-1L.js} +2 -2
- package/dist/{runtime-discord-ops.runtime-CmStqYK4.js → runtime-discord-ops.runtime-8w-055sR.js} +46 -46
- package/dist/{runtime-slack-ops.runtime-Cm1935hR.js → runtime-slack-ops.runtime-XJJrByCY.js} +48 -48
- package/dist/{runtime-telegram-ops.runtime-CKozoVxf.js → runtime-telegram-ops.runtime-wOdrd2eH.js} +46 -46
- package/dist/{sandbox-cli-BIyJ-1r-.js → sandbox-cli-CvFmY6Kq.js} +46 -46
- package/dist/{search-manager-BVE1EPHv.js → search-manager-ZNiamJHa.js} +6 -6
- package/dist/{search-manager-DMTYqpmg.js → search-manager-zaZ4tAYz.js} +5 -5
- package/dist/{secrets-cli-CMMtWzst.js → secrets-cli-D5a_lvAP.js} +47 -47
- package/dist/{security-cli-Bw4cVkTN.js → security-cli-DJovxmST.js} +47 -47
- package/dist/{send-CfI8y11o.js → send-C3KhjjcU.js} +1 -1
- package/dist/{send-C8HDmafP.js → send-CIkS5fLj.js} +2 -2
- package/dist/{server-0n2tu0ff.js → server-B1z10Ohi.js} +6 -6
- package/dist/{server-node-events-J5-mGOea.js → server-node-events-D3_b2nU-.js} +47 -47
- package/dist/{server-startup-matrix-migration-CMBUtdN2.js → server-startup-matrix-migration-DDRaKUPQ.js} +3 -3
- package/dist/{session-cost-usage-CrPCO4HN.js → session-cost-usage-BwIud0lY.js} +46 -46
- package/dist/{sessions-n_Z6bcbr.js → sessions-B5Pffwj6.js} +3 -3
- package/dist/{sessions-BK_M3Nu1.js → sessions-ClamZkvP.js} +47 -47
- package/dist/{setup-OCrVlmv7.js → setup-B8gsbmH4.js} +18 -18
- package/dist/{setup-core-BVBCTInv.js → setup-core-B6csKf5s.js} +2 -2
- package/dist/{setup-core-z8Q1sgUU.js → setup-core-DkgiVKzw.js} +2 -2
- package/dist/{setup-entry-CvuaW-4I.js → setup-entry-C8XH3da9.js} +2 -2
- package/dist/{setup-entry-Jf6V23s6.js → setup-entry-CMSlnfft.js} +3 -3
- package/dist/{setup-entry-Bo3chgoG.js → setup-entry-CZVAwPKZ.js} +2 -2
- package/dist/{setup-entry-Co-YP41_.js → setup-entry-Duh-ewBV.js} +3 -3
- package/dist/{setup-entry-BnSZlMP1.js → setup-entry-ksUWY45r.js} +2 -2
- package/dist/{setup-entry-BNSYJMzp.js → setup-entry-vQgAuveW.js} +2 -2
- package/dist/{setup-group-access-BYV3O8yu.js → setup-group-access-CTlnq-M9.js} +1 -1
- package/dist/{setup-surface-B6XBqyMJ.js → setup-surface-B7uYEI9F.js} +2 -2
- package/dist/{setup-surface-fixjWejm.js → setup-surface-CMgQr2R9.js} +5 -5
- package/dist/{setup-surface-CzzV3QV6.js → setup-surface-Yd-YLGfa.js} +46 -46
- package/dist/{setup-wizard-proxy-DFDQV7FN.js → setup-wizard-proxy-CHGAY6ob.js} +1 -1
- package/dist/{setup.finalize-WT9kXSLX.js → setup.finalize-C2bq4D8j.js} +58 -58
- package/dist/{setup.gateway-config-Bp50kjo3.js → setup.gateway-config-BGgVOvQf.js} +48 -48
- package/dist/{shared-CyR3Ki--.js → shared-BEMZg0vb.js} +5 -5
- package/dist/{shared-DXzPv5D7.js → shared-BYRyVoVx.js} +5 -5
- package/dist/{shared-DCOVJ3QB.js → shared-Bj3fwdyM.js} +4 -4
- package/dist/{shared-B8_JHpU2.js → shared-CSydqOgE.js} +4 -4
- package/dist/{shared-C3fKAUbw.js → shared-DLAg-pKT.js} +3 -3
- package/dist/{signal-D16eMrBf.js → signal-Dh6z2uaT.js} +5 -5
- package/dist/{signal-oGrspg1k.js → signal-FEtxekyc.js} +46 -46
- package/dist/{skills-cli-CY6lUTRv.js → skills-cli-9NuRJd3Z.js} +5 -5
- package/dist/{slack-ueYeeNF7.js → slack-Ci1VArkq.js} +48 -48
- package/dist/{slack-B1GgT1_u.js → slack-CjslLjTc.js} +5 -5
- package/dist/{slash-commands.runtime-1q-llUpe.js → slash-commands.runtime-COXzcGjL.js} +46 -46
- package/dist/{slash-dispatch.runtime-BqJ1FZZ6.js → slash-dispatch.runtime-D5j8d7dg.js} +47 -47
- package/dist/{slash-skill-commands.runtime-D-BEZgQ1.js → slash-skill-commands.runtime-6U65Nany.js} +46 -46
- package/dist/{status-CnKcjD2h.js → status-BWUft8B5.js} +16 -16
- package/dist/{status-C1BR9Hft.js → status-BjV1ysoW.js} +50 -50
- package/dist/{status-D_1nxvoi.js → status-CM77XYRR.js} +4 -4
- package/dist/{status-Dp3OriYl.js → status-D7XHAzLz.js} +46 -46
- package/dist/{status-DoSH4nEL.js → status-DwO4xEHI.js} +54 -54
- package/dist/{status-json-DwNPzoCk.js → status-json-BYDBfkr3.js} +19 -19
- package/dist/{status-B45v-A8b.js → status-yoA_KX2O.js} +1 -1
- package/dist/{status.link-channel-Cz8GoHZ2.js → status.link-channel-DkISMfW8.js} +2 -2
- package/dist/{status.scan.deps.runtime-BQGei2B_.js → status.scan.deps.runtime-B6__B0kL.js} +14 -14
- package/dist/{status.scan.runtime-D4HkKTZu.js → status.scan.runtime-BAkcX3vO.js} +2 -2
- package/dist/{status.summary-Dxo5qDuD.js → status.summary-DNaMhaXy.js} +8 -8
- package/dist/{subagent-orphan-recovery-BPa7yoId.js → subagent-orphan-recovery-DtK8inah.js} +46 -46
- package/dist/{subagent-registry-runtime-B6homy_H.js → subagent-registry-runtime-02s7QJo3.js} +46 -46
- package/dist/{synology-chat-DY8xNv_g.js → synology-chat-QURTpvMf.js} +2 -2
- package/dist/{system-cli-CkWRbLu4.js → system-cli-BXd7evEt.js} +7 -7
- package/dist/{system-run-command-jY6Is_ri.js → system-run-command-CQCx0f24.js} +1 -1
- package/dist/telegram/audit.js +1 -1
- package/dist/telegram/token.js +46 -46
- package/dist/{telegram-uQdpyLeS.js → telegram-Btwvg0PX.js} +46 -46
- package/dist/{telegram-Bnigf1Qe.js → telegram-Dh5gM1mc.js} +7 -7
- package/dist/{tool-policy-match-BLASiL8y.js → tool-policy-match-B6J0bSfQ.js} +1 -1
- package/dist/{tui-Dj52JiFV.js → tui-CKGcNyM8.js} +6 -6
- package/dist/{tui-cli-B4SN4wzX.js → tui-cli-D3CLnnB9.js} +47 -47
- package/dist/{update-cli-CEAEBCp2.js → update-cli-DQ4j_nIh.js} +69 -69
- package/dist/{update-offset-store-Bp1RjZK2.js → update-offset-store-RxVdgbyo.js} +46 -46
- package/dist/{upsert-with-lock-CFIy4b7I.js → upsert-with-lock-BqkAnFym.js} +1 -1
- package/dist/{web-media-BJ-azd7j.js → web-media-BM1Mg6AN.js} +1 -1
- package/dist/{webhook-shared-DYKTXPVw.js → webhook-shared-UDKLpQnU.js} +1 -1
- package/dist/{webhooks-cli-CEBJbLqS.js → webhooks-cli-Ca3PlK8h.js} +5 -5
- package/dist/{whatsapp-63jqHVrE.js → whatsapp-CHEvDa2g.js} +46 -46
- package/dist/{with-timeout-CvaBvNie.js → with-timeout-CvBH67nj.js} +2 -2
- package/dist/{workspace-DuH1agxz.js → workspace-uCYzunu4.js} +5 -33
- package/dist/{zalo-CTrI2C4i.js → zalo-Dr4ysJLW.js} +1 -1
- package/dist/{zalo-Sw_XHo3-.js → zalo-keqX1Wnx.js} +2 -2
- package/docs/concepts/agent-workspace.md +0 -5
- package/docs/concepts/memory.md +6 -12
- package/docs/plans/2026-03-22-semantic-cache-telemetry-docs-plan.md +1431 -0
- package/docs/plans/2026-03-22-supermemory-steals-plan.md +1679 -0
- package/docs/plans/2026-03-23-almost-perfect-sprint-plan.md +1080 -0
- package/docs/plans/2026-03-23-master-steal-list.md +224 -0
- package/docs/plans/2026-03-23-memory-md-deprecation-plan.md +632 -0
- package/docs/plans/2026-03-23-production-readiness-e2e-plan.md +659 -0
- package/docs/plans/2026-03-23-supermemory-audit-fixes-plan.md +1291 -0
- package/docs/reference/clawmongo-vs-default-memory.md +2 -2
- package/docs/reference/heart-brain-boundary.md +8 -10
- package/docs/reference/memory-config.md +3 -4
- package/docs/reference/mongodb-capabilities.md +246 -9
- package/docs/reference/templates/AGENTS.md +5 -10
- package/docs/research/2026-03-22-atlas-local-preview-web.md +41 -31
- package/docs/research/2026-03-23-agent-management-ui-github.md +482 -0
- package/docs/research/2026-03-23-almost-perfect-mongodb-docs.md +255 -0
- package/docs/research/2026-03-23-company-os-agent-ui-web.md +511 -0
- package/docs/research/2026-03-23-supermemory-audit-fixes-mongodb-research.md +995 -0
- package/docs/start/clawmongo-getting-started.md +1 -1
- package/package.json +1 -1
- /package/dist/{memory-BAVM2Jxh.js → memory-CcbELE82.js} +0 -0
|
@@ -0,0 +1,995 @@
|
|
|
1
|
+
# SuperMemory Audit Fixes - MongoDB Official Documentation Research
|
|
2
|
+
|
|
3
|
+
> Research date: 2026-03-23
|
|
4
|
+
> Researcher: MongoDB Documentation Research Agent
|
|
5
|
+
> All URLs verified by scraping mongodb.com official documentation pages
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## C1. Score Normalization Across Different Search Methods
|
|
10
|
+
|
|
11
|
+
### Problem
|
|
12
|
+
|
|
13
|
+
`searchV2()` merges results from `$vectorSearch` (scores 0-1), `$search`/BM25 (scores 0-infinity), structured memory (synthetic scores ~0.85), and episodes (synthetic scores). These incompatible score ranges make naive score merging unreliable.
|
|
14
|
+
|
|
15
|
+
### MongoDB Documentation Sources
|
|
16
|
+
|
|
17
|
+
- URL: https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/
|
|
18
|
+
- Confirms: "MongoDB Vector Search assigns a score, in a fixed range from `0` to `1` (where `0` indicates low similarity and `1` indicates high similarity)"
|
|
19
|
+
- URL: https://www.mongodb.com/docs/atlas/atlas-search/scoring/
|
|
20
|
+
- Confirms: `$search` scores are unbounded (Lucene TF-IDF based, range 0 to infinity)
|
|
21
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/rankFusion/
|
|
22
|
+
- Version: MongoDB 8.0+
|
|
23
|
+
- `$rankFusion` uses Reciprocal Rank Fusion (RRF) with formula: `sum of weight * (1 / (60 + rank))` across input pipelines. Sensitivity parameter is 60.
|
|
24
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/
|
|
25
|
+
- Version: MongoDB 8.2+
|
|
26
|
+
- `$scoreFusion` provides score-based fusion with built-in normalization options: `none`, `sigmoid`, `minMaxScaler`
|
|
27
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/score/
|
|
28
|
+
- Version: MongoDB 8.2+
|
|
29
|
+
- `$score` stage can normalize scores with `sigmoid` or `minMaxScaler`, and apply weights
|
|
30
|
+
|
|
31
|
+
### Official Pattern / Syntax
|
|
32
|
+
|
|
33
|
+
**$rankFusion (rank-based, no score normalization needed):**
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
{
|
|
37
|
+
$rankFusion: {
|
|
38
|
+
input: {
|
|
39
|
+
pipelines: {
|
|
40
|
+
vectorPipeline: [{ $vectorSearch: { ... } }],
|
|
41
|
+
textPipeline: [{ $search: { ... } }, { $limit: 20 }]
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
combination: {
|
|
45
|
+
weights: { vectorPipeline: 0.7, textPipeline: 0.3 }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**$scoreFusion (score-based with normalization):**
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
{
|
|
55
|
+
$scoreFusion: {
|
|
56
|
+
input: {
|
|
57
|
+
pipelines: {
|
|
58
|
+
vectorPipeline: [{ $vectorSearch: { ... } }],
|
|
59
|
+
textPipeline: [{ $search: { ... } }, { $limit: 20 }]
|
|
60
|
+
},
|
|
61
|
+
normalization: "sigmoid" // or "minMaxScaler"
|
|
62
|
+
},
|
|
63
|
+
combination: {
|
|
64
|
+
weights: { vectorPipeline: 0.7, textPipeline: 0.3 },
|
|
65
|
+
method: "avg"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**$score stage (normalize individual pipeline scores):**
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
{
|
|
75
|
+
$score: {
|
|
76
|
+
score: { $meta: "vectorSearchScore" },
|
|
77
|
+
normalization: "sigmoid",
|
|
78
|
+
weight: 0.8
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Recommendations for ClawMongo
|
|
84
|
+
|
|
85
|
+
1. **Immediate (no version dependency):** Implement manual RRF in `mongodb-hybrid.ts` using the official formula: `score = sum(weight_i / (60 + rank_i))`. This eliminates the score range problem entirely by using ranks instead of scores.
|
|
86
|
+
2. **For MongoDB 8.0+:** Migrate to `$rankFusion` as the server-side hybrid search stage. It handles de-duplication and weighted rank fusion natively.
|
|
87
|
+
3. **For MongoDB 8.2+:** Consider `$scoreFusion` with `normalization: "sigmoid"` for score-aware fusion that preserves score magnitude differences.
|
|
88
|
+
4. **For synthetic scores (structured memory, episodes):** Use `$score` stage with `normalization: "sigmoid"` to bring them into a 0-1 range before merging with vector search results.
|
|
89
|
+
5. **Stop merging raw scores from different search methods.** Either use rank-based fusion (RRF) or normalize all scores to 0-1 first.
|
|
90
|
+
|
|
91
|
+
### Caveats / Limitations
|
|
92
|
+
|
|
93
|
+
- `$rankFusion` and `$scoreFusion` are **Preview features** as of MongoDB 8.2
|
|
94
|
+
- `$rankFusion` requires MongoDB 8.0+; `$scoreFusion` requires MongoDB 8.2+
|
|
95
|
+
- Both stages operate on a **single collection only**
|
|
96
|
+
- Both stages require input pipelines to be "Selection Pipelines" (no document modification after retrieval)
|
|
97
|
+
- `$vectorSearch` cannot be inside a `$lookup` sub-pipeline or `$facet`
|
|
98
|
+
- For ClawMongo's multi-source merging (different collections), manual RRF remains necessary
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## C2. synthesizeProfile $facet Performance
|
|
103
|
+
|
|
104
|
+
### Problem
|
|
105
|
+
|
|
106
|
+
Uses correlated `$lookup` with `$expr` + `$or` inside entity aggregation. The `$facet` stage also has known performance limitations.
|
|
107
|
+
|
|
108
|
+
### MongoDB Documentation Sources
|
|
109
|
+
|
|
110
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/
|
|
111
|
+
- Correlated subquery performance: "operations that contain correlated subqueries perform better when the following conditions apply: The foreign collection contains an index on the foreignField"
|
|
112
|
+
- Index usage in correlated `$lookup`: The `$match` stage within a `$lookup` pipeline that uses `$expr` can use indexes for equality matches only. It cannot use indexes for range queries or `$or` operators within `$expr`.
|
|
113
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet/
|
|
114
|
+
- Hard limit: "each stage in a $facet executes, the resulting document is limited to 100 megabytes. Note the allowDiskUse flag doesn't affect the 100 megabyte size limit"
|
|
115
|
+
|
|
116
|
+
### Official Pattern / Syntax
|
|
117
|
+
|
|
118
|
+
**Correlated $lookup with index usage:**
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
// This CAN use indexes (equality only):
|
|
122
|
+
{
|
|
123
|
+
$lookup: {
|
|
124
|
+
from: "relations",
|
|
125
|
+
let: { entityId: "$_id" },
|
|
126
|
+
pipeline: [
|
|
127
|
+
{ $match: { $expr: { $eq: ["$fromEntityId", "$$entityId"] } } }
|
|
128
|
+
],
|
|
129
|
+
as: "outgoing"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// This CANNOT use indexes ($or inside $expr):
|
|
134
|
+
{
|
|
135
|
+
$lookup: {
|
|
136
|
+
from: "relations",
|
|
137
|
+
let: { entityId: "$_id" },
|
|
138
|
+
pipeline: [
|
|
139
|
+
{ $match: {
|
|
140
|
+
$expr: {
|
|
141
|
+
$or: [
|
|
142
|
+
{ $eq: ["$fromEntityId", "$$entityId"] },
|
|
143
|
+
{ $eq: ["$toEntityId", "$$entityId"] }
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
}}
|
|
147
|
+
],
|
|
148
|
+
as: "relations"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Recommendations for ClawMongo
|
|
154
|
+
|
|
155
|
+
1. **Replace `$or` in correlated `$lookup` with two separate `$lookup` stages.** Do one lookup for `fromEntityId` matches and one for `toEntityId` matches, then merge results. Each can use its own index.
|
|
156
|
+
2. **Alternative: Use `$unionWith` + `$group`** to combine results from two separate indexed queries instead of a single `$or`.
|
|
157
|
+
3. **For the `$facet` issue:** Be aware of the 100MB hard limit per facet. For profile synthesis with many entities, consider breaking the aggregation into multiple smaller pipelines.
|
|
158
|
+
4. **Add compound indexes** on `(fromEntityId, scope)` and `(toEntityId, scope)` for the relations collection.
|
|
159
|
+
|
|
160
|
+
### Caveats / Limitations
|
|
161
|
+
|
|
162
|
+
- `$facet` has a 100 MB output limit that `allowDiskUse` does NOT override
|
|
163
|
+
- `$expr` within `$lookup` pipeline only uses indexes for `$eq` comparisons, NOT for `$or`, `$and`, ranges, or complex expressions
|
|
164
|
+
- Each sub-pipeline inside `$facet` processes the full input dataset independently
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## C3. Missing Fetch Timeout on External API Calls
|
|
169
|
+
|
|
170
|
+
### Problem
|
|
171
|
+
|
|
172
|
+
External API calls (e.g., to embedding services) lack timeout configuration.
|
|
173
|
+
|
|
174
|
+
### MongoDB Documentation Source
|
|
175
|
+
|
|
176
|
+
- URL: https://www.mongodb.com/docs/manual/administration/production-checklist-development/
|
|
177
|
+
- MongoDB's development checklist recommends setting appropriate timeouts for all operations
|
|
178
|
+
- URL: https://www.mongodb.com/docs/drivers/node/current/fundamentals/connection/connection-options/
|
|
179
|
+
- Driver-level: `serverSelectionTimeoutMS`, `connectTimeoutMS`, `socketTimeoutMS`
|
|
180
|
+
|
|
181
|
+
### Official Pattern / Syntax
|
|
182
|
+
|
|
183
|
+
MongoDB documentation focuses on database connection timeouts, not external HTTP call timeouts. However, the general principle from the production checklist applies: always set timeouts.
|
|
184
|
+
|
|
185
|
+
### Recommendations for ClawMongo
|
|
186
|
+
|
|
187
|
+
1. **Not a MongoDB-specific issue.** Use Node.js `AbortController` with `setTimeout` on all `fetch()` calls to embedding/reranker APIs.
|
|
188
|
+
2. **Pattern:**
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
const controller = new AbortController();
|
|
192
|
+
const timeout = setTimeout(() => controller.abort(), 5000); // 5s timeout
|
|
193
|
+
try {
|
|
194
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
195
|
+
} finally {
|
|
196
|
+
clearTimeout(timeout);
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
3. Make the timeout configurable per source in the memory config.
|
|
201
|
+
|
|
202
|
+
### Caveats / Limitations
|
|
203
|
+
|
|
204
|
+
- No MongoDB-specific documentation for this; it is a general application-level concern
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## H1. bulkWrite for Entity Upserts (N+1 Problem)
|
|
209
|
+
|
|
210
|
+
### Problem
|
|
211
|
+
|
|
212
|
+
Currently uses sequential `upsertEntity()` calls (N round-trips to the database). Should use `bulkWrite` to batch.
|
|
213
|
+
|
|
214
|
+
### MongoDB Documentation Sources
|
|
215
|
+
|
|
216
|
+
- URL: https://www.mongodb.com/docs/manual/core/bulk-write-operations/
|
|
217
|
+
- "MongoDB provides clients the ability to perform write operations in bulk"
|
|
218
|
+
- "Unordered operations continue despite errors and may execute in parallel, making them typically faster"
|
|
219
|
+
- URL: https://www.mongodb.com/docs/manual/reference/method/db.collection.bulkWrite/
|
|
220
|
+
- Supports: `insertOne`, `updateOne`, `updateMany`, `replaceOne`, `deleteOne`, `deleteMany`
|
|
221
|
+
- URL: https://www.mongodb.com/docs/manual/reference/command/bulkwrite/
|
|
222
|
+
- Version: MongoDB 8.0+ for cross-collection bulkWrite command
|
|
223
|
+
|
|
224
|
+
### Official Pattern / Syntax
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
db.entities.bulkWrite(
|
|
228
|
+
[
|
|
229
|
+
{
|
|
230
|
+
updateOne: {
|
|
231
|
+
filter: { name: "Entity1", scope: "agent123" },
|
|
232
|
+
update: {
|
|
233
|
+
$set: { type: "PERSON", updatedAt: new Date() },
|
|
234
|
+
$setOnInsert: { createdAt: new Date() },
|
|
235
|
+
},
|
|
236
|
+
upsert: true,
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
updateOne: {
|
|
241
|
+
filter: { name: "Entity2", scope: "agent123" },
|
|
242
|
+
update: {
|
|
243
|
+
$set: { type: "ORGANIZATION", updatedAt: new Date() },
|
|
244
|
+
$setOnInsert: { createdAt: new Date() },
|
|
245
|
+
},
|
|
246
|
+
upsert: true,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
{ ordered: false },
|
|
251
|
+
);
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Recommendations for ClawMongo
|
|
255
|
+
|
|
256
|
+
1. **Replace sequential `upsertEntity()` loops with a single `bulkWrite()` call using `ordered: false`** for maximum throughput.
|
|
257
|
+
2. **Use `updateOne` with `upsert: true`** for each entity in the bulk array.
|
|
258
|
+
3. **Use `$setOnInsert` for fields that should only be set on creation** (e.g., `createdAt`), and `$set` for fields updated on every write.
|
|
259
|
+
4. **Error handling:** With `ordered: false`, some operations may succeed even if others fail. Check `bulkWriteResult.getWriteErrors()` for partial failures.
|
|
260
|
+
|
|
261
|
+
### Caveats / Limitations
|
|
262
|
+
|
|
263
|
+
- `bulkWrite()` on a single collection is available in all MongoDB versions
|
|
264
|
+
- Cross-collection `bulkWrite` command requires MongoDB 8.0+
|
|
265
|
+
- `ordered: false` may reorder operations for performance; do not depend on execution order
|
|
266
|
+
- Maximum document size limits still apply per operation
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## H2. Change Streams for Async Entity Enrichment
|
|
271
|
+
|
|
272
|
+
### Problem
|
|
273
|
+
|
|
274
|
+
Want to use Change Streams to trigger LLM extraction after event writes.
|
|
275
|
+
|
|
276
|
+
### MongoDB Documentation Sources
|
|
277
|
+
|
|
278
|
+
- URL: https://www.mongodb.com/docs/manual/changeStreams/
|
|
279
|
+
- Change streams allow applications to access real-time data changes
|
|
280
|
+
- Can use `resumeAfter` or `startAfter` with resume tokens
|
|
281
|
+
- Support pipeline filtering with `$match`
|
|
282
|
+
- Require a replica set or sharded cluster (atlas-local includes a single-node replica set)
|
|
283
|
+
- URL: https://www.mongodb.com/docs/manual/administration/change-streams-production-recommendations/
|
|
284
|
+
- "Change streams cannot use indexes"
|
|
285
|
+
- "avoid opening a high number of specifically-targeted change streams as these can impact server performance"
|
|
286
|
+
- Response documents must adhere to 16MB BSON limit
|
|
287
|
+
- Resume tokens can become invalid if oplog rotates
|
|
288
|
+
|
|
289
|
+
### Official Pattern / Syntax
|
|
290
|
+
|
|
291
|
+
```javascript
|
|
292
|
+
// Watch for inserts on the events collection with filtering
|
|
293
|
+
const pipeline = [
|
|
294
|
+
{
|
|
295
|
+
$match: {
|
|
296
|
+
operationType: "insert",
|
|
297
|
+
"fullDocument.type": { $in: ["message", "tool_result"] },
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
];
|
|
301
|
+
|
|
302
|
+
const changeStream = db.collection("events").watch(pipeline, {
|
|
303
|
+
fullDocument: "updateLookup",
|
|
304
|
+
resumeAfter: lastResumeToken, // for crash recovery
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
changeStream.on("change", async (event) => {
|
|
308
|
+
const resumeToken = event._id;
|
|
309
|
+
// Process the event
|
|
310
|
+
await enrichEntity(event.fullDocument);
|
|
311
|
+
// Persist resume token for crash recovery
|
|
312
|
+
await saveResumeToken(resumeToken);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
changeStream.on("error", (err) => {
|
|
316
|
+
// ChangeStreamFatalError (280) means resume token expired
|
|
317
|
+
if (err.code === 280) {
|
|
318
|
+
// Must restart from beginning or a known checkpoint
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Recommendations for ClawMongo
|
|
324
|
+
|
|
325
|
+
1. **Use `watch()` with a `$match` pipeline** filtering for `operationType: "insert"` to avoid processing updates/deletes.
|
|
326
|
+
2. **Persist resume tokens** to a dedicated collection (e.g., `change_stream_checkpoints`) for crash recovery.
|
|
327
|
+
3. **Handle `ChangeStreamFatalError` (code 280)** by restarting the stream without a resume token and replaying from the earliest available oplog entry.
|
|
328
|
+
4. **Atlas-local supports Change Streams** since it runs a single-node replica set.
|
|
329
|
+
5. **Limit the number of concurrent change streams** to avoid performance impact.
|
|
330
|
+
|
|
331
|
+
### Caveats / Limitations
|
|
332
|
+
|
|
333
|
+
- Change streams cannot use indexes (they read the oplog)
|
|
334
|
+
- Resume tokens expire when the oplog rotates (depends on oplog size)
|
|
335
|
+
- 16MB BSON document limit applies to change events
|
|
336
|
+
- Opening too many change streams impacts server performance
|
|
337
|
+
- If a collection is dropped or renamed, the change stream cursor closes
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## H3. Vector Search Pre-Filtering with Entity Metadata
|
|
342
|
+
|
|
343
|
+
### Problem
|
|
344
|
+
|
|
345
|
+
Want to filter `$vectorSearch` by entity type metadata.
|
|
346
|
+
|
|
347
|
+
### MongoDB Documentation Source
|
|
348
|
+
|
|
349
|
+
- URL: https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/
|
|
350
|
+
- Pre-filtering supported with MQL operators: `$eq`, `$ne`, `$gt`, `$lt`, `$gte`, `$lte`, `$in`, `$nin`, `$exists`, `$not`, `$nor`, `$and`, `$or`
|
|
351
|
+
- "You must index the fields that you want to filter your data by as the `filter` type in a vectorSearch type index definition"
|
|
352
|
+
- "Pre-filtering your data doesn't affect the score that MongoDB Vector Search returns"
|
|
353
|
+
|
|
354
|
+
### Official Pattern / Syntax
|
|
355
|
+
|
|
356
|
+
**Vector search index definition (must include filter fields):**
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
{
|
|
360
|
+
"fields": [
|
|
361
|
+
{
|
|
362
|
+
"type": "vector",
|
|
363
|
+
"path": "embedding",
|
|
364
|
+
"numDimensions": 1024,
|
|
365
|
+
"similarity": "cosine"
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"type": "filter",
|
|
369
|
+
"path": "entityType"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"type": "filter",
|
|
373
|
+
"path": "scope"
|
|
374
|
+
}
|
|
375
|
+
]
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Query with pre-filter:**
|
|
380
|
+
|
|
381
|
+
```javascript
|
|
382
|
+
{
|
|
383
|
+
$vectorSearch: {
|
|
384
|
+
index: "vector_index",
|
|
385
|
+
path: "embedding",
|
|
386
|
+
queryVector: queryEmbedding,
|
|
387
|
+
numCandidates: 100,
|
|
388
|
+
limit: 10,
|
|
389
|
+
filter: {
|
|
390
|
+
$and: [
|
|
391
|
+
{ entityType: { $in: ["PERSON", "ORGANIZATION"] } },
|
|
392
|
+
{ scope: "agent123" }
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Recommendations for ClawMongo
|
|
400
|
+
|
|
401
|
+
1. **Add `filter` type fields to the vector search index definition** for `entityType`, `scope`, `source`, and any other metadata fields used for filtering.
|
|
402
|
+
2. **Use the `filter` parameter in `$vectorSearch`** instead of post-filtering with `$match` for better performance (pre-filter reduces the candidate set before vector comparison).
|
|
403
|
+
3. **Pre-filtering does NOT affect vector search scores** -- this is confirmed in the docs.
|
|
404
|
+
|
|
405
|
+
### Caveats / Limitations
|
|
406
|
+
|
|
407
|
+
- Filter fields MUST be declared as `type: "filter"` in the vector search index definition
|
|
408
|
+
- `$vectorSearch` filter does NOT support `$regex`, `$text`, or aggregation pipeline operators
|
|
409
|
+
- Only supports specific MQL operators listed above
|
|
410
|
+
- Cannot use `$vectorSearch` inside `$facet` or `$lookup` sub-pipeline
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## H4. Cache TTL Derivation from Query Source
|
|
415
|
+
|
|
416
|
+
### Problem
|
|
417
|
+
|
|
418
|
+
Need variable TTL per cached document based on query source type.
|
|
419
|
+
|
|
420
|
+
### MongoDB Documentation Sources
|
|
421
|
+
|
|
422
|
+
- URL: https://www.mongodb.com/docs/manual/tutorial/expire-data/
|
|
423
|
+
- Two patterns: fixed TTL via `expireAfterSeconds`, or per-document TTL via `expireAfterSeconds: 0` with a date field
|
|
424
|
+
- URL: https://www.mongodb.com/docs/manual/core/index-ttl/
|
|
425
|
+
- "TTL indexes expire documents after the specified number of seconds has passed since the indexed field value"
|
|
426
|
+
- "The TTL index is a single field index. Compound indexes do not support the TTL property"
|
|
427
|
+
|
|
428
|
+
### Official Pattern / Syntax
|
|
429
|
+
|
|
430
|
+
**Pattern 1: Fixed TTL (same expiration for all documents):**
|
|
431
|
+
|
|
432
|
+
```javascript
|
|
433
|
+
db.cache.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 });
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Pattern 2: Per-document variable TTL (set `expireAfterSeconds: 0`):**
|
|
437
|
+
|
|
438
|
+
```javascript
|
|
439
|
+
// Create index with expireAfterSeconds: 0
|
|
440
|
+
db.cache.createIndex({ "expiresAt": 1 }, { expireAfterSeconds: 0 })
|
|
441
|
+
|
|
442
|
+
// Each document sets its own expiration time
|
|
443
|
+
db.cache.insertOne({
|
|
444
|
+
queryHash: "abc123",
|
|
445
|
+
source: "vector",
|
|
446
|
+
result: { ... },
|
|
447
|
+
expiresAt: new Date(Date.now() + 5 * 60 * 1000) // 5 min for vector
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
db.cache.insertOne({
|
|
451
|
+
queryHash: "def456",
|
|
452
|
+
source: "structured",
|
|
453
|
+
result: { ... },
|
|
454
|
+
expiresAt: new Date(Date.now() + 30 * 60 * 1000) // 30 min for structured
|
|
455
|
+
})
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Pattern 3: Partial TTL index with filter conditions:**
|
|
459
|
+
|
|
460
|
+
```javascript
|
|
461
|
+
// Only expire documents where type is "cache"
|
|
462
|
+
db.memory.createIndex(
|
|
463
|
+
{ expiresAt: 1 },
|
|
464
|
+
{
|
|
465
|
+
expireAfterSeconds: 0,
|
|
466
|
+
partialFilterExpression: { type: "cache" },
|
|
467
|
+
},
|
|
468
|
+
);
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Recommendations for ClawMongo
|
|
472
|
+
|
|
473
|
+
1. **Use Pattern 2 (per-document TTL) with `expireAfterSeconds: 0`** and an `expiresAt` date field.
|
|
474
|
+
2. **Compute `expiresAt` at write time** based on the query source:
|
|
475
|
+
- Vector search cache: 5 minutes
|
|
476
|
+
- Structured memory cache: 30 minutes
|
|
477
|
+
- Episode cache: 1 hour
|
|
478
|
+
- Profile cache: 15 minutes
|
|
479
|
+
3. **Use a partial TTL index** if the cache collection also holds non-expiring documents.
|
|
480
|
+
4. **The `expiresAt` field must be a BSON date type**, not a Unix timestamp number.
|
|
481
|
+
|
|
482
|
+
### Caveats / Limitations
|
|
483
|
+
|
|
484
|
+
- TTL indexes are **single field only** -- cannot be compound indexes
|
|
485
|
+
- TTL background thread runs every 60 seconds, so documents may persist briefly past their expiration
|
|
486
|
+
- `expireAfterSeconds` must be between 0 and 2147483647 inclusive
|
|
487
|
+
- `allowDiskUse` does not affect TTL behavior
|
|
488
|
+
- TTL index with `NaN` as `expireAfterSeconds` can cause data loss (documented bug in 5.0-6.0)
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## H5. Empty/Blank Document Handling in Reranking
|
|
493
|
+
|
|
494
|
+
### Problem
|
|
495
|
+
|
|
496
|
+
When sending documents to an external reranker, some may be empty graph relation strings.
|
|
497
|
+
|
|
498
|
+
### MongoDB Documentation Source
|
|
499
|
+
|
|
500
|
+
- No specific MongoDB documentation for handling empty text in search/rerank pipelines. This is an application-level concern.
|
|
501
|
+
|
|
502
|
+
### Recommendations for ClawMongo
|
|
503
|
+
|
|
504
|
+
1. **Filter out empty/blank documents before sending to the reranker.** Add a `$match` stage or application-level filter:
|
|
505
|
+
|
|
506
|
+
```javascript
|
|
507
|
+
// Server-side filtering in aggregation
|
|
508
|
+
{ $match: { text: { $exists: true, $ne: "", $type: "string" } } }
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
2. **Alternatively, use `$addFields` to provide a fallback text** for empty documents:
|
|
512
|
+
|
|
513
|
+
```javascript
|
|
514
|
+
{
|
|
515
|
+
$addFields: {
|
|
516
|
+
rerank_text: {
|
|
517
|
+
$cond: {
|
|
518
|
+
if: { $or: [
|
|
519
|
+
{ $eq: ["$text", ""] },
|
|
520
|
+
{ $eq: ["$text", null] },
|
|
521
|
+
{ $not: "$text" }
|
|
522
|
+
]},
|
|
523
|
+
then: "$fallback_field",
|
|
524
|
+
else: "$text"
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
3. For graph relations, construct a meaningful text representation like `"[entityA] --[relationType]--> [entityB]"` instead of sending raw empty strings.
|
|
532
|
+
|
|
533
|
+
### Caveats / Limitations
|
|
534
|
+
|
|
535
|
+
- No MongoDB-specific guidance; this is application logic
|
|
536
|
+
- External reranker APIs may reject or error on empty strings
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## M1. $percentile Aggregation Operator
|
|
541
|
+
|
|
542
|
+
### Problem
|
|
543
|
+
|
|
544
|
+
Currently computing percentiles client-side by loading all values into memory.
|
|
545
|
+
|
|
546
|
+
### MongoDB Documentation Source
|
|
547
|
+
|
|
548
|
+
- URL: https://www.mongodb.com/docs/v7.0/reference/operator/aggregation/percentile/
|
|
549
|
+
- Version: **New in MongoDB 7.0**
|
|
550
|
+
|
|
551
|
+
### Official Pattern / Syntax
|
|
552
|
+
|
|
553
|
+
```javascript
|
|
554
|
+
// Syntax
|
|
555
|
+
{
|
|
556
|
+
$percentile: {
|
|
557
|
+
input: <expression>, // field or expression evaluating to numeric
|
|
558
|
+
p: [ 0.5, 0.75, 0.95 ], // percentile values (0.0 to 1.0)
|
|
559
|
+
method: "approximate" // required, only "approximate" supported
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Usage in $group
|
|
564
|
+
db.telemetry.aggregate([
|
|
565
|
+
{
|
|
566
|
+
$group: {
|
|
567
|
+
_id: "$metricName",
|
|
568
|
+
p50: {
|
|
569
|
+
$percentile: {
|
|
570
|
+
input: "$latencyMs",
|
|
571
|
+
p: [0.5],
|
|
572
|
+
method: "approximate"
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
p95: {
|
|
576
|
+
$percentile: {
|
|
577
|
+
input: "$latencyMs",
|
|
578
|
+
p: [0.95],
|
|
579
|
+
method: "approximate"
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
p99: {
|
|
583
|
+
$percentile: {
|
|
584
|
+
input: "$latencyMs",
|
|
585
|
+
p: [0.99],
|
|
586
|
+
method: "approximate"
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
])
|
|
592
|
+
|
|
593
|
+
// Can also be used in $project (per-document) and $setWindowFields (window)
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Recommendations for ClawMongo
|
|
597
|
+
|
|
598
|
+
1. **Replace all client-side percentile calculations with `$percentile`** in the aggregation pipeline.
|
|
599
|
+
2. **Use in `$group` stage** for computing percentiles across all telemetry documents.
|
|
600
|
+
3. **Use in `$setWindowFields`** for rolling percentiles over time windows.
|
|
601
|
+
4. **Combine with `$avg`, `$stdDevPop`** in the same `$group` for complete statistical summaries.
|
|
602
|
+
|
|
603
|
+
### Caveats / Limitations
|
|
604
|
+
|
|
605
|
+
- Method must be `"approximate"` -- there is no exact calculation option
|
|
606
|
+
- Uses t-digest algorithm; results may vary slightly between runs
|
|
607
|
+
- Non-numeric values are silently ignored
|
|
608
|
+
- Returns `null` if no numeric values are found
|
|
609
|
+
- Available since MongoDB 7.0 (atlas-local 8.2 includes this)
|
|
610
|
+
- `$percentile` returns the minimum for `p = 0.0` and maximum for `p = 1.0`
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
## M2. Unbounded getEventsByTimeRange
|
|
615
|
+
|
|
616
|
+
### Problem
|
|
617
|
+
|
|
618
|
+
Time-range queries without limits could return unbounded result sets.
|
|
619
|
+
|
|
620
|
+
### MongoDB Documentation Source
|
|
621
|
+
|
|
622
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit/
|
|
623
|
+
- `$limit` takes a positive integer that specifies the maximum number of documents to pass along
|
|
624
|
+
- URL: https://www.mongodb.com/docs/manual/tutorial/query-documents/
|
|
625
|
+
- Best practice: always use `.limit()` with `.sort()` for range queries
|
|
626
|
+
|
|
627
|
+
### Official Pattern / Syntax
|
|
628
|
+
|
|
629
|
+
```javascript
|
|
630
|
+
// Always add $limit after time-range $match
|
|
631
|
+
db.events.aggregate([
|
|
632
|
+
{
|
|
633
|
+
$match: {
|
|
634
|
+
timestamp: {
|
|
635
|
+
$gte: ISODate("2026-03-01"),
|
|
636
|
+
$lte: ISODate("2026-03-23"),
|
|
637
|
+
},
|
|
638
|
+
scope: "agent123",
|
|
639
|
+
},
|
|
640
|
+
},
|
|
641
|
+
{ $sort: { timestamp: -1 } },
|
|
642
|
+
{ $limit: 1000 }, // Always bound the result set
|
|
643
|
+
]);
|
|
644
|
+
|
|
645
|
+
// Or with find():
|
|
646
|
+
db.events
|
|
647
|
+
.find({
|
|
648
|
+
timestamp: { $gte: start, $lte: end },
|
|
649
|
+
})
|
|
650
|
+
.sort({ timestamp: -1 })
|
|
651
|
+
.limit(1000);
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Recommendations for ClawMongo
|
|
655
|
+
|
|
656
|
+
1. **Always add a `$limit` or `.limit()` to time-range queries.** Default to 1000 documents.
|
|
657
|
+
2. **Add a configurable `maxEvents` parameter** to `getEventsByTimeRange()` with a sensible default.
|
|
658
|
+
3. **Use cursor-based pagination** if the caller needs more than the limit.
|
|
659
|
+
4. **Ensure the compound index `{ scope: 1, timestamp: -1 }`** exists for efficient time-range queries with scope filtering.
|
|
660
|
+
|
|
661
|
+
### Caveats / Limitations
|
|
662
|
+
|
|
663
|
+
- Without `$limit`, MongoDB will return all matching documents, potentially causing memory pressure
|
|
664
|
+
- The `$limit` stage value must be a positive 64-bit integer
|
|
665
|
+
|
|
666
|
+
---
|
|
667
|
+
|
|
668
|
+
## M3. Telemetry Aggregation Patterns
|
|
669
|
+
|
|
670
|
+
### Problem
|
|
671
|
+
|
|
672
|
+
Currently using `$push` to collect all values into an array, then processing statistics client-side.
|
|
673
|
+
|
|
674
|
+
### MongoDB Documentation Sources
|
|
675
|
+
|
|
676
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg/
|
|
677
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile/
|
|
678
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/
|
|
679
|
+
|
|
680
|
+
### Official Pattern / Syntax
|
|
681
|
+
|
|
682
|
+
```javascript
|
|
683
|
+
// Server-side statistical aggregation (replaces $push + client-side processing)
|
|
684
|
+
db.telemetry.aggregate([
|
|
685
|
+
{
|
|
686
|
+
$match: {
|
|
687
|
+
metricName: "searchLatency",
|
|
688
|
+
timestamp: { $gte: ISODate("2026-03-22") },
|
|
689
|
+
},
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
$group: {
|
|
693
|
+
_id: "$metricName",
|
|
694
|
+
count: { $sum: 1 },
|
|
695
|
+
avg: { $avg: "$value" },
|
|
696
|
+
min: { $min: "$value" },
|
|
697
|
+
max: { $max: "$value" },
|
|
698
|
+
stdDev: { $stdDevPop: "$value" },
|
|
699
|
+
percentiles: {
|
|
700
|
+
$percentile: {
|
|
701
|
+
input: "$value",
|
|
702
|
+
p: [0.5, 0.75, 0.9, 0.95, 0.99],
|
|
703
|
+
method: "approximate",
|
|
704
|
+
},
|
|
705
|
+
},
|
|
706
|
+
median: {
|
|
707
|
+
$median: {
|
|
708
|
+
input: "$value",
|
|
709
|
+
method: "approximate",
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
]);
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
**Available server-side statistical accumulators:**
|
|
718
|
+
| Operator | Description | Since |
|
|
719
|
+
|----------|-------------|-------|
|
|
720
|
+
| `$avg` | Average | All versions |
|
|
721
|
+
| `$min` | Minimum | All versions |
|
|
722
|
+
| `$max` | Maximum | All versions |
|
|
723
|
+
| `$sum` | Sum / Count | All versions |
|
|
724
|
+
| `$stdDevPop` | Population standard deviation | 3.2 |
|
|
725
|
+
| `$stdDevSamp` | Sample standard deviation | 3.2 |
|
|
726
|
+
| `$percentile` | Approximate percentiles | 7.0 |
|
|
727
|
+
| `$median` | Approximate median | 7.0 |
|
|
728
|
+
|
|
729
|
+
### Recommendations for ClawMongo
|
|
730
|
+
|
|
731
|
+
1. **Replace `$push` + client-side processing** with server-side aggregation using the operators above.
|
|
732
|
+
2. **Use `$percentile` with `p: [0.5, 0.75, 0.90, 0.95, 0.99]`** for comprehensive percentile stats.
|
|
733
|
+
3. **Use `$stdDevPop`** for standard deviation (population, not sample, since we have all telemetry data).
|
|
734
|
+
4. **Combine in a single `$group` stage** for efficiency -- all these accumulators can run in one pass.
|
|
735
|
+
5. **For time-bucketed stats**, use `$group` with `$dateTrunc` or `$setWindowFields` with time-based windows.
|
|
736
|
+
|
|
737
|
+
### Caveats / Limitations
|
|
738
|
+
|
|
739
|
+
- `$percentile` and `$median` are approximate (t-digest algorithm)
|
|
740
|
+
- `$stdDevPop` ignores non-numeric values
|
|
741
|
+
- `$push` into large arrays can hit the 16MB BSON document limit; server-side aggregation avoids this
|
|
742
|
+
|
|
743
|
+
---
|
|
744
|
+
|
|
745
|
+
## M4. Index Usage in Correlated $lookup with $expr
|
|
746
|
+
|
|
747
|
+
### Problem
|
|
748
|
+
|
|
749
|
+
Profile synthesis uses `$lookup` with `$expr` and `$or` on `fromEntityId`/`toEntityId`. Need to know if indexes are used.
|
|
750
|
+
|
|
751
|
+
### MongoDB Documentation Source
|
|
752
|
+
|
|
753
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/
|
|
754
|
+
- Explicit statement: "Indexes are not used for comparisons with more than one field path operand"
|
|
755
|
+
- For correlated subqueries: indexes are used when the foreign collection has an index on the field being compared with `$eq` only
|
|
756
|
+
- `$or` within `$expr` in a `$lookup` pipeline does NOT use indexes
|
|
757
|
+
|
|
758
|
+
### Official Pattern / Syntax
|
|
759
|
+
|
|
760
|
+
```javascript
|
|
761
|
+
// DOES use index (single $eq comparison):
|
|
762
|
+
{
|
|
763
|
+
$lookup: {
|
|
764
|
+
from: "relations",
|
|
765
|
+
let: { eid: "$_id" },
|
|
766
|
+
pipeline: [
|
|
767
|
+
{ $match: { $expr: { $eq: ["$fromEntityId", "$$eid"] } } }
|
|
768
|
+
],
|
|
769
|
+
as: "outRelations"
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// DOES NOT use index ($or with multiple comparisons):
|
|
774
|
+
{
|
|
775
|
+
$lookup: {
|
|
776
|
+
from: "relations",
|
|
777
|
+
let: { eid: "$_id" },
|
|
778
|
+
pipeline: [
|
|
779
|
+
{ $match: {
|
|
780
|
+
$expr: {
|
|
781
|
+
$or: [
|
|
782
|
+
{ $eq: ["$fromEntityId", "$$eid"] },
|
|
783
|
+
{ $eq: ["$toEntityId", "$$eid"] }
|
|
784
|
+
]
|
|
785
|
+
}
|
|
786
|
+
}}
|
|
787
|
+
],
|
|
788
|
+
as: "allRelations"
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
### Recommendations for ClawMongo
|
|
794
|
+
|
|
795
|
+
1. **Split the single `$lookup` with `$or` into TWO `$lookup` stages**, each with a single `$eq` comparison:
|
|
796
|
+
|
|
797
|
+
```javascript
|
|
798
|
+
// Lookup 1: outgoing relations (uses index on fromEntityId)
|
|
799
|
+
{ $lookup: {
|
|
800
|
+
from: "relations",
|
|
801
|
+
let: { eid: "$_id" },
|
|
802
|
+
pipeline: [
|
|
803
|
+
{ $match: { $expr: { $eq: ["$fromEntityId", "$$eid"] } } }
|
|
804
|
+
],
|
|
805
|
+
as: "outgoingRelations"
|
|
806
|
+
}},
|
|
807
|
+
// Lookup 2: incoming relations (uses index on toEntityId)
|
|
808
|
+
{ $lookup: {
|
|
809
|
+
from: "relations",
|
|
810
|
+
let: { eid: "$_id" },
|
|
811
|
+
pipeline: [
|
|
812
|
+
{ $match: { $expr: { $eq: ["$toEntityId", "$$eid"] } } }
|
|
813
|
+
],
|
|
814
|
+
as: "incomingRelations"
|
|
815
|
+
}},
|
|
816
|
+
// Merge them
|
|
817
|
+
{ $addFields: {
|
|
818
|
+
allRelations: { $concatArrays: ["$outgoingRelations", "$incomingRelations"] }
|
|
819
|
+
}}
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
2. **Ensure indexes exist** on both `fromEntityId` and `toEntityId` in the relations collection.
|
|
823
|
+
3. **Use `explain("executionStats")`** to verify index usage after the change.
|
|
824
|
+
|
|
825
|
+
### Caveats / Limitations
|
|
826
|
+
|
|
827
|
+
- Two `$lookup` stages means two passes over the foreign collection, but each is indexed
|
|
828
|
+
- This is more efficient than one `$lookup` with `$or` that does a COLLSCAN
|
|
829
|
+
- The `$concatArrays` merge may produce duplicates if a relation references the same entity on both sides -- add `$setUnion` or dedup logic if needed
|
|
830
|
+
|
|
831
|
+
---
|
|
832
|
+
|
|
833
|
+
## B1. MongoDB Official Patterns for "Write Fast, Enrich Later"
|
|
834
|
+
|
|
835
|
+
### Problem
|
|
836
|
+
|
|
837
|
+
ClawMongo uses an event-sourcing pattern where events are written first and enriched asynchronously.
|
|
838
|
+
|
|
839
|
+
### MongoDB Documentation Sources
|
|
840
|
+
|
|
841
|
+
- URL: https://www.mongodb.com/docs/manual/changeStreams/
|
|
842
|
+
- Change streams enable reactive architectures: "applications [can] access real-time data changes without the complexity and risk of tailing the oplog"
|
|
843
|
+
- URL: https://www.mongodb.com/docs/manual/administration/change-streams-production-recommendations/
|
|
844
|
+
- Production guidance for change stream usage
|
|
845
|
+
- URL: https://www.mongodb.com/resources/basics/artificial-intelligence/agent-memory
|
|
846
|
+
- MongoDB's agent memory patterns page (concept-level)
|
|
847
|
+
|
|
848
|
+
### Recommendations for ClawMongo
|
|
849
|
+
|
|
850
|
+
1. **The "write fast, enrich later" pattern maps directly to Change Streams:**
|
|
851
|
+
- Write raw events to the `events` collection (fast write path)
|
|
852
|
+
- A Change Stream watcher picks up new inserts
|
|
853
|
+
- Async enrichment runs (entity extraction, embedding generation, episode materialization)
|
|
854
|
+
- Enrichment results written back to events or to derived collections
|
|
855
|
+
2. **Store resume tokens** in a `change_stream_checkpoints` collection for crash recovery
|
|
856
|
+
3. **Use `$match` in the change stream pipeline** to filter only relevant operation types (inserts)
|
|
857
|
+
4. **For atlas-local development**, Change Streams work because atlas-local runs as a replica set
|
|
858
|
+
|
|
859
|
+
### Caveats / Limitations
|
|
860
|
+
|
|
861
|
+
- Change Streams require a replica set or sharded cluster
|
|
862
|
+
- Resume tokens have a limited lifetime (tied to oplog size)
|
|
863
|
+
- Cannot index the oplog; high-volume change streams impact performance
|
|
864
|
+
- Consider batching enrichment work rather than processing one event at a time
|
|
865
|
+
|
|
866
|
+
---
|
|
867
|
+
|
|
868
|
+
## B2. $rankFusion and $scoreFusion
|
|
869
|
+
|
|
870
|
+
### Problem
|
|
871
|
+
|
|
872
|
+
Need to understand the official MongoDB operators for normalizing and fusing scores across search methods.
|
|
873
|
+
|
|
874
|
+
### MongoDB Documentation Sources
|
|
875
|
+
|
|
876
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/rankFusion/
|
|
877
|
+
- Version: MongoDB 8.0+, Preview feature
|
|
878
|
+
- Uses Reciprocal Rank Fusion: `RRF(d) = sum(weight_i / (60 + rank_i(d)))`
|
|
879
|
+
- De-duplicates results across pipelines
|
|
880
|
+
- Supports weighted pipelines via `combination.weights`
|
|
881
|
+
- Input pipelines must be Selection Pipelines AND Ranked Pipelines
|
|
882
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/
|
|
883
|
+
- Version: MongoDB 8.2+, Preview feature
|
|
884
|
+
- Score-based fusion with normalization: `none`, `sigmoid`, `minMaxScaler`
|
|
885
|
+
- Supports custom combination expressions: `method: "expression"` with custom `$sum`, `$multiply` etc.
|
|
886
|
+
- Input pipelines must be Selection Pipelines AND Scoring Pipelines
|
|
887
|
+
- If input pipeline doesn't return a score, must add a `$score` stage
|
|
888
|
+
- URL: https://www.mongodb.com/docs/manual/reference/operator/aggregation/score/
|
|
889
|
+
- Version: MongoDB 8.2+
|
|
890
|
+
- Standalone `$score` stage for computing/normalizing scores
|
|
891
|
+
- Normalization options: `none`, `sigmoid`, `minMaxScaler`
|
|
892
|
+
- Can apply `weight` multiplier after normalization
|
|
893
|
+
|
|
894
|
+
### Official Pattern / Syntax
|
|
895
|
+
|
|
896
|
+
**$rankFusion with weights:**
|
|
897
|
+
|
|
898
|
+
```javascript
|
|
899
|
+
{
|
|
900
|
+
$rankFusion: {
|
|
901
|
+
input: {
|
|
902
|
+
pipelines: {
|
|
903
|
+
vector: [{ $vectorSearch: { ... } }],
|
|
904
|
+
text: [{ $search: { ... } }, { $limit: 20 }]
|
|
905
|
+
}
|
|
906
|
+
},
|
|
907
|
+
combination: {
|
|
908
|
+
weights: { vector: 3, text: 1 } // vector results weighted 3x
|
|
909
|
+
},
|
|
910
|
+
scoreDetails: true
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
```
|
|
914
|
+
|
|
915
|
+
**$scoreFusion with sigmoid normalization and custom expression:**
|
|
916
|
+
|
|
917
|
+
```javascript
|
|
918
|
+
{
|
|
919
|
+
$scoreFusion: {
|
|
920
|
+
input: {
|
|
921
|
+
pipelines: {
|
|
922
|
+
vector: [{ $vectorSearch: { ... } }],
|
|
923
|
+
text: [{ $search: { ... } }, { $limit: 20 }]
|
|
924
|
+
},
|
|
925
|
+
normalization: "sigmoid"
|
|
926
|
+
},
|
|
927
|
+
combination: {
|
|
928
|
+
method: "expression",
|
|
929
|
+
expression: {
|
|
930
|
+
$sum: [
|
|
931
|
+
{ $multiply: ["$$vector", 10] },
|
|
932
|
+
"$$text"
|
|
933
|
+
]
|
|
934
|
+
}
|
|
935
|
+
},
|
|
936
|
+
scoreDetails: true
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
**$score stage for normalizing non-search scores:**
|
|
942
|
+
|
|
943
|
+
```javascript
|
|
944
|
+
// Add a score to a pipeline that doesn't inherently produce one
|
|
945
|
+
[
|
|
946
|
+
{ $match: { type: "structured_fact", scope: "agent123" } },
|
|
947
|
+
{ $sort: { relevance: -1 } },
|
|
948
|
+
{
|
|
949
|
+
$score: {
|
|
950
|
+
score: "$relevance",
|
|
951
|
+
normalization: "sigmoid",
|
|
952
|
+
weight: 0.5,
|
|
953
|
+
},
|
|
954
|
+
},
|
|
955
|
+
];
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
### Recommendations for ClawMongo
|
|
959
|
+
|
|
960
|
+
1. **For MongoDB 8.0+ (atlas-local):** Use `$rankFusion` for hybrid search combining `$vectorSearch` and `$search` pipelines. This is the simplest and most robust approach.
|
|
961
|
+
2. **For MongoDB 8.2+:** Use `$scoreFusion` with `normalization: "sigmoid"` for score-aware fusion that preserves magnitude differences.
|
|
962
|
+
3. **For non-search sources (structured memory, episodes):** Use `$score` stage to assign and normalize scores before feeding into `$scoreFusion`.
|
|
963
|
+
4. **Manual RRF remains necessary** for merging results from different collections (the native operators work on a single collection only).
|
|
964
|
+
5. **Use `scoreDetails: true`** during development to debug and tune fusion weights.
|
|
965
|
+
|
|
966
|
+
### Caveats / Limitations
|
|
967
|
+
|
|
968
|
+
- Both `$rankFusion` and `$scoreFusion` are **Preview features** (not GA)
|
|
969
|
+
- Both require all input pipelines to operate on the **same collection**
|
|
970
|
+
- `$rankFusion` requires MongoDB 8.0+; `$scoreFusion` requires MongoDB 8.2+
|
|
971
|
+
- `$scoreFusion` requires each pipeline to produce a score (add `$score` stage if not)
|
|
972
|
+
- Pipeline names must not start with `$`, contain `.`, or contain null characters
|
|
973
|
+
- MongoDB does not guarantee specific output format for `scoreDetails`
|
|
974
|
+
- Both stages operate on a single collection only -- cannot fuse results from multiple collections
|
|
975
|
+
|
|
976
|
+
---
|
|
977
|
+
|
|
978
|
+
## Summary Table
|
|
979
|
+
|
|
980
|
+
| Issue | MongoDB Solution | Min Version | Status |
|
|
981
|
+
| ---------------------------- | ------------------------------------------------------------ | ------------------ | ------- |
|
|
982
|
+
| C1. Score normalization | `$rankFusion` / `$scoreFusion` / manual RRF | 8.0+ / 8.2+ / any | Preview |
|
|
983
|
+
| C2. $facet + $lookup perf | Split $or into two $lookup stages | any | GA |
|
|
984
|
+
| C3. Fetch timeouts | Application-level (not MongoDB) | N/A | N/A |
|
|
985
|
+
| H1. bulkWrite upserts | `db.collection.bulkWrite()` with `ordered: false` | any | GA |
|
|
986
|
+
| H2. Change Streams | `collection.watch()` with resume tokens | 3.6+ (replica set) | GA |
|
|
987
|
+
| H3. Vector pre-filter | `$vectorSearch` `filter` clause with indexed filter fields | 6.0+ (Atlas) | GA |
|
|
988
|
+
| H4. Variable TTL | TTL index with `expireAfterSeconds: 0` + per-doc `expiresAt` | any | GA |
|
|
989
|
+
| H5. Empty doc handling | `$match`/`$cond` filtering (application pattern) | any | N/A |
|
|
990
|
+
| M1. $percentile | `$percentile` accumulator | 7.0+ | GA |
|
|
991
|
+
| M2. Unbounded queries | Always add `$limit` to time-range queries | any | GA |
|
|
992
|
+
| M3. Server-side stats | `$avg`, `$stdDevPop`, `$percentile`, `$median` in `$group` | 7.0+ | GA |
|
|
993
|
+
| M4. $lookup index usage | Split `$or` into two indexed `$eq` lookups | any | GA |
|
|
994
|
+
| B1. Write-then-enrich | Change Streams + async enrichment | 3.6+ | GA |
|
|
995
|
+
| B2. $rankFusion/$scoreFusion | Native hybrid search stages | 8.0+ / 8.2+ | Preview |
|