@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
|
@@ -1,22 +1,42 @@
|
|
|
1
1
|
import { n as redactSensitiveText } from "./redact-BDinS1q9.js";
|
|
2
2
|
import { t as createSubsystemLogger } from "./subsystem-VzQeL-96.js";
|
|
3
|
-
import { p as resolveAgentWorkspaceDir } from "./agent-scope-
|
|
3
|
+
import { p as resolveAgentWorkspaceDir } from "./agent-scope-DXZH506l.js";
|
|
4
4
|
import { c as resolveSessionTranscriptsDirForAgent } from "./paths-CGTGVWe2.js";
|
|
5
|
-
import { a as listMemoryFiles, n as chunkMarkdown, o as normalizeExtraMemoryPaths, r as hashText, t as buildFileEntry } from "./internal-
|
|
6
|
-
import {
|
|
5
|
+
import { a as listMemoryFiles, n as chunkMarkdown, o as normalizeExtraMemoryPaths, r as hashText, t as buildFileEntry } from "./internal-DLE9baj7.js";
|
|
6
|
+
import { C as relationsCollection, D as structuredMemCollection, E as relevanceRunsCollection, S as queryCacheCollection, _ as metaCollection, a as ensureCollections, b as proceduresCollection, c as ensureStandardIndexes, d as episodesCollection, f as eventsCollection, g as kbCollection, h as kbChunksCollection, k as telemetryCollection, l as entitiesCollection, m as ingestRunsCollection, n as chunksCollection, p as filesCollection, r as detectCapabilities, s as ensureSearchIndexes, u as entityLinksCollection, x as projectionRunsCollection } from "./mongodb-schema-Dt6jxcPL.js";
|
|
7
7
|
import { t as resolveScopeRef } from "./mongodb-scope-0bwP6Q3D.js";
|
|
8
|
-
import {
|
|
9
|
-
import { n as
|
|
10
|
-
import { t as
|
|
11
|
-
import {
|
|
12
|
-
import { t as searchKB } from "./mongodb-kb-search-
|
|
8
|
+
import { n as writeStructuredMemory, t as searchStructuredMemory } from "./mongodb-structured-memory-D-3SEfTu.js";
|
|
9
|
+
import { a as normalizeSearchResults, n as buildVectorSearchStage, o as rrfScore, r as mongoSearch, s as MongoDBRelevanceRuntime } from "./mongodb-search-DMsUyfpa.js";
|
|
10
|
+
import { n as writeProcedure, t as searchProcedures } from "./mongodb-procedures-DI-_Dakz.js";
|
|
11
|
+
import { t as getMemoryStats } from "./mongodb-analytics-mnKJih5x.js";
|
|
12
|
+
import { t as searchKB } from "./mongodb-kb-search-Dq6E746K.js";
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
import fs from "node:fs/promises";
|
|
15
15
|
import { createHash, randomUUID } from "node:crypto";
|
|
16
16
|
import chokidar from "chokidar";
|
|
17
17
|
import { MongoClient } from "mongodb";
|
|
18
|
+
//#region src/memory/mongodb-telemetry.ts
|
|
19
|
+
const log$14 = createSubsystemLogger("memory:mongodb:telemetry");
|
|
20
|
+
/**
|
|
21
|
+
* Emit a telemetry document to the memory_telemetry time series collection.
|
|
22
|
+
* Fire-and-forget: never blocks the caller, never throws.
|
|
23
|
+
* Uses insertOne with .catch() for error-swallowing.
|
|
24
|
+
*/
|
|
25
|
+
function emitTelemetry(db, prefix, doc) {
|
|
26
|
+
const entry = {
|
|
27
|
+
...doc,
|
|
28
|
+
ts: /* @__PURE__ */ new Date()
|
|
29
|
+
};
|
|
30
|
+
telemetryCollection(db, prefix).insertOne(entry).catch((err) => {
|
|
31
|
+
log$14.warn("telemetry emit failed", {
|
|
32
|
+
operation: doc.meta.operation,
|
|
33
|
+
error: err
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
18
38
|
//#region src/memory/mongodb-ops.ts
|
|
19
|
-
const log$
|
|
39
|
+
const log$13 = createSubsystemLogger("memory:mongodb:ops");
|
|
20
40
|
async function recordProjectionRun(params) {
|
|
21
41
|
const { db, prefix, run } = params;
|
|
22
42
|
const runId = randomUUID();
|
|
@@ -27,9 +47,18 @@ async function recordProjectionRun(params) {
|
|
|
27
47
|
};
|
|
28
48
|
try {
|
|
29
49
|
await projectionRunsCollection(db, prefix).insertOne(doc);
|
|
50
|
+
emitTelemetry(db, prefix, {
|
|
51
|
+
meta: {
|
|
52
|
+
agentId: run.agentId,
|
|
53
|
+
operation: "projection-run"
|
|
54
|
+
},
|
|
55
|
+
durationMs: run.durationMs,
|
|
56
|
+
ok: run.status === "ok",
|
|
57
|
+
itemCount: run.itemsProjected
|
|
58
|
+
});
|
|
30
59
|
return runId;
|
|
31
60
|
} catch (err) {
|
|
32
|
-
log$
|
|
61
|
+
log$13.error("recordProjectionRun failed", {
|
|
33
62
|
runId,
|
|
34
63
|
error: err
|
|
35
64
|
});
|
|
@@ -41,7 +70,7 @@ async function getLatestIngestRun(params) {
|
|
|
41
70
|
try {
|
|
42
71
|
return await ingestRunsCollection(db, prefix).findOne({ agentId }, { sort: { ts: -1 } }) ?? null;
|
|
43
72
|
} catch (err) {
|
|
44
|
-
log$
|
|
73
|
+
log$13.error("getLatestIngestRun failed", {
|
|
45
74
|
agentId,
|
|
46
75
|
error: err
|
|
47
76
|
});
|
|
@@ -56,7 +85,7 @@ async function getLatestProjectionRun(params) {
|
|
|
56
85
|
projectionType
|
|
57
86
|
}, { sort: { ts: -1 } }) ?? null;
|
|
58
87
|
} catch (err) {
|
|
59
|
-
log$
|
|
88
|
+
log$13.error("getLatestProjectionRun failed", {
|
|
60
89
|
agentId,
|
|
61
90
|
projectionType,
|
|
62
91
|
error: err
|
|
@@ -76,7 +105,7 @@ async function getProjectionLag(params) {
|
|
|
76
105
|
const ts = doc.ts;
|
|
77
106
|
return Math.floor((Date.now() - ts.getTime()) / 1e3);
|
|
78
107
|
} catch (err) {
|
|
79
|
-
log$
|
|
108
|
+
log$13.error("getProjectionLag failed", {
|
|
80
109
|
agentId,
|
|
81
110
|
projectionType,
|
|
82
111
|
error: err
|
|
@@ -86,7 +115,7 @@ async function getProjectionLag(params) {
|
|
|
86
115
|
}
|
|
87
116
|
//#endregion
|
|
88
117
|
//#region src/memory/mongodb-events.ts
|
|
89
|
-
const log$
|
|
118
|
+
const log$12 = createSubsystemLogger("memory:mongodb:events");
|
|
90
119
|
function renderEventChunkText(event) {
|
|
91
120
|
return `${event.role.charAt(0).toUpperCase() + event.role.slice(1)}: ${event.body}`;
|
|
92
121
|
}
|
|
@@ -115,7 +144,7 @@ async function writeEvent(params) {
|
|
|
115
144
|
...event.metadata && { metadata: event.metadata }
|
|
116
145
|
};
|
|
117
146
|
await collection.updateOne({ eventId }, { $setOnInsert: doc }, { upsert: true });
|
|
118
|
-
log$
|
|
147
|
+
log$12.info(`event written: ${eventId} role=${event.role}`);
|
|
119
148
|
return {
|
|
120
149
|
eventId,
|
|
121
150
|
timestamp,
|
|
@@ -156,7 +185,7 @@ async function markEventsConsolidated(params) {
|
|
|
156
185
|
consolidatedAt: /* @__PURE__ */ new Date(),
|
|
157
186
|
consolidatedIntoEpisodeId: episodeId
|
|
158
187
|
} });
|
|
159
|
-
log$
|
|
188
|
+
log$12.info(`marked ${result.modifiedCount} events consolidated into episode=${episodeId}`);
|
|
160
189
|
return result.modifiedCount;
|
|
161
190
|
}
|
|
162
191
|
/**
|
|
@@ -212,9 +241,132 @@ async function projectEventChunk(params) {
|
|
|
212
241
|
}).catch(() => {});
|
|
213
242
|
return { chunkCreated: result.upsertedCount > 0 };
|
|
214
243
|
}
|
|
244
|
+
createSubsystemLogger("memory:mongodb:entity-extractor");
|
|
245
|
+
const STOP_WORDS = new Set([
|
|
246
|
+
"the",
|
|
247
|
+
"a",
|
|
248
|
+
"an",
|
|
249
|
+
"is",
|
|
250
|
+
"are",
|
|
251
|
+
"was",
|
|
252
|
+
"were",
|
|
253
|
+
"be",
|
|
254
|
+
"been",
|
|
255
|
+
"being",
|
|
256
|
+
"have",
|
|
257
|
+
"has",
|
|
258
|
+
"had",
|
|
259
|
+
"do",
|
|
260
|
+
"does",
|
|
261
|
+
"did",
|
|
262
|
+
"will",
|
|
263
|
+
"would",
|
|
264
|
+
"could",
|
|
265
|
+
"should",
|
|
266
|
+
"may",
|
|
267
|
+
"might",
|
|
268
|
+
"can",
|
|
269
|
+
"shall",
|
|
270
|
+
"must",
|
|
271
|
+
"need",
|
|
272
|
+
"not",
|
|
273
|
+
"and",
|
|
274
|
+
"or",
|
|
275
|
+
"but",
|
|
276
|
+
"if",
|
|
277
|
+
"then",
|
|
278
|
+
"else",
|
|
279
|
+
"when",
|
|
280
|
+
"where",
|
|
281
|
+
"how",
|
|
282
|
+
"what",
|
|
283
|
+
"which",
|
|
284
|
+
"who",
|
|
285
|
+
"whom",
|
|
286
|
+
"this",
|
|
287
|
+
"that",
|
|
288
|
+
"these",
|
|
289
|
+
"those",
|
|
290
|
+
"it",
|
|
291
|
+
"its",
|
|
292
|
+
"i",
|
|
293
|
+
"me",
|
|
294
|
+
"my",
|
|
295
|
+
"we",
|
|
296
|
+
"our",
|
|
297
|
+
"you",
|
|
298
|
+
"your",
|
|
299
|
+
"he",
|
|
300
|
+
"she",
|
|
301
|
+
"him",
|
|
302
|
+
"her",
|
|
303
|
+
"they",
|
|
304
|
+
"them",
|
|
305
|
+
"their"
|
|
306
|
+
]);
|
|
307
|
+
const MENTION_REGEX = /@(\w{3,})/g;
|
|
308
|
+
const TAG_REGEX = /#(\w{3,})/g;
|
|
309
|
+
const URL_REGEX = /https?:\/\/[^\s)]+/g;
|
|
310
|
+
const FILE_PATH_REGEX = /(?:^|\s)((?:[\w.-]+\/)+[\w.-]+\.\w+)/g;
|
|
311
|
+
const QUOTED_NAME_REGEX = /"([^"]{3,})"/g;
|
|
312
|
+
const DATE_REGEX = /\b(\d{4}-\d{2}-\d{2}|\w+ \d{1,2},? \d{4}|\d{1,2}\/\d{1,2}\/\d{4})\b/g;
|
|
313
|
+
var RegexEntityExtractor = class {
|
|
314
|
+
async extract(content) {
|
|
315
|
+
const entities = [];
|
|
316
|
+
const seen = /* @__PURE__ */ new Set();
|
|
317
|
+
const addEntity = (name, type) => {
|
|
318
|
+
if (type !== "document" && STOP_WORDS.has(name.toLowerCase())) return;
|
|
319
|
+
const key = `${name.toLowerCase()}:${type}`;
|
|
320
|
+
if (!seen.has(key)) {
|
|
321
|
+
seen.add(key);
|
|
322
|
+
entities.push({
|
|
323
|
+
name,
|
|
324
|
+
type,
|
|
325
|
+
confidence: .5,
|
|
326
|
+
extractionMethod: "regex"
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
for (const match of content.matchAll(MENTION_REGEX)) addEntity(match[1], "person");
|
|
331
|
+
for (const match of content.matchAll(TAG_REGEX)) addEntity(match[1], "topic");
|
|
332
|
+
for (const match of content.matchAll(URL_REGEX)) addEntity(match[0], "document");
|
|
333
|
+
for (const match of content.matchAll(FILE_PATH_REGEX)) addEntity(match[1], "document");
|
|
334
|
+
for (const match of content.matchAll(QUOTED_NAME_REGEX)) {
|
|
335
|
+
const name = match[1];
|
|
336
|
+
if (name && name.trim().length >= 3 && !STOP_WORDS.has(name.toLowerCase().trim())) {
|
|
337
|
+
const key = `${name.trim().toLowerCase()}:person`;
|
|
338
|
+
if (!seen.has(key)) {
|
|
339
|
+
seen.add(key);
|
|
340
|
+
entities.push({
|
|
341
|
+
name: name.trim(),
|
|
342
|
+
type: "person",
|
|
343
|
+
confidence: .5,
|
|
344
|
+
extractionMethod: "regex"
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
for (const match of content.matchAll(DATE_REGEX)) {
|
|
350
|
+
const dateName = match[1].trim();
|
|
351
|
+
if (dateName.length >= 5) {
|
|
352
|
+
const key = `${dateName.toLowerCase()}:concept`;
|
|
353
|
+
if (!seen.has(key)) {
|
|
354
|
+
seen.add(key);
|
|
355
|
+
entities.push({
|
|
356
|
+
name: dateName,
|
|
357
|
+
type: "concept",
|
|
358
|
+
confidence: .7,
|
|
359
|
+
extractionMethod: "regex"
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return entities;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
215
367
|
//#endregion
|
|
216
368
|
//#region src/memory/mongodb-graph.ts
|
|
217
|
-
const log$
|
|
369
|
+
const log$10 = createSubsystemLogger("memory:mongodb:graph");
|
|
218
370
|
function relationPriority(type) {
|
|
219
371
|
switch (type) {
|
|
220
372
|
case "works_on":
|
|
@@ -263,133 +415,6 @@ function inferEntityLinkType(left, right) {
|
|
|
263
415
|
provenance: { heuristic: "co-mentioned" }
|
|
264
416
|
};
|
|
265
417
|
}
|
|
266
|
-
async function upsertEntity(params) {
|
|
267
|
-
const { db, prefix, entity } = params;
|
|
268
|
-
try {
|
|
269
|
-
const collection = entitiesCollection(db, prefix);
|
|
270
|
-
const now = /* @__PURE__ */ new Date();
|
|
271
|
-
const scopeRef = resolveScopeRef({
|
|
272
|
-
scope: entity.scope,
|
|
273
|
-
scopeRef: entity.scopeRef,
|
|
274
|
-
agentId: entity.agentId
|
|
275
|
-
});
|
|
276
|
-
const setDoc = {
|
|
277
|
-
entityId: entity.entityId,
|
|
278
|
-
name: entity.name,
|
|
279
|
-
type: entity.type,
|
|
280
|
-
agentId: entity.agentId,
|
|
281
|
-
scope: entity.scope,
|
|
282
|
-
scopeRef,
|
|
283
|
-
updatedAt: now
|
|
284
|
-
};
|
|
285
|
-
if (entity.aliases !== void 0) setDoc.aliases = entity.aliases;
|
|
286
|
-
if (entity.metadata !== void 0) setDoc.metadata = entity.metadata;
|
|
287
|
-
if (entity.sourceEventIds !== void 0) setDoc.sourceEventIds = entity.sourceEventIds;
|
|
288
|
-
const upserted = (await collection.updateOne({
|
|
289
|
-
entityId: entity.entityId,
|
|
290
|
-
agentId: entity.agentId,
|
|
291
|
-
scope: entity.scope,
|
|
292
|
-
scopeRef
|
|
293
|
-
}, {
|
|
294
|
-
$set: setDoc,
|
|
295
|
-
$setOnInsert: { createdAt: now }
|
|
296
|
-
}, { upsert: true })).upsertedCount > 0;
|
|
297
|
-
log$7.info(`entity ${upserted ? "created" : "updated"}: ${entity.entityId} name=${entity.name}`);
|
|
298
|
-
return { upserted };
|
|
299
|
-
} catch (err) {
|
|
300
|
-
log$7.error(`upsertEntity failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
301
|
-
throw err;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
async function upsertRelation(params) {
|
|
305
|
-
const { db, prefix, relation } = params;
|
|
306
|
-
try {
|
|
307
|
-
const collection = relationsCollection(db, prefix);
|
|
308
|
-
const now = /* @__PURE__ */ new Date();
|
|
309
|
-
const scopeRef = resolveScopeRef({
|
|
310
|
-
scope: relation.scope,
|
|
311
|
-
scopeRef: relation.scopeRef,
|
|
312
|
-
agentId: relation.agentId
|
|
313
|
-
});
|
|
314
|
-
const setDoc = {
|
|
315
|
-
fromEntityId: relation.fromEntityId,
|
|
316
|
-
toEntityId: relation.toEntityId,
|
|
317
|
-
type: relation.type,
|
|
318
|
-
agentId: relation.agentId,
|
|
319
|
-
scope: relation.scope,
|
|
320
|
-
scopeRef,
|
|
321
|
-
updatedAt: now
|
|
322
|
-
};
|
|
323
|
-
if (relation.weight !== void 0) setDoc.weight = relation.weight;
|
|
324
|
-
if (relation.sourceEventIds !== void 0) setDoc.sourceEventIds = relation.sourceEventIds;
|
|
325
|
-
const upserted = (await collection.updateOne({
|
|
326
|
-
fromEntityId: relation.fromEntityId,
|
|
327
|
-
toEntityId: relation.toEntityId,
|
|
328
|
-
type: relation.type,
|
|
329
|
-
agentId: relation.agentId,
|
|
330
|
-
scope: relation.scope,
|
|
331
|
-
scopeRef
|
|
332
|
-
}, {
|
|
333
|
-
$set: setDoc,
|
|
334
|
-
$setOnInsert: { createdAt: now }
|
|
335
|
-
}, { upsert: true })).upsertedCount > 0;
|
|
336
|
-
log$7.info(`relation ${upserted ? "created" : "updated"}: ${relation.fromEntityId} -[${relation.type}]-> ${relation.toEntityId}`);
|
|
337
|
-
return { upserted };
|
|
338
|
-
} catch (err) {
|
|
339
|
-
log$7.error(`upsertRelation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
340
|
-
throw err;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
async function upsertEntityLink(params) {
|
|
344
|
-
const { db, prefix, link } = params;
|
|
345
|
-
try {
|
|
346
|
-
const collection = entityLinksCollection(db, prefix);
|
|
347
|
-
const scopeRef = resolveScopeRef({
|
|
348
|
-
scope: link.scope,
|
|
349
|
-
scopeRef: link.scopeRef,
|
|
350
|
-
agentId: link.agentId
|
|
351
|
-
});
|
|
352
|
-
const pair = canonicalizeEntityPair(link.fromEntityId, link.toEntityId);
|
|
353
|
-
const linkId = link.linkId ?? makeEntityLinkId({
|
|
354
|
-
...pair,
|
|
355
|
-
linkType: link.linkType,
|
|
356
|
-
agentId: link.agentId,
|
|
357
|
-
scope: link.scope,
|
|
358
|
-
scopeRef
|
|
359
|
-
});
|
|
360
|
-
const now = link.updatedAt ?? /* @__PURE__ */ new Date();
|
|
361
|
-
const setDoc = {
|
|
362
|
-
linkId,
|
|
363
|
-
...pair,
|
|
364
|
-
linkType: link.linkType,
|
|
365
|
-
status: link.status,
|
|
366
|
-
confidence: link.confidence,
|
|
367
|
-
agentId: link.agentId,
|
|
368
|
-
scope: link.scope,
|
|
369
|
-
scopeRef,
|
|
370
|
-
updatedAt: now
|
|
371
|
-
};
|
|
372
|
-
if (link.sourceEventIds !== void 0) setDoc.sourceEventIds = link.sourceEventIds;
|
|
373
|
-
if (link.provenance !== void 0) setDoc.provenance = link.provenance;
|
|
374
|
-
return {
|
|
375
|
-
upserted: (await collection.updateOne({
|
|
376
|
-
agentId: link.agentId,
|
|
377
|
-
scope: link.scope,
|
|
378
|
-
scopeRef,
|
|
379
|
-
fromEntityId: pair.fromEntityId,
|
|
380
|
-
toEntityId: pair.toEntityId,
|
|
381
|
-
linkType: link.linkType
|
|
382
|
-
}, {
|
|
383
|
-
$set: setDoc,
|
|
384
|
-
$setOnInsert: { createdAt: now }
|
|
385
|
-
}, { upsert: true })).upsertedCount > 0,
|
|
386
|
-
linkId
|
|
387
|
-
};
|
|
388
|
-
} catch (err) {
|
|
389
|
-
log$7.error(`upsertEntityLink failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
390
|
-
throw err;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
418
|
async function findEntitiesByName(params) {
|
|
394
419
|
const { db, prefix, query, agentId, scope, scopeRef, limit } = params;
|
|
395
420
|
try {
|
|
@@ -404,12 +429,13 @@ async function findEntitiesByName(params) {
|
|
|
404
429
|
if (scopeRef) filter.scopeRef = scopeRef;
|
|
405
430
|
return await collection.find(filter).sort({ updatedAt: -1 }).limit(limit ?? 50).toArray();
|
|
406
431
|
} catch (err) {
|
|
407
|
-
log$
|
|
432
|
+
log$10.error(`findEntitiesByName failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
408
433
|
throw err;
|
|
409
434
|
}
|
|
410
435
|
}
|
|
411
436
|
async function expandGraph(params) {
|
|
412
437
|
const { db, prefix, entityId, agentId, scope, scopeRef, maxDepth, bidirectional, maxConnections } = params;
|
|
438
|
+
const graphStart = Date.now();
|
|
413
439
|
try {
|
|
414
440
|
const entCol = entitiesCollection(db, prefix);
|
|
415
441
|
const relCol = relationsCollection(db, prefix);
|
|
@@ -546,133 +572,66 @@ async function expandGraph(params) {
|
|
|
546
572
|
});
|
|
547
573
|
const connectionLimit = maxConnections ?? 100;
|
|
548
574
|
const limitedConnections = connections.slice(0, connectionLimit);
|
|
549
|
-
if (connections.length > connectionLimit) log$
|
|
575
|
+
if (connections.length > connectionLimit) log$10.warn(`expandGraph: truncated ${connections.length} connections to maxConnections=${connectionLimit} for entity=${entityId}`);
|
|
576
|
+
emitTelemetry(db, prefix, {
|
|
577
|
+
meta: {
|
|
578
|
+
agentId,
|
|
579
|
+
operation: "graph-expansion"
|
|
580
|
+
},
|
|
581
|
+
durationMs: Date.now() - graphStart,
|
|
582
|
+
ok: true,
|
|
583
|
+
resultCount: limitedConnections.length
|
|
584
|
+
});
|
|
550
585
|
return {
|
|
551
586
|
rootEntity,
|
|
552
587
|
connections: limitedConnections
|
|
553
588
|
};
|
|
554
589
|
} catch (err) {
|
|
555
|
-
log$
|
|
590
|
+
log$10.error(`expandGraph failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
556
591
|
throw err;
|
|
557
592
|
}
|
|
558
593
|
}
|
|
559
|
-
const
|
|
560
|
-
"the",
|
|
561
|
-
"a",
|
|
562
|
-
"an",
|
|
563
|
-
"is",
|
|
564
|
-
"are",
|
|
565
|
-
"was",
|
|
566
|
-
"were",
|
|
567
|
-
"be",
|
|
568
|
-
"been",
|
|
569
|
-
"being",
|
|
570
|
-
"have",
|
|
571
|
-
"has",
|
|
572
|
-
"had",
|
|
573
|
-
"do",
|
|
574
|
-
"does",
|
|
575
|
-
"did",
|
|
576
|
-
"will",
|
|
577
|
-
"would",
|
|
578
|
-
"could",
|
|
579
|
-
"should",
|
|
580
|
-
"may",
|
|
581
|
-
"might",
|
|
582
|
-
"can",
|
|
583
|
-
"shall",
|
|
584
|
-
"must",
|
|
585
|
-
"need",
|
|
586
|
-
"not",
|
|
587
|
-
"and",
|
|
588
|
-
"or",
|
|
589
|
-
"but",
|
|
590
|
-
"if",
|
|
591
|
-
"then",
|
|
592
|
-
"else",
|
|
593
|
-
"when",
|
|
594
|
-
"where",
|
|
595
|
-
"how",
|
|
596
|
-
"what",
|
|
597
|
-
"which",
|
|
598
|
-
"who",
|
|
599
|
-
"whom",
|
|
600
|
-
"this",
|
|
601
|
-
"that",
|
|
602
|
-
"these",
|
|
603
|
-
"those",
|
|
604
|
-
"it",
|
|
605
|
-
"its",
|
|
606
|
-
"i",
|
|
607
|
-
"me",
|
|
608
|
-
"my",
|
|
609
|
-
"we",
|
|
610
|
-
"our",
|
|
611
|
-
"you",
|
|
612
|
-
"your",
|
|
613
|
-
"he",
|
|
614
|
-
"she",
|
|
615
|
-
"him",
|
|
616
|
-
"her",
|
|
617
|
-
"they",
|
|
618
|
-
"them",
|
|
619
|
-
"their"
|
|
620
|
-
]);
|
|
621
|
-
const MENTION_REGEX = /@(\w{3,})/g;
|
|
622
|
-
const TAG_REGEX = /#(\w{3,})/g;
|
|
623
|
-
const URL_REGEX = /https?:\/\/[^\s)]+/g;
|
|
624
|
-
const FILE_PATH_REGEX = /(?:^|\s)((?:[\w.-]+\/)+[\w.-]+\.\w+)/g;
|
|
625
|
-
const QUOTED_NAME_REGEX = /"([^"]{3,})"/g;
|
|
594
|
+
const defaultExtractor = new RegexEntityExtractor();
|
|
626
595
|
function makeEntityId(name, type, agentId, scope, scopeRef) {
|
|
627
596
|
return createHash("sha256").update(`${agentId}:${scope}:${scopeRef}:${name.toLowerCase()}:${type}`).digest("hex").slice(0, 16);
|
|
628
597
|
}
|
|
629
598
|
/**
|
|
630
599
|
* Extract structural entities from event content and upsert them.
|
|
631
|
-
*
|
|
632
|
-
* file paths->document, "quoted names"->person.
|
|
600
|
+
* Uses a pluggable EntityExtractor (defaults to RegexEntityExtractor).
|
|
633
601
|
*
|
|
634
602
|
* Deterministic entityIds via hash of name.toLowerCase() + type.
|
|
635
603
|
* Fire-and-forget: caller decides whether to await.
|
|
636
604
|
* SEPARATE from writeEvent -- not called automatically.
|
|
637
605
|
*/
|
|
638
606
|
async function extractAndUpsertEntities(params) {
|
|
639
|
-
const { db, prefix, agentId, eventContent, scope, sourceEventId } = params;
|
|
607
|
+
const { db, prefix, agentId, eventContent, scope, sourceEventId, role } = params;
|
|
640
608
|
const startMs = Date.now();
|
|
641
609
|
const scopeRef = resolveScopeRef({
|
|
642
610
|
scope,
|
|
643
611
|
scopeRef: params.scopeRef,
|
|
644
612
|
agentId
|
|
645
613
|
});
|
|
614
|
+
const extractor = params.extractor ?? defaultExtractor;
|
|
615
|
+
const extractorContext = role ? {
|
|
616
|
+
agentId,
|
|
617
|
+
scope,
|
|
618
|
+
scopeRef,
|
|
619
|
+
role
|
|
620
|
+
} : void 0;
|
|
621
|
+
const extractorResults = await extractor.extract(eventContent, extractorContext);
|
|
646
622
|
const extracted = [];
|
|
647
623
|
const seen = /* @__PURE__ */ new Set();
|
|
648
|
-
|
|
649
|
-
const entityId = makeEntityId(name, type, agentId, scope, scopeRef);
|
|
624
|
+
for (const r of extractorResults) {
|
|
625
|
+
const entityId = makeEntityId(r.name, r.type, agentId, scope, scopeRef);
|
|
650
626
|
if (!seen.has(entityId)) {
|
|
651
627
|
seen.add(entityId);
|
|
652
628
|
extracted.push({
|
|
653
629
|
entityId,
|
|
654
|
-
name,
|
|
655
|
-
type
|
|
630
|
+
name: r.name,
|
|
631
|
+
type: r.type
|
|
656
632
|
});
|
|
657
633
|
}
|
|
658
634
|
}
|
|
659
|
-
for (const match of eventContent.matchAll(MENTION_REGEX)) {
|
|
660
|
-
const name = match[1];
|
|
661
|
-
if (name && !STOP_WORDS.has(name.toLowerCase())) addEntity(name, "person");
|
|
662
|
-
}
|
|
663
|
-
for (const match of eventContent.matchAll(TAG_REGEX)) {
|
|
664
|
-
const name = match[1];
|
|
665
|
-
if (name && !STOP_WORDS.has(name.toLowerCase())) addEntity(name, "topic");
|
|
666
|
-
}
|
|
667
|
-
for (const match of eventContent.matchAll(URL_REGEX)) addEntity(match[0], "document");
|
|
668
|
-
for (const match of eventContent.matchAll(FILE_PATH_REGEX)) {
|
|
669
|
-
const filePath = match[1];
|
|
670
|
-
if (filePath) addEntity(filePath, "document");
|
|
671
|
-
}
|
|
672
|
-
for (const match of eventContent.matchAll(QUOTED_NAME_REGEX)) {
|
|
673
|
-
const name = match[1];
|
|
674
|
-
if (name && name.trim().length >= 3 && !STOP_WORDS.has(name.toLowerCase().trim())) addEntity(name.trim(), "person");
|
|
675
|
-
}
|
|
676
635
|
if (extracted.length === 0) {
|
|
677
636
|
await Promise.allSettled([recordProjectionRun({
|
|
678
637
|
db,
|
|
@@ -701,57 +660,129 @@ async function extractAndUpsertEntities(params) {
|
|
|
701
660
|
};
|
|
702
661
|
}
|
|
703
662
|
try {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
663
|
+
const now = /* @__PURE__ */ new Date();
|
|
664
|
+
const validSourceRole = role === "user" || role === "assistant" ? role : void 0;
|
|
665
|
+
const entityOps = extracted.map((entity) => ({ updateOne: {
|
|
666
|
+
filter: {
|
|
708
667
|
entityId: entity.entityId,
|
|
709
|
-
name: entity.name,
|
|
710
|
-
type: entity.type,
|
|
711
668
|
agentId,
|
|
712
669
|
scope,
|
|
713
|
-
scopeRef
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
const link = inferEntityLinkType(extracted[i], extracted[j]);
|
|
721
|
-
await upsertEntityLink({
|
|
722
|
-
db,
|
|
723
|
-
prefix,
|
|
724
|
-
link: {
|
|
725
|
-
fromEntityId: extracted[i].entityId,
|
|
726
|
-
toEntityId: extracted[j].entityId,
|
|
727
|
-
linkType: link.linkType,
|
|
728
|
-
status: "active",
|
|
729
|
-
confidence: link.confidence,
|
|
730
|
-
provenance: link.provenance,
|
|
670
|
+
scopeRef
|
|
671
|
+
},
|
|
672
|
+
update: {
|
|
673
|
+
$set: {
|
|
674
|
+
entityId: entity.entityId,
|
|
675
|
+
name: entity.name,
|
|
676
|
+
type: entity.type,
|
|
731
677
|
agentId,
|
|
732
678
|
scope,
|
|
733
679
|
scopeRef,
|
|
734
|
-
|
|
680
|
+
updatedAt: now,
|
|
681
|
+
...sourceEventId ? { sourceEventIds: [sourceEventId] } : {},
|
|
682
|
+
...validSourceRole ? { sourceRole: validSourceRole } : {}
|
|
683
|
+
},
|
|
684
|
+
$setOnInsert: {
|
|
685
|
+
createdAt: now,
|
|
686
|
+
extractedAt: now
|
|
735
687
|
}
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
688
|
+
},
|
|
689
|
+
upsert: true
|
|
690
|
+
} }));
|
|
691
|
+
if (entityOps.length > 0) try {
|
|
692
|
+
await entitiesCollection(db, prefix).bulkWrite(entityOps, { ordered: false });
|
|
693
|
+
} catch (bulkErr) {
|
|
694
|
+
log$10.warn("bulkWrite entity upserts partial failure", { error: bulkErr });
|
|
695
|
+
}
|
|
696
|
+
let relationsCreated = 0;
|
|
697
|
+
if (extracted.length >= 2) {
|
|
698
|
+
const relationOps = [];
|
|
699
|
+
const linkOps = [];
|
|
700
|
+
for (let i = 0; i < extracted.length - 1 && i < 5; i++) for (let j = i + 1; j < extracted.length && j < 6; j++) {
|
|
701
|
+
const link = inferEntityLinkType(extracted[i], extracted[j]);
|
|
702
|
+
const pair = canonicalizeEntityPair(extracted[i].entityId, extracted[j].entityId);
|
|
703
|
+
const linkId = makeEntityLinkId({
|
|
704
|
+
...pair,
|
|
705
|
+
linkType: link.linkType,
|
|
745
706
|
agentId,
|
|
746
707
|
scope,
|
|
747
|
-
scopeRef
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
708
|
+
scopeRef
|
|
709
|
+
});
|
|
710
|
+
linkOps.push({ updateOne: {
|
|
711
|
+
filter: {
|
|
712
|
+
agentId,
|
|
713
|
+
scope,
|
|
714
|
+
scopeRef,
|
|
715
|
+
fromEntityId: pair.fromEntityId,
|
|
716
|
+
toEntityId: pair.toEntityId,
|
|
717
|
+
linkType: link.linkType
|
|
718
|
+
},
|
|
719
|
+
update: {
|
|
720
|
+
$set: {
|
|
721
|
+
linkId,
|
|
722
|
+
...pair,
|
|
723
|
+
linkType: link.linkType,
|
|
724
|
+
status: "active",
|
|
725
|
+
confidence: link.confidence,
|
|
726
|
+
agentId,
|
|
727
|
+
scope,
|
|
728
|
+
scopeRef,
|
|
729
|
+
updatedAt: now,
|
|
730
|
+
...link.provenance ? { provenance: link.provenance } : {},
|
|
731
|
+
...sourceEventId ? { sourceEventIds: [sourceEventId] } : {}
|
|
732
|
+
},
|
|
733
|
+
$setOnInsert: { createdAt: now }
|
|
734
|
+
},
|
|
735
|
+
upsert: true
|
|
736
|
+
} });
|
|
737
|
+
relationOps.push({ updateOne: {
|
|
738
|
+
filter: {
|
|
739
|
+
fromEntityId: extracted[i].entityId,
|
|
740
|
+
toEntityId: extracted[j].entityId,
|
|
741
|
+
type: "mentioned_with",
|
|
742
|
+
agentId,
|
|
743
|
+
scope,
|
|
744
|
+
scopeRef
|
|
745
|
+
},
|
|
746
|
+
update: {
|
|
747
|
+
$set: {
|
|
748
|
+
fromEntityId: extracted[i].entityId,
|
|
749
|
+
toEntityId: extracted[j].entityId,
|
|
750
|
+
type: "mentioned_with",
|
|
751
|
+
weight: .2,
|
|
752
|
+
agentId,
|
|
753
|
+
scope,
|
|
754
|
+
scopeRef,
|
|
755
|
+
updatedAt: now,
|
|
756
|
+
...sourceEventId ? { sourceEventIds: [sourceEventId] } : {}
|
|
757
|
+
},
|
|
758
|
+
$setOnInsert: { createdAt: now }
|
|
759
|
+
},
|
|
760
|
+
upsert: true
|
|
761
|
+
} });
|
|
762
|
+
relationsCreated++;
|
|
763
|
+
}
|
|
764
|
+
if (relationOps.length > 0) try {
|
|
765
|
+
await relationsCollection(db, prefix).bulkWrite(relationOps, { ordered: false });
|
|
766
|
+
} catch (bulkErr) {
|
|
767
|
+
log$10.warn("bulkWrite relation upserts partial failure", { error: bulkErr });
|
|
768
|
+
}
|
|
769
|
+
if (linkOps.length > 0) try {
|
|
770
|
+
await entityLinksCollection(db, prefix).bulkWrite(linkOps, { ordered: false });
|
|
771
|
+
} catch (bulkErr) {
|
|
772
|
+
log$10.warn("bulkWrite entity-link upserts partial failure", { error: bulkErr });
|
|
773
|
+
}
|
|
753
774
|
}
|
|
754
|
-
log$
|
|
775
|
+
log$10.info(`extracted ${extracted.length} entities and ${relationsCreated} relations from event content for agent=${agentId}`);
|
|
776
|
+
emitTelemetry(db, prefix, {
|
|
777
|
+
meta: {
|
|
778
|
+
agentId,
|
|
779
|
+
operation: "entity-extraction"
|
|
780
|
+
},
|
|
781
|
+
durationMs: Date.now() - startMs,
|
|
782
|
+
ok: true,
|
|
783
|
+
extractionMethod: extractorResults[0]?.extractionMethod ?? "regex",
|
|
784
|
+
entitiesExtracted: extracted.length
|
|
785
|
+
});
|
|
755
786
|
await Promise.allSettled([recordProjectionRun({
|
|
756
787
|
db,
|
|
757
788
|
prefix,
|
|
@@ -778,6 +809,16 @@ async function extractAndUpsertEntities(params) {
|
|
|
778
809
|
relationsCreated
|
|
779
810
|
};
|
|
780
811
|
} catch (err) {
|
|
812
|
+
emitTelemetry(db, prefix, {
|
|
813
|
+
meta: {
|
|
814
|
+
agentId,
|
|
815
|
+
operation: "entity-extraction"
|
|
816
|
+
},
|
|
817
|
+
durationMs: Date.now() - startMs,
|
|
818
|
+
ok: false,
|
|
819
|
+
extractionMethod: extractor instanceof RegexEntityExtractor ? "regex" : "llm",
|
|
820
|
+
entitiesExtracted: 0
|
|
821
|
+
});
|
|
781
822
|
await Promise.allSettled([recordProjectionRun({
|
|
782
823
|
db,
|
|
783
824
|
prefix,
|
|
@@ -799,13 +840,13 @@ async function extractAndUpsertEntities(params) {
|
|
|
799
840
|
durationMs: Date.now() - startMs
|
|
800
841
|
}
|
|
801
842
|
})]);
|
|
802
|
-
log$
|
|
843
|
+
log$10.error(`extractAndUpsertEntities failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
803
844
|
throw err;
|
|
804
845
|
}
|
|
805
846
|
}
|
|
806
847
|
//#endregion
|
|
807
848
|
//#region src/memory/mongodb-episodes.ts
|
|
808
|
-
const log$
|
|
849
|
+
const log$9 = createSubsystemLogger("memory:mongodb:episodes");
|
|
809
850
|
function buildEpisodeSummarizerInput(events) {
|
|
810
851
|
const conversational = events.filter((event) => {
|
|
811
852
|
return event.body.trim().length > 0 && (event.role === "user" || event.role === "assistant");
|
|
@@ -846,7 +887,7 @@ async function materializeEpisode(params) {
|
|
|
846
887
|
scopeRef
|
|
847
888
|
});
|
|
848
889
|
if (events.length < 2) {
|
|
849
|
-
log$
|
|
890
|
+
log$9.info(`skipping episode materialization: only ${events.length} events in range for agent=${agentId}`);
|
|
850
891
|
await recordProjectionRun({
|
|
851
892
|
db,
|
|
852
893
|
prefix,
|
|
@@ -866,7 +907,7 @@ async function materializeEpisode(params) {
|
|
|
866
907
|
timestamp: e.timestamp
|
|
867
908
|
})));
|
|
868
909
|
if (summarizerInput.length < 2) {
|
|
869
|
-
log$
|
|
910
|
+
log$9.info(`skipping episode materialization: only ${summarizerInput.length} conversational events in range for agent=${agentId}`);
|
|
870
911
|
await recordProjectionRun({
|
|
871
912
|
db,
|
|
872
913
|
prefix,
|
|
@@ -915,7 +956,8 @@ async function materializeEpisode(params) {
|
|
|
915
956
|
$set: setDoc,
|
|
916
957
|
$setOnInsert: {
|
|
917
958
|
episodeId,
|
|
918
|
-
createdAt: now
|
|
959
|
+
createdAt: now,
|
|
960
|
+
status: "active"
|
|
919
961
|
}
|
|
920
962
|
}, { upsert: true });
|
|
921
963
|
let persistedEpisodeId = episodeId;
|
|
@@ -940,7 +982,7 @@ async function materializeEpisode(params) {
|
|
|
940
982
|
updatedAt: now,
|
|
941
983
|
...tags !== void 0 && { tags }
|
|
942
984
|
};
|
|
943
|
-
log$
|
|
985
|
+
log$9.info(`episode materialized: ${episodeId} type=${type} events=${events.length} agent=${agentId}`);
|
|
944
986
|
await recordProjectionRun({
|
|
945
987
|
db,
|
|
946
988
|
prefix,
|
|
@@ -965,7 +1007,7 @@ async function materializeEpisode(params) {
|
|
|
965
1007
|
durationMs: Date.now() - startMs
|
|
966
1008
|
}
|
|
967
1009
|
}).catch(() => {});
|
|
968
|
-
log$
|
|
1010
|
+
log$9.error(`materializeEpisode failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
969
1011
|
throw err;
|
|
970
1012
|
}
|
|
971
1013
|
}
|
|
@@ -976,14 +1018,15 @@ async function getEpisodesByTimeRange(params) {
|
|
|
976
1018
|
const filter = {
|
|
977
1019
|
agentId,
|
|
978
1020
|
"timeRange.start": { $lte: end },
|
|
979
|
-
"timeRange.end": { $gte: start }
|
|
1021
|
+
"timeRange.end": { $gte: start },
|
|
1022
|
+
status: { $ne: "deleted" }
|
|
980
1023
|
};
|
|
981
1024
|
if (type) filter.type = type;
|
|
982
1025
|
if (scope) filter.scope = scope;
|
|
983
1026
|
if (scopeRef) filter.scopeRef = scopeRef;
|
|
984
1027
|
return await col.find(filter).sort({ "timeRange.start": -1 }).limit(100).toArray();
|
|
985
1028
|
} catch (err) {
|
|
986
|
-
log$
|
|
1029
|
+
log$9.error(`getEpisodesByTimeRange failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
987
1030
|
throw err;
|
|
988
1031
|
}
|
|
989
1032
|
}
|
|
@@ -996,6 +1039,7 @@ async function searchEpisodes(params) {
|
|
|
996
1039
|
const regex = new RegExp(escapedQuery, "i");
|
|
997
1040
|
const filter = {
|
|
998
1041
|
agentId,
|
|
1042
|
+
status: { $ne: "deleted" },
|
|
999
1043
|
$or: [{ title: { $regex: regex } }, { summary: { $regex: regex } }]
|
|
1000
1044
|
};
|
|
1001
1045
|
if (scope) filter.scope = scope;
|
|
@@ -1006,7 +1050,7 @@ async function searchEpisodes(params) {
|
|
|
1006
1050
|
}
|
|
1007
1051
|
return await col.find(filter).sort({ updatedAt: -1 }).limit(limit ?? 50).toArray();
|
|
1008
1052
|
} catch (err) {
|
|
1009
|
-
log$
|
|
1053
|
+
log$9.error(`searchEpisodes failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1010
1054
|
throw err;
|
|
1011
1055
|
}
|
|
1012
1056
|
}
|
|
@@ -1095,20 +1139,20 @@ async function checkAutoEpisodeTriggers(params) {
|
|
|
1095
1139
|
eventIds,
|
|
1096
1140
|
episodeId: episode.episodeId
|
|
1097
1141
|
});
|
|
1098
|
-
log$
|
|
1142
|
+
log$9.info(`auto episode triggered: reason=${triggerReason} episode=${episode.episodeId} events=${eventIds.length} agent=${agentId}`);
|
|
1099
1143
|
return {
|
|
1100
1144
|
triggered: true,
|
|
1101
1145
|
reason: triggerReason,
|
|
1102
1146
|
episode
|
|
1103
1147
|
};
|
|
1104
1148
|
} catch (err) {
|
|
1105
|
-
log$
|
|
1149
|
+
log$9.error(`checkAutoEpisodeTriggers failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1106
1150
|
throw err;
|
|
1107
1151
|
}
|
|
1108
1152
|
}
|
|
1109
1153
|
//#endregion
|
|
1110
1154
|
//#region src/memory/mongodb-retrieval-planner.ts
|
|
1111
|
-
const log$
|
|
1155
|
+
const log$8 = createSubsystemLogger("memory:mongodb:planner");
|
|
1112
1156
|
function buildKeywordRegexes(keywords) {
|
|
1113
1157
|
return keywords.map((kw) => new RegExp(`\\b${kw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "i"));
|
|
1114
1158
|
}
|
|
@@ -1498,7 +1542,7 @@ function planRetrieval(query, context) {
|
|
|
1498
1542
|
...Object.keys(constraints).length > 0 ? { constraints } : {}
|
|
1499
1543
|
};
|
|
1500
1544
|
} catch (err) {
|
|
1501
|
-
log$
|
|
1545
|
+
log$8.error("planRetrieval failed", {
|
|
1502
1546
|
query,
|
|
1503
1547
|
error: err
|
|
1504
1548
|
});
|
|
@@ -1507,7 +1551,7 @@ function planRetrieval(query, context) {
|
|
|
1507
1551
|
}
|
|
1508
1552
|
//#endregion
|
|
1509
1553
|
//#region src/memory/mongodb-change-stream.ts
|
|
1510
|
-
const log$
|
|
1554
|
+
const log$7 = createSubsystemLogger("memory:mongodb:changestream");
|
|
1511
1555
|
/**
|
|
1512
1556
|
* MongoDBChangeStreamWatcher watches for changes to the chunks collection
|
|
1513
1557
|
* and invokes a callback when relevant inserts/updates/deletes are detected.
|
|
@@ -1553,19 +1597,19 @@ var MongoDBChangeStreamWatcher = class {
|
|
|
1553
1597
|
this.stream.on("error", (err) => {
|
|
1554
1598
|
const msg = err.message ?? String(err);
|
|
1555
1599
|
if (isChangeStreamNotSupported(msg)) {
|
|
1556
|
-
log$
|
|
1600
|
+
log$7.info("change streams not supported (standalone topology), closing watcher");
|
|
1557
1601
|
this.close();
|
|
1558
|
-
} else log$
|
|
1602
|
+
} else log$7.warn(`change stream error: ${msg}`);
|
|
1559
1603
|
});
|
|
1560
|
-
log$
|
|
1604
|
+
log$7.info("change stream started");
|
|
1561
1605
|
return true;
|
|
1562
1606
|
} catch (err) {
|
|
1563
1607
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1564
1608
|
if (isChangeStreamNotSupported(msg)) {
|
|
1565
|
-
log$
|
|
1609
|
+
log$7.info("change streams not supported (standalone topology)");
|
|
1566
1610
|
return false;
|
|
1567
1611
|
}
|
|
1568
|
-
log$
|
|
1612
|
+
log$7.warn(`failed to start change stream: ${msg}`);
|
|
1569
1613
|
return false;
|
|
1570
1614
|
}
|
|
1571
1615
|
}
|
|
@@ -1602,7 +1646,7 @@ var MongoDBChangeStreamWatcher = class {
|
|
|
1602
1646
|
});
|
|
1603
1647
|
} catch (err) {
|
|
1604
1648
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1605
|
-
log$
|
|
1649
|
+
log$7.warn(`change stream callback error: ${msg}`);
|
|
1606
1650
|
}
|
|
1607
1651
|
}
|
|
1608
1652
|
async close() {
|
|
@@ -1618,7 +1662,7 @@ var MongoDBChangeStreamWatcher = class {
|
|
|
1618
1662
|
} catch {}
|
|
1619
1663
|
this.stream = null;
|
|
1620
1664
|
}
|
|
1621
|
-
log$
|
|
1665
|
+
log$7.info("change stream closed");
|
|
1622
1666
|
}
|
|
1623
1667
|
get isActive() {
|
|
1624
1668
|
return this.stream !== null && !this.closed;
|
|
@@ -1629,7 +1673,7 @@ function isChangeStreamNotSupported(msg) {
|
|
|
1629
1673
|
}
|
|
1630
1674
|
//#endregion
|
|
1631
1675
|
//#region src/memory/mongodb-derived-memory.ts
|
|
1632
|
-
const log$
|
|
1676
|
+
const log$6 = createSubsystemLogger("memory:mongodb:derived");
|
|
1633
1677
|
const STOPWORDS = new Set([
|
|
1634
1678
|
"a",
|
|
1635
1679
|
"an",
|
|
@@ -1894,7 +1938,7 @@ async function promoteDerivedMemoryFromEvent(params) {
|
|
|
1894
1938
|
durationMs: 0
|
|
1895
1939
|
}
|
|
1896
1940
|
}).catch(() => {});
|
|
1897
|
-
log$
|
|
1941
|
+
log$6.warn(`structured promotion failed for ${event.eventId}: ${String(err)}`);
|
|
1898
1942
|
}
|
|
1899
1943
|
try {
|
|
1900
1944
|
for (const candidate of extractProcedureCandidatesFromEvent(event)) if ((await writeProcedure({
|
|
@@ -1927,7 +1971,7 @@ async function promoteDerivedMemoryFromEvent(params) {
|
|
|
1927
1971
|
durationMs: 0
|
|
1928
1972
|
}
|
|
1929
1973
|
}).catch(() => {});
|
|
1930
|
-
log$
|
|
1974
|
+
log$6.warn(`procedure promotion failed for ${event.eventId}: ${String(err)}`);
|
|
1931
1975
|
}
|
|
1932
1976
|
return {
|
|
1933
1977
|
structuredCreated,
|
|
@@ -1935,6 +1979,696 @@ async function promoteDerivedMemoryFromEvent(params) {
|
|
|
1935
1979
|
};
|
|
1936
1980
|
}
|
|
1937
1981
|
//#endregion
|
|
1982
|
+
//#region src/memory/mongodb-profile.ts
|
|
1983
|
+
const log$5 = createSubsystemLogger("memory:mongodb:profile");
|
|
1984
|
+
/**
|
|
1985
|
+
* Synthesize a dynamic agent profile from structured memory, entities,
|
|
1986
|
+
* episodes, and events. Read-only aggregation across 5 collections.
|
|
1987
|
+
*
|
|
1988
|
+
* Uses $facet for structured_mem (single pass), $lookup + $group for
|
|
1989
|
+
* entity relation counts, simple find for episodes, and $group for
|
|
1990
|
+
* event activity patterns.
|
|
1991
|
+
*/
|
|
1992
|
+
async function synthesizeProfile(params) {
|
|
1993
|
+
const profileStart = Date.now();
|
|
1994
|
+
const { db, prefix, agentId, scope, scopeRef, maxPerType = 20, maxEntities = 10, maxEpisodes = 10, activityWindowMs = 720 * 60 * 60 * 1e3 } = params;
|
|
1995
|
+
const scopeFilter = {
|
|
1996
|
+
agentId,
|
|
1997
|
+
scope,
|
|
1998
|
+
scopeRef
|
|
1999
|
+
};
|
|
2000
|
+
async function settled(label, fn) {
|
|
2001
|
+
try {
|
|
2002
|
+
return await fn();
|
|
2003
|
+
} catch (err) {
|
|
2004
|
+
log$5.warn(`synthesizeProfile: ${label} query failed`, { error: err });
|
|
2005
|
+
return null;
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
try {
|
|
2009
|
+
const [structuredResults, entityResults, episodeResults, activityResults] = await Promise.all([
|
|
2010
|
+
settled("structured", () => structuredMemCollection(db, prefix).aggregate([{ $match: {
|
|
2011
|
+
...scopeFilter,
|
|
2012
|
+
state: "active"
|
|
2013
|
+
} }, { $facet: {
|
|
2014
|
+
preferences: [
|
|
2015
|
+
{ $match: { type: "preference" } },
|
|
2016
|
+
{ $sort: { updatedAt: -1 } },
|
|
2017
|
+
{ $limit: maxPerType },
|
|
2018
|
+
{ $project: {
|
|
2019
|
+
key: 1,
|
|
2020
|
+
value: 1,
|
|
2021
|
+
salience: 1,
|
|
2022
|
+
updatedAt: 1
|
|
2023
|
+
} }
|
|
2024
|
+
],
|
|
2025
|
+
decisions: [
|
|
2026
|
+
{ $match: { type: "decision" } },
|
|
2027
|
+
{ $sort: { updatedAt: -1 } },
|
|
2028
|
+
{ $limit: maxPerType },
|
|
2029
|
+
{ $project: {
|
|
2030
|
+
key: 1,
|
|
2031
|
+
value: 1,
|
|
2032
|
+
salience: 1,
|
|
2033
|
+
updatedAt: 1
|
|
2034
|
+
} }
|
|
2035
|
+
],
|
|
2036
|
+
facts: [
|
|
2037
|
+
{ $match: { type: "fact" } },
|
|
2038
|
+
{ $sort: { updatedAt: -1 } },
|
|
2039
|
+
{ $limit: maxPerType },
|
|
2040
|
+
{ $project: {
|
|
2041
|
+
key: 1,
|
|
2042
|
+
value: 1,
|
|
2043
|
+
salience: 1,
|
|
2044
|
+
updatedAt: 1
|
|
2045
|
+
} }
|
|
2046
|
+
],
|
|
2047
|
+
todos: [
|
|
2048
|
+
{ $match: { type: "todo" } },
|
|
2049
|
+
{ $sort: { updatedAt: -1 } },
|
|
2050
|
+
{ $limit: maxPerType },
|
|
2051
|
+
{ $project: {
|
|
2052
|
+
key: 1,
|
|
2053
|
+
value: 1,
|
|
2054
|
+
salience: 1,
|
|
2055
|
+
updatedAt: 1
|
|
2056
|
+
} }
|
|
2057
|
+
]
|
|
2058
|
+
} }]).toArray()),
|
|
2059
|
+
settled("entities", () => entitiesCollection(db, prefix).aggregate([
|
|
2060
|
+
{ $match: scopeFilter },
|
|
2061
|
+
{ $lookup: {
|
|
2062
|
+
from: `${prefix}relations`,
|
|
2063
|
+
let: { eid: "$entityId" },
|
|
2064
|
+
pipeline: [{ $match: {
|
|
2065
|
+
$expr: { $eq: ["$fromEntityId", "$$eid"] },
|
|
2066
|
+
...scopeFilter
|
|
2067
|
+
} }, { $count: "cnt" }],
|
|
2068
|
+
as: "outRels"
|
|
2069
|
+
} },
|
|
2070
|
+
{ $lookup: {
|
|
2071
|
+
from: `${prefix}relations`,
|
|
2072
|
+
let: { eid: "$entityId" },
|
|
2073
|
+
pipeline: [{ $match: {
|
|
2074
|
+
$expr: { $eq: ["$toEntityId", "$$eid"] },
|
|
2075
|
+
...scopeFilter
|
|
2076
|
+
} }, { $count: "cnt" }],
|
|
2077
|
+
as: "inRels"
|
|
2078
|
+
} },
|
|
2079
|
+
{ $addFields: { relationCount: { $add: [{ $ifNull: [{ $arrayElemAt: ["$outRels.cnt", 0] }, 0] }, { $ifNull: [{ $arrayElemAt: ["$inRels.cnt", 0] }, 0] }] } } },
|
|
2080
|
+
{ $sort: { relationCount: -1 } },
|
|
2081
|
+
{ $limit: maxEntities },
|
|
2082
|
+
{ $project: {
|
|
2083
|
+
name: 1,
|
|
2084
|
+
type: 1,
|
|
2085
|
+
relationCount: 1
|
|
2086
|
+
} }
|
|
2087
|
+
]).toArray()),
|
|
2088
|
+
settled("episodes", () => episodesCollection(db, prefix).find(scopeFilter).sort({ "timeRange.start": -1 }).limit(maxEpisodes).project({
|
|
2089
|
+
title: 1,
|
|
2090
|
+
summary: 1,
|
|
2091
|
+
type: 1,
|
|
2092
|
+
timeRange: 1
|
|
2093
|
+
}).toArray()),
|
|
2094
|
+
settled("activity", () => {
|
|
2095
|
+
const activitySince = new Date(Date.now() - activityWindowMs);
|
|
2096
|
+
return eventsCollection(db, prefix).aggregate([{ $match: {
|
|
2097
|
+
...scopeFilter,
|
|
2098
|
+
timestamp: { $gte: activitySince }
|
|
2099
|
+
} }, { $group: {
|
|
2100
|
+
_id: "$role",
|
|
2101
|
+
count: { $sum: 1 },
|
|
2102
|
+
lastTs: { $max: "$timestamp" }
|
|
2103
|
+
} }]).toArray();
|
|
2104
|
+
})
|
|
2105
|
+
]);
|
|
2106
|
+
const structured = structuredResults?.[0] ?? {
|
|
2107
|
+
preferences: [],
|
|
2108
|
+
decisions: [],
|
|
2109
|
+
facts: [],
|
|
2110
|
+
todos: []
|
|
2111
|
+
};
|
|
2112
|
+
const roleDistribution = {};
|
|
2113
|
+
let totalEvents = 0;
|
|
2114
|
+
let lastActive = null;
|
|
2115
|
+
for (const r of activityResults ?? []) {
|
|
2116
|
+
roleDistribution[r._id] = r.count;
|
|
2117
|
+
totalEvents += r.count;
|
|
2118
|
+
const ts = r.lastTs;
|
|
2119
|
+
if (!lastActive || ts > lastActive) lastActive = ts;
|
|
2120
|
+
}
|
|
2121
|
+
const durationMs = Date.now() - profileStart;
|
|
2122
|
+
emitTelemetry(db, prefix, {
|
|
2123
|
+
meta: {
|
|
2124
|
+
agentId,
|
|
2125
|
+
operation: "profile-synthesis"
|
|
2126
|
+
},
|
|
2127
|
+
durationMs,
|
|
2128
|
+
ok: true,
|
|
2129
|
+
resultCount: totalEvents
|
|
2130
|
+
});
|
|
2131
|
+
log$5.info("profile synthesis complete", {
|
|
2132
|
+
agentId,
|
|
2133
|
+
durationMs,
|
|
2134
|
+
totalEvents
|
|
2135
|
+
});
|
|
2136
|
+
return {
|
|
2137
|
+
agentId,
|
|
2138
|
+
scope,
|
|
2139
|
+
scopeRef,
|
|
2140
|
+
preferences: mapMemoryItems(structured.preferences),
|
|
2141
|
+
decisions: mapMemoryItems(structured.decisions),
|
|
2142
|
+
facts: mapMemoryItems(structured.facts),
|
|
2143
|
+
todos: mapMemoryItems(structured.todos),
|
|
2144
|
+
topEntities: (entityResults ?? []).map((e) => ({
|
|
2145
|
+
name: e.name,
|
|
2146
|
+
type: e.type,
|
|
2147
|
+
relationCount: e.relationCount
|
|
2148
|
+
})),
|
|
2149
|
+
recentEpisodes: (episodeResults ?? []).map((e) => ({
|
|
2150
|
+
title: e.title,
|
|
2151
|
+
summary: e.summary,
|
|
2152
|
+
type: e.type,
|
|
2153
|
+
timeRange: e.timeRange
|
|
2154
|
+
})),
|
|
2155
|
+
activityPatterns: {
|
|
2156
|
+
roleDistribution,
|
|
2157
|
+
totalEvents,
|
|
2158
|
+
lastActive
|
|
2159
|
+
},
|
|
2160
|
+
synthesizedAt: /* @__PURE__ */ new Date()
|
|
2161
|
+
};
|
|
2162
|
+
} catch (err) {
|
|
2163
|
+
log$5.error("synthesizeProfile failed", {
|
|
2164
|
+
agentId,
|
|
2165
|
+
error: err
|
|
2166
|
+
});
|
|
2167
|
+
emitTelemetry(db, prefix, {
|
|
2168
|
+
meta: {
|
|
2169
|
+
agentId,
|
|
2170
|
+
operation: "profile-synthesis"
|
|
2171
|
+
},
|
|
2172
|
+
durationMs: Date.now() - profileStart,
|
|
2173
|
+
ok: false
|
|
2174
|
+
});
|
|
2175
|
+
throw err;
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
function mapMemoryItems(items) {
|
|
2179
|
+
return items.map((i) => ({
|
|
2180
|
+
key: i.key,
|
|
2181
|
+
value: i.value,
|
|
2182
|
+
salience: i.salience ?? "normal",
|
|
2183
|
+
updatedAt: i.updatedAt
|
|
2184
|
+
}));
|
|
2185
|
+
}
|
|
2186
|
+
//#endregion
|
|
2187
|
+
//#region src/memory/mongodb-query-cache.ts
|
|
2188
|
+
const log$4 = createSubsystemLogger("memory:mongodb:query-cache");
|
|
2189
|
+
/** Normalize query for consistent hashing: lowercase, collapse whitespace, trim. */
|
|
2190
|
+
function normalizeQuery(query) {
|
|
2191
|
+
return query.toLowerCase().replace(/\s+/g, " ").trim();
|
|
2192
|
+
}
|
|
2193
|
+
/** SHA-256 hash of normalized query string. */
|
|
2194
|
+
function hashQuery(normalizedQuery) {
|
|
2195
|
+
return createHash("sha256").update(normalizedQuery).digest("hex");
|
|
2196
|
+
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Two-tier cache check:
|
|
2199
|
+
* Tier 1: Exact SHA-256 hash match via findOne on unique index.
|
|
2200
|
+
* Tier 2: $vectorSearch with autoEmbed on queryNorm field, cosine >= threshold.
|
|
2201
|
+
*
|
|
2202
|
+
* On hit: increments hitCount and updates lastHitAt (fire-and-forget).
|
|
2203
|
+
*/
|
|
2204
|
+
async function checkCache(params) {
|
|
2205
|
+
const { db, prefix, query, agentId, scope, scopeRef, config } = params;
|
|
2206
|
+
if (!config.enabled) return {
|
|
2207
|
+
hit: false,
|
|
2208
|
+
tier: "miss",
|
|
2209
|
+
results: []
|
|
2210
|
+
};
|
|
2211
|
+
const normalized = normalizeQuery(query);
|
|
2212
|
+
if (!normalized) return {
|
|
2213
|
+
hit: false,
|
|
2214
|
+
tier: "miss",
|
|
2215
|
+
results: []
|
|
2216
|
+
};
|
|
2217
|
+
const cacheStart = Date.now();
|
|
2218
|
+
const col = queryCacheCollection(db, prefix);
|
|
2219
|
+
const qHash = hashQuery(normalized);
|
|
2220
|
+
const now = /* @__PURE__ */ new Date();
|
|
2221
|
+
try {
|
|
2222
|
+
const exact = await col.findOne({
|
|
2223
|
+
queryHash: qHash,
|
|
2224
|
+
agentId,
|
|
2225
|
+
scope,
|
|
2226
|
+
scopeRef,
|
|
2227
|
+
expiresAt: { $gt: now }
|
|
2228
|
+
});
|
|
2229
|
+
if (exact) {
|
|
2230
|
+
col.findOneAndUpdate({ _id: exact._id }, {
|
|
2231
|
+
$inc: { hitCount: 1 },
|
|
2232
|
+
$set: { lastHitAt: now }
|
|
2233
|
+
}).catch((err) => {
|
|
2234
|
+
log$4.warn("cache hit count update failed", { error: err });
|
|
2235
|
+
});
|
|
2236
|
+
emitTelemetry(db, prefix, {
|
|
2237
|
+
meta: {
|
|
2238
|
+
agentId,
|
|
2239
|
+
operation: "cache-check"
|
|
2240
|
+
},
|
|
2241
|
+
durationMs: Date.now() - cacheStart,
|
|
2242
|
+
ok: true,
|
|
2243
|
+
cacheHit: true
|
|
2244
|
+
});
|
|
2245
|
+
return {
|
|
2246
|
+
hit: true,
|
|
2247
|
+
tier: "exact",
|
|
2248
|
+
results: exact.results,
|
|
2249
|
+
pathUsed: exact.pathUsed,
|
|
2250
|
+
sourceScope: exact.sourceScope
|
|
2251
|
+
};
|
|
2252
|
+
}
|
|
2253
|
+
} catch (err) {
|
|
2254
|
+
log$4.warn("cache exact lookup failed", { error: err });
|
|
2255
|
+
emitTelemetry(db, prefix, {
|
|
2256
|
+
meta: {
|
|
2257
|
+
agentId,
|
|
2258
|
+
operation: "cache-check"
|
|
2259
|
+
},
|
|
2260
|
+
durationMs: Date.now() - cacheStart,
|
|
2261
|
+
ok: false,
|
|
2262
|
+
cacheHit: false
|
|
2263
|
+
});
|
|
2264
|
+
return {
|
|
2265
|
+
hit: false,
|
|
2266
|
+
tier: "miss",
|
|
2267
|
+
results: []
|
|
2268
|
+
};
|
|
2269
|
+
}
|
|
2270
|
+
try {
|
|
2271
|
+
const vsStage = buildVectorSearchStage({
|
|
2272
|
+
queryVector: null,
|
|
2273
|
+
queryText: normalized,
|
|
2274
|
+
embeddingMode: "automated",
|
|
2275
|
+
indexName: params.vectorIndexName ?? `${prefix}query_cache_vector`,
|
|
2276
|
+
numCandidates: 20,
|
|
2277
|
+
limit: 1,
|
|
2278
|
+
filter: {
|
|
2279
|
+
agentId,
|
|
2280
|
+
scope,
|
|
2281
|
+
scopeRef
|
|
2282
|
+
},
|
|
2283
|
+
textFieldPath: "queryNorm"
|
|
2284
|
+
});
|
|
2285
|
+
if (!vsStage) {
|
|
2286
|
+
emitTelemetry(db, prefix, {
|
|
2287
|
+
meta: {
|
|
2288
|
+
agentId,
|
|
2289
|
+
operation: "cache-check"
|
|
2290
|
+
},
|
|
2291
|
+
durationMs: Date.now() - cacheStart,
|
|
2292
|
+
ok: true,
|
|
2293
|
+
cacheHit: false
|
|
2294
|
+
});
|
|
2295
|
+
return {
|
|
2296
|
+
hit: false,
|
|
2297
|
+
tier: "miss",
|
|
2298
|
+
results: []
|
|
2299
|
+
};
|
|
2300
|
+
}
|
|
2301
|
+
const pipeline = [
|
|
2302
|
+
{ $vectorSearch: vsStage },
|
|
2303
|
+
{ $limit: 1 },
|
|
2304
|
+
{ $project: {
|
|
2305
|
+
_id: 1,
|
|
2306
|
+
results: 1,
|
|
2307
|
+
pathUsed: 1,
|
|
2308
|
+
sourceScope: 1,
|
|
2309
|
+
expiresAt: 1,
|
|
2310
|
+
score: { $meta: "vectorSearchScore" }
|
|
2311
|
+
} }
|
|
2312
|
+
];
|
|
2313
|
+
const candidates = await col.aggregate(pipeline).toArray();
|
|
2314
|
+
if (candidates.length > 0 && candidates[0].score >= config.similarityThreshold && candidates[0].expiresAt > now) {
|
|
2315
|
+
const match = candidates[0];
|
|
2316
|
+
col.findOneAndUpdate({ _id: match._id }, {
|
|
2317
|
+
$inc: { hitCount: 1 },
|
|
2318
|
+
$set: { lastHitAt: now }
|
|
2319
|
+
}).catch((err) => {
|
|
2320
|
+
log$4.warn("cache hit count update failed (semantic)", { error: err });
|
|
2321
|
+
});
|
|
2322
|
+
emitTelemetry(db, prefix, {
|
|
2323
|
+
meta: {
|
|
2324
|
+
agentId,
|
|
2325
|
+
operation: "cache-check"
|
|
2326
|
+
},
|
|
2327
|
+
durationMs: Date.now() - cacheStart,
|
|
2328
|
+
ok: true,
|
|
2329
|
+
cacheHit: true
|
|
2330
|
+
});
|
|
2331
|
+
return {
|
|
2332
|
+
hit: true,
|
|
2333
|
+
tier: "semantic",
|
|
2334
|
+
results: match.results,
|
|
2335
|
+
pathUsed: match.pathUsed,
|
|
2336
|
+
sourceScope: match.sourceScope
|
|
2337
|
+
};
|
|
2338
|
+
}
|
|
2339
|
+
} catch (err) {
|
|
2340
|
+
log$4.warn("cache semantic lookup failed", { error: err });
|
|
2341
|
+
}
|
|
2342
|
+
emitTelemetry(db, prefix, {
|
|
2343
|
+
meta: {
|
|
2344
|
+
agentId,
|
|
2345
|
+
operation: "cache-check"
|
|
2346
|
+
},
|
|
2347
|
+
durationMs: Date.now() - cacheStart,
|
|
2348
|
+
ok: true,
|
|
2349
|
+
cacheHit: false
|
|
2350
|
+
});
|
|
2351
|
+
return {
|
|
2352
|
+
hit: false,
|
|
2353
|
+
tier: "miss",
|
|
2354
|
+
results: []
|
|
2355
|
+
};
|
|
2356
|
+
}
|
|
2357
|
+
/**
|
|
2358
|
+
* Write search results to cache. Fire-and-forget: does not block caller.
|
|
2359
|
+
* Uses upsert to handle race conditions (two identical queries completing simultaneously).
|
|
2360
|
+
*/
|
|
2361
|
+
function writeCache(params) {
|
|
2362
|
+
const { db, prefix, query, agentId, scope, scopeRef, results, pathUsed, sourceScope, ttlSec } = params;
|
|
2363
|
+
const normalized = normalizeQuery(query);
|
|
2364
|
+
if (!normalized || results.length === 0) return;
|
|
2365
|
+
const now = /* @__PURE__ */ new Date();
|
|
2366
|
+
const expiresAt = new Date(now.getTime() + ttlSec * 1e3);
|
|
2367
|
+
const qHash = hashQuery(normalized);
|
|
2368
|
+
queryCacheCollection(db, prefix).updateOne({
|
|
2369
|
+
queryHash: qHash,
|
|
2370
|
+
agentId,
|
|
2371
|
+
scope,
|
|
2372
|
+
scopeRef
|
|
2373
|
+
}, {
|
|
2374
|
+
$setOnInsert: {
|
|
2375
|
+
queryNorm: normalized,
|
|
2376
|
+
createdAt: now,
|
|
2377
|
+
hitCount: 0
|
|
2378
|
+
},
|
|
2379
|
+
$set: {
|
|
2380
|
+
results,
|
|
2381
|
+
pathUsed,
|
|
2382
|
+
sourceScope,
|
|
2383
|
+
expiresAt,
|
|
2384
|
+
lastHitAt: now
|
|
2385
|
+
}
|
|
2386
|
+
}, { upsert: true }).catch((err) => {
|
|
2387
|
+
log$4.warn("cache write failed", { error: err });
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2390
|
+
//#endregion
|
|
2391
|
+
//#region src/memory/mongodb-query-rewriter.ts
|
|
2392
|
+
/**
|
|
2393
|
+
* Domain-specific synonym map for agent memory queries.
|
|
2394
|
+
* Bidirectional: each key expands to its values.
|
|
2395
|
+
*/
|
|
2396
|
+
const SYNONYM_MAP = {
|
|
2397
|
+
auth: [
|
|
2398
|
+
"authentication",
|
|
2399
|
+
"login",
|
|
2400
|
+
"oauth"
|
|
2401
|
+
],
|
|
2402
|
+
db: [
|
|
2403
|
+
"database",
|
|
2404
|
+
"mongodb",
|
|
2405
|
+
"collection"
|
|
2406
|
+
],
|
|
2407
|
+
bug: [
|
|
2408
|
+
"issue",
|
|
2409
|
+
"error",
|
|
2410
|
+
"defect"
|
|
2411
|
+
],
|
|
2412
|
+
perf: [
|
|
2413
|
+
"performance",
|
|
2414
|
+
"latency",
|
|
2415
|
+
"speed"
|
|
2416
|
+
],
|
|
2417
|
+
config: [
|
|
2418
|
+
"configuration",
|
|
2419
|
+
"settings",
|
|
2420
|
+
"options"
|
|
2421
|
+
],
|
|
2422
|
+
deps: [
|
|
2423
|
+
"dependencies",
|
|
2424
|
+
"packages",
|
|
2425
|
+
"modules"
|
|
2426
|
+
],
|
|
2427
|
+
deploy: [
|
|
2428
|
+
"deployment",
|
|
2429
|
+
"release",
|
|
2430
|
+
"publish"
|
|
2431
|
+
],
|
|
2432
|
+
docs: [
|
|
2433
|
+
"documentation",
|
|
2434
|
+
"readme",
|
|
2435
|
+
"guide"
|
|
2436
|
+
],
|
|
2437
|
+
test: [
|
|
2438
|
+
"testing",
|
|
2439
|
+
"tests",
|
|
2440
|
+
"spec"
|
|
2441
|
+
],
|
|
2442
|
+
refactor: [
|
|
2443
|
+
"restructure",
|
|
2444
|
+
"reorganize",
|
|
2445
|
+
"cleanup"
|
|
2446
|
+
]
|
|
2447
|
+
};
|
|
2448
|
+
/** Abbreviation expansions (unidirectional: abbreviation -> full form) */
|
|
2449
|
+
const ABBREVIATION_MAP = {
|
|
2450
|
+
ts: "typescript",
|
|
2451
|
+
js: "javascript",
|
|
2452
|
+
py: "python",
|
|
2453
|
+
env: "environment",
|
|
2454
|
+
var: "variable",
|
|
2455
|
+
fn: "function",
|
|
2456
|
+
cb: "callback",
|
|
2457
|
+
req: "request",
|
|
2458
|
+
res: "response",
|
|
2459
|
+
err: "error",
|
|
2460
|
+
msg: "message",
|
|
2461
|
+
ctx: "context",
|
|
2462
|
+
impl: "implementation",
|
|
2463
|
+
repo: "repository"
|
|
2464
|
+
};
|
|
2465
|
+
/**
|
|
2466
|
+
* Deterministic synonym expansion.
|
|
2467
|
+
* For each word in the query:
|
|
2468
|
+
* 1. Check if it is an abbreviation -- add full form
|
|
2469
|
+
* 2. Check if it matches a synonym group -- add all synonyms
|
|
2470
|
+
* Original words are always preserved.
|
|
2471
|
+
*/
|
|
2472
|
+
function expandSynonyms(query) {
|
|
2473
|
+
const words = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
2474
|
+
const expanded = new Set(words);
|
|
2475
|
+
const maxTotal = words.length * 3;
|
|
2476
|
+
for (const word of words) {
|
|
2477
|
+
const abbr = ABBREVIATION_MAP[word];
|
|
2478
|
+
if (abbr && expanded.size < maxTotal) expanded.add(abbr);
|
|
2479
|
+
const syns = SYNONYM_MAP[word];
|
|
2480
|
+
if (syns) for (const syn of syns) {
|
|
2481
|
+
if (expanded.size >= maxTotal) break;
|
|
2482
|
+
expanded.add(syn);
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
return [...expanded].join(" ");
|
|
2486
|
+
}
|
|
2487
|
+
/**
|
|
2488
|
+
* Rewrite a query for improved vector search recall.
|
|
2489
|
+
*
|
|
2490
|
+
* CRITICAL: The retrieval planner must ALWAYS see the ORIGINAL query.
|
|
2491
|
+
* This function is called AFTER planRetrieval() and BEFORE search execution.
|
|
2492
|
+
* The cache key must also use the ORIGINAL query.
|
|
2493
|
+
*
|
|
2494
|
+
* Tier 1 (synonym-expansion): Deterministic, zero latency.
|
|
2495
|
+
* - Expand known abbreviations
|
|
2496
|
+
* - Add synonyms for recognized terms
|
|
2497
|
+
* - Preserve original terms (expansion, not replacement)
|
|
2498
|
+
*/
|
|
2499
|
+
async function rewriteQuery(params) {
|
|
2500
|
+
const { db, prefix, agentId, query, config } = params;
|
|
2501
|
+
const rewriteStart = Date.now();
|
|
2502
|
+
if (!config.enabled || !query.trim()) return {
|
|
2503
|
+
originalQuery: query,
|
|
2504
|
+
rewrittenQuery: query,
|
|
2505
|
+
rewritten: false,
|
|
2506
|
+
method: "none"
|
|
2507
|
+
};
|
|
2508
|
+
let rewritten;
|
|
2509
|
+
let method;
|
|
2510
|
+
switch (config.method) {
|
|
2511
|
+
case "synonym-expansion":
|
|
2512
|
+
rewritten = expandSynonyms(query);
|
|
2513
|
+
method = "synonym-expansion";
|
|
2514
|
+
break;
|
|
2515
|
+
case "llm":
|
|
2516
|
+
case "hyde": throw new Error(`Query rewrite method "${config.method}" is not yet implemented. Use "synonym-expansion" or disable query rewriting (queryRewriting.enabled: false).`);
|
|
2517
|
+
default:
|
|
2518
|
+
rewritten = query;
|
|
2519
|
+
method = "none";
|
|
2520
|
+
}
|
|
2521
|
+
const wasRewritten = rewritten !== query;
|
|
2522
|
+
if (wasRewritten) {
|
|
2523
|
+
const maxChars = config.maxTokens * 4;
|
|
2524
|
+
if (rewritten.length > maxChars) rewritten = rewritten.slice(0, maxChars).trimEnd();
|
|
2525
|
+
}
|
|
2526
|
+
emitTelemetry(db, prefix, {
|
|
2527
|
+
meta: {
|
|
2528
|
+
agentId,
|
|
2529
|
+
operation: "query-rewrite"
|
|
2530
|
+
},
|
|
2531
|
+
durationMs: Date.now() - rewriteStart,
|
|
2532
|
+
ok: true,
|
|
2533
|
+
queryRewritten: wasRewritten,
|
|
2534
|
+
rewriteMethod: method
|
|
2535
|
+
});
|
|
2536
|
+
return {
|
|
2537
|
+
originalQuery: query,
|
|
2538
|
+
rewrittenQuery: rewritten,
|
|
2539
|
+
rewritten: wasRewritten,
|
|
2540
|
+
method
|
|
2541
|
+
};
|
|
2542
|
+
}
|
|
2543
|
+
//#endregion
|
|
2544
|
+
//#region src/memory/mongodb-reranker.ts
|
|
2545
|
+
const log$3 = createSubsystemLogger("memory:mongodb:reranker");
|
|
2546
|
+
const VOYAGE_RERANK_URL_ATLAS = "https://ai.mongodb.com/v1/rerank";
|
|
2547
|
+
const VOYAGE_RERANK_URL_DIRECT = "https://api.voyageai.com/v1/rerank";
|
|
2548
|
+
function resolveRerankUrl(apiKey) {
|
|
2549
|
+
return apiKey.startsWith("al-") ? VOYAGE_RERANK_URL_ATLAS : VOYAGE_RERANK_URL_DIRECT;
|
|
2550
|
+
}
|
|
2551
|
+
/**
|
|
2552
|
+
* Cross-encoder re-ranking of search results using Voyage rerank-2.5 API.
|
|
2553
|
+
*
|
|
2554
|
+
* On ANY error (network, API, JSON parse, unexpected shape): falls back to
|
|
2555
|
+
* input order unchanged, logs a warning, and never crashes the search pipeline.
|
|
2556
|
+
*
|
|
2557
|
+
* Uses `r.snippet` for document text (MemorySearchResult has no `text` field).
|
|
2558
|
+
*/
|
|
2559
|
+
async function crossEncoderRerank(params) {
|
|
2560
|
+
const { db, prefix, agentId, query, results, config } = params;
|
|
2561
|
+
const rerankStart = Date.now();
|
|
2562
|
+
if (!config.enabled || results.length === 0 || !config.voyageApiKey) return {
|
|
2563
|
+
results,
|
|
2564
|
+
reranked: false,
|
|
2565
|
+
latencyMs: 0
|
|
2566
|
+
};
|
|
2567
|
+
const aboveMinScore = results.filter((r) => r.score >= config.minScore);
|
|
2568
|
+
const candidates = aboveMinScore.slice(0, config.topN);
|
|
2569
|
+
const overflow = aboveMinScore.slice(config.topN);
|
|
2570
|
+
const below = results.filter((r) => r.score < config.minScore);
|
|
2571
|
+
if (candidates.length <= 1) return {
|
|
2572
|
+
results,
|
|
2573
|
+
reranked: false,
|
|
2574
|
+
latencyMs: 0
|
|
2575
|
+
};
|
|
2576
|
+
try {
|
|
2577
|
+
const validCandidates = candidates.filter((r) => r.snippet.trim().length > 0);
|
|
2578
|
+
const emptySnippetCandidates = candidates.filter((r) => r.snippet.trim().length === 0);
|
|
2579
|
+
if (validCandidates.length <= 1) return {
|
|
2580
|
+
results,
|
|
2581
|
+
reranked: false,
|
|
2582
|
+
latencyMs: 0
|
|
2583
|
+
};
|
|
2584
|
+
const documents = validCandidates.map((r) => r.snippet);
|
|
2585
|
+
const rerankUrl = resolveRerankUrl(config.voyageApiKey);
|
|
2586
|
+
const response = await fetch(rerankUrl, {
|
|
2587
|
+
method: "POST",
|
|
2588
|
+
headers: {
|
|
2589
|
+
"Content-Type": "application/json",
|
|
2590
|
+
Authorization: `Bearer ${config.voyageApiKey}`
|
|
2591
|
+
},
|
|
2592
|
+
body: JSON.stringify({
|
|
2593
|
+
model: config.model,
|
|
2594
|
+
query: config.instruction ? `${config.instruction}\n${query}` : query,
|
|
2595
|
+
documents,
|
|
2596
|
+
top_k: validCandidates.length
|
|
2597
|
+
}),
|
|
2598
|
+
signal: AbortSignal.timeout(2e3)
|
|
2599
|
+
});
|
|
2600
|
+
if (!response.ok) {
|
|
2601
|
+
log$3.warn("rerank API returned non-OK status", { status: response.status });
|
|
2602
|
+
return {
|
|
2603
|
+
results,
|
|
2604
|
+
reranked: false,
|
|
2605
|
+
latencyMs: Date.now() - rerankStart
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2608
|
+
const body = await response.json();
|
|
2609
|
+
if (!body.data || !Array.isArray(body.data)) {
|
|
2610
|
+
log$3.warn("rerank API returned unexpected response shape");
|
|
2611
|
+
return {
|
|
2612
|
+
results,
|
|
2613
|
+
reranked: false,
|
|
2614
|
+
latencyMs: Date.now() - rerankStart
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
const reranked = body.data.filter((r) => {
|
|
2618
|
+
if (typeof r.index !== "number" || r.index < 0 || r.index >= validCandidates.length) {
|
|
2619
|
+
log$3.warn("rerank API returned out-of-bounds index", {
|
|
2620
|
+
index: r.index,
|
|
2621
|
+
max: validCandidates.length - 1
|
|
2622
|
+
});
|
|
2623
|
+
return false;
|
|
2624
|
+
}
|
|
2625
|
+
return true;
|
|
2626
|
+
}).toSorted((a, b) => b.relevance_score - a.relevance_score).map((r) => ({
|
|
2627
|
+
...validCandidates[r.index],
|
|
2628
|
+
score: Math.min(1, Math.max(0, r.relevance_score))
|
|
2629
|
+
}));
|
|
2630
|
+
const latencyMs = Date.now() - rerankStart;
|
|
2631
|
+
emitTelemetry(db, prefix, {
|
|
2632
|
+
meta: {
|
|
2633
|
+
agentId,
|
|
2634
|
+
operation: "rerank"
|
|
2635
|
+
},
|
|
2636
|
+
durationMs: latencyMs,
|
|
2637
|
+
ok: true,
|
|
2638
|
+
resultCount: reranked.length,
|
|
2639
|
+
rerankModel: config.model,
|
|
2640
|
+
rerankLatencyMs: latencyMs
|
|
2641
|
+
});
|
|
2642
|
+
return {
|
|
2643
|
+
results: [
|
|
2644
|
+
...reranked,
|
|
2645
|
+
...emptySnippetCandidates,
|
|
2646
|
+
...overflow,
|
|
2647
|
+
...below
|
|
2648
|
+
],
|
|
2649
|
+
reranked: true,
|
|
2650
|
+
latencyMs
|
|
2651
|
+
};
|
|
2652
|
+
} catch (err) {
|
|
2653
|
+
log$3.warn("rerank failed, falling back to input order", { error: err });
|
|
2654
|
+
emitTelemetry(db, prefix, {
|
|
2655
|
+
meta: {
|
|
2656
|
+
agentId,
|
|
2657
|
+
operation: "rerank"
|
|
2658
|
+
},
|
|
2659
|
+
durationMs: Date.now() - rerankStart,
|
|
2660
|
+
ok: false,
|
|
2661
|
+
rerankModel: config.model,
|
|
2662
|
+
rerankLatencyMs: Date.now() - rerankStart
|
|
2663
|
+
});
|
|
2664
|
+
return {
|
|
2665
|
+
results,
|
|
2666
|
+
reranked: false,
|
|
2667
|
+
latencyMs: Date.now() - rerankStart
|
|
2668
|
+
};
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
//#endregion
|
|
1938
2672
|
//#region src/memory/session-files.ts
|
|
1939
2673
|
const log$2 = createSubsystemLogger("memory");
|
|
1940
2674
|
async function listSessionFilesForAgent(agentId) {
|
|
@@ -2685,7 +3419,8 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
2685
3419
|
buildConversationChunkFilter() {
|
|
2686
3420
|
return {
|
|
2687
3421
|
source: { $in: ["conversation", "sessions"] },
|
|
2688
|
-
agentId: this.agentId
|
|
3422
|
+
agentId: this.agentId,
|
|
3423
|
+
status: { $ne: "deleted" }
|
|
2689
3424
|
};
|
|
2690
3425
|
}
|
|
2691
3426
|
buildBridgeChunkFilter() {
|
|
@@ -2693,7 +3428,8 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
2693
3428
|
source: { $in: ["conversation", "memory"] },
|
|
2694
3429
|
agentId: this.agentId,
|
|
2695
3430
|
scope: "workspace",
|
|
2696
|
-
scopeRef: this.workspaceScopeRef
|
|
3431
|
+
scopeRef: this.workspaceScopeRef,
|
|
3432
|
+
status: { $ne: "deleted" }
|
|
2697
3433
|
};
|
|
2698
3434
|
}
|
|
2699
3435
|
getBridgeChunkBudget(maxResults) {
|
|
@@ -2868,6 +3604,25 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
2868
3604
|
const minScore = opts?.minScore ?? .1;
|
|
2869
3605
|
const activeSources = getActiveSources(mongoCfg.sources, mongoCfg.kb.enabled);
|
|
2870
3606
|
const availablePaths = this.buildV2AvailablePaths(activeSources);
|
|
3607
|
+
if (mongoCfg.cache.enabled) {
|
|
3608
|
+
const cacheResult = await checkCache({
|
|
3609
|
+
db: this.db,
|
|
3610
|
+
prefix: this.prefix,
|
|
3611
|
+
query: cleaned,
|
|
3612
|
+
agentId: this.agentId,
|
|
3613
|
+
scope: "agent",
|
|
3614
|
+
scopeRef: this.agentScopeRef,
|
|
3615
|
+
config: mongoCfg.cache
|
|
3616
|
+
});
|
|
3617
|
+
if (cacheResult.hit) {
|
|
3618
|
+
this.setLastSearchMode(`v2:cache:${cacheResult.tier}`, {
|
|
3619
|
+
pathUsed: cacheResult.pathUsed,
|
|
3620
|
+
sourceScope: cacheResult.sourceScope
|
|
3621
|
+
});
|
|
3622
|
+
return cacheResult.results;
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
const searchStart = Date.now();
|
|
2871
3626
|
try {
|
|
2872
3627
|
const v2 = await searchV2(this.db, this.prefix, cleaned, this.agentId, {
|
|
2873
3628
|
availablePaths,
|
|
@@ -2885,9 +3640,23 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
2885
3640
|
bridgeFilter: activeSources.conversation ? this.buildBridgeChunkFilter() : void 0,
|
|
2886
3641
|
bridgeMaxResults: this.getBridgeChunkBudget(maxResults),
|
|
2887
3642
|
scope: "agent",
|
|
2888
|
-
scopeRef: this.agentScopeRef
|
|
3643
|
+
scopeRef: this.agentScopeRef,
|
|
3644
|
+
rerankConfig: mongoCfg.reranking,
|
|
3645
|
+
queryRewriteConfig: mongoCfg.queryRewriting
|
|
2889
3646
|
}
|
|
2890
3647
|
});
|
|
3648
|
+
emitTelemetry(this.db, this.prefix, {
|
|
3649
|
+
meta: {
|
|
3650
|
+
agentId: this.agentId,
|
|
3651
|
+
operation: "search"
|
|
3652
|
+
},
|
|
3653
|
+
durationMs: Date.now() - searchStart,
|
|
3654
|
+
ok: v2.results.length > 0,
|
|
3655
|
+
pathUsed: v2.metadata.pathsExecuted.join(","),
|
|
3656
|
+
resultCount: v2.results.length,
|
|
3657
|
+
topScore: v2.results[0]?.score ?? 0,
|
|
3658
|
+
fusionMethod: mongoCfg.fusionMethod
|
|
3659
|
+
});
|
|
2891
3660
|
const v2Details = {
|
|
2892
3661
|
plan: v2.metadata.plan.paths,
|
|
2893
3662
|
confidence: v2.metadata.plan.confidence,
|
|
@@ -2897,6 +3666,21 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
2897
3666
|
};
|
|
2898
3667
|
if (v2.results.length > 0) {
|
|
2899
3668
|
this.setLastSearchMode("v2", v2Details);
|
|
3669
|
+
if (mongoCfg.cache.enabled) {
|
|
3670
|
+
const ttlSec = v2.metadata.pathsExecuted.includes("kb") ? mongoCfg.cache.kbTtlSec : mongoCfg.cache.conversationTtlSec;
|
|
3671
|
+
writeCache({
|
|
3672
|
+
db: this.db,
|
|
3673
|
+
prefix: this.prefix,
|
|
3674
|
+
query: cleaned,
|
|
3675
|
+
agentId: this.agentId,
|
|
3676
|
+
scope: "agent",
|
|
3677
|
+
scopeRef: this.agentScopeRef,
|
|
3678
|
+
results: v2.results,
|
|
3679
|
+
pathUsed: v2.metadata.pathsExecuted.join(","),
|
|
3680
|
+
sourceScope: "conversation",
|
|
3681
|
+
ttlSec
|
|
3682
|
+
});
|
|
3683
|
+
}
|
|
2900
3684
|
return v2.results;
|
|
2901
3685
|
}
|
|
2902
3686
|
const fallbackResults = await this.legacySearch(cleaned, opts);
|
|
@@ -3557,7 +4341,8 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
3557
4341
|
const { rawPath, episodeId, expandEvents } = params;
|
|
3558
4342
|
const episode = await episodesCollection(this.db, this.prefix).findOne({
|
|
3559
4343
|
agentId: this.agentId,
|
|
3560
|
-
episodeId
|
|
4344
|
+
episodeId,
|
|
4345
|
+
status: { $ne: "deleted" }
|
|
3561
4346
|
});
|
|
3562
4347
|
if (!episode) return {
|
|
3563
4348
|
text: "",
|
|
@@ -3693,7 +4478,7 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
3693
4478
|
if (hoursSinceRefresh < autoRefreshHours) return;
|
|
3694
4479
|
log.info(`KB auto-refresh: ${hoursSinceRefresh.toFixed(1)}h since last import, refreshing ${paths.length} paths`);
|
|
3695
4480
|
try {
|
|
3696
|
-
const { ingestFilesToKB } = await import("./mongodb-kb-
|
|
4481
|
+
const { ingestFilesToKB } = await import("./mongodb-kb-1tSOXXb9.js");
|
|
3697
4482
|
const result = await ingestFilesToKB({
|
|
3698
4483
|
db: this.db,
|
|
3699
4484
|
prefix: this.prefix,
|
|
@@ -3713,12 +4498,7 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
3713
4498
|
ensureWatcher() {
|
|
3714
4499
|
if (this.watcher) return;
|
|
3715
4500
|
const debounceMs = this.config.mongodb.watchDebounceMs;
|
|
3716
|
-
const watchPaths = new Set([
|
|
3717
|
-
path.join(this.workspaceDir, "MEMORY.md"),
|
|
3718
|
-
path.join(this.workspaceDir, "memory.md"),
|
|
3719
|
-
path.join(this.workspaceDir, "memory"),
|
|
3720
|
-
...this.extraMemoryPaths
|
|
3721
|
-
]);
|
|
4501
|
+
const watchPaths = new Set([path.join(this.workspaceDir, "memory"), ...this.extraMemoryPaths]);
|
|
3722
4502
|
this.watcher = chokidar.watch(Array.from(watchPaths), {
|
|
3723
4503
|
ignoreInitial: true,
|
|
3724
4504
|
awaitWriteFinish: {
|
|
@@ -3773,7 +4553,7 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
3773
4553
|
}
|
|
3774
4554
|
async writeStructuredMemory(entry) {
|
|
3775
4555
|
const mongoCfg = this.config.mongodb;
|
|
3776
|
-
const { writeStructuredMemory: writeFn } = await import("./mongodb-structured-memory-
|
|
4556
|
+
const { writeStructuredMemory: writeFn } = await import("./mongodb-structured-memory-lpyyW0kn.js");
|
|
3777
4557
|
return writeFn({
|
|
3778
4558
|
db: this.db,
|
|
3779
4559
|
prefix: this.prefix,
|
|
@@ -3787,7 +4567,7 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
3787
4567
|
}
|
|
3788
4568
|
async writeProcedure(entry) {
|
|
3789
4569
|
const mongoCfg = this.config.mongodb;
|
|
3790
|
-
const { writeProcedure: writeFn } = await import("./mongodb-procedures-
|
|
4570
|
+
const { writeProcedure: writeFn } = await import("./mongodb-procedures-tjhGdBV7.js");
|
|
3791
4571
|
return writeFn({
|
|
3792
4572
|
db: this.db,
|
|
3793
4573
|
prefix: this.prefix,
|
|
@@ -3802,6 +4582,19 @@ var MongoDBMemoryManager = class MongoDBMemoryManager {
|
|
|
3802
4582
|
async getDetailedStatus() {
|
|
3803
4583
|
return getV2Status(this.db, this.prefix, this.agentId);
|
|
3804
4584
|
}
|
|
4585
|
+
async synthesizeProfile(params = {}) {
|
|
4586
|
+
return synthesizeProfile({
|
|
4587
|
+
db: this.db,
|
|
4588
|
+
prefix: this.prefix,
|
|
4589
|
+
agentId: this.agentId,
|
|
4590
|
+
scope: params.scope ?? "agent",
|
|
4591
|
+
scopeRef: params.scopeRef ?? this.agentScopeRef,
|
|
4592
|
+
maxPerType: params.maxPerType,
|
|
4593
|
+
maxEntities: params.maxEntities,
|
|
4594
|
+
maxEpisodes: params.maxEpisodes,
|
|
4595
|
+
activityWindowMs: params.activityWindowMs
|
|
4596
|
+
});
|
|
4597
|
+
}
|
|
3805
4598
|
enqueueDerivedWork(task) {
|
|
3806
4599
|
const run = async () => {
|
|
3807
4600
|
try {
|
|
@@ -4016,7 +4809,8 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4016
4809
|
});
|
|
4017
4810
|
const conversationChunkFilter = context.searchOptions?.conversationFilter ?? {
|
|
4018
4811
|
source: { $in: ["conversation", "sessions"] },
|
|
4019
|
-
agentId
|
|
4812
|
+
agentId,
|
|
4813
|
+
status: { $ne: "deleted" }
|
|
4020
4814
|
};
|
|
4021
4815
|
const bridgeChunkFilter = context.searchOptions?.bridgeFilter;
|
|
4022
4816
|
const maxResults = context.maxResults ?? 20;
|
|
@@ -4038,6 +4832,22 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4038
4832
|
hasEpisodes: context.hasEpisodes,
|
|
4039
4833
|
hasGraphData: context.hasGraphData
|
|
4040
4834
|
});
|
|
4835
|
+
const qrConfig = context.searchOptions?.queryRewriteConfig;
|
|
4836
|
+
let searchQuery = query;
|
|
4837
|
+
let wasQueryRewritten = false;
|
|
4838
|
+
if (qrConfig?.enabled) {
|
|
4839
|
+
const rewriteResult = await rewriteQuery({
|
|
4840
|
+
db,
|
|
4841
|
+
prefix,
|
|
4842
|
+
agentId,
|
|
4843
|
+
query,
|
|
4844
|
+
config: qrConfig
|
|
4845
|
+
});
|
|
4846
|
+
if (rewriteResult.rewritten) {
|
|
4847
|
+
searchQuery = rewriteResult.rewrittenQuery;
|
|
4848
|
+
wasQueryRewritten = true;
|
|
4849
|
+
}
|
|
4850
|
+
}
|
|
4041
4851
|
const constrainedGraphCandidates = plan.constraints?.entities?.names && plan.constraints.entities.names.length > 0 ? plan.constraints.entities.names : graphQueryCandidates;
|
|
4042
4852
|
const timeRange = plan.constraints?.timeRange ? resolveTimeRangePreset(plan.constraints.timeRange.preset) : void 0;
|
|
4043
4853
|
const structuredFilter = {
|
|
@@ -4058,12 +4868,13 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4058
4868
|
const results = [];
|
|
4059
4869
|
const pathsExecuted = [];
|
|
4060
4870
|
const resultsByPath = {};
|
|
4871
|
+
const perPathResults = {};
|
|
4061
4872
|
const pathsToExecute = plan.paths.slice(0, 3);
|
|
4062
4873
|
for (const path of pathsToExecute) try {
|
|
4063
4874
|
let pathResults = [];
|
|
4064
4875
|
switch (path) {
|
|
4065
4876
|
case "active-critical":
|
|
4066
|
-
pathResults = await searchStructuredMemory(structuredMemCollection(db, prefix),
|
|
4877
|
+
pathResults = await searchStructuredMemory(structuredMemCollection(db, prefix), searchQuery, null, {
|
|
4067
4878
|
maxResults: context.maxResults ?? 10,
|
|
4068
4879
|
minScore,
|
|
4069
4880
|
filter: activeCriticalFilter,
|
|
@@ -4077,7 +4888,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4077
4888
|
});
|
|
4078
4889
|
break;
|
|
4079
4890
|
case "structured":
|
|
4080
|
-
pathResults = await searchStructuredMemory(structuredMemCollection(db, prefix),
|
|
4891
|
+
pathResults = await searchStructuredMemory(structuredMemCollection(db, prefix), searchQuery, null, {
|
|
4081
4892
|
maxResults: context.maxResults ?? 10,
|
|
4082
4893
|
minScore,
|
|
4083
4894
|
filter: structuredFilter,
|
|
@@ -4098,7 +4909,8 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4098
4909
|
start: timeRange?.start ?? /* @__PURE__ */ new Date(Date.now() - 1440 * 60 * 1e3),
|
|
4099
4910
|
end: timeRange?.end ?? /* @__PURE__ */ new Date(),
|
|
4100
4911
|
scope,
|
|
4101
|
-
scopeRef: agentScopeRef
|
|
4912
|
+
scopeRef: agentScopeRef,
|
|
4913
|
+
limit: 50
|
|
4102
4914
|
})].toSorted((a, b) => b.timestamp.getTime() - a.timestamp.getTime()).map((e, i) => ({
|
|
4103
4915
|
path: `events/${e.eventId}`,
|
|
4104
4916
|
filePath: `events/${e.eventId}`,
|
|
@@ -4135,7 +4947,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4135
4947
|
startLine: 0,
|
|
4136
4948
|
endLine: 0,
|
|
4137
4949
|
snippet: `${graph.rootEntity.name} ${c.relation.type} ${c.entity.name}`,
|
|
4138
|
-
score: Math.max(.25, .9 - c.depth * .08 - i * .02 - (4 - graphRelationPriority(c.relation.type)) * .05) + Math.min(c.relation.weight ?? 0, .15),
|
|
4950
|
+
score: Math.min(1, Math.max(.25, .9 - c.depth * .08 - i * .02 - (4 - graphRelationPriority(c.relation.type)) * .05) + Math.min(c.relation.weight ?? 0, .15)),
|
|
4139
4951
|
source: "conversation"
|
|
4140
4952
|
}));
|
|
4141
4953
|
}
|
|
@@ -4161,7 +4973,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4161
4973
|
}));
|
|
4162
4974
|
break;
|
|
4163
4975
|
case "procedural":
|
|
4164
|
-
pathResults = await searchProcedures(proceduresCollection(db, prefix),
|
|
4976
|
+
pathResults = await searchProcedures(proceduresCollection(db, prefix), searchQuery, null, {
|
|
4165
4977
|
maxResults: context.maxResults ?? 10,
|
|
4166
4978
|
minScore,
|
|
4167
4979
|
filter: proceduralFilter,
|
|
@@ -4176,7 +4988,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4176
4988
|
break;
|
|
4177
4989
|
case "hybrid": {
|
|
4178
4990
|
const searches = [];
|
|
4179
|
-
if (conversationChunkFilter) searches.push(mongoSearch(chunksCollection(db, prefix),
|
|
4991
|
+
if (conversationChunkFilter) searches.push(mongoSearch(chunksCollection(db, prefix), searchQuery, null, {
|
|
4180
4992
|
maxResults: context.maxResults ?? 10,
|
|
4181
4993
|
minScore,
|
|
4182
4994
|
numCandidates,
|
|
@@ -4193,7 +5005,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4193
5005
|
log.warn(`searchV2 hybrid conversation path failed: ${String(err)}`);
|
|
4194
5006
|
return [];
|
|
4195
5007
|
}));
|
|
4196
|
-
if (bridgeChunkFilter) searches.push(mongoSearch(chunksCollection(db, prefix),
|
|
5008
|
+
if (bridgeChunkFilter) searches.push(mongoSearch(chunksCollection(db, prefix), searchQuery, null, {
|
|
4197
5009
|
maxResults: bridgeMaxResults,
|
|
4198
5010
|
minScore,
|
|
4199
5011
|
numCandidates,
|
|
@@ -4214,7 +5026,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4214
5026
|
break;
|
|
4215
5027
|
}
|
|
4216
5028
|
case "kb":
|
|
4217
|
-
pathResults = await searchKB(kbChunksCollection(db, prefix),
|
|
5029
|
+
pathResults = await searchKB(kbChunksCollection(db, prefix), searchQuery, null, {
|
|
4218
5030
|
maxResults: Math.max(3, Math.floor((context.maxResults ?? 10) / 3)),
|
|
4219
5031
|
minScore,
|
|
4220
5032
|
...kbFilter ? { filter: kbFilter } : {},
|
|
@@ -4233,6 +5045,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4233
5045
|
if (pathResults.length > 0) {
|
|
4234
5046
|
pathsExecuted.push(path);
|
|
4235
5047
|
resultsByPath[path] = pathResults.length;
|
|
5048
|
+
perPathResults[path] = pathResults;
|
|
4236
5049
|
results.push(...pathResults);
|
|
4237
5050
|
}
|
|
4238
5051
|
} catch (pathErr) {
|
|
@@ -4240,7 +5053,7 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4240
5053
|
}
|
|
4241
5054
|
let deduped = deduplicateSearchResults(results);
|
|
4242
5055
|
if (context.availablePaths.has("procedural") && !pathsToExecute.includes("procedural") && deduped.length < Math.max(2, Math.ceil(maxResults / 3))) try {
|
|
4243
|
-
const procedureFallback = await searchProcedures(proceduresCollection(db, prefix),
|
|
5056
|
+
const procedureFallback = await searchProcedures(proceduresCollection(db, prefix), searchQuery, null, {
|
|
4244
5057
|
maxResults: context.maxResults ?? 10,
|
|
4245
5058
|
minScore,
|
|
4246
5059
|
filter: proceduralFilter,
|
|
@@ -4252,35 +5065,74 @@ async function searchV2(db, prefix, query, agentId, context) {
|
|
|
4252
5065
|
if (procedureFallback.length > 0) {
|
|
4253
5066
|
pathsExecuted.push("procedural");
|
|
4254
5067
|
resultsByPath.procedural = procedureFallback.length;
|
|
5068
|
+
perPathResults.procedural = procedureFallback;
|
|
4255
5069
|
deduped = deduplicateSearchResults([...deduped, ...procedureFallback]);
|
|
4256
5070
|
}
|
|
4257
5071
|
} catch (err) {
|
|
4258
5072
|
log.warn(`searchV2 procedural backstop failed: ${String(err)}`);
|
|
4259
5073
|
}
|
|
4260
5074
|
if (allowHybridBackstop && context.availablePaths.has("hybrid") && !pathsExecuted.includes("hybrid") && deduped.length < Math.max(2, Math.ceil(maxResults / 3))) try {
|
|
4261
|
-
const fallback = await searchV2(db, prefix,
|
|
5075
|
+
const fallback = await searchV2(db, prefix, searchQuery, agentId, {
|
|
4262
5076
|
...context,
|
|
4263
5077
|
availablePaths: new Set(["hybrid"]),
|
|
4264
5078
|
maxResults,
|
|
4265
5079
|
searchOptions: {
|
|
4266
5080
|
...context.searchOptions,
|
|
4267
|
-
allowHybridBackstop: false
|
|
5081
|
+
allowHybridBackstop: false,
|
|
5082
|
+
queryRewriteConfig: void 0
|
|
4268
5083
|
}
|
|
4269
5084
|
});
|
|
4270
5085
|
if (fallback.results.length > 0) {
|
|
4271
5086
|
pathsExecuted.push("hybrid");
|
|
4272
5087
|
resultsByPath.hybrid = fallback.results.length;
|
|
5088
|
+
perPathResults.hybrid = fallback.results;
|
|
4273
5089
|
deduped = deduplicateSearchResults([...deduped, ...fallback.results]);
|
|
4274
5090
|
}
|
|
4275
5091
|
} catch (err) {
|
|
4276
5092
|
log.warn(`searchV2 hybrid backstop failed: ${String(err)}`);
|
|
4277
5093
|
}
|
|
5094
|
+
if (Object.keys(perPathResults).length > 1) {
|
|
5095
|
+
const rrfMap = /* @__PURE__ */ new Map();
|
|
5096
|
+
for (const [_pathName, pathRes] of Object.entries(perPathResults)) for (let rank = 0; rank < pathRes.length; rank++) {
|
|
5097
|
+
const key = pathRes[rank].snippet;
|
|
5098
|
+
rrfMap.set(key, (rrfMap.get(key) ?? 0) + rrfScore(rank + 1));
|
|
5099
|
+
}
|
|
5100
|
+
for (const r of deduped) {
|
|
5101
|
+
const rrfVal = rrfMap.get(r.snippet);
|
|
5102
|
+
if (rrfVal !== void 0) r.score = rrfVal;
|
|
5103
|
+
}
|
|
5104
|
+
deduped.sort((a, b) => b.score - a.score);
|
|
5105
|
+
}
|
|
5106
|
+
const heuristicReranked = rerankResults(deduped, query);
|
|
5107
|
+
const rerankCfg = context.searchOptions?.rerankConfig;
|
|
5108
|
+
let finalResults = heuristicReranked;
|
|
5109
|
+
let wasReranked = false;
|
|
5110
|
+
if (rerankCfg?.enabled) {
|
|
5111
|
+
const rerankResult = await crossEncoderRerank({
|
|
5112
|
+
db,
|
|
5113
|
+
prefix,
|
|
5114
|
+
agentId,
|
|
5115
|
+
query,
|
|
5116
|
+
results: heuristicReranked,
|
|
5117
|
+
config: rerankCfg
|
|
5118
|
+
});
|
|
5119
|
+
if (rerankResult.reranked) {
|
|
5120
|
+
finalResults = rerankResult.results;
|
|
5121
|
+
wasReranked = true;
|
|
5122
|
+
}
|
|
5123
|
+
}
|
|
5124
|
+
const sliced = finalResults.slice(0, maxResults);
|
|
4278
5125
|
return {
|
|
4279
|
-
results:
|
|
5126
|
+
results: (context.searchOptions?.projection ?? "full") === "ids-only" ? sliced.map((r) => ({
|
|
5127
|
+
...r,
|
|
5128
|
+
snippet: ""
|
|
5129
|
+
})) : sliced,
|
|
4280
5130
|
metadata: {
|
|
4281
5131
|
plan,
|
|
4282
5132
|
pathsExecuted,
|
|
4283
|
-
resultsByPath
|
|
5133
|
+
resultsByPath,
|
|
5134
|
+
reranked: wasReranked,
|
|
5135
|
+
queryRewritten: wasQueryRewritten
|
|
4284
5136
|
}
|
|
4285
5137
|
};
|
|
4286
5138
|
} catch (err) {
|