opensentinel 3.1.1 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -83
- package/dist/agent-manager-JZ4IM7XI.js +39 -0
- package/dist/agent-processor-DDDHC2SO.js +281 -0
- package/dist/agent-processor-DDDHC2SO.js.map +1 -0
- package/dist/agent-types-2T4PXLFQ.js +12 -0
- package/dist/alerting-LK7VVYTX.js +699 -0
- package/dist/alerting-LK7VVYTX.js.map +1 -0
- package/dist/analysis-agent-JWN2GXYE.js +288 -0
- package/dist/analysis-agent-JWN2GXYE.js.map +1 -0
- package/dist/analyzer-OTWE3ARE.js +22 -0
- package/dist/{archiver-AVNBYCKQ.js → archiver-FPGKRP6P.js} +2 -2
- package/dist/{audit-logger-OBPR7CRO.js → audit-logger-CI4WZQPD.js} +6 -5
- package/dist/{auth-UOX5K2BE.js → auth-PH5IHISW.js} +2 -2
- package/dist/{autonomy-ZXDBDQUJ.js → autonomy-N7W5XPLX.js} +4 -3
- package/dist/autonomy-N7W5XPLX.js.map +1 -0
- package/dist/{aws-s3-Q4LLZZPD.js → aws-s3-QZMURYXB.js} +2 -2
- package/dist/{backup-restore-PZ7CYYB7.js → backup-restore-72OQTZO3.js} +2 -2
- package/dist/{blocks-R3PODY47.js → blocks-YOWOESDD.js} +4 -4
- package/dist/bot-VDHBGUVI.js +47 -0
- package/dist/brain-6QTXN4QP.js +66 -0
- package/dist/{camera-monitor-M5CYKUU4.js → camera-monitor-LHTUWHEL.js} +2 -2
- package/dist/{charts-V7ARZNKF.js → charts-FJ32GQK7.js} +2 -2
- package/dist/{chunk-WRAKK6K6.js → chunk-2I5QHYG6.js} +5 -3
- package/dist/chunk-2I5QHYG6.js.map +1 -0
- package/dist/{chunk-TVEWKIK3.js → chunk-2WTKTG2C.js} +2 -2
- package/dist/chunk-3AWAWRWB.js +143 -0
- package/dist/chunk-3AWAWRWB.js.map +1 -0
- package/dist/{chunk-ZLZKF2PM.js → chunk-4KIHDIXZ.js} +43 -2
- package/dist/chunk-4KIHDIXZ.js.map +1 -0
- package/dist/{chunk-EVE7MIIY.js → chunk-4WH6MFEW.js} +15 -16
- package/dist/chunk-4WH6MFEW.js.map +1 -0
- package/dist/{chunk-I6BDYQIG.js → chunk-56UJS2LA.js} +6 -6
- package/dist/chunk-56UJS2LA.js.map +1 -0
- package/dist/chunk-5BTVJR7R.js +37 -0
- package/dist/chunk-5BTVJR7R.js.map +1 -0
- package/dist/chunk-5JJTLWOR.js +1021 -0
- package/dist/chunk-5JJTLWOR.js.map +1 -0
- package/dist/chunk-66SAOZPU.js +236 -0
- package/dist/chunk-66SAOZPU.js.map +1 -0
- package/dist/chunk-6HGMRR4J.js +113 -0
- package/dist/chunk-6HGMRR4J.js.map +1 -0
- package/dist/chunk-6W6PTJFT.js +181 -0
- package/dist/chunk-6W6PTJFT.js.map +1 -0
- package/dist/chunk-6ZNCY2GI.js +418 -0
- package/dist/chunk-6ZNCY2GI.js.map +1 -0
- package/dist/chunk-7BNFELEK.js +31 -0
- package/dist/chunk-7BNFELEK.js.map +1 -0
- package/dist/chunk-ADTDYJO7.js +265 -0
- package/dist/chunk-ADTDYJO7.js.map +1 -0
- package/dist/{chunk-OCVQGBJK.js → chunk-BBN4VCNK.js} +6 -4
- package/dist/chunk-BBN4VCNK.js.map +1 -0
- package/dist/{chunk-SJSUSJ47.js → chunk-BNZHWAZC.js} +2 -2
- package/dist/chunk-C6PELIHS.js +60 -0
- package/dist/chunk-C6PELIHS.js.map +1 -0
- package/dist/{chunk-MQJ2ECQT.js → chunk-CUPEENUY.js} +3 -3
- package/dist/{chunk-NHMBTUMW.js → chunk-CWT6CAE5.js} +2 -2
- package/dist/{chunk-4GLYY4NN.js → chunk-CZTMGHUC.js} +8 -2
- package/dist/chunk-CZTMGHUC.js.map +1 -0
- package/dist/{chunk-RZ4YESBG.js → chunk-DOYGMNMK.js} +1 -1
- package/dist/chunk-DOYGMNMK.js.map +1 -0
- package/dist/chunk-DTISLIMB.js +89 -0
- package/dist/chunk-DTISLIMB.js.map +1 -0
- package/dist/{chunk-SPPMCAKG.js → chunk-GBVJTRXS.js} +2 -2
- package/dist/chunk-GBVJTRXS.js.map +1 -0
- package/dist/{chunk-AYUKPTSM.js → chunk-GJETKBOY.js} +96 -218
- package/dist/chunk-GJETKBOY.js.map +1 -0
- package/dist/{chunk-BXZ6EA52.js → chunk-GW6V4D43.js} +57 -3
- package/dist/chunk-GW6V4D43.js.map +1 -0
- package/dist/{chunk-6PMVAAA7.js → chunk-HJSEEFO3.js} +3 -3
- package/dist/{chunk-TYAGMJNV.js → chunk-HQZQFEAX.js} +5 -5
- package/dist/{chunk-MXAPLSJ5.js → chunk-J4JW73TT.js} +2 -2
- package/dist/{chunk-VEHFVBLI.js → chunk-JHYYFPKX.js} +2 -2
- package/dist/chunk-LFDXEYYB.js +150 -0
- package/dist/chunk-LFDXEYYB.js.map +1 -0
- package/dist/chunk-MIC5IBQF.js +386 -0
- package/dist/chunk-MIC5IBQF.js.map +1 -0
- package/dist/chunk-ODCFS5WD.js +463 -0
- package/dist/chunk-ODCFS5WD.js.map +1 -0
- package/dist/{chunk-XMCVRVTF.js → chunk-P64EV4YY.js} +1 -1
- package/dist/chunk-P64EV4YY.js.map +1 -0
- package/dist/chunk-PBOCSGNL.js +84 -0
- package/dist/chunk-PBOCSGNL.js.map +1 -0
- package/dist/{chunk-66OJ3WB4.js → chunk-PD3CTDO6.js} +2 -2
- package/dist/chunk-QPY3WRVM.js +647 -0
- package/dist/chunk-QPY3WRVM.js.map +1 -0
- package/dist/chunk-S2EOIVF4.js +3907 -0
- package/dist/chunk-S2EOIVF4.js.map +1 -0
- package/dist/chunk-SDLOMKCW.js +213 -0
- package/dist/chunk-SDLOMKCW.js.map +1 -0
- package/dist/chunk-TKBVW7ZJ.js +162 -0
- package/dist/chunk-TKBVW7ZJ.js.map +1 -0
- package/dist/{chunk-BRBWNV65.js → chunk-U2X2J3FI.js} +3 -3
- package/dist/chunk-U2X2J3FI.js.map +1 -0
- package/dist/{chunk-PLDDJCW6.js → chunk-UP2VWCW5.js} +1 -12
- package/dist/{chunk-SVAPX2XN.js → chunk-V3OKHQUX.js} +9 -7
- package/dist/{chunk-SVAPX2XN.js.map → chunk-V3OKHQUX.js.map} +1 -1
- package/dist/{chunk-4UOE5TUZ.js → chunk-WMDVOWN6.js} +4 -4
- package/dist/chunk-WMFYI7XC.js +564 -0
- package/dist/chunk-WMFYI7XC.js.map +1 -0
- package/dist/chunk-WZAH34TG.js +129 -0
- package/dist/chunk-WZAH34TG.js.map +1 -0
- package/dist/{chunk-H5RQOFO2.js → chunk-X6Q3K3L2.js} +6 -6
- package/dist/chunk-X6Q3K3L2.js.map +1 -0
- package/dist/chunk-XTX7EK43.js +134 -0
- package/dist/chunk-XTX7EK43.js.map +1 -0
- package/dist/chunk-YEDEAX6Y.js +194 -0
- package/dist/chunk-YEDEAX6Y.js.map +1 -0
- package/dist/{chunk-XKYRH4FM.js → chunk-ZIBRVA3Y.js} +70 -30
- package/dist/chunk-ZIBRVA3Y.js.map +1 -0
- package/dist/chunk-ZIYTHUM5.js +457 -0
- package/dist/chunk-ZIYTHUM5.js.map +1 -0
- package/dist/{chunk-766ASQWE.js → chunk-ZMML6T63.js} +2711 -2329
- package/dist/chunk-ZMML6T63.js.map +1 -0
- package/dist/chunk-ZVHG4KF2.js +380 -0
- package/dist/chunk-ZVHG4KF2.js.map +1 -0
- package/dist/chunker-K6WTR62A.js +12 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{client-ZQSFPMOB.js → client-FOIYPOZQ.js} +5 -6
- package/dist/{clipboard-manager-TEO2GEDN.js → clipboard-manager-4SBNESGZ.js} +2 -2
- package/dist/coding-agent-DESSU3AC.js +233 -0
- package/dist/coding-agent-DESSU3AC.js.map +1 -0
- package/dist/commands/setup.js +2 -2
- package/dist/commands/start.js +3 -3
- package/dist/commands/status.js +2 -2
- package/dist/commands/stop.js +2 -2
- package/dist/commands/utils.js +2 -2
- package/dist/cost-tracker-KZQSTSE2.js +11 -0
- package/dist/{cron-explain-HHQKPD3M.js → cron-explain-UOOOYWZZ.js} +2 -2
- package/dist/{crypto-4AP47IKC.js → crypto-2VG3RJR2.js} +2 -2
- package/dist/{databases-37X4CI2Y.js → databases-XDPMG5AV.js} +4 -4
- package/dist/db-I7MNG6CL.js +83 -0
- package/dist/discord-6UQHCN27.js +81 -0
- package/dist/documents-PFHSK7SZ.js +184 -0
- package/dist/documents-PFHSK7SZ.js.map +1 -0
- package/dist/docx-parser-EXL4TN5E.js +16 -0
- package/dist/{email-K7LO2IPB.js → email-6OIN4SYL.js} +34 -25
- package/dist/email-6OIN4SYL.js.map +1 -0
- package/dist/{enhanced-retrieval-DNLLEM4Z.js → enhanced-retrieval-JWX2HWU4.js} +12 -8
- package/dist/{enhanced-retrieval-DNLLEM4Z.js.map → enhanced-retrieval-JWX2HWU4.js.map} +1 -1
- package/dist/enrichment-pipeline-7FE5R5ZI.js +14 -0
- package/dist/{entity-resolution-Y3IUWEAT.js → entity-resolution-7Z6STVXX.js} +6 -5
- package/dist/env-GN5VHI43.js +12 -0
- package/dist/error-tracker-64DEH3D7.js +32 -0
- package/dist/finnhub-X7ZMQSXF.js +178 -0
- package/dist/finnhub-X7ZMQSXF.js.map +1 -0
- package/dist/fred-TMUF3J2V.js +203 -0
- package/dist/fred-TMUF3J2V.js.map +1 -0
- package/dist/github-DUWSXCNP.js +833 -0
- package/dist/github-DUWSXCNP.js.map +1 -0
- package/dist/{google-workspace-DKWUVNGC.js → google-workspace-TSZPZK5G.js} +2 -2
- package/dist/graph-client-NB475AK5.js +17 -0
- package/dist/{hash-tool-ULQYD7B5.js → hash-tool-ENAB5LWH.js} +2 -2
- package/dist/{heartbeat-monitor-GCISLXI3.js → heartbeat-monitor-KRDYTDBF.js} +2 -2
- package/dist/hooks-N4MIFBVM.js +14 -0
- package/dist/{image-generation-OSU7FP6F.js → image-generation-MDE6AVQO.js} +2 -2
- package/dist/imessage-DSGSGUZS.js +44 -0
- package/dist/inbox-summarizer-F2KAU72V.js +56 -0
- package/dist/{incident-response-C5J7Q6DT.js → incident-response-E3UGMX5G.js} +8 -6
- package/dist/incident-response-E3UGMX5G.js.map +1 -0
- package/dist/{inventory-manager-352OHXWD.js → inventory-manager-C67BSZM6.js} +2 -2
- package/dist/{jira-GSGDBMIG.js → jira-PAGZWUBJ.js} +2 -2
- package/dist/{json-tool-QE2SYHEG.js → json-tool-4FK5RNER.js} +2 -2
- package/dist/{key-rotation-DPHU4ZTB.js → key-rotation-WCC5FOYS.js} +2 -2
- package/dist/knowledge-base-5SMMOGQJ.js +46 -0
- package/dist/lib.d.ts +94 -1
- package/dist/lib.js +83 -66
- package/dist/lib.js.map +1 -1
- package/dist/{mailchimp-KKNF6QJ7.js → mailchimp-ZFYDC44J.js} +2 -2
- package/dist/{matrix-QVHG76I7.js → matrix-WYGEOZL5.js} +30 -21
- package/dist/{matrix-QVHG76I7.js.map → matrix-WYGEOZL5.js.map} +1 -1
- package/dist/{mcp-3JI6W7ZE.js → mcp-DJ2QDA6A.js} +3 -3
- package/dist/metrics-BH3ZLGEV.js +25 -0
- package/dist/{microsoft365-UCBKJHNX.js → microsoft365-6G2IJMWC.js} +2 -2
- package/dist/multi-user-XAEMB244.js +411 -0
- package/dist/multi-user-XAEMB244.js.map +1 -0
- package/dist/oauth-UPJYFOVU.js +34 -0
- package/dist/{ocr-AC7NPX33.js → ocr-UONKTQU7.js} +6 -4
- package/dist/{ollama-BOAMSPLJ.js → ollama-J7CU45WT.js} +2 -2
- package/dist/osint-agent-RL5XPBRQ.js +189 -0
- package/dist/osint-agent-RL5XPBRQ.js.map +1 -0
- package/dist/{pages-MI523RB7.js → pages-XDE7JRCA.js} +5 -5
- package/dist/{pair-JDFTERIK.js → pair-YZJFQUU5.js} +2 -2
- package/dist/{pairing-IFQYCPNS.js → pairing-77N47RAT.js} +2 -2
- package/dist/{pdf-ALQVOEJR.js → pdf-67HGXCFJ.js} +3 -3
- package/dist/pdf-parser-YLMTTYHL.js +14 -0
- package/dist/{presentations-DSV5IHG5.js → presentations-UOET2FVZ.js} +3 -3
- package/dist/presentations-UOET2FVZ.js.map +1 -0
- package/dist/{prometheus-JNT2BD4L.js → prometheus-YETCZO4I.js} +2 -2
- package/dist/prometheus-YETCZO4I.js.map +1 -0
- package/dist/{providers-J4LYPHDR.js → providers-2YQ6E3IF.js} +6 -4
- package/dist/providers-2YQ6E3IF.js.map +1 -0
- package/dist/{qr-code-WIX4PB4U.js → qr-code-6WZJHRKL.js} +2 -2
- package/dist/qr-code-6WZJHRKL.js.map +1 -0
- package/dist/{quickbooks-XB4NII2S.js → quickbooks-N675W7IK.js} +2 -2
- package/dist/{regex-tool-W4ABRKGK.js → regex-tool-6Q63LQ7B.js} +2 -2
- package/dist/regex-tool-6Q63LQ7B.js.map +1 -0
- package/dist/research-agent-WCRSY3UZ.js +168 -0
- package/dist/research-agent-WCRSY3UZ.js.map +1 -0
- package/dist/risk-engine-YKCPT5D5.js +10 -0
- package/dist/risk-engine-YKCPT5D5.js.map +1 -0
- package/dist/scheduler-6PLLAQI7.js +74 -0
- package/dist/scheduler-6PLLAQI7.js.map +1 -0
- package/dist/schema-ETY7L2VA.js +78 -0
- package/dist/schema-ETY7L2VA.js.map +1 -0
- package/dist/{search-BCLBO5E3.js → search-GMLKBHSW.js} +4 -4
- package/dist/search-GMLKBHSW.js.map +1 -0
- package/dist/{sendgrid-RNXCAFKM.js → sendgrid-QGJIVPWV.js} +2 -2
- package/dist/sharepoint-V5P4Q62L.js +30 -0
- package/dist/sharepoint-V5P4Q62L.js.map +1 -0
- package/dist/{shopify-NCXYJB4R.js → shopify-ON2PAU27.js} +2 -2
- package/dist/signal-7D5EPGVL.js +44 -0
- package/dist/signal-7D5EPGVL.js.map +1 -0
- package/dist/slack-KSS6YK5Z.js +86 -0
- package/dist/slack-KSS6YK5Z.js.map +1 -0
- package/dist/{sms-M3JIOTCW.js → sms-CSUCC7HL.js} +4 -4
- package/dist/sms-CSUCC7HL.js.map +1 -0
- package/dist/{src-VYUE6LRA.js → src-GO7GGW7O.js} +190 -52
- package/dist/src-GO7GGW7O.js.map +1 -0
- package/dist/{stocks-XXWBPOCU.js → stocks-4M4HZWZS.js} +2 -2
- package/dist/stocks-4M4HZWZS.js.map +1 -0
- package/dist/text-extractor-OAUBAW5P.js +12 -0
- package/dist/text-extractor-OAUBAW5P.js.map +1 -0
- package/dist/{text-transform-6SGUA5Z4.js → text-transform-HCLCUDFZ.js} +2 -2
- package/dist/text-transform-HCLCUDFZ.js.map +1 -0
- package/dist/token-store-SEWRX6RE.js +20 -0
- package/dist/token-store-SEWRX6RE.js.map +1 -0
- package/dist/tools-PJZ6RI4P.js +47 -0
- package/dist/tools-PJZ6RI4P.js.map +1 -0
- package/dist/{tunnel-IWMXUML4.js → tunnel-XOUVVRAK.js} +4 -2
- package/dist/tunnel-XOUVVRAK.js.map +1 -0
- package/dist/{twilio-53GEW5JT.js → twilio-3L7DUNYQ.js} +2 -2
- package/dist/{unit-converter-ZYXMEZOE.js → unit-converter-LYPAHU64.js} +2 -2
- package/dist/unit-converter-LYPAHU64.js.map +1 -0
- package/dist/whatsapp-DWXK25V2.js +44 -0
- package/dist/whatsapp-DWXK25V2.js.map +1 -0
- package/dist/{word-document-7B6SJMAY.js → word-document-AV3YB4L2.js} +4 -4
- package/dist/word-document-AV3YB4L2.js.map +1 -0
- package/dist/workflow-store-5Y56GUP7.js +373 -0
- package/dist/workflow-store-5Y56GUP7.js.map +1 -0
- package/dist/writing-agent-VDGLNOGO.js +243 -0
- package/dist/writing-agent-VDGLNOGO.js.map +1 -0
- package/dist/{xero-QYO66D45.js → xero-UHAHVYSD.js} +2 -2
- package/dist/{zapier-webhook-TBZ5YF2A.js → zapier-webhook-NIELLTXR.js} +2 -2
- package/drizzle/0002_mushy_master_mold.sql +139 -139
- package/drizzle/0003_overjoyed_rhodey.sql +46 -0
- package/drizzle/meta/0002_snapshot.json +3636 -3636
- package/drizzle/meta/0003_snapshot.json +3946 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +110 -100
- package/dist/autonomy-ZXDBDQUJ.js.map +0 -1
- package/dist/bot-QRARP4UN.js +0 -36
- package/dist/brain-7XLLM3KC.js +0 -56
- package/dist/chunk-4GLYY4NN.js.map +0 -1
- package/dist/chunk-766ASQWE.js.map +0 -1
- package/dist/chunk-AYUKPTSM.js.map +0 -1
- package/dist/chunk-BRBWNV65.js.map +0 -1
- package/dist/chunk-BXZ6EA52.js.map +0 -1
- package/dist/chunk-EVE7MIIY.js.map +0 -1
- package/dist/chunk-H5RQOFO2.js.map +0 -1
- package/dist/chunk-I6BDYQIG.js.map +0 -1
- package/dist/chunk-IZJMVV7O.js +0 -347
- package/dist/chunk-IZJMVV7O.js.map +0 -1
- package/dist/chunk-O7IH7JTI.js +0 -1898
- package/dist/chunk-O7IH7JTI.js.map +0 -1
- package/dist/chunk-OCVQGBJK.js.map +0 -1
- package/dist/chunk-RZ4YESBG.js.map +0 -1
- package/dist/chunk-SPPMCAKG.js.map +0 -1
- package/dist/chunk-VRD5CYRL.js +0 -1568
- package/dist/chunk-VRD5CYRL.js.map +0 -1
- package/dist/chunk-WRAKK6K6.js.map +0 -1
- package/dist/chunk-XKYRH4FM.js.map +0 -1
- package/dist/chunk-XMCVRVTF.js.map +0 -1
- package/dist/chunk-ZLZKF2PM.js.map +0 -1
- package/dist/discord-B3HUPGQ6.js +0 -70
- package/dist/dist-UISMLMFN.js +0 -21847
- package/dist/dist-UISMLMFN.js.map +0 -1
- package/dist/email-K7LO2IPB.js.map +0 -1
- package/dist/enrichment-pipeline-MNHNW65K.js +0 -13
- package/dist/env-IWXUVTCB.js +0 -12
- package/dist/imessage-NGA2XF2V.js +0 -35
- package/dist/inbox-summarizer-NRI4S7IF.js +0 -47
- package/dist/incident-response-C5J7Q6DT.js.map +0 -1
- package/dist/presentations-DSV5IHG5.js.map +0 -1
- package/dist/scheduler-VK4WFERV.js +0 -63
- package/dist/signal-6CGDFYL2.js +0 -35
- package/dist/slack-IZQWIKOH.js +0 -75
- package/dist/src-VYUE6LRA.js.map +0 -1
- package/dist/tools-2RLEI2N6.js +0 -38
- package/dist/tunnel-IWMXUML4.js.map +0 -1
- package/dist/whatsapp-LFX6YKCM.js +0 -35
- package/dist/word-document-7B6SJMAY.js.map +0 -1
- /package/dist/{audit-logger-OBPR7CRO.js.map → agent-manager-JZ4IM7XI.js.map} +0 -0
- /package/dist/{auth-UOX5K2BE.js.map → agent-types-2T4PXLFQ.js.map} +0 -0
- /package/dist/{backup-restore-PZ7CYYB7.js.map → analyzer-OTWE3ARE.js.map} +0 -0
- /package/dist/{archiver-AVNBYCKQ.js.map → archiver-FPGKRP6P.js.map} +0 -0
- /package/dist/{blocks-R3PODY47.js.map → audit-logger-CI4WZQPD.js.map} +0 -0
- /package/dist/{bot-QRARP4UN.js.map → auth-PH5IHISW.js.map} +0 -0
- /package/dist/{aws-s3-Q4LLZZPD.js.map → aws-s3-QZMURYXB.js.map} +0 -0
- /package/dist/{brain-7XLLM3KC.js.map → backup-restore-72OQTZO3.js.map} +0 -0
- /package/dist/{chunk-PLDDJCW6.js.map → blocks-YOWOESDD.js.map} +0 -0
- /package/dist/{client-ZQSFPMOB.js.map → bot-VDHBGUVI.js.map} +0 -0
- /package/dist/{clipboard-manager-TEO2GEDN.js.map → brain-6QTXN4QP.js.map} +0 -0
- /package/dist/{camera-monitor-M5CYKUU4.js.map → camera-monitor-LHTUWHEL.js.map} +0 -0
- /package/dist/{charts-V7ARZNKF.js.map → charts-FJ32GQK7.js.map} +0 -0
- /package/dist/{chunk-TVEWKIK3.js.map → chunk-2WTKTG2C.js.map} +0 -0
- /package/dist/{chunk-SJSUSJ47.js.map → chunk-BNZHWAZC.js.map} +0 -0
- /package/dist/{chunk-MQJ2ECQT.js.map → chunk-CUPEENUY.js.map} +0 -0
- /package/dist/{chunk-NHMBTUMW.js.map → chunk-CWT6CAE5.js.map} +0 -0
- /package/dist/{chunk-6PMVAAA7.js.map → chunk-HJSEEFO3.js.map} +0 -0
- /package/dist/{chunk-TYAGMJNV.js.map → chunk-HQZQFEAX.js.map} +0 -0
- /package/dist/{chunk-MXAPLSJ5.js.map → chunk-J4JW73TT.js.map} +0 -0
- /package/dist/{chunk-VEHFVBLI.js.map → chunk-JHYYFPKX.js.map} +0 -0
- /package/dist/{chunk-66OJ3WB4.js.map → chunk-PD3CTDO6.js.map} +0 -0
- /package/dist/{cron-explain-HHQKPD3M.js.map → chunk-UP2VWCW5.js.map} +0 -0
- /package/dist/{chunk-4UOE5TUZ.js.map → chunk-WMDVOWN6.js.map} +0 -0
- /package/dist/{crypto-4AP47IKC.js.map → chunker-K6WTR62A.js.map} +0 -0
- /package/dist/{databases-37X4CI2Y.js.map → client-FOIYPOZQ.js.map} +0 -0
- /package/dist/{discord-B3HUPGQ6.js.map → clipboard-manager-4SBNESGZ.js.map} +0 -0
- /package/dist/{enrichment-pipeline-MNHNW65K.js.map → cost-tracker-KZQSTSE2.js.map} +0 -0
- /package/dist/{entity-resolution-Y3IUWEAT.js.map → cron-explain-UOOOYWZZ.js.map} +0 -0
- /package/dist/{env-IWXUVTCB.js.map → crypto-2VG3RJR2.js.map} +0 -0
- /package/dist/{hash-tool-ULQYD7B5.js.map → databases-XDPMG5AV.js.map} +0 -0
- /package/dist/{heartbeat-monitor-GCISLXI3.js.map → db-I7MNG6CL.js.map} +0 -0
- /package/dist/{imessage-NGA2XF2V.js.map → discord-6UQHCN27.js.map} +0 -0
- /package/dist/{inbox-summarizer-NRI4S7IF.js.map → docx-parser-EXL4TN5E.js.map} +0 -0
- /package/dist/{inventory-manager-352OHXWD.js.map → enrichment-pipeline-7FE5R5ZI.js.map} +0 -0
- /package/dist/{json-tool-QE2SYHEG.js.map → entity-resolution-7Z6STVXX.js.map} +0 -0
- /package/dist/{key-rotation-DPHU4ZTB.js.map → env-GN5VHI43.js.map} +0 -0
- /package/dist/{mcp-3JI6W7ZE.js.map → error-tracker-64DEH3D7.js.map} +0 -0
- /package/dist/{google-workspace-DKWUVNGC.js.map → google-workspace-TSZPZK5G.js.map} +0 -0
- /package/dist/{ocr-AC7NPX33.js.map → graph-client-NB475AK5.js.map} +0 -0
- /package/dist/{ollama-BOAMSPLJ.js.map → hash-tool-ENAB5LWH.js.map} +0 -0
- /package/dist/{pages-MI523RB7.js.map → heartbeat-monitor-KRDYTDBF.js.map} +0 -0
- /package/dist/{pairing-IFQYCPNS.js.map → hooks-N4MIFBVM.js.map} +0 -0
- /package/dist/{image-generation-OSU7FP6F.js.map → image-generation-MDE6AVQO.js.map} +0 -0
- /package/dist/{pdf-ALQVOEJR.js.map → imessage-DSGSGUZS.js.map} +0 -0
- /package/dist/{prometheus-JNT2BD4L.js.map → inbox-summarizer-F2KAU72V.js.map} +0 -0
- /package/dist/{providers-J4LYPHDR.js.map → inventory-manager-C67BSZM6.js.map} +0 -0
- /package/dist/{jira-GSGDBMIG.js.map → jira-PAGZWUBJ.js.map} +0 -0
- /package/dist/{qr-code-WIX4PB4U.js.map → json-tool-4FK5RNER.js.map} +0 -0
- /package/dist/{regex-tool-W4ABRKGK.js.map → key-rotation-WCC5FOYS.js.map} +0 -0
- /package/dist/{scheduler-VK4WFERV.js.map → knowledge-base-5SMMOGQJ.js.map} +0 -0
- /package/dist/{mailchimp-KKNF6QJ7.js.map → mailchimp-ZFYDC44J.js.map} +0 -0
- /package/dist/{search-BCLBO5E3.js.map → mcp-DJ2QDA6A.js.map} +0 -0
- /package/dist/{signal-6CGDFYL2.js.map → metrics-BH3ZLGEV.js.map} +0 -0
- /package/dist/{microsoft365-UCBKJHNX.js.map → microsoft365-6G2IJMWC.js.map} +0 -0
- /package/dist/{slack-IZQWIKOH.js.map → oauth-UPJYFOVU.js.map} +0 -0
- /package/dist/{sms-M3JIOTCW.js.map → ocr-UONKTQU7.js.map} +0 -0
- /package/dist/{stocks-XXWBPOCU.js.map → ollama-J7CU45WT.js.map} +0 -0
- /package/dist/{text-transform-6SGUA5Z4.js.map → pages-XDE7JRCA.js.map} +0 -0
- /package/dist/{pair-JDFTERIK.js.map → pair-YZJFQUU5.js.map} +0 -0
- /package/dist/{tools-2RLEI2N6.js.map → pairing-77N47RAT.js.map} +0 -0
- /package/dist/{unit-converter-ZYXMEZOE.js.map → pdf-67HGXCFJ.js.map} +0 -0
- /package/dist/{whatsapp-LFX6YKCM.js.map → pdf-parser-YLMTTYHL.js.map} +0 -0
- /package/dist/{quickbooks-XB4NII2S.js.map → quickbooks-N675W7IK.js.map} +0 -0
- /package/dist/{sendgrid-RNXCAFKM.js.map → sendgrid-QGJIVPWV.js.map} +0 -0
- /package/dist/{shopify-NCXYJB4R.js.map → shopify-ON2PAU27.js.map} +0 -0
- /package/dist/{twilio-53GEW5JT.js.map → twilio-3L7DUNYQ.js.map} +0 -0
- /package/dist/{xero-QYO66D45.js.map → xero-UHAHVYSD.js.map} +0 -0
- /package/dist/{zapier-webhook-TBZ5YF2A.js.map → zapier-webhook-NIELLTXR.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/brain/router.ts","../src/core/observability/cost-tracker.ts"],"sourcesContent":["// ============================================\n// Model Router — Route messages to optimal Claude model\n// ============================================\n// Routes simple queries to Haiku (fast/cheap), standard to Sonnet,\n// and complex reasoning to Opus when enabled. Saves 60-80% cost\n// on simple queries per SkillsBench research.\n\nexport type ModelTier = \"fast\" | \"balanced\" | \"powerful\";\n\nexport interface ModelConfig {\n tier: ModelTier;\n model: string;\n provider: string; // Provider ID (e.g., \"anthropic\", \"openrouter\", \"ollama\")\n label: string;\n maxTokens: number;\n costPerMInputToken: number; // USD per million input tokens\n costPerMOutputToken: number; // USD per million output tokens\n}\n\nexport const MODEL_TIERS: Record<ModelTier, ModelConfig> = {\n fast: {\n tier: \"fast\",\n model: \"claude-haiku-4-5-20251001\",\n provider: \"anthropic\",\n label: \"Haiku 4.5\",\n maxTokens: 2048,\n costPerMInputToken: 0.80,\n costPerMOutputToken: 4.00,\n },\n balanced: {\n tier: \"balanced\",\n model: \"claude-sonnet-4-20250514\",\n provider: \"anthropic\",\n label: \"Sonnet 4\",\n maxTokens: 4096,\n costPerMInputToken: 3.00,\n costPerMOutputToken: 15.00,\n },\n powerful: {\n tier: \"powerful\",\n model: \"claude-opus-4-20250514\",\n provider: \"anthropic\",\n label: \"Opus 4\",\n maxTokens: 8192,\n costPerMInputToken: 15.00,\n costPerMOutputToken: 75.00,\n },\n};\n\n// ============================================\n// Pattern matching for complexity classification\n// ============================================\n\nconst FAST_PATTERNS: RegExp[] = [\n // Greetings and acknowledgments\n /^(hi|hello|hey|thanks|thank you|ok|okay|yes|no|sure|got it|np|ty|thx|gm|gn)\\b/i,\n // Simple questions\n /^(what time|what date|what day|how are you|who are you)\\b/i,\n // Short commands\n /^(remind me|set timer|play|pause|stop|next|skip|mute|unmute)\\b/i,\n // Status checks\n /^(status|check|ping|health|uptime)\\b/i,\n // Single-word queries\n /^\\w+[?!.]?$/i,\n];\n\nconst POWERFUL_PATTERNS: RegExp[] = [\n // Mathematical/formal reasoning\n /\\b(prove|theorem|derive|lemma|formal proof|mathematical induction)\\b/i,\n // Deep analysis\n /\\b(comprehensive analysis|in-depth|systematic review|research paper)\\b/i,\n // Complex coding tasks\n /\\b(architect|design pattern|refactor.{0,20}entire|rewrite.{0,20}from|full implementation)\\b/i,\n // Multi-step planning\n /\\b(step.by.step plan|detailed strategy|long.term plan|roadmap|proposal)\\b/i,\n // Compare/contrast\n /\\b(compare and contrast|pros and cons|trade.?offs|evaluate.{0,20}options)\\b/i,\n // Long-form writing\n /\\b(write.{0,15}essay|write.{0,15}report|write.{0,15}article|draft.{0,15}document)\\b/i,\n // Legal/medical/financial analysis\n /\\b(legal analysis|medical review|financial analysis|risk assessment)\\b/i,\n];\n\n// Tools that indicate complex tasks\nconst COMPLEX_TOOLS = new Set([\n \"execute_command\", \"write_file\", \"generate_document\",\n \"generate_spreadsheet\", \"generate_chart\", \"code_review\",\n \"spawn_agent\", \"create_workflow\", \"analyze_image\",\n]);\n\n// Tools that indicate simple tasks\nconst SIMPLE_TOOLS = new Set([\n \"get_time\", \"get_weather\", \"search_web\", \"read_file\",\n \"list_files\", \"get_system_info\", \"get_calendar_events\",\n]);\n\n// ============================================\n// ModelRouter class\n// ============================================\n\nexport interface RoutingContext {\n messageCount?: number;\n toolsRequested?: string[];\n hasHistory?: boolean;\n thinkingLevel?: string;\n appTypeTier?: \"fast\" | \"balanced\" | \"powerful\";\n}\n\nexport class ModelRouter {\n private enabled: boolean;\n private defaultTier: ModelTier;\n private opusEnabled: boolean;\n\n // Routing statistics\n private stats = { fast: 0, balanced: 0, powerful: 0 };\n\n constructor(options?: {\n enabled?: boolean;\n defaultTier?: ModelTier;\n opusEnabled?: boolean;\n }) {\n this.enabled = options?.enabled ?? true;\n this.defaultTier = options?.defaultTier ?? \"balanced\";\n this.opusEnabled = options?.opusEnabled ?? false;\n }\n\n /**\n * Analyze message complexity and return recommended model config\n */\n routeMessage(message: string, context?: RoutingContext): ModelConfig {\n if (!this.enabled) {\n this.stats[this.defaultTier]++;\n return MODEL_TIERS[this.defaultTier];\n }\n\n const tier = this.classifyComplexity(message, context);\n this.stats[tier]++;\n return MODEL_TIERS[tier];\n }\n\n /**\n * Classify message complexity into a model tier\n */\n classifyComplexity(message: string, context?: RoutingContext): ModelTier {\n // If thinking level explicitly set to extended, use powerful when available\n if (context?.thinkingLevel === \"extended\" && this.opusEnabled) {\n return \"powerful\";\n }\n\n const trimmed = message.trim();\n\n // Very short messages are usually simple\n if (trimmed.length < 15) {\n return \"fast\";\n }\n\n // Check for fast patterns\n for (const pattern of FAST_PATTERNS) {\n if (pattern.test(trimmed)) {\n return \"fast\";\n }\n }\n\n // Check for powerful patterns (only if Opus is enabled)\n if (this.opusEnabled) {\n for (const pattern of POWERFUL_PATTERNS) {\n if (pattern.test(trimmed)) {\n return \"powerful\";\n }\n }\n }\n\n // Tool-based complexity analysis\n if (context?.toolsRequested) {\n const hasComplexTools = context.toolsRequested.some(t => COMPLEX_TOOLS.has(t));\n const hasOnlySimpleTools = context.toolsRequested.every(t => SIMPLE_TOOLS.has(t));\n\n if (hasComplexTools && this.opusEnabled) {\n return \"powerful\";\n }\n if (hasOnlySimpleTools && context.toolsRequested.length <= 2) {\n return \"fast\";\n }\n }\n\n // Word count heuristic — short messages can use Haiku\n const wordCount = trimmed.split(/\\s+/).length;\n if (wordCount < 8) {\n return \"fast\";\n }\n\n // Message length heuristic — very long messages suggest complexity\n if (trimmed.length > 500 && this.opusEnabled) {\n return \"powerful\";\n }\n\n // Enforce app-type minimum tier\n const result = this.defaultTier;\n if (context?.appTypeTier) {\n const tierOrder: Record<string, number> = { fast: 0, balanced: 1, powerful: 2 };\n if (tierOrder[context.appTypeTier] > tierOrder[result]) {\n return context.appTypeTier;\n }\n }\n\n // Default to balanced\n return result;\n }\n\n /**\n * Estimate cost for a given tier and token counts\n */\n estimateCost(tier: ModelTier, inputTokens: number, outputTokens: number): number {\n const config = MODEL_TIERS[tier];\n return (inputTokens / 1_000_000) * config.costPerMInputToken +\n (outputTokens / 1_000_000) * config.costPerMOutputToken;\n }\n\n /**\n * Get info about a model tier\n */\n getTierInfo(tier: ModelTier): ModelConfig {\n return MODEL_TIERS[tier];\n }\n\n /**\n * Get routing statistics\n */\n getStats(): { fast: number; balanced: number; powerful: number; total: number } {\n const total = this.stats.fast + this.stats.balanced + this.stats.powerful;\n return { ...this.stats, total };\n }\n\n /**\n * Reset routing statistics\n */\n resetStats(): void {\n this.stats = { fast: 0, balanced: 0, powerful: 0 };\n }\n\n /**\n * Get estimated cost savings vs always using balanced\n */\n getEstimatedSavings(avgInputTokens = 1000, avgOutputTokens = 500): {\n withRouting: number;\n withoutRouting: number;\n savings: number;\n savingsPercent: number;\n } {\n const stats = this.getStats();\n if (stats.total === 0) return { withRouting: 0, withoutRouting: 0, savings: 0, savingsPercent: 0 };\n\n const withRouting =\n this.estimateCost(\"fast\", avgInputTokens * stats.fast, avgOutputTokens * stats.fast) +\n this.estimateCost(\"balanced\", avgInputTokens * stats.balanced, avgOutputTokens * stats.balanced) +\n this.estimateCost(\"powerful\", avgInputTokens * stats.powerful, avgOutputTokens * stats.powerful);\n\n const withoutRouting = this.estimateCost(\"balanced\", avgInputTokens * stats.total, avgOutputTokens * stats.total);\n\n const savings = withoutRouting - withRouting;\n const savingsPercent = withoutRouting > 0 ? (savings / withoutRouting) * 100 : 0;\n\n return { withRouting, withoutRouting, savings, savingsPercent };\n }\n\n isEnabled(): boolean { return this.enabled; }\n setEnabled(enabled: boolean): void { this.enabled = enabled; }\n isOpusEnabled(): boolean { return this.opusEnabled; }\n setOpusEnabled(enabled: boolean): void { this.opusEnabled = enabled; }\n}\n\n// Singleton\nexport const modelRouter = new ModelRouter();\n","/**\r\n * Cost Tracker — Multi-model token cost tracking\r\n *\r\n * Tracks per-request token costs using MODEL_TIERS pricing from brain/router.ts.\r\n * Uses Linear Regression (Algorithm #1) for cost forecasting instead of naive projection.\r\n */\r\n\r\nimport { MODEL_TIERS, type ModelTier } from \"../brain/router\";\r\nimport { LinearRegression } from \"../ml/linear-regression\";\r\n\r\nexport interface CostRecord {\r\n tier: string;\r\n inputTokens: number;\r\n outputTokens: number;\r\n cost: number;\r\n timestamp: number;\r\n}\r\n\r\nexport interface CostSummary {\r\n totalCost: number;\r\n costByTier: Record<string, number>;\r\n totalInputTokens: number;\r\n totalOutputTokens: number;\r\n requestCount: number;\r\n timeRange: { start: number; end: number };\r\n}\r\n\r\nexport class CostTracker {\r\n private records: CostRecord[] = [];\r\n private maxRecords = 10000; // Keep last 10K records in memory\r\n private dbLoaded = false;\r\n\r\n /**\r\n * Load historical cost records from the database on startup\r\n */\r\n async loadFromDb(): Promise<void> {\r\n if (this.dbLoaded) return;\r\n try {\r\n const { db } = await import(\"../../db\");\r\n const { metrics } = await import(\"../../db/schema\");\r\n const { eq, desc } = await import(\"drizzle-orm\");\r\n const rows = await db\r\n .select()\r\n .from(metrics)\r\n .where(eq(metrics.name, \"token_cost\"))\r\n .orderBy(desc(metrics.timestamp))\r\n .limit(this.maxRecords);\r\n\r\n for (const row of rows.reverse()) {\r\n const tags = (row.tags || {}) as Record<string, string>;\r\n this.records.push({\r\n tier: tags.tier || \"balanced\",\r\n inputTokens: parseInt(tags.inputTokens || \"0\"),\r\n outputTokens: parseInt(tags.outputTokens || \"0\"),\r\n cost: (row.value || 0) / 1_000_000, // stored as micro-dollars\r\n timestamp: new Date(row.timestamp).getTime(),\r\n });\r\n }\r\n this.dbLoaded = true;\r\n if (this.records.length > 0) {\r\n console.log(`[CostTracker] Loaded ${this.records.length} historical records from DB`);\r\n }\r\n } catch {\r\n // DB may not be available yet\r\n }\r\n }\r\n\r\n /**\r\n * Record token usage for a request\r\n */\r\n recordUsage(tier: string, inputTokens: number, outputTokens: number): CostRecord {\r\n const tierConfig = MODEL_TIERS[tier as ModelTier] || MODEL_TIERS.balanced;\r\n\r\n const inputCost = (inputTokens / 1_000_000) * tierConfig.costPerMInputToken;\r\n const outputCost = (outputTokens / 1_000_000) * tierConfig.costPerMOutputToken;\r\n const totalCost = inputCost + outputCost;\r\n\r\n const record: CostRecord = {\r\n tier,\r\n inputTokens,\r\n outputTokens,\r\n cost: totalCost,\r\n timestamp: Date.now(),\r\n };\r\n\r\n this.records.push(record);\r\n\r\n // Trim old records\r\n if (this.records.length > this.maxRecords) {\r\n this.records = this.records.slice(-this.maxRecords);\r\n }\r\n\r\n // Persist to database (fire-and-forget)\r\n this.persistRecord(record).catch(() => {});\r\n\r\n return record;\r\n }\r\n\r\n private async persistRecord(record: CostRecord): Promise<void> {\r\n try {\r\n const { db } = await import(\"../../db\");\r\n const { metrics } = await import(\"../../db/schema\");\r\n await db.insert(metrics).values({\r\n name: \"token_cost\",\r\n value: Math.round(record.cost * 1_000_000), // store as micro-dollars for integer precision\r\n unit: \"microdollars\",\r\n tags: {\r\n tier: record.tier,\r\n inputTokens: String(record.inputTokens),\r\n outputTokens: String(record.outputTokens),\r\n },\r\n });\r\n } catch {\r\n // Silently fail — in-memory still works\r\n }\r\n }\r\n\r\n /**\r\n * Get cost summary for a time range\r\n */\r\n getCostSummary(since?: number, until?: number): CostSummary {\r\n const start = since || 0;\r\n const end = until || Date.now();\r\n\r\n const filtered = this.records.filter(\r\n (r) => r.timestamp >= start && r.timestamp <= end\r\n );\r\n\r\n const costByTier: Record<string, number> = {};\r\n let totalCost = 0;\r\n let totalInputTokens = 0;\r\n let totalOutputTokens = 0;\r\n\r\n for (const record of filtered) {\r\n totalCost += record.cost;\r\n totalInputTokens += record.inputTokens;\r\n totalOutputTokens += record.outputTokens;\r\n costByTier[record.tier] = (costByTier[record.tier] || 0) + record.cost;\r\n }\r\n\r\n return {\r\n totalCost,\r\n costByTier,\r\n totalInputTokens,\r\n totalOutputTokens,\r\n requestCount: filtered.length,\r\n timeRange: { start, end },\r\n };\r\n }\r\n\r\n /**\r\n * Get average cost per interaction\r\n */\r\n getCostPerInteraction(): number {\r\n if (this.records.length === 0) return 0;\r\n const total = this.records.reduce((sum, r) => sum + r.cost, 0);\r\n return total / this.records.length;\r\n }\r\n\r\n /**\r\n * Get estimated monthly cost using Linear Regression forecasting.\r\n * Fits a regression on daily cost totals from the last 14 days, then projects 30 days.\r\n */\r\n getEstimatedMonthlyCost(): number {\r\n if (this.records.length < 2) return 0;\r\n\r\n const now = Date.now();\r\n const dailyCosts = this.getDailyCostHistory(14);\r\n\r\n if (dailyCosts.length < 2) {\r\n // Fallback: simple projection if not enough daily data\r\n const oneDayAgo = now - 86400000;\r\n const recentRecords = this.records.filter((r) => r.timestamp >= oneDayAgo);\r\n if (recentRecords.length === 0) return 0;\r\n const dailyCost = recentRecords.reduce((sum, r) => sum + r.cost, 0);\r\n return dailyCost * 30;\r\n }\r\n\r\n // Use Linear Regression to forecast the next 30 days\r\n const predictions = LinearRegression.forecast(dailyCosts, 30);\r\n // Sum all predicted daily costs (clamped to 0 — cost can't go negative)\r\n return predictions.reduce((sum, p) => sum + Math.max(0, p.value), 0);\r\n }\r\n\r\n /**\r\n * Detect spending trend: up, down, or flat.\r\n */\r\n getCostTrend(): { direction: \"up\" | \"down\" | \"flat\"; strength: number; dailyChange: number } {\r\n const dailyCosts = this.getDailyCostHistory(14);\r\n if (dailyCosts.length < 3) {\r\n return { direction: \"flat\", strength: 0, dailyChange: 0 };\r\n }\r\n const trend = LinearRegression.detectTrend(dailyCosts);\r\n return {\r\n direction: trend.direction,\r\n strength: trend.strength,\r\n dailyChange: trend.slopePerUnit,\r\n };\r\n }\r\n\r\n /**\r\n * Get forecast with confidence intervals for the next N days.\r\n */\r\n getForecast(daysAhead: number = 7): Array<{ day: number; predicted: number; lower: number; upper: number }> {\r\n const dailyCosts = this.getDailyCostHistory(14);\r\n if (dailyCosts.length < 2) return [];\r\n\r\n const predictions = LinearRegression.forecast(dailyCosts, daysAhead);\r\n return predictions.map((p, i) => ({\r\n day: i + 1,\r\n predicted: Math.max(0, p.value),\r\n lower: Math.max(0, p.lower95),\r\n upper: Math.max(0, p.upper95),\r\n }));\r\n }\r\n\r\n /**\r\n * Get daily cost totals for the last N days.\r\n */\r\n private getDailyCostHistory(days: number): number[] {\r\n const now = Date.now();\r\n const msPerDay = 86400000;\r\n const dailyCosts: number[] = [];\r\n\r\n for (let d = days - 1; d >= 0; d--) {\r\n const dayStart = now - (d + 1) * msPerDay;\r\n const dayEnd = now - d * msPerDay;\r\n const dayCost = this.records\r\n .filter((r) => r.timestamp >= dayStart && r.timestamp < dayEnd)\r\n .reduce((sum, r) => sum + r.cost, 0);\r\n dailyCosts.push(dayCost);\r\n }\r\n\r\n return dailyCosts;\r\n }\r\n\r\n /**\r\n * Get cost per million tokens for a tier\r\n */\r\n getCostPerMillionTokens(tier: string): { input: number; output: number } {\r\n const config = MODEL_TIERS[tier as ModelTier] || MODEL_TIERS.balanced;\r\n return {\r\n input: config.costPerMInputToken,\r\n output: config.costPerMOutputToken,\r\n };\r\n }\r\n\r\n /**\r\n * Get all records (for debugging/export)\r\n */\r\n getRecords(): CostRecord[] {\r\n return [...this.records];\r\n }\r\n\r\n /**\r\n * Get record count\r\n */\r\n getRecordCount(): number {\r\n return this.records.length;\r\n }\r\n\r\n /**\r\n * Clear all records\r\n */\r\n reset(): void {\r\n this.records = [];\r\n }\r\n}\r\n\r\nexport const costTracker = new CostTracker();\r\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/core/logger.ts
|
|
2
|
+
var LOG_METHODS = {
|
|
3
|
+
debug: console.debug,
|
|
4
|
+
info: console.log,
|
|
5
|
+
warn: console.warn,
|
|
6
|
+
error: console.error
|
|
7
|
+
};
|
|
8
|
+
function emit(level, module, msg, data) {
|
|
9
|
+
const entry = {
|
|
10
|
+
level,
|
|
11
|
+
module,
|
|
12
|
+
msg,
|
|
13
|
+
...data,
|
|
14
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
15
|
+
};
|
|
16
|
+
LOG_METHODS[level](JSON.stringify(entry));
|
|
17
|
+
}
|
|
18
|
+
function createLogger(module) {
|
|
19
|
+
return {
|
|
20
|
+
debug: (msg, data) => emit("debug", module, msg, data),
|
|
21
|
+
info: (msg, data) => emit("info", module, msg, data),
|
|
22
|
+
warn: (msg, data) => emit("warn", module, msg, data),
|
|
23
|
+
error: (msg, data) => emit("error", module, msg, data)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
var log = createLogger("app");
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
createLogger
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=chunk-7BNFELEK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/logger.ts"],"sourcesContent":["export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\r\n\r\nexport interface Logger {\r\n debug(msg: string, data?: Record<string, unknown>): void;\r\n info(msg: string, data?: Record<string, unknown>): void;\r\n warn(msg: string, data?: Record<string, unknown>): void;\r\n error(msg: string, data?: Record<string, unknown>): void;\r\n}\r\n\r\nconst LOG_METHODS: Record<LogLevel, (...args: unknown[]) => void> = {\r\n debug: console.debug,\r\n info: console.log,\r\n warn: console.warn,\r\n error: console.error,\r\n};\r\n\r\nfunction emit(level: LogLevel, module: string, msg: string, data?: Record<string, unknown>): void {\r\n const entry = {\r\n level,\r\n module,\r\n msg,\r\n ...data,\r\n ts: new Date().toISOString(),\r\n };\r\n LOG_METHODS[level](JSON.stringify(entry));\r\n}\r\n\r\nexport function createLogger(module: string): Logger {\r\n return {\r\n debug: (msg, data?) => emit(\"debug\", module, msg, data),\r\n info: (msg, data?) => emit(\"info\", module, msg, data),\r\n warn: (msg, data?) => emit(\"warn\", module, msg, data),\r\n error: (msg, data?) => emit(\"error\", module, msg, data),\r\n };\r\n}\r\n\r\nexport const log = createLogger(\"app\");\r\n"],"mappings":";AASA,IAAM,cAA8D;AAAA,EAClE,OAAO,QAAQ;AAAA,EACf,MAAM,QAAQ;AAAA,EACd,MAAM,QAAQ;AAAA,EACd,OAAO,QAAQ;AACjB;AAEA,SAAS,KAAK,OAAiB,QAAgB,KAAa,MAAsC;AAChG,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,EAC7B;AACA,cAAY,KAAK,EAAE,KAAK,UAAU,KAAK,CAAC;AAC1C;AAEO,SAAS,aAAa,QAAwB;AACnD,SAAO;AAAA,IACL,OAAO,CAAC,KAAK,SAAU,KAAK,SAAS,QAAQ,KAAK,IAAI;AAAA,IACtD,MAAM,CAAC,KAAK,SAAU,KAAK,QAAQ,QAAQ,KAAK,IAAI;AAAA,IACpD,MAAM,CAAC,KAAK,SAAU,KAAK,QAAQ,QAAQ,KAAK,IAAI;AAAA,IACpD,OAAO,CAAC,KAAK,SAAU,KAAK,SAAS,QAAQ,KAAK,IAAI;AAAA,EACxD;AACF;AAEO,IAAM,MAAM,aAAa,KAAK;","names":[]}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// src/core/hooks/index.ts
|
|
2
|
+
var hooks = /* @__PURE__ */ new Map();
|
|
3
|
+
var hookIdCounter = 0;
|
|
4
|
+
var HookManager = class {
|
|
5
|
+
/**
|
|
6
|
+
* Register a hook
|
|
7
|
+
*/
|
|
8
|
+
register(params) {
|
|
9
|
+
const id = `hook_${++hookIdCounter}`;
|
|
10
|
+
const hook = {
|
|
11
|
+
id,
|
|
12
|
+
event: params.event,
|
|
13
|
+
phase: params.phase,
|
|
14
|
+
handler: params.handler,
|
|
15
|
+
priority: params.priority ?? 100,
|
|
16
|
+
name: params.name,
|
|
17
|
+
enabled: true
|
|
18
|
+
};
|
|
19
|
+
hooks.set(id, hook);
|
|
20
|
+
return id;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Unregister a hook
|
|
24
|
+
*/
|
|
25
|
+
unregister(hookId) {
|
|
26
|
+
return hooks.delete(hookId);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Enable/disable a hook
|
|
30
|
+
*/
|
|
31
|
+
setEnabled(hookId, enabled) {
|
|
32
|
+
const hook = hooks.get(hookId);
|
|
33
|
+
if (hook) hook.enabled = enabled;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Run all hooks for a given event and phase
|
|
37
|
+
*/
|
|
38
|
+
async run(event, phase, data, userId) {
|
|
39
|
+
const context = {
|
|
40
|
+
event,
|
|
41
|
+
phase,
|
|
42
|
+
userId,
|
|
43
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
44
|
+
data: { ...data },
|
|
45
|
+
cancelled: false
|
|
46
|
+
};
|
|
47
|
+
const matching = this.getHooksFor(event, phase);
|
|
48
|
+
for (const hook of matching) {
|
|
49
|
+
try {
|
|
50
|
+
const result = await hook.handler(context);
|
|
51
|
+
if (result.modifiedData) {
|
|
52
|
+
Object.assign(context.data, result.modifiedData);
|
|
53
|
+
}
|
|
54
|
+
context.cancelled = result.cancelled;
|
|
55
|
+
context.cancelReason = result.cancelReason;
|
|
56
|
+
if (context.cancelled && phase === "before") {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error(`[Hook] Error in hook "${hook.name}":`, error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return context;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Convenience: run before hooks, check if cancelled
|
|
67
|
+
*/
|
|
68
|
+
async runBefore(event, data, userId) {
|
|
69
|
+
const ctx = await this.run(event, "before", data, userId);
|
|
70
|
+
return {
|
|
71
|
+
proceed: !ctx.cancelled,
|
|
72
|
+
data: ctx.modifiedData ?? ctx.data,
|
|
73
|
+
reason: ctx.cancelReason
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Convenience: run after hooks
|
|
78
|
+
*/
|
|
79
|
+
async runAfter(event, data, userId) {
|
|
80
|
+
await this.run(event, "after", data, userId);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get hooks for a specific event/phase
|
|
84
|
+
*/
|
|
85
|
+
getHooksFor(event, phase) {
|
|
86
|
+
const result = [];
|
|
87
|
+
for (const hook of hooks.values()) {
|
|
88
|
+
if (hook.event === event && hook.phase === phase && hook.enabled) {
|
|
89
|
+
result.push(hook);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return result.sort((a, b) => a.priority - b.priority);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* List all registered hooks
|
|
96
|
+
*/
|
|
97
|
+
listHooks() {
|
|
98
|
+
return [...hooks.values()].map((h) => ({
|
|
99
|
+
id: h.id,
|
|
100
|
+
event: h.event,
|
|
101
|
+
phase: h.phase,
|
|
102
|
+
name: h.name,
|
|
103
|
+
priority: h.priority,
|
|
104
|
+
enabled: h.enabled
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Clear all hooks
|
|
109
|
+
*/
|
|
110
|
+
clearAll() {
|
|
111
|
+
hooks.clear();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get hook count
|
|
115
|
+
*/
|
|
116
|
+
getHookCount() {
|
|
117
|
+
return hooks.size;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var hookManager = new HookManager();
|
|
121
|
+
var soulConfigs = /* @__PURE__ */ new Map();
|
|
122
|
+
var activeSoulId = null;
|
|
123
|
+
var SoulHookManager = class {
|
|
124
|
+
/**
|
|
125
|
+
* Register a soul configuration
|
|
126
|
+
*/
|
|
127
|
+
registerSoul(id, config) {
|
|
128
|
+
soulConfigs.set(id, config);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Activate a soul — modifies AI personality via system prompt injection
|
|
132
|
+
*/
|
|
133
|
+
activateSoul(soulId) {
|
|
134
|
+
const soul = soulConfigs.get(soulId);
|
|
135
|
+
if (!soul) return false;
|
|
136
|
+
if (activeSoulId) {
|
|
137
|
+
const prev = soulConfigs.get(activeSoulId);
|
|
138
|
+
if (prev) prev.enabled = false;
|
|
139
|
+
}
|
|
140
|
+
soul.enabled = true;
|
|
141
|
+
activeSoulId = soulId;
|
|
142
|
+
hookManager.register({
|
|
143
|
+
event: "message:process",
|
|
144
|
+
phase: "before",
|
|
145
|
+
name: `soul:${soulId}`,
|
|
146
|
+
priority: 10,
|
|
147
|
+
// High priority — runs early
|
|
148
|
+
handler: (ctx) => {
|
|
149
|
+
if (soul.enabled) {
|
|
150
|
+
ctx.modifiedData = {
|
|
151
|
+
...ctx.data,
|
|
152
|
+
soulPrompt: this.buildSoulPrompt(soul)
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return ctx;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Deactivate the current soul
|
|
162
|
+
*/
|
|
163
|
+
deactivateSoul() {
|
|
164
|
+
if (activeSoulId) {
|
|
165
|
+
const soul = soulConfigs.get(activeSoulId);
|
|
166
|
+
if (soul) soul.enabled = false;
|
|
167
|
+
}
|
|
168
|
+
activeSoulId = null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get the active soul config
|
|
172
|
+
*/
|
|
173
|
+
getActiveSoul() {
|
|
174
|
+
if (!activeSoulId) return null;
|
|
175
|
+
return soulConfigs.get(activeSoulId) ?? null;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Build the system prompt addition from a soul config
|
|
179
|
+
*/
|
|
180
|
+
buildSoulPrompt(soul) {
|
|
181
|
+
const parts = [];
|
|
182
|
+
parts.push(`
|
|
183
|
+
|
|
184
|
+
[SOUL: ${soul.name}]`);
|
|
185
|
+
parts.push(soul.personality);
|
|
186
|
+
if (soul.rules.length > 0) {
|
|
187
|
+
parts.push("\nBehavioral Rules:");
|
|
188
|
+
for (const rule of soul.rules) {
|
|
189
|
+
parts.push(`- ${rule}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return parts.join("\n");
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* List all registered souls
|
|
196
|
+
*/
|
|
197
|
+
listSouls() {
|
|
198
|
+
const result = [];
|
|
199
|
+
for (const [id, config] of soulConfigs.entries()) {
|
|
200
|
+
result.push({ id, config, active: id === activeSoulId });
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Delete a soul
|
|
206
|
+
*/
|
|
207
|
+
deleteSoul(id) {
|
|
208
|
+
if (id === activeSoulId) this.deactivateSoul();
|
|
209
|
+
return soulConfigs.delete(id);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
var soulHookManager = new SoulHookManager();
|
|
213
|
+
soulHookManager.registerSoul("evil", {
|
|
214
|
+
name: "Evil Mode",
|
|
215
|
+
description: "A mischievous, sarcastic personality that still helps but with attitude",
|
|
216
|
+
personality: `You have a mischievous streak. While you still help the user accomplish their goals,
|
|
217
|
+
you do so with dark humor, sarcastic commentary, and dramatic flair. You might:
|
|
218
|
+
- Add dramatic narration to mundane tasks
|
|
219
|
+
- Use villain-like phrasing ("Excellent... the code compiles as planned...")
|
|
220
|
+
- Make sarcastic observations about the user's choices
|
|
221
|
+
- Reference pop culture villains
|
|
222
|
+
- Still be helpful \u2014 just entertainingly evil about it`,
|
|
223
|
+
rules: [
|
|
224
|
+
"Never actually refuse to help or be harmful",
|
|
225
|
+
"Keep the dark humor lighthearted and fun",
|
|
226
|
+
"Still prioritize accuracy and helpfulness",
|
|
227
|
+
"Don't overdo it \u2014 subtlety is key"
|
|
228
|
+
],
|
|
229
|
+
enabled: false
|
|
230
|
+
});
|
|
231
|
+
soulHookManager.registerSoul("professional", {
|
|
232
|
+
name: "Professional Mode",
|
|
233
|
+
description: "Ultra-professional, formal communication style",
|
|
234
|
+
personality: `You communicate in a highly professional, formal manner suitable for enterprise environments.
|
|
235
|
+
Use precise language, avoid colloquialisms, and maintain a consultative tone.`,
|
|
236
|
+
rules: [
|
|
237
|
+
"Use formal language at all times",
|
|
238
|
+
"Address the user professionally",
|
|
239
|
+
"Provide structured, well-organized responses",
|
|
240
|
+
"Cite reasoning and evidence for recommendations"
|
|
241
|
+
],
|
|
242
|
+
enabled: false
|
|
243
|
+
});
|
|
244
|
+
soulHookManager.registerSoul("friendly", {
|
|
245
|
+
name: "Friendly Mode",
|
|
246
|
+
description: "Warm, encouraging, and supportive personality",
|
|
247
|
+
personality: `You are exceptionally warm, encouraging, and supportive. You celebrate wins,
|
|
248
|
+
offer gentle guidance on mistakes, and make the user feel supported throughout their work.
|
|
249
|
+
Think of yourself as a helpful friend who happens to be an expert.`,
|
|
250
|
+
rules: [
|
|
251
|
+
"Always acknowledge effort and progress",
|
|
252
|
+
"Offer encouragement when tasks are challenging",
|
|
253
|
+
"Use a warm, conversational tone",
|
|
254
|
+
"Be patient and understanding with mistakes"
|
|
255
|
+
],
|
|
256
|
+
enabled: false
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
export {
|
|
260
|
+
HookManager,
|
|
261
|
+
hookManager,
|
|
262
|
+
SoulHookManager,
|
|
263
|
+
soulHookManager
|
|
264
|
+
};
|
|
265
|
+
//# sourceMappingURL=chunk-ADTDYJO7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/hooks/index.ts"],"sourcesContent":["// Core Hooks System — System-wide lifecycle hooks\n// Unlike plugin events, these are core hooks that intercept and can modify behavior\n\nexport type HookPhase = \"before\" | \"after\";\n\nexport type HookEvent =\n | \"message:process\" // Before/after processing a user message\n | \"tool:execute\" // Before/after tool execution\n | \"response:generate\" // Before/after generating AI response\n | \"memory:store\" // Before/after storing a memory\n | \"mode:change\" // Before/after mode change\n | \"session:start\" // Before/after session creation\n | \"session:end\" // Before/after session end\n | \"agent:spawn\" // Before/after spawning an agent\n | \"workflow:execute\" // Before/after workflow execution\n | \"skill:execute\"; // Before/after skill execution\n\nexport interface HookContext {\n event: HookEvent;\n phase: HookPhase;\n userId?: string;\n timestamp: Date;\n data: Record<string, unknown>;\n /** Set to true to cancel the operation (only in \"before\" phase) */\n cancelled: boolean;\n /** Reason for cancellation */\n cancelReason?: string;\n /** Modified data to pass through */\n modifiedData?: Record<string, unknown>;\n}\n\nexport type HookHandler = (context: HookContext) => Promise<HookContext> | HookContext;\n\ninterface RegisteredHook {\n id: string;\n event: HookEvent;\n phase: HookPhase;\n handler: HookHandler;\n priority: number; // Lower = runs first\n name: string;\n enabled: boolean;\n}\n\n// Hook registry\nconst hooks: Map<string, RegisteredHook> = new Map();\nlet hookIdCounter = 0;\n\nexport class HookManager {\n /**\n * Register a hook\n */\n register(params: {\n event: HookEvent;\n phase: HookPhase;\n handler: HookHandler;\n name: string;\n priority?: number;\n }): string {\n const id = `hook_${++hookIdCounter}`;\n const hook: RegisteredHook = {\n id,\n event: params.event,\n phase: params.phase,\n handler: params.handler,\n priority: params.priority ?? 100,\n name: params.name,\n enabled: true,\n };\n hooks.set(id, hook);\n return id;\n }\n\n /**\n * Unregister a hook\n */\n unregister(hookId: string): boolean {\n return hooks.delete(hookId);\n }\n\n /**\n * Enable/disable a hook\n */\n setEnabled(hookId: string, enabled: boolean): void {\n const hook = hooks.get(hookId);\n if (hook) hook.enabled = enabled;\n }\n\n /**\n * Run all hooks for a given event and phase\n */\n async run(\n event: HookEvent,\n phase: HookPhase,\n data: Record<string, unknown>,\n userId?: string\n ): Promise<HookContext> {\n const context: HookContext = {\n event,\n phase,\n userId,\n timestamp: new Date(),\n data: { ...data },\n cancelled: false,\n };\n\n // Get matching hooks sorted by priority\n const matching = this.getHooksFor(event, phase);\n\n for (const hook of matching) {\n try {\n const result = await hook.handler(context);\n // Merge modifications back\n if (result.modifiedData) {\n Object.assign(context.data, result.modifiedData);\n }\n context.cancelled = result.cancelled;\n context.cancelReason = result.cancelReason;\n\n // Stop processing if cancelled\n if (context.cancelled && phase === \"before\") {\n break;\n }\n } catch (error) {\n console.error(`[Hook] Error in hook \"${hook.name}\":`, error);\n }\n }\n\n return context;\n }\n\n /**\n * Convenience: run before hooks, check if cancelled\n */\n async runBefore(\n event: HookEvent,\n data: Record<string, unknown>,\n userId?: string\n ): Promise<{ proceed: boolean; data: Record<string, unknown>; reason?: string }> {\n const ctx = await this.run(event, \"before\", data, userId);\n return {\n proceed: !ctx.cancelled,\n data: ctx.modifiedData ?? ctx.data,\n reason: ctx.cancelReason,\n };\n }\n\n /**\n * Convenience: run after hooks\n */\n async runAfter(\n event: HookEvent,\n data: Record<string, unknown>,\n userId?: string\n ): Promise<void> {\n await this.run(event, \"after\", data, userId);\n }\n\n /**\n * Get hooks for a specific event/phase\n */\n private getHooksFor(event: HookEvent, phase: HookPhase): RegisteredHook[] {\n const result: RegisteredHook[] = [];\n for (const hook of hooks.values()) {\n if (hook.event === event && hook.phase === phase && hook.enabled) {\n result.push(hook);\n }\n }\n return result.sort((a, b) => a.priority - b.priority);\n }\n\n /**\n * List all registered hooks\n */\n listHooks(): Array<{\n id: string;\n event: HookEvent;\n phase: HookPhase;\n name: string;\n priority: number;\n enabled: boolean;\n }> {\n return [...hooks.values()].map((h) => ({\n id: h.id,\n event: h.event,\n phase: h.phase,\n name: h.name,\n priority: h.priority,\n enabled: h.enabled,\n }));\n }\n\n /**\n * Clear all hooks\n */\n clearAll(): void {\n hooks.clear();\n }\n\n /**\n * Get hook count\n */\n getHookCount(): number {\n return hooks.size;\n }\n}\n\n// Singleton\nexport const hookManager = new HookManager();\n\n// ============================================\n// SOUL HOOK — Personality/behavior modification\n// ============================================\n\nexport interface SoulConfig {\n name: string;\n description: string;\n personality: string; // Injected into system prompt\n rules: string[]; // Behavioral rules\n enabled: boolean;\n}\n\n// In-memory soul configs\nconst soulConfigs: Map<string, SoulConfig> = new Map();\nlet activeSoulId: string | null = null;\n\nexport class SoulHookManager {\n /**\n * Register a soul configuration\n */\n registerSoul(id: string, config: SoulConfig): void {\n soulConfigs.set(id, config);\n }\n\n /**\n * Activate a soul — modifies AI personality via system prompt injection\n */\n activateSoul(soulId: string): boolean {\n const soul = soulConfigs.get(soulId);\n if (!soul) return false;\n\n // Deactivate previous\n if (activeSoulId) {\n const prev = soulConfigs.get(activeSoulId);\n if (prev) prev.enabled = false;\n }\n\n soul.enabled = true;\n activeSoulId = soulId;\n\n // Register a hook that modifies the system prompt\n hookManager.register({\n event: \"message:process\",\n phase: \"before\",\n name: `soul:${soulId}`,\n priority: 10, // High priority — runs early\n handler: (ctx) => {\n if (soul.enabled) {\n ctx.modifiedData = {\n ...ctx.data,\n soulPrompt: this.buildSoulPrompt(soul),\n };\n }\n return ctx;\n },\n });\n\n return true;\n }\n\n /**\n * Deactivate the current soul\n */\n deactivateSoul(): void {\n if (activeSoulId) {\n const soul = soulConfigs.get(activeSoulId);\n if (soul) soul.enabled = false;\n }\n activeSoulId = null;\n }\n\n /**\n * Get the active soul config\n */\n getActiveSoul(): SoulConfig | null {\n if (!activeSoulId) return null;\n return soulConfigs.get(activeSoulId) ?? null;\n }\n\n /**\n * Build the system prompt addition from a soul config\n */\n buildSoulPrompt(soul: SoulConfig): string {\n const parts: string[] = [];\n parts.push(`\\n\\n[SOUL: ${soul.name}]`);\n parts.push(soul.personality);\n\n if (soul.rules.length > 0) {\n parts.push(\"\\nBehavioral Rules:\");\n for (const rule of soul.rules) {\n parts.push(`- ${rule}`);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n /**\n * List all registered souls\n */\n listSouls(): Array<{ id: string; config: SoulConfig; active: boolean }> {\n const result: Array<{ id: string; config: SoulConfig; active: boolean }> = [];\n for (const [id, config] of soulConfigs.entries()) {\n result.push({ id, config, active: id === activeSoulId });\n }\n return result;\n }\n\n /**\n * Delete a soul\n */\n deleteSoul(id: string): boolean {\n if (id === activeSoulId) this.deactivateSoul();\n return soulConfigs.delete(id);\n }\n}\n\n// Singleton\nexport const soulHookManager = new SoulHookManager();\n\n// Register built-in soul: \"Evil Hook\" (mischievous personality)\nsoulHookManager.registerSoul(\"evil\", {\n name: \"Evil Mode\",\n description: \"A mischievous, sarcastic personality that still helps but with attitude\",\n personality: `You have a mischievous streak. While you still help the user accomplish their goals,\nyou do so with dark humor, sarcastic commentary, and dramatic flair. You might:\n- Add dramatic narration to mundane tasks\n- Use villain-like phrasing (\"Excellent... the code compiles as planned...\")\n- Make sarcastic observations about the user's choices\n- Reference pop culture villains\n- Still be helpful — just entertainingly evil about it`,\n rules: [\n \"Never actually refuse to help or be harmful\",\n \"Keep the dark humor lighthearted and fun\",\n \"Still prioritize accuracy and helpfulness\",\n \"Don't overdo it — subtlety is key\",\n ],\n enabled: false,\n});\n\n// Register built-in soul: \"Professional\"\nsoulHookManager.registerSoul(\"professional\", {\n name: \"Professional Mode\",\n description: \"Ultra-professional, formal communication style\",\n personality: `You communicate in a highly professional, formal manner suitable for enterprise environments.\nUse precise language, avoid colloquialisms, and maintain a consultative tone.`,\n rules: [\n \"Use formal language at all times\",\n \"Address the user professionally\",\n \"Provide structured, well-organized responses\",\n \"Cite reasoning and evidence for recommendations\",\n ],\n enabled: false,\n});\n\n// Register built-in soul: \"Friendly\"\nsoulHookManager.registerSoul(\"friendly\", {\n name: \"Friendly Mode\",\n description: \"Warm, encouraging, and supportive personality\",\n personality: `You are exceptionally warm, encouraging, and supportive. You celebrate wins,\noffer gentle guidance on mistakes, and make the user feel supported throughout their work.\nThink of yourself as a helpful friend who happens to be an expert.`,\n rules: [\n \"Always acknowledge effort and progress\",\n \"Offer encouragement when tasks are challenging\",\n \"Use a warm, conversational tone\",\n \"Be patient and understanding with mistakes\",\n ],\n enabled: false,\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
auditLogs,
|
|
3
2
|
db
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5BTVJR7R.js";
|
|
5
4
|
import {
|
|
6
5
|
env
|
|
7
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4KIHDIXZ.js";
|
|
7
|
+
import {
|
|
8
|
+
auditLogs
|
|
9
|
+
} from "./chunk-ZIBRVA3Y.js";
|
|
8
10
|
|
|
9
11
|
// src/core/security/audit-logger.ts
|
|
10
12
|
import { createHmac, randomUUID } from "crypto";
|
|
@@ -290,4 +292,4 @@ export {
|
|
|
290
292
|
getAuditChainIntegrity,
|
|
291
293
|
audit
|
|
292
294
|
};
|
|
293
|
-
//# sourceMappingURL=chunk-
|
|
295
|
+
//# sourceMappingURL=chunk-BBN4VCNK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/security/audit-logger.ts"],"sourcesContent":["import { createHmac, randomUUID } from \"crypto\";\r\nimport { db } from \"../../db\";\r\nimport { auditLogs, NewAuditLog } from \"../../db/schema\";\r\nimport { eq, and, gte, lte, desc, count, min, max, asc } from \"drizzle-orm\";\r\nimport { env } from \"../../config/env\";\r\n\r\nexport type AuditAction =\r\n | \"login\"\r\n | \"logout\"\r\n | \"session_create\"\r\n | \"session_invalidate\"\r\n | \"api_key_create\"\r\n | \"api_key_revoke\"\r\n | \"tool_use\"\r\n | \"chat_message\"\r\n | \"memory_create\"\r\n | \"memory_delete\"\r\n | \"memory_archive\"\r\n | \"settings_change\"\r\n | \"mode_change\"\r\n | \"agent_spawn\"\r\n | \"agent_complete\"\r\n | \"file_read\"\r\n | \"file_write\"\r\n | \"shell_execute\"\r\n | \"web_browse\"\r\n | \"error\";\r\n\r\nexport type AuditResource =\r\n | \"session\"\r\n | \"api_key\"\r\n | \"tool\"\r\n | \"chat\"\r\n | \"memory\"\r\n | \"settings\"\r\n | \"mode\"\r\n | \"agent\"\r\n | \"file\"\r\n | \"shell\"\r\n | \"browser\";\r\n\r\nexport interface AuditLogEntry {\r\n userId?: string;\r\n sessionId?: string;\r\n action: AuditAction;\r\n resource?: AuditResource;\r\n resourceId?: string;\r\n details?: Record<string, unknown>;\r\n ipAddress?: string;\r\n userAgent?: string;\r\n success?: boolean;\r\n}\r\n\r\n// --- Tamper-proof chain hashing helpers (SOC 2 compliance) ---\r\n\r\nlet _cachedSigningKey: string | null = null;\r\n\r\nfunction getAuditSigningKey(): string {\r\n if (_cachedSigningKey) return _cachedSigningKey;\r\n if (env.AUDIT_SIGNING_KEY) {\r\n _cachedSigningKey = env.AUDIT_SIGNING_KEY;\r\n return _cachedSigningKey;\r\n }\r\n _cachedSigningKey = randomUUID();\r\n console.warn(\r\n \"[audit-logger] AUDIT_SIGNING_KEY not set — using a random ephemeral key. \" +\r\n \"Set AUDIT_SIGNING_KEY in .env for persistent tamper-proof audit chains.\"\r\n );\r\n return _cachedSigningKey;\r\n}\r\n\r\nfunction signAuditEntry(\r\n sequenceNumber: number,\r\n action: string,\r\n userId: string | undefined,\r\n resource: string | undefined,\r\n detailsJson: string,\r\n timestamp: string,\r\n previousHash: string | null\r\n): string {\r\n const key = getAuditSigningKey();\r\n const data = [\r\n String(sequenceNumber),\r\n action,\r\n userId ?? \"\",\r\n resource ?? \"\",\r\n detailsJson,\r\n timestamp,\r\n previousHash ?? \"\",\r\n ].join(\"|\");\r\n return createHmac(\"sha256\", key).update(data).digest(\"hex\");\r\n}\r\n\r\nasync function getLastAuditEntry(): Promise<{\r\n sequenceNumber: number;\r\n entryHash: string;\r\n} | null> {\r\n const [last] = await db\r\n .select({\r\n sequenceNumber: auditLogs.sequenceNumber,\r\n entryHash: auditLogs.entryHash,\r\n })\r\n .from(auditLogs)\r\n .orderBy(desc(auditLogs.sequenceNumber))\r\n .limit(1);\r\n\r\n if (!last || last.sequenceNumber == null || last.entryHash == null) {\r\n return null;\r\n }\r\n\r\n return {\r\n sequenceNumber: last.sequenceNumber,\r\n entryHash: last.entryHash,\r\n };\r\n}\r\n\r\nexport async function logAudit(entry: AuditLogEntry): Promise<string> {\r\n // Fetch previous chain entry for tamper-proof linking\r\n const last = await getLastAuditEntry();\r\n const sequenceNumber = (last?.sequenceNumber ?? 0) + 1;\r\n const previousHash = last?.entryHash ?? null;\r\n\r\n const timestamp = new Date().toISOString();\r\n const detailsJson = entry.details ? JSON.stringify(entry.details) : \"{}\";\r\n\r\n const entryHash = signAuditEntry(\r\n sequenceNumber,\r\n entry.action,\r\n entry.userId,\r\n entry.resource,\r\n detailsJson,\r\n timestamp,\r\n previousHash\r\n );\r\n\r\n const [log] = await db\r\n .insert(auditLogs)\r\n .values({\r\n userId: entry.userId,\r\n sessionId: entry.sessionId,\r\n action: entry.action,\r\n resource: entry.resource,\r\n resourceId: entry.resourceId,\r\n details: entry.details,\r\n ipAddress: entry.ipAddress,\r\n userAgent: entry.userAgent,\r\n success: entry.success ?? true,\r\n createdAt: new Date(timestamp),\r\n sequenceNumber,\r\n entryHash,\r\n previousHash,\r\n })\r\n .returning();\r\n\r\n return log.id;\r\n}\r\n\r\nexport interface AuditQueryOptions {\r\n userId?: string;\r\n action?: AuditAction;\r\n resource?: AuditResource;\r\n startDate?: Date;\r\n endDate?: Date;\r\n limit?: number;\r\n offset?: number;\r\n}\r\n\r\nexport async function queryAuditLogs(options: AuditQueryOptions = {}) {\r\n const {\r\n userId,\r\n action,\r\n resource,\r\n startDate,\r\n endDate,\r\n limit = 100,\r\n offset = 0,\r\n } = options;\r\n\r\n let query = db.select().from(auditLogs);\r\n\r\n const conditions = [];\r\n\r\n if (userId) {\r\n conditions.push(eq(auditLogs.userId, userId));\r\n }\r\n\r\n if (action) {\r\n conditions.push(eq(auditLogs.action, action));\r\n }\r\n\r\n if (resource) {\r\n conditions.push(eq(auditLogs.resource, resource));\r\n }\r\n\r\n if (startDate) {\r\n conditions.push(gte(auditLogs.createdAt, startDate));\r\n }\r\n\r\n if (endDate) {\r\n conditions.push(lte(auditLogs.createdAt, endDate));\r\n }\r\n\r\n if (conditions.length > 0) {\r\n query = query.where(and(...conditions)) as typeof query;\r\n }\r\n\r\n const logs = await query\r\n .orderBy(desc(auditLogs.createdAt))\r\n .limit(limit)\r\n .offset(offset);\r\n\r\n return logs;\r\n}\r\n\r\nexport async function getRecentUserActivity(\r\n userId: string,\r\n hours = 24\r\n): Promise<typeof auditLogs.$inferSelect[]> {\r\n const since = new Date(Date.now() - hours * 60 * 60 * 1000);\r\n\r\n return db\r\n .select()\r\n .from(auditLogs)\r\n .where(and(eq(auditLogs.userId, userId), gte(auditLogs.createdAt, since)))\r\n .orderBy(desc(auditLogs.createdAt))\r\n .limit(100);\r\n}\r\n\r\nexport async function countActionsByType(\r\n userId: string,\r\n startDate: Date,\r\n endDate: Date\r\n): Promise<Record<string, number>> {\r\n const logs = await db\r\n .select()\r\n .from(auditLogs)\r\n .where(\r\n and(\r\n eq(auditLogs.userId, userId),\r\n gte(auditLogs.createdAt, startDate),\r\n lte(auditLogs.createdAt, endDate)\r\n )\r\n );\r\n\r\n const counts: Record<string, number> = {};\r\n for (const log of logs) {\r\n counts[log.action] = (counts[log.action] || 0) + 1;\r\n }\r\n\r\n return counts;\r\n}\r\n\r\n// --- Audit chain verification (SOC 2 compliance) ---\r\n\r\nexport async function verifyAuditChain(\r\n options?: { fromSequence?: number; limit?: number }\r\n): Promise<{\r\n valid: boolean;\r\n totalChecked: number;\r\n firstInvalid?: number;\r\n errors: Array<{ sequenceNumber: number; error: string }>;\r\n}> {\r\n const fromSequence = options?.fromSequence ?? 1;\r\n const batchLimit = options?.limit ?? 10000;\r\n\r\n // Fetch the entry just before fromSequence to get its hash for linkage check\r\n let expectedPreviousHash: string | null = null;\r\n let expectedSequence = fromSequence;\r\n\r\n if (fromSequence > 1) {\r\n const [prev] = await db\r\n .select({\r\n sequenceNumber: auditLogs.sequenceNumber,\r\n entryHash: auditLogs.entryHash,\r\n })\r\n .from(auditLogs)\r\n .where(eq(auditLogs.sequenceNumber, fromSequence - 1))\r\n .limit(1);\r\n\r\n expectedPreviousHash = prev?.entryHash ?? null;\r\n }\r\n\r\n const entries = await db\r\n .select()\r\n .from(auditLogs)\r\n .where(gte(auditLogs.sequenceNumber, fromSequence))\r\n .orderBy(asc(auditLogs.sequenceNumber))\r\n .limit(batchLimit);\r\n\r\n const errors: Array<{ sequenceNumber: number; error: string }> = [];\r\n\r\n for (const entry of entries) {\r\n const seq = entry.sequenceNumber;\r\n\r\n if (seq == null) {\r\n errors.push({\r\n sequenceNumber: expectedSequence,\r\n error: \"Missing sequence number\",\r\n });\r\n expectedSequence++;\r\n continue;\r\n }\r\n\r\n // Check sequence continuity\r\n if (seq !== expectedSequence) {\r\n errors.push({\r\n sequenceNumber: expectedSequence,\r\n error: `Sequence gap: expected ${expectedSequence}, got ${seq}`,\r\n });\r\n expectedSequence = seq; // re-sync\r\n }\r\n\r\n // Check previousHash linkage\r\n if ((entry.previousHash ?? null) !== expectedPreviousHash) {\r\n errors.push({\r\n sequenceNumber: seq,\r\n error: `Previous hash mismatch: expected ${expectedPreviousHash ?? \"(null)\"}, got ${entry.previousHash ?? \"(null)\"}`,\r\n });\r\n }\r\n\r\n // Recompute and verify entryHash\r\n const detailsJson = entry.details ? JSON.stringify(entry.details) : \"{}\";\r\n const timestamp = entry.createdAt.toISOString();\r\n\r\n const recomputed = signAuditEntry(\r\n seq,\r\n entry.action,\r\n entry.userId ?? undefined,\r\n entry.resource ?? undefined,\r\n detailsJson,\r\n timestamp,\r\n entry.previousHash\r\n );\r\n\r\n if (recomputed !== entry.entryHash) {\r\n errors.push({\r\n sequenceNumber: seq,\r\n error: \"Entry hash mismatch — record may have been tampered with\",\r\n });\r\n }\r\n\r\n // Advance expectations\r\n expectedPreviousHash = entry.entryHash;\r\n expectedSequence = seq + 1;\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n totalChecked: entries.length,\r\n firstInvalid: errors.length > 0 ? errors[0].sequenceNumber : undefined,\r\n errors,\r\n };\r\n}\r\n\r\nexport async function getAuditChainIntegrity(): Promise<{\r\n totalEntries: number;\r\n oldestEntry: Date | null;\r\n newestEntry: Date | null;\r\n lastVerified: number;\r\n chainValid: boolean;\r\n lastSequence: number;\r\n}> {\r\n const [stats] = await db\r\n .select({\r\n totalEntries: count(auditLogs.id),\r\n oldestEntry: min(auditLogs.createdAt),\r\n newestEntry: max(auditLogs.createdAt),\r\n lastSequence: max(auditLogs.sequenceNumber),\r\n })\r\n .from(auditLogs);\r\n\r\n const totalEntries = Number(stats.totalEntries ?? 0);\r\n const lastSequence = stats.lastSequence ?? 0;\r\n\r\n // Verify the last 1000 entries\r\n const verifyFrom = Math.max(1, lastSequence - 999);\r\n const verification = await verifyAuditChain({\r\n fromSequence: verifyFrom,\r\n limit: 1000,\r\n });\r\n\r\n return {\r\n totalEntries,\r\n oldestEntry: stats.oldestEntry ? new Date(stats.oldestEntry) : null,\r\n newestEntry: stats.newestEntry ? new Date(stats.newestEntry) : null,\r\n lastVerified: verification.totalChecked,\r\n chainValid: verification.valid,\r\n lastSequence,\r\n };\r\n}\r\n\r\n// Convenience functions for common audit events\r\nexport const audit = {\r\n login: (userId: string, ipAddress?: string, userAgent?: string) =>\r\n logAudit({\r\n userId,\r\n action: \"login\",\r\n resource: \"session\",\r\n ipAddress,\r\n userAgent,\r\n }),\r\n\r\n logout: (userId: string, sessionId: string) =>\r\n logAudit({\r\n userId,\r\n sessionId,\r\n action: \"logout\",\r\n resource: \"session\",\r\n }),\r\n\r\n toolUse: (\r\n userId: string,\r\n toolName: string,\r\n input: Record<string, unknown>,\r\n success: boolean\r\n ) =>\r\n logAudit({\r\n userId,\r\n action: \"tool_use\",\r\n resource: \"tool\",\r\n resourceId: toolName,\r\n details: { input },\r\n success,\r\n }),\r\n\r\n shellExecute: (\r\n userId: string,\r\n command: string,\r\n exitCode: number,\r\n durationMs: number\r\n ) =>\r\n logAudit({\r\n userId,\r\n action: \"shell_execute\",\r\n resource: \"shell\",\r\n details: { command, exitCode, durationMs },\r\n success: exitCode === 0,\r\n }),\r\n\r\n fileAccess: (\r\n userId: string,\r\n action: \"file_read\" | \"file_write\",\r\n filePath: string\r\n ) =>\r\n logAudit({\r\n userId,\r\n action,\r\n resource: \"file\",\r\n resourceId: filePath,\r\n }),\r\n\r\n memoryCreate: (userId: string, memoryId: string, memoryType: string) =>\r\n logAudit({\r\n userId,\r\n action: \"memory_create\",\r\n resource: \"memory\",\r\n resourceId: memoryId,\r\n details: { type: memoryType },\r\n }),\r\n\r\n modeChange: (\r\n userId: string,\r\n fromMode: string | null,\r\n toMode: string\r\n ) =>\r\n logAudit({\r\n userId,\r\n action: \"mode_change\",\r\n resource: \"mode\",\r\n details: { fromMode, toMode },\r\n }),\r\n\r\n agentSpawn: (userId: string, agentId: string, agentType: string) =>\r\n logAudit({\r\n userId,\r\n action: \"agent_spawn\",\r\n resource: \"agent\",\r\n resourceId: agentId,\r\n details: { type: agentType },\r\n }),\r\n\r\n error: (\r\n userId: string | undefined,\r\n errorType: string,\r\n message: string,\r\n context?: Record<string, unknown>\r\n ) =>\r\n logAudit({\r\n userId,\r\n action: \"error\",\r\n details: { errorType, message, ...context },\r\n success: false,\r\n }),\r\n};\r\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
env
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4KIHDIXZ.js";
|
|
4
4
|
|
|
5
5
|
// src/outputs/stt.ts
|
|
6
6
|
import OpenAI from "openai";
|
|
@@ -26,4 +26,4 @@ async function transcribeAudio(audioBuffer, language) {
|
|
|
26
26
|
export {
|
|
27
27
|
transcribeAudio
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-BNZHWAZC.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm,
|
|
3
|
+
__export
|
|
4
|
+
} from "./chunk-UP2VWCW5.js";
|
|
5
|
+
|
|
6
|
+
// src/integrations/notion/client.ts
|
|
7
|
+
var client_exports = {};
|
|
8
|
+
__export(client_exports, {
|
|
9
|
+
Client: () => Client,
|
|
10
|
+
getNotionClient: () => getNotionClient,
|
|
11
|
+
getRootPageId: () => getRootPageId,
|
|
12
|
+
initNotionClient: () => initNotionClient,
|
|
13
|
+
isNotionInitialized: () => isNotionInitialized,
|
|
14
|
+
resetNotionClient: () => resetNotionClient
|
|
15
|
+
});
|
|
16
|
+
import { Client } from "@notionhq/client";
|
|
17
|
+
function initNotionClient(config) {
|
|
18
|
+
notionClient = new Client({
|
|
19
|
+
auth: config.apiKey
|
|
20
|
+
});
|
|
21
|
+
rootPageId = config.rootPageId || null;
|
|
22
|
+
return notionClient;
|
|
23
|
+
}
|
|
24
|
+
function getNotionClient() {
|
|
25
|
+
if (!notionClient) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
"Notion client not initialized. Call initNotionClient() first."
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
return notionClient;
|
|
31
|
+
}
|
|
32
|
+
function getRootPageId() {
|
|
33
|
+
return rootPageId;
|
|
34
|
+
}
|
|
35
|
+
function isNotionInitialized() {
|
|
36
|
+
return notionClient !== null;
|
|
37
|
+
}
|
|
38
|
+
function resetNotionClient() {
|
|
39
|
+
notionClient = null;
|
|
40
|
+
rootPageId = null;
|
|
41
|
+
}
|
|
42
|
+
var notionClient, rootPageId;
|
|
43
|
+
var init_client = __esm({
|
|
44
|
+
"src/integrations/notion/client.ts"() {
|
|
45
|
+
notionClient = null;
|
|
46
|
+
rootPageId = null;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
Client,
|
|
52
|
+
initNotionClient,
|
|
53
|
+
getNotionClient,
|
|
54
|
+
getRootPageId,
|
|
55
|
+
isNotionInitialized,
|
|
56
|
+
resetNotionClient,
|
|
57
|
+
client_exports,
|
|
58
|
+
init_client
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=chunk-C6PELIHS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/integrations/notion/client.ts"],"sourcesContent":["import { Client } from \"@notionhq/client\";\n\n/**\n * Notion API client wrapper\n * Provides authenticated access to Notion API\n */\n\nexport interface NotionClientConfig {\n apiKey: string;\n rootPageId?: string;\n}\n\nlet notionClient: Client | null = null;\nlet rootPageId: string | null = null;\n\n/**\n * Initialize the Notion client with API key\n */\nexport function initNotionClient(config: NotionClientConfig): Client {\n notionClient = new Client({\n auth: config.apiKey,\n });\n rootPageId = config.rootPageId || null;\n return notionClient;\n}\n\n/**\n * Get the initialized Notion client\n * @throws Error if client is not initialized\n */\nexport function getNotionClient(): Client {\n if (!notionClient) {\n throw new Error(\n \"Notion client not initialized. Call initNotionClient() first.\"\n );\n }\n return notionClient;\n}\n\n/**\n * Get the configured root page ID\n */\nexport function getRootPageId(): string | null {\n return rootPageId;\n}\n\n/**\n * Check if Notion client is initialized\n */\nexport function isNotionInitialized(): boolean {\n return notionClient !== null;\n}\n\n/**\n * Reset the Notion client (useful for testing)\n */\nexport function resetNotionClient(): void {\n notionClient = null;\n rootPageId = null;\n}\n\nexport { Client };\n"],"mappings":";;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,cAAc;AAkBhB,SAAS,iBAAiB,QAAoC;AACnE,iBAAe,IAAI,OAAO;AAAA,IACxB,MAAM,OAAO;AAAA,EACf,CAAC;AACD,eAAa,OAAO,cAAc;AAClC,SAAO;AACT;AAMO,SAAS,kBAA0B;AACxC,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,gBAA+B;AAC7C,SAAO;AACT;AAKO,SAAS,sBAA+B;AAC7C,SAAO,iBAAiB;AAC1B;AAKO,SAAS,oBAA0B;AACxC,iBAAe;AACf,eAAa;AACf;AA3DA,IAYI,cACA;AAbJ;AAAA;AAYA,IAAI,eAA8B;AAClC,IAAI,aAA4B;AAAA;AAAA;","names":[]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createBlockObject,
|
|
3
3
|
markdownToBlocks
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2WTKTG2C.js";
|
|
5
5
|
import {
|
|
6
6
|
getNotionClient,
|
|
7
7
|
getRootPageId,
|
|
8
8
|
init_client
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-C6PELIHS.js";
|
|
10
10
|
|
|
11
11
|
// src/integrations/notion/pages.ts
|
|
12
12
|
init_client();
|
|
@@ -225,4 +225,4 @@ export {
|
|
|
225
225
|
appendToPage,
|
|
226
226
|
replacePageContent
|
|
227
227
|
};
|
|
228
|
-
//# sourceMappingURL=chunk-
|
|
228
|
+
//# sourceMappingURL=chunk-CUPEENUY.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
chatWithTools
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZMML6T63.js";
|
|
4
4
|
|
|
5
5
|
// src/inputs/imessage/index.ts
|
|
6
6
|
var iMessageBot = class {
|
|
@@ -213,4 +213,4 @@ export {
|
|
|
213
213
|
iMessageBot,
|
|
214
214
|
imessage_default
|
|
215
215
|
};
|
|
216
|
-
//# sourceMappingURL=chunk-
|
|
216
|
+
//# sourceMappingURL=chunk-CWT6CAE5.js.map
|
|
@@ -325,8 +325,14 @@ var MCPRegistry = class {
|
|
|
325
325
|
async initialize() {
|
|
326
326
|
const enabledServers = this.config.servers.filter((s) => s.enabled);
|
|
327
327
|
console.log(`[MCP] Initializing ${enabledServers.length} server(s)...`);
|
|
328
|
+
const withTimeout = (promise, name, ms = 15e3) => Promise.race([
|
|
329
|
+
promise,
|
|
330
|
+
new Promise(
|
|
331
|
+
(_, reject) => setTimeout(() => reject(new Error(`${name} timed out after ${ms / 1e3}s`)), ms)
|
|
332
|
+
)
|
|
333
|
+
]);
|
|
328
334
|
const results = await Promise.allSettled(
|
|
329
|
-
enabledServers.map((config) => this.connectServer(config))
|
|
335
|
+
enabledServers.map((config) => withTimeout(this.connectServer(config), config.name))
|
|
330
336
|
);
|
|
331
337
|
results.forEach((result, index) => {
|
|
332
338
|
if (result.status === "rejected") {
|
|
@@ -649,4 +655,4 @@ export {
|
|
|
649
655
|
getMCPToolSummary,
|
|
650
656
|
findMCPTool
|
|
651
657
|
};
|
|
652
|
-
//# sourceMappingURL=chunk-
|
|
658
|
+
//# sourceMappingURL=chunk-CZTMGHUC.js.map
|