@askexenow/exe-os 0.9.299 → 0.9.301
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/deploy/compose/.env.customer.example +1 -1
- package/deploy/compose/.env.example +1 -1
- package/deploy/compose/docker-compose.yml +31 -5
- package/deploy/compose/erp-nginx/nginx.conf +6 -3
- package/deploy/compose/generate-env.ts +1 -1
- package/deploy/compose/observability/otel-collector-config.yaml +10 -1
- package/deploy/compose/setup.sh +1 -1
- package/dist/active-agent-56J56WW5.js +27 -0
- package/dist/active-agent-UNJO6AJ2.js +27 -0
- package/dist/active-agent-VDWK7TES.js +28 -0
- package/dist/active-agent-Y5LSIMVC.js +28 -0
- package/dist/agentic-ontology-MZ4WHFDE.js +25 -0
- package/dist/agentic-ontology-QEV7GI3T.js +25 -0
- package/dist/assets/com.askexe.exed.plist +6 -5
- package/dist/backfill-metadata-IHKI5GXV.js +600 -0
- package/dist/backfill-metadata-RQZ4BN7G.js +600 -0
- package/dist/backfill-metadata-ZU3SZNBD.js +600 -0
- package/dist/behaviors-A3L5CWMK.js +46 -0
- package/dist/behaviors-G4KWGS24.js +46 -0
- package/dist/behaviors-WO67R6C4.js +46 -0
- package/dist/bin/agentic-ontology-backfill.js +5 -5
- package/dist/bin/agentic-reflection-backfill.js +6 -6
- package/dist/bin/agentic-semantic-label.js +5 -5
- package/dist/bin/backfill-conversations.js +6 -6
- package/dist/bin/backfill-responses.js +6 -6
- package/dist/bin/backfill-vectors.js +8 -8
- package/dist/bin/bulk-sync-postgres.js +13 -7
- package/dist/bin/cc-doctor.js +5 -5
- package/dist/bin/cleanup-stale-review-tasks.js +10 -10
- package/dist/bin/cli.js +16 -16
- package/dist/bin/deferred-daemon-restart.js +1 -1
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +10 -10
- package/dist/bin/exe-assign.js +8 -8
- package/dist/bin/exe-boot.js +36 -21
- package/dist/bin/exe-call.js +4 -4
- package/dist/bin/exe-cloud.js +13 -7
- package/dist/bin/exe-dispatch.js +10 -10
- package/dist/bin/exe-doctor.js +2 -2
- package/dist/bin/exe-export-behaviors.js +7 -7
- package/dist/bin/exe-forget.js +6 -6
- package/dist/bin/exe-gateway.js +7 -7
- package/dist/bin/exe-healthcheck.js +5 -5
- package/dist/bin/exe-heartbeat.js +10 -10
- package/dist/bin/exe-kill.js +13 -13
- package/dist/bin/exe-launch-agent.js +29 -19
- package/dist/bin/exe-new-employee.js +6 -6
- package/dist/bin/exe-pending-messages.js +11 -11
- package/dist/bin/exe-pending-notifications.js +10 -10
- package/dist/bin/exe-pending-reviews.js +10 -10
- package/dist/bin/exe-rename.js +4 -4
- package/dist/bin/exe-review.js +12 -12
- package/dist/bin/exe-search.js +5 -5
- package/dist/bin/exe-session-cleanup.js +15 -15
- package/dist/bin/exe-settings.js +13 -7
- package/dist/bin/exe-start-codex.js +11 -11
- package/dist/bin/exe-start-opencode.js +8 -8
- package/dist/bin/exe-status.js +11 -11
- package/dist/bin/exe-team.js +3 -3
- package/dist/bin/exe-watchdog.js +3 -3
- package/dist/bin/git-sweep.js +11 -11
- package/dist/bin/graph-backfill.js +6 -6
- package/dist/bin/graph-export.js +5 -5
- package/dist/bin/import-history.js +9 -9
- package/dist/bin/install-launchd.js +7 -3
- package/dist/bin/install.js +19 -15
- package/dist/bin/intercom-check.js +4 -4
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +4 -4
- package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
- package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
- package/dist/bin/pre-publish.js +24 -1
- package/dist/bin/scan-tasks.js +10 -10
- package/dist/bin/setup.js +1 -1
- package/dist/bin/shard-migrate.js +4 -4
- package/dist/bin/stack-update.js +123 -3
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/capability-cards-VTGDTOZ4.js +89 -0
- package/dist/capability-cards-XAQSL26B.js +89 -0
- package/dist/capacity-monitor-6MQLFFQT.js +51 -0
- package/dist/capacity-monitor-BB3LKJLE.js +51 -0
- package/dist/capacity-monitor-G2MAJPRP.js +51 -0
- package/dist/catchup-brief-BQSL5M5S.js +175 -0
- package/dist/catchup-brief-COALBX6L.js +175 -0
- package/dist/catchup-brief-VBGEJQRS.js +175 -0
- package/dist/cc-binary-detect-B5JDCJ5J.js +19 -0
- package/dist/chunk-22LDUTY7.js +14597 -0
- package/dist/chunk-24JVDLQJ.js +345 -0
- package/dist/chunk-24M4AJPG.js +128 -0
- package/dist/chunk-2B7RCTPT.js +85 -0
- package/dist/chunk-2QBA6YE6.js +127 -0
- package/dist/chunk-2RGDEBZC.js +731 -0
- package/dist/chunk-2T3OYZMR.js +1158 -0
- package/dist/chunk-32DBQWR5.js +333 -0
- package/dist/chunk-3ABY3QDX.js +199 -0
- package/dist/chunk-3EOPMTG2.js +128 -0
- package/dist/chunk-3G3ECFB5.js +668 -0
- package/dist/chunk-3LHOFGHT.js +280 -0
- package/dist/chunk-3NS4V4JW.js +382 -0
- package/dist/chunk-3NYY2NZ3.js +836 -0
- package/dist/chunk-3RA62PNQ.js +58 -0
- package/dist/chunk-3ROUD5WA.js +97 -0
- package/dist/chunk-3RY2ARDN.js +129 -0
- package/dist/chunk-3XRS5AVV.js +567 -0
- package/dist/chunk-3Y5IRIRU.js +290 -0
- package/dist/chunk-3YK7X5FD.js +1186 -0
- package/dist/chunk-3ZWWUKBI.js +210 -0
- package/dist/chunk-463G3VAH.js +122 -0
- package/dist/chunk-4L6PVYFE.js +54 -0
- package/dist/chunk-4LC7BFI2.js +76 -0
- package/dist/chunk-4O67LBMK.js +377 -0
- package/dist/chunk-4OIU3N6U.js +167 -0
- package/dist/chunk-4Z3FWLOE.js +836 -0
- package/dist/chunk-5BAU4T5G.js +208 -0
- package/dist/chunk-5FP7YHCG.js +1158 -0
- package/dist/chunk-5SYYMNPE.js +30 -0
- package/dist/chunk-5TO5PH7O.js +304 -0
- package/dist/chunk-5U3JZP62.js +1352 -0
- package/dist/chunk-5VNFXIGF.js +85 -0
- package/dist/chunk-5XD2Y463.js +402 -0
- package/dist/chunk-63AENHJC.js +123 -0
- package/dist/chunk-673IFJYB.js +731 -0
- package/dist/chunk-6UVUJNLY.js +1186 -0
- package/dist/chunk-7AWH47AR.js +448 -0
- package/dist/chunk-7KPWYWYL.js +290 -0
- package/dist/chunk-7P4B6AEP.js +227 -0
- package/dist/chunk-7URNGDEY.js +2145 -0
- package/dist/chunk-7VHOALNC.js +244 -0
- package/dist/chunk-ADZQBZOX.js +122 -0
- package/dist/chunk-APSZAEDO.js +1186 -0
- package/dist/chunk-ASHF6VO4.js +2265 -0
- package/dist/chunk-ASJHCAVL.js +38 -0
- package/dist/chunk-BT2LEHIW.js +448 -0
- package/dist/chunk-BTS5QUWB.js +50 -0
- package/dist/chunk-BWJDJ3BS.js +604 -0
- package/dist/chunk-CME46VWP.js +150 -0
- package/dist/chunk-D3ICCKXY.js +54 -0
- package/dist/chunk-D3IOU3NO.js +377 -0
- package/dist/chunk-DFGXRKI2.js +221 -0
- package/dist/chunk-DICIFTCS.js +150 -0
- package/dist/chunk-DIFI5JDC.js +76 -0
- package/dist/chunk-DO65VHQZ.js +128 -0
- package/dist/chunk-DPOIJ5SM.js +284 -0
- package/dist/chunk-E2OMUBXQ.js +567 -0
- package/dist/chunk-ECMXIV6N.js +97 -0
- package/dist/chunk-EDMVA3PT.js +727 -0
- package/dist/chunk-F5OSXH4A.js +4388 -0
- package/dist/chunk-F5OWHPRG.js +236 -0
- package/dist/chunk-F7MZA3QP.js +199 -0
- package/dist/chunk-FAZNXNA5.js +33 -0
- package/dist/chunk-FCHG5RC4.js +197 -0
- package/dist/chunk-FFKSPZO2.js +157 -0
- package/dist/chunk-FNHYH5U6.js +331 -0
- package/dist/chunk-FRNXQSB4.js +134 -0
- package/dist/chunk-FTAASABV.js +362 -0
- package/dist/chunk-FWPDAQ6Q.js +1350 -0
- package/dist/chunk-FZB73QOI.js +210 -0
- package/dist/chunk-GBL5QSTM.js +197 -0
- package/dist/chunk-GJBR6QLD.js +630 -0
- package/dist/chunk-GRSYAHKI.js +535 -0
- package/dist/chunk-GRXWINOW.js +244 -0
- package/dist/chunk-GUPNVUG5.js +348 -0
- package/dist/chunk-GY66UPMX.js +167 -0
- package/dist/chunk-HCCG67BY.js +43 -0
- package/dist/chunk-HCSZZXZZ.js +197 -0
- package/dist/chunk-HNGNZU62.js +240 -0
- package/dist/chunk-HP2D5LIE.js +214 -0
- package/dist/chunk-HUABQHDC.js +1352 -0
- package/dist/chunk-HYKO2LNW.js +157 -0
- package/dist/chunk-IFL6DG2K.js +181 -0
- package/dist/chunk-IKPQRHVQ.js +304 -0
- package/dist/chunk-J5HFRVNW.js +362 -0
- package/dist/chunk-J6SD7LT2.js +171 -0
- package/dist/chunk-JCWA3X6A.js +402 -0
- package/dist/chunk-JHPK33IP.js +2162 -0
- package/dist/chunk-JURL2S27.js +128 -0
- package/dist/chunk-JWGDH5I2.js +127 -0
- package/dist/chunk-KBXQFXYM.js +567 -0
- package/dist/chunk-KGY5QIOJ.js +1350 -0
- package/dist/chunk-KLES22FB.js +1094 -0
- package/dist/chunk-KPUYYOFS.js +122 -0
- package/dist/chunk-KY43UELJ.js +331 -0
- package/dist/chunk-L32V4O5Z.js +58 -0
- package/dist/chunk-LAFARYU5.js +456 -0
- package/dist/chunk-LC7ETNTJ.js +1350 -0
- package/dist/chunk-LEJ5FKIK.js +55 -0
- package/dist/chunk-LNLLCAI4.js +377 -0
- package/dist/chunk-LQWZYMNU.js +448 -0
- package/dist/chunk-LSDXEHKL.js +381 -0
- package/dist/chunk-LY3SOO73.js +76 -0
- package/dist/chunk-M6CIHXXB.js +159 -0
- package/dist/chunk-MJOQ35DX.js +427 -0
- package/dist/chunk-MO5HER5Y.js +345 -0
- package/dist/chunk-MS2EOZJQ.js +290 -0
- package/dist/chunk-MUIMJGSQ.js +128 -0
- package/dist/chunk-MY4TGLT6.js +284 -0
- package/dist/chunk-N3ARGCVG.js +345 -0
- package/dist/chunk-N4XG2M2U.js +735 -0
- package/dist/chunk-N72JNFJ4.js +535 -0
- package/dist/chunk-NJMPNYBS.js +427 -0
- package/dist/chunk-NM3AUMFE.js +2145 -0
- package/dist/chunk-NPPQ3TR4.js +735 -0
- package/dist/chunk-NTWF4DAF.js +581 -0
- package/dist/chunk-NXL3VKXM.js +331 -0
- package/dist/chunk-OJACH2JF.js +128 -0
- package/dist/chunk-OMSLHEEF.js +456 -0
- package/dist/chunk-OO4IFABD.js +382 -0
- package/dist/chunk-OYIP3QVN.js +167 -0
- package/dist/chunk-P2IOW54H.js +668 -0
- package/dist/chunk-P5KXQ3RN.js +731 -0
- package/dist/chunk-P5UXP53T.js +81 -0
- package/dist/chunk-PH6VRRFR.js +395 -0
- package/dist/chunk-Q3GKOF7Z.js +85 -0
- package/dist/chunk-Q65NCNL4.js +1352 -0
- package/dist/chunk-QIGS2LRT.js +735 -0
- package/dist/chunk-QKBN3CY2.js +381 -0
- package/dist/chunk-QNNAVMQH.js +1094 -0
- package/dist/chunk-QODDW4YI.js +171 -0
- package/dist/chunk-QPAYPTSH.js +2162 -0
- package/dist/chunk-QRWDJ5RI.js +381 -0
- package/dist/chunk-RBFZCHVB.js +105 -0
- package/dist/chunk-RCEULTPF.js +185 -0
- package/dist/chunk-RCGHXBCX.js +630 -0
- package/dist/chunk-ROSCLRTH.js +204 -0
- package/dist/chunk-RYAOSGUW.js +227 -0
- package/dist/chunk-S2SPGHPY.js +38 -0
- package/dist/chunk-S73ZAJ2S.js +262 -0
- package/dist/chunk-SBPEWD7Z.js +171 -0
- package/dist/chunk-SDPUWZP5.js +333 -0
- package/dist/chunk-SJ4UF7YK.js +1094 -0
- package/dist/chunk-SOZ7D77I.js +204 -0
- package/dist/chunk-SVLSHDNL.js +54 -0
- package/dist/chunk-SVUYBT5N.js +262 -0
- package/dist/chunk-T7PTLVJV.js +284 -0
- package/dist/chunk-TDX2LK2M.js +240 -0
- package/dist/chunk-TGUSLO4B.js +50 -0
- package/dist/chunk-TPJH6PE6.js +1158 -0
- package/dist/chunk-TVW7EDOJ.js +382 -0
- package/dist/chunk-TYRUIE6P.js +58 -0
- package/dist/chunk-U5RKGLV6.js +50 -0
- package/dist/chunk-UFGTHBHP.js +127 -0
- package/dist/chunk-ULCYWCPI.js +1079 -0
- package/dist/chunk-UN5EPVBN.js +14597 -0
- package/dist/chunk-URLH7ZVR.js +70 -0
- package/dist/chunk-USYRTGR7.js +402 -0
- package/dist/chunk-V4ABCEHM.js +30 -0
- package/dist/chunk-V6LOEOXG.js +3372 -0
- package/dist/chunk-VAZOVAW4.js +2162 -0
- package/dist/chunk-VEUQVKKT.js +185 -0
- package/dist/chunk-VIDDJ5RF.js +214 -0
- package/dist/chunk-VKCNXOQ6.js +214 -0
- package/dist/chunk-VNB4ROYG.js +348 -0
- package/dist/chunk-VWUQFZFB.js +395 -0
- package/dist/chunk-W77GRCNA.js +85 -0
- package/dist/chunk-WB2B25UM.js +230 -0
- package/dist/chunk-WCUZX7F7.js +204 -0
- package/dist/chunk-WL5RMOZQ.js +362 -0
- package/dist/chunk-WPAXAOHD.js +1079 -0
- package/dist/chunk-WVMG4ZRH.js +14597 -0
- package/dist/chunk-WYVOTRRZ.js +129 -0
- package/dist/chunk-XABJRAUW.js +3346 -0
- package/dist/chunk-XQQ7D4I4.js +85 -0
- package/dist/chunk-YDFY6YCH.js +280 -0
- package/dist/chunk-YGUMRYCN.js +33 -0
- package/dist/chunk-YHJPTIPR.js +836 -0
- package/dist/chunk-YJSP5PPG.js +128 -0
- package/dist/chunk-YLKS7KKC.js +2145 -0
- package/dist/chunk-YOMETWOJ.js +4388 -0
- package/dist/chunk-YU3KEVCO.js +333 -0
- package/dist/chunk-Z4FVFSE3.js +81 -0
- package/dist/chunk-Z4TLSNUW.js +244 -0
- package/dist/chunk-ZDPU3JTF.js +221 -0
- package/dist/chunk-ZDY4LYAJ.js +81 -0
- package/dist/chunk-ZG33AACD.js +70 -0
- package/dist/chunk-ZKHPZ6KN.js +181 -0
- package/dist/chunk-ZO2TM5N5.js +97 -0
- package/dist/chunk-ZP6T5K6I.js +535 -0
- package/dist/chunk-ZR6ZJT32.js +123 -0
- package/dist/chunk-ZSUACDQC.js +4388 -0
- package/dist/co-activation-JGF5YIDU.js +74 -0
- package/dist/co-activation-XM25BLZM.js +74 -0
- package/dist/co-occurrence-CKEMDPWO.js +95 -0
- package/dist/co-occurrence-HLLC6GT2.js +95 -0
- package/dist/co-occurrence-W2LIAPHI.js +95 -0
- package/dist/code-context-index-FCL47WKE.js +30 -0
- package/dist/conversation-entity-extractor-WC2RU6RS.js +114 -0
- package/dist/core-memory-CRSR2PSL.js +110 -0
- package/dist/core-memory-VSKFRMEV.js +110 -0
- package/dist/core-memory-ZDA76EU3.js +110 -0
- package/dist/crdt-sync-6VH2YDVY.js +33 -0
- package/dist/crdt-sync-BJKZB6T6.js +33 -0
- package/dist/crm-webhook-E5PAFAUN.js +10 -0
- package/dist/crm-webhook-RXFPZJXP.js +10 -0
- package/dist/crm-webhook-Z26LEFKG.js +10 -0
- package/dist/cto-delegation-gate-45IBLPTK.js +280 -0
- package/dist/cto-delegation-gate-EMY6ZZ2F.js +280 -0
- package/dist/cto-delegation-gate-SF4EUB2Q.js +280 -0
- package/dist/daemon-orchestration-VB3BLYIT.js +143 -0
- package/dist/daemon-orchestration-W66UYGUD.js +143 -0
- package/dist/daemon-orchestration-Y5Y6YNE3.js +143 -0
- package/dist/db-backup-HFJ53IBU.js +43 -0
- package/dist/db-backup-NVUTS7L5.js +43 -0
- package/dist/doc-graph-extractor-ID45AQ2P.js +133 -0
- package/dist/doc-graph-extractor-MLYQYT4B.js +133 -0
- package/dist/doc-graph-extractor-SVFSXKL6.js +133 -0
- package/dist/dreaming-AZYRAGKA.js +34 -0
- package/dist/dreaming-N6B7KBIE.js +34 -0
- package/dist/dreaming-WG5CDUHX.js +34 -0
- package/dist/entity-boost-XAFCDDB6.js +375 -0
- package/dist/exe-drift-3SGA53CL.js +70 -0
- package/dist/exe-drift-CPUEAPIU.js +70 -0
- package/dist/exe-export-4RTGDV53.js +77 -0
- package/dist/exe-export-APUNLKWF.js +77 -0
- package/dist/exe-export-NM4SXB3P.js +77 -0
- package/dist/exe-import-6GLNCP62.js +80 -0
- package/dist/exe-import-AZMIF34Z.js +80 -0
- package/dist/exe-import-U4H4ES3Z.js +80 -0
- package/dist/exe-key-FIPXUTMF.js +673 -0
- package/dist/exe-key-LJV23AJI.js +673 -0
- package/dist/exe-key-WTLCMOYJ.js +673 -0
- package/dist/exe-snapshot-ILO3WSEC.js +338 -0
- package/dist/exe-snapshot-IODRQLBX.js +338 -0
- package/dist/exe-snapshot-ZOZBW7V6.js +338 -0
- package/dist/fast-db-init-7LYYUCSJ.js +7 -0
- package/dist/fast-db-init-ATRZGHOL.js +7 -0
- package/dist/fast-db-init-IU7GYFWB.js +7 -0
- package/dist/gateway/index.js +11 -11
- package/dist/git-staleness-GGCFPHQ5.js +112 -0
- package/dist/git-staleness-XNOKI4D3.js +112 -0
- package/dist/git-task-sweep-3MO4OVND.js +42 -0
- package/dist/git-task-sweep-M3SWXFKJ.js +42 -0
- package/dist/git-task-sweep-Y6KNWB67.js +42 -0
- package/dist/global-procedures-626WAU3I.js +22 -0
- package/dist/global-procedures-EBAPPWGZ.js +22 -0
- package/dist/graph-auto-extract-TKHQ4OR3.js +183 -0
- package/dist/graph-auto-extract-VGFEWFZX.js +183 -0
- package/dist/graph-auto-extract-VJOUQBPK.js +183 -0
- package/dist/graph-rag-KECA5TE4.js +35 -0
- package/dist/hooks/bug-report-worker.js +12 -12
- package/dist/hooks/codex-stop-task-finalizer.js +12 -12
- package/dist/hooks/commit-complete.js +12 -12
- package/dist/hooks/error-recall.js +6 -6
- package/dist/hooks/exe-heartbeat-hook.js +3 -3
- package/dist/hooks/ingest-worker.js +3 -3
- package/dist/hooks/ingest.js +6 -6
- package/dist/hooks/instructions-loaded.js +4 -4
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +4 -4
- package/dist/hooks/post-compact.js +12 -12
- package/dist/hooks/post-tool-combined.js +6 -6
- package/dist/hooks/pre-compact.js +16 -16
- package/dist/hooks/pre-tool-use.js +15 -15
- package/dist/hooks/prompt-submit.js +28 -26
- package/dist/hooks/session-end.js +20 -20
- package/dist/hooks/session-start.js +12 -12
- package/dist/hooks/stop.js +18 -18
- package/dist/hooks/subagent-stop.js +11 -11
- package/dist/hooks/summary-worker.js +18 -18
- package/dist/index.js +20 -20
- package/dist/installer-37KFNAWE.js +344 -0
- package/dist/installer-3FB5EMPB.js +40 -0
- package/dist/installer-BRQ42CPB.js +344 -0
- package/dist/installer-F55NR4E2.js +298 -0
- package/dist/installer-KOYBUS4J.js +40 -0
- package/dist/installer-PXZJG256.js +298 -0
- package/dist/lib/cloud-sync.js +13 -7
- package/dist/lib/consolidation.js +7 -7
- package/dist/lib/database.js +6 -4
- package/dist/lib/db-daemon-client.js +11 -202
- package/dist/lib/db.js +6 -4
- package/dist/lib/embedder.js +3 -3
- package/dist/lib/employee-templates.js +4 -4
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon-client.js +2 -2
- package/dist/lib/exe-daemon.js +53 -51
- package/dist/lib/hybrid-search.js +5 -5
- package/dist/lib/identity.js +2 -2
- package/dist/lib/messaging.js +10 -10
- package/dist/lib/reminders.js +3 -3
- package/dist/lib/schedules.js +5 -5
- package/dist/lib/session-registry.js +4 -4
- package/dist/lib/skill-learning.js +6 -6
- package/dist/lib/store.js +4 -4
- package/dist/lib/task-router.js +3 -3
- package/dist/lib/tasks.js +11 -11
- package/dist/lib/tmux-routing.js +9 -9
- package/dist/lib/token-spend.js +3 -3
- package/dist/mcp/register-tools.js +65 -63
- package/dist/mcp/server.js +66 -64
- package/dist/mcp/tools/complete-reminder.js +4 -4
- package/dist/mcp/tools/create-reminder.js +4 -4
- package/dist/mcp/tools/create-task.js +13 -13
- package/dist/mcp/tools/deactivate-behavior.js +7 -7
- package/dist/mcp/tools/list-reminders.js +4 -4
- package/dist/mcp/tools/list-tasks.js +13 -13
- package/dist/mcp/tools/send-message.js +12 -12
- package/dist/mcp/tools/update-task.js +12 -12
- package/dist/mcp-http-config-7KJZI7UD.js +31 -0
- package/dist/mcp-http-config-OF3MB7M5.js +31 -0
- package/dist/memory-cards-CPIZVXWI.js +180 -0
- package/dist/memory-cards-ZIT7ZKL5.js +180 -0
- package/dist/memory-graph-extractor-JIYWLBFF.js +22 -0
- package/dist/memory-graph-extractor-LY2VORZT.js +22 -0
- package/dist/memory-graph-extractor-MDPSLZDM.js +22 -0
- package/dist/memory-poisoning-defense-5UZT3WWA.js +224 -0
- package/dist/memory-poisoning-defense-SEM25TY5.js +224 -0
- package/dist/memory-queue-client-WKWRFERJ.js +16 -0
- package/dist/memory-reflection-J2W7CJ7C.js +244 -0
- package/dist/memory-reflection-TA2VQYPH.js +244 -0
- package/dist/message-queue-client-IFQQ2HI7.js +92 -0
- package/dist/notifications-CZBQ3H5T.js +47 -0
- package/dist/notifications-EIIL2EQV.js +47 -0
- package/dist/notifications-RLMSI4YE.js +47 -0
- package/dist/orchestration-events-TGQYA72K.js +27 -0
- package/dist/orchestration-events-VUYR6MXE.js +27 -0
- package/dist/orchestrator-JQD5G3CW.js +35 -0
- package/dist/orchestrator-MAMR4C37.js +35 -0
- package/dist/orchestrator-VE5WHEJH.js +35 -0
- package/dist/pipeline-router-3Q3YBYSM.js +15 -0
- package/dist/pipeline-router-DKXD6DJO.js +15 -0
- package/dist/pipeline-router-YNW63BY5.js +15 -0
- package/dist/plan-limits-YGXTYCW4.js +28 -0
- package/dist/plan-limits-ZM4MNZKY.js +28 -0
- package/dist/project-boot-E2TWYTAC.js +299 -0
- package/dist/project-boot-TDOZKKDR.js +299 -0
- package/dist/projection-worker-TMKUSVGD.js +1084 -0
- package/dist/projection-worker-WFPRM4AI.js +1084 -0
- package/dist/projection-worker-YKV3PFCV.js +1084 -0
- package/dist/prospective-memory-CNJDBNWF.js +232 -0
- package/dist/prospective-memory-OAFZUODU.js +232 -0
- package/dist/reranker-AFU75HEX.js +19 -0
- package/dist/reranker-RYNSJNDF.js +19 -0
- package/dist/reranker-YQIRNGDM.js +19 -0
- package/dist/retrieval-health-M5BVB7EV.js +12 -0
- package/dist/retrieval-health-RSQEIYIB.js +12 -0
- package/dist/review-polling-LGX7DUNT.js +126 -0
- package/dist/review-polling-MJBCYV4I.js +126 -0
- package/dist/review-polling-ZMB3OBPC.js +126 -0
- package/dist/runtime/index.js +16 -16
- package/dist/services/codex-reviewd/index.js +855 -0
- package/dist/session-events-5N47BRFK.js +38 -0
- package/dist/session-events-PT6SVS2P.js +38 -0
- package/dist/session-events-UTMCKDIN.js +38 -0
- package/dist/session-kill-telemetry-FRQA5MVD.js +31 -0
- package/dist/session-kill-telemetry-HKL2NQMR.js +31 -0
- package/dist/session-scope-2BD6QLNI.js +88 -0
- package/dist/session-scope-GQNCM6UQ.js +88 -0
- package/dist/session-scope-MMGM232A.js +88 -0
- package/dist/setup-wizard-SELXXVLD.js +12 -0
- package/dist/setup-wizard-W64I6SHC.js +12 -0
- package/dist/setup-wizard-X7YSRDNQ.js +12 -0
- package/dist/skill-refinement-CCP4ULZ3.js +159 -0
- package/dist/skill-refinement-FXCXTUS2.js +159 -0
- package/dist/skill-refinement-WCPDNHZ5.js +159 -0
- package/dist/stack-update-5VSGG36W.js +84 -0
- package/dist/steward-gate-JDR3SLH3.js +15 -0
- package/dist/steward-gate-PIXNK4BK.js +15 -0
- package/dist/task-enforcement-LEBWCYZT.js +506 -0
- package/dist/task-enforcement-VOSQRAQB.js +506 -0
- package/dist/task-enforcement-WCEA4FZI.js +506 -0
- package/dist/task-scope-CQZ33PRU.js +37 -0
- package/dist/task-scope-JTTEZKDU.js +37 -0
- package/dist/task-scope-L5GDL2AV.js +37 -0
- package/dist/tasks-crud-DC4GCXQQ.js +79 -0
- package/dist/tasks-crud-S36AFYYM.js +79 -0
- package/dist/tasks-crud-T32IRPXF.js +79 -0
- package/dist/tasks-notify-OBFVHJDP.js +40 -0
- package/dist/tasks-notify-OUQWUM6W.js +40 -0
- package/dist/tasks-notify-W2W2BJRB.js +40 -0
- package/dist/tasks-review-34WV7BX2.js +49 -0
- package/dist/tasks-review-N33MTHWJ.js +49 -0
- package/dist/tasks-review-OSBG2YN2.js +49 -0
- package/dist/telemetry-upload-3CSVO3J7.js +741 -0
- package/dist/telemetry-upload-EYHEWTKG.js +741 -0
- package/dist/telemetry-upload-XLBW4DRP.js +741 -0
- package/dist/token-budget-I6FMMDFX.js +86 -0
- package/dist/token-budget-ZG2MQ5GD.js +86 -0
- package/dist/tool-capability-index-IWQBQKM7.js +10 -0
- package/dist/tool-telemetry-2E3Z7CRV.js +17 -0
- package/dist/tool-telemetry-ODL4F2CW.js +17 -0
- package/dist/tui/App.js +17 -17
- package/dist/tui-data-VWT4Q5UT.js +260 -0
- package/dist/tui-data-XFBFBSBE.js +260 -0
- package/dist/tui-data-Z5UF7KEI.js +260 -0
- package/dist/wiki-acl-EUOPNUIQ.js +111 -0
- package/dist/wiki-acl-SZFHCEC4.js +111 -0
- package/dist/worker-gate-OOO6BWZ6.js +21 -0
- package/dist/worker-gate-OQMKAMP7.js +21 -0
- package/dist/worker-gate-ZPP3SZK6.js +21 -0
- package/dist/workflow-engine-P7WYJP2B.js +28 -0
- package/dist/workflow-engine-QY3IFFR2.js +28 -0
- package/dist/workflow-engine-UYNB5RTB.js +28 -0
- package/dist/worktree-CNOQZBNT.js +28 -0
- package/dist/worktree-H5C4LMQR.js +28 -0
- package/dist/worktree-sweep-KFWF3XZD.js +21 -0
- package/dist/worktree-sweep-SE7ITXC4.js +21 -0
- package/package.json +1 -1
- package/release-notes.json +117 -191
- package/src/commands/exe.md +18 -1
|
@@ -0,0 +1,727 @@
|
|
|
1
|
+
import {
|
|
2
|
+
chunkSourceFile,
|
|
3
|
+
languageForFile
|
|
4
|
+
} from "./chunk-I7AW4237.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveType
|
|
7
|
+
} from "./chunk-GUMRIUI5.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/graph-rag.ts
|
|
10
|
+
import crypto from "crypto";
|
|
11
|
+
var AST_EXTRACTABLE_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "javascript"]);
|
|
12
|
+
var ENTITY_TYPES = [
|
|
13
|
+
"person",
|
|
14
|
+
"tool",
|
|
15
|
+
"project",
|
|
16
|
+
"decision",
|
|
17
|
+
"concept",
|
|
18
|
+
"file",
|
|
19
|
+
// Cross-repo contract entities (v1.2)
|
|
20
|
+
"repo",
|
|
21
|
+
"api_contract",
|
|
22
|
+
"mcp_tool",
|
|
23
|
+
"protocol",
|
|
24
|
+
"schema"
|
|
25
|
+
];
|
|
26
|
+
var RELATIONSHIP_TYPES = [
|
|
27
|
+
"implemented",
|
|
28
|
+
"superseded_by",
|
|
29
|
+
"depends_on",
|
|
30
|
+
"blocked_by",
|
|
31
|
+
"worked_on",
|
|
32
|
+
"uses",
|
|
33
|
+
"decided",
|
|
34
|
+
"related_to",
|
|
35
|
+
// Cross-repo contract relationships (v1.2)
|
|
36
|
+
"implements_contract",
|
|
37
|
+
// repo/service implements an API contract
|
|
38
|
+
"exposes_api",
|
|
39
|
+
// repo exposes an API endpoint/MCP tool
|
|
40
|
+
"consumes_api",
|
|
41
|
+
// repo consumes another repo's API
|
|
42
|
+
"shares_schema",
|
|
43
|
+
// repos share a DB schema or data contract
|
|
44
|
+
"depends_on_repo"
|
|
45
|
+
// repo-level dependency
|
|
46
|
+
];
|
|
47
|
+
async function tableHasColumn(client, table, column) {
|
|
48
|
+
try {
|
|
49
|
+
const result = await client.execute(`PRAGMA table_info(${table})`);
|
|
50
|
+
return result.rows.some((row) => String(row.name) === column);
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
var GRAPH_EXTRACTION_CONTENT_LIMIT = 4e3;
|
|
56
|
+
function normalizeEntityName(name) {
|
|
57
|
+
return name.replace(/\s*\([^)]*\)\s*/g, "").trim().replace(/\s+/g, " ").toLowerCase();
|
|
58
|
+
}
|
|
59
|
+
function entityId(name, type) {
|
|
60
|
+
const normalized = normalizeEntityName(name);
|
|
61
|
+
const resolvedType = resolveType(type).type.toLowerCase();
|
|
62
|
+
return crypto.createHash("sha256").update(`${normalized}::${resolvedType}`).digest("hex").slice(0, 16);
|
|
63
|
+
}
|
|
64
|
+
async function resolveAlias(client, name) {
|
|
65
|
+
const normalized = normalizeEntityName(name);
|
|
66
|
+
try {
|
|
67
|
+
const result = await client.execute({
|
|
68
|
+
sql: "SELECT canonical_entity_id FROM entity_aliases WHERE alias = ?",
|
|
69
|
+
args: [normalized]
|
|
70
|
+
});
|
|
71
|
+
if (result.rows.length > 0) {
|
|
72
|
+
return String(result.rows[0].canonical_entity_id);
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
async function registerAlias(client, alias, canonicalEntityId) {
|
|
79
|
+
const normalized = normalizeEntityName(alias);
|
|
80
|
+
await client.execute({
|
|
81
|
+
sql: `INSERT OR REPLACE INTO entity_aliases (alias, canonical_entity_id) VALUES (?, ?)`,
|
|
82
|
+
args: [normalized, canonicalEntityId]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async function selectActualEntityId(client, name, type, fallbackId) {
|
|
86
|
+
const result = await client.execute({
|
|
87
|
+
sql: "SELECT id FROM entities WHERE LOWER(name) = LOWER(?) AND type = ? LIMIT 1",
|
|
88
|
+
args: [normalizeEntityName(name), type]
|
|
89
|
+
});
|
|
90
|
+
return result.rows[0]?.id ? String(result.rows[0].id) : fallbackId;
|
|
91
|
+
}
|
|
92
|
+
async function cleanupGraphLinksForMemories(client, memoryIds) {
|
|
93
|
+
const uniqueIds = [...new Set(memoryIds)].filter(Boolean);
|
|
94
|
+
if (uniqueIds.length === 0) {
|
|
95
|
+
return { entityLinksDeleted: 0, relationshipLinksDeleted: 0 };
|
|
96
|
+
}
|
|
97
|
+
const placeholders = uniqueIds.map(() => "?").join(",");
|
|
98
|
+
const entityLinks = await client.execute({
|
|
99
|
+
sql: `DELETE FROM entity_memories WHERE memory_id IN (${placeholders})`,
|
|
100
|
+
args: uniqueIds
|
|
101
|
+
});
|
|
102
|
+
const relationshipLinks = await client.execute({
|
|
103
|
+
sql: `DELETE FROM relationship_memories WHERE memory_id IN (${placeholders})`,
|
|
104
|
+
args: uniqueIds
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
entityLinksDeleted: entityLinks.rowsAffected ?? 0,
|
|
108
|
+
relationshipLinksDeleted: relationshipLinks.rowsAffected ?? 0
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
async function mergeEntities(client, sourceEntityId, targetEntityId) {
|
|
112
|
+
if (sourceEntityId === targetEntityId) {
|
|
113
|
+
return { relationshipsMoved: 0, memoriesMoved: 0 };
|
|
114
|
+
}
|
|
115
|
+
const sourceResult = await client.execute({
|
|
116
|
+
sql: "SELECT name FROM entities WHERE id = ?",
|
|
117
|
+
args: [sourceEntityId]
|
|
118
|
+
});
|
|
119
|
+
if (sourceResult.rows.length === 0) {
|
|
120
|
+
throw new Error(`Source entity ${sourceEntityId} not found`);
|
|
121
|
+
}
|
|
122
|
+
const targetResult = await client.execute({
|
|
123
|
+
sql: "SELECT id FROM entities WHERE id = ?",
|
|
124
|
+
args: [targetEntityId]
|
|
125
|
+
});
|
|
126
|
+
if (targetResult.rows.length === 0) {
|
|
127
|
+
throw new Error(`Target entity ${targetEntityId} not found`);
|
|
128
|
+
}
|
|
129
|
+
const sourceName = String(sourceResult.rows[0].name);
|
|
130
|
+
const relsSource = await client.execute({
|
|
131
|
+
sql: `UPDATE relationships SET source_entity_id = ?
|
|
132
|
+
WHERE source_entity_id = ?
|
|
133
|
+
AND NOT EXISTS (
|
|
134
|
+
SELECT 1 FROM relationships r2
|
|
135
|
+
WHERE r2.source_entity_id = ? AND r2.target_entity_id = relationships.target_entity_id AND r2.type = relationships.type
|
|
136
|
+
)`,
|
|
137
|
+
args: [targetEntityId, sourceEntityId, targetEntityId]
|
|
138
|
+
});
|
|
139
|
+
const relsTarget = await client.execute({
|
|
140
|
+
sql: `UPDATE relationships SET target_entity_id = ?
|
|
141
|
+
WHERE target_entity_id = ?
|
|
142
|
+
AND NOT EXISTS (
|
|
143
|
+
SELECT 1 FROM relationships r2
|
|
144
|
+
WHERE r2.target_entity_id = ? AND r2.source_entity_id = relationships.source_entity_id AND r2.type = relationships.type
|
|
145
|
+
)`,
|
|
146
|
+
args: [targetEntityId, sourceEntityId, targetEntityId]
|
|
147
|
+
});
|
|
148
|
+
await client.execute({
|
|
149
|
+
sql: "DELETE FROM relationships WHERE source_entity_id = ? OR target_entity_id = ?",
|
|
150
|
+
args: [sourceEntityId, sourceEntityId]
|
|
151
|
+
});
|
|
152
|
+
await client.execute({
|
|
153
|
+
sql: "DELETE FROM relationships WHERE source_entity_id = target_entity_id",
|
|
154
|
+
args: []
|
|
155
|
+
});
|
|
156
|
+
const mems = await client.execute({
|
|
157
|
+
sql: `INSERT OR IGNORE INTO entity_memories (entity_id, memory_id)
|
|
158
|
+
SELECT ?, memory_id FROM entity_memories WHERE entity_id = ?`,
|
|
159
|
+
args: [targetEntityId, sourceEntityId]
|
|
160
|
+
});
|
|
161
|
+
await client.execute({
|
|
162
|
+
sql: "DELETE FROM entity_memories WHERE entity_id = ?",
|
|
163
|
+
args: [sourceEntityId]
|
|
164
|
+
});
|
|
165
|
+
try {
|
|
166
|
+
await client.execute({
|
|
167
|
+
sql: "UPDATE entity_aliases SET canonical_entity_id = ? WHERE canonical_entity_id = ?",
|
|
168
|
+
args: [targetEntityId, sourceEntityId]
|
|
169
|
+
});
|
|
170
|
+
} catch {
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
await client.execute({
|
|
174
|
+
sql: `INSERT OR IGNORE INTO hyperedge_nodes (hyperedge_id, entity_id)
|
|
175
|
+
SELECT hyperedge_id, ? FROM hyperedge_nodes WHERE entity_id = ?`,
|
|
176
|
+
args: [targetEntityId, sourceEntityId]
|
|
177
|
+
});
|
|
178
|
+
await client.execute({
|
|
179
|
+
sql: "DELETE FROM hyperedge_nodes WHERE entity_id = ?",
|
|
180
|
+
args: [sourceEntityId]
|
|
181
|
+
});
|
|
182
|
+
} catch {
|
|
183
|
+
}
|
|
184
|
+
await registerAlias(client, sourceName, targetEntityId);
|
|
185
|
+
await client.execute({
|
|
186
|
+
sql: "DELETE FROM entities WHERE id = ?",
|
|
187
|
+
args: [sourceEntityId]
|
|
188
|
+
});
|
|
189
|
+
return {
|
|
190
|
+
relationshipsMoved: (relsSource.rowsAffected ?? 0) + (relsTarget.rowsAffected ?? 0),
|
|
191
|
+
memoriesMoved: mems.rowsAffected ?? 0
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
var EXTRACT_TOOL = {
|
|
195
|
+
name: "extract_entities_and_relationships",
|
|
196
|
+
description: "Extract entities, relationships, and group connections from a memory record. Include confidence scoring.",
|
|
197
|
+
input_schema: {
|
|
198
|
+
type: "object",
|
|
199
|
+
properties: {
|
|
200
|
+
entities: {
|
|
201
|
+
type: "array",
|
|
202
|
+
items: {
|
|
203
|
+
type: "object",
|
|
204
|
+
properties: {
|
|
205
|
+
name: { type: "string", description: "Entity name" },
|
|
206
|
+
type: { type: "string", enum: ["person", "human", "agent", "vendor", "customer", "tool", "software", "hardware", "service", "project", "sprint", "epic", "repo", "decision", "architectural", "operational", "business", "concept", "pattern", "principle", "standard", "file", "rationale", "product", "company", "location", "order", "supplier", "category"] }
|
|
207
|
+
},
|
|
208
|
+
required: ["name", "type"]
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
relationships: {
|
|
212
|
+
type: "array",
|
|
213
|
+
items: {
|
|
214
|
+
type: "object",
|
|
215
|
+
properties: {
|
|
216
|
+
source: { type: "string" },
|
|
217
|
+
source_type: { type: "string" },
|
|
218
|
+
target: { type: "string" },
|
|
219
|
+
target_type: { type: "string" },
|
|
220
|
+
relationship: {
|
|
221
|
+
type: "string",
|
|
222
|
+
enum: [
|
|
223
|
+
// Engineering
|
|
224
|
+
"implemented",
|
|
225
|
+
"superseded_by",
|
|
226
|
+
"depends_on",
|
|
227
|
+
"blocked_by",
|
|
228
|
+
"worked_on",
|
|
229
|
+
"uses",
|
|
230
|
+
"decided",
|
|
231
|
+
"created",
|
|
232
|
+
"fixed",
|
|
233
|
+
"reviewed",
|
|
234
|
+
"rationale_for",
|
|
235
|
+
// Business / organizational
|
|
236
|
+
"supplies",
|
|
237
|
+
"ordered_from",
|
|
238
|
+
"reports_to",
|
|
239
|
+
"manages",
|
|
240
|
+
"located_at",
|
|
241
|
+
"ships_to",
|
|
242
|
+
"categorized_as",
|
|
243
|
+
"priced_at",
|
|
244
|
+
"partnered_with",
|
|
245
|
+
"contracted_by",
|
|
246
|
+
// General purpose
|
|
247
|
+
"related_to",
|
|
248
|
+
"part_of",
|
|
249
|
+
"owns",
|
|
250
|
+
"communicates_with"
|
|
251
|
+
]
|
|
252
|
+
},
|
|
253
|
+
confidence: { type: "number", description: "0.0-1.0. 1.0=explicitly stated, 0.6-0.9=inferred, 0.1-0.3=ambiguous" },
|
|
254
|
+
confidence_label: { type: "string", enum: ["extracted", "inferred", "ambiguous"] }
|
|
255
|
+
},
|
|
256
|
+
required: ["source", "source_type", "target", "target_type", "relationship", "confidence", "confidence_label"]
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
hyperedges: {
|
|
260
|
+
type: "array",
|
|
261
|
+
items: {
|
|
262
|
+
type: "object",
|
|
263
|
+
properties: {
|
|
264
|
+
label: { type: "string", description: "Group label (e.g., 'auth flow files', 'v1.3 contributors')" },
|
|
265
|
+
relation: { type: "string", description: "What connects them (e.g., 'part_of', 'contributed_to')" },
|
|
266
|
+
entity_names: { type: "array", items: { type: "string" }, description: "3+ entity names in this group" },
|
|
267
|
+
confidence: { type: "number" }
|
|
268
|
+
},
|
|
269
|
+
required: ["label", "relation", "entity_names", "confidence"]
|
|
270
|
+
},
|
|
271
|
+
description: "Group relationships connecting 3+ entities"
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
required: ["entities", "relationships", "hyperedges"]
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
var READ_MEMORY_PATH_PATTERN = /^Read\s+(\S+\.(?:ts|tsx|js|jsx))\s*\n/;
|
|
278
|
+
function parseImportPaths(importText) {
|
|
279
|
+
const paths = [];
|
|
280
|
+
const fromRegex = /from\s+["']([^"']+)["']/g;
|
|
281
|
+
let match;
|
|
282
|
+
while ((match = fromRegex.exec(importText)) !== null) {
|
|
283
|
+
paths.push(match[1]);
|
|
284
|
+
}
|
|
285
|
+
const bareRegex = /^import\s+["']([^"']+)["']/gm;
|
|
286
|
+
while ((match = bareRegex.exec(importText)) !== null) {
|
|
287
|
+
if (!paths.includes(match[1])) paths.push(match[1]);
|
|
288
|
+
}
|
|
289
|
+
return paths;
|
|
290
|
+
}
|
|
291
|
+
function moduleNameFromPath(importPath) {
|
|
292
|
+
const base = importPath.split("/").pop() ?? importPath;
|
|
293
|
+
return base.replace(/\.\w+$/, "") || base;
|
|
294
|
+
}
|
|
295
|
+
function extractFromCode(source, filePath) {
|
|
296
|
+
let chunks;
|
|
297
|
+
try {
|
|
298
|
+
chunks = chunkSourceFile(source, filePath);
|
|
299
|
+
} catch {
|
|
300
|
+
return { entities: [], relationships: [], hyperedges: [] };
|
|
301
|
+
}
|
|
302
|
+
if (chunks.length === 0) {
|
|
303
|
+
return { entities: [], relationships: [], hyperedges: [] };
|
|
304
|
+
}
|
|
305
|
+
const entities = [];
|
|
306
|
+
const relationships = [];
|
|
307
|
+
const fileName = filePath.split("/").pop() ?? filePath;
|
|
308
|
+
entities.push({ name: fileName, type: "file" });
|
|
309
|
+
for (const chunk of chunks) {
|
|
310
|
+
if (chunk.kind === "import") {
|
|
311
|
+
const importPaths = parseImportPaths(chunk.text);
|
|
312
|
+
for (const importPath of importPaths) {
|
|
313
|
+
const moduleName = moduleNameFromPath(importPath);
|
|
314
|
+
entities.push({ name: moduleName, type: "file" });
|
|
315
|
+
relationships.push({
|
|
316
|
+
source: fileName,
|
|
317
|
+
sourceType: "file",
|
|
318
|
+
target: moduleName,
|
|
319
|
+
targetType: "file",
|
|
320
|
+
relationship: "depends_on",
|
|
321
|
+
confidence: 1,
|
|
322
|
+
confidenceLabel: "extracted"
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (chunk.kind === "other" || chunk.name === "(unknown)") continue;
|
|
328
|
+
entities.push({ name: chunk.name, type: "concept" });
|
|
329
|
+
relationships.push({
|
|
330
|
+
source: fileName,
|
|
331
|
+
sourceType: "file",
|
|
332
|
+
target: chunk.name,
|
|
333
|
+
targetType: "concept",
|
|
334
|
+
relationship: "uses",
|
|
335
|
+
confidence: 1,
|
|
336
|
+
confidenceLabel: "extracted"
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
return { entities, relationships, hyperedges: [] };
|
|
340
|
+
}
|
|
341
|
+
function pushUniqueEntity(entities, seen, name, type) {
|
|
342
|
+
const normalized = normalizeEntityName(name);
|
|
343
|
+
if (!normalized || normalized.length < 2) return;
|
|
344
|
+
const key = `${normalized.toLowerCase()}::${type.toLowerCase()}`;
|
|
345
|
+
if (seen.has(key)) return;
|
|
346
|
+
seen.add(key);
|
|
347
|
+
entities.push({ name: normalized.slice(0, 160), type });
|
|
348
|
+
}
|
|
349
|
+
function pushHeuristicRelationship(relationships, source, sourceType, target, targetType, relationship, confidence = 0.6) {
|
|
350
|
+
if (!source || !target || source === target) return;
|
|
351
|
+
relationships.push({
|
|
352
|
+
source,
|
|
353
|
+
sourceType,
|
|
354
|
+
target,
|
|
355
|
+
targetType,
|
|
356
|
+
relationship,
|
|
357
|
+
confidence,
|
|
358
|
+
confidenceLabel: "inferred"
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
function extractHeuristicMemoryGraph(content, agentId) {
|
|
362
|
+
const entities = [];
|
|
363
|
+
const relationships = [];
|
|
364
|
+
const seen = /* @__PURE__ */ new Set();
|
|
365
|
+
pushUniqueEntity(entities, seen, agentId, "person");
|
|
366
|
+
const toolMatch = content.match(/^(Bash|Read|Edit|Write|Grep|Glob|AssistantResponse|Tool|Ran|Wrote|Edited):/m);
|
|
367
|
+
if (toolMatch?.[1]) {
|
|
368
|
+
pushUniqueEntity(entities, seen, toolMatch[1], "tool");
|
|
369
|
+
pushHeuristicRelationship(relationships, agentId, "person", toolMatch[1], "tool", "uses", 0.75);
|
|
370
|
+
}
|
|
371
|
+
const repoMatches = [...content.matchAll(/\/Users\/[^/\s]+\/([A-Za-z0-9_.-]+)|\/opt\/([A-Za-z0-9_.-]+)/g)].map((m) => m[1] ?? m[2]).filter((repo) => Boolean(repo)).slice(0, 6);
|
|
372
|
+
for (const repo of repoMatches) {
|
|
373
|
+
pushUniqueEntity(entities, seen, repo, "project");
|
|
374
|
+
pushHeuristicRelationship(relationships, agentId, "person", repo, "project", "worked_on", 0.7);
|
|
375
|
+
}
|
|
376
|
+
const pathMatches = new Set(
|
|
377
|
+
(content.match(/(?:\/[\w .@-]+)+(?:\.[A-Za-z0-9]{1,10})|(?:[\w@.-]+\/)+[\w@.-]+\.(?:ts|tsx|js|jsx|json|md|yml|yaml|sql|py|go|rs|sh|css|html)/g) ?? []).slice(0, 10)
|
|
378
|
+
);
|
|
379
|
+
for (const filePath of pathMatches) {
|
|
380
|
+
pushUniqueEntity(entities, seen, filePath, "file");
|
|
381
|
+
pushHeuristicRelationship(relationships, agentId, "person", filePath, "file", "uses", 0.65);
|
|
382
|
+
}
|
|
383
|
+
const backtickTerms = [...content.matchAll(/`([^`\n]{2,80})`/g)].map((m) => m[1]).slice(0, 10);
|
|
384
|
+
for (const term of backtickTerms) {
|
|
385
|
+
if (!term || term.length < 2) continue;
|
|
386
|
+
const type = term.includes("/") || /\.[A-Za-z0-9]{1,10}$/.test(term) ? "file" : "concept";
|
|
387
|
+
pushUniqueEntity(entities, seen, term, type);
|
|
388
|
+
pushHeuristicRelationship(relationships, agentId, "person", term, type, "uses", 0.55);
|
|
389
|
+
}
|
|
390
|
+
return { entities, relationships, hyperedges: [] };
|
|
391
|
+
}
|
|
392
|
+
async function extractFromMemory(content, agentId, model = "claude-haiku-4-5-20251001", filePath) {
|
|
393
|
+
if (content.length < 50) {
|
|
394
|
+
return { entities: [], relationships: [], hyperedges: [] };
|
|
395
|
+
}
|
|
396
|
+
const lang = filePath ? languageForFile(filePath) : void 0;
|
|
397
|
+
if (filePath && lang && AST_EXTRACTABLE_LANGUAGES.has(lang)) {
|
|
398
|
+
const astResult = extractFromCode(content, filePath);
|
|
399
|
+
if (astResult.entities.length > 0) {
|
|
400
|
+
return astResult;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
try {
|
|
404
|
+
const Anthropic = (await import("@anthropic-ai/sdk")).default;
|
|
405
|
+
const client = new Anthropic();
|
|
406
|
+
const response = await client.messages.create({
|
|
407
|
+
model,
|
|
408
|
+
max_tokens: 512,
|
|
409
|
+
system: `Extract entities and relationships from this AI agent work memory. Agent: ${agentId}. Focus on: people, tools, projects, decisions, files, rationale \u2014 and for business contexts: products, companies, suppliers, locations, orders, categories. Only extract what's clearly stated \u2014 don't infer. Use the simplest form of names (e.g., "Lenny" not "Lenny (HYGO)"). When content says "we chose X because Y", extract a rationale entity with rationale_for edge. Business examples: "Lenny supplies organic flour to HYGO" \u2192 (Lenny, supplies, HYGO). "Order #1234 shipped to Auckland" \u2192 (Order #1234, ships_to, Auckland).`,
|
|
410
|
+
messages: [{ role: "user", content: content.slice(0, GRAPH_EXTRACTION_CONTENT_LIMIT) }],
|
|
411
|
+
tools: [EXTRACT_TOOL],
|
|
412
|
+
tool_choice: { type: "tool", name: "extract_entities_and_relationships" }
|
|
413
|
+
});
|
|
414
|
+
const toolBlock = response.content.find((b) => b.type === "tool_use");
|
|
415
|
+
if (toolBlock && toolBlock.type === "tool_use") {
|
|
416
|
+
const input = toolBlock.input;
|
|
417
|
+
const rawEntities = input.entities ?? [];
|
|
418
|
+
const rawRels = input.relationships ?? [];
|
|
419
|
+
const rawHyperedges = input.hyperedges ?? [];
|
|
420
|
+
return {
|
|
421
|
+
entities: rawEntities.map((e) => ({
|
|
422
|
+
name: e.name ?? "",
|
|
423
|
+
type: e.type ?? "concept"
|
|
424
|
+
})).filter((e) => e.name.length > 0),
|
|
425
|
+
relationships: rawRels.map((r) => ({
|
|
426
|
+
source: r.source ?? "",
|
|
427
|
+
sourceType: r.source_type ?? "concept",
|
|
428
|
+
target: r.target ?? "",
|
|
429
|
+
targetType: r.target_type ?? "concept",
|
|
430
|
+
relationship: r.relationship ?? "uses",
|
|
431
|
+
confidence: Number(r.confidence ?? 1),
|
|
432
|
+
confidenceLabel: String(r.confidence_label ?? "extracted")
|
|
433
|
+
})).filter((r) => r.source.length > 0 && r.target.length > 0),
|
|
434
|
+
hyperedges: rawHyperedges.map((h) => ({
|
|
435
|
+
label: String(h.label ?? ""),
|
|
436
|
+
relation: String(h.relation ?? ""),
|
|
437
|
+
entityNames: h.entity_names ?? [],
|
|
438
|
+
confidence: Number(h.confidence ?? 1)
|
|
439
|
+
})).filter((h) => h.label.length > 0 && h.entityNames.length >= 3)
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
} catch (err) {
|
|
443
|
+
process.stderr.write(
|
|
444
|
+
`[graph-rag] Extraction failed: ${err instanceof Error ? err.message : String(err)}
|
|
445
|
+
`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
return extractHeuristicMemoryGraph(content, agentId);
|
|
449
|
+
}
|
|
450
|
+
async function storeExtraction(client, extraction, memoryId, timestamp) {
|
|
451
|
+
let entitiesStored = 0;
|
|
452
|
+
let relationshipsStored = 0;
|
|
453
|
+
const entitiesHaveParentType = await tableHasColumn(client, "entities", "parent_type");
|
|
454
|
+
const relationshipsHaveValidFrom = await tableHasColumn(client, "relationships", "valid_from");
|
|
455
|
+
const actualEntityIds = /* @__PURE__ */ new Map();
|
|
456
|
+
for (const e of extraction.entities) {
|
|
457
|
+
const aliasTarget = await resolveAlias(client, e.name);
|
|
458
|
+
const resolved = resolveType(e.type);
|
|
459
|
+
const id = aliasTarget ?? entityId(e.name, resolved.type);
|
|
460
|
+
const normalizedName = normalizeEntityName(e.name);
|
|
461
|
+
try {
|
|
462
|
+
const newProps = e.properties ?? {};
|
|
463
|
+
let mergedPropsJson = JSON.stringify(newProps);
|
|
464
|
+
if (newProps.provenance) {
|
|
465
|
+
const existing = await client.execute({
|
|
466
|
+
sql: "SELECT properties FROM entities WHERE id = ?",
|
|
467
|
+
args: [aliasTarget ?? id]
|
|
468
|
+
});
|
|
469
|
+
const existingProps = existing.rows.length > 0 ? JSON.parse(String(existing.rows[0].properties ?? "{}")) : {};
|
|
470
|
+
const existingProvenance = Array.isArray(existingProps.provenance) ? existingProps.provenance : existingProps.provenance ? [existingProps.provenance] : [];
|
|
471
|
+
mergedPropsJson = JSON.stringify({
|
|
472
|
+
...existingProps,
|
|
473
|
+
...newProps,
|
|
474
|
+
provenance: [...existingProvenance, newProps.provenance]
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
if (aliasTarget) {
|
|
478
|
+
await client.execute({
|
|
479
|
+
sql: `UPDATE entities SET last_seen = ?, properties = ? WHERE id = ?`,
|
|
480
|
+
args: [timestamp, mergedPropsJson, aliasTarget]
|
|
481
|
+
});
|
|
482
|
+
} else {
|
|
483
|
+
if (entitiesHaveParentType) {
|
|
484
|
+
await client.execute({
|
|
485
|
+
sql: `INSERT INTO entities (id, name, type, parent_type, first_seen, last_seen, properties)
|
|
486
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
487
|
+
ON CONFLICT(name, type) DO UPDATE SET last_seen = ?, properties = ?,
|
|
488
|
+
parent_type = COALESCE(excluded.parent_type, entities.parent_type)`,
|
|
489
|
+
args: [
|
|
490
|
+
id,
|
|
491
|
+
normalizedName,
|
|
492
|
+
resolved.type,
|
|
493
|
+
resolved.parentType ?? null,
|
|
494
|
+
timestamp,
|
|
495
|
+
timestamp,
|
|
496
|
+
mergedPropsJson,
|
|
497
|
+
timestamp,
|
|
498
|
+
mergedPropsJson
|
|
499
|
+
]
|
|
500
|
+
});
|
|
501
|
+
} else {
|
|
502
|
+
await client.execute({
|
|
503
|
+
sql: `INSERT INTO entities (id, name, type, first_seen, last_seen, properties)
|
|
504
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
505
|
+
ON CONFLICT(name, type) DO UPDATE SET last_seen = ?, properties = ?`,
|
|
506
|
+
args: [
|
|
507
|
+
id,
|
|
508
|
+
normalizedName,
|
|
509
|
+
resolved.type,
|
|
510
|
+
timestamp,
|
|
511
|
+
timestamp,
|
|
512
|
+
mergedPropsJson,
|
|
513
|
+
timestamp,
|
|
514
|
+
mergedPropsJson
|
|
515
|
+
]
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
const actualId = aliasTarget ?? await selectActualEntityId(client, normalizedName, resolved.type, id);
|
|
520
|
+
actualEntityIds.set(`${resolved.type}:${normalizedName}`, actualId);
|
|
521
|
+
await client.execute({
|
|
522
|
+
sql: `INSERT OR IGNORE INTO entity_memories (entity_id, memory_id)
|
|
523
|
+
VALUES (?, ?)`,
|
|
524
|
+
args: [actualId, memoryId]
|
|
525
|
+
});
|
|
526
|
+
entitiesStored++;
|
|
527
|
+
} catch {
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
for (const r of extraction.relationships) {
|
|
531
|
+
const resolvedSourceType = resolveType(r.sourceType);
|
|
532
|
+
const resolvedTargetType = resolveType(r.targetType);
|
|
533
|
+
const normalizedSourceName = normalizeEntityName(r.source);
|
|
534
|
+
const normalizedTargetName = normalizeEntityName(r.target);
|
|
535
|
+
const sourceAlias = await resolveAlias(client, r.source);
|
|
536
|
+
const targetAlias = await resolveAlias(client, r.target);
|
|
537
|
+
const sourceId = sourceAlias ?? entityId(r.source, resolvedSourceType.type);
|
|
538
|
+
const targetId = targetAlias ?? entityId(r.target, resolvedTargetType.type);
|
|
539
|
+
const relId = crypto.randomUUID().slice(0, 16);
|
|
540
|
+
try {
|
|
541
|
+
await client.execute({
|
|
542
|
+
sql: `INSERT OR IGNORE INTO entities (id, name, type, first_seen, last_seen)
|
|
543
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
544
|
+
args: [sourceId, normalizedSourceName, resolvedSourceType.type, timestamp, timestamp]
|
|
545
|
+
});
|
|
546
|
+
await client.execute({
|
|
547
|
+
sql: `INSERT OR IGNORE INTO entities (id, name, type, first_seen, last_seen)
|
|
548
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
549
|
+
args: [targetId, normalizedTargetName, resolvedTargetType.type, timestamp, timestamp]
|
|
550
|
+
});
|
|
551
|
+
const actualSourceId = sourceAlias ?? actualEntityIds.get(`${resolvedSourceType.type}:${normalizedSourceName}`) ?? await selectActualEntityId(client, normalizedSourceName, resolvedSourceType.type, sourceId);
|
|
552
|
+
const actualTargetId = targetAlias ?? actualEntityIds.get(`${resolvedTargetType.type}:${normalizedTargetName}`) ?? await selectActualEntityId(client, normalizedTargetName, resolvedTargetType.type, targetId);
|
|
553
|
+
if (actualSourceId === actualTargetId) continue;
|
|
554
|
+
const relProps = r.properties ?? {};
|
|
555
|
+
let relPropsJson = JSON.stringify(relProps);
|
|
556
|
+
if (relProps.provenance) {
|
|
557
|
+
const existingRels = await client.execute({
|
|
558
|
+
sql: "SELECT properties FROM relationships WHERE source_entity_id = ? AND target_entity_id = ? AND type = ?",
|
|
559
|
+
args: [actualSourceId, actualTargetId, r.relationship]
|
|
560
|
+
});
|
|
561
|
+
const existingRelProps = existingRels.rows.length > 0 ? JSON.parse(String(existingRels.rows[0].properties ?? "{}")) : {};
|
|
562
|
+
const existingProvenance = Array.isArray(existingRelProps.provenance) ? existingRelProps.provenance : existingRelProps.provenance ? [existingRelProps.provenance] : [];
|
|
563
|
+
relPropsJson = JSON.stringify({
|
|
564
|
+
...existingRelProps,
|
|
565
|
+
...relProps,
|
|
566
|
+
provenance: [...existingProvenance, relProps.provenance]
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
if (relationshipsHaveValidFrom) {
|
|
570
|
+
await client.execute({
|
|
571
|
+
sql: `INSERT INTO relationships (id, source_entity_id, target_entity_id, type, weight, timestamp, confidence, confidence_label, properties, valid_from)
|
|
572
|
+
VALUES (?, ?, ?, ?, 1.0, ?, ?, ?, ?, ?)
|
|
573
|
+
ON CONFLICT(source_entity_id, target_entity_id, type)
|
|
574
|
+
DO UPDATE SET weight = MIN(weight + 0.1, 2.0), timestamp = ?,
|
|
575
|
+
confidence = MAX(confidence, ?), confidence_label = ?, properties = ?`,
|
|
576
|
+
args: [
|
|
577
|
+
relId,
|
|
578
|
+
actualSourceId,
|
|
579
|
+
actualTargetId,
|
|
580
|
+
r.relationship,
|
|
581
|
+
timestamp,
|
|
582
|
+
r.confidence,
|
|
583
|
+
r.confidenceLabel,
|
|
584
|
+
relPropsJson,
|
|
585
|
+
timestamp,
|
|
586
|
+
timestamp,
|
|
587
|
+
r.confidence,
|
|
588
|
+
r.confidenceLabel,
|
|
589
|
+
relPropsJson
|
|
590
|
+
]
|
|
591
|
+
});
|
|
592
|
+
} else {
|
|
593
|
+
await client.execute({
|
|
594
|
+
sql: `INSERT INTO relationships (id, source_entity_id, target_entity_id, type, weight, timestamp, confidence, confidence_label, properties)
|
|
595
|
+
VALUES (?, ?, ?, ?, 1.0, ?, ?, ?, ?)
|
|
596
|
+
ON CONFLICT(source_entity_id, target_entity_id, type)
|
|
597
|
+
DO UPDATE SET weight = MIN(weight + 0.1, 2.0), timestamp = ?,
|
|
598
|
+
confidence = MAX(confidence, ?), confidence_label = ?, properties = ?`,
|
|
599
|
+
args: [
|
|
600
|
+
relId,
|
|
601
|
+
actualSourceId,
|
|
602
|
+
actualTargetId,
|
|
603
|
+
r.relationship,
|
|
604
|
+
timestamp,
|
|
605
|
+
r.confidence,
|
|
606
|
+
r.confidenceLabel,
|
|
607
|
+
relPropsJson,
|
|
608
|
+
timestamp,
|
|
609
|
+
r.confidence,
|
|
610
|
+
r.confidenceLabel,
|
|
611
|
+
relPropsJson
|
|
612
|
+
]
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
const existingRel = await client.execute({
|
|
616
|
+
sql: `SELECT id FROM relationships WHERE source_entity_id = ? AND target_entity_id = ? AND type = ?`,
|
|
617
|
+
args: [actualSourceId, actualTargetId, r.relationship]
|
|
618
|
+
});
|
|
619
|
+
const actualRelId = existingRel.rows[0]?.id ? String(existingRel.rows[0].id) : relId;
|
|
620
|
+
await client.execute({
|
|
621
|
+
sql: `INSERT OR IGNORE INTO relationship_memories (relationship_id, memory_id)
|
|
622
|
+
VALUES (?, ?)`,
|
|
623
|
+
args: [actualRelId, memoryId]
|
|
624
|
+
});
|
|
625
|
+
relationshipsStored++;
|
|
626
|
+
} catch {
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
for (const h of extraction.hyperedges) {
|
|
630
|
+
const hId = crypto.randomUUID().slice(0, 16);
|
|
631
|
+
try {
|
|
632
|
+
await client.execute({
|
|
633
|
+
sql: `INSERT OR IGNORE INTO hyperedges (id, label, relation, confidence, timestamp)
|
|
634
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
635
|
+
args: [hId, h.label, h.relation, h.confidence, timestamp]
|
|
636
|
+
});
|
|
637
|
+
for (const entityName of h.entityNames) {
|
|
638
|
+
const rawType = extraction.entities.find((e) => e.name === entityName)?.type ?? "concept";
|
|
639
|
+
const resolvedEType = resolveType(rawType);
|
|
640
|
+
const normalizedEName = normalizeEntityName(entityName);
|
|
641
|
+
const eId = entityId(entityName, resolvedEType.type);
|
|
642
|
+
await client.execute({
|
|
643
|
+
sql: `INSERT OR IGNORE INTO entities (id, name, type, first_seen, last_seen)
|
|
644
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
645
|
+
args: [eId, normalizedEName, resolvedEType.type, timestamp, timestamp]
|
|
646
|
+
});
|
|
647
|
+
const actualEId = actualEntityIds.get(`${resolvedEType.type}:${normalizedEName}`) ?? await selectActualEntityId(client, normalizedEName, resolvedEType.type, eId);
|
|
648
|
+
await client.execute({
|
|
649
|
+
sql: `INSERT OR IGNORE INTO hyperedge_nodes (hyperedge_id, entity_id) VALUES (?, ?)`,
|
|
650
|
+
args: [hId, actualEId]
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
} catch {
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return { entitiesStored, relationshipsStored };
|
|
657
|
+
}
|
|
658
|
+
async function extractBatch(client, batchSize = 50, model = "claude-haiku-4-5-20251001") {
|
|
659
|
+
const result = await client.execute({
|
|
660
|
+
sql: `SELECT id, agent_id, raw_text, tool_name, timestamp, content_hash, graph_extracted_hash
|
|
661
|
+
FROM memories
|
|
662
|
+
WHERE (COALESCE(graph_extracted, 0) = 0
|
|
663
|
+
OR (content_hash IS NOT NULL AND content_hash != COALESCE(graph_extracted_hash, '')))
|
|
664
|
+
AND COALESCE(status, 'active') = 'active'
|
|
665
|
+
AND LENGTH(raw_text) >= 50
|
|
666
|
+
ORDER BY timestamp DESC
|
|
667
|
+
LIMIT ?`,
|
|
668
|
+
args: [batchSize]
|
|
669
|
+
});
|
|
670
|
+
if (result.rows.length === 0) {
|
|
671
|
+
return { processed: 0, entities: 0, relationships: 0 };
|
|
672
|
+
}
|
|
673
|
+
let totalEntities = 0;
|
|
674
|
+
let totalRelationships = 0;
|
|
675
|
+
for (const row of result.rows) {
|
|
676
|
+
const memoryId = String(row.id);
|
|
677
|
+
const agentId = String(row.agent_id);
|
|
678
|
+
const rawContent = String(row.raw_text);
|
|
679
|
+
const toolName = String(row.tool_name ?? "");
|
|
680
|
+
const timestamp = String(row.timestamp);
|
|
681
|
+
let extractionContent = rawContent;
|
|
682
|
+
let detectedFilePath;
|
|
683
|
+
if (toolName === "Read") {
|
|
684
|
+
const pathMatch = rawContent.match(READ_MEMORY_PATH_PATTERN);
|
|
685
|
+
if (pathMatch) {
|
|
686
|
+
detectedFilePath = pathMatch[1];
|
|
687
|
+
extractionContent = rawContent.slice(pathMatch[0].length);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
try {
|
|
691
|
+
const extraction = await extractFromMemory(extractionContent, agentId, model, detectedFilePath);
|
|
692
|
+
if (extraction.entities.length > 0 || extraction.relationships.length > 0) {
|
|
693
|
+
const stored = await storeExtraction(client, extraction, memoryId, timestamp);
|
|
694
|
+
totalEntities += stored.entitiesStored;
|
|
695
|
+
totalRelationships += stored.relationshipsStored;
|
|
696
|
+
}
|
|
697
|
+
const contentHash = crypto.createHash("sha256").update(rawContent).digest("hex").slice(0, 32);
|
|
698
|
+
await client.execute({
|
|
699
|
+
sql: "UPDATE memories SET graph_extracted = 1, content_hash = ?, graph_extracted_hash = ? WHERE id = ?",
|
|
700
|
+
args: [contentHash, contentHash, memoryId]
|
|
701
|
+
});
|
|
702
|
+
} catch (err) {
|
|
703
|
+
process.stderr.write(
|
|
704
|
+
`[graph-rag] Batch extraction failed for ${memoryId}: ${err instanceof Error ? err.message : String(err)}
|
|
705
|
+
`
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return { processed: result.rows.length, entities: totalEntities, relationships: totalRelationships };
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
export {
|
|
713
|
+
ENTITY_TYPES,
|
|
714
|
+
RELATIONSHIP_TYPES,
|
|
715
|
+
normalizeEntityName,
|
|
716
|
+
entityId,
|
|
717
|
+
resolveAlias,
|
|
718
|
+
registerAlias,
|
|
719
|
+
cleanupGraphLinksForMemories,
|
|
720
|
+
mergeEntities,
|
|
721
|
+
EXTRACT_TOOL,
|
|
722
|
+
extractFromCode,
|
|
723
|
+
extractHeuristicMemoryGraph,
|
|
724
|
+
extractFromMemory,
|
|
725
|
+
storeExtraction,
|
|
726
|
+
extractBatch
|
|
727
|
+
};
|