@indexnetwork/protocol 4.5.0-rc.323.1 → 4.5.0-rc.324.1
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/dist/agent/agent.tools.js +1 -1
- package/dist/agent/agent.tools.js.map +1 -1
- package/dist/chat/chat.interrupt.classifier.js +1 -1
- package/dist/chat/chat.interrupt.classifier.js.map +1 -1
- package/dist/chat/chat.suggester.js +3 -3
- package/dist/chat/chat.suggester.js.map +1 -1
- package/dist/chat/chat.title.generator.js +2 -2
- package/dist/chat/chat.title.generator.js.map +1 -1
- package/dist/contact/contact.tools.js +1 -1
- package/dist/contact/contact.tools.js.map +1 -1
- package/dist/enrichment/enrichment.graph.d.ts.map +1 -1
- package/dist/enrichment/enrichment.graph.js +9 -3
- package/dist/enrichment/enrichment.graph.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/integration/integration.tools.js +1 -1
- package/dist/integration/integration.tools.js.map +1 -1
- package/dist/intent/intent.graph.d.ts.map +1 -1
- package/dist/intent/intent.graph.js +12 -10
- package/dist/intent/intent.graph.js.map +1 -1
- package/dist/intent/intent.indexer.d.ts.map +1 -1
- package/dist/intent/intent.indexer.js +4 -3
- package/dist/intent/intent.indexer.js.map +1 -1
- package/dist/intent/intent.inferrer.d.ts.map +1 -1
- package/dist/intent/intent.inferrer.js +2 -1
- package/dist/intent/intent.inferrer.js.map +1 -1
- package/dist/intent/intent.reconciler.d.ts.map +1 -1
- package/dist/intent/intent.reconciler.js +5 -4
- package/dist/intent/intent.reconciler.js.map +1 -1
- package/dist/intent/intent.verifier.d.ts.map +1 -1
- package/dist/intent/intent.verifier.js +4 -3
- package/dist/intent/intent.verifier.js.map +1 -1
- package/dist/maintenance/maintenance.graph.d.ts.map +1 -1
- package/dist/maintenance/maintenance.graph.js +27 -5
- package/dist/maintenance/maintenance.graph.js.map +1 -1
- package/dist/mcp/mcp.server.d.ts.map +1 -1
- package/dist/mcp/mcp.server.js +5 -4
- package/dist/mcp/mcp.server.js.map +1 -1
- package/dist/negotiation/insight.generator.js +2 -2
- package/dist/negotiation/insight.generator.js.map +1 -1
- package/dist/negotiation/negotiation.graph.d.ts.map +1 -1
- package/dist/negotiation/negotiation.graph.js +15 -11
- package/dist/negotiation/negotiation.graph.js.map +1 -1
- package/dist/negotiation/negotiation.tools.js +1 -1
- package/dist/negotiation/negotiation.tools.js.map +1 -1
- package/dist/network/network.recommender.d.ts.map +1 -1
- package/dist/network/network.recommender.js +5 -4
- package/dist/network/network.recommender.js.map +1 -1
- package/dist/network/network.tools.d.ts.map +1 -1
- package/dist/network/network.tools.js +4 -2
- package/dist/network/network.tools.js.map +1 -1
- package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.graph.js +30 -23
- package/dist/opportunity/feed/feed.graph.js.map +1 -1
- package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
- package/dist/opportunity/opportunity.discover.js +6 -4
- package/dist/opportunity/opportunity.discover.js.map +1 -1
- package/dist/opportunity/opportunity.enricher.js +2 -2
- package/dist/opportunity/opportunity.enricher.js.map +1 -1
- package/dist/opportunity/opportunity.evaluator.d.ts.map +1 -1
- package/dist/opportunity/opportunity.evaluator.js +9 -7
- package/dist/opportunity/opportunity.evaluator.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
- package/dist/opportunity/opportunity.graph.js +123 -105
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/opportunity.introducer.js +5 -5
- package/dist/opportunity/opportunity.introducer.js.map +1 -1
- package/dist/opportunity/opportunity.persist.js +2 -2
- package/dist/opportunity/opportunity.persist.js.map +1 -1
- package/dist/opportunity/opportunity.presenter.d.ts.map +1 -1
- package/dist/opportunity/opportunity.presenter.js +4 -2
- package/dist/opportunity/opportunity.presenter.js.map +1 -1
- package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
- package/dist/opportunity/opportunity.tools.js +2 -1
- package/dist/opportunity/opportunity.tools.js.map +1 -1
- package/dist/opportunity/opportunity.utils.d.ts.map +1 -1
- package/dist/opportunity/opportunity.utils.js +29 -5
- package/dist/opportunity/opportunity.utils.js.map +1 -1
- package/dist/premise/premise.analyzer.d.ts.map +1 -1
- package/dist/premise/premise.analyzer.js +3 -2
- package/dist/premise/premise.analyzer.js.map +1 -1
- package/dist/premise/premise.decomposer.d.ts.map +1 -1
- package/dist/premise/premise.decomposer.js +12 -3
- package/dist/premise/premise.decomposer.js.map +1 -1
- package/dist/premise/premise.graph.d.ts.map +1 -1
- package/dist/premise/premise.graph.js +19 -9
- package/dist/premise/premise.graph.js.map +1 -1
- package/dist/premise/premise.indexer.d.ts.map +1 -1
- package/dist/premise/premise.indexer.js +2 -1
- package/dist/premise/premise.indexer.js.map +1 -1
- package/dist/premise/premise.tools.d.ts.map +1 -1
- package/dist/premise/premise.tools.js +8 -4
- package/dist/premise/premise.tools.js.map +1 -1
- package/dist/shared/agent/tool.factory.d.ts.map +1 -1
- package/dist/shared/agent/tool.factory.js +4 -2
- package/dist/shared/agent/tool.factory.js.map +1 -1
- package/dist/shared/agent/tool.registry.d.ts.map +1 -1
- package/dist/shared/agent/tool.registry.js +6 -4
- package/dist/shared/agent/tool.registry.js.map +1 -1
- package/dist/shared/interfaces/database.interface.d.ts +1 -1
- package/dist/shared/interfaces/database.interface.js.map +1 -1
- package/dist/shared/observability/log.d.ts +3 -2
- package/dist/shared/observability/log.d.ts.map +1 -1
- package/dist/shared/observability/log.js +72 -9
- package/dist/shared/observability/log.js.map +1 -1
- package/dist/shared/observability/protocol.logger.d.ts.map +1 -1
- package/dist/shared/observability/protocol.logger.js +5 -3
- package/dist/shared/observability/protocol.logger.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.tools.js","sourceRoot":"/","sources":["network/network.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAG9E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,8EAA8E;AAC9E,0EAA0E;AAC1E,IAAI,WAA2C,CAAC;AAEhD,MAAM,UAAU,kBAAkB,CAAC,UAAsB,EAAE,IAAc;IACvE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE1C,MAAM,iBAAiB,GAAG,CAAC,QAAwC,EAAE,EAAE,CACrE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnB,GAAG,CAAC;QACJ,eAAe,EAAE,oBAAoB,CAAC;YACpC,IAAI,EAAG,CAAC,CAAC,IAAe,IAAI,WAAW;YACvC,KAAK,EAAG,CAAC,CAAC,KAAgB,IAAI,EAAE;YAChC,MAAM,EAAE,CAAC,CAAC,MAA4B;YACtC,QAAQ,EAAG,CAAC,CAAC,QAAoC,IAAI,EAAE;SACxD,CAAC;KACH,CAAC,CAAC,CAAC;IAEN,MAAM,WAAW,GAAG,UAAU,CAAC;QAC7B,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,0HAA0H;YAC1H,sIAAsI;YACtI,2DAA2D;YAC3D,mIAAmI;YACnI,2IAA2I;YAC3I,uBAAuB;YACvB,iHAAiH;YACjH,4KAA4K;QAC9K,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+EAA+E,CAAC;SACxH,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC3D,OAAO,KAAK,CAAC,oFAAoF,CAAC,CAAC;YACrG,CAAC;YAED,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACxC,MAAM,sBAAsB,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;YACvE,sBAAsB,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACjE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;gBACzC,aAAa,EAAE,MAAe;gBAC9B,OAAO,EAAE,KAAK,EAAE,gDAAgD;aACjE,CAAC,CAAC;YACH,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,CAAC;YAC5D,sBAAsB,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAE9F,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;YACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,MAAM,EAAE,GAAG,MAAM,CAAC,UAAqC,CAAC;gBACxD,MAAM,QAAQ,GAAG;oBACf,GAAG,EAAE;oBACL,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,EAAE,CAAC,QAA0C,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrH,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC,IAAsC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,iBAAiB,CAAC,EAAE,CAAC,cAAgD,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACxI,CAAC;gBAEF,qEAAqE;gBACrE,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;oBACtB,OAAO,OAAO,CAAC;wBACb,GAAG,QAAQ;wBACX,gBAAgB,EAAE;4BAChB,QAAQ,EAAE,IAAI;4BACd,aAAa,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;4BACrD,OAAO,EAAE,2BAA2B,OAAO,CAAC,SAAS,IAAI,cAAc,2GAA2G;yBACnL;wBACD,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;qBACrG,CAAC,CAAC;gBACL,CAAC;gBACD,0EAA0E;gBAC1E,4EAA4E;gBAC5E,0EAA0E;gBAC1E,6EAA6E;gBAC7E,IAAI,iBAAuC,CAAC;gBAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjG,IACE,OAAO,CAAC,YAAY;oBACpB,WAAW;oBACX,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;oBACrC,QAAQ,CAAC,cAAiD,CAAC,MAAM,GAAG,CAAC,EACtE,CAAC;oBACD,+FAA+F;oBAC/F,MAAM,wBAAwB,GAAI,QAAQ,CAAC,cAAiD;yBACzF,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;yBACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACX,SAAS,EAAE,CAAC,CAAC,SAAmB;wBAChC,eAAe,EAAG,CAAC,CAAC,eAA0B,IAAI,MAAM,CAAC,CAAC,KAAe,EAAE;qBAC5E,CAAC,CAAC,CAAC;oBACN,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;wBACpD,IAAI,CAAC;4BACH,WAAW,KAAX,WAAW,GAAK,IAAI,kBAAkB,EAAE,EAAC;4BACzC,OAAO,MAAM,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACzC,CAAC;wBAAC,OAAO,GAAG,EAAE,CAAC;4BACb,+EAA+E;4BAC/E,OAAO,CAAC,IAAI,CAAC,mEAAmE,EAAE,GAAG,CAAC,CAAC;4BACvF,OAAO,IAAI,CAAC;wBACd,CAAC;oBACH,CAAC,CAAC,CAAC;oBACH,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC;wBACjC,WAAW;wBACX,QAAQ,EAAE,wBAAwB;qBACnC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;wBACxB,wEAAwE;wBACxE,kFAAkF;wBAClF,OAAO,CAAC,IAAI,CAAC,wDAAwD,EAAE,GAAG,CAAC,CAAC;wBAC5E,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;wBACjH,OAAO,IAAI,CAAC;oBACd,CAAC,CAAC,CAAC;oBACH,IAAI,aAAa,EAAE,CAAC;wBAClB,0DAA0D;wBAC1D,mEAAmE;wBACnE,qEAAqE;wBACrE,sEAAsE;wBACtE,6DAA6D;wBAC7D,MAAM,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;wBAClE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;wBAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;wBAChC,KAAK,MAAM,EAAE,IAAI,aAAa,CAAC,gBAAgB,EAAE,CAAC;4BAChD,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gCACxC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gCACpB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;4BACf,CAAC;wBACH,CAAC;wBACD,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;4BAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gCAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBACzC,CAAC;wBACD,iBAAiB,GAAG,UAAU,CAAC;oBACjC,CAAC;gBACH,CAAC;gBAED,OAAO,OAAO,CAAC;oBACb,GAAG,QAAQ;oBACX,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjE,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;iBACrG,CAAC,CAAC;YACL,CAAC;YACD,OAAO,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACrD,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,oBAAoB,GAAG,UAAU,CAAC;QACtC,IAAI,EAAE,0BAA0B;QAChC,WAAW,EACT,wHAAwH;YACxH,kDAAkD;YAClD,oBAAoB;YACpB,kJAAkJ;YAClJ,iGAAiG;YACjG,8IAA8I;YAC9I,4IAA4I;YAC5I,2HAA2H;YAC3H,wDAAwD;YACxD,sHAAsH;YACtH,4GAA4G;YAC5G,6GAA6G;YAC7G,0CAA0C;YAC1C,oGAAoG;YACpG,sGAAsG;YACtG,gGAAgG;YAChG,wGAAwG;YACxG,uCAAuC;QACzC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0IAA0I,CAAC;YACrL,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2KAA2K,CAAC;SACpN,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;YACvD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;YAEjD,IAAI,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7C,OAAO,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACpF,CAAC;YAED,mCAAmC;YACnC,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzB,oFAAoF;gBACpF,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;oBACzD,OAAO,KAAK,CACV,0BAA0B,OAAO,CAAC,SAAS,IAAI,cAAc,+CAA+C,CAC7G,CAAC;gBACJ,CAAC;gBAED,MAAM,sBAAsB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC1C,MAAM,wBAAwB,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;gBACzE,wBAAwB,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;gBAChF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC;oBACnD,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,SAAS;oBACT,aAAa,EAAE,MAAe;iBAC/B,CAAC,CAAC;gBACH,MAAM,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,sBAAsB,CAAC;gBAChE,wBAAwB,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBAE/G,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjB,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7B,CAAC;gBACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBACtB,OAAO,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;gBAChK,CAAC;gBACD,OAAO,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACnD,CAAC;YAED,6DAA6D;YAC7D,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;YAE9C,+FAA+F;YAC/F,IAAI,WAAqE,CAAC;YAC1E,IAAI,YAAY,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpC,sEAAsE;gBACtE,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,qBAAqB,EAAE,CAAC;gBAC/D,IAAI,SAAS,EAAE,CAAC;oBACd,wFAAwF;oBACxF,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;wBACzD,OAAO,KAAK,CACV,0BAA0B,OAAO,CAAC,SAAS,IAAI,cAAc,oDAAoD,CAClH,CAAC;oBACJ,CAAC;oBAED,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;oBAC/E,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,OAAO,KAAK,CACV,mJAAmJ,CACpJ,CAAC;oBACJ,CAAC;oBACD,kEAAkE;oBAClE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;oBACzE,IAAI,QAAQ,EAAE,CAAC;wBACb,OAAO,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;oBACtE,CAAC;oBACD,OAAO,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,uCAAuC,EAAE,CAAC,CAAC;gBACzH,CAAC;qBAAM,CAAC;oBACN,qFAAqF;oBACrF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;wBACtB,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;wBACjF,IAAI,QAAQ,EAAE,CAAC;4BACb,OAAO,OAAO,CAAC;gCACb,QAAQ,EAAE,IAAI;gCACd,MAAM,EAAE,YAAY;gCACpB,SAAS,EAAE,OAAO,CAAC,SAAS;gCAC5B,gBAAgB,EAAE;oCAChB,QAAQ,EAAE,IAAI;oCACd,aAAa,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;oCACrD,OAAO,EAAE,2BAA2B,OAAO,CAAC,SAAS,IAAI,cAAc,gDAAgD;iCACxH;6BACF,CAAC,CAAC;wBACL,CAAC;wBACD,OAAO,OAAO,CAAC;4BACb,QAAQ,EAAE,KAAK;4BACf,MAAM,EAAE,YAAY;4BACpB,SAAS,EAAE,OAAO,CAAC,SAAS;4BAC5B,OAAO,EAAE,yCAAyC;4BAClD,gBAAgB,EAAE;gCAChB,QAAQ,EAAE,IAAI;gCACd,aAAa,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;gCACrD,OAAO,EAAE,2BAA2B,OAAO,CAAC,SAAS,IAAI,cAAc,mDAAmD;6BAC3H;yBACF,CAAC,CAAC;oBACL,CAAC;oBAED,mGAAmG;oBACnG,MAAM,aAAa,GAA6B,EAAE,CAAC;oBACnD,KAAK,MAAM,CAAC,IAAI,iBAAiB,EAAE,CAAC;wBAClC,IAAI,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,CAAC;4BAC9D,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBACxB,CAAC;oBACH,CAAC;oBACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC/B,OAAO,KAAK,CACV,8HAA8H,CAC/H,CAAC;oBACJ,CAAC;oBACD,0CAA0C;oBAC1C,OAAO,OAAO,CAAC;wBACb,MAAM,EAAE,YAAY;wBACpB,KAAK,EAAE,aAAa,CAAC,MAAM;wBAC3B,WAAW,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BACrC,SAAS,EAAE,CAAC,CAAC,SAAS;4BACtB,YAAY,EAAE,CAAC,CAAC,YAAY;yBAC7B,CAAC,CAAC;wBACH,IAAI,EAAE,+BAA+B;qBACtC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,+BAA+B;gBAC/B,WAAW,GAAG,MAAM,MAAM,CAAC,qBAAqB,EAAE,CAAC;gBAEnD,8EAA8E;gBAC9E,0EAA0E;gBAC1E,gFAAgF;gBAChF,mGAAmG;gBACnG,IAAI,OAAO,CAAC,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpC,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;gBAC7E,CAAC;YACH,CAAC;YAED,mEAAmE;YACnE,IAAI,SAAS,EAAE,CAAC;gBACd,wFAAwF;gBACxF,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;oBACzD,OAAO,KAAK,CACV,0BAA0B,OAAO,CAAC,SAAS,IAAI,cAAc,oDAAoD,CAClH,CAAC;gBACJ,CAAC;gBAED,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,qBAAqB,EAAE,CAAC;gBAC/D,MAAM,aAAa,GACjB,YAAY,KAAK,OAAO,CAAC,MAAM;oBAC/B,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;gBAC3D,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,OAAO,KAAK,CACV,uEAAuE,CACxE,CAAC;gBACJ,CAAC;gBACD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;gBACjE,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,uCAAuC,EAAE,CAAC,CAAC;gBACzH,CAAC;gBACD,OAAO,OAAO,CAAC;oBACb,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,YAAY;oBACpB,SAAS;oBACT,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;iBACzB,CAAC,CAAC;YACL,CAAC;YAED,qEAAqE;YACrE,IAAI,OAAO,CAAC,SAAS,IAAI,YAAY,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;gBACzD,OAAO,OAAO,CAAC;oBACb,MAAM,EAAE,YAAY;oBACpB,KAAK,EAAE,WAAW,CAAC,MAAM;oBACzB,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACnC,SAAS,EAAE,CAAC,CAAC,SAAS;wBACtB,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,WAAW,EAAE,CAAC,CAAC,WAAW;wBAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;qBACrB,CAAC,CAAC;oBACH,gBAAgB,EAAE;wBAChB,QAAQ,EAAE,IAAI;wBACd,aAAa,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;wBACrD,OAAO,EAAE,2BAA2B,OAAO,CAAC,SAAS,IAAI,cAAc,2GAA2G;qBACnL;iBACF,CAAC,CAAC;YACL,CAAC;YAED,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,YAAY;gBACpB,KAAK,EAAE,WAAW,CAAC,MAAM;gBACzB,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACnC,SAAS,EAAE,CAAC,CAAC,SAAS;oBACtB,YAAY,EAAE,CAAC,CAAC,YAAY;oBAC5B,WAAW,EAAE,CAAC,CAAC,WAAW;oBAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;iBACrB,CAAC,CAAC;aACJ,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;QAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAChD,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE;QACxD,mBAAmB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;KAC5C,CAAC,CAAC,MAAM,EAAE,CAAC;IAEZ,MAAM,aAAa,GAAG,UAAU,CAAC;QAC/B,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,sGAAsG;YACtG,4GAA4G;YAC5G,uIAAuI;YACvI,0HAA0H;YAC1H,qEAAqE;YACrE,mHAAmH;YACnH,uEAAuE;YACvE,wEAAwE;QAC1E,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uGAAuG,CAAC;YAClJ,QAAQ,EAAE,2BAA2B,CAAC,QAAQ,CAAC,mSAAmS,CAAC;SACpV,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,MAAM,gBAAgB,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;YAChF,IAAI,CAAC,gBAAgB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC5D,OAAO,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC5C,CAAC;YAED,wFAAwF;YACxF,IAAI,OAAO,CAAC,SAAS,IAAI,gBAAgB,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;gBAChE,OAAO,KAAK,CACV,0BAA0B,OAAO,CAAC,SAAS,IAAI,cAAc,kDAAkD,CAChH,CAAC;YACJ,CAAC;YAED,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5C,MAAM,0BAA0B,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;YAC3E,0BAA0B,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,gBAAgB;gBAC3B,aAAa,EAAE,QAAiB;gBAChC,WAAW,EAAE,KAAK,CAAC,QAAQ;aAC5B,CAAC,CAAC;YACH,MAAM,qBAAqB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,wBAAwB,CAAC;YACpE,0BAA0B,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC,CAAC;YAEtG,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC5D,OAAO,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,IAAI,yBAAyB,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACjM,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,UAAU,CAAC;QAC/B,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,uIAAuI;YACvI,qIAAqI;YACrI,wGAAwG;YACxG,oIAAoI;YACpI,2HAA2H;YAC3H,+FAA+F;QACjG,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oFAAoF,CAAC;YAChH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iQAAiQ,CAAC;YACzS,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;YACjG,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sHAAsH,CAAC;SAC1L,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACrC,CAAC;YAED,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5C,MAAM,0BAA0B,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;YAC3E,0BAA0B,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,aAAa,EAAE,QAAiB;gBAChC,WAAW,EAAE;oBACX,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;oBACzB,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS;oBACzC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;oBACrC,UAAU,EAAE,KAAK,CAAC,UAAU;iBAC7B;aACF,CAAC,CAAC;YACH,MAAM,qBAAqB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,wBAAwB,CAAC;YACpE,0BAA0B,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC,CAAC;YAEtG,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC1B,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;oBAClC,OAAO,OAAO,CAAC;wBACb,OAAO,EAAE,IAAI;wBACb,SAAS,EAAE,MAAM,CAAC,cAAc,CAAC,SAAS;wBAC1C,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK;wBAClC,OAAO,EAAE,MAAM,CAAC,cAAc,CAAC,OAAO;wBACtC,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;qBACzG,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,IAAI,2BAA2B,CAAC,CAAC;YAC3E,CAAC;YACD,OAAO,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC5C,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,UAAU,CAAC;QAC/B,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,mHAAmH;YACnH,qGAAqG;YACrG,gJAAgJ;YAChJ,oGAAoG;YACpG,yDAAyD;QAC3D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qIAAqI,CAAC;SACjL,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,CAAC;YAC/D,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9C,OAAO,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC5C,CAAC;YAED,wFAAwF;YACxF,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;gBACzD,OAAO,KAAK,CACV,0BAA0B,OAAO,CAAC,SAAS,IAAI,cAAc,uCAAuC,CACrG,CAAC;YACJ,CAAC;YAED,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5C,MAAM,0BAA0B,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;YAC3E,0BAA0B,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBACvC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS;gBACT,aAAa,EAAE,QAAiB;aACjC,CAAC,CAAC;YACH,MAAM,qBAAqB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,wBAAwB,CAAC;YACpE,0BAA0B,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC,CAAC;YAEtG,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC5D,OAAO,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,IAAI,2BAA2B,CAAC,CAAC;YAC3E,CAAC;YACD,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5J,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,uBAAuB,GAAG,UAAU,CAAC;QACzC,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,iIAAiI;YACjI,oDAAoD;YACpD,oBAAoB;YACpB,gFAAgF;YAChF,qGAAqG;YACrG,sHAAsH;YACtH,mGAAmG;YACnG,2GAA2G;QAC7G,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8IAA8I,CAAC;YACtL,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kHAAkH,CAAC;SAC9J,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,CAAC;YAC/D,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC;YAC5D,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9C,OAAO,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACpF,CAAC;YAED,yFAAyF;YACzF,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;gBACzD,OAAO,KAAK,CACV,0BAA0B,OAAO,CAAC,SAAS,IAAI,cAAc,+CAA+C,CAC7G,CAAC;YACJ,CAAC;YAED,MAAM,2BAA2B,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/C,MAAM,6BAA6B,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;YAC9E,6BAA6B,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACrF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC;gBACnD,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS;gBACT,YAAY;gBACZ,aAAa,EAAE,QAAiB;aACjC,CAAC,CAAC;YACH,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,2BAA2B,CAAC;YAC1E,6BAA6B,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAEzH,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC1B,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;oBAClC,MAAM,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;oBACzE,OAAO,OAAO,CAAC;wBACb,OAAO,EAAE,CAAC,aAAa;wBACvB,OAAO,EAAE,MAAM,CAAC,cAAc,CAAC,OAAO;wBACtC,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;qBACzH,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAC;YACvE,CAAC;YACD,OAAO,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACxC,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,uBAAuB,GAAG,UAAU,CAAC;QACzC,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,8GAA8G;YAC9G,4EAA4E;YAC5E,sIAAsI;YACtI,qFAAqF;YACrF,8FAA8F;YAC9F,wDAAwD;QAC1D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6GAA6G,CAAC;YAC1I,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uHAAuH,CAAC;SACnK,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,CAAC;YAC/D,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;YAE1C,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9C,OAAO,KAAK,CAAC,kEAAkE,CAAC,CAAC;YACnF,CAAC;YACD,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACtC,CAAC;YAED,+EAA+E;YAC/E,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;gBACzD,OAAO,KAAK,CACV,0BAA0B,OAAO,CAAC,SAAS,IAAI,cAAc,kDAAkD,CAChH,CAAC;YACJ,CAAC;YAED,MAAM,2BAA2B,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/C,MAAM,6BAA6B,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;YAC9E,6BAA6B,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACrF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC;gBACnD,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS;gBACT,YAAY;gBACZ,aAAa,EAAE,QAAiB;aACjC,CAAC,CAAC;YACH,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,2BAA2B,CAAC;YAC1E,6BAA6B,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAEzH,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC1B,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;oBAClC,OAAO,OAAO,CAAC;wBACb,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,MAAM,CAAC,cAAc,CAAC,OAAO;wBACtC,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;qBACzH,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,IAAI,0BAA0B,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,uBAAuB,EAAE,uBAAuB,CAAU,CAAC;AACrJ,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { requestContext } from \"../shared/observability/request-context.js\";\nimport { renderNetworkContext } from '../shared/network/metadata.renderer.js';\n\nimport type { DefineTool, ToolDeps } from \"../shared/agent/tool.helpers.js\";\nimport { success, error, UUID_REGEX } from \"../shared/agent/tool.helpers.js\";\nimport { NetworkRecommender } from \"./network.recommender.js\";\n\n// Lazy singleton — only instantiated on first onboarding ranking call so that\n// importing this module does not require OPENROUTER_API_KEY at load time.\nlet recommender: NetworkRecommender | undefined;\n\nexport function createNetworkTools(defineTool: DefineTool, deps: ToolDeps) {\n const { graphs, userDb, systemDb } = deps;\n\n const enrichWithContext = (networks: Array<Record<string, unknown>>) =>\n networks.map((n) => ({\n ...n,\n renderedContext: renderNetworkContext({\n type: (n.type as string) ?? 'community',\n title: (n.title as string) ?? '',\n prompt: n.prompt as string | undefined,\n metadata: (n.metadata as Record<string, unknown>) ?? {},\n }),\n }));\n\n const readIndexes = defineTool({\n name: \"read_networks\",\n description:\n \"Lists the authenticated user's networks (communities), including ones they own and public communities they can join.\\n\\n\" +\n \"**When to use:** To find network IDs for scoping other operations (read_intents, discover_opportunities, read_network_memberships), \" +\n \"or to show the user which communities they belong to.\\n\\n\" +\n \"**Returns:** Up to three lists — `memberOf` (networks the user joined), `owns` (networks the user created), and `publicNetworks` \" +\n \"(publicly joinable communities the user is not yet a member of). Entries in `memberOf` include `isPersonal` set to `true` for the user's \" +\n \"personal network.\\n\\n\" +\n \"**Note:** In network-scoped chats, only the scoped network is returned. During onboarding, `orderedNetworkIds` \" +\n \"may be returned alongside `publicNetworks` \\u2014 a ranked array of network IDs ordered by relevance to the user's profile (omitted when ranking is unavailable or fails).\",\n querySchema: z.object({\n userId: z.string().optional().describe(\"Must be the current user's ID or omitted. Cannot list another user's indexes.\"),\n }),\n handler: async ({ context, query }) => {\n if (query.userId && query.userId.trim() !== context.userId) {\n return error(\"You can only list your own indexes. Omit userId to see the current user's indexes.\");\n }\n\n const _readIndexGraphStart = Date.now();\n const _readIndexTraceEmitter = requestContext.getStore()?.traceEmitter;\n _readIndexTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n networkId: context.networkId || undefined,\n operationMode: 'read' as const,\n showAll: false, // Never allow bypass - strict scope enforcement\n });\n const _readIndexGraphMs = Date.now() - _readIndexGraphStart;\n _readIndexTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _readIndexGraphMs });\n\n if (result.error) {\n return error(result.error);\n }\n if (result.readResult) {\n const rr = result.readResult as Record<string, unknown>;\n const enriched = {\n ...rr,\n ...(Array.isArray(rr.memberOf) ? { memberOf: enrichWithContext(rr.memberOf as Array<Record<string, unknown>>) } : {}),\n ...(Array.isArray(rr.owns) ? { owns: enrichWithContext(rr.owns as Array<Record<string, unknown>>) } : {}),\n ...(Array.isArray(rr.publicNetworks) ? { publicNetworks: enrichWithContext(rr.publicNetworks as Array<Record<string, unknown>>) } : {}),\n };\n\n // When scoped, add clear metadata so model knows results are limited\n if (context.networkId) {\n return success({\n ...enriched,\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `Results are limited to \"${context.indexName ?? 'this network'}\" because this chat is scoped to that community. The user may belong to other communities not shown here.`,\n },\n _graphTimings: [{ name: 'index', durationMs: _readIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n // Onboarding-only: rank public networks by relevance to the user's global\n // user_context paragraph (the profile-replacing identity text). Guard: only\n // when isOnboarding, not scoped, there are public networks to rank, and a\n // user_context is resolvable (generated on demand by the injected resolver).\n let orderedNetworkIds: string[] | undefined;\n const userContext = deps.getUserContextText ? await deps.getUserContextText(context.userId) : \"\";\n if (\n context.isOnboarding &&\n userContext &&\n Array.isArray(enriched.publicNetworks) &&\n (enriched.publicNetworks as Array<Record<string, unknown>>).length > 0\n ) {\n // Cap at 50 to bound LLM context window usage (matches the UI's discoverPublicIndexes(1, 50)).\n const publicNetworksForRanking = (enriched.publicNetworks as Array<Record<string, unknown>>)\n .slice(0, 50)\n .map((n) => ({\n networkId: n.networkId as string,\n renderedContext: (n.renderedContext as string) ?? `## ${n.title as string}`,\n }));\n const rankFn = deps.networkRanker ?? (async (input) => {\n try {\n recommender ??= new NetworkRecommender();\n return await recommender.invoke(input);\n } catch (err) {\n // e.g. missing OPENROUTER_API_KEY — degrade gracefully, omit orderedNetworkIds\n console.warn(\"[read_networks] NetworkRecommender unavailable, skipping ranking:\", err);\n return null;\n }\n });\n const rankingResult = await rankFn({\n userContext,\n networks: publicNetworksForRanking,\n }).catch((err: unknown) => {\n // Catches errors from a custom deps.networkRanker (the default fallback\n // handles its own errors internally). Degrade gracefully: omit orderedNetworkIds.\n console.warn(\"[read_networks] networkRanker threw, skipping ranking:\", err);\n deps.reportToolError?.(err, { operation: \"network-ranking\", toolName: \"read_networks\", userId: context.userId });\n return null;\n });\n if (rankingResult) {\n // Normalize LLM output against the ranked slice (top 50):\n // keep only IDs from the input set, de-dupe preserving order, then\n // append any slice IDs the model omitted. Networks beyond the top-50\n // slice are not in orderedNetworkIds and will sort to the tail in the\n // frontend (consistent with the UI's own 50-item page size).\n const inputIds = publicNetworksForRanking.map((n) => n.networkId);\n const inputIdSet = new Set(inputIds);\n const seen = new Set<string>();\n const normalized: string[] = [];\n for (const id of rankingResult.rankedNetworkIds) {\n if (inputIdSet.has(id) && !seen.has(id)) {\n normalized.push(id);\n seen.add(id);\n }\n }\n for (const id of inputIds) {\n if (!seen.has(id)) normalized.push(id);\n }\n orderedNetworkIds = normalized;\n }\n }\n\n return success({\n ...enriched,\n ...(orderedNetworkIds !== undefined ? { orderedNetworkIds } : {}),\n _graphTimings: [{ name: 'index', durationMs: _readIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(\"Failed to fetch index information.\");\n },\n });\n\n const readIndexMemberships = defineTool({\n name: \"read_network_memberships\",\n description:\n \"Reads network membership information — who is in which community. Essential for understanding the social graph before \" +\n \"creating introductions or exploring intents.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- With `networkId` only: lists ALL members of that index — returns userId, name, avatar, permissions (owner/member), intentCount, and joinedAt. \" +\n \"Use this to see who's in a community before browsing their intents or creating introductions.\\n\" +\n \"- With `userId` only (or omit for self): lists all networks that user belongs to — returns networkId, networkTitle, permissions, joinedAt.\\n\" +\n \"- With both `networkId` and `userId`: checks whether that specific user is a member of that specific index (returns isMember boolean).\\n\\n\" +\n \"**When to use:** Before creating introductions (need to verify shared network membership), to explore community members, \" +\n \"or to check if a user belongs to a specific index.\\n\\n\" +\n \"**Returns:** Member list with user details, or membership list with index details, or a membership check result.\\n\\n\" +\n \"**Personal network semantics.** The personal network (`isPersonal: true` on the membership) is the user's \" +\n \"contact list — members of that index are the user's contacts. For another user, this tool only reveals the \" +\n \"indexes you already share with them.\\n\\n\" +\n \"**Shared-context pattern.** To find overlap with another user: (1) omit `userId` to read your own \" +\n \"memberships, (2) call this tool with the other person's actual `userId` to get the shared networks, \" +\n \"(3) call read_intents for each shared network to see what each is looking for there, (4) call \" +\n \"read_user_contexts for the other party. That sequence gives you enough to decide whether to propose a \" +\n \"direct connection or an introduction.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Network UUID — lists all members of this network. Get from read_networks. In network-scoped chats, only the scoped index can be queried.\"),\n userId: z.string().optional().describe(\"User ID — lists that user's network memberships. Omit to get the current user's memberships. When combined with networkId, checks if this user is in that specific index.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || undefined;\n const userId = query.userId?.trim() || undefined;\n\n if (networkId && !UUID_REGEX.test(networkId)) {\n return error(\"Invalid network ID format. Use the exact UUID from read_networks.\");\n }\n\n // Mode 1: list members of an index\n if (networkId && !userId) {\n // Enforce strict scope: when chat is network-scoped, only allow querying that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only query members of this network.`\n );\n }\n\n const _readMembersGraphStart = Date.now();\n const _readMembersTraceEmitter = requestContext.getStore()?.traceEmitter;\n _readMembersTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const result = await graphs.networkMembership.invoke({\n userId: context.userId,\n networkId,\n operationMode: 'read' as const,\n });\n const _readMembersGraphMs = Date.now() - _readMembersGraphStart;\n _readMembersTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _readMembersGraphMs });\n\n if (result.error) {\n return error(result.error);\n }\n if (result.readResult) {\n return success({ ...result.readResult, _graphTimings: [{ name: 'network_membership', durationMs: _readMembersGraphMs, agents: result.agentTimings ?? [] }] });\n }\n return error(\"Failed to fetch network members.\");\n }\n\n // Mode 2: list a user's memberships (indexes they belong to)\n const targetUserId = userId || context.userId;\n\n // Use userDb for own memberships, but systemDb access is implicit through shared network scope\n let memberships: Awaited<ReturnType<typeof userDb.getNetworkMemberships>>;\n if (targetUserId !== context.userId) {\n // Cross-user access: systemDb will validate shared network membership\n const callerMemberships = await userDb.getNetworkMemberships();\n if (networkId) {\n // Strict scope enforcement: when chat is network-scoped, only allow querying that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only query membership in this community.`\n );\n }\n\n const callerInIndex = callerMemberships.some((m) => m.networkId === networkId);\n if (!callerInIndex) {\n return error(\n \"Unauthorized: you can only view another user's membership in an index you belong to. Provide your own userId or omit userId for your memberships.\",\n );\n }\n // Check if target user is in the index (systemDb validates scope)\n const isMember = await systemDb.isNetworkMember(networkId, targetUserId);\n if (isMember) {\n return success({ isMember: true, userId: targetUserId, networkId });\n }\n return success({ isMember: false, userId: targetUserId, networkId, message: \"User is not a member of this network.\" });\n } else {\n // Strict scope enforcement: when chat is network-scoped, only check the scoped index\n if (context.networkId) {\n const isMember = await systemDb.isNetworkMember(context.networkId, targetUserId);\n if (isMember) {\n return success({\n isMember: true,\n userId: targetUserId,\n networkId: context.networkId,\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `This chat is scoped to \"${context.indexName ?? 'this network'}\". Only membership in this community is shown.`,\n },\n });\n }\n return success({\n isMember: false,\n userId: targetUserId,\n networkId: context.networkId,\n message: \"User is not a member of this community.\",\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `This chat is scoped to \"${context.indexName ?? 'this network'}\". Only membership in this community was checked.`,\n },\n });\n }\n\n // Unscoped chat: show overlap with shared networks (intersection of caller and target memberships)\n const sharedIndexes: typeof callerMemberships = [];\n for (const m of callerMemberships) {\n if (await systemDb.isNetworkMember(m.networkId, targetUserId)) {\n sharedIndexes.push(m);\n }\n }\n if (sharedIndexes.length === 0) {\n return error(\n \"Unauthorized: you can only view another user's memberships if you share at least one index, or request your own memberships.\",\n );\n }\n // Return only the indexes that are shared\n return success({\n userId: targetUserId,\n count: sharedIndexes.length,\n memberships: sharedIndexes.map((m) => ({\n networkId: m.networkId,\n networkTitle: m.networkTitle,\n })),\n note: \"Only showing shared networks.\",\n });\n }\n } else {\n // Own memberships - use userDb\n memberships = await userDb.getNetworkMemberships();\n\n // NOTE: context.networkId here is the *focus* of the scoped chat — it filters\n // what we show, not what we can reach. indexScope is the reach; the bound\n // network is one element of it. See IND-306 for the equivalent in read_intents.\n // Strict scope enforcement: when chat is network-scoped, only return the scoped network membership\n if (context.networkId && !networkId) {\n memberships = memberships.filter((m) => m.networkId === context.networkId);\n }\n }\n\n // If both networkId and userId: filter to that specific membership\n if (networkId) {\n // Strict scope enforcement: when chat is network-scoped, only allow querying that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only query membership in this community.`\n );\n }\n\n const callerMemberships = await userDb.getNetworkMemberships();\n const callerInIndex =\n targetUserId === context.userId ||\n callerMemberships.some((m) => m.networkId === networkId);\n if (!callerInIndex) {\n return error(\n \"Unauthorized: you can only view membership in an index you belong to.\",\n );\n }\n const match = memberships.find((m) => m.networkId === networkId);\n if (!match) {\n return success({ isMember: false, userId: targetUserId, networkId, message: \"User is not a member of this network.\" });\n }\n return success({\n isMember: true,\n userId: targetUserId,\n networkId,\n networkTitle: match.networkTitle,\n permissions: match.permissions,\n joinedAt: match.joinedAt,\n });\n }\n\n // When scoped, add clear metadata so model knows results are limited\n if (context.networkId && targetUserId === context.userId) {\n return success({\n userId: targetUserId,\n count: memberships.length,\n memberships: memberships.map((m) => ({\n networkId: m.networkId,\n networkTitle: m.networkTitle,\n permissions: m.permissions,\n joinedAt: m.joinedAt,\n })),\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `Results are limited to \"${context.indexName ?? 'this network'}\" because this chat is scoped to that community. The user may belong to other communities not shown here.`,\n },\n });\n }\n\n return success({\n userId: targetUserId,\n count: memberships.length,\n memberships: memberships.map((m) => ({\n networkId: m.networkId,\n networkTitle: m.networkTitle,\n permissions: m.permissions,\n joinedAt: m.joinedAt,\n })),\n });\n },\n });\n\n const updateNetworkSettingsSchema = z.object({\n title: z.string().optional(),\n prompt: z.string().nullable().optional(),\n imageUrl: z.string().url().nullable().optional(),\n joinPolicy: z.enum(['anyone', 'invite_only']).optional(),\n allowGuestVibeCheck: z.boolean().optional(),\n }).strict();\n\n const updateNetwork = defineTool({\n name: \"update_network\",\n description:\n \"Updates settings of an existing network (community). Only the network owner can perform updates.\\n\\n\" +\n \"**Updatable fields:** title (display name), prompt (purpose description used for intent auto-assignment), \" +\n \"imageUrl (community avatar), joinPolicy ('anyone' for open or 'invite_only'), allowGuestVibeCheck (allow non-members to preview).\\n\\n\" +\n \"**When to use:** When a network owner wants to change their community's settings — e.g. update the purpose description, \" +\n \"change from invite-only to open, or update the community image.\\n\\n\" +\n \"**Important:** Changing the prompt affects how future intents are evaluated for auto-assignment to this network. \" +\n \"Existing intent-network links are not re-evaluated automatically.\\n\\n\" +\n \"**Returns:** Confirmation with the list of settings that were updated.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Network UUID to update. Get from read_networks. Defaults to the scoped index in network-scoped chats.\"),\n settings: updateNetworkSettingsSchema.describe(\"Object with fields to update. All fields are optional — only include the ones to change. title: display name. prompt: purpose description (used for intent auto-assignment). imageUrl: community image URL (null to remove). joinPolicy: 'anyone' or 'invite_only'. allowGuestVibeCheck: boolean.\"),\n }),\n handler: async ({ context, query }) => {\n const effectiveIndexId = (query.networkId?.trim() || context.networkId) ?? null;\n if (!effectiveIndexId || !UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Valid networkId required.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow updating that index\n if (context.networkId && effectiveIndexId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only update this community's settings.`\n );\n }\n\n const _updateNetworkGraphStart = Date.now();\n const _updateNetworkTraceEmitter = requestContext.getStore()?.traceEmitter;\n _updateNetworkTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n networkId: effectiveIndexId,\n operationMode: 'update' as const,\n updateInput: query.settings,\n });\n const _updateNetworkGraphMs = Date.now() - _updateNetworkGraphStart;\n _updateNetworkTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _updateNetworkGraphMs });\n\n if (result.mutationResult && !result.mutationResult.success) {\n return error(result.mutationResult.error || \"Failed to update index.\");\n }\n return success({ message: \"Index updated.\", settings: Object.keys(query.settings), _graphTimings: [{ name: 'index', durationMs: _updateNetworkGraphMs, agents: result.agentTimings ?? [] }] });\n },\n });\n\n const createNetwork = defineTool({\n name: \"create_network\",\n description:\n \"Creates a new network (community/group). The authenticated user becomes the owner with full control over settings and membership.\\n\\n\" +\n \"**What is a network?** A shared space where members post intents (what they're looking for) and the system discovers opportunities \" +\n \"(complementary matches) between members. The network's prompt guides what kinds of intents belong.\\n\\n\" +\n \"**When to use:** When the user wants to create a new community — e.g. a professional network, interest group, or project team.\\n\\n\" +\n \"**Returns:** The new network's networkId (UUID) and title. Use the networkId to add members (create_network_membership), \" +\n \"link intents (create_intent_index), or run discovery (discover_opportunities with networkId).\",\n querySchema: z.object({\n title: z.string().describe(\"Display name of the network (e.g. 'AI Founders Berlin', 'Design Co-op'). Required.\"),\n prompt: z.string().optional().describe(\"Description of what this community is about (e.g. 'Early-stage AI/ML founders in Berlin looking for co-founders, advisors, and investors'). Used by the system to evaluate which intents belong in this network. Highly recommended for better auto-assignment.\"),\n imageUrl: z.string().url().optional().describe(\"URL for the community's avatar/image. Optional.\"),\n joinPolicy: z.enum(['anyone', 'invite_only']).optional().describe(\"'anyone' = open (any user can self-join), 'invite_only' = only the owner can add members. Defaults to 'invite_only'.\"),\n }),\n handler: async ({ context, query }) => {\n if (!query.title?.trim()) {\n return error(\"Title is required.\");\n }\n\n const _createNetworkGraphStart = Date.now();\n const _createNetworkTraceEmitter = requestContext.getStore()?.traceEmitter;\n _createNetworkTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n operationMode: 'create' as const,\n createInput: {\n title: query.title.trim(),\n prompt: query.prompt?.trim() || undefined,\n imageUrl: query.imageUrl || undefined,\n joinPolicy: query.joinPolicy,\n },\n });\n const _createNetworkGraphMs = Date.now() - _createNetworkGraphStart;\n _createNetworkTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _createNetworkGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n created: true,\n networkId: result.mutationResult.networkId,\n title: result.mutationResult.title,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'index', durationMs: _createNetworkGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to create network.\");\n }\n return error(\"Failed to create network.\");\n },\n });\n\n const deleteNetwork = defineTool({\n name: \"delete_network\",\n description:\n \"Permanently deletes a network (community). Only the owner can delete, and the network must have no other members \" +\n \"(remove all members first with delete_network_membership). Personal networks cannot be deleted.\\n\\n\" +\n \"**When to use:** When the owner wants to disband a community. This is irreversible — all intent-network links to this network are removed.\\n\\n\" +\n \"**Prerequisites:** Must be the owner. Must be the sole remaining member (remove others first).\\n\\n\" +\n \"**Returns:** Confirmation that the network was deleted.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Network UUID to delete. Get from read_networks. Defaults to the scoped index in network-scoped chats. Cannot be a personal network.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || context.networkId;\n if (!networkId || !UUID_REGEX.test(networkId)) {\n return error(\"Valid networkId required.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow deleting that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only delete this community.`\n );\n }\n\n const _deleteNetworkGraphStart = Date.now();\n const _deleteNetworkTraceEmitter = requestContext.getStore()?.traceEmitter;\n _deleteNetworkTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n networkId,\n operationMode: 'delete' as const,\n });\n const _deleteNetworkGraphMs = Date.now() - _deleteNetworkGraphStart;\n _deleteNetworkTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _deleteNetworkGraphMs });\n\n if (result.mutationResult && !result.mutationResult.success) {\n return error(result.mutationResult.error || \"Failed to delete network.\");\n }\n return success({ message: \"Network deleted.\", _graphTimings: [{ name: 'index', durationMs: _deleteNetworkGraphMs, agents: result.agentTimings ?? [] }] });\n },\n });\n\n const createNetworkMembership = defineTool({\n name: \"create_network_membership\",\n description:\n \"Adds a user as a member of a network (community). Membership enables the user to post intents in the network and be discovered \" +\n \"by other members through opportunity matching.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- Omit userId: self-join (only works for networks with joinPolicy 'anyone').\\n\" +\n \"- With userId: add another user (only the network owner can do this for 'invite_only' indexes).\\n\\n\" +\n \"**When to use:** When the user wants to join an open community, or when a network owner wants to invite someone.\\n\\n\" +\n \"**Returns:** Confirmation that the member was added (or a note that they were already a member). \" +\n \"After joining, the user's existing intents with autoAssign=true may be evaluated against the new network.\",\n querySchema: z.object({\n userId: z.string().optional().describe(\"User ID to add as a member. Omit to join the network yourself. Get user IDs from read_user_contexts(query=name) or read_network_memberships.\"),\n networkId: z.string().optional().describe(\"Network UUID to add the member to. Get from read_networks. Defaults to the scoped index in network-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || context.networkId;\n const targetUserId = query.userId?.trim() || context.userId;\n if (!networkId || !UUID_REGEX.test(networkId)) {\n return error(\"Invalid network ID format. Use the exact UUID from read_networks.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow adding to that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only add members to this community.`\n );\n }\n\n const _createMembershipGraphStart = Date.now();\n const _createMembershipTraceEmitter = requestContext.getStore()?.traceEmitter;\n _createMembershipTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const result = await graphs.networkMembership.invoke({\n userId: context.userId,\n networkId,\n targetUserId,\n operationMode: 'create' as const,\n });\n const _createMembershipGraphMs = Date.now() - _createMembershipGraphStart;\n _createMembershipTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _createMembershipGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n const alreadyMember = result.mutationResult.message?.includes(\"already\");\n return success({\n created: !alreadyMember,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'network_membership', durationMs: _createMembershipGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to add member.\");\n }\n return error(\"Failed to add member.\");\n },\n });\n\n const deleteNetworkMembership = defineTool({\n name: \"delete_network_membership\",\n description:\n \"Removes a user from a network (community). After removal, the user's intents are unlinked from this network \" +\n \"and they can no longer participate in opportunity discovery within it.\\n\\n\" +\n \"**Permissions:** Only the network owner can remove members. The owner themselves cannot be removed (delete the network instead).\\n\\n\" +\n \"**When to use:** When a network owner wants to remove a member from the community. \" +\n \"Use read_network_memberships(networkId) first to get the userId of the member to remove.\\n\\n\" +\n \"**Returns:** Confirmation that the member was removed.\",\n querySchema: z.object({\n userId: z.string().describe(\"User ID of the member to remove. Get from read_network_memberships(networkId). Cannot be the network owner.\"),\n networkId: z.string().optional().describe(\"Network UUID to remove the member from. Get from read_networks. Defaults to the scoped index in network-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || context.networkId;\n const targetUserId = query.userId?.trim();\n\n if (!networkId || !UUID_REGEX.test(networkId)) {\n return error(\"Valid networkId required. Use the exact UUID from read_networks.\");\n }\n if (!targetUserId) {\n return error(\"userId is required.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only manage members of this community.`\n );\n }\n\n const _deleteMembershipGraphStart = Date.now();\n const _deleteMembershipTraceEmitter = requestContext.getStore()?.traceEmitter;\n _deleteMembershipTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const result = await graphs.networkMembership.invoke({\n userId: context.userId,\n networkId,\n targetUserId,\n operationMode: 'delete' as const,\n });\n const _deleteMembershipGraphMs = Date.now() - _deleteMembershipGraphStart;\n _deleteMembershipTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _deleteMembershipGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n removed: true,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'network_membership', durationMs: _deleteMembershipGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to remove member.\");\n }\n return error(\"Failed to remove member.\");\n },\n });\n\n return [readIndexes, readIndexMemberships, updateNetwork, createNetwork, deleteNetwork, createNetworkMembership, deleteNetworkMembership] as const;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"network.tools.js","sourceRoot":"/","sources":["network/network.tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { requestContext } from \"../shared/observability/request-context.js\";\nimport { log } from \"../shared/observability/log.js\";\nimport { renderNetworkContext } from '../shared/network/metadata.renderer.js';\n\nimport type { DefineTool, ToolDeps } from \"../shared/agent/tool.helpers.js\";\nimport { success, error, UUID_REGEX } from \"../shared/agent/tool.helpers.js\";\nimport { NetworkRecommender } from \"./network.recommender.js\";\n\n// Lazy singleton — only instantiated on first onboarding ranking call so that\n// importing this module does not require OPENROUTER_API_KEY at load time.\nlet recommender: NetworkRecommender | undefined;\n\nconst logger = log.protocol.from(\"ChatTools:Network\");\n\nexport function createNetworkTools(defineTool: DefineTool, deps: ToolDeps) {\n const { graphs, userDb, systemDb } = deps;\n\n const enrichWithContext = (networks: Array<Record<string, unknown>>) =>\n networks.map((n) => ({\n ...n,\n renderedContext: renderNetworkContext({\n type: (n.type as string) ?? 'community',\n title: (n.title as string) ?? '',\n prompt: n.prompt as string | undefined,\n metadata: (n.metadata as Record<string, unknown>) ?? {},\n }),\n }));\n\n const readIndexes = defineTool({\n name: \"read_networks\",\n description:\n \"Lists the authenticated user's networks (communities), including ones they own and public communities they can join.\\n\\n\" +\n \"**When to use:** To find network IDs for scoping other operations (read_intents, discover_opportunities, read_network_memberships), \" +\n \"or to show the user which communities they belong to.\\n\\n\" +\n \"**Returns:** Up to three lists — `memberOf` (networks the user joined), `owns` (networks the user created), and `publicNetworks` \" +\n \"(publicly joinable communities the user is not yet a member of). Entries in `memberOf` include `isPersonal` set to `true` for the user's \" +\n \"personal network.\\n\\n\" +\n \"**Note:** In network-scoped chats, only the scoped network is returned. During onboarding, `orderedNetworkIds` \" +\n \"may be returned alongside `publicNetworks` \\u2014 a ranked array of network IDs ordered by relevance to the user's profile (omitted when ranking is unavailable or fails).\",\n querySchema: z.object({\n userId: z.string().optional().describe(\"Must be the current user's ID or omitted. Cannot list another user's indexes.\"),\n }),\n handler: async ({ context, query }) => {\n if (query.userId && query.userId.trim() !== context.userId) {\n return error(\"You can only list your own indexes. Omit userId to see the current user's indexes.\");\n }\n\n const _readIndexGraphStart = Date.now();\n const _readIndexTraceEmitter = requestContext.getStore()?.traceEmitter;\n _readIndexTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n networkId: context.networkId || undefined,\n operationMode: 'read' as const,\n showAll: false, // Never allow bypass - strict scope enforcement\n });\n const _readIndexGraphMs = Date.now() - _readIndexGraphStart;\n _readIndexTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _readIndexGraphMs });\n\n if (result.error) {\n return error(result.error);\n }\n if (result.readResult) {\n const rr = result.readResult as Record<string, unknown>;\n const enriched = {\n ...rr,\n ...(Array.isArray(rr.memberOf) ? { memberOf: enrichWithContext(rr.memberOf as Array<Record<string, unknown>>) } : {}),\n ...(Array.isArray(rr.owns) ? { owns: enrichWithContext(rr.owns as Array<Record<string, unknown>>) } : {}),\n ...(Array.isArray(rr.publicNetworks) ? { publicNetworks: enrichWithContext(rr.publicNetworks as Array<Record<string, unknown>>) } : {}),\n };\n\n // When scoped, add clear metadata so model knows results are limited\n if (context.networkId) {\n return success({\n ...enriched,\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `Results are limited to \"${context.indexName ?? 'this network'}\" because this chat is scoped to that community. The user may belong to other communities not shown here.`,\n },\n _graphTimings: [{ name: 'index', durationMs: _readIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n // Onboarding-only: rank public networks by relevance to the user's global\n // user_context paragraph (the profile-replacing identity text). Guard: only\n // when isOnboarding, not scoped, there are public networks to rank, and a\n // user_context is resolvable (generated on demand by the injected resolver).\n let orderedNetworkIds: string[] | undefined;\n const userContext = deps.getUserContextText ? await deps.getUserContextText(context.userId) : \"\";\n if (\n context.isOnboarding &&\n userContext &&\n Array.isArray(enriched.publicNetworks) &&\n (enriched.publicNetworks as Array<Record<string, unknown>>).length > 0\n ) {\n // Cap at 50 to bound LLM context window usage (matches the UI's discoverPublicIndexes(1, 50)).\n const publicNetworksForRanking = (enriched.publicNetworks as Array<Record<string, unknown>>)\n .slice(0, 50)\n .map((n) => ({\n networkId: n.networkId as string,\n renderedContext: (n.renderedContext as string) ?? `## ${n.title as string}`,\n }));\n const rankFn = deps.networkRanker ?? (async (input) => {\n try {\n recommender ??= new NetworkRecommender();\n return await recommender.invoke(input);\n } catch (err) {\n // e.g. missing OPENROUTER_API_KEY — degrade gracefully, omit orderedNetworkIds\n logger.warn(\"read_networks: NetworkRecommender unavailable, skipping ranking\", { error: err });\n return null;\n }\n });\n const rankingResult = await rankFn({\n userContext,\n networks: publicNetworksForRanking,\n }).catch((err: unknown) => {\n // Catches errors from a custom deps.networkRanker (the default fallback\n // handles its own errors internally). Degrade gracefully: omit orderedNetworkIds.\n logger.warn(\"read_networks: networkRanker threw, skipping ranking\", { error: err });\n deps.reportToolError?.(err, { operation: \"network-ranking\", toolName: \"read_networks\", userId: context.userId });\n return null;\n });\n if (rankingResult) {\n // Normalize LLM output against the ranked slice (top 50):\n // keep only IDs from the input set, de-dupe preserving order, then\n // append any slice IDs the model omitted. Networks beyond the top-50\n // slice are not in orderedNetworkIds and will sort to the tail in the\n // frontend (consistent with the UI's own 50-item page size).\n const inputIds = publicNetworksForRanking.map((n) => n.networkId);\n const inputIdSet = new Set(inputIds);\n const seen = new Set<string>();\n const normalized: string[] = [];\n for (const id of rankingResult.rankedNetworkIds) {\n if (inputIdSet.has(id) && !seen.has(id)) {\n normalized.push(id);\n seen.add(id);\n }\n }\n for (const id of inputIds) {\n if (!seen.has(id)) normalized.push(id);\n }\n orderedNetworkIds = normalized;\n }\n }\n\n return success({\n ...enriched,\n ...(orderedNetworkIds !== undefined ? { orderedNetworkIds } : {}),\n _graphTimings: [{ name: 'index', durationMs: _readIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(\"Failed to fetch index information.\");\n },\n });\n\n const readIndexMemberships = defineTool({\n name: \"read_network_memberships\",\n description:\n \"Reads network membership information — who is in which community. Essential for understanding the social graph before \" +\n \"creating introductions or exploring intents.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- With `networkId` only: lists ALL members of that index — returns userId, name, avatar, permissions (owner/member), intentCount, and joinedAt. \" +\n \"Use this to see who's in a community before browsing their intents or creating introductions.\\n\" +\n \"- With `userId` only (or omit for self): lists all networks that user belongs to — returns networkId, networkTitle, permissions, joinedAt.\\n\" +\n \"- With both `networkId` and `userId`: checks whether that specific user is a member of that specific index (returns isMember boolean).\\n\\n\" +\n \"**When to use:** Before creating introductions (need to verify shared network membership), to explore community members, \" +\n \"or to check if a user belongs to a specific index.\\n\\n\" +\n \"**Returns:** Member list with user details, or membership list with index details, or a membership check result.\\n\\n\" +\n \"**Personal network semantics.** The personal network (`isPersonal: true` on the membership) is the user's \" +\n \"contact list — members of that index are the user's contacts. For another user, this tool only reveals the \" +\n \"indexes you already share with them.\\n\\n\" +\n \"**Shared-context pattern.** To find overlap with another user: (1) omit `userId` to read your own \" +\n \"memberships, (2) call this tool with the other person's actual `userId` to get the shared networks, \" +\n \"(3) call read_intents for each shared network to see what each is looking for there, (4) call \" +\n \"read_user_contexts for the other party. That sequence gives you enough to decide whether to propose a \" +\n \"direct connection or an introduction.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Network UUID — lists all members of this network. Get from read_networks. In network-scoped chats, only the scoped index can be queried.\"),\n userId: z.string().optional().describe(\"User ID — lists that user's network memberships. Omit to get the current user's memberships. When combined with networkId, checks if this user is in that specific index.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || undefined;\n const userId = query.userId?.trim() || undefined;\n\n if (networkId && !UUID_REGEX.test(networkId)) {\n return error(\"Invalid network ID format. Use the exact UUID from read_networks.\");\n }\n\n // Mode 1: list members of an index\n if (networkId && !userId) {\n // Enforce strict scope: when chat is network-scoped, only allow querying that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only query members of this network.`\n );\n }\n\n const _readMembersGraphStart = Date.now();\n const _readMembersTraceEmitter = requestContext.getStore()?.traceEmitter;\n _readMembersTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const result = await graphs.networkMembership.invoke({\n userId: context.userId,\n networkId,\n operationMode: 'read' as const,\n });\n const _readMembersGraphMs = Date.now() - _readMembersGraphStart;\n _readMembersTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _readMembersGraphMs });\n\n if (result.error) {\n return error(result.error);\n }\n if (result.readResult) {\n return success({ ...result.readResult, _graphTimings: [{ name: 'network_membership', durationMs: _readMembersGraphMs, agents: result.agentTimings ?? [] }] });\n }\n return error(\"Failed to fetch network members.\");\n }\n\n // Mode 2: list a user's memberships (indexes they belong to)\n const targetUserId = userId || context.userId;\n\n // Use userDb for own memberships, but systemDb access is implicit through shared network scope\n let memberships: Awaited<ReturnType<typeof userDb.getNetworkMemberships>>;\n if (targetUserId !== context.userId) {\n // Cross-user access: systemDb will validate shared network membership\n const callerMemberships = await userDb.getNetworkMemberships();\n if (networkId) {\n // Strict scope enforcement: when chat is network-scoped, only allow querying that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only query membership in this community.`\n );\n }\n\n const callerInIndex = callerMemberships.some((m) => m.networkId === networkId);\n if (!callerInIndex) {\n return error(\n \"Unauthorized: you can only view another user's membership in an index you belong to. Provide your own userId or omit userId for your memberships.\",\n );\n }\n // Check if target user is in the index (systemDb validates scope)\n const isMember = await systemDb.isNetworkMember(networkId, targetUserId);\n if (isMember) {\n return success({ isMember: true, userId: targetUserId, networkId });\n }\n return success({ isMember: false, userId: targetUserId, networkId, message: \"User is not a member of this network.\" });\n } else {\n // Strict scope enforcement: when chat is network-scoped, only check the scoped index\n if (context.networkId) {\n const isMember = await systemDb.isNetworkMember(context.networkId, targetUserId);\n if (isMember) {\n return success({\n isMember: true,\n userId: targetUserId,\n networkId: context.networkId,\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `This chat is scoped to \"${context.indexName ?? 'this network'}\". Only membership in this community is shown.`,\n },\n });\n }\n return success({\n isMember: false,\n userId: targetUserId,\n networkId: context.networkId,\n message: \"User is not a member of this community.\",\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `This chat is scoped to \"${context.indexName ?? 'this network'}\". Only membership in this community was checked.`,\n },\n });\n }\n\n // Unscoped chat: show overlap with shared networks (intersection of caller and target memberships)\n const sharedIndexes: typeof callerMemberships = [];\n for (const m of callerMemberships) {\n if (await systemDb.isNetworkMember(m.networkId, targetUserId)) {\n sharedIndexes.push(m);\n }\n }\n if (sharedIndexes.length === 0) {\n return error(\n \"Unauthorized: you can only view another user's memberships if you share at least one index, or request your own memberships.\",\n );\n }\n // Return only the indexes that are shared\n return success({\n userId: targetUserId,\n count: sharedIndexes.length,\n memberships: sharedIndexes.map((m) => ({\n networkId: m.networkId,\n networkTitle: m.networkTitle,\n })),\n note: \"Only showing shared networks.\",\n });\n }\n } else {\n // Own memberships - use userDb\n memberships = await userDb.getNetworkMemberships();\n\n // NOTE: context.networkId here is the *focus* of the scoped chat — it filters\n // what we show, not what we can reach. indexScope is the reach; the bound\n // network is one element of it. See IND-306 for the equivalent in read_intents.\n // Strict scope enforcement: when chat is network-scoped, only return the scoped network membership\n if (context.networkId && !networkId) {\n memberships = memberships.filter((m) => m.networkId === context.networkId);\n }\n }\n\n // If both networkId and userId: filter to that specific membership\n if (networkId) {\n // Strict scope enforcement: when chat is network-scoped, only allow querying that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only query membership in this community.`\n );\n }\n\n const callerMemberships = await userDb.getNetworkMemberships();\n const callerInIndex =\n targetUserId === context.userId ||\n callerMemberships.some((m) => m.networkId === networkId);\n if (!callerInIndex) {\n return error(\n \"Unauthorized: you can only view membership in an index you belong to.\",\n );\n }\n const match = memberships.find((m) => m.networkId === networkId);\n if (!match) {\n return success({ isMember: false, userId: targetUserId, networkId, message: \"User is not a member of this network.\" });\n }\n return success({\n isMember: true,\n userId: targetUserId,\n networkId,\n networkTitle: match.networkTitle,\n permissions: match.permissions,\n joinedAt: match.joinedAt,\n });\n }\n\n // When scoped, add clear metadata so model knows results are limited\n if (context.networkId && targetUserId === context.userId) {\n return success({\n userId: targetUserId,\n count: memberships.length,\n memberships: memberships.map((m) => ({\n networkId: m.networkId,\n networkTitle: m.networkTitle,\n permissions: m.permissions,\n joinedAt: m.joinedAt,\n })),\n scopeRestriction: {\n isScoped: true,\n scopedToIndex: context.indexName ?? context.networkId,\n message: `Results are limited to \"${context.indexName ?? 'this network'}\" because this chat is scoped to that community. The user may belong to other communities not shown here.`,\n },\n });\n }\n\n return success({\n userId: targetUserId,\n count: memberships.length,\n memberships: memberships.map((m) => ({\n networkId: m.networkId,\n networkTitle: m.networkTitle,\n permissions: m.permissions,\n joinedAt: m.joinedAt,\n })),\n });\n },\n });\n\n const updateNetworkSettingsSchema = z.object({\n title: z.string().optional(),\n prompt: z.string().nullable().optional(),\n imageUrl: z.string().url().nullable().optional(),\n joinPolicy: z.enum(['anyone', 'invite_only']).optional(),\n allowGuestVibeCheck: z.boolean().optional(),\n }).strict();\n\n const updateNetwork = defineTool({\n name: \"update_network\",\n description:\n \"Updates settings of an existing network (community). Only the network owner can perform updates.\\n\\n\" +\n \"**Updatable fields:** title (display name), prompt (purpose description used for intent auto-assignment), \" +\n \"imageUrl (community avatar), joinPolicy ('anyone' for open or 'invite_only'), allowGuestVibeCheck (allow non-members to preview).\\n\\n\" +\n \"**When to use:** When a network owner wants to change their community's settings — e.g. update the purpose description, \" +\n \"change from invite-only to open, or update the community image.\\n\\n\" +\n \"**Important:** Changing the prompt affects how future intents are evaluated for auto-assignment to this network. \" +\n \"Existing intent-network links are not re-evaluated automatically.\\n\\n\" +\n \"**Returns:** Confirmation with the list of settings that were updated.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Network UUID to update. Get from read_networks. Defaults to the scoped index in network-scoped chats.\"),\n settings: updateNetworkSettingsSchema.describe(\"Object with fields to update. All fields are optional — only include the ones to change. title: display name. prompt: purpose description (used for intent auto-assignment). imageUrl: community image URL (null to remove). joinPolicy: 'anyone' or 'invite_only'. allowGuestVibeCheck: boolean.\"),\n }),\n handler: async ({ context, query }) => {\n const effectiveIndexId = (query.networkId?.trim() || context.networkId) ?? null;\n if (!effectiveIndexId || !UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Valid networkId required.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow updating that index\n if (context.networkId && effectiveIndexId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only update this community's settings.`\n );\n }\n\n const _updateNetworkGraphStart = Date.now();\n const _updateNetworkTraceEmitter = requestContext.getStore()?.traceEmitter;\n _updateNetworkTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n networkId: effectiveIndexId,\n operationMode: 'update' as const,\n updateInput: query.settings,\n });\n const _updateNetworkGraphMs = Date.now() - _updateNetworkGraphStart;\n _updateNetworkTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _updateNetworkGraphMs });\n\n if (result.mutationResult && !result.mutationResult.success) {\n return error(result.mutationResult.error || \"Failed to update index.\");\n }\n return success({ message: \"Index updated.\", settings: Object.keys(query.settings), _graphTimings: [{ name: 'index', durationMs: _updateNetworkGraphMs, agents: result.agentTimings ?? [] }] });\n },\n });\n\n const createNetwork = defineTool({\n name: \"create_network\",\n description:\n \"Creates a new network (community/group). The authenticated user becomes the owner with full control over settings and membership.\\n\\n\" +\n \"**What is a network?** A shared space where members post intents (what they're looking for) and the system discovers opportunities \" +\n \"(complementary matches) between members. The network's prompt guides what kinds of intents belong.\\n\\n\" +\n \"**When to use:** When the user wants to create a new community — e.g. a professional network, interest group, or project team.\\n\\n\" +\n \"**Returns:** The new network's networkId (UUID) and title. Use the networkId to add members (create_network_membership), \" +\n \"link intents (create_intent_index), or run discovery (discover_opportunities with networkId).\",\n querySchema: z.object({\n title: z.string().describe(\"Display name of the network (e.g. 'AI Founders Berlin', 'Design Co-op'). Required.\"),\n prompt: z.string().optional().describe(\"Description of what this community is about (e.g. 'Early-stage AI/ML founders in Berlin looking for co-founders, advisors, and investors'). Used by the system to evaluate which intents belong in this network. Highly recommended for better auto-assignment.\"),\n imageUrl: z.string().url().optional().describe(\"URL for the community's avatar/image. Optional.\"),\n joinPolicy: z.enum(['anyone', 'invite_only']).optional().describe(\"'anyone' = open (any user can self-join), 'invite_only' = only the owner can add members. Defaults to 'invite_only'.\"),\n }),\n handler: async ({ context, query }) => {\n if (!query.title?.trim()) {\n return error(\"Title is required.\");\n }\n\n const _createNetworkGraphStart = Date.now();\n const _createNetworkTraceEmitter = requestContext.getStore()?.traceEmitter;\n _createNetworkTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n operationMode: 'create' as const,\n createInput: {\n title: query.title.trim(),\n prompt: query.prompt?.trim() || undefined,\n imageUrl: query.imageUrl || undefined,\n joinPolicy: query.joinPolicy,\n },\n });\n const _createNetworkGraphMs = Date.now() - _createNetworkGraphStart;\n _createNetworkTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _createNetworkGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n created: true,\n networkId: result.mutationResult.networkId,\n title: result.mutationResult.title,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'index', durationMs: _createNetworkGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to create network.\");\n }\n return error(\"Failed to create network.\");\n },\n });\n\n const deleteNetwork = defineTool({\n name: \"delete_network\",\n description:\n \"Permanently deletes a network (community). Only the owner can delete, and the network must have no other members \" +\n \"(remove all members first with delete_network_membership). Personal networks cannot be deleted.\\n\\n\" +\n \"**When to use:** When the owner wants to disband a community. This is irreversible — all intent-network links to this network are removed.\\n\\n\" +\n \"**Prerequisites:** Must be the owner. Must be the sole remaining member (remove others first).\\n\\n\" +\n \"**Returns:** Confirmation that the network was deleted.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Network UUID to delete. Get from read_networks. Defaults to the scoped index in network-scoped chats. Cannot be a personal network.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || context.networkId;\n if (!networkId || !UUID_REGEX.test(networkId)) {\n return error(\"Valid networkId required.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow deleting that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only delete this community.`\n );\n }\n\n const _deleteNetworkGraphStart = Date.now();\n const _deleteNetworkTraceEmitter = requestContext.getStore()?.traceEmitter;\n _deleteNetworkTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const result = await graphs.index.invoke({\n userId: context.userId,\n networkId,\n operationMode: 'delete' as const,\n });\n const _deleteNetworkGraphMs = Date.now() - _deleteNetworkGraphStart;\n _deleteNetworkTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _deleteNetworkGraphMs });\n\n if (result.mutationResult && !result.mutationResult.success) {\n return error(result.mutationResult.error || \"Failed to delete network.\");\n }\n return success({ message: \"Network deleted.\", _graphTimings: [{ name: 'index', durationMs: _deleteNetworkGraphMs, agents: result.agentTimings ?? [] }] });\n },\n });\n\n const createNetworkMembership = defineTool({\n name: \"create_network_membership\",\n description:\n \"Adds a user as a member of a network (community). Membership enables the user to post intents in the network and be discovered \" +\n \"by other members through opportunity matching.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- Omit userId: self-join (only works for networks with joinPolicy 'anyone').\\n\" +\n \"- With userId: add another user (only the network owner can do this for 'invite_only' indexes).\\n\\n\" +\n \"**When to use:** When the user wants to join an open community, or when a network owner wants to invite someone.\\n\\n\" +\n \"**Returns:** Confirmation that the member was added (or a note that they were already a member). \" +\n \"After joining, the user's existing intents with autoAssign=true may be evaluated against the new network.\",\n querySchema: z.object({\n userId: z.string().optional().describe(\"User ID to add as a member. Omit to join the network yourself. Get user IDs from read_user_contexts(query=name) or read_network_memberships.\"),\n networkId: z.string().optional().describe(\"Network UUID to add the member to. Get from read_networks. Defaults to the scoped index in network-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || context.networkId;\n const targetUserId = query.userId?.trim() || context.userId;\n if (!networkId || !UUID_REGEX.test(networkId)) {\n return error(\"Invalid network ID format. Use the exact UUID from read_networks.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow adding to that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only add members to this community.`\n );\n }\n\n const _createMembershipGraphStart = Date.now();\n const _createMembershipTraceEmitter = requestContext.getStore()?.traceEmitter;\n _createMembershipTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const result = await graphs.networkMembership.invoke({\n userId: context.userId,\n networkId,\n targetUserId,\n operationMode: 'create' as const,\n });\n const _createMembershipGraphMs = Date.now() - _createMembershipGraphStart;\n _createMembershipTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _createMembershipGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n const alreadyMember = result.mutationResult.message?.includes(\"already\");\n return success({\n created: !alreadyMember,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'network_membership', durationMs: _createMembershipGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to add member.\");\n }\n return error(\"Failed to add member.\");\n },\n });\n\n const deleteNetworkMembership = defineTool({\n name: \"delete_network_membership\",\n description:\n \"Removes a user from a network (community). After removal, the user's intents are unlinked from this network \" +\n \"and they can no longer participate in opportunity discovery within it.\\n\\n\" +\n \"**Permissions:** Only the network owner can remove members. The owner themselves cannot be removed (delete the network instead).\\n\\n\" +\n \"**When to use:** When a network owner wants to remove a member from the community. \" +\n \"Use read_network_memberships(networkId) first to get the userId of the member to remove.\\n\\n\" +\n \"**Returns:** Confirmation that the member was removed.\",\n querySchema: z.object({\n userId: z.string().describe(\"User ID of the member to remove. Get from read_network_memberships(networkId). Cannot be the network owner.\"),\n networkId: z.string().optional().describe(\"Network UUID to remove the member from. Get from read_networks. Defaults to the scoped index in network-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const networkId = query.networkId?.trim() || context.networkId;\n const targetUserId = query.userId?.trim();\n\n if (!networkId || !UUID_REGEX.test(networkId)) {\n return error(\"Valid networkId required. Use the exact UUID from read_networks.\");\n }\n if (!targetUserId) {\n return error(\"userId is required.\");\n }\n\n // Strict scope enforcement: when chat is network-scoped, only allow that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this network'}. You can only manage members of this community.`\n );\n }\n\n const _deleteMembershipGraphStart = Date.now();\n const _deleteMembershipTraceEmitter = requestContext.getStore()?.traceEmitter;\n _deleteMembershipTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const result = await graphs.networkMembership.invoke({\n userId: context.userId,\n networkId,\n targetUserId,\n operationMode: 'delete' as const,\n });\n const _deleteMembershipGraphMs = Date.now() - _deleteMembershipGraphStart;\n _deleteMembershipTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _deleteMembershipGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n removed: true,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'network_membership', durationMs: _deleteMembershipGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to remove member.\");\n }\n return error(\"Failed to remove member.\");\n },\n });\n\n return [readIndexes, readIndexMemberships, updateNetwork, createNetwork, deleteNetwork, createNetworkMembership, deleteNetworkMembership] as const;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feed.graph.d.ts","sourceRoot":"/","sources":["opportunity/feed/feed.graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAkB,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAwB,MAAM,iBAAiB,CAAC;AAQtI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"feed.graph.d.ts","sourceRoot":"/","sources":["opportunity/feed/feed.graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAkB,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAwB,MAAM,iBAAiB,CAAC;AAQtI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAczE,8HAA8H;AAC9H,KAAK,WAAW,GAAG,iBAAiB,CAAC;AAErC,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,IAAI,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,EAAE,iBAAiB,EAA0B,CAAC;AAgBhF,0HAA0H;AAC1H,eAAO,MAAM,wBAAwB,EAAE,iBAAiB,EAEhC,CAAC;AAczB;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAarF;AA4ED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ;IAAe,OAAO,CAAC,KAAK;gBAApC,QAAQ,EAAE,WAAW,EAAU,KAAK,EAAE,gBAAgB;IAE1E,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4iBZ"}
|
|
@@ -22,6 +22,13 @@ import { protocolLogger } from '../../shared/observability/protocol.logger.js';
|
|
|
22
22
|
import { timed } from '../../shared/observability/performance.js';
|
|
23
23
|
import { requestContext } from "../../shared/observability/request-context.js";
|
|
24
24
|
const logger = protocolLogger('HomeGraph');
|
|
25
|
+
const checkCategorizerCacheLog = protocolLogger('HomeGraph:checkCategorizerCache');
|
|
26
|
+
const cacheCategorizerResultsLog = protocolLogger('HomeGraph:cacheCategorizerResults');
|
|
27
|
+
const checkPresenterCacheLog = protocolLogger('HomeGraph:checkPresenterCache');
|
|
28
|
+
const cachePresenterResultsLog = protocolLogger('HomeGraph:cachePresenterResults');
|
|
29
|
+
const categorizeDynamicallyLog = protocolLogger('HomeGraph:categorizeDynamically');
|
|
30
|
+
const normalizeAndSortLog = protocolLogger('HomeGraph:normalizeAndSort');
|
|
31
|
+
const generateCardTextLog = protocolLogger('HomeGraph:generateCardText');
|
|
25
32
|
/** Default home-feed statuses: the lifecycle stages a viewer can act on today. */
|
|
26
33
|
export const DEFAULT_HOME_STATUSES = ['latent', 'pending'];
|
|
27
34
|
// Exhaustive registry — keys must cover every OpportunityStatus union member.
|
|
@@ -213,7 +220,7 @@ export class HomeGraphFactory {
|
|
|
213
220
|
return { cachedCards: new Map(), uncachedOpportunities: [] };
|
|
214
221
|
}
|
|
215
222
|
if (state.noCache) {
|
|
216
|
-
|
|
223
|
+
checkPresenterCacheLog.verbose('noCache=true, skipping cache');
|
|
217
224
|
return { cachedCards: new Map(), uncachedOpportunities: opportunities };
|
|
218
225
|
}
|
|
219
226
|
try {
|
|
@@ -240,7 +247,7 @@ export class HomeGraphFactory {
|
|
|
240
247
|
uncachedOpportunities.push(cacheable[i]);
|
|
241
248
|
}
|
|
242
249
|
}
|
|
243
|
-
|
|
250
|
+
checkPresenterCacheLog.verbose('', {
|
|
244
251
|
total: opportunities.length,
|
|
245
252
|
cacheHits: cachedCards.size,
|
|
246
253
|
cacheMisses: uncachedOpportunities.length,
|
|
@@ -248,7 +255,7 @@ export class HomeGraphFactory {
|
|
|
248
255
|
return { cachedCards, uncachedOpportunities };
|
|
249
256
|
}
|
|
250
257
|
catch (e) {
|
|
251
|
-
|
|
258
|
+
checkPresenterCacheLog.warn('cache unavailable, skipping', { error: e });
|
|
252
259
|
return { cachedCards: new Map(), uncachedOpportunities: opportunities };
|
|
253
260
|
}
|
|
254
261
|
});
|
|
@@ -257,7 +264,7 @@ export class HomeGraphFactory {
|
|
|
257
264
|
if (state.uncachedOpportunities.length > 0) {
|
|
258
265
|
return 'generate';
|
|
259
266
|
}
|
|
260
|
-
logger.verbose('
|
|
267
|
+
logger.verbose('All presenter results cached, skipping generation');
|
|
261
268
|
return 'skip';
|
|
262
269
|
};
|
|
263
270
|
const generateCardTextNode = async (state) => {
|
|
@@ -265,9 +272,9 @@ export class HomeGraphFactory {
|
|
|
265
272
|
const opportunities = state.uncachedOpportunities.length > 0
|
|
266
273
|
? state.uncachedOpportunities
|
|
267
274
|
: state.opportunities;
|
|
268
|
-
|
|
275
|
+
generateCardTextLog.verbose('entry', { opportunitiesLength: opportunities.length, userId: state.userId });
|
|
269
276
|
if (opportunities.length === 0) {
|
|
270
|
-
|
|
277
|
+
generateCardTextLog.verbose('exit', { totalOpportunities: 0, totalSections: 0 });
|
|
271
278
|
return { cards: [], agentTimings: [], meta: { totalOpportunities: 0, totalSections: 0 } };
|
|
272
279
|
}
|
|
273
280
|
const db = this.database;
|
|
@@ -329,7 +336,7 @@ export class HomeGraphFactory {
|
|
|
329
336
|
// Fallback to profile identity name when users.name is missing (e.g. profile has display name, users row does not)
|
|
330
337
|
if ((userName === 'Unknown' || !userName?.trim()) && otherActor?.userId && db.getProfile) {
|
|
331
338
|
const profile = await db.getProfile(otherActor.userId).catch((err) => {
|
|
332
|
-
logger.debug('
|
|
339
|
+
logger.debug('getProfile fallback failed', { otherActorUserId: otherActor.userId, error: err });
|
|
333
340
|
return null;
|
|
334
341
|
});
|
|
335
342
|
const profileName = profile?.identity?.name?.trim();
|
|
@@ -444,7 +451,7 @@ export class HomeGraphFactory {
|
|
|
444
451
|
}));
|
|
445
452
|
cards.push(...chunkCards);
|
|
446
453
|
}
|
|
447
|
-
|
|
454
|
+
generateCardTextLog.verbose('exit', { totalOpportunities: state.opportunities.length, totalSections: 0 });
|
|
448
455
|
return {
|
|
449
456
|
cards,
|
|
450
457
|
agentTimings: agentTimingsAccum,
|
|
@@ -472,7 +479,7 @@ export class HomeGraphFactory {
|
|
|
472
479
|
}));
|
|
473
480
|
}
|
|
474
481
|
catch (e) {
|
|
475
|
-
|
|
482
|
+
cachePresenterResultsLog.warn('cache write failed, continuing', { error: e });
|
|
476
483
|
}
|
|
477
484
|
// Merge cached cards into full card list
|
|
478
485
|
const allCards = [...cards];
|
|
@@ -483,7 +490,7 @@ export class HomeGraphFactory {
|
|
|
483
490
|
}
|
|
484
491
|
// Re-sort by _cardIndex to maintain original ordering
|
|
485
492
|
allCards.sort((a, b) => a._cardIndex - b._cardIndex);
|
|
486
|
-
|
|
493
|
+
cachePresenterResultsLog.verbose('', {
|
|
487
494
|
newlyCached: newCards.length,
|
|
488
495
|
totalCards: allCards.length,
|
|
489
496
|
});
|
|
@@ -499,36 +506,36 @@ export class HomeGraphFactory {
|
|
|
499
506
|
return { categoryCacheHit: false };
|
|
500
507
|
}
|
|
501
508
|
if (state.noCache) {
|
|
502
|
-
|
|
509
|
+
checkCategorizerCacheLog.verbose('noCache=true, skipping cache');
|
|
503
510
|
return { categoryCacheHit: false };
|
|
504
511
|
}
|
|
505
512
|
try {
|
|
506
513
|
const key = buildCategorizerCacheKey(state.userId, state.cards);
|
|
507
514
|
const cached = await this.cache.get(key);
|
|
508
515
|
if (cached) {
|
|
509
|
-
|
|
516
|
+
checkCategorizerCacheLog.verbose('cache hit');
|
|
510
517
|
return { sectionProposals: cached, categoryCacheHit: true };
|
|
511
518
|
}
|
|
512
|
-
|
|
519
|
+
checkCategorizerCacheLog.verbose('cache miss');
|
|
513
520
|
}
|
|
514
521
|
catch (e) {
|
|
515
|
-
|
|
522
|
+
checkCategorizerCacheLog.warn('cache unavailable, skipping', { error: e });
|
|
516
523
|
}
|
|
517
524
|
return { categoryCacheHit: false };
|
|
518
525
|
});
|
|
519
526
|
};
|
|
520
527
|
const shouldCategorize = (state) => {
|
|
521
528
|
if (state.categoryCacheHit) {
|
|
522
|
-
logger.verbose('
|
|
529
|
+
logger.verbose('Categorizer results cached, skipping');
|
|
523
530
|
return 'skip';
|
|
524
531
|
}
|
|
525
532
|
return 'categorize';
|
|
526
533
|
};
|
|
527
534
|
const categorizeDynamicallyNode = async (state) => {
|
|
528
535
|
return timed("HomeGraph.categorizeDynamically", async () => {
|
|
529
|
-
|
|
536
|
+
categorizeDynamicallyLog.verbose('entry', { cardsLength: state.cards.length });
|
|
530
537
|
if (state.cards.length === 0) {
|
|
531
|
-
|
|
538
|
+
categorizeDynamicallyLog.verbose('exit', { sectionProposalsCount: 0 });
|
|
532
539
|
return { sectionProposals: [], agentTimings: [] };
|
|
533
540
|
}
|
|
534
541
|
const agentTimingsAccum = [];
|
|
@@ -551,7 +558,7 @@ export class HomeGraphFactory {
|
|
|
551
558
|
...s,
|
|
552
559
|
itemIndices: s.itemIndices.filter((i) => i >= 0 && i < state.cards.length),
|
|
553
560
|
}));
|
|
554
|
-
|
|
561
|
+
categorizeDynamicallyLog.verbose('exit', { sectionProposalsCount: proposals.length });
|
|
555
562
|
return { sectionProposals: proposals, agentTimings: agentTimingsAccum };
|
|
556
563
|
});
|
|
557
564
|
};
|
|
@@ -563,12 +570,12 @@ export class HomeGraphFactory {
|
|
|
563
570
|
try {
|
|
564
571
|
const key = buildCategorizerCacheKey(state.userId, state.cards);
|
|
565
572
|
await this.cache.set(key, state.sectionProposals, { ttl: HOME_CACHE_TTL });
|
|
566
|
-
|
|
573
|
+
cacheCategorizerResultsLog.verbose('cached', {
|
|
567
574
|
sectionCount: state.sectionProposals.length,
|
|
568
575
|
});
|
|
569
576
|
}
|
|
570
577
|
catch (e) {
|
|
571
|
-
|
|
578
|
+
cacheCategorizerResultsLog.warn('cache write failed, continuing', { error: e });
|
|
572
579
|
}
|
|
573
580
|
return {};
|
|
574
581
|
});
|
|
@@ -577,9 +584,9 @@ export class HomeGraphFactory {
|
|
|
577
584
|
return timed("HomeGraph.normalizeAndSort", async () => {
|
|
578
585
|
const cards = state.cards;
|
|
579
586
|
const proposals = state.sectionProposals;
|
|
580
|
-
|
|
587
|
+
normalizeAndSortLog.verbose('entry', { cardsLength: cards.length, proposalsLength: proposals.length });
|
|
581
588
|
if (cards.length === 0) {
|
|
582
|
-
|
|
589
|
+
normalizeAndSortLog.verbose('exit', { totalOpportunities: 0, totalSections: 0 });
|
|
583
590
|
return { sections: [], meta: { totalOpportunities: 0, totalSections: 0 } };
|
|
584
591
|
}
|
|
585
592
|
const usedIndices = new Set();
|
|
@@ -619,7 +626,7 @@ export class HomeGraphFactory {
|
|
|
619
626
|
totalOpportunities: state.opportunities.length,
|
|
620
627
|
totalSections: sections.length,
|
|
621
628
|
};
|
|
622
|
-
|
|
629
|
+
normalizeAndSortLog.verbose('exit', { totalOpportunities: meta.totalOpportunities, totalSections: meta.totalSections });
|
|
623
630
|
return { sections, meta };
|
|
624
631
|
});
|
|
625
632
|
};
|